All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: xen-devel <xen-devel@lists.xenproject.org>, Keir Fraser <keir@xen.org>
Subject: Re: [PATCH 3/4] x86: use {rd, wr}{fs, gs}base when available
Date: Thu, 10 Oct 2013 15:15:10 +0100	[thread overview]
Message-ID: <5256B66E.50906@citrix.com> (raw)
In-Reply-To: <5256CDCB02000078000FA3EA@nat28.tlf.novell.com>


[-- Attachment #1.1: Type: text/plain, Size: 7633 bytes --]

On 10/10/13 14:54, Jan Beulich wrote:
> ... as being intended to be faster than MSR reads/writes.
>
> In the case of emulate_privileged_op() also use these in favor of the
> cached (but possibly stale) addresses from arch.pv_vcpu. This allows
> entirely removing the code that was the subject of XSA-67.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

>
> --- a/xen/arch/x86/Rules.mk
> +++ b/xen/arch/x86/Rules.mk
> @@ -31,6 +31,7 @@ $(call cc-options-add,CFLAGS,CC,$(EMBEDD
>  $(call cc-option-add,CFLAGS,CC,-Wnested-externs)
>  $(call as-insn-check,CFLAGS,CC,"vmcall",-DHAVE_GAS_VMX)
>  $(call as-insn-check,CFLAGS,CC,"invept (%rax)$$(comma)%rax",-DHAVE_GAS_EPT)
> +$(call as-insn-check,CFLAGS,CC,"rdfsbase %rax",-DHAVE_GAS_FSGSBASE)
>  
>  ifeq ($(supervisor_mode_kernel),y)
>  CFLAGS += -DCONFIG_X86_SUPERVISOR_MODE_KERNEL=1
> --- a/xen/arch/x86/acpi/suspend.c
> +++ b/xen/arch/x86/acpi/suspend.c
> @@ -27,8 +27,8 @@ void save_rest_processor_state(void)
>      asm volatile (
>          "movw %%ds,(%0); movw %%es,2(%0); movw %%fs,4(%0); movw %%gs,6(%0)"
>          : : "r" (saved_segs) : "memory" );
> -    rdmsrl(MSR_FS_BASE, saved_fs_base);
> -    rdmsrl(MSR_GS_BASE, saved_gs_base);
> +    saved_fs_base = rdfsbase();
> +    saved_gs_base = rdgsbase();
>      rdmsrl(MSR_SHADOW_GS_BASE, saved_kernel_gs_base);
>      rdmsrl(MSR_CSTAR, saved_cstar);
>      rdmsrl(MSR_LSTAR, saved_lstar);
> @@ -56,8 +56,8 @@ void restore_rest_processor_state(void)
>            X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_TF,
>            0U);
>  
> -    wrmsrl(MSR_FS_BASE, saved_fs_base);
> -    wrmsrl(MSR_GS_BASE, saved_gs_base);
> +    wrfsbase(saved_fs_base);
> +    wrgsbase(saved_gs_base);
>      wrmsrl(MSR_SHADOW_GS_BASE, saved_kernel_gs_base);
>  
>      if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -1092,7 +1092,7 @@ static void load_segments(struct vcpu *n
>      {
>          /* This can only be non-zero if selector is NULL. */
>          if ( n->arch.pv_vcpu.fs_base )
> -            wrmsrl(MSR_FS_BASE, n->arch.pv_vcpu.fs_base);
> +            wrfsbase(n->arch.pv_vcpu.fs_base);
>  
>          /* Most kernels have non-zero GS base, so don't bother testing. */
>          /* (This is also a serialising instruction, avoiding AMD erratum #88.) */
> @@ -1100,7 +1100,7 @@ static void load_segments(struct vcpu *n
>  
>          /* This can only be non-zero if selector is NULL. */
>          if ( n->arch.pv_vcpu.gs_base_user )
> -            wrmsrl(MSR_GS_BASE, n->arch.pv_vcpu.gs_base_user);
> +            wrgsbase(n->arch.pv_vcpu.gs_base_user);
>  
>          /* If in kernel mode then switch the GS bases around. */
>          if ( (n->arch.flags & TF_kernel_mode) )
> --- a/xen/arch/x86/setup.c
> +++ b/xen/arch/x86/setup.c
> @@ -1264,6 +1264,9 @@ void __init __start_xen(unsigned long mb
>      if ( cpu_has_smep )
>          set_in_cr4(X86_CR4_SMEP);
>  
> +    if ( cpu_has_fsgsbase )
> +        set_in_cr4(X86_CR4_FSGSBASE);
> +
>      local_irq_enable();
>  
>      pt_pci_init();
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -1985,28 +1985,18 @@ static int emulate_privileged_op(struct 
>          }
>          else
>          {
> -            if ( lm_ovr == lm_seg_none || data_sel < 4 )
> +            switch ( lm_ovr )
>              {
> -                switch ( lm_ovr )
> -                {
> -                case lm_seg_none:
> -                    data_base = 0UL;
> -                    break;
> -                case lm_seg_fs:
> -                    data_base = v->arch.pv_vcpu.fs_base;
> -                    break;
> -                case lm_seg_gs:
> -                    if ( guest_kernel_mode(v, regs) )
> -                        data_base = v->arch.pv_vcpu.gs_base_kernel;
> -                    else
> -                        data_base = v->arch.pv_vcpu.gs_base_user;
> -                    break;
> -                }
> +            default:
> +                data_base = 0UL;
> +                break;
> +            case lm_seg_fs:
> +                data_base = rdfsbase();
> +                break;
> +            case lm_seg_gs:
> +                data_base = rdgsbase();
> +                break;
>              }
> -            else if ( !read_descriptor(data_sel, v, regs,
> -                                       &data_base, &data_limit, &ar, 0) ||
> -                      !(ar & _SEGMENT_S) || !(ar & _SEGMENT_P) )
> -                goto fail;
>              data_limit = ~0UL;
>              ar = _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P;
>          }
> --- a/xen/include/asm-x86/domain.h
> +++ b/xen/include/asm-x86/domain.h
> @@ -457,12 +457,12 @@ unsigned long pv_guest_cr4_fixup(const s
>      (((v)->arch.pv_vcpu.ctrlreg[4]                          \
>        | (mmu_cr4_features                                   \
>           & (X86_CR4_PGE | X86_CR4_PSE | X86_CR4_SMEP |      \
> -            X86_CR4_OSXSAVE))                               \
> +            X86_CR4_OSXSAVE | X86_CR4_FSGSBASE))            \
>        | ((v)->domain->arch.vtsc ? X86_CR4_TSD : 0))         \
>       & ~X86_CR4_DE)
>  #define real_cr4_to_pv_guest_cr4(c)                         \
> -    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_TSD        \
> -             | X86_CR4_OSXSAVE | X86_CR4_SMEP))
> +    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_TSD |      \
> +             X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE))
>  
>  void domain_cpuid(struct domain *d,
>                    unsigned int  input,
> --- a/xen/include/asm-x86/msr.h
> +++ b/xen/include/asm-x86/msr.h
> @@ -9,6 +9,7 @@
>  #include <xen/percpu.h>
>  #include <xen/errno.h>
>  #include <asm/asm_defns.h>
> +#include <asm/cpufeature.h>
>  
>  #define rdmsr(msr,val1,val2) \
>       __asm__ __volatile__("rdmsr" \
> @@ -97,6 +98,61 @@ static inline int wrmsr_safe(unsigned in
>  			  : "=a" (low), "=d" (high) \
>  			  : "c" (counter))
>  
> +static inline unsigned long rdfsbase(void)
> +{
> +    unsigned long base;
> +
> +    if ( cpu_has_fsgsbase )
> +#ifdef HAVE_GAS_FSGSBASE
> +        asm volatile ( "rdfsbase %0" : "=r" (base) );
> +#else
> +        asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc0" : "=a" (base) );
> +#endif
> +    else
> +        rdmsrl(MSR_FS_BASE, base);
> +
> +    return base;
> +}
> +
> +static inline unsigned long rdgsbase(void)
> +{
> +    unsigned long base;
> +
> +    if ( cpu_has_fsgsbase )
> +#ifdef HAVE_GAS_FSGSBASE
> +        asm volatile ( "rdgsbase %0" : "=r" (base) );
> +#else
> +        asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc8" : "=a" (base) );
> +#endif
> +    else
> +        rdmsrl(MSR_GS_BASE, base);
> +
> +    return base;
> +}
> +
> +static inline void wrfsbase(unsigned long base)
> +{
> +    if ( cpu_has_fsgsbase )
> +#ifdef HAVE_GAS_FSGSBASE
> +        asm volatile ( "wrfsbase %0" :: "r" (base) );
> +#else
> +        asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd0" :: "a" (base) );
> +#endif
> +    else
> +        wrmsrl(MSR_FS_BASE, base);
> +}
> +
> +static inline void wrgsbase(unsigned long base)
> +{
> +    if ( cpu_has_fsgsbase )
> +#ifdef HAVE_GAS_FSGSBASE
> +        asm volatile ( "wrgsbase %0" :: "r" (base) );
> +#else
> +        asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xd8" :: "a" (base) );
> +#endif
> +    else
> +        wrmsrl(MSR_GS_BASE, base);
> +}
>  
>  DECLARE_PER_CPU(u64, efer);
>  u64 read_efer(void);
>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel


[-- Attachment #1.2: Type: text/html, Size: 8255 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

  reply	other threads:[~2013-10-10 14:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-10 13:49 [PATCH 0/4] x86: XSA-67 follow-up Jan Beulich
2013-10-10 13:53 ` [PATCH 1/4] x86: correct LDT checks Jan Beulich
2013-10-10 13:54 ` [PATCH 2/4] x86: add address validity check to guest_map_l1e() Jan Beulich
2013-10-10 13:57   ` Andrew Cooper
2013-10-10 13:54 ` [PATCH 3/4] x86: use {rd, wr}{fs, gs}base when available Jan Beulich
2013-10-10 14:15   ` Andrew Cooper [this message]
2013-10-10 13:55 ` [PATCH 4/4] x86: check for canonical address before doing page walks Jan Beulich
2013-10-10 14:01   ` Andrew Cooper
2013-10-10 14:10     ` Jan Beulich
2013-10-10 14:17       ` Andrew Cooper
2013-10-10 15:13 ` [PATCH 0/4] x86: XSA-67 follow-up Keir Fraser

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=5256B66E.50906@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=keir@xen.org \
    --cc=xen-devel@lists.xenproject.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 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.