Received: by 10.213.65.68 with SMTP id h4csp1322932imn; Mon, 26 Mar 2018 05:29:10 -0700 (PDT) X-Google-Smtp-Source: AG47ELvN9z2OvT1GgBJH+nAllm/xZ40TcR+Iz5FF0u02jjVkpVCHiyZ6jCYW/N0lMJBxzJfCiXsg X-Received: by 2002:a17:902:43e4:: with SMTP id j91-v6mr22346797pld.118.1522067350647; Mon, 26 Mar 2018 05:29:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522067350; cv=none; d=google.com; s=arc-20160816; b=kN0Tp/Bbnn/uD7Ug12FMi7x3NZoqc9H3Sl5k2kDJb/eTBFa4KZ4Kpt5tvVziIIJ/d0 DLrXA6G3lGNhMuz8fI9LtdiLhkyeuqqOcZDHxkvL1YCDJklms6WJt2L2PfJ3U87Xpwna 0ZaVoVcF8469SD3WrhajfgcD6FFjxCDMCj8uE7FmsgLcRKMq4ngsnc7Rwb8xlPD3ZrTL o0ZsukdusOUcqgb0YkgvTMa2Dt1A2pRx1+qjYJUs1fm5RD2YYrj7epY2TSNUwvx3Ncbm bmiggVaeZXJ7hu8j5+6vH+K2vHWwu5tzA2spOr6/HP2xYLitmyFSOWiWrgPj4Nau6tLA VUVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:arc-authentication-results; bh=QWMr87r1zkCKgj6q39FPu6biyx8DtnM2gqkGr3LkCXQ=; b=V01BTiKhJePq58KJfWYbtyQ4lPK1KDwDK5XUi5tzkOjNrz3ouUgwdxKYuwPXc7tGXO t7jkn1dv5h409FPmt/DYqdwgvM9CMTW7DrZiPsqGpz1PW9PTSQPrg09b3JRrsrmyUl90 QYnYlsrdlUmt60YfjUJ1Y8kTykr4oLtV6EUm5Lsvt215f6FUkzogBVk0/EPkaftInwak H+ulqlQcVAsRC6uup60wltio0JA48l3WJaT2M7DkTNEBwgtaEH83lNITSS3XRqfVfVFP eQdgwOgY6/WS4aafuP6QzDJ3V4XBMwGo75bhBEHMgbfyFMvcExOXnLAEhU4y3IKe/Txh uVGw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o16si9833787pgc.832.2018.03.26.05.28.55; Mon, 26 Mar 2018 05:29:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751805AbeCZM1v (ORCPT + 99 others); Mon, 26 Mar 2018 08:27:51 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:59532 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751099AbeCZM1u (ORCPT ); Mon, 26 Mar 2018 08:27:50 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A5F458182D01; Mon, 26 Mar 2018 12:27:48 +0000 (UTC) Received: from [10.36.117.130] (ovpn-117-130.ams2.redhat.com [10.36.117.130]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5385E215CDB5; Mon, 26 Mar 2018 12:27:44 +0000 (UTC) Subject: Re: [PATCH] KVM: X86: Fix the decoding of segment overrides in 64bit mode To: Wanpeng Li Cc: Andrew Cooper , LKML , kvm , =?UTF-8?B?UmFkaW0gS3LEjW3DocWZ?= References: <1521707651-9375-1-git-send-email-wanpengli@tencent.com> <49454fe4-16e2-4d8b-7ad5-9e488afc786e@citrix.com> <9bd82cb0-d88f-4891-a111-3704802e1d4e@redhat.com> <94bbfac5-2022-ab92-0b9a-1c3cd2275054@citrix.com> <46ef9359-a87c-224c-53e0-c948b79314a8@redhat.com> From: Paolo Bonzini Message-ID: Date: Mon, 26 Mar 2018 14:27:39 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Mon, 26 Mar 2018 12:27:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Mon, 26 Mar 2018 12:27:49 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'pbonzini@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 26/03/2018 14:25, Wanpeng Li wrote: > 2018-03-23 23:04 GMT+08:00 Paolo Bonzini : >> On 23/03/2018 15:27, Wanpeng Li wrote: >>> 2018-03-22 21:53 GMT+08:00 Andrew Cooper : >>>> On 22/03/18 13:39, Wanpeng Li wrote: >>>>> 2018-03-22 20:38 GMT+08:00 Paolo Bonzini : >>>>>> On 22/03/2018 12:04, Andrew Cooper wrote: >>>>>>> We've got a Force Emulation Prefix (ud2a; .ascii "xen") for doing >>>>>>> magic. Originally, this was used for PV guests to explicitly request an >>>>>>> emulated CPUID, but I extended it to HVM guests for "emulate the next >>>>>>> instruction", after we had some guest user => guest kernel privilege >>>>>>> escalations because of incorrect emulation. >>>>>> Wanpeng, why don't you add it behind a new kvm module parameter? :) >>>>> Great point! I will have a try. Thanks Paolo and Andrew. :) >>>> >>>> Using the force emulation prefix requires intercepting #UD, which is in >>>> general a BadThing(tm) for security. Therefore, we have a build time >>> >>> Yeah, however kvm intercepts and emulates #UD by default, should we >>> add a new kvm module parameter to enable it and disable by default? >> >> No, the module parameter should only be about the force-emulation prefix. > > How about something like this? (Add EmulateOnUD to cpuid, the testcase > will use it) I think you don't need either EmulateOnUD or EMULTYPE_TRAP_UD (the latter only when fep=1 of course). Otherwise yes. Paolo > > diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c > index dd88158..80da5c6 100644 > --- a/arch/x86/kvm/emulate.c > +++ b/arch/x86/kvm/emulate.c > @@ -4772,7 +4772,7 @@ static const struct opcode twobyte_table[256] = { > X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)), > /* 0xA0 - 0xA7 */ > I(Stack | Src2FS, em_push_sreg), I(Stack | Src2FS, em_pop_sreg), > - II(ImplicitOps, em_cpuid, cpuid), > + II(EmulateOnUD | ImplicitOps, em_cpuid, cpuid), > F(DstMem | SrcReg | ModRM | BitOp | NoWrite, em_bt), > F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shld), > F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N, > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 9bc05f5..1825b45 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -108,6 +108,9 @@ module_param_named(enable_shadow_vmcs, > enable_shadow_vmcs, bool, S_IRUGO); > static bool __read_mostly nested = 0; > module_param(nested, bool, S_IRUGO); > > +static bool __read_mostly fep = 0; > +module_param(fep, bool, S_IRUGO); > + > static u64 __read_mostly host_xss; > > static bool __read_mostly enable_pml = 1; > @@ -6215,6 +6218,27 @@ static int handle_machine_check(struct kvm_vcpu *vcpu) > return 1; > } > > +static int handle_ud(struct kvm_vcpu *vcpu) > +{ > + enum emulation_result er; > + > + if (fep) { > + char sig[5]; /* ud2; .ascii "kvm" */ > + struct x86_exception e; > + > + kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, > + kvm_get_linear_rip(vcpu), sig, sizeof(sig), &e); > + if (memcmp(sig, "\xf\xbkvm", sizeof(sig)) == 0) > + kvm_rip_write(vcpu, kvm_rip_read(vcpu) + sizeof(sig)); > + } > + er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); > + if (er == EMULATE_USER_EXIT) > + return 0; > + if (er != EMULATE_DONE) > + kvm_queue_exception(vcpu, UD_VECTOR); > + return 1; > +} > + > static int handle_exception(struct kvm_vcpu *vcpu) > { > struct vcpu_vmx *vmx = to_vmx(vcpu); > @@ -6233,14 +6257,8 @@ static int handle_exception(struct kvm_vcpu *vcpu) > if (is_nmi(intr_info)) > return 1; /* already handled by vmx_vcpu_run() */ > > - if (is_invalid_opcode(intr_info)) { > - er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); > - if (er == EMULATE_USER_EXIT) > - return 0; > - if (er != EMULATE_DONE) > - kvm_queue_exception(vcpu, UD_VECTOR); > - return 1; > - } > + if (is_invalid_opcode(intr_info)) > + return handle_ud(vcpu); > > error_code = 0; > if (intr_info & INTR_INFO_DELIVER_CODE_MASK) > > > The testcase: > > #include > #include > > #define HYPERVISOR_INFO 0x40000000 > > #define CPUID(idx, eax, ebx, ecx, edx)\ > asm volatile (\ > "test %1,%1;jz 1f; ud2a; .ascii \"kvm\"; 1: cpuid" \ > :"=b" (*ebx), "=a" (*eax),"=c" (*ecx), "=d" (*edx)\ > :"0"(idx) ); > > void main() > { > unsigned int eax,ebx,ecx,edx; > char string[13]; > > CPUID(HYPERVISOR_INFO, &eax, &ebx, &ecx, &edx); > *(unsigned int *)(string+0) = ebx; > *(unsigned int *)(string+4) = ecx; > *(unsigned int *)(string+8) = edx; > > string[12] = 0; > if (strncmp(string, "KVMKVMKVM\0\0\0",12) == 0) { > printf("kvm guest\n"); > } else > printf("bare hardware\n"); > > } > > Regards, > Wanpeng Li >