[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/hvm: Intercept RDPMC when vPMU is disabled
vPMU isn't security supported, and in general guests can't access any of the performance counter MSRs. However, the RDPMC instruction isn't intercepted, meaning that guest software can read the instantaneous counter values. When vPMU isn't configured, intercept RDPMC and unconditionally fail it as if software has requested a bad counter index (#GP fault). It is model specific as to which counters are available to begin with, and in levelled scenarios, this information may not be accurate in the first place. This change isn't expected to have any impact on VMs. Userspace is not usually given access to RDPMC (Windows appear to completely prohibit it; Linux is restricted to root), and kernels won't be executing RDPMC instructions if their PMU drivers have failed to start. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Jun Nakajima <jun.nakajima@xxxxxxxxx> CC: Kevin Tian <kevin.tian@xxxxxxxxx> CC: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> CC: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> CC: Brian Woods <brian.woods@xxxxxxx> CC: Juergen Gross <jgross@xxxxxxxx> This should be taken into Xen 4.12 and backported to the stable releases. While it isn't an XSA itself, it is an information leak (Xen's NMI watchdog in particular) which could be advantagous to an attacker trying to exploit a race condition. The only other option is to emulate the reported family and offer back all 0's for the accessable counters. Obviously this is a non-starter. This patch has had some basic testing in XenServer with no issues identified with any guests. --- xen/arch/x86/hvm/svm/svm.c | 8 ++++++++ xen/arch/x86/hvm/svm/vmcb.c | 3 +++ xen/arch/x86/hvm/vmx/vmcs.c | 2 ++ xen/arch/x86/hvm/vmx/vmx.c | 9 +++++++++ 4 files changed, 22 insertions(+) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 2584b90..de20bb2 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -2984,6 +2984,14 @@ void svm_vmexit_handler(struct cpu_user_regs *regs) svm_vmexit_do_rdtsc(regs, exit_reason == VMEXIT_RDTSCP); break; + case VMEXIT_RDPMC: + /* + * Interception is only active when VPMU is disabled, and the guest + * mustn't be able to read the counters. Emulate "bad counter index". + */ + hvm_inject_hw_exception(TRAP_gp_fault, 0); + break; + case VMEXIT_MONITOR: case VMEXIT_MWAIT: hvm_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); diff --git a/xen/arch/x86/hvm/svm/vmcb.c b/xen/arch/x86/hvm/svm/vmcb.c index 9d1c5bf..092c049 100644 --- a/xen/arch/x86/hvm/svm/vmcb.c +++ b/xen/arch/x86/hvm/svm/vmcb.c @@ -67,6 +67,9 @@ static int construct_vmcb(struct vcpu *v) GENERAL1_INTERCEPT_INVLPGA | GENERAL1_INTERCEPT_IOIO_PROT | GENERAL1_INTERCEPT_MSR_PROT | GENERAL1_INTERCEPT_SHUTDOWN_EVT| GENERAL1_INTERCEPT_TASK_SWITCH; + if ( !vpmu_available(v) ) + vmcb->_general1_intercepts |= GENERAL1_INTERCEPT_RDPMC; + vmcb->_general2_intercepts = GENERAL2_INTERCEPT_VMRUN | GENERAL2_INTERCEPT_VMMCALL | GENERAL2_INTERCEPT_VMLOAD | GENERAL2_INTERCEPT_VMSAVE | diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 74f2a08..e860db9 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -994,6 +994,8 @@ static int construct_vmcs(struct vcpu *v) __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control); v->arch.hvm.vmx.exec_control = vmx_cpu_based_exec_control; + if ( !vpmu_available(v) ) + v->arch.hvm.vmx.exec_control |= CPU_BASED_RDPMC_EXITING; if ( d->arch.vtsc && !cpu_has_vmx_tsc_scaling ) v->arch.hvm.vmx.exec_control |= CPU_BASED_RDTSC_EXITING; diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 24def93..c5e5804 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -3956,6 +3956,15 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) __vmread(EXIT_QUALIFICATION, &exit_qualification); vmx_invlpg_intercept(exit_qualification); break; + + case EXIT_REASON_RDPMC: + /* + * Interception is only active when VPMU is disabled, and the guest + * mustn't be able to read the counters. Emulate "bad counter index". + */ + hvm_inject_hw_exception(TRAP_gp_fault, 0); + break; + case EXIT_REASON_RDTSCP: if ( !currd->arch.cpuid->extd.rdtscp ) { -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |