xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Feng Wu <feng.wu@intel.com>, xen-devel@lists.xen.org
Cc: linux@eikelenboom.it, keir@xen.org, tim@xen.org, jbeulich@suse.com
Subject: Re: [PATCH 1/2] x86/hvm: Always do SMAP check when updating runstate_guest(v)
Date: Tue, 8 Jul 2014 11:04:32 +0100	[thread overview]
Message-ID: <53BBC230.7080705@citrix.com> (raw)
In-Reply-To: <1404775098-6083-2-git-send-email-feng.wu@intel.com>

On 08/07/14 00:18, Feng Wu wrote:
> In the current implementation, we honor the guest's CPL and AC
> to determain whether do the SMAP check or not for runstate_guest(v).
> However, this doesn't work. The VMCS feild is invalid when we try
> to get geust's SS by hvm_get_segment_register(), since the
> right VMCS has not beed loaded for the current VCPU.
>
> In this patch, we always do the SMAP check when updating
> runstate_guest(v) for the guest when SMAP is enabled by it.
>
> Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
> Signed-off-by: Feng Wu <feng.wu@intel.com>

Why can't the VMCS be reloaded in vmx_ctxt_switch_to() rather than
vmx_do_resume() ?  The problem is not with updating the runstate area
persay, but due to using guest_walk_tables() during a context switch
before the VMCS has been loaded.

> ---
>  xen/arch/x86/domain.c        | 15 ++++++++++++---
>  xen/arch/x86/mm/guest_walk.c | 41 ++++++++++++++++++++++++++++-------------
>  xen/include/asm-x86/domain.h | 15 ++++++++++++++-
>  3 files changed, 54 insertions(+), 17 deletions(-)
>
> diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
> index e896210..b0c8810 100644
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -1349,22 +1349,31 @@ static void paravirt_ctxt_switch_to(struct vcpu *v)
>  }
>  
>  /* Update per-VCPU guest runstate shared memory area (if registered). */
> -bool_t update_runstate_area(const struct vcpu *v)
> +bool_t update_runstate_area(struct vcpu *v)
>  {
> +    bool_t rc;
> +
>      if ( guest_handle_is_null(runstate_guest(v)) )
>          return 1;
>  
> +    v->arch.smap_check_policy = SMAP_CHECK_ENABLED;
> +
>      if ( has_32bit_shinfo(v->domain) )
>      {
>          struct compat_vcpu_runstate_info info;
>  
>          XLAT_vcpu_runstate_info(&info, &v->runstate);
>          __copy_to_guest(v->runstate_guest.compat, &info, 1);
> -        return 1;
> +        rc = 1;
> +        goto out;
>      }
>  
> -    return __copy_to_guest(runstate_guest(v), &v->runstate, 1) !=
> +    rc = __copy_to_guest(runstate_guest(v), &v->runstate, 1) !=
>             sizeof(v->runstate);
> +
> +out:
> +    v->arch.smap_check_policy = SMAP_CHECK_HONOR_CPL_AC;
> +    return rc;
>  }
>  
>  static void _update_runstate_area(struct vcpu *v)
> diff --git a/xen/arch/x86/mm/guest_walk.c b/xen/arch/x86/mm/guest_walk.c
> index bb38fda..1afa7fd 100644
> --- a/xen/arch/x86/mm/guest_walk.c
> +++ b/xen/arch/x86/mm/guest_walk.c
> @@ -164,25 +164,40 @@ guest_walk_tables(struct vcpu *v, struct p2m_domain *p2m,
>          struct segment_register seg;
>          const struct cpu_user_regs *regs = guest_cpu_user_regs();
>  
> -        hvm_get_segment_register(v, x86_seg_ss, &seg);
> -
>          /* SMEP: kernel-mode instruction fetches from user-mode mappings
>           * should fault.  Unlike NX or invalid bits, we're looking for _all_
>           * entries in the walk to have _PAGE_USER set, so we need to do the
>           * whole walk as if it were a user-mode one and then invert the answer. */
>          smep =  hvm_smep_enabled(v) && (pfec & PFEC_insn_fetch);
>  
> -        /*
> -         * SMAP: kernel-mode data accesses from user-mode mappings should fault
> -         * A fault is considered as a SMAP violation if the following
> -         * conditions come true:
> -         *   - X86_CR4_SMAP is set in CR4
> -         *   - A user page is accessed
> -         *   - CPL = 3 or X86_EFLAGS_AC is clear
> -         *   - Page fault in kernel mode
> -         */
> -        smap = hvm_smap_enabled(v) &&
> -               ((seg.attr.fields.dpl == 3) || !(regs->eflags & X86_EFLAGS_AC));
> +        switch ( v->arch.smap_check_policy )
> +        {
> +        case SMAP_CHECK_HONOR_CPL_AC:
> +            hvm_get_segment_register(v, x86_seg_ss, &seg);
> +
> +            /*
> +             * SMAP: kernel-mode data accesses from user-mode mappings
> +             * should fault.
> +             * A fault is considered as a SMAP violation if the following
> +             * conditions come true:
> +             *   - X86_CR4_SMAP is set in CR4
> +             *   - A user page is accessed
> +             *   - CPL = 3 or X86_EFLAGS_AC is clear
> +             *   - Page fault in kernel mode
> +             */
> +            smap = hvm_smap_enabled(v) &&
> +                   ((seg.attr.fields.dpl == 3) ||
> +                   !(regs->eflags & X86_EFLAGS_AC));
> +            break;
> +        case SMAP_CHECK_ENABLED:
> +            smap = hvm_smap_enabled(v);

Can you describe what behavioural change this will cause.  From my
understanding, for a guest which has enabled CR4.SMAP, it will
unconditionally cause an -EFAULT for runstate areas in user pagetables?

~Andrew

> +            break;
> +        case SMAP_CHECK_DISABLED:
> +            break;
> +        default:
> +            printk(XENLOG_INFO "Invalid SMAP check type!\n");
> +            break;
> +        }
>      }
>  
>      if ( smep || smap )
> diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
> index abf55fb..d7cac4f 100644
> --- a/xen/include/asm-x86/domain.h
> +++ b/xen/include/asm-x86/domain.h
> @@ -446,13 +446,26 @@ struct arch_vcpu
>  
>      /* A secondary copy of the vcpu time info. */
>      XEN_GUEST_HANDLE(vcpu_time_info_t) time_info_guest;
> +
> +    /*
> +     * The SMAP check policy when updating runstate_guest(v) and the
> +     * secondary system time.
> +     *     SMAP_CHECK_HONOR_CPL_AC - honor the guest's CPL and AC
> +     *     SMAP_CHECK_ENABLED      - enable the check
> +     *     SMAP_CHECK_DISABLED     - disable the check
> +     */
> +    uint8_t smap_check_policy;
>  } __cacheline_aligned;
>  
> +#define SMAP_CHECK_HONOR_CPL_AC  0
> +#define SMAP_CHECK_ENABLED       1
> +#define SMAP_CHECK_DISABLED      2
> +
>  /* Shorthands to improve code legibility. */
>  #define hvm_vmx         hvm_vcpu.u.vmx
>  #define hvm_svm         hvm_vcpu.u.svm
>  
> -bool_t update_runstate_area(const struct vcpu *);
> +bool_t update_runstate_area(struct vcpu *);
>  bool_t update_secondary_system_time(const struct vcpu *,
>                                      struct vcpu_time_info *);
>  

  reply	other threads:[~2014-07-08 10:04 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-07 23:18 [PATCH 0/2] x86/HVM: Properly handle SMAP check in certain cases Feng Wu
2014-07-07 23:18 ` [PATCH 1/2] x86/hvm: Always do SMAP check when updating runstate_guest(v) Feng Wu
2014-07-08 10:04   ` Andrew Cooper [this message]
2014-07-09  1:33     ` Wu, Feng
2014-07-23 12:10       ` Jan Beulich
2014-07-10 10:56   ` Tim Deegan
2014-07-23 12:11     ` Jan Beulich
2014-07-23 12:15       ` Tim Deegan
2014-07-07 23:18 ` [PATCH 2/2] x86/hvm: honor guest's option when updating secondary system time for guest Feng Wu
2014-07-08 10:08   ` Andrew Cooper
2014-07-09  1:39     ` Wu, Feng
2014-07-08 16:13   ` Konrad Rzeszutek Wilk
2014-07-09  1:52     ` Wu, Feng
2014-07-10 11:00   ` Tim Deegan
2014-07-23 12:16     ` Jan Beulich
2014-07-23 12:19   ` Jan Beulich
2014-07-25  4:30     ` Wu, Feng
2014-07-25  7:25       ` Jan Beulich
2014-07-25  7:33         ` Wu, Feng
2014-07-25  7:39           ` Jan Beulich
2014-07-25  8:03             ` Wu, Feng
2014-07-25  8:31               ` Jan Beulich
2014-07-25  8:35                 ` Wu, Feng
2014-07-25  8:52                 ` Andrew Cooper
2014-07-25  9:17                   ` Jan Beulich
2014-07-08  9:56 ` [PATCH 0/2] x86/HVM: Properly handle SMAP check in certain cases Sander Eikelenboom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53BBC230.7080705@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=feng.wu@intel.com \
    --cc=jbeulich@suse.com \
    --cc=keir@xen.org \
    --cc=linux@eikelenboom.it \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).