x86-64 - 向量化代码写入 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 中缺少的功能还是错误或只是建议,我如何才能防止编译器生成这些向量指令?
解决方案
推荐阅读
- mysql - ArcGIS REST 地理编码数据的唯一标识符检查
- javascript - 如何通过 for 循环在 React 类组件中创建对象数组以映射到功能组件中?
- html - 使用
渲染一组 SVG - php - 如何在 DataTables 中实现搜索框和排序
- json - 带有 json 列的 pyspark 数据框将 json 元素聚合到一个新列中并删除重复的
- scala - 我可以从 sbt 将警告处理程序附加到 scalac 吗?
- algorithm - 非结构化文本分组算法
- autocomplete - Vuetify 圆形自动完成菜单宽度
- php - 在 php symfony 中手动编码密码
- xaml - Xamarin HtmlWebViewSource 未绑定