Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp8415260rwb; Wed, 23 Nov 2022 22:04:00 -0800 (PST) X-Google-Smtp-Source: AA0mqf7yUEOUkerwbGce6PxyrOQPVPi0x64rGcqEipmRQU7nLP7macQPQcuy/jKT+1Mkso3ViMYQ X-Received: by 2002:a17:90a:ac07:b0:20a:f75d:b9af with SMTP id o7-20020a17090aac0700b0020af75db9afmr38913213pjq.222.1669269840339; Wed, 23 Nov 2022 22:04:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669269840; cv=none; d=google.com; s=arc-20160816; b=kYmEchd5R+IC2u6folLe2ArTTqVSe7D/11/i3zgesQ+xlmiJBhBRymhJTX1uYzcFIZ aqVS4JHavzwxVvk54VEZ5ROwrRGO5lXi3E19ZKFBbm+E95K26GjZFlDCnLQYrsKQXO3c UqYdmlqX2iZ98lwI/cdsLzNgFi7lZlhfUDIw1N0MTANOKKZ8r9P13iVMXkUnWN+bq3LG 3/HTjTp0L+gR5nOX9OvEXXE8QFbbu6aLSXfrl0eJo5DLNVMbQ0kfAIPr1wwWrc0cn2HW Io7yuQKKvSdAHbDTSlihslopebrUVUhKvRmlvD4MAhqIrPZPXPv/lzzfsiLO3N/FhUpd JKVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-filter; bh=OfWgxvQeVht24a4E8EyqR7JJ0JMc9v0fQdY41479A3A=; b=r2lXWRATCDc5pUAjzkt/MaeZkmHeDIPVxJFU7KJxnOtqF8kfJvU4U1UNirFN81iEAG IVu7P/v2By0TnUC696+jH5pvDaTyULzLsbpXSEI2fWPoeecf193taU+E4R0KWeiW0Pag cS5+8qUNlR9klBGjqZZlvmzhOckEtp5YTVKftXp76Is46h1+pKll6bNaxC5um8qLz6Qp kse3iZI9E6RqpVlhzzdimlW3GRMc7tZScZrTf1YG5sqKc4yk2Kl9tMP8OEI2gaexcWuG ieo4+l4uZF07F2XvF6l3bSQpiN3k4gG1XqntvndXS7WcgaqB6aPmOFaPDKOC8rOy8jQm AI5w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=ipSMlKGP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x9-20020a17090abc8900b00212d699c686si457849pjr.125.2022.11.23.22.03.48; Wed, 23 Nov 2022 22:04:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=ipSMlKGP; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229502AbiKXFxe (ORCPT + 89 others); Thu, 24 Nov 2022 00:53:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229622AbiKXFxX (ORCPT ); Thu, 24 Nov 2022 00:53:23 -0500 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3E5AC419A6; Wed, 23 Nov 2022 21:53:22 -0800 (PST) Received: from jinankjain-dranzer.zrrkmle5drku1h0apvxbr2u2ee.ix.internal.cloudapp.net (unknown [20.188.121.5]) by linux.microsoft.com (Postfix) with ESMTPSA id CA45F20B83DC; Wed, 23 Nov 2022 21:53:17 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com CA45F20B83DC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1669269202; bh=OfWgxvQeVht24a4E8EyqR7JJ0JMc9v0fQdY41479A3A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ipSMlKGPnv1mIEIXYidzEQ3rPwxeP+RjLs16K6bhQg+Pq7VoQmxGFCowGVvqODWnG lim2CM2e/N7de8LrUVHnlLLJMh89USbl4T+Nmpg4D9A92t0JpryFe1kArYStNHFlyp yyGhNoPYHuv47qFuX0vPFuzOH5SejviafGDffJX0= From: Jinank Jain To: jinankjain@microsoft.com Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org, decui@microsoft.com, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, arnd@arndb.de, peterz@infradead.org, jpoimboe@kernel.org, jinankjain@linux.microsoft.com, seanjc@google.com, kirill.shutemov@linux.intel.com, ak@linux.intel.com, sathyanarayanan.kuppuswamy@linux.intel.com, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, anrayabh@linux.microsoft.com, mikelley@microsoft.com Subject: [PATCH v5 2/5] Drivers: hv: Setup synic registers in case of nested root partition Date: Thu, 24 Nov 2022 05:53:03 +0000 Message-Id: <11dda2c697781c5d12bbffd11052e6d6bb2ca705.1669007822.git.jinankjain@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-19.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,ENV_AND_HDR_SPF_MATCH,RCVD_IN_DNSWL_MED, SPF_HELO_PASS,SPF_PASS,USER_IN_DEF_DKIM_WL,USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Child partitions are free to allocate SynIC message and event page but in case of root partition it must use the pages allocated by Microsoft Hypervisor (MSHV). Base address for these pages can be found using synthetic MSRs exposed by MSHV. There is a slight difference in those MSRs for nested vs non-nested root partition. Signed-off-by: Jinank Jain --- arch/x86/include/asm/hyperv-tlfs.h | 11 +++++++ arch/x86/include/asm/mshyperv.h | 26 ++-------------- arch/x86/kernel/cpu/mshyperv.c | 49 ++++++++++++++++++++++++++++++ drivers/hv/hv.c | 18 ++++++++--- 4 files changed, 75 insertions(+), 29 deletions(-) diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index 58c03d18c235..b5019becb618 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -225,6 +225,17 @@ enum hv_isolation_type { #define HV_REGISTER_SINT14 0x4000009E #define HV_REGISTER_SINT15 0x4000009F +/* + * Define synthetic interrupt controller model specific registers for + * nested hypervisor. + */ +#define HV_REGISTER_NESTED_SCONTROL 0x40001080 +#define HV_REGISTER_NESTED_SVERSION 0x40001081 +#define HV_REGISTER_NESTED_SIEFP 0x40001082 +#define HV_REGISTER_NESTED_SIMP 0x40001083 +#define HV_REGISTER_NESTED_EOM 0x40001084 +#define HV_REGISTER_NESTED_SINT0 0x40001090 + /* * Synthetic Timer MSRs. Four timers per vcpu. */ diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 61f0c206bff0..326d699b30d5 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -198,30 +198,8 @@ static inline bool hv_is_synic_reg(unsigned int reg) return false; } -static inline u64 hv_get_register(unsigned int reg) -{ - u64 value; - - if (hv_is_synic_reg(reg) && hv_isolation_type_snp()) - hv_ghcb_msr_read(reg, &value); - else - rdmsrl(reg, value); - return value; -} - -static inline void hv_set_register(unsigned int reg, u64 value) -{ - if (hv_is_synic_reg(reg) && hv_isolation_type_snp()) { - hv_ghcb_msr_write(reg, value); - - /* Write proxy bit via wrmsl instruction */ - if (reg >= HV_REGISTER_SINT0 && - reg <= HV_REGISTER_SINT15) - wrmsrl(reg, value | 1 << 20); - } else { - wrmsrl(reg, value); - } -} +u64 hv_get_register(unsigned int reg); +void hv_set_register(unsigned int reg, u64 value); #else /* CONFIG_HYPERV */ static inline void hyperv_init(void) {} diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 9a4204139490..3e6711a6af6b 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -41,6 +41,55 @@ bool hv_root_partition; bool hv_nested; struct ms_hyperv_info ms_hyperv; +static inline unsigned int hv_get_nested_reg(unsigned int reg) +{ + switch (reg) { + case HV_REGISTER_SIMP: + return HV_REGISTER_NESTED_SIMP; + case HV_REGISTER_NESTED_SIEFP: + return HV_REGISTER_SIEFP; + case HV_REGISTER_SCONTROL: + return HV_REGISTER_NESTED_SCONTROL; + case HV_REGISTER_SINT0: + return HV_REGISTER_NESTED_SINT0; + case HV_REGISTER_EOM: + return HV_REGISTER_NESTED_EOM; + default: + return reg; + } +} + +inline u64 hv_get_register(unsigned int reg) +{ + u64 value; + + if (hv_nested) + reg = hv_get_nested_reg(reg); + + if (hv_is_synic_reg(reg) && hv_isolation_type_snp()) + hv_ghcb_msr_read(reg, &value); + else + rdmsrl(reg, value); + return value; +} + +inline void hv_set_register(unsigned int reg, u64 value) +{ + if (hv_nested) + reg = hv_get_nested_reg(reg); + + if (hv_is_synic_reg(reg) && hv_isolation_type_snp()) { + hv_ghcb_msr_write(reg, value); + + /* Write proxy bit via wrmsl instruction */ + if (reg >= HV_REGISTER_SINT0 && + reg <= HV_REGISTER_SINT15) + wrmsrl(reg, value | 1 << 20); + } else { + wrmsrl(reg, value); + } +} + #if IS_ENABLED(CONFIG_HYPERV) static void (*vmbus_handler)(void); static void (*hv_stimer0_handler)(void); diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 4d6480d57546..9e1eb50cc76f 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -147,7 +147,7 @@ int hv_synic_alloc(void) * Synic message and event pages are allocated by paravisor. * Skip these pages allocation here. */ - if (!hv_isolation_type_snp()) { + if (!hv_isolation_type_snp() && !hv_root_partition) { hv_cpu->synic_message_page = (void *)get_zeroed_page(GFP_ATOMIC); if (hv_cpu->synic_message_page == NULL) { @@ -188,8 +188,16 @@ void hv_synic_free(void) struct hv_per_cpu_context *hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); - free_page((unsigned long)hv_cpu->synic_event_page); - free_page((unsigned long)hv_cpu->synic_message_page); + if (hv_root_partition) { + if (hv_cpu->synic_event_page != NULL) + memunmap(hv_cpu->synic_event_page); + + if (hv_cpu->synic_message_page != NULL) + memunmap(hv_cpu->synic_message_page); + } else { + free_page((unsigned long)hv_cpu->synic_event_page); + free_page((unsigned long)hv_cpu->synic_message_page); + } free_page((unsigned long)hv_cpu->post_msg_page); } @@ -216,7 +224,7 @@ void hv_synic_enable_regs(unsigned int cpu) simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP); simp.simp_enabled = 1; - if (hv_isolation_type_snp()) { + if (hv_isolation_type_snp() || hv_root_partition) { hv_cpu->synic_message_page = memremap(simp.base_simp_gpa << HV_HYP_PAGE_SHIFT, HV_HYP_PAGE_SIZE, MEMREMAP_WB); @@ -233,7 +241,7 @@ void hv_synic_enable_regs(unsigned int cpu) siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP); siefp.siefp_enabled = 1; - if (hv_isolation_type_snp()) { + if (hv_isolation_type_snp() || hv_root_partition) { hv_cpu->synic_event_page = memremap(siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT, HV_HYP_PAGE_SIZE, MEMREMAP_WB); -- 2.25.1