* Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
2014-04-15 13:02 [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest Feng Wu
@ 2014-04-15 9:25 ` Jan Beulich
2014-04-16 1:49 ` Wu, Feng
2014-04-15 10:36 ` Andrew Cooper
1 sibling, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2014-04-15 9:25 UTC (permalink / raw)
To: Feng Wu; +Cc: eddie.dong, Ian.Campbell, jun.nakajima, xen-devel
>>> On 15.04.14 at 15:02, <feng.wu@intel.com> wrote:
> --- a/xen/arch/x86/mm/guest_walk.c
> +++ b/xen/arch/x86/mm/guest_walk.c
> @@ -29,6 +29,7 @@
> #include <xen/sched.h>
> #include <asm/page.h>
> #include <asm/guest_pt.h>
> +#include <asm/hvm/vmx/vmx.h>
>
>
> /* Flags that are needed in a pagetable entry, with the sense of NX inverted */
> @@ -144,14 +145,18 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
> guest_l4e_t *l4p;
> #endif
> uint32_t gflags, mflags, iflags, rc = 0;
> - int smep;
> + int smep, smap;
These want to be bool_t I suppose.
> bool_t pse1G = 0, pse2M = 0;
> + unsigned long sel = 0;
> + uint64_t eflags = guest_cpu_user_regs()->eflags;
> p2m_query_t qt = P2M_ALLOC | P2M_UNSHARE;
>
> perfc_incr(guest_walk);
> memset(gw, 0, sizeof(*gw));
> gw->va = va;
>
> + __vmread(GUEST_CS_SELECTOR, &sel);
You're in common code here - please use the proper HVM
abstraction.
> @@ -165,7 +170,21 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
> * whole walk as if it were a user-mode one and then invert the answer. */
> smep = (is_hvm_vcpu(v) && hvm_smep_enabled(v)
> && (pfec & PFEC_insn_fetch) && !(pfec & PFEC_user_mode) );
> - if ( smep )
> +
> + /*
> + * SMAP: kernel-mode data accesses from user-mode mappings should fault
> + * A fault is considered as a SMAP violation if the following
> + * conditions come ture:
"true"
> + * - X86_CR4_SMAP is set in CR4
> + * - An user page is accessed
"A user page ..." afaik.
> + * - CPL = 3 or X86_EFLAGS_AC clear set)
Stray closing parenthesis.
> + * - Page fault in kernel mode
> + */
> + smap = ( is_hvm_vcpu(v) && hvm_smap_enabled(v)
> + && !(!((sel & 3) == 3) && (eflags & X86_EFLAGS_AC))
!( == ) is better written as ( != ) or, as done elsewhere, ( < ).
> + && !(pfec & PFEC_user_mode) );
> +
> + if ( smep || smap )
Again, please fold these are far as possible (is_hvm_vcpu() and
the PFEC_user_mode are common and hence should be done just
once.
> @@ -363,6 +365,16 @@ static inline int hvm_event_pending(struct vcpu *v)
> #define HVM_CR4_HOST_MASK (mmu_cr4_features & \
> (X86_CR4_VMXE | X86_CR4_PAE | X86_CR4_MCE))
>
> +static inline bool_t hvm_cpuid_has_smap(void)
> +{
> + unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
> + unsigned int leaf = 0x7;
> +
> + hvm_cpuid(leaf, &eax, &ebx, &ecx, &edx);
Please pass NULL for all outputs you don't need.
> @@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu *v)
> X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
> X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
> (cpu_has_smep ? X86_CR4_SMEP : 0) | \
> + (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
What's the reason for the asymmetry with SMEP here? Also, did you
verify that v == current in all call paths? And even if you did, passing
v into the function and adding a respective ASSERT() would seem
rather desirable.
Jan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
2014-04-15 13:02 [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest Feng Wu
2014-04-15 9:25 ` Jan Beulich
@ 2014-04-15 10:36 ` Andrew Cooper
2014-04-16 1:51 ` Wu, Feng
1 sibling, 1 reply; 8+ messages in thread
From: Andrew Cooper @ 2014-04-15 10:36 UTC (permalink / raw)
To: Feng Wu; +Cc: jun.nakajima, eddie.dong, Ian.Campbell, JBeulich, xen-devel
On 15/04/14 14:02, Feng Wu wrote:
> Intel new CPU supports SMAP (Supervisor Mode Access Prevention).
> SMAP prevents supervisor-mode accesses to any linear address with
> a valid translation for which the U/S flag (bit 2) is 1 in every
> paging-structure entry controlling the translation for the linear
> address.
>
> This patch enable SMAP for HVM geust.
>
> Signed-off-by: Feng Wu <feng.wu@intel.com>
> ---
> xen/arch/x86/hvm/hvm.c | 3 +++
> xen/arch/x86/mm/guest_walk.c | 27 +++++++++++++++++++++++----
> xen/include/asm-x86/hvm/hvm.h | 13 +++++++++++++
> 3 files changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> index b0da8e7..b52476d 100644
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -3036,6 +3036,9 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
> if ( (count == 0) && !cpu_has_smep )
> *ebx &= ~cpufeat_mask(X86_FEATURE_SMEP);
>
> + if ( (count == 0) && !cpu_has_smap )
> + *ebx &= ~cpufeat_mask(X86_FEATURE_SMAP);
> +
> /* Don't expose MPX to hvm when VMX support is not available */
> if ( (count == 0) &&
> (!(vmx_vmexit_control & VM_EXIT_CLEAR_BNDCFGS) ||
> diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
> index 70460b6..1d5f1fc 100644
> --- a/xen/arch/x86/mm/guest_walk.c
> +++ b/xen/arch/x86/mm/guest_walk.c
> @@ -29,6 +29,7 @@
> #include <xen/sched.h>
> #include <asm/page.h>
> #include <asm/guest_pt.h>
> +#include <asm/hvm/vmx/vmx.h>
>
>
> /* Flags that are needed in a pagetable entry, with the sense of NX inverted */
> @@ -144,14 +145,18 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
> guest_l4e_t *l4p;
> #endif
> uint32_t gflags, mflags, iflags, rc = 0;
> - int smep;
> + int smep, smap;
> bool_t pse1G = 0, pse2M = 0;
> + unsigned long sel = 0;
> + uint64_t eflags = guest_cpu_user_regs()->eflags;
> p2m_query_t qt = P2M_ALLOC | P2M_UNSHARE;
>
> perfc_incr(guest_walk);
> memset(gw, 0, sizeof(*gw));
> gw->va = va;
>
> + __vmread(GUEST_CS_SELECTOR, &sel);
> +
> /* Mandatory bits that must be set in every entry. We invert NX and
> * the invalid bits, to calculate as if there were an "X" bit that
> * allowed access. We will accumulate, in rc, the set of flags that
> @@ -165,7 +170,21 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
> * whole walk as if it were a user-mode one and then invert the answer. */
> smep = (is_hvm_vcpu(v) && hvm_smep_enabled(v)
> && (pfec & PFEC_insn_fetch) && !(pfec & PFEC_user_mode) );
> - if ( smep )
> +
> + /*
> + * SMAP: kernel-mode data accesses from user-mode mappings should fault
> + * A fault is considered as a SMAP violation if the following
> + * conditions come ture:
> + * - X86_CR4_SMAP is set in CR4
> + * - An user page is accessed
> + * - CPL = 3 or X86_EFLAGS_AC clear set)
"X86_EFLAGS_AC clear set" ? What do you mean by this?
~Andrew
> + * - Page fault in kernel mode
> + */
> + smap = ( is_hvm_vcpu(v) && hvm_smap_enabled(v)
> + && !(!((sel & 3) == 3) && (eflags & X86_EFLAGS_AC))
> + && !(pfec & PFEC_user_mode) );
> +
> + if ( smep || smap )
> mflags |= _PAGE_USER;
>
> #if GUEST_PAGING_LEVELS >= 3 /* PAE or 64... */
> @@ -338,8 +357,8 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
> #if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
> set_ad:
> #endif
> - /* Now re-invert the user-mode requirement for SMEP. */
> - if ( smep )
> + /* Now re-invert the user-mode requirement for SMEP and SMAP */
> + if ( smep || smap )
> rc ^= _PAGE_USER;
>
> /* Go back and set accessed and dirty bits only if the walk was a
> diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
> index dcc3483..b703b93 100644
> --- a/xen/include/asm-x86/hvm/hvm.h
> +++ b/xen/include/asm-x86/hvm/hvm.h
> @@ -257,6 +257,8 @@ int hvm_girq_dest_2_vcpu_id(struct domain *d, uint8_t dest, uint8_t dest_mode);
> (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PAE))
> #define hvm_smep_enabled(v) \
> (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_SMEP))
> +#define hvm_smap_enabled(v) \
> + (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_SMAP))
> #define hvm_nx_enabled(v) \
> (!!((v)->arch.hvm_vcpu.guest_efer & EFER_NX))
>
> @@ -363,6 +365,16 @@ static inline int hvm_event_pending(struct vcpu *v)
> #define HVM_CR4_HOST_MASK (mmu_cr4_features & \
> (X86_CR4_VMXE | X86_CR4_PAE | X86_CR4_MCE))
>
> +static inline bool_t hvm_cpuid_has_smap(void)
> +{
> + unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
> + unsigned int leaf = 0x7;
> +
> + hvm_cpuid(leaf, &eax, &ebx, &ecx, &edx);
> +
> + return !!(ebx & cpufeat_mask(X86_FEATURE_SMAP));
> +}
> +
> /* These bits in CR4 cannot be set by the guest. */
> #define HVM_CR4_GUEST_RESERVED_BITS(_v) \
> (~((unsigned long) \
> @@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu *v)
> X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
> X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
> (cpu_has_smep ? X86_CR4_SMEP : 0) | \
> + (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
> (cpu_has_fsgsbase ? X86_CR4_FSGSBASE : 0) | \
> ((nestedhvm_enabled((_v)->domain) && cpu_has_vmx)\
> ? X86_CR4_VMXE : 0) | \
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
@ 2014-04-15 13:02 Feng Wu
2014-04-15 9:25 ` Jan Beulich
2014-04-15 10:36 ` Andrew Cooper
0 siblings, 2 replies; 8+ messages in thread
From: Feng Wu @ 2014-04-15 13:02 UTC (permalink / raw)
To: JBeulich, Ian.Campbell, xen-devel; +Cc: Feng Wu, eddie.dong, jun.nakajima
Intel new CPU supports SMAP (Supervisor Mode Access Prevention).
SMAP prevents supervisor-mode accesses to any linear address with
a valid translation for which the U/S flag (bit 2) is 1 in every
paging-structure entry controlling the translation for the linear
address.
This patch enable SMAP for HVM geust.
Signed-off-by: Feng Wu <feng.wu@intel.com>
---
xen/arch/x86/hvm/hvm.c | 3 +++
xen/arch/x86/mm/guest_walk.c | 27 +++++++++++++++++++++++----
xen/include/asm-x86/hvm/hvm.h | 13 +++++++++++++
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index b0da8e7..b52476d 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3036,6 +3036,9 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
if ( (count == 0) && !cpu_has_smep )
*ebx &= ~cpufeat_mask(X86_FEATURE_SMEP);
+ if ( (count == 0) && !cpu_has_smap )
+ *ebx &= ~cpufeat_mask(X86_FEATURE_SMAP);
+
/* Don't expose MPX to hvm when VMX support is not available */
if ( (count == 0) &&
(!(vmx_vmexit_control & VM_EXIT_CLEAR_BNDCFGS) ||
diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
index 70460b6..1d5f1fc 100644
--- a/xen/arch/x86/mm/guest_walk.c
+++ b/xen/arch/x86/mm/guest_walk.c
@@ -29,6 +29,7 @@
#include <xen/sched.h>
#include <asm/page.h>
#include <asm/guest_pt.h>
+#include <asm/hvm/vmx/vmx.h>
/* Flags that are needed in a pagetable entry, with the sense of NX inverted */
@@ -144,14 +145,18 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
guest_l4e_t *l4p;
#endif
uint32_t gflags, mflags, iflags, rc = 0;
- int smep;
+ int smep, smap;
bool_t pse1G = 0, pse2M = 0;
+ unsigned long sel = 0;
+ uint64_t eflags = guest_cpu_user_regs()->eflags;
p2m_query_t qt = P2M_ALLOC | P2M_UNSHARE;
perfc_incr(guest_walk);
memset(gw, 0, sizeof(*gw));
gw->va = va;
+ __vmread(GUEST_CS_SELECTOR, &sel);
+
/* Mandatory bits that must be set in every entry. We invert NX and
* the invalid bits, to calculate as if there were an "X" bit that
* allowed access. We will accumulate, in rc, the set of flags that
@@ -165,7 +170,21 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
* whole walk as if it were a user-mode one and then invert the answer. */
smep = (is_hvm_vcpu(v) && hvm_smep_enabled(v)
&& (pfec & PFEC_insn_fetch) && !(pfec & PFEC_user_mode) );
- if ( smep )
+
+ /*
+ * SMAP: kernel-mode data accesses from user-mode mappings should fault
+ * A fault is considered as a SMAP violation if the following
+ * conditions come ture:
+ * - X86_CR4_SMAP is set in CR4
+ * - An user page is accessed
+ * - CPL = 3 or X86_EFLAGS_AC clear set)
+ * - Page fault in kernel mode
+ */
+ smap = ( is_hvm_vcpu(v) && hvm_smap_enabled(v)
+ && !(!((sel & 3) == 3) && (eflags & X86_EFLAGS_AC))
+ && !(pfec & PFEC_user_mode) );
+
+ if ( smep || smap )
mflags |= _PAGE_USER;
#if GUEST_PAGING_LEVELS >= 3 /* PAE or 64... */
@@ -338,8 +357,8 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
#if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
set_ad:
#endif
- /* Now re-invert the user-mode requirement for SMEP. */
- if ( smep )
+ /* Now re-invert the user-mode requirement for SMEP and SMAP */
+ if ( smep || smap )
rc ^= _PAGE_USER;
/* Go back and set accessed and dirty bits only if the walk was a
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index dcc3483..b703b93 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -257,6 +257,8 @@ int hvm_girq_dest_2_vcpu_id(struct domain *d, uint8_t dest, uint8_t dest_mode);
(hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PAE))
#define hvm_smep_enabled(v) \
(hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_SMEP))
+#define hvm_smap_enabled(v) \
+ (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] & X86_CR4_SMAP))
#define hvm_nx_enabled(v) \
(!!((v)->arch.hvm_vcpu.guest_efer & EFER_NX))
@@ -363,6 +365,16 @@ static inline int hvm_event_pending(struct vcpu *v)
#define HVM_CR4_HOST_MASK (mmu_cr4_features & \
(X86_CR4_VMXE | X86_CR4_PAE | X86_CR4_MCE))
+static inline bool_t hvm_cpuid_has_smap(void)
+{
+ unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
+ unsigned int leaf = 0x7;
+
+ hvm_cpuid(leaf, &eax, &ebx, &ecx, &edx);
+
+ return !!(ebx & cpufeat_mask(X86_FEATURE_SMAP));
+}
+
/* These bits in CR4 cannot be set by the guest. */
#define HVM_CR4_GUEST_RESERVED_BITS(_v) \
(~((unsigned long) \
@@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu *v)
X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
(cpu_has_smep ? X86_CR4_SMEP : 0) | \
+ (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
(cpu_has_fsgsbase ? X86_CR4_FSGSBASE : 0) | \
((nestedhvm_enabled((_v)->domain) && cpu_has_vmx)\
? X86_CR4_VMXE : 0) | \
--
1.8.3.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
2014-04-15 9:25 ` Jan Beulich
@ 2014-04-16 1:49 ` Wu, Feng
2014-04-16 8:47 ` Jan Beulich
0 siblings, 1 reply; 8+ messages in thread
From: Wu, Feng @ 2014-04-16 1:49 UTC (permalink / raw)
To: Jan Beulich
Cc: Dong, Eddie, Ian.Campbell@citrix.com, Nakajima, Jun,
xen-devel@lists.xen.org
> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Tuesday, April 15, 2014 5:26 PM
> To: Wu, Feng
> Cc: Ian.Campbell@citrix.com; Dong, Eddie; Nakajima, Jun;
> xen-devel@lists.xen.org
> Subject: Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
>
> >>> On 15.04.14 at 15:02, <feng.wu@intel.com> wrote:
> > --- a/xen/arch/x86/mm/guest_walk.c
> > +++ b/xen/arch/x86/mm/guest_walk.c
> > @@ -29,6 +29,7 @@
> > #include <xen/sched.h>
> > #include <asm/page.h>
> > #include <asm/guest_pt.h>
> > +#include <asm/hvm/vmx/vmx.h>
> >
> >
> > /* Flags that are needed in a pagetable entry, with the sense of NX inverted
> */
> > @@ -144,14 +145,18 @@ guest_walk_tables(struct vcpu *v, struct
> p2m_domain *p2m,
> > guest_l4e_t *l4p;
> > #endif
> > uint32_t gflags, mflags, iflags, rc = 0;
> > - int smep;
> > + int smep, smap;
>
> These want to be bool_t I suppose.
>
> > bool_t pse1G = 0, pse2M = 0;
> > + unsigned long sel = 0;
> > + uint64_t eflags = guest_cpu_user_regs()->eflags;
> > p2m_query_t qt = P2M_ALLOC | P2M_UNSHARE;
> >
> > perfc_incr(guest_walk);
> > memset(gw, 0, sizeof(*gw));
> > gw->va = va;
> >
> > + __vmread(GUEST_CS_SELECTOR, &sel);
>
> You're in common code here - please use the proper HVM
> abstraction.
>
> > @@ -165,7 +170,21 @@ guest_walk_tables(struct vcpu *v, struct
> p2m_domain *p2m,
> > * whole walk as if it were a user-mode one and then invert the
> answer. */
> > smep = (is_hvm_vcpu(v) && hvm_smep_enabled(v)
> > && (pfec & PFEC_insn_fetch) && !(pfec &
> PFEC_user_mode) );
> > - if ( smep )
> > +
> > + /*
> > + * SMAP: kernel-mode data accesses from user-mode mappings should
> fault
> > + * A fault is considered as a SMAP violation if the following
> > + * conditions come ture:
>
> "true"
>
> > + * - X86_CR4_SMAP is set in CR4
> > + * - An user page is accessed
>
> "A user page ..." afaik.
>
> > + * - CPL = 3 or X86_EFLAGS_AC clear set)
>
> Stray closing parenthesis.
>
> > + * - Page fault in kernel mode
> > + */
> > + smap = ( is_hvm_vcpu(v) && hvm_smap_enabled(v)
> > + && !(!((sel & 3) == 3) && (eflags & X86_EFLAGS_AC))
>
> !( == ) is better written as ( != ) or, as done elsewhere, ( < ).
>
> > + && !(pfec & PFEC_user_mode) );
> > +
> > + if ( smep || smap )
>
> Again, please fold these are far as possible (is_hvm_vcpu() and
> the PFEC_user_mode are common and hence should be done just
> once.
>
> > @@ -363,6 +365,16 @@ static inline int hvm_event_pending(struct vcpu *v)
> > #define HVM_CR4_HOST_MASK (mmu_cr4_features & \
> > (X86_CR4_VMXE | X86_CR4_PAE | X86_CR4_MCE))
> >
> > +static inline bool_t hvm_cpuid_has_smap(void)
> > +{
> > + unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
> > + unsigned int leaf = 0x7;
> > +
> > + hvm_cpuid(leaf, &eax, &ebx, &ecx, &edx);
>
> Please pass NULL for all outputs you don't need.
>
> > @@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu *v)
> > X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
> > X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
> > (cpu_has_smep ? X86_CR4_SMEP : 0) | \
> > + (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
>
> What's the reason for the asymmetry with SMEP here? Also, did you
> verify that v == current in all call paths? And even if you did, passing
> v into the function and adding a respective ASSERT() would seem
> rather desirable.
My original thought is that "cpu_has_smap" reflects whether the host cpu has
SMAP feature, however, here we need to check whether the VCPU of the hvm
has this feature, so I used hvm_cpuid_has_smap() instead. But I thought about
this logic again yesterday, seems using "cpu_has_smap" here is okay, since we
always expose the SMAP feature to HVM guest if it exists on the host cpu. So
I will change this to align with smep.
>
> Jan
Thanks,
Feng
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
2014-04-15 10:36 ` Andrew Cooper
@ 2014-04-16 1:51 ` Wu, Feng
0 siblings, 0 replies; 8+ messages in thread
From: Wu, Feng @ 2014-04-16 1:51 UTC (permalink / raw)
To: Andrew Cooper
Cc: Nakajima, Jun, Dong, Eddie, Ian.Campbell@citrix.com,
JBeulich@suse.com, xen-devel@lists.xen.org
> -----Original Message-----
> From: Andrew Cooper [mailto:andrew.cooper3@citrix.com]
> Sent: Tuesday, April 15, 2014 6:37 PM
> To: Wu, Feng
> Cc: JBeulich@suse.com; Ian.Campbell@citrix.com; xen-devel@lists.xen.org;
> Dong, Eddie; Nakajima, Jun
> Subject: Re: [Xen-devel] [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM
> guest
>
> On 15/04/14 14:02, Feng Wu wrote:
> > Intel new CPU supports SMAP (Supervisor Mode Access Prevention).
> > SMAP prevents supervisor-mode accesses to any linear address with
> > a valid translation for which the U/S flag (bit 2) is 1 in every
> > paging-structure entry controlling the translation for the linear
> > address.
> >
> > This patch enable SMAP for HVM geust.
> >
> > Signed-off-by: Feng Wu <feng.wu@intel.com>
> > ---
> > xen/arch/x86/hvm/hvm.c | 3 +++
> > xen/arch/x86/mm/guest_walk.c | 27 +++++++++++++++++++++++----
> > xen/include/asm-x86/hvm/hvm.h | 13 +++++++++++++
> > 3 files changed, 39 insertions(+), 4 deletions(-)
> >
> > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> > index b0da8e7..b52476d 100644
> > --- a/xen/arch/x86/hvm/hvm.c
> > +++ b/xen/arch/x86/hvm/hvm.c
> > @@ -3036,6 +3036,9 @@ void hvm_cpuid(unsigned int input, unsigned int
> *eax, unsigned int *ebx,
> > if ( (count == 0) && !cpu_has_smep )
> > *ebx &= ~cpufeat_mask(X86_FEATURE_SMEP);
> >
> > + if ( (count == 0) && !cpu_has_smap )
> > + *ebx &= ~cpufeat_mask(X86_FEATURE_SMAP);
> > +
> > /* Don't expose MPX to hvm when VMX support is not available
> */
> > if ( (count == 0) &&
> > (!(vmx_vmexit_control & VM_EXIT_CLEAR_BNDCFGS) ||
> > diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
> > index 70460b6..1d5f1fc 100644
> > --- a/xen/arch/x86/mm/guest_walk.c
> > +++ b/xen/arch/x86/mm/guest_walk.c
> > @@ -29,6 +29,7 @@
> > #include <xen/sched.h>
> > #include <asm/page.h>
> > #include <asm/guest_pt.h>
> > +#include <asm/hvm/vmx/vmx.h>
> >
> >
> > /* Flags that are needed in a pagetable entry, with the sense of NX inverted
> */
> > @@ -144,14 +145,18 @@ guest_walk_tables(struct vcpu *v, struct
> p2m_domain *p2m,
> > guest_l4e_t *l4p;
> > #endif
> > uint32_t gflags, mflags, iflags, rc = 0;
> > - int smep;
> > + int smep, smap;
> > bool_t pse1G = 0, pse2M = 0;
> > + unsigned long sel = 0;
> > + uint64_t eflags = guest_cpu_user_regs()->eflags;
> > p2m_query_t qt = P2M_ALLOC | P2M_UNSHARE;
> >
> > perfc_incr(guest_walk);
> > memset(gw, 0, sizeof(*gw));
> > gw->va = va;
> >
> > + __vmread(GUEST_CS_SELECTOR, &sel);
> > +
> > /* Mandatory bits that must be set in every entry. We invert NX and
> > * the invalid bits, to calculate as if there were an "X" bit that
> > * allowed access. We will accumulate, in rc, the set of flags that
> > @@ -165,7 +170,21 @@ guest_walk_tables(struct vcpu *v, struct
> p2m_domain *p2m,
> > * whole walk as if it were a user-mode one and then invert the
> answer. */
> > smep = (is_hvm_vcpu(v) && hvm_smep_enabled(v)
> > && (pfec & PFEC_insn_fetch) && !(pfec &
> PFEC_user_mode) );
> > - if ( smep )
> > +
> > + /*
> > + * SMAP: kernel-mode data accesses from user-mode mappings should
> fault
> > + * A fault is considered as a SMAP violation if the following
> > + * conditions come ture:
> > + * - X86_CR4_SMAP is set in CR4
> > + * - An user page is accessed
> > + * - CPL = 3 or X86_EFLAGS_AC clear set)
>
> "X86_EFLAGS_AC clear set" ? What do you mean by this?
>
> ~Andrew
It should be "CPL = 3 or X86_EFLAGS_AC is clear", sorry for this typo.
>
> > + * - Page fault in kernel mode
> > + */
> > + smap = ( is_hvm_vcpu(v) && hvm_smap_enabled(v)
> > + && !(!((sel & 3) == 3) && (eflags & X86_EFLAGS_AC))
> > + && !(pfec & PFEC_user_mode) );
> > +
> > + if ( smep || smap )
> > mflags |= _PAGE_USER;
> >
> > #if GUEST_PAGING_LEVELS >= 3 /* PAE or 64... */
> > @@ -338,8 +357,8 @@ guest_walk_tables(struct vcpu *v, struct
> p2m_domain *p2m,
> > #if GUEST_PAGING_LEVELS >= 4 /* 64-bit only... */
> > set_ad:
> > #endif
> > - /* Now re-invert the user-mode requirement for SMEP. */
> > - if ( smep )
> > + /* Now re-invert the user-mode requirement for SMEP and SMAP */
> > + if ( smep || smap )
> > rc ^= _PAGE_USER;
> >
> > /* Go back and set accessed and dirty bits only if the walk was a
> > diff --git a/xen/include/asm-x86/hvm/hvm.h
> b/xen/include/asm-x86/hvm/hvm.h
> > index dcc3483..b703b93 100644
> > --- a/xen/include/asm-x86/hvm/hvm.h
> > +++ b/xen/include/asm-x86/hvm/hvm.h
> > @@ -257,6 +257,8 @@ int hvm_girq_dest_2_vcpu_id(struct domain *d,
> uint8_t dest, uint8_t dest_mode);
> > (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] &
> X86_CR4_PAE))
> > #define hvm_smep_enabled(v) \
> > (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] &
> X86_CR4_SMEP))
> > +#define hvm_smap_enabled(v) \
> > + (hvm_paging_enabled(v) && ((v)->arch.hvm_vcpu.guest_cr[4] &
> X86_CR4_SMAP))
> > #define hvm_nx_enabled(v) \
> > (!!((v)->arch.hvm_vcpu.guest_efer & EFER_NX))
> >
> > @@ -363,6 +365,16 @@ static inline int hvm_event_pending(struct vcpu *v)
> > #define HVM_CR4_HOST_MASK (mmu_cr4_features & \
> > (X86_CR4_VMXE | X86_CR4_PAE | X86_CR4_MCE))
> >
> > +static inline bool_t hvm_cpuid_has_smap(void)
> > +{
> > + unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
> > + unsigned int leaf = 0x7;
> > +
> > + hvm_cpuid(leaf, &eax, &ebx, &ecx, &edx);
> > +
> > + return !!(ebx & cpufeat_mask(X86_FEATURE_SMAP));
> > +}
> > +
> > /* These bits in CR4 cannot be set by the guest. */
> > #define HVM_CR4_GUEST_RESERVED_BITS(_v) \
> > (~((unsigned long) \
> > @@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu *v)
> > X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
> > X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
> > (cpu_has_smep ? X86_CR4_SMEP : 0) | \
> > + (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
> > (cpu_has_fsgsbase ? X86_CR4_FSGSBASE : 0) | \
> > ((nestedhvm_enabled((_v)->domain) && cpu_has_vmx)\
> > ? X86_CR4_VMXE : 0) | \
Thanks,
Feng
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
2014-04-16 1:49 ` Wu, Feng
@ 2014-04-16 8:47 ` Jan Beulich
2014-04-16 8:54 ` Wu, Feng
0 siblings, 1 reply; 8+ messages in thread
From: Jan Beulich @ 2014-04-16 8:47 UTC (permalink / raw)
To: Feng Wu
Cc: Eddie Dong, Ian.Campbell@citrix.com, Jun Nakajima,
xen-devel@lists.xen.org
>>> On 16.04.14 at 03:49, <feng.wu@intel.com> wrote:
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> >>> On 15.04.14 at 15:02, <feng.wu@intel.com> wrote:
>> > @@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu *v)
>> > X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
>> > X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
>> > (cpu_has_smep ? X86_CR4_SMEP : 0) | \
>> > + (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
>>
>> What's the reason for the asymmetry with SMEP here? Also, did you
>> verify that v == current in all call paths? And even if you did, passing
>> v into the function and adding a respective ASSERT() would seem
>> rather desirable.
>
> My original thought is that "cpu_has_smap" reflects whether the host cpu has
> SMAP feature, however, here we need to check whether the VCPU of the hvm
> has this feature, so I used hvm_cpuid_has_smap() instead. But I thought
> about
> this logic again yesterday, seems using "cpu_has_smap" here is okay, since
> we
> always expose the SMAP feature to HVM guest if it exists on the host cpu. So
> I will change this to align with smep.
Please indeed do so initially, even if your argumentation is slightly
wrong: Via CPUID masking the guest may not see the SMEP and/or
SMAP features, and hence cpu_has_sm[ea]p isn't generally the
correct qualifier. So we'd need a fixup patch on top (or, alternatively
one preceding the SMAP additions, correcting the SMEP aspect here,
in which case then your change could remain as is).
Jan
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
2014-04-16 8:47 ` Jan Beulich
@ 2014-04-16 8:54 ` Wu, Feng
2014-04-16 8:57 ` Jan Beulich
0 siblings, 1 reply; 8+ messages in thread
From: Wu, Feng @ 2014-04-16 8:54 UTC (permalink / raw)
To: Jan Beulich
Cc: Dong, Eddie, Ian.Campbell@citrix.com, Nakajima, Jun,
xen-devel@lists.xen.org
> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: Wednesday, April 16, 2014 4:47 PM
> To: Wu, Feng
> Cc: Ian.Campbell@citrix.com; Dong, Eddie; Nakajima, Jun;
> xen-devel@lists.xen.org
> Subject: RE: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
>
> >>> On 16.04.14 at 03:49, <feng.wu@intel.com> wrote:
> >> From: Jan Beulich [mailto:JBeulich@suse.com]
> >> >>> On 15.04.14 at 15:02, <feng.wu@intel.com> wrote:
> >> > @@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu
> *v)
> >> > X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
> >> > X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
> >> > (cpu_has_smep ? X86_CR4_SMEP : 0) | \
> >> > + (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
> >>
> >> What's the reason for the asymmetry with SMEP here? Also, did you
> >> verify that v == current in all call paths? And even if you did, passing
> >> v into the function and adding a respective ASSERT() would seem
> >> rather desirable.
> >
> > My original thought is that "cpu_has_smap" reflects whether the host cpu
> has
> > SMAP feature, however, here we need to check whether the VCPU of the hvm
> > has this feature, so I used hvm_cpuid_has_smap() instead. But I thought
> > about
> > this logic again yesterday, seems using "cpu_has_smap" here is okay, since
> > we
> > always expose the SMAP feature to HVM guest if it exists on the host cpu. So
> > I will change this to align with smep.
>
> Please indeed do so initially, even if your argumentation is slightly
> wrong: Via CPUID masking the guest may not see the SMEP and/or
> SMAP features, and hence cpu_has_sm[ea]p isn't generally the
> correct qualifier. So we'd need a fixup patch on top (or, alternatively
> one preceding the SMAP additions, correcting the SMEP aspect here,
> in which case then your change could remain as is).
>
So, I need send out a patch to fix this SMEP issue, then make the SMAP patch set
based on it, right?
> Jan
Thanks,
Feng
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
2014-04-16 8:54 ` Wu, Feng
@ 2014-04-16 8:57 ` Jan Beulich
0 siblings, 0 replies; 8+ messages in thread
From: Jan Beulich @ 2014-04-16 8:57 UTC (permalink / raw)
To: Feng Wu
Cc: Eddie Dong, Ian.Campbell@citrix.com, Jun Nakajima,
xen-devel@lists.xen.org
>>> On 16.04.14 at 10:54, <feng.wu@intel.com> wrote:
>
>> -----Original Message-----
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> Sent: Wednesday, April 16, 2014 4:47 PM
>> To: Wu, Feng
>> Cc: Ian.Campbell@citrix.com; Dong, Eddie; Nakajima, Jun;
>> xen-devel@lists.xen.org
>> Subject: RE: [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest
>>
>> >>> On 16.04.14 at 03:49, <feng.wu@intel.com> wrote:
>> >> From: Jan Beulich [mailto:JBeulich@suse.com]
>> >> >>> On 15.04.14 at 15:02, <feng.wu@intel.com> wrote:
>> >> > @@ -371,6 +383,7 @@ static inline int hvm_event_pending(struct vcpu
>> *v)
>> >> > X86_CR4_MCE | X86_CR4_PGE | X86_CR4_PCE | \
>> >> > X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT | \
>> >> > (cpu_has_smep ? X86_CR4_SMEP : 0) | \
>> >> > + (hvm_cpuid_has_smap() ? X86_CR4_SMAP : 0) | \
>> >>
>> >> What's the reason for the asymmetry with SMEP here? Also, did you
>> >> verify that v == current in all call paths? And even if you did, passing
>> >> v into the function and adding a respective ASSERT() would seem
>> >> rather desirable.
>> >
>> > My original thought is that "cpu_has_smap" reflects whether the host cpu
>> has
>> > SMAP feature, however, here we need to check whether the VCPU of the hvm
>> > has this feature, so I used hvm_cpuid_has_smap() instead. But I thought
>> > about
>> > this logic again yesterday, seems using "cpu_has_smap" here is okay, since
>> > we
>> > always expose the SMAP feature to HVM guest if it exists on the host cpu.
> So
>> > I will change this to align with smep.
>>
>> Please indeed do so initially, even if your argumentation is slightly
>> wrong: Via CPUID masking the guest may not see the SMEP and/or
>> SMAP features, and hence cpu_has_sm[ea]p isn't generally the
>> correct qualifier. So we'd need a fixup patch on top (or, alternatively
>> one preceding the SMAP additions, correcting the SMEP aspect here,
>> in which case then your change could remain as is).
>>
>
> So, I need send out a patch to fix this SMEP issue, then make the SMAP patch
> set
> based on it, right?
That would be the ideal flow, yes.
Jan
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-04-16 8:57 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-15 13:02 [PATCH v1 4/6] x86/hvm: Add SMAP support to HVM guest Feng Wu
2014-04-15 9:25 ` Jan Beulich
2014-04-16 1:49 ` Wu, Feng
2014-04-16 8:47 ` Jan Beulich
2014-04-16 8:54 ` Wu, Feng
2014-04-16 8:57 ` Jan Beulich
2014-04-15 10:36 ` Andrew Cooper
2014-04-16 1:51 ` Wu, Feng
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.