]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Always intercept cpuid
authorJan Kiszka <jan.kiszka@siemens.com>
Fri, 1 May 2015 10:12:27 +0000 (12:12 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 22 May 2015 04:54:49 +0000 (06:54 +0200)
Refactor vmx_handle_cpuid to vcpu_handle_cpuid and ensure that both VMX
and SVM use it for emulating guest cpuid invocations. That means SVM has
to intercept it now.

We will need this to reliably indicate the presence of Jailhouse to our
inmates.

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

index 07dd64fd54af2f89503dd8e99d8522bd848084a4..ca9f9c691871fd861bb1abd48cf3f7375dbcb9f9 100644 (file)
@@ -113,6 +113,8 @@ bool vcpu_handle_mmio_access(void);
 bool vcpu_handle_msr_read(void);
 bool vcpu_handle_msr_write(void);
 
+void vcpu_handle_cpuid(void);
+
 bool vcpu_handle_xsetbv(void);
 
 void vcpu_reset(bool hard_reset);
index 10e4f64641a056e309f3da5e9f0384b49138d49f..949446fd7e278da7f1db8529877e5581438834b6 100644 (file)
@@ -199,6 +199,7 @@ static void vmcb_setup(struct per_cpu *cpu_data)
 
        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_NMI;
        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_CR0_SEL_WRITE;
+       vmcb->general1_intercepts |= GENERAL1_INTERCEPT_CPUID;
        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_IOIO_PROT;
        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_MSR_PROT;
        vmcb->general1_intercepts |= GENERAL1_INTERCEPT_SHUTDOWN_EVT;
@@ -879,6 +880,9 @@ void vcpu_handle_exit(struct per_cpu *cpu_data)
                if (svm_handle_cr(cpu_data))
                        goto vmentry;
                break;
+       case VMEXIT_CPUID:
+               vcpu_handle_cpuid();
+               goto vmentry;
        case VMEXIT_MSR:
                cpu_data->stats[JAILHOUSE_CPU_STAT_VMEXITS_MSR]++;
                if (!vmcb->exitinfo1)
index b52f9bf7ea2f0bfed89a210293dc9833fd87a2de..16b5db232a3ad73af0d03c5245e2740469369f67 100644 (file)
@@ -311,6 +311,24 @@ bool vcpu_handle_msr_write(void)
        return true;
 }
 
+void vcpu_handle_cpuid(void)
+{
+       union registers *guest_regs = &this_cpu_data()->guest_regs;
+
+       this_cpu_data()->stats[JAILHOUSE_CPU_STAT_VMEXITS_CPUID]++;
+
+       /* clear upper 32 bits of the involved registers */
+       guest_regs->rax &= 0xffffffff;
+       guest_regs->rbx &= 0xffffffff;
+       guest_regs->rcx &= 0xffffffff;
+       guest_regs->rdx &= 0xffffffff;
+
+       cpuid((u32 *)&guest_regs->rax, (u32 *)&guest_regs->rbx,
+             (u32 *)&guest_regs->rcx, (u32 *)&guest_regs->rdx);
+
+       vcpu_skip_emulated_instruction(X86_INST_LEN_CPUID);
+}
+
 bool vcpu_handle_xsetbv(void)
 {
        union registers *guest_regs = &this_cpu_data()->guest_regs;
index 622668ea9d38649a712d973be3fbbb39f41e97f3..7f7e9a782989e699d754285a91626288e9631534 100644 (file)
@@ -881,22 +881,6 @@ void vcpu_skip_emulated_instruction(unsigned int inst_len)
        vmcs_write64(GUEST_RIP, vmcs_read64(GUEST_RIP) + inst_len);
 }
 
-static void vmx_handle_cpuid(union registers *guest_regs)
-{
-       this_cpu_data()->stats[JAILHOUSE_CPU_STAT_VMEXITS_CPUID]++;
-
-       /* clear upper 32 bits of the involved registers */
-       guest_regs->rax &= 0xffffffff;
-       guest_regs->rbx &= 0xffffffff;
-       guest_regs->rcx &= 0xffffffff;
-       guest_regs->rdx &= 0xffffffff;
-
-       cpuid((u32 *)&guest_regs->rax, (u32 *)&guest_regs->rbx,
-             (u32 *)&guest_regs->rcx, (u32 *)&guest_regs->rdx);
-
-       vcpu_skip_emulated_instruction(X86_INST_LEN_CPUID);
-}
-
 static void update_efer(void)
 {
        unsigned long efer = vmcs_read64(GUEST_IA32_EFER);
@@ -1076,7 +1060,7 @@ void vcpu_handle_exit(struct per_cpu *cpu_data)
                iommu_check_pending_faults(cpu_data);
                return;
        case EXIT_REASON_CPUID:
-               vmx_handle_cpuid(&cpu_data->guest_regs);
+               vcpu_handle_cpuid();
                return;
        case EXIT_REASON_VMCALL:
                vcpu_handle_hypercall();