Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp539941rwb; Tue, 13 Dec 2022 22:35:00 -0800 (PST) X-Google-Smtp-Source: AA0mqf4nyBpYPIujSFaJJvMDBb++mO9zMZno6upMcGQJShJr8gdYdJBvUkMmqSODRityI+YSAtbe X-Received: by 2002:a17:903:2ca:b0:189:8329:dba8 with SMTP id s10-20020a17090302ca00b001898329dba8mr27752840plk.39.1670999700218; Tue, 13 Dec 2022 22:35:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670999700; cv=none; d=google.com; s=arc-20160816; b=IApET+9VAzYpn6Wura3HeiNve4Sd+Dg4wNzjDRHDEphUiCHSF88Wa7X9G4SJmWTwyw 32j3e1PcJftIDGIw4l7bcgylCA5mPa51OU3Z8649LbgqFgtCcoVvJiLnayrnJnSmwNI9 pBNbAZ24zOi6Ly69J31WWHsddJO1HMBEQR/SQxpimmgPj1DqgvrpvdI/sosxv9xsg7sL 2dZPqWAoKlhXgaCBF/nOsHMtFn/CcBv1zN0BMoI+gNK1W7kQl5okgwYL/gebVrNr3SKZ 1LOVG7qwo4rQL0SmRFg4NIDRngClwb2/IeAZNjG1Wc3YYB1pHETciWZPsWFFiUkS5pdn 2KOQ== 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=TIC0KidNOOB8s/ekaM0qOiR6d3gnjJ+hklMBcwu9C60=; b=rYKediJ4p4po4L6QNv978pRX1VznWz4E5rrdEEd7D8DaO5QzoR3bFPiC2VrYWA4L55 UnsDND8a6v89qKzxA6RpZCB1BjMsJBzXN+iHNhqpuvT9jBUnXWSePBp4ZgLaAUj7JDn1 5w58mvLBGA1ieJFSg+S56SJY9FPULgENyBIxIUCWWBVJZak2J03ur3DHv8KpUCO2o6Q0 gfoYOOwVMzzDafo9Oqy64VE+2YHxDzMx28JuqC6XAI9mrLtROVLQQM5vrpvwq9gwj4xN Jt+CsyX04j5droooiFHFdGlK9CfWdorwiXvySciuoTUEUc479RAi82DnXHcjMhrN/e8J ekzg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b=ELTBAX3b; 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 f5-20020a170902ce8500b00188a7401d89si2020020plg.481.2022.12.13.22.34.50; Tue, 13 Dec 2022 22:35: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=ELTBAX3b; 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 S237337AbiLNGdc (ORCPT + 71 others); Wed, 14 Dec 2022 01:33:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237314AbiLNGdX (ORCPT ); Wed, 14 Dec 2022 01:33:23 -0500 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 93D3827CE3; Tue, 13 Dec 2022 22:33:20 -0800 (PST) Received: from jinankjain-dranzer.zrrkmle5drku1h0apvxbr2u2ee.ix.internal.cloudapp.net (unknown [20.188.121.5]) by linux.microsoft.com (Postfix) with ESMTPSA id 8F6C120B876E; Tue, 13 Dec 2022 22:33:15 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 8F6C120B876E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1670999599; bh=TIC0KidNOOB8s/ekaM0qOiR6d3gnjJ+hklMBcwu9C60=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ELTBAX3b6bDo/+nispELS8K0M9Q/g0el/vGcW0TkD61yMNMEg7uoVD4J0RkqcfbvV Ov9IW4yE1YuohYiKKUOI9ipVwf+xjcijXwRN5eq4kkjf4Crf9iEPpIMp1vnmnpYO7w 56u+PY5bmmpb8xcbJ+lZCnK11UameZedxGufiCb4= 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 v9 2/5] Drivers: hv: Setup synic registers in case of nested root partition Date: Wed, 14 Dec 2022 06:33:01 +0000 Message-Id: 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 | 30 +++----------- arch/x86/kernel/cpu/mshyperv.c | 65 ++++++++++++++++++++++++++++++ drivers/hv/hv.c | 19 ++++++--- 4 files changed, 96 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..c38e4c66a3ac 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -198,30 +198,10 @@ 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); +u64 hv_get_non_nested_register(unsigned int reg); +void hv_set_non_nested_register(unsigned int reg, u64 value); #else /* CONFIG_HYPERV */ static inline void hyperv_init(void) {} @@ -241,6 +221,8 @@ static inline int hyperv_flush_guest_mapping_range(u64 as, } static inline void hv_set_register(unsigned int reg, u64 value) { } static inline u64 hv_get_register(unsigned int reg) { return 0; } +static inline void hv_set_non_nested_register(unsigned int reg, u64 value) { } +static inline u64 hv_get_non_nested_register(unsigned int reg) { return 0; } static inline int hv_set_mem_host_visibility(unsigned long addr, int numpages, bool visible) { diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index f9b78d4829e3..938fc82edf05 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -41,7 +41,72 @@ 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_SIEFP: + return HV_REGISTER_NESTED_SIEFP; + case HV_REGISTER_SVERSION: + return HV_REGISTER_NESTED_SVERSION; + 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; + } +} + #if IS_ENABLED(CONFIG_HYPERV) +u64 hv_get_non_nested_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; +} +EXPORT_SYMBOL_GPL(hv_get_non_nested_register); + +void hv_set_non_nested_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); + } +} +EXPORT_SYMBOL_GPL(hv_set_non_nested_register); + +u64 hv_get_register(unsigned int reg) +{ + if (hv_nested) + reg = hv_get_nested_reg(reg); + + return hv_get_non_nested_register(reg); +} +EXPORT_SYMBOL_GPL(hv_get_register); + +void hv_set_register(unsigned int reg, u64 value) +{ + if (hv_nested) + reg = hv_get_nested_reg(reg); + + hv_set_non_nested_register(reg, value); +} +EXPORT_SYMBOL_GPL(hv_set_register); + static void (*vmbus_handler)(void); static void (*hv_stimer0_handler)(void); static void (*hv_kexec_handler)(void); diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 4d6480d57546..986814a903ee 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); } @@ -214,9 +222,10 @@ void hv_synic_enable_regs(unsigned int cpu) /* Setup the Synic's message page */ 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 +242,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