首页 > 解决方案 > 向量化代码写入 PCI 时获取非法指令

问题描述

我正在编写一个写入设备的硬件寄存器范围的程序。我正在使用 mmap 将硬件地址映射到虚拟地址(用户空间)。我测试了mmap的结果,没问题。我在设备中实现了一个缓冲区的副本:

void bufferCopy(void *dest, void *src, const size_t size) {
    uint8_t *pdest = static_cast<uint8_t *>(dest);
    uint8_t *psrc = static_cast<uint8_t *>(src);
    size_t iters = 0, tailBytes = 0;

    /* iterate 64bit */
    iters = (size / sizeof(uint64_t));
    for (size_t index = 0; index < iters; ++index) {
        *(reinterpret_cast<uint64_t *>(pdest)) =
            *(reinterpret_cast<uint64_t *>(psrc));
        pdest += sizeof(uint64_t);
        psrc += sizeof(uint64_t);
    }
.
.
.

但是在 QEMU 上运行它时,我得到了非法指令异常。当我调试它时,它在下一条指令上崩溃(下面是主循环的汇编):

movdqu (%rsi,%rax,1),%xmm0                                                   
movups %xmm0,(%rdi,%rax,1)   <----- this instruction crashes ...                                                  
add    $0x10,%rax                                                            
cmp    %rax,%r9                                                              
jne    0x7ffff7eca1e0 <_ZN12_GLOBAL__N_110bufferCopyEPvS0_m+64>   

任何想法为什么?我猜你只能写入 32/64 位的 PCI。编译不知道我的限制,所以它优化了我的代码并创建了矢量化循环(每次迭代加载 128 位并保存 128 位)。有道理吗??我可以用矢量化指令写入 PCI 吗?

此外,无论是 QEMU 中缺少的功能还是错误或只是建议,我如何才能防止编译器生成这些向量指令?

标签: x86-64sseqemummappci

解决方案


推荐阅读