From patchwork Fri Dec 8 08:39:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Quan Xu X-Patchwork-Id: 10101801 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 013C060325 for ; Fri, 8 Dec 2017 08:42:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E495C28B30 for ; Fri, 8 Dec 2017 08:42:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D7E8728B3B; Fri, 8 Dec 2017 08:42:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7B79728B30 for ; Fri, 8 Dec 2017 08:42:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752468AbdLHIkc (ORCPT ); Fri, 8 Dec 2017 03:40:32 -0500 Received: from mail-ot0-f194.google.com ([74.125.82.194]:44979 "EHLO mail-ot0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752350AbdLHIka (ORCPT ); Fri, 8 Dec 2017 03:40:30 -0500 Received: by mail-ot0-f194.google.com with SMTP id d27so8635643ote.11; Fri, 08 Dec 2017 00:40:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ddF4x0b2mkYKknuLROCFJvIhH+6J/GjSG4r36vJbExw=; b=TBvyL0RnjcDR5tKlrEF5ZyhQSy11F9X46GrDRw4K0n+lka1ZM7dq6i/HI9uKH1HuCv A5K67EA3SG8kmKRNJAIY6J3/+bnmwK56RtAbXyIKMwqjAkrlUeGgbpwOquUw5ZJ2ENdQ qoiHNWGfzewGHycNTiGanT3LJnLiqhJxkAuCD1xGap1aUD8UrJC8oWMIsKr6K4Mg42MA r/r+q9yWdRGxxPa60cGAIR+IYpolHsGMDyBCXIJviFlVxaOBnCPzSt8B9PV0APYTnbzT gmz9lPSu/J06qHR803KjRoUPGebmwaoAq1OHGC8SXQSGykt8pllE3pIG07S/R9zynlc5 SXhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ddF4x0b2mkYKknuLROCFJvIhH+6J/GjSG4r36vJbExw=; b=PlRknz8QxtN/TnKR2LXlI6UaKaoc21t79oP1RXGtcOOwdQNUPnYILEDWN3zIMclbxi 7xKQFO97W40qqOlJU2yR1KX9JjwYlM3AG95eQVDcHvPVfkQk7CPoJlAXkB7Wy4l9AsGW 1as/plBkITFlZCpRH8IQCBDj5aHkYzBgE8cp9bs2RJIaYXWJ2oESdicKX8yCAp7D/lEK rpcL9R8f289pVbCnnsMFcoeOs4GnZJI4ZG1BvPWqd2o7PpG4XJKs1Z/qCifzaAfnHryl OZv8Ml27BjPhdncGU6KpO0umBhRi+j9+OCeiae4ztEa3Z4/gVCBXQi5p+fS1SmtjCHcQ a3Dg== X-Gm-Message-State: AJaThX6E1jMfh6+lrwH2N+xbafARIUb3I52EcmHjYUz2LxZvVJw9KWqt ZlhI23a6K0FoGSzPdvJ9Amssx0rh X-Google-Smtp-Source: AGs4zMZ59agzmiJ3uqHQTOuLd1Ou5HOnnLQ3zMOs2QjxYdql0wsnmniPzdfbGoCeMjeq/exuWpZyPQ== X-Received: by 10.157.14.56 with SMTP id c53mr28926421otc.81.1512722430078; Fri, 08 Dec 2017 00:40:30 -0800 (PST) Received: from localhost.localdomain ([121.0.29.66]) by smtp.googlemail.com with ESMTPSA id p24sm3046407oie.54.2017.12.08.00.40.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 08 Dec 2017 00:40:29 -0800 (PST) From: Quan Xu X-Google-Original-From: Quan Xu To: pbonzini@redhat.com, rkrcmar@redhat.com Cc: yang.zhang.wz@gmail.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Ben Luo , Quan Xu Subject: [PATCH RFC 1/7] kvm: x86: emulate MSR_KVM_PV_TIMER_EN MSR Date: Fri, 8 Dec 2017 16:39:44 +0800 Message-Id: <1512722390-3654-2-git-send-email-quan.xu0@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1512722390-3654-1-git-send-email-quan.xu0@gmail.com> References: <1512722390-3654-1-git-send-email-quan.xu0@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ben Luo Guest enables pv timer functionality using this MSR Signed-off-by: Yang Zhang Signed-off-by: Quan Xu Signed-off-by: Ben Luo --- arch/x86/include/asm/kvm_host.h | 5 +++++ arch/x86/include/uapi/asm/kvm_para.h | 6 ++++++ arch/x86/kvm/lapic.c | 22 ++++++++++++++++++++++ arch/x86/kvm/lapic.h | 6 ++++++ arch/x86/kvm/x86.c | 8 ++++++++ 5 files changed, 47 insertions(+), 0 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c73e493..641b4aa 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -684,6 +684,11 @@ struct kvm_vcpu_arch { bool pv_unhalted; } pv; + struct { + u64 msr_val; + struct gfn_to_hva_cache data; + } pv_timer; + int pending_ioapic_eoi; int pending_external_vector; diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 554aa8f..3dd6116 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -41,6 +41,7 @@ #define MSR_KVM_ASYNC_PF_EN 0x4b564d02 #define MSR_KVM_STEAL_TIME 0x4b564d03 #define MSR_KVM_PV_EOI_EN 0x4b564d04 +#define MSR_KVM_PV_TIMER_EN 0x4b564d05 struct kvm_steal_time { __u64 steal; @@ -64,6 +65,11 @@ struct kvm_clock_pairing { #define KVM_STEAL_VALID_BITS ((-1ULL << (KVM_STEAL_ALIGNMENT_BITS + 1))) #define KVM_STEAL_RESERVED_MASK (((1 << KVM_STEAL_ALIGNMENT_BITS) - 1 ) << 1) +struct pvtimer_vcpu_event_info { + __u64 expire_tsc; + __u64 next_sync_tsc; +} __attribute__((__packed__)); + #define KVM_MAX_MMU_OP_BATCH 32 #define KVM_ASYNC_PF_ENABLED (1 << 0) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 36c90d6..55c9ba3 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1991,6 +1991,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) kvm_lapic_set_base(vcpu, vcpu->arch.apic_base | MSR_IA32_APICBASE_BSP); vcpu->arch.pv_eoi.msr_val = 0; + vcpu->arch.pv_timer.msr_val = 0; apic_update_ppr(apic); if (vcpu->arch.apicv_active) { kvm_x86_ops->apicv_post_state_restore(vcpu); @@ -2478,6 +2479,27 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) addr, sizeof(u8)); } +int kvm_lapic_enable_pv_timer(struct kvm_vcpu *vcpu, u64 data) +{ + u64 addr = data & ~KVM_MSR_ENABLED; + int ret; + + if (!lapic_in_kernel(vcpu)) + return 1; + + if (!IS_ALIGNED(addr, 4)) + return 1; + + vcpu->arch.pv_timer.msr_val = data; + if (!pv_timer_enabled(vcpu)) + return 0; + + ret = kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_timer.data, + addr, sizeof(struct pvtimer_vcpu_event_info)); + + return ret; +} + void kvm_apic_accept_events(struct kvm_vcpu *vcpu) { struct kvm_lapic *apic = vcpu->arch.apic; diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 4b9935a..539a738 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -113,6 +113,7 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu) } int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data); +int kvm_lapic_enable_pv_timer(struct kvm_vcpu *vcpu, u64 data); void kvm_lapic_init(void); void kvm_lapic_exit(void); @@ -207,6 +208,11 @@ static inline int kvm_lapic_latched_init(struct kvm_vcpu *vcpu) return lapic_in_kernel(vcpu) && test_bit(KVM_APIC_INIT, &vcpu->arch.apic->pending_events); } +static inline bool pv_timer_enabled(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.pv_timer.msr_val & KVM_MSR_ENABLED; +} + bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector); void wait_lapic_expire(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 03869eb..5668774 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1025,6 +1025,7 @@ bool kvm_rdpmc(struct kvm_vcpu *vcpu) HV_X64_MSR_STIMER0_CONFIG, HV_X64_MSR_APIC_ASSIST_PAGE, MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME, MSR_KVM_PV_EOI_EN, + MSR_KVM_PV_TIMER_EN, MSR_IA32_TSC_ADJUST, MSR_IA32_TSCDEADLINE, @@ -2279,6 +2280,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) if (kvm_lapic_enable_pv_eoi(vcpu, data)) return 1; break; + case MSR_KVM_PV_TIMER_EN: + if (kvm_lapic_enable_pv_timer(vcpu, data)) + return 1; + break; case MSR_IA32_MCG_CTL: case MSR_IA32_MCG_STATUS: @@ -2510,6 +2515,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) case MSR_KVM_PV_EOI_EN: msr_info->data = vcpu->arch.pv_eoi.msr_val; break; + case MSR_KVM_PV_TIMER_EN: + msr_info->data = vcpu->arch.pv_timer.msr_val; + break; case MSR_IA32_P5_MC_ADDR: case MSR_IA32_P5_MC_TYPE: case MSR_IA32_MCG_CAP: