From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>,
xen-devel <xen-devel@lists.xenproject.org>,
Keir Fraser <keir@xen.org>
Subject: Re: [PATCH 1/3] x86: fix FS/GS base handling when using the fsgsbase feature
Date: Wed, 5 Feb 2014 15:50:59 +0000 [thread overview]
Message-ID: <52F25DE3.4070306@citrix.com> (raw)
In-Reply-To: <52F25E3F02000078001196E4@nat28.tlf.novell.com>
[-- Attachment #1.1: Type: text/plain, Size: 5463 bytes --]
On 05/02/14 14:52, Jan Beulich wrote:
> In that case, due to the respective instructions not being privileged,
> we can't rely on our in-memory data to always be correct: While the
> guest is running, it may change without us knowing about it. Therefore
> we need to
> - read the correct values from hardware during context switch out
> (save_segments())
> - read the correct values from hardware during RDMSR emulation
> - update in-memory values during guest mode change
> (toggle_guest_mode())
>
> For completeness/consistency, WRMSR emulation is also being switched
> to use wr[fg]sbase().
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>
> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -1251,6 +1251,15 @@ static void save_segments(struct vcpu *v
> regs->fs = read_segment_register(fs);
> regs->gs = read_segment_register(gs);
>
> + if ( cpu_has_fsgsbase && !is_pv_32bit_vcpu(v) )
> + {
> + v->arch.pv_vcpu.fs_base = __rdfsbase();
> + if ( v->arch.flags & TF_kernel_mode )
> + v->arch.pv_vcpu.gs_base_kernel = __rdgsbase();
> + else
> + v->arch.pv_vcpu.gs_base_user = __rdgsbase();
> + }
> +
> if ( regs->ds )
> dirty_segment_mask |= DIRTY_DS;
>
> --- a/xen/arch/x86/traps.c
> +++ b/xen/arch/x86/traps.c
> @@ -2382,15 +2382,13 @@ static int emulate_privileged_op(struct
> case MSR_FS_BASE:
> if ( is_pv_32on64_vcpu(v) )
> goto fail;
> - if ( wrmsr_safe(MSR_FS_BASE, msr_content) )
> - goto fail;
> + wrfsbase(msr_content);
> v->arch.pv_vcpu.fs_base = msr_content;
> break;
> case MSR_GS_BASE:
> if ( is_pv_32on64_vcpu(v) )
> goto fail;
> - if ( wrmsr_safe(MSR_GS_BASE, msr_content) )
> - goto fail;
> + wrgsbase(msr_content);
> v->arch.pv_vcpu.gs_base_kernel = msr_content;
> break;
> case MSR_SHADOW_GS_BASE:
> @@ -2535,15 +2533,14 @@ static int emulate_privileged_op(struct
> case MSR_FS_BASE:
> if ( is_pv_32on64_vcpu(v) )
> goto fail;
> - regs->eax = v->arch.pv_vcpu.fs_base & 0xFFFFFFFFUL;
> - regs->edx = v->arch.pv_vcpu.fs_base >> 32;
> - break;
> + val = cpu_has_fsgsbase ? __rdfsbase() : v->arch.pv_vcpu.fs_base;
> + goto rdmsr_writeback;
> case MSR_GS_BASE:
> if ( is_pv_32on64_vcpu(v) )
> goto fail;
> - regs->eax = v->arch.pv_vcpu.gs_base_kernel & 0xFFFFFFFFUL;
> - regs->edx = v->arch.pv_vcpu.gs_base_kernel >> 32;
> - break;
> + val = cpu_has_fsgsbase ? __rdgsbase()
> + : v->arch.pv_vcpu.gs_base_kernel;
> + goto rdmsr_writeback;
> case MSR_SHADOW_GS_BASE:
> if ( is_pv_32on64_vcpu(v) )
> goto fail;
> --- a/xen/arch/x86/x86_64/traps.c
> +++ b/xen/arch/x86/x86_64/traps.c
> @@ -257,6 +257,13 @@ void toggle_guest_mode(struct vcpu *v)
> {
> if ( is_pv_32bit_vcpu(v) )
> return;
> + if ( cpu_has_fsgsbase )
> + {
> + if ( v->arch.flags & TF_kernel_mode )
> + v->arch.pv_vcpu.gs_base_kernel = __rdgsbase();
> + else
> + v->arch.pv_vcpu.gs_base_user = __rdgsbase();
> + }
> v->arch.flags ^= TF_kernel_mode;
> asm volatile ( "swapgs" );
> update_cr3(v);
> --- a/xen/include/asm-x86/msr.h
> +++ b/xen/include/asm-x86/msr.h
> @@ -98,34 +98,52 @@ static inline int wrmsr_safe(unsigned in
> : "=a" (low), "=d" (high) \
> : "c" (counter))
>
> -static inline unsigned long rdfsbase(void)
> +static inline unsigned long __rdfsbase(void)
> {
> unsigned long base;
>
> - if ( cpu_has_fsgsbase )
> #ifdef HAVE_GAS_FSGSBASE
> - asm volatile ( "rdfsbase %0" : "=r" (base) );
> + asm volatile ( "rdfsbase %0" : "=r" (base) );
> #else
> - asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc0" : "=a" (base) );
> + 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)
> +static inline unsigned long __rdgsbase(void)
> {
> unsigned long base;
>
> - if ( cpu_has_fsgsbase )
> #ifdef HAVE_GAS_FSGSBASE
> - asm volatile ( "rdgsbase %0" : "=r" (base) );
> + asm volatile ( "rdgsbase %0" : "=r" (base) );
> #else
> - asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc8" : "=a" (base) );
> + asm volatile ( ".byte 0xf3, 0x48, 0x0f, 0xae, 0xc8" : "=a" (base) );
> #endif
> - else
> - rdmsrl(MSR_GS_BASE, base);
> +
> + return base;
> +}
> +
> +static inline unsigned long rdfsbase(void)
> +{
> + unsigned long base;
> +
> + if ( cpu_has_fsgsbase )
> + return __rdfsbase();
> +
> + rdmsrl(MSR_FS_BASE, base);
> +
> + return base;
> +}
> +
> +static inline unsigned long rdgsbase(void)
> +{
> + unsigned long base;
> +
> + if ( cpu_has_fsgsbase )
> + return __rdgsbase();
> +
> + rdmsrl(MSR_GS_BASE, base);
>
> return base;
> }
>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
[-- Attachment #1.2: Type: text/html, Size: 6180 bytes --]
[-- Attachment #2: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2014-02-05 15:51 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-05 14:48 [PATCH 0/3] guest context management adjustments Jan Beulich
2014-02-05 14:52 ` [PATCH 1/3] x86: fix FS/GS base handling when using the fsgsbase feature Jan Beulich
2014-02-05 15:50 ` Andrew Cooper [this message]
2014-02-05 14:54 ` [PATCH 2/3] domctl: also pause domain for extended context updates Jan Beulich
2014-02-05 15:05 ` Andrew Cooper
2014-02-05 14:54 ` [PATCH 3/3] domctl: pause vCPU for context reads Jan Beulich
2014-02-05 15:29 ` Andrew Cooper
2014-02-05 15:39 ` Jan Beulich
2014-02-05 15:43 ` Andrew Cooper
2014-02-05 14:55 ` [PATCH 0/3] guest context management adjustments Jan Beulich
2014-02-05 16:02 ` George Dunlap
2014-02-05 15:35 ` 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=52F25DE3.4070306@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=George.Dunlap@eu.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.