From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Andy Lutomirski <luto@kernel.org>
Cc: Gabriel Krisman Bertazi <krisman@collabora.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Thomas Gleixner <tglx@linutronix.de>,
Christoph Hellwig <hch@lst.de>, "H. Peter Anvin" <hpa@zytor.com>,
Borislav Petkov <bp@alien8.de>, Robert Richter <rric@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>, X86 ML <x86@kernel.org>,
LKML <linux-kernel@vger.kernel.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
kernel@collabora.com
Subject: Re: [PATCH v2 7/9] x86: Use current USER_CS to setup correct context on vmx entry
Date: Fri, 2 Oct 2020 15:40:06 -0700 [thread overview]
Message-ID: <20201002224005.GF24460@linux.intel.com> (raw)
In-Reply-To: <CALCETrW74MjC2-MRkRrp3uGOhapH_1zG5GCBkPsLFXs+jPXNOg@mail.gmail.com>
On Thu, Oct 01, 2020 at 02:52:32PM -0700, Andy Lutomirski wrote:
> On Thu, Oct 1, 2020 at 1:59 PM Gabriel Krisman Bertazi
> <krisman@collabora.com> wrote:
> >
> > vmx_prepare_switch_to_guest shouldn't use is_64bit_mm, which has a
> > very specific use in uprobes. Use the user_64bit_mode helper instead.
> > This reduces the usage of is_64bit_mm, which is awkward, since it relies
> > on the personality at load time, which is fine for uprobes, but doesn't
> > seem fine here.
> >
> > I tested this by running VMs with 64 and 32 bits payloads from 64/32
> > programs.
> >
> > Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com>
> > ---
> > arch/x86/kvm/vmx/vmx.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> > index 7b2a068f08c1..b5aafd9e5f5d 100644
> > --- a/arch/x86/kvm/vmx/vmx.c
> > +++ b/arch/x86/kvm/vmx/vmx.c
> > @@ -1172,7 +1172,7 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
> > savesegment(es, host_state->es_sel);
> >
> > gs_base = cpu_kernelmode_gs_base(cpu);
> > - if (likely(is_64bit_mm(current->mm))) {
> > + if (likely(user_64bit_mode(current_pt_regs()))) {
> > current_save_fsgs();
> > fs_sel = current->thread.fsindex;
> > gs_sel = current->thread.gsindex;
>
> I disagree with this one. This whole code path is nonsense. Can you
> just remove the condition entirely and use the 64-bit path
> unconditionally?
I finally came back to this one with fresh eyes. I've read through the code
a bajllion times and typed up half a dozen responses. I think, finally, I
understand what's broken.
I believe your original assertion that the bug was misdiagnosed is correct
(can't link because LKML wasn't in the loop). I'm pretty sure your analysis
that KVM's handling of things works mostly by coincidence is also correct.
The coincidence is that "real" VMMs all use arch_prctl(), and
do_arch_prctl_64() ensures thread.{fs,gs}base are accurate. save_base_legacy()
detects sel==0 and intentionally does nothing, knowing the the base is already
accurate.
Userspaces that don't use arch_prctl(), in the bug report case a 32-bit compat
test, may or may not have accurate thread.{fs,gs}base values. This is
especially true if sel!=0 as save_base_legacy() explicitly zeros the base in
this case, as load_seg_legacy() will restore the seg on the backend.
KVM on the other hand assumes thread.{fs,gs}base are always fresh. When that
didn't hold true for userspace that didn't use arch_prctl(), the fix of
detecting a !64-bit mm just so happened to work because all 64-bit VMMs use
arch_prctl().
It's tempting to just open code this and use RD{FS,GS}BASE when possible,
i.e. avoid any guesswork. Maybe with a module param that userspace can set
to tell KVM it doesn't do anything fancy with FS/GS base (will userspace still
use arch_prctl() even if FSGSABSE is available?).
savesegment(fs, fs_sel);
savesegment(gs, gs_sel);
if (use_current_fsgs_base) {
fs_base = current->thread.fsbase;
vmx->msr_host_kernel_gs_base = current->thread.gsbase;
} else if (static_cpu_has(X86_FEATURE_FSGSBASE)) {
fs_base = rdfsbase()
vmx->msr_host_kernel_gs_base = __rdgsbase_inactive();
} else {
fs_base = read_msr(MSR_FS_BASE);
vmx->msr_host_kernel_gs_base = read_msr(MSR_KERNEL_GS_BASE);
}
I'll revisit this on Monday and run a patch by Paolo.
next prev parent reply other threads:[~2020-10-02 22:40 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-01 20:58 [PATCH v2 0/9] Reclaim TIF_IA32 and TIF_X32 Gabriel Krisman Bertazi
2020-10-01 20:58 ` [PATCH v2 1/9] x86: events: Avoid TIF_IA32 when checking 64bit mode Gabriel Krisman Bertazi
2020-10-01 20:58 ` [PATCH v2 2/9] x86: Simplify compat syscall userspace allocation Gabriel Krisman Bertazi
2020-10-01 20:58 ` [PATCH v2 3/9] x86: oprofile: Avoid TIF_IA32 when checking 64bit mode Gabriel Krisman Bertazi
2020-10-01 20:58 ` [PATCH v2 4/9] x86: elf: Use e_machine to choose DLINFO in compat Gabriel Krisman Bertazi
2020-10-01 21:46 ` Andy Lutomirski
2020-10-01 20:58 ` [PATCH v2 5/9] x86: elf: Use e_machine to select start_thread for x32 Gabriel Krisman Bertazi
2020-10-01 21:49 ` Andy Lutomirski
2020-10-01 20:58 ` [PATCH v2 6/9] x86: elf: Use e_machine to select setup_additional_pages " Gabriel Krisman Bertazi
2020-10-01 21:50 ` Andy Lutomirski
2020-10-01 20:58 ` [PATCH v2 7/9] x86: Use current USER_CS to setup correct context on vmx entry Gabriel Krisman Bertazi
2020-10-01 21:52 ` Andy Lutomirski
2020-10-02 22:40 ` Sean Christopherson [this message]
2020-10-02 23:11 ` Gabriel Krisman Bertazi
2020-10-03 0:15 ` Andy Lutomirski
2020-10-03 23:04 ` Andy Lutomirski
2020-10-05 18:56 ` Andy Lutomirski
2020-10-05 19:54 ` Sean Christopherson
2020-10-01 20:58 ` [PATCH v2 8/9] x86: Convert mmu context ia32_compat into a proper flags field Gabriel Krisman Bertazi
2020-10-01 22:09 ` Andy Lutomirski
2020-10-01 20:58 ` [PATCH v2 9/9] x86: Reclaim TIF_IA32 and TIF_X32 Gabriel Krisman Bertazi
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=20201002224005.GF24460@linux.intel.com \
--to=sean.j.christopherson@intel.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hch@lst.de \
--cc=hpa@zytor.com \
--cc=kernel@collabora.com \
--cc=krisman@collabora.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rric@kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.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).