From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: [PATCH 2/3] VMX: don't blindly enable descriptor table exiting control Date: Thu, 13 Apr 2017 08:53:12 -0600 Message-ID: <58EFACF80200007800150CFD@prv-mh.provo.novell.com> References: <58EFAA7F0200007800150CD0@prv-mh.provo.novell.com> <58EFAA7F0200007800150CD0@prv-mh.provo.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=__Part87BE3DC8.5__=" Return-path: Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cyg7a-0006hr-3t for xen-devel@lists.xenproject.org; Thu, 13 Apr 2017 14:53:18 +0000 In-Reply-To: <58EFAA7F0200007800150CD0@prv-mh.provo.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" To: xen-devel Cc: Kevin Tian , Suravee Suthikulpanit , Razvan Cojocaru , Adrian Pop , Andrew Cooper , Julien Grall , Jun Nakajima , Tamas K Lengyel , Boris Ostrovsky List-Id: xen-devel@lists.xenproject.org This is a MIME message. If you are reading this text, you may want to consider changing to a mail reader or gateway that understands how to properly handle MIME multipart messages. --=__Part87BE3DC8.5__= Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline This is an optional feature and hence we should check for it before use. Signed-off-by: Jan Beulich --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -866,7 +866,7 @@ static void svm_set_rdtsc_exiting(struct vmcb_set_general2_intercepts(vmcb, general2_intercepts); } =20 -static void svm_set_descriptor_access_exiting(struct vcpu *v, bool = enable) +static bool svm_set_descriptor_access_exiting(struct vcpu *v, bool = enable) { struct vmcb_struct *vmcb =3D v->arch.hvm_svm.vmcb; u32 general1_intercepts =3D vmcb_get_general1_intercepts(vmcb); @@ -881,6 +881,8 @@ static void svm_set_descriptor_access_ex general1_intercepts &=3D ~mask; =20 vmcb_set_general1_intercepts(vmcb, general1_intercepts); + + return true; } =20 static unsigned int svm_get_insn_bytes(struct vcpu *v, uint8_t *buf) --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -226,6 +226,7 @@ static int vmx_init_vmcs_config(void) opt =3D (SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | SECONDARY_EXEC_WBINVD_EXITING | SECONDARY_EXEC_ENABLE_EPT | + SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING | SECONDARY_EXEC_ENABLE_RDTSCP | SECONDARY_EXEC_PAUSE_LOOP_EXITING | SECONDARY_EXEC_ENABLE_INVPCID | @@ -1020,6 +1021,13 @@ static int construct_vmcs(struct vcpu *v =20 v->arch.hvm_vmx.secondary_exec_control =3D vmx_secondary_exec_control;= =20 + /* + * Disable descriptor table exiting: It's controlled by the VM event + * monitor requesting it. + */ + v->arch.hvm_vmx.secondary_exec_control &=3D + ~SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING; + /* Disable VPID for now: we decide when to enable it on VMENTER. */ v->arch.hvm_vmx.secondary_exec_control &=3D ~SECONDARY_EXEC_ENABLE_VPI= D; =20 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -1423,11 +1423,15 @@ static void vmx_set_rdtsc_exiting(struct vmx_vmcs_exit(v); } =20 -static void vmx_set_descriptor_access_exiting(struct vcpu *v, bool = enable) +static bool vmx_set_descriptor_access_exiting(struct vcpu *v, bool = enable) { if ( enable ) + { + if ( !cpu_has_vmx_dt_exiting ) + return false; v->arch.hvm_vmx.secondary_exec_control |=3D SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING; + } else v->arch.hvm_vmx.secondary_exec_control &=3D ~SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING; @@ -1435,6 +1439,8 @@ static void vmx_set_descriptor_access_ex vmx_vmcs_enter(v); vmx_update_secondary_exec_control(v); vmx_vmcs_exit(v); + + return true; } =20 static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page= ) --- a/xen/arch/x86/monitor.c +++ b/xen/arch/x86/monitor.c @@ -213,7 +213,7 @@ int arch_monitor_domctl_event(struct dom =20 case XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS: { - bool old_status =3D ad->monitor.descriptor_access_enabled; + bool old_status =3D ad->monitor.descriptor_access_enabled, ok =3D = true; struct vcpu *v; =20 if ( unlikely(old_status =3D=3D requested_status) ) @@ -223,9 +223,15 @@ int arch_monitor_domctl_event(struct dom ad->monitor.descriptor_access_enabled =3D requested_status; =20 for_each_vcpu ( d, v ) - hvm_funcs.set_descriptor_access_exiting(v, requested_status); + { + ok =3D hvm_funcs.set_descriptor_access_exiting(v, requested_st= atus); + if ( !ok ) + break; + } =20 domain_unpause(d); + if ( !ok ) + return -EOPNOTSUPP; break; } =20 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -173,7 +173,7 @@ struct hvm_function_table { void (*handle_cd)(struct vcpu *v, unsigned long value); void (*set_info_guest)(struct vcpu *v); void (*set_rdtsc_exiting)(struct vcpu *v, bool_t); - void (*set_descriptor_access_exiting)(struct vcpu *v, bool); + bool (*set_descriptor_access_exiting)(struct vcpu *v, bool); =20 /* Nested HVM */ int (*nhvm_vcpu_initialise)(struct vcpu *v); --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -274,6 +274,8 @@ extern u64 vmx_ept_vpid_cap; (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) #define cpu_has_vmx_ept \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) +#define cpu_has_vmx_dt_exiting \ + (vmx_secondary_exec_control & SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING)= #define cpu_has_vmx_vpid \ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID) #define cpu_has_monitor_trap_flag \ --- a/xen/include/asm-x86/monitor.h +++ b/xen/include/asm-x86/monitor.h @@ -77,13 +77,15 @@ static inline uint32_t arch_monitor_get_ (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST) | (1U << XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION) | (1U << XEN_DOMCTL_MONITOR_EVENT_CPUID) | - (1U << XEN_DOMCTL_MONITOR_EVENT_INTERRUPT) | - (1U << XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS); + (1U << XEN_DOMCTL_MONITOR_EVENT_INTERRUPT); =20 /* Since we know this is on VMX, we can just call the hvm func */ if ( hvm_is_singlestep_supported() ) capabilities |=3D (1U << XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP); =20 + if ( cpu_has_vmx_dt_exiting || cpu_has_svm ) + capabilities |=3D (1U << XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS); + return capabilities; } =20 --=__Part87BE3DC8.5__= Content-Type: text/plain; name="VMX-check-dt-exiting.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="VMX-check-dt-exiting.patch" VMX: don't blindly enable descriptor table exiting control=0A=0AThis is an = optional feature and hence we should check for it before=0Ause.=0A=0ASigned= -off-by: Jan Beulich =0A=0A--- a/xen/arch/x86/hvm/svm/sv= m.c=0A+++ b/xen/arch/x86/hvm/svm/svm.c=0A@@ -866,7 +866,7 @@ static void = svm_set_rdtsc_exiting(struct=0A vmcb_set_general2_intercepts(vmcb, = general2_intercepts);=0A }=0A =0A-static void svm_set_descriptor_access_exi= ting(struct vcpu *v, bool enable)=0A+static bool svm_set_descriptor_access_= exiting(struct vcpu *v, bool enable)=0A {=0A struct vmcb_struct *vmcb = =3D v->arch.hvm_svm.vmcb;=0A u32 general1_intercepts =3D vmcb_get_gener= al1_intercepts(vmcb);=0A@@ -881,6 +881,8 @@ static void svm_set_descriptor_= access_ex=0A general1_intercepts &=3D ~mask;=0A =0A vmcb_set_ge= neral1_intercepts(vmcb, general1_intercepts);=0A+=0A+ return true;=0A = }=0A =0A static unsigned int svm_get_insn_bytes(struct vcpu *v, uint8_t = *buf)=0A--- a/xen/arch/x86/hvm/vmx/vmcs.c=0A+++ b/xen/arch/x86/hvm/vmx/vmcs= .c=0A@@ -226,6 +226,7 @@ static int vmx_init_vmcs_config(void)=0A = opt =3D (SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |=0A = SECONDARY_EXEC_WBINVD_EXITING |=0A SECONDARY_EXEC_ENABLE_EPT= |=0A+ SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING |=0A = SECONDARY_EXEC_ENABLE_RDTSCP |=0A SECONDARY_EXEC_PAUSE= _LOOP_EXITING |=0A SECONDARY_EXEC_ENABLE_INVPCID |=0A@@ = -1020,6 +1021,13 @@ static int construct_vmcs(struct vcpu *v=0A =0A = v->arch.hvm_vmx.secondary_exec_control =3D vmx_secondary_exec_control;=0A = =0A+ /*=0A+ * Disable descriptor table exiting: It's controlled by = the VM event=0A+ * monitor requesting it.=0A+ */=0A+ v->arch.hvm= _vmx.secondary_exec_control &=3D=0A+ ~SECONDARY_EXEC_DESCRIPTOR_TABL= E_EXITING;=0A+=0A /* Disable VPID for now: we decide when to enable it = on VMENTER. */=0A v->arch.hvm_vmx.secondary_exec_control &=3D = ~SECONDARY_EXEC_ENABLE_VPID;=0A =0A--- a/xen/arch/x86/hvm/vmx/vmx.c=0A+++ = b/xen/arch/x86/hvm/vmx/vmx.c=0A@@ -1423,11 +1423,15 @@ static void = vmx_set_rdtsc_exiting(struct=0A vmx_vmcs_exit(v);=0A }=0A =0A-static = void vmx_set_descriptor_access_exiting(struct vcpu *v, bool enable)=0A+stat= ic bool vmx_set_descriptor_access_exiting(struct vcpu *v, bool enable)=0A = {=0A if ( enable )=0A+ {=0A+ if ( !cpu_has_vmx_dt_exiting = )=0A+ return false;=0A v->arch.hvm_vmx.secondary_exec_co= ntrol |=3D=0A SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING;=0A+ = }=0A else=0A v->arch.hvm_vmx.secondary_exec_control &=3D=0A = ~SECONDARY_EXEC_DESCRIPTOR_TABLE_EXITING;=0A@@ -1435,6 +1439,8 @@ = static void vmx_set_descriptor_access_ex=0A vmx_vmcs_enter(v);=0A = vmx_update_secondary_exec_control(v);=0A vmx_vmcs_exit(v);=0A+=0A+ = return true;=0A }=0A =0A static void vmx_init_hypercall_page(struct domain = *d, void *hypercall_page)=0A--- a/xen/arch/x86/monitor.c=0A+++ b/xen/arch/x= 86/monitor.c=0A@@ -213,7 +213,7 @@ int arch_monitor_domctl_event(struct = dom=0A =0A case XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS:=0A {=0A- = bool old_status =3D ad->monitor.descriptor_access_enabled;=0A+ = bool old_status =3D ad->monitor.descriptor_access_enabled, ok =3D true;=0A = struct vcpu *v;=0A =0A if ( unlikely(old_status =3D=3D = requested_status) )=0A@@ -223,9 +223,15 @@ int arch_monitor_domctl_event(st= ruct dom=0A ad->monitor.descriptor_access_enabled =3D requested_sta= tus;=0A =0A for_each_vcpu ( d, v )=0A- hvm_funcs.set_des= criptor_access_exiting(v, requested_status);=0A+ {=0A+ = ok =3D hvm_funcs.set_descriptor_access_exiting(v, requested_status);=0A+ = if ( !ok )=0A+ break;=0A+ }=0A =0A = domain_unpause(d);=0A+ if ( !ok )=0A+ return -EOPNOTSUPP;= =0A break;=0A }=0A =0A--- a/xen/include/asm-x86/hvm/hvm.h=0A+++= b/xen/include/asm-x86/hvm/hvm.h=0A@@ -173,7 +173,7 @@ struct hvm_function_= table {=0A void (*handle_cd)(struct vcpu *v, unsigned long value);=0A = void (*set_info_guest)(struct vcpu *v);=0A void (*set_rdtsc_exiting)= (struct vcpu *v, bool_t);=0A- void (*set_descriptor_access_exiting)(stru= ct vcpu *v, bool);=0A+ bool (*set_descriptor_access_exiting)(struct = vcpu *v, bool);=0A =0A /* Nested HVM */=0A int (*nhvm_vcpu_initiali= se)(struct vcpu *v);=0A--- a/xen/include/asm-x86/hvm/vmx/vmcs.h=0A+++ = b/xen/include/asm-x86/hvm/vmx/vmcs.h=0A@@ -274,6 +274,8 @@ extern u64 = vmx_ept_vpid_cap;=0A (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_S= ECONDARY_CONTROLS)=0A #define cpu_has_vmx_ept \=0A (vmx_secondary_exec_= control & SECONDARY_EXEC_ENABLE_EPT)=0A+#define cpu_has_vmx_dt_exiting = \=0A+ (vmx_secondary_exec_control & SECONDARY_EXEC_DESCRIPTOR_TABLE_EXIT= ING)=0A #define cpu_has_vmx_vpid \=0A (vmx_secondary_exec_control & = SECONDARY_EXEC_ENABLE_VPID)=0A #define cpu_has_monitor_trap_flag \=0A--- = a/xen/include/asm-x86/monitor.h=0A+++ b/xen/include/asm-x86/monitor.h=0A@@ = -77,13 +77,15 @@ static inline uint32_t arch_monitor_get_=0A = (1U << XEN_DOMCTL_MONITOR_EVENT_GUEST_REQUEST) |=0A = (1U << XEN_DOMCTL_MONITOR_EVENT_DEBUG_EXCEPTION) |=0A = (1U << XEN_DOMCTL_MONITOR_EVENT_CPUID) |=0A- (1U << = XEN_DOMCTL_MONITOR_EVENT_INTERRUPT) |=0A- (1U << = XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS);=0A+ (1U << = XEN_DOMCTL_MONITOR_EVENT_INTERRUPT);=0A =0A /* Since we know this is = on VMX, we can just call the hvm func */=0A if ( hvm_is_singlestep_supp= orted() )=0A capabilities |=3D (1U << XEN_DOMCTL_MONITOR_EVENT_SING= LESTEP);=0A =0A+ if ( cpu_has_vmx_dt_exiting || cpu_has_svm )=0A+ = capabilities |=3D (1U << XEN_DOMCTL_MONITOR_EVENT_DESC_ACCESS);=0A+=0A = return capabilities;=0A }=0A =0A --=__Part87BE3DC8.5__= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Content-Disposition: inline X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KWGVuLWRldmVs IG1haWxpbmcgbGlzdApYZW4tZGV2ZWxAbGlzdHMueGVuLm9yZwpodHRwczovL2xpc3RzLnhlbi5v cmcveGVuLWRldmVsCg== --=__Part87BE3DC8.5__=--