From patchwork Thu Sep 19 10:37:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 11152119 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A0FB816B1 for ; Thu, 19 Sep 2019 10:39:08 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 86CE7207FC for ; Thu, 19 Sep 2019 10:39:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 86CE7207FC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iAtoc-0005ej-Vs; Thu, 19 Sep 2019 10:37:34 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iAtob-0005eR-SL for xen-devel@lists.xenproject.org; Thu, 19 Sep 2019 10:37:33 +0000 X-Inumbo-ID: 7bc9caec-dac9-11e9-b76c-bc764e2007e4 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 7bc9caec-dac9-11e9-b76c-bc764e2007e4; Thu, 19 Sep 2019 10:37:31 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 5EEA6AFB2; Thu, 19 Sep 2019 10:37:30 +0000 (UTC) To: "xen-devel@lists.xenproject.org" From: Jan Beulich Message-ID: <845737d3-e16e-61d7-7733-0f8b9eddfb45@suse.com> Date: Thu, 19 Sep 2019 12:37:36 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0 MIME-Version: 1.0 Content-Language: en-US Subject: [Xen-devel] [PATCH] SVM: correct CPUID event processing X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Petre Pircalabu , Juergen Gross , Kevin Tian , Tamas K Lengyel , Jun Nakajima , Wei Liu , Andrew Cooper , Razvan Cojocaru , Suravee Suthikulpanit , Alexandru Isaila , Boris Ostrovsky , =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" hvm_monitor_cpuid() expects the input registers, not two of the outputs. However, once having made the necessary adjustment, the SVM and VMX functions are so similar that they should be folded (thus avoiding further similar asymmetries to get introduced). Use the best of both worlds by e.g. using "curr" consistently. This then being the only caller of hvm_check_cpuid_faulting(), fold in that function as well. Signed-off-by: Jan Beulich Reviewed-by: Boris Ostrovsky Acked-by: Razvan Cojocaru Reviewed-by: Alexandru Isaila Reviewed-by: Andrew Cooper Reviewed-by: Kevin Tian --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -3349,14 +3349,28 @@ unsigned long copy_from_user_hvm(void *t return rc ? len : 0; /* fake a copy_from_user() return code */ } -bool hvm_check_cpuid_faulting(struct vcpu *v) +int hvm_vmexit_cpuid(struct cpu_user_regs *regs, unsigned int inst_len) { - const struct vcpu_msrs *msrs = v->arch.msrs; + struct vcpu *curr = current; + unsigned int leaf = regs->eax, subleaf = regs->ecx; + struct cpuid_leaf res; - if ( !msrs->misc_features_enables.cpuid_faulting ) - return false; + if ( curr->arch.msrs->misc_features_enables.cpuid_faulting && + hvm_get_cpl(curr) > 0 ) + { + hvm_inject_hw_exception(TRAP_gp_fault, 0); + return 1; /* Don't advance the guest IP! */ + } - return hvm_get_cpl(v) > 0; + guest_cpuid(curr, leaf, subleaf, &res); + HVMTRACE_6D(CPUID, leaf, subleaf, res.a, res.b, res.c, res.d); + + regs->rax = res.a; + regs->rbx = res.b; + regs->rcx = res.c; + regs->rdx = res.d; + + return hvm_monitor_cpuid(inst_len, leaf, subleaf); } static uint64_t _hvm_rdtsc_intercept(void) --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1784,28 +1784,6 @@ static void svm_fpu_dirty_intercept(void vmcb_set_cr0(vmcb, vmcb_get_cr0(vmcb) & ~X86_CR0_TS); } -static int svm_vmexit_do_cpuid(struct cpu_user_regs *regs, unsigned int inst_len) -{ - struct vcpu *curr = current; - struct cpuid_leaf res; - - if ( hvm_check_cpuid_faulting(curr) ) - { - hvm_inject_hw_exception(TRAP_gp_fault, 0); - return 1; /* Don't advance the guest IP! */ - } - - guest_cpuid(curr, regs->eax, regs->ecx, &res); - HVMTRACE_5D(CPUID, regs->eax, res.a, res.b, res.c, res.d); - - regs->rax = res.a; - regs->rbx = res.b; - regs->rcx = res.c; - regs->rdx = res.d; - - return hvm_monitor_cpuid(inst_len, regs->eax, regs->ecx); -} - static void svm_vmexit_do_cr_access( struct vmcb_struct *vmcb, struct cpu_user_regs *regs) { @@ -2828,7 +2806,7 @@ void svm_vmexit_handler(struct cpu_user_ if ( inst_len == 0 ) break; - rc = svm_vmexit_do_cpuid(regs, inst_len); + rc = hvm_vmexit_cpuid(regs, inst_len); if ( rc < 0 ) goto unexpected_exit_type; --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2489,29 +2389,6 @@ static void vmx_fpu_dirty_intercept(void } } -static int vmx_do_cpuid(struct cpu_user_regs *regs) -{ - struct vcpu *curr = current; - uint32_t leaf = regs->eax, subleaf = regs->ecx; - struct cpuid_leaf res; - - if ( hvm_check_cpuid_faulting(current) ) - { - hvm_inject_hw_exception(TRAP_gp_fault, 0); - return 1; /* Don't advance the guest IP! */ - } - - guest_cpuid(curr, leaf, subleaf, &res); - HVMTRACE_5D(CPUID, leaf, res.a, res.b, res.c, res.d); - - regs->rax = res.a; - regs->rbx = res.b; - regs->rcx = res.c; - regs->rdx = res.d; - - return hvm_monitor_cpuid(get_instruction_length(), leaf, subleaf); -} - static void vmx_dr_access(unsigned long exit_qualification, struct cpu_user_regs *regs) { @@ -3862,7 +3839,7 @@ void vmx_vmexit_handler(struct cpu_user_ } case EXIT_REASON_CPUID: { - int rc = vmx_do_cpuid(regs); + int rc = hvm_vmexit_cpuid(regs, get_instruction_length()); /* * rc < 0 error in monitor/vm_event, crash --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -280,7 +280,7 @@ void hvm_set_segment_register(struct vcp bool hvm_set_guest_bndcfgs(struct vcpu *v, u64 val); -bool hvm_check_cpuid_faulting(struct vcpu *v); +int hvm_vmexit_cpuid(struct cpu_user_regs *regs, unsigned int inst_len); void hvm_migrate_timers(struct vcpu *v); void hvm_do_resume(struct vcpu *v); void hvm_migrate_pirq(struct hvm_pirq_dpci *pirq_dpci, const struct vcpu *v);