]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Intercept guest XSETBV instruction in AMD-V
authorValentine Sinitsyn <valentine.sinitsyn@gmail.com>
Sun, 28 Sep 2014 12:35:46 +0000 (18:35 +0600)
committerJan Kiszka <jan.kiszka@siemens.com>
Sat, 1 Nov 2014 19:10:09 +0000 (20:10 +0100)
This adds XSETBV instruction emulation. The code is almost the same as in
VMX, and is barely tested as the instruction is rarely used in real-world
scenarios.

Signed-off-by: Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/svm.c

index 12b62b7b3f4c6d26a2a06d7675fe808264c45a90..5b0f6fcb9d657d30fbad53ba815696e4b961bb3f 100644 (file)
@@ -869,6 +869,22 @@ void vcpu_handle_exit(struct registers *guest_regs, struct per_cpu *cpu_data)
                             "error code is %x\n", vmcb->exitinfo2,
                             vmcb->exitinfo1 & 0xf);
                break;
+       case VMEXIT_XSETBV:
+               cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_XSETBV]++;
+               if ((guest_regs->rax & X86_XCR0_FP) &&
+                   (guest_regs->rax & ~cpuid_eax(0x0d)) == 0 &&
+                   guest_regs->rcx == 0 && guest_regs->rdx == 0) {
+                       vcpu_skip_emulated_instruction(X86_INST_LEN_XSETBV);
+                       asm volatile(
+                               "xsetbv"
+                               : /* no output */
+                               : "a" (guest_regs->rax), "c" (0), "d" (0));
+                       return;
+               }
+               panic_printk("FATAL: Invalid xsetbv parameters: "
+                            "xcr[%d] = %x:%x\n", guest_regs->rcx,
+                            guest_regs->rdx, guest_regs->rax);
+               break;
        case VMEXIT_IOIO:
                cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_PIO]++;
                vcpu_vendor_get_io_intercept(cpu_data, &io);