All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/hvm: Intercept RDPMC when vPMU is disabled
@ 2019-02-22 21:13 Andrew Cooper
  2019-02-22 21:58 ` Boris Ostrovsky
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Cooper @ 2019-02-22 21:13 UTC (permalink / raw)
  To: Xen-devel
  Cc: Juergen Gross, Kevin Tian, Wei Liu, Jan Beulich, Andrew Cooper,
	Jun Nakajima, Boris Ostrovsky, Brian Woods,
	Suravee Suthikulpanit, Roger Pau Monné

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@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Jun Nakajima <jun.nakajima@intel.com>
CC: Kevin Tian <kevin.tian@intel.com>
CC: Boris Ostrovsky <boris.ostrovsky@oracle.com>
CC: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
CC: Brian Woods <brian.woods@amd.com>
CC: Juergen Gross <jgross@suse.com>

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@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-02-25 21:25 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-22 21:13 [PATCH] x86/hvm: Intercept RDPMC when vPMU is disabled Andrew Cooper
2019-02-22 21:58 ` Boris Ostrovsky
2019-02-22 22:44   ` Andrew Cooper
2019-02-22 23:48     ` Boris Ostrovsky
2019-02-25 13:11       ` Jan Beulich
2019-02-25 14:11         ` Andrew Cooper
2019-02-25 15:26           ` Jan Beulich
2019-02-25 21:25             ` Boris Ostrovsky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.