Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp601558ybi; Fri, 12 Jul 2019 01:32:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqwDEE/hpXjp7PYUCnBxn6cEjNT6w1JNqQbEEJeMvw5ljrN9jmT2jQJKjUOkNrbunRvF5QwZ X-Received: by 2002:a17:902:106:: with SMTP id 6mr10190256plb.64.1562920362383; Fri, 12 Jul 2019 01:32:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562920362; cv=none; d=google.com; s=arc-20160816; b=aEvUoVGVcC+73DL3o9YckScE0ST+Pl7NbqsMSdjOwjDNyD2BDwU0UQBcHfz7jmOaoO 9vR2M39/4c0xztijhnAAXF1j6aiHxngcn8UnChX/tIuYRk1uEM8Thr1pUTzh8MLUdru+ AxSSWoQ+6ZYmEaKkubD2iwIqaQ54GL8TYuMapJfaL4raON5oZUCqZ7m16h4aAx+nV5f6 wYOXLqETZEye6VvWt3gLPIcYupfDUu0cUoWLT2em32AG3zH5jrD05+BtfLPCPSTI5Y2o WkC1ujSym3HVeMIzoV+kqrU12w0TLmrQ8ACpB1GIEyFsqbYQl3hCAyeuGYk/bYUDmbd8 bVGg== 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:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=pc5rAweR/HKV5tZrBP94wi0A9OuvyjyphE/oFw9z3p8=; b=FbWVlkHINvydB1TD3rg6q104BmcDiLrAdk6s4v5NtblBLqM39OQ7A6c4Vx2f4Qnyxv zFZI61xDQd/URdJe/hwDLkjBeVRNWrVxAf0mywGM8rzN4PmSBOkzfnU7blu9cWcEw8lI 8/gG964Lkw1TEcVcL++mmpSC+XXC8B5frnRGpJZ6Zu2jyfKzq6D1mDFxBhLHkGNoEVb1 yeYyN1QqoxCdfg+QWTwSXHQielX8rQ0ea8wTAe+UWhUXAq4zgXOhzVGR5VZnAOKqmMp9 OgEwc+inT7W9GTy+VTIwsleueLCgyQnbHxC9yl5RQ6+93Uo+dAs11L6nl0Uuh2Ladk/S Sk1A== 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=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l4si7187052pjq.69.2019.07.12.01.32.27; Fri, 12 Jul 2019 01:32:42 -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=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726690AbfGLIb7 (ORCPT + 99 others); Fri, 12 Jul 2019 04:31:59 -0400 Received: from mga01.intel.com ([192.55.52.88]:9319 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725877AbfGLIb6 (ORCPT ); Fri, 12 Jul 2019 04:31:58 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Jul 2019 01:31:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,481,1557212400"; d="scan'208";a="317928796" Received: from tao-optiplex-7060.sh.intel.com ([10.239.13.104]) by orsmga004.jf.intel.com with ESMTP; 12 Jul 2019 01:31:55 -0700 From: Tao Xu To: pbonzini@redhat.com, rkrcmar@redhat.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, hpa@zytor.com, sean.j.christopherson@intel.com Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, fenghua.yu@intel.com, xiaoyao.li@linux.intel.com, jingqi.liu@intel.com, tao3.xu@intel.com Subject: [PATCH v7 1/3] KVM: x86: add support for user wait instructions Date: Fri, 12 Jul 2019 16:29:05 +0800 Message-Id: <20190712082907.29137-2-tao3.xu@intel.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190712082907.29137-1-tao3.xu@intel.com> References: <20190712082907.29137-1-tao3.xu@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org UMONITOR, UMWAIT and TPAUSE are a set of user wait instructions. This patch adds support for user wait instructions in KVM. Availability of the user wait instructions is indicated by the presence of the CPUID feature flag WAITPKG CPUID.0x07.0x0:ECX[5]. User wait instructions may be executed at any privilege level, and use IA32_UMWAIT_CONTROL MSR to set the maximum time. The behavior of user wait instructions in VMX non-root operation is determined first by the setting of the "enable user wait and pause" secondary processor-based VM-execution control bit 26. If the VM-execution control is 0, UMONITOR/UMWAIT/TPAUSE cause an invalid-opcode exception (#UD). If the VM-execution control is 1, treatment is based on the setting of the “RDTSC exiting” VM-execution control. Because KVM never enables RDTSC exiting, if the instruction causes a delay, the amount of time delayed is called here the physical delay. The physical delay is first computed by determining the virtual delay. If IA32_UMWAIT_CONTROL[31:2] is zero, the virtual delay is the value in EDX:EAX minus the value that RDTSC would return; if IA32_UMWAIT_CONTROL[31:2] is not zero, the virtual delay is the minimum of that difference and AND(IA32_UMWAIT_CONTROL,FFFFFFFCH). Because umwait and tpause can put a (psysical) CPU into a power saving state, by default we dont't expose it to kvm and enable it only when guest CPUID has it. Detailed information about user wait instructions can be found in the latest Intel 64 and IA-32 Architectures Software Developer's Manual. Co-developed-by: Jingqi Liu Signed-off-by: Jingqi Liu Signed-off-by: Tao Xu --- Changes in v7: - Add nested support for user wait instructions (Paolo) --- arch/x86/include/asm/vmx.h | 1 + arch/x86/kvm/cpuid.c | 2 +- arch/x86/kvm/vmx/nested.c | 1 + arch/x86/kvm/vmx/vmx.c | 20 ++++++++++++++++++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index a39136b0d509..8f00882664d3 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h @@ -69,6 +69,7 @@ #define SECONDARY_EXEC_PT_USE_GPA 0x01000000 #define SECONDARY_EXEC_MODE_BASED_EPT_EXEC 0x00400000 #define SECONDARY_EXEC_TSC_SCALING 0x02000000 +#define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE 0x04000000 #define PIN_BASED_EXT_INTR_MASK 0x00000001 #define PIN_BASED_NMI_EXITING 0x00000008 diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 4992e7c99588..7d2cd4066f64 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -402,7 +402,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) | F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) | - F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B); + F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/; /* cpuid 7.0.edx*/ const u32 kvm_cpuid_7_0_edx_x86_features = diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 46af3a5e9209..a4d5da34b306 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -2048,6 +2048,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12) SECONDARY_EXEC_ENABLE_INVPCID | SECONDARY_EXEC_RDTSCP | SECONDARY_EXEC_XSAVES | + SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY | SECONDARY_EXEC_APIC_REGISTER_VIRT | SECONDARY_EXEC_ENABLE_VMFUNC); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index d98eac371c0a..f411c9ae5589 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -2247,6 +2247,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, SECONDARY_EXEC_RDRAND_EXITING | SECONDARY_EXEC_ENABLE_PML | SECONDARY_EXEC_TSC_SCALING | + SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | SECONDARY_EXEC_PT_USE_GPA | SECONDARY_EXEC_PT_CONCEAL_VMX | SECONDARY_EXEC_ENABLE_VMFUNC | @@ -3984,6 +3985,25 @@ static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx) } } + if (vmcs_config.cpu_based_2nd_exec_ctrl & + SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE) { + /* Exposing WAITPKG only when WAITPKG is exposed */ + bool waitpkg_enabled = + guest_cpuid_has(vcpu, X86_FEATURE_WAITPKG); + + if (!waitpkg_enabled) + exec_control &= ~SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; + + if (nested) { + if (waitpkg_enabled) + vmx->nested.msrs.secondary_ctls_high |= + SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; + else + vmx->nested.msrs.secondary_ctls_high &= + ~SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; + } + } + vmx->secondary_exec_control = exec_control; } -- 2.20.1