I am trying to develop a simple PCI device and I am setting up 3 BARs. The last BAR is a DDR and I ve tried 2 different implementations: one with memory_region_init_io and one with memory_region_init_ram.
I ve got a small program that declares a buffer and does float operations in the following fashion: float *buffer; buffer[index] = (float)value; When I use QEMU with KVM, the memory_region_init_ram implementation seems to be happy running the above code. When I use the memory_region_init_io I get a SIGILL on the guest. I ve run this with GDB and the disassembly shows movss %xmm0, (%rcx) According to Intel ISA, the instruction does this MOVSS Move Single Scalar Opcode Cycles Instruction F3 0F 10 MOVSS xmm reg,xmm reg/mem32 F3 0F 11 MOVSS mem32,xmm reg MOVSS op1, op2 op1 contains 1 single precision 32-bit floating point value op2 contains 1 single precision 32-bit floating point value I ve looked at the KVM on the Host and hacked it to add some debug statements to see when it fails to execute a command. Tracing KVM during the run it fails on the movss instruction opcode: f3 0f 11: qemu-system-x86-1129 [000] .... 80154.583037: kvm_fpu: load qemu-system-x86-1129 [000] d... 80154.583037: kvm_entry: vcpu 1 qemu-system-x86-1129 [000] .... 80154.583039: kvm_exit: reason EPT_VIOLATION rip 0x7f2f45163c40 info 182 0 qemu-system-x86-1129 [000] .... 80154.583039: kvm_page_fault: address 1404bc000 error_code 182 qemu-system-x86-1129 [000] .... 80154.583042: kvm_emulate_insn: 0:7f2f45163c40:f3 0f 11 (prot64) qemu-system-x86-1129 [000] .N.. 80154.588339: kvm_emulate_insn: 0:7f2f45163c40:f3 0f 11 (prot64) failed qemu-system-x86-1129 [000] d... 80154.588342: kvm_fpu: unload qemu-system-x86-1129 [002] .... 80154.588523: kvm_inj_exception: #UD (0x0) qemu-system-x86-1129 [002] .... 80154.588525: kvm_fpu: load The opcode is twobyte. Byte 0x11 is used to lookup flags from the twobyte table in KVM in arch/x86/kvm/emulate.c:4615 static const struct opcode twobyte_table[256] = { /* 0x00 - 0x0F */ G(0, group6), GD(0, &group7), N, N, N, I(ImplicitOps | EmulateOnUD, em_syscall), II(ImplicitOps | Priv, em_clts, clts), N, DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, N, D(ImplicitOps | ModRM | SrcMem | NoAccess), N, N, /* 0x10 - 0x1F */ N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM | SrcMem | NoAccess), N, N, N, N, N, N, D(ImplicitOps | ModRM | SrcMem | NoAccess), It looks like that the instruction is not implemented. I ve tried this on the 3.10, 4.4 & 4.11 kernels on the host. The interesting thing is that in the ram case the test is passing, but in the io is failing. Also, if I try this without KVM, it passes in both cases. So I ve done some reading and for the 2 cases above I get: - KVM_EXIT_MMIO on memory_region_init_io (KVM attempts and fails to emulate MOVSS), - KVM_EXIT_EXCEPTION on memory_region_init_ram(QEMU emulates MOVSS) Is that right? Now the question is, if I want to use the IO instead of a RAM, what's the best way to solve this? ​Milton