From patchwork Fri Sep 27 16:33:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksii Kurochko X-Patchwork-Id: 13814460 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 2E6CACDD1CE for ; Fri, 27 Sep 2024 16:37:22 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.806446.1217837 (Exim 4.92) (envelope-from ) id 1suDxs-0006lX-Qx; Fri, 27 Sep 2024 16:37:08 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 806446.1217837; Fri, 27 Sep 2024 16:37:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDxs-0006lQ-NR; Fri, 27 Sep 2024 16:37:08 +0000 Received: by outflank-mailman (input) for mailman id 806446; Fri, 27 Sep 2024 16:37:08 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuL-0001aC-So for xen-devel@lists.xenproject.org; Fri, 27 Sep 2024 16:33:29 +0000 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [2a00:1450:4864:20::52d]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 38b90ecc-7cee-11ef-99a2-01e77a169b0f; Fri, 27 Sep 2024 18:33:26 +0200 (CEST) Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-5c4146c7b28so2639951a12.2 for ; Fri, 27 Sep 2024 09:33:26 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a93c27d47a2sm150697966b.89.2024.09.27.09.33.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 09:33:25 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 38b90ecc-7cee-11ef-99a2-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727454805; x=1728059605; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0vqI1PmTrCMsFkwqH2ZKg8mKiDsRsn2nxQ/Gez0HurI=; b=JNEfruLGXuoFwtCVmvaI2NbqUaioCoP2+XNPHfi/vSZ8WuTQwG43/LWT5lu7B8QS4O 6DRavxt/rZaETbPgHm3rlHIIlIp91laUo5kvOm+H4a9rLbb3YwieFFZB7y7ZRPoj+ZjG A8b5N9S0PDKPgu2NcQK06J4WW5Nh2yYyNYtXhukxhKC/RYg0NTTbymAgckYhgworVHEn s8cwxRpxdpXitnxGZlOLuiljeFEzRLeZkyb9s2TpFBTjuAEUn0nn3HU7lrVEHE9el2YA N9w35eb8ZXnq6/q5Mv5cUKujkibVabBSum+a/ceITWJQYazXpKEGAabznRR/Xe3qsAGf 21tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727454805; x=1728059605; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0vqI1PmTrCMsFkwqH2ZKg8mKiDsRsn2nxQ/Gez0HurI=; b=rE/fFLViAjhMZZ+GKoR2szKhXgNaKEw5sIZ574sxvA4WxEnl7Q6yw8RkxoKJAwog+r Kghf5lcQ2jPX2gPKRt96y/lrmaREJA0erDfXY6bF/fchah7vlbtr/asR7PMgkSMIYN9T 6bKt7Fm/+qTXX+2PVPdKtkT7fr0hNsLIQ2fBLtXHTHhTDgVQUDlTpYUfORVjhALGz6+z hpTnScUAs2tFMOFaRS6V25HncZ8CHp+6qbElzqiEik3kiY2JdxZg1pzueTpgj5SkWA6v PLnncbGTZ7eEhHtwlZuNGSfGO+PhD2XWiqfPPtKycBZU6DnEo3AYFEuFg079fBmIBDC6 QbcA== X-Gm-Message-State: AOJu0YxAxvWCsm3LNlzakuboIAa8SJgy/zxKeb0X0V+hQiaD+v3RzYCM XC4lRqMJcpi2IhkN0OUv6RkArB59snCMyAcNPdsOs5FreY9omKyxt+qFVQ== X-Google-Smtp-Source: AGHT+IFEi62tiH0OkymrRFEP2hzoCZcydJe31gphU1xKa1aOfSbeMSI9AniBinfMCvbPqfr8MXVlow== X-Received: by 2002:a17:907:6d1a:b0:a86:a41c:29b with SMTP id a640c23a62f3a-a93c48e80bdmr369021766b.8.1727454805497; Fri, 27 Sep 2024 09:33:25 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v8 1/7] xen/riscv: allow write_atomic() to work with non-scalar types Date: Fri, 27 Sep 2024 18:33:13 +0200 Message-ID: <09b925f9732699b348c6f2654d3bb5aaa0f0badd.1727449154.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: References: MIME-Version: 1.0 Update the defintion of write_atomic() to support non-scalar types, bringing it closer to the behavior of read_atomic(). Signed-off-by: Oleksii Kurochko Acked-by: Jan Beulich --- xen/arch/riscv/include/asm/atomic.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/xen/arch/riscv/include/asm/atomic.h b/xen/arch/riscv/include/asm/atomic.h index 95910ebfeb..9669a3286d 100644 --- a/xen/arch/riscv/include/asm/atomic.h +++ b/xen/arch/riscv/include/asm/atomic.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ + /* SPDX-License-Identifier: GPL-2.0-only */ /* * Taken and modified from Linux. * @@ -69,10 +69,11 @@ static always_inline void _write_atomic(volatile void *p, } } -#define write_atomic(p, x) \ -({ \ - typeof(*(p)) x_ = (x); \ - _write_atomic(p, x_, sizeof(*(p))); \ +#define write_atomic(p, x) \ +({ \ + union { typeof(*(p)) v; unsigned long ul; } x_ = { .ul = 0UL }; \ + x_.v = (x); \ + _write_atomic(p, x_.ul, sizeof(*(p))); \ }) static always_inline void _add_sized(volatile void *p, From patchwork Fri Sep 27 16:33:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksii Kurochko X-Patchwork-Id: 13814461 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 05EC6CDD1CD for ; Fri, 27 Sep 2024 16:38:13 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.806454.1217847 (Exim 4.92) (envelope-from ) id 1suDyg-0007OW-3U; Fri, 27 Sep 2024 16:37:58 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 806454.1217847; Fri, 27 Sep 2024 16:37:58 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDyf-0007OP-Vz; Fri, 27 Sep 2024 16:37:57 +0000 Received: by outflank-mailman (input) for mailman id 806454; Fri, 27 Sep 2024 16:37:57 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuN-0001aC-T9 for xen-devel@lists.xenproject.org; Fri, 27 Sep 2024 16:33:31 +0000 Received: from mail-lj1-x22b.google.com (mail-lj1-x22b.google.com [2a00:1450:4864:20::22b]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 39931e38-7cee-11ef-99a2-01e77a169b0f; Fri, 27 Sep 2024 18:33:28 +0200 (CEST) Received: by mail-lj1-x22b.google.com with SMTP id 38308e7fff4ca-2f761461150so35137521fa.0 for ; Fri, 27 Sep 2024 09:33:28 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a93c27d47a2sm150697966b.89.2024.09.27.09.33.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 09:33:26 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 39931e38-7cee-11ef-99a2-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727454807; x=1728059607; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BwSoUGEZl7grVzkdzdM2ghnra4ddaVuK/Ny9WfROoWY=; b=NJ6sstZUveYpMf/i8cUHoztTVKumMKYYozyZaqJXft4DqggqxThvHStDnIWFGU/54J v9s09jvsCDc//3bR0ZIvuObp4iVvNz86biQUhSVzZYrYgtYd7v7Gte0HvI0318rjcRDG FqzI2n5/tjaLEXL71WWICS6JYf9LT7zzZerVCzm5RMLd/itYrdr+Z5e3Cq+ESfr5ELxP HhAay1MZ/Y01fFXg6LTpTWUmemCB9rS2OOelumLP/yf0P6PrU7KuPZBk+vr5YhUTAs16 MvnU25j8/t+fMK4bo6SSPjMkDaGylH6cDqTgi62YpEqjuLXliNFBETDTfqVGvUpKHxKU 7kSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727454807; x=1728059607; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BwSoUGEZl7grVzkdzdM2ghnra4ddaVuK/Ny9WfROoWY=; b=KxJSSxA4+gtPhmYiLuqbcsdEI6GCvb+BHjZxKBcWLD+cTt8FU6YhbsHEFFbhpfK7MQ ylwtNMfBwajmaWj+aZXSBFvGwo19RRQJSacFv+hukuUHfaPrhwBEX116t/djmuZNDo2A hahnTFM10yYipTZBQx3lPm+m7+8ycwDb5aobk2XbSPzTL11OxratiydCuzN6xKCmK9D5 BaZS5WWFYrWRLB5bOCfBP5RUjLlxDD2Vs9IyiySbKxQFD3oYDXzJiLbO4zcmtpfkWPzK xCrwnTHUNwU8kTrCtuIXKb9NE8pPq/A1SiouRCaFIt/Id3J/uPn74Zz3bFBQ4BS2HzYm PeRA== X-Gm-Message-State: AOJu0YzAHT2fRUu6rcWDRL/F++yxBsegeVMHJEl8K3h+FuWMl7Fua5rm 2SiG+MDyMO9z/1efW3yIpvuIXnjLKFwu5wDC5tMp03L3Db4A7/pARfac2g== X-Google-Smtp-Source: AGHT+IH5CH+SY/GIpkAiTnx4/CnjlsFKE+BAUA496qjogEk9Pmzyrb0HX0xmG+p2IYfvi15tJJHr3w== X-Received: by 2002:a05:6512:3e05:b0:52c:cd77:fe03 with SMTP id 2adb3069b0e04-5389fc3bd31mr3443461e87.14.1727454806952; Fri, 27 Sep 2024 09:33:26 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v8 2/7] xen/riscv: set up fixmap mappings Date: Fri, 27 Sep 2024 18:33:14 +0200 Message-ID: <87bc91db10442273d3f99cd1777571515b287297.1727449154.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: References: MIME-Version: 1.0 Set up fixmap mappings and the L0 page table for fixmap support. Modify the PTEs (xen_fixmap[]) directly in arch_pmap_map() instead of using set_fixmap() which is expected to be implemented using map_pages_to_xen(), which, in turn, is expected to use arch_pmap_map() during early boot, resulting in a loop. Define new macros in riscv/config.h for calculating the FIXMAP_BASE address, including BOOT_FDT_VIRT_{START, SIZE}, XEN_VIRT_SIZE, and XEN_VIRT_END. Update the check for Xen size in riscv/xen.lds.S to use XEN_VIRT_SIZE instead of a hardcoded constant. Signed-off-by: Oleksii Kurochko Acked-by: Jan Beulich --- xen/arch/riscv/include/asm/config.h | 16 ++++++++-- xen/arch/riscv/include/asm/fixmap.h | 46 +++++++++++++++++++++++++++++ xen/arch/riscv/include/asm/mm.h | 2 ++ xen/arch/riscv/include/asm/page.h | 13 ++++++++ xen/arch/riscv/mm.c | 43 +++++++++++++++++++++++++++ xen/arch/riscv/setup.c | 2 ++ xen/arch/riscv/xen.lds.S | 2 +- 7 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 xen/arch/riscv/include/asm/fixmap.h diff --git a/xen/arch/riscv/include/asm/config.h b/xen/arch/riscv/include/asm/config.h index 50583aafdc..7dbb235685 100644 --- a/xen/arch/riscv/include/asm/config.h +++ b/xen/arch/riscv/include/asm/config.h @@ -41,8 +41,10 @@ * Start addr | End addr | Slot | area description * ============================================================================ * ..... L2 511 Unused - * 0xffffffffc0600000 0xffffffffc0800000 L2 511 Fixmap - * 0xffffffffc0200000 0xffffffffc0600000 L2 511 FDT + * 0xffffffffc0a00000 0xffffffffc0c00000 L2 511 Fixmap + * ..... ( 2 MB gap ) + * 0xffffffffc0400000 0xffffffffc0800000 L2 511 FDT + * ..... ( 2 MB gap ) * 0xffffffffc0000000 0xffffffffc0200000 L2 511 Xen * ..... L2 510 Unused * 0x3200000000 0x7f40000000 L2 200-509 Direct map @@ -74,6 +76,16 @@ #error "unsupported RV_STAGE1_MODE" #endif +#define GAP_SIZE MB(2) + +#define XEN_VIRT_SIZE MB(2) + +#define BOOT_FDT_VIRT_START (XEN_VIRT_START + XEN_VIRT_SIZE + GAP_SIZE) +#define BOOT_FDT_VIRT_SIZE MB(4) + +#define FIXMAP_BASE \ + (BOOT_FDT_VIRT_START + BOOT_FDT_VIRT_SIZE + GAP_SIZE) + #define DIRECTMAP_SLOT_END 509 #define DIRECTMAP_SLOT_START 200 #define DIRECTMAP_VIRT_START SLOTN(DIRECTMAP_SLOT_START) diff --git a/xen/arch/riscv/include/asm/fixmap.h b/xen/arch/riscv/include/asm/fixmap.h new file mode 100644 index 0000000000..63732df36c --- /dev/null +++ b/xen/arch/riscv/include/asm/fixmap.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * fixmap.h: compile-time virtual memory allocation + */ +#ifndef ASM_FIXMAP_H +#define ASM_FIXMAP_H + +#include +#include +#include + +#include + +#define FIXMAP_ADDR(n) (FIXMAP_BASE + (n) * PAGE_SIZE) + +/* Fixmap slots */ +#define FIX_PMAP_BEGIN (0) /* Start of PMAP */ +#define FIX_PMAP_END (FIX_PMAP_BEGIN + NUM_FIX_PMAP - 1) /* End of PMAP */ +#define FIX_MISC (FIX_PMAP_END + 1) /* Ephemeral mappings of hardware */ + +#define FIX_LAST FIX_MISC + +#define FIXADDR_START FIXMAP_ADDR(0) +#define FIXADDR_TOP FIXMAP_ADDR(FIX_LAST + 1) + +#ifndef __ASSEMBLY__ + +/* + * Direct access to xen_fixmap[] should only happen when {set, + * clear}_fixmap() is unusable (e.g. where we would end up to + * recursively call the helpers). + */ +extern pte_t xen_fixmap[]; + +#define fix_to_virt(slot) ((void *)FIXMAP_ADDR(slot)) + +static inline unsigned int virt_to_fix(vaddr_t vaddr) +{ + BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); + + return ((vaddr - FIXADDR_START) >> PAGE_SHIFT); +} + +#endif /* __ASSEMBLY__ */ + +#endif /* ASM_FIXMAP_H */ diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h index 25af9e1aaa..a0bdc2bc3a 100644 --- a/xen/arch/riscv/include/asm/mm.h +++ b/xen/arch/riscv/include/asm/mm.h @@ -255,4 +255,6 @@ static inline unsigned int arch_get_dma_bitsize(void) return 32; /* TODO */ } +void setup_fixmap_mappings(void); + #endif /* _ASM_RISCV_MM_H */ diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h index c831e16417..d4a5009823 100644 --- a/xen/arch/riscv/include/asm/page.h +++ b/xen/arch/riscv/include/asm/page.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -81,6 +82,18 @@ static inline void flush_page_to_ram(unsigned long mfn, bool sync_icache) BUG_ON("unimplemented"); } +/* Write a pagetable entry. */ +static inline void write_pte(pte_t *p, pte_t pte) +{ + write_atomic(p, pte); +} + +/* Read a pagetable entry. */ +static inline pte_t read_pte(const pte_t *p) +{ + return read_atomic(p); +} + #endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_PAGE_H */ diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index 7d09e781bf..b8ff91cf4e 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,9 @@ stage1_pgtbl_root[PAGETABLE_ENTRIES]; pte_t __section(".bss.page_aligned") __aligned(PAGE_SIZE) stage1_pgtbl_nonroot[PGTBL_INITIAL_COUNT * PAGETABLE_ENTRIES]; +pte_t __section(".bss.page_aligned") __aligned(PAGE_SIZE) +xen_fixmap[PAGETABLE_ENTRIES]; + #define HANDLE_PGTBL(curr_lvl_num) \ index = pt_index(curr_lvl_num, page_addr); \ if ( pte_is_valid(pgtbl[index]) ) \ @@ -191,6 +195,45 @@ static bool __init check_pgtbl_mode_support(struct mmu_desc *mmu_desc, return is_mode_supported; } +void __init setup_fixmap_mappings(void) +{ + pte_t *pte, tmp; + unsigned int i; + + BUILD_BUG_ON(FIX_LAST >= PAGETABLE_ENTRIES); + + pte = &stage1_pgtbl_root[pt_index(HYP_PT_ROOT_LEVEL, FIXMAP_ADDR(0))]; + + /* + * In RISC-V page table levels are numbered from Lx to L0 where + * x is the highest page table level for currect MMU mode ( for example, + * for Sv39 has 3 page tables so the x = 2 (L2 -> L1 -> L0) ). + * + * In this cycle we want to find L1 page table because as L0 page table + * xen_fixmap[] will be used. + */ + for ( i = HYP_PT_ROOT_LEVEL; i-- > 1; ) + { + BUG_ON(!pte_is_valid(*pte)); + + pte = (pte_t *)LOAD_TO_LINK(pte_to_paddr(*pte)); + pte = &pte[pt_index(i, FIXMAP_ADDR(0))]; + } + + BUG_ON(pte_is_valid(*pte)); + + tmp = paddr_to_pte(LINK_TO_LOAD((unsigned long)&xen_fixmap), PTE_TABLE); + write_pte(pte, tmp); + + RISCV_FENCE(rw, rw); + sfence_vma(); + + /* + * We only need the zeroeth table allocated, but not the PTEs set, because + * set_fixmap() will set them on the fly. + */ +} + /* * setup_initial_pagetables: * diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c index 97c599db44..82c5752da1 100644 --- a/xen/arch/riscv/setup.c +++ b/xen/arch/riscv/setup.c @@ -47,6 +47,8 @@ void __init noreturn start_xen(unsigned long bootcpu_id, test_macros_from_bug_h(); #endif + setup_fixmap_mappings(); + printk("All set up\n"); machine_halt(); diff --git a/xen/arch/riscv/xen.lds.S b/xen/arch/riscv/xen.lds.S index 871b47a235..558a5a992a 100644 --- a/xen/arch/riscv/xen.lds.S +++ b/xen/arch/riscv/xen.lds.S @@ -174,6 +174,6 @@ ASSERT(!SIZEOF(.got.plt), ".got.plt non-empty") * Changing the size of Xen binary can require an update of * PGTBL_INITIAL_COUNT. */ -ASSERT(_end - _start <= MB(2), "Xen too large for early-boot assumptions") +ASSERT(_end - _start <= XEN_VIRT_SIZE, "Xen too large for early-boot assumptions") ASSERT(_ident_end - _ident_start <= IDENT_AREA_SIZE, "identity region is too big"); From patchwork Fri Sep 27 16:33:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksii Kurochko X-Patchwork-Id: 13814459 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id A9154CDD1CE for ; Fri, 27 Sep 2024 16:33:55 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.806418.1217817 (Exim 4.92) (envelope-from ) id 1suDuP-0004kE-VH; Fri, 27 Sep 2024 16:33:33 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 806418.1217817; Fri, 27 Sep 2024 16:33:33 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuP-0004k7-Sd; Fri, 27 Sep 2024 16:33:33 +0000 Received: by outflank-mailman (input) for mailman id 806418; Fri, 27 Sep 2024 16:33:32 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuO-0001aD-7P for xen-devel@lists.xenproject.org; Fri, 27 Sep 2024 16:33:32 +0000 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [2a00:1450:4864:20::329]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 3a1fa2eb-7cee-11ef-a0ba-8be0dac302b0; Fri, 27 Sep 2024 18:33:29 +0200 (CEST) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-42cb6f3a5bcso27944195e9.2 for ; Fri, 27 Sep 2024 09:33:29 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a93c27d47a2sm150697966b.89.2024.09.27.09.33.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 09:33:27 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3a1fa2eb-7cee-11ef-a0ba-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727454808; x=1728059608; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=A74SThhYGpNGHbuzB0A5PnKvSwX2Icc/uEq6ULocwYc=; b=cdE5UvzGChYE8qVGYWnfGjM6SllAXULZWeL+6x4DFRMoO4656qsLwR7wHvlc0Af/J4 SpzfDR1k9QgGutqOmIgdahTYWbNxz6o/yQrxJ3/fOFUTzT5f3AmiEfeEHoCyc9G40ef3 WAF2Wz6rYN7JKQS/RxwbBFD1g7eQzV3mk+cHAeovjBwhc/x1y5mt3ZIJ7jraJMCAwr8V Nr7QuSQM1u0Fuwk0P2tHEM77oPbSpXBz17WorFqqBwa4asUj8nf53A1jMA/Lo0ICUUa2 1HFac829xkXKiv76dKR62EZQ2jh9upNJAvBzxIj5lpRbXYwMg9kHVSF5z8vuPhTvBQPT evmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727454808; x=1728059608; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=A74SThhYGpNGHbuzB0A5PnKvSwX2Icc/uEq6ULocwYc=; b=Ut5lENH2JUvHAfK5TXgSLYsfo/SwI3GFYY1miBugZ3F7L1Xrel5xb7+27l9ER9dwZ+ P9VopHJqGYs7Oyx/Zi+EeN9KAFKodYE/2X+FKun+rcKeAyqJLLk89A9McIGJG627zNIt cikTm1gQPRbks0Gn2M6fXTTOjNKRCLXPkWJ6e5pd7OlkWqwg4Cd/6yS+tyrhLaBkYXUB KPIRI3oixmbSJhkrgELh2gBw+JgINKZb7IAhT00zqUOMRuyE/cihe6phC8sPzgenSuaU Y1gy+sRQ9AVy3gJ6pdhmUSXFNs6JeqCloY4qXjulKlFily9UMKGGPx/srbUTUzWT/NWo CjOw== X-Gm-Message-State: AOJu0YwroomWKy4A/s30muaOJg4ZbrXEFR4IjYKKjTTpmm1ozo6O7mBp UhiCcUBsgaPNzpysnbnFnVl8NEDkYIehJcsEEFgXejMUS+XPDCedxmTL1w== X-Google-Smtp-Source: AGHT+IF051dFpVO8XlpMXfYgtd4R1pf5U3XwDtozp0fFwnpFoF7v1vlaYdcetKSqUDFEJlyAz0s5jQ== X-Received: by 2002:a5d:6310:0:b0:37c:cdbf:2cc0 with SMTP id ffacd0b85a97d-37cd5b15489mr3003878f8f.53.1727454807921; Fri, 27 Sep 2024 09:33:27 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v8 3/7] xen/riscv: introduce asm/pmap.h header Date: Fri, 27 Sep 2024 18:33:15 +0200 Message-ID: <4bfd2bfdb276f982420bac85c4b6f2da8c5f5367.1727449154.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: References: MIME-Version: 1.0 Introduce arch_pmap_{un}map functions and select HAS_PMAP for CONFIG_RISCV. Add pte_from_mfn() for use in arch_pmap_map(). Introduce flush_xen_tlb_one_local() and use it in arch_pmap_{un}map(). Signed-off-by: Oleksii Kurochko Reviewed-by: Jan Beulich --- xen/arch/riscv/Kconfig | 1 + xen/arch/riscv/include/asm/flushtlb.h | 6 +++++ xen/arch/riscv/include/asm/page.h | 6 +++++ xen/arch/riscv/include/asm/pmap.h | 36 +++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 xen/arch/riscv/include/asm/pmap.h diff --git a/xen/arch/riscv/Kconfig b/xen/arch/riscv/Kconfig index 7a113c7774..1858004676 100644 --- a/xen/arch/riscv/Kconfig +++ b/xen/arch/riscv/Kconfig @@ -3,6 +3,7 @@ config RISCV select FUNCTION_ALIGNMENT_16B select GENERIC_BUG_FRAME select HAS_DEVICE_TREE + select HAS_PMAP select HAS_VMAP config RISCV_64 diff --git a/xen/arch/riscv/include/asm/flushtlb.h b/xen/arch/riscv/include/asm/flushtlb.h index 7ce32bea0b..f4a735fd6c 100644 --- a/xen/arch/riscv/include/asm/flushtlb.h +++ b/xen/arch/riscv/include/asm/flushtlb.h @@ -5,6 +5,12 @@ #include #include +/* Flush TLB of local processor for address va. */ +static inline void flush_tlb_one_local(vaddr_t va) +{ + asm volatile ( "sfence.vma %0" :: "r" (va) : "memory" ); +} + /* * Filter the given set of CPUs, removing those that definitely flushed their * TLB since @page_timestamp. diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h index d4a5009823..eb79cb9409 100644 --- a/xen/arch/riscv/include/asm/page.h +++ b/xen/arch/riscv/include/asm/page.h @@ -94,6 +94,12 @@ static inline pte_t read_pte(const pte_t *p) return read_atomic(p); } +static inline pte_t pte_from_mfn(mfn_t mfn, unsigned int flags) +{ + unsigned long pte = (mfn_x(mfn) << PTE_PPN_SHIFT) | flags; + return (pte_t){ .pte = pte }; +} + #endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_PAGE_H */ diff --git a/xen/arch/riscv/include/asm/pmap.h b/xen/arch/riscv/include/asm/pmap.h new file mode 100644 index 0000000000..60065c996f --- /dev/null +++ b/xen/arch/riscv/include/asm/pmap.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef ASM_PMAP_H +#define ASM_PMAP_H + +#include +#include +#include +#include + +#include +#include +#include + +static inline void __init arch_pmap_map(unsigned int slot, mfn_t mfn) +{ + pte_t *entry = &xen_fixmap[slot]; + pte_t pte; + + ASSERT(!pte_is_valid(*entry)); + + pte = pte_from_mfn(mfn, PAGE_HYPERVISOR_RW); + write_pte(entry, pte); + + flush_tlb_one_local(FIXMAP_ADDR(slot)); +} + +static inline void __init arch_pmap_unmap(unsigned int slot) +{ + pte_t pte = {}; + + write_pte(&xen_fixmap[slot], pte); + + flush_tlb_one_local(FIXMAP_ADDR(slot)); +} + +#endif /* ASM_PMAP_H */ From patchwork Fri Sep 27 16:33:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksii Kurochko X-Patchwork-Id: 13814458 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 5B43CCDD1CF for ; Fri, 27 Sep 2024 16:33:47 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.806420.1217827 (Exim 4.92) (envelope-from ) id 1suDuR-00050W-7F; Fri, 27 Sep 2024 16:33:35 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 806420.1217827; Fri, 27 Sep 2024 16:33:35 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuR-00050H-3T; Fri, 27 Sep 2024 16:33:35 +0000 Received: by outflank-mailman (input) for mailman id 806420; Fri, 27 Sep 2024 16:33:33 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuP-0001aD-7Z for xen-devel@lists.xenproject.org; Fri, 27 Sep 2024 16:33:33 +0000 Received: from mail-lf1-x135.google.com (mail-lf1-x135.google.com [2a00:1450:4864:20::135]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 3a9b8ed4-7cee-11ef-a0ba-8be0dac302b0; Fri, 27 Sep 2024 18:33:29 +0200 (CEST) Received: by mail-lf1-x135.google.com with SMTP id 2adb3069b0e04-5365cc68efaso2192132e87.1 for ; Fri, 27 Sep 2024 09:33:29 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a93c27d47a2sm150697966b.89.2024.09.27.09.33.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 09:33:28 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3a9b8ed4-7cee-11ef-a0ba-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727454809; x=1728059609; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/lmgDuLjmXqyvP8NcM6DuHkV8rf9NddkBsqcBWqHAn8=; b=DcRox8PIEfd5AezHvP9fm8yKCMbBQ3zSwvUbsPaQzsqUBd6RLvqK03qPSQBJzguGuB wTqxjI9xmmf0u/traLM2hcH421vo+33J/yy9l2wfbfIRVOHAUDXqoARByfQpoTcHL/Bs OcRXHWBgT+bG0nJDFviB0A/5w2981CxW5CALvf9XlydkJ7KzDsmSnRKZmrCgz1hbrvCm QVWWZ8aj6Bi/uIphW2qo3Dy6JbztHo107cTu1xnLhptjHVVq3zsMId0LYg+eh+r1IAwq w63wWSTZKwYcQtGnyTfaVMb+2ziNDR/5lbOEFxfSReYa+v1dvnRRGSbgyPNDNS4bGVT+ iGig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727454809; x=1728059609; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/lmgDuLjmXqyvP8NcM6DuHkV8rf9NddkBsqcBWqHAn8=; b=uJ4RYS/IjIMvguhes3tcosz0a/SVDGkV8pn1nJAetnOJC66mt+2iImWzqGjPgWkBOO Vkr3HG/kv/3o3I6JJlVL5OQ3d6pui4rVY2wzfCMXeFlljYJmDH/mNglTgSIP9quGTSiF iYt8rEUlH2YtTwrTCROs9h8FIcLRYJXeWOor8ekeQ2un4+vG8GNFL6YL11BPIkiYJk82 hrXBov23j4R3T8AjfCIhwF/mlEwBTFqaemF5Yq3WKxnLEwIkCxWncsxyHfyxabpNOX2T gnweBFFVKdeFTfJVhl22kM4Ev4g3geQhxu9/n1gl0aDZO6uey/4L5FTt7A9TuVH5hSUr 7z/A== X-Gm-Message-State: AOJu0Yx0qAlbt/FeV17mmK+EegiHcjpFN3TCrJ/kbLF0VriYIFX9gJGp mBFZQinb+jCjeFMB+y5aDrRyTG6i7+I4e+v/AQ2pAnfKz9Ewhry6goB8Eg== X-Google-Smtp-Source: AGHT+IFTk+0xcVyRNaQOYKV5gdNufK90rKVUmfyHd5wBS6DK1VS2FEAwdUQShzU1AVhotR1bO5Y1eQ== X-Received: by 2002:a05:6512:3404:b0:533:44e7:1b2a with SMTP id 2adb3069b0e04-5389fc70f6cmr3130607e87.40.1727454808829; Fri, 27 Sep 2024 09:33:28 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v8 4/7] xen/riscv: introduce functionality to work with CPU info Date: Fri, 27 Sep 2024 18:33:16 +0200 Message-ID: <3ffb3ffd38b2e0d3568bfd3f9ef974d61b0d2508.1727449154.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: References: MIME-Version: 1.0 Introduce struct pcpu_info to store pCPU-related information. Initially, it includes only processor_id and hart id, but it will be extended to include guest CPU information and temporary variables for saving/restoring vCPU registers. Add set_processor_id() function to set processor_id stored in pcpu_info. Define smp_processor_id() to provide accurate information, replacing the previous "dummy" value of 0. Initialize tp registers to point to pcpu_info[0]. Set processor_id to 0 for logical CPU 0 and store the physical CPU ID in pcpu_info[0]. Introduce helpers for getting/setting hart_id ( physical CPU id in RISC-V terms ) from Xen CPU id. Signed-off-by: Oleksii Kurochko Acked-by: Jan Beulich --- xen/arch/riscv/Makefile | 1 + xen/arch/riscv/include/asm/current.h | 27 +++++++++++++++++++++++++- xen/arch/riscv/include/asm/processor.h | 3 --- xen/arch/riscv/include/asm/smp.h | 18 +++++++++++++++++ xen/arch/riscv/riscv64/asm-offsets.c | 3 +++ xen/arch/riscv/riscv64/head.S | 14 +++++++++++++ xen/arch/riscv/setup.c | 5 +++++ xen/arch/riscv/smp.c | 15 ++++++++++++++ 8 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 xen/arch/riscv/smp.c diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile index d192be7b55..6832549133 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_RISCV_64) += riscv64/ obj-y += sbi.o obj-y += setup.o obj-y += shutdown.o +obj-y += smp.o obj-y += stubs.o obj-y += traps.o obj-y += vm_event.o diff --git a/xen/arch/riscv/include/asm/current.h b/xen/arch/riscv/include/asm/current.h index aedb6dc732..6f1ec4e190 100644 --- a/xen/arch/riscv/include/asm/current.h +++ b/xen/arch/riscv/include/asm/current.h @@ -3,12 +3,37 @@ #ifndef __ASM_CURRENT_H #define __ASM_CURRENT_H -#include +#include +#include #include + #include #ifndef __ASSEMBLY__ +register struct pcpu_info *tp asm ( "tp" ); + +struct pcpu_info { + unsigned int processor_id; /* Xen CPU id */ + unsigned long hart_id; /* physical CPU id */ +} __cacheline_aligned; + +/* tp points to one of these */ +extern struct pcpu_info pcpu_info[NR_CPUS]; + +#define set_processor_id(id) do { \ + tp->processor_id = (id); \ +} while (0) + +static inline unsigned int smp_processor_id(void) +{ + unsigned int id = tp->processor_id; + + BUG_ON(id >= NR_CPUS); + + return id; +} + /* Which VCPU is "current" on this PCPU. */ DECLARE_PER_CPU(struct vcpu *, curr_vcpu); diff --git a/xen/arch/riscv/include/asm/processor.h b/xen/arch/riscv/include/asm/processor.h index 3ae164c265..e42b353b4c 100644 --- a/xen/arch/riscv/include/asm/processor.h +++ b/xen/arch/riscv/include/asm/processor.h @@ -12,9 +12,6 @@ #ifndef __ASSEMBLY__ -/* TODO: need to be implemeted */ -#define smp_processor_id() 0 - /* On stack VCPU state */ struct cpu_user_regs { diff --git a/xen/arch/riscv/include/asm/smp.h b/xen/arch/riscv/include/asm/smp.h index b1ea91b1eb..a824be8e78 100644 --- a/xen/arch/riscv/include/asm/smp.h +++ b/xen/arch/riscv/include/asm/smp.h @@ -5,6 +5,8 @@ #include #include +#include + DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_mask); DECLARE_PER_CPU(cpumask_var_t, cpu_core_mask); @@ -14,6 +16,22 @@ DECLARE_PER_CPU(cpumask_var_t, cpu_core_mask); */ #define park_offline_cpus false +/* + * Mapping between Xen logical cpu index and hartid. + */ +static inline unsigned long cpuid_to_hartid(unsigned long cpuid) +{ + return pcpu_info[cpuid].hart_id; +} + +static inline void set_cpuid_to_hartid(unsigned long cpuid, + unsigned long hartid) +{ + pcpu_info[cpuid].hart_id = hartid; +} + +void setup_tp(unsigned int cpuid); + #endif /* diff --git a/xen/arch/riscv/riscv64/asm-offsets.c b/xen/arch/riscv/riscv64/asm-offsets.c index 9f663b9510..3b5daf3b36 100644 --- a/xen/arch/riscv/riscv64/asm-offsets.c +++ b/xen/arch/riscv/riscv64/asm-offsets.c @@ -1,5 +1,6 @@ #define COMPILE_OFFSETS +#include #include #include @@ -50,4 +51,6 @@ void asm_offsets(void) OFFSET(CPU_USER_REGS_SSTATUS, struct cpu_user_regs, sstatus); OFFSET(CPU_USER_REGS_PREGS, struct cpu_user_regs, pregs); BLANK(); + DEFINE(PCPU_INFO_SIZE, sizeof(struct pcpu_info)); + BLANK(); } diff --git a/xen/arch/riscv/riscv64/head.S b/xen/arch/riscv/riscv64/head.S index 3261e9fce8..2a1b3dad91 100644 --- a/xen/arch/riscv/riscv64/head.S +++ b/xen/arch/riscv/riscv64/head.S @@ -1,4 +1,5 @@ #include +#include #include .section .text.header, "ax", %progbits @@ -55,6 +56,10 @@ FUNC(start) */ jal reset_stack + /* Xen's boot cpu id is equal to 0 so setup TP register for it */ + li a0, 0 + jal setup_tp + /* restore hart_id ( bootcpu_id ) and dtb address */ mv a0, s0 mv a1, s1 @@ -72,6 +77,15 @@ FUNC(reset_stack) ret END(reset_stack) +/* void setup_tp(unsigned int xen_cpuid); */ +FUNC(setup_tp) + la t0, pcpu_info + li t1, PCPU_INFO_SIZE + mul t1, a0, t1 + add tp, t0, t1 + ret +END(setup_tp) + .section .text.ident, "ax", %progbits FUNC(turn_on_mmu) diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c index 82c5752da1..6e3a787dbe 100644 --- a/xen/arch/riscv/setup.c +++ b/xen/arch/riscv/setup.c @@ -9,6 +9,7 @@ #include #include +#include #include void arch_get_xen_caps(xen_capabilities_info_t *info) @@ -41,6 +42,10 @@ void __init noreturn start_xen(unsigned long bootcpu_id, { remove_identity_mapping(); + set_processor_id(0); + + set_cpuid_to_hartid(0, bootcpu_id); + trap_init(); #ifdef CONFIG_SELF_TESTS diff --git a/xen/arch/riscv/smp.c b/xen/arch/riscv/smp.c new file mode 100644 index 0000000000..4ca6a4e892 --- /dev/null +++ b/xen/arch/riscv/smp.c @@ -0,0 +1,15 @@ +#include + +/* + * FIXME: make pcpu_info[] dynamically allocated when necessary + * functionality will be ready + */ +/* + * tp points to one of these per cpu. + * + * hart_id would be valid (no matter which value) if its + * processor_id field is valid (less than NR_CPUS). + */ +struct pcpu_info pcpu_info[NR_CPUS] = { [0 ... NR_CPUS - 1] = { + .processor_id = NR_CPUS, +}}; From patchwork Fri Sep 27 16:33:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksii Kurochko X-Patchwork-Id: 13814463 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id ED891CDD1CE for ; Fri, 27 Sep 2024 16:38:44 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.806463.1217867 (Exim 4.92) (envelope-from ) id 1suDzJ-00008F-MY; Fri, 27 Sep 2024 16:38:37 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 806463.1217867; Fri, 27 Sep 2024 16:38:37 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDzJ-00007b-IZ; Fri, 27 Sep 2024 16:38:37 +0000 Received: by outflank-mailman (input) for mailman id 806463; Fri, 27 Sep 2024 16:38:36 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuQ-0001aD-7q for xen-devel@lists.xenproject.org; Fri, 27 Sep 2024 16:33:34 +0000 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [2a00:1450:4864:20::42d]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 3b0f08ea-7cee-11ef-a0ba-8be0dac302b0; Fri, 27 Sep 2024 18:33:30 +0200 (CEST) Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-37cd26c6dd1so1581755f8f.3 for ; Fri, 27 Sep 2024 09:33:30 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a93c27d47a2sm150697966b.89.2024.09.27.09.33.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 09:33:29 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3b0f08ea-7cee-11ef-a0ba-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727454810; x=1728059610; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DP7Xm5Q3EVpTTcb6SH6DY0V9FnTfHbgjU3oF6cyyUOk=; b=g2U4ph2uE1Pu8ly8sqLGqMjnuadn6ZjkID9n4cXQLYUH1m1xzJ2GIe+te0otk5gtJp vOFS50DlUj2VJCtLW1hHFlRuoHS3OEZupOjoIM8HSxUiCHNTkBgB49m7kbArOKE7qAbP sqYfeUWX4q+qaruzAc4IjBxF6r8wmkPZSoWJuvNzdjp+YsQz8/45yEW/ADRhIPu5f2H5 zwdw9Md3G6GUfkPFUVPP25BL+nlA4C6IrxDb0jTY/d3ulogr6xXOXzG5cVCfswrilGxL qc3GGrXKGnYjDTApnIM5RV0aXOO5Ja9rCV6pabZML3KIQ1amjobCdwpDGhduYjXgXYR8 3zpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727454810; x=1728059610; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DP7Xm5Q3EVpTTcb6SH6DY0V9FnTfHbgjU3oF6cyyUOk=; b=UtMEuhPEIHkM4OmMnm/IUSLz7djxjcd06u5eawf7LfSWny1D3JLJ9/ppQkuL+nwDeB CbmdTI3twSxBhBm3XeTDb6mftmPDSjqUtTCvk9qIzNizvj7YnXa4Kt9fDAHF+tNPv+7D RaFRMIOhvv8u1l4MOYIrn7CioCy/bpJKlkBqgPq1oVP1jfyewPnW8NzfXgFAPPGapOKG hYT4s8mvVODpydQyJEbxI+QGvZDLHTZN/RwVyMfwKi0+MYyaz2kpPhlYrkfujL/6vKHh CXgXUtYKfmdOKLwyHh7eT9BmBv9WhFKDQmDM5X+K4c0feFaJWJX4QeYb+JwNRjLHPfOl kxRw== X-Gm-Message-State: AOJu0YyxTIUqKmLfJir3o8T3Usw4Vm7AHiuUguX6+0B+8q/emQfjoLbD qIEXroGBqdCpx8mrYTsfJF6kLEYVZmLL++y2YdCfl7TVPm7KBoEMrwbJ8A== X-Google-Smtp-Source: AGHT+IG5hv3hJ7cEI3LJk4ma+fgfbM7/mnWK0sOIXdFVlyxMZT3rgNsBpD5rzYv5ljbYcJmVn9gIiw== X-Received: by 2002:a5d:4cc8:0:b0:37c:cfdc:19ba with SMTP id ffacd0b85a97d-37cd5aa6811mr3456352f8f.28.1727454809724; Fri, 27 Sep 2024 09:33:29 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v8 5/7] xen/riscv: introduce and initialize SBI RFENCE extension Date: Fri, 27 Sep 2024 18:33:17 +0200 Message-ID: X-Mailer: git-send-email 2.46.1 In-Reply-To: References: MIME-Version: 1.0 Introduce functions to work with the SBI RFENCE extension for issuing various fence operations to remote CPUs. Add the sbi_init() function along with auxiliary functions and macro definitions for proper initialization and checking the availability of SBI extensions. Currently, this is implemented only for RFENCE. Introduce sbi_remote_sfence_vma() to send SFENCE_VMA instructions to a set of target HARTs. This will support the implementation of flush_xen_tlb_range_va(). Integrate __sbi_rfence_v02 from Linux kernel 6.6.0-rc4 with minimal modifications: - Adapt to Xen code style. - Use cpuid_to_hartid() instead of cpuid_to_hartid_map[]. - Update BIT(...) to BIT(..., UL). - Rename __sbi_rfence_v02_call to sbi_rfence_v02_real and remove the unused arg5. - Handle NULL cpu_mask to execute rfence on all CPUs by calling sbi_rfence_v02_real(..., 0UL, -1UL,...) instead of creating hmask. - change type for start_addr and size to vaddr_t and size_t. - Add an explanatory comment about when batching can and cannot occur, and why batching happens in the first place. Signed-off-by: Oleksii Kurochko Acked-by: Jan Beulich --- xen/arch/riscv/include/asm/sbi.h | 62 +++++++ xen/arch/riscv/sbi.c | 273 ++++++++++++++++++++++++++++++- xen/arch/riscv/setup.c | 3 + 3 files changed, 337 insertions(+), 1 deletion(-) diff --git a/xen/arch/riscv/include/asm/sbi.h b/xen/arch/riscv/include/asm/sbi.h index 4d72a2295e..5947fed779 100644 --- a/xen/arch/riscv/include/asm/sbi.h +++ b/xen/arch/riscv/include/asm/sbi.h @@ -12,9 +12,42 @@ #ifndef __ASM_RISCV_SBI_H__ #define __ASM_RISCV_SBI_H__ +#include + #define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1 #define SBI_EXT_0_1_SHUTDOWN 0x8 +#define SBI_EXT_BASE 0x10 +#define SBI_EXT_RFENCE 0x52464E43 + +/* SBI function IDs for BASE extension */ +#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0 +#define SBI_EXT_BASE_GET_IMP_ID 0x1 +#define SBI_EXT_BASE_GET_IMP_VERSION 0x2 +#define SBI_EXT_BASE_PROBE_EXT 0x3 + +/* SBI function IDs for RFENCE extension */ +#define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0 +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA 0x1 +#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID 0x2 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA 0x3 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID 0x4 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5 +#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6 + +#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f000000 +#define SBI_SPEC_VERSION_MINOR_MASK 0x00ffffff + +/* SBI return error codes */ +#define SBI_SUCCESS 0 +#define SBI_ERR_FAILURE (-1) +#define SBI_ERR_NOT_SUPPORTED (-2) +#define SBI_ERR_INVALID_PARAM (-3) +#define SBI_ERR_DENIED (-4) +#define SBI_ERR_INVALID_ADDRESS (-5) + +#define SBI_SPEC_VERSION_DEFAULT 0x1 + struct sbiret { long error; long value; @@ -34,4 +67,33 @@ void sbi_console_putchar(int ch); void sbi_shutdown(void); +/* + * Check underlying SBI implementation has RFENCE + * + * @return true for supported AND false for not-supported + */ +bool sbi_has_rfence(void); + +/* + * Instructs the remote harts to execute one or more SFENCE.VMA + * instructions, covering the range of virtual addresses between + * [start_addr, start_addr + size). + * + * Returns 0 if IPI was sent to all the targeted harts successfully + * or negative value if start_addr or size is not valid. + * + * @hart_mask a cpu mask containing all the target harts. + * @param start virtual address start + * @param size virtual address range size + */ +int sbi_remote_sfence_vma(const cpumask_t *cpu_mask, vaddr_t start, + size_t size); + +/* + * Initialize SBI library + * + * @return 0 on success, otherwise negative errno on failure + */ +int sbi_init(void); + #endif /* __ASM_RISCV_SBI_H__ */ diff --git a/xen/arch/riscv/sbi.c b/xen/arch/riscv/sbi.c index c7984344bc..4209520389 100644 --- a/xen/arch/riscv/sbi.c +++ b/xen/arch/riscv/sbi.c @@ -5,13 +5,26 @@ * (anup.patel@wdc.com). * * Modified by Bobby Eshleman (bobby.eshleman@gmail.com). + * Modified by Oleksii Kurochko (oleksii.kurochko@gmail.com). * * Copyright (c) 2019 Western Digital Corporation or its affiliates. - * Copyright (c) 2021-2023 Vates SAS. + * Copyright (c) 2021-2024 Vates SAS. */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include +static unsigned long __ro_after_init sbi_spec_version = SBI_SPEC_VERSION_DEFAULT; + struct sbiret sbi_ecall(unsigned long ext, unsigned long fid, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, @@ -38,6 +51,26 @@ struct sbiret sbi_ecall(unsigned long ext, unsigned long fid, return ret; } +static int sbi_err_map_xen_errno(int err) +{ + switch ( err ) + { + case SBI_SUCCESS: + return 0; + case SBI_ERR_DENIED: + return -EACCES; + case SBI_ERR_INVALID_PARAM: + return -EINVAL; + case SBI_ERR_INVALID_ADDRESS: + return -EFAULT; + case SBI_ERR_NOT_SUPPORTED: + return -EOPNOTSUPP; + case SBI_ERR_FAILURE: + default: + return -ENOSYS; + }; +} + void sbi_console_putchar(int ch) { sbi_ecall(SBI_EXT_0_1_CONSOLE_PUTCHAR, 0, ch, 0, 0, 0, 0, 0); @@ -47,3 +80,241 @@ void sbi_shutdown(void) { sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); } + +static unsigned int sbi_major_version(void) +{ + return MASK_EXTR(sbi_spec_version, SBI_SPEC_VERSION_MAJOR_MASK); +} + +static unsigned int sbi_minor_version(void) +{ + return MASK_EXTR(sbi_spec_version, SBI_SPEC_VERSION_MINOR_MASK); +} + +static long sbi_ext_base_func(long fid) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); + + if ( !ret.error ) + { + /* + * I wasn't able to find a case in the SBI spec where sbiret.value + * could be negative. + * + * Unfortunately, the spec does not specify the possible values of + * sbiret.value, but based on the description of the SBI function, + * ret.value >= 0 when sbiret.error = 0. SPI spec specify only + * possible value for sbiret.error (<= 0 whwere 0 is SBI_SUCCESS ). + * + * Just to be sure that SBI base extension functions one day won't + * start to return a negative value for sbiret.value when + * sbiret.error < 0 BUG_ON() is added. + */ + BUG_ON(ret.value < 0); + + return ret.value; + } + else + return ret.error; +} + +static int sbi_rfence_v02_real(unsigned long fid, + unsigned long hmask, unsigned long hbase, + vaddr_t start, size_t size, + unsigned long arg4) +{ + struct sbiret ret = {0}; + int result = 0; + + switch ( fid ) + { + case SBI_EXT_RFENCE_REMOTE_FENCE_I: + ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase, + 0, 0, 0, 0); + break; + + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA: + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA: + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: + ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase, + start, size, 0, 0); + break; + + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID: + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID: + ret = sbi_ecall(SBI_EXT_RFENCE, fid, hmask, hbase, + start, size, arg4, 0); + break; + + default: + printk("%s: unknown function ID [%#lx]\n", + __func__, fid); + result = -EINVAL; + break; + }; + + if ( ret.error ) + { + result = sbi_err_map_xen_errno(ret.error); + printk("%s: hbase=%lu hmask=%#lx failed (error %ld)\n", + __func__, hbase, hmask, ret.error); + } + + return result; +} + +static int cf_check sbi_rfence_v02(unsigned long fid, + const cpumask_t *cpu_mask, + vaddr_t start, size_t size, + unsigned long arg4, unsigned long arg5) +{ + unsigned long hartid, cpuid, hmask = 0, hbase = 0, htop = 0; + int result = -EINVAL; + + /* + * hart_mask_base can be set to -1 to indicate that hart_mask can be + * ignored and all available harts must be considered. + */ + if ( !cpu_mask ) + return sbi_rfence_v02_real(fid, 0UL, -1UL, start, size, arg4); + + for_each_cpu ( cpuid, cpu_mask ) + { + /* + * Hart IDs might not necessarily be numbered contiguously in + * a multiprocessor system. + * + * This means that it is possible for the hart ID mapping to look like: + * 0, 1, 3, 65, 66, 69 + * In such cases, more than one call to sbi_rfence_v02_real() will be + * needed, as a single hmask can only cover sizeof(unsigned long) CPUs: + * 1. sbi_rfence_v02_real(hmask=0b1011, hbase=0) + * 2. sbi_rfence_v02_real(hmask=0b1011, hbase=65) + * + * The algorithm below tries to batch as many harts as possible before + * making an SBI call. However, batching may not always be possible. + * For example, consider the hart ID mapping: + * 0, 64, 1, 65, 2, 66 (1) + * + * Generally, batching is also possible for (1): + * First (0,1,2), then (64,65,66). + * It just requires a different approach and updates to the current + * algorithm. + */ + hartid = cpuid_to_hartid(cpuid); + if ( hmask ) + { + if ( hartid + BITS_PER_LONG <= htop || + hbase + BITS_PER_LONG <= hartid ) + { + result = sbi_rfence_v02_real(fid, hmask, hbase, + start, size, arg4); + hmask = 0; + if ( result ) + break; + } + else if ( hartid < hbase ) + { + /* shift the mask to fit lower hartid */ + hmask <<= hbase - hartid; + hbase = hartid; + } + } + + if ( !hmask ) + { + hbase = hartid; + htop = hartid; + } + else if ( hartid > htop ) + htop = hartid; + + hmask |= BIT(hartid - hbase, UL); + } + + if ( hmask ) + result = sbi_rfence_v02_real(fid, hmask, hbase, + start, size, arg4); + + return result; +} + +static int (* __ro_after_init sbi_rfence)(unsigned long fid, + const cpumask_t *cpu_mask, + vaddr_t start, + size_t size, + unsigned long arg4, + unsigned long arg5); + +int sbi_remote_sfence_vma(const cpumask_t *cpu_mask, vaddr_t start, + size_t size) +{ + ASSERT(sbi_rfence); + + return sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, + cpu_mask, start, size, 0, 0); +} + +/* This function must always succeed. */ +#define sbi_get_spec_version() \ + sbi_ext_base_func(SBI_EXT_BASE_GET_SPEC_VERSION) + +#define sbi_get_firmware_id() \ + sbi_ext_base_func(SBI_EXT_BASE_GET_IMP_ID) + +#define sbi_get_firmware_version() \ + sbi_ext_base_func(SBI_EXT_BASE_GET_IMP_VERSION) + +int sbi_probe_extension(long extid) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_BASE, SBI_EXT_BASE_PROBE_EXT, extid, + 0, 0, 0, 0, 0); + if ( !ret.error && ret.value ) + return ret.value; + + return sbi_err_map_xen_errno(ret.error); +} + +static bool sbi_spec_is_0_1(void) +{ + return (sbi_spec_version == SBI_SPEC_VERSION_DEFAULT); +} + +bool sbi_has_rfence(void) +{ + return (sbi_rfence != NULL); +} + +int __init sbi_init(void) +{ + sbi_spec_version = sbi_get_spec_version(); + + printk("SBI specification v%u.%u detected\n", + sbi_major_version(), sbi_minor_version()); + + if ( !sbi_spec_is_0_1() ) + { + long sbi_fw_id = sbi_get_firmware_id(); + long sbi_fw_version = sbi_get_firmware_version(); + + BUG_ON((sbi_fw_id < 0) || (sbi_fw_version < 0)); + + printk("SBI implementation ID=%#lx Version=%#lx\n", + sbi_fw_id, sbi_fw_version); + + if ( sbi_probe_extension(SBI_EXT_RFENCE) > 0 ) + { + sbi_rfence = sbi_rfence_v02; + printk("SBI v0.2 RFENCE extension detected\n"); + } + } + else + panic("Ooops. SBI spec version 0.1 detected. Need to add support"); + + return 0; +} diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c index 6e3a787dbe..c4fadd36c6 100644 --- a/xen/arch/riscv/setup.c +++ b/xen/arch/riscv/setup.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -48,6 +49,8 @@ void __init noreturn start_xen(unsigned long bootcpu_id, trap_init(); + sbi_init(); + #ifdef CONFIG_SELF_TESTS test_macros_from_bug_h(); #endif From patchwork Fri Sep 27 16:33:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Oleksii Kurochko X-Patchwork-Id: 13814462 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 5F132CDD1CD for ; Fri, 27 Sep 2024 16:38:37 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.806456.1217857 (Exim 4.92) (envelope-from ) id 1suDz0-00083T-9u; Fri, 27 Sep 2024 16:38:18 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 806456.1217857; Fri, 27 Sep 2024 16:38:18 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDz0-00083M-6s; Fri, 27 Sep 2024 16:38:18 +0000 Received: by outflank-mailman (input) for mailman id 806456; Fri, 27 Sep 2024 16:38:16 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuS-0001aC-U0 for xen-devel@lists.xenproject.org; Fri, 27 Sep 2024 16:33:37 +0000 Received: from mail-ed1-x532.google.com (mail-ed1-x532.google.com [2a00:1450:4864:20::532]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 3bde271f-7cee-11ef-99a2-01e77a169b0f; Fri, 27 Sep 2024 18:33:32 +0200 (CEST) Received: by mail-ed1-x532.google.com with SMTP id 4fb4d7f45d1cf-5c4146c7b28so2640037a12.2 for ; Fri, 27 Sep 2024 09:33:32 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a93c27d47a2sm150697966b.89.2024.09.27.09.33.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 09:33:30 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3bde271f-7cee-11ef-99a2-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727454811; x=1728059611; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=h4Ld+5lPduJk2yBXbctOw9z79Y28xifXYie/Iqgy91c=; b=V1y/fJqvbsHHrXXkHrG1QL2TkJ/3C/9ty5MvDLJNLbTy4uUjUA5g4gJ/Nj1rNXGyf0 bqSSafyiYBVwr1AgA8x833UVefO22wJ1pFhDAR2VxTP1G6h0vGn46JwWNiNSw90xzTZ7 FhkJgmL60SxsWAgzFJaAuVBbAgA4uwZ7s6bZtc8NwKE1XGSzUw4/9YzTa/WTRO2JsuXV Iw7BMAExi93PBMXjM9lX2j3EjlGgcvKgpxdA4aSSTiwi/4LFHF5iqur4/HPaszTxc4QY jNfv+QMCQncaZLYTimrjtKaxrTWqMx/Pa341+HFIjP3e/dc/d/MDv5PXhy93oqxGfq9T UmfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727454811; x=1728059611; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=h4Ld+5lPduJk2yBXbctOw9z79Y28xifXYie/Iqgy91c=; b=hlL3cS9oT+D71n4D8SrEgZcW7D/2N1mMAH1iXhXW4UKN9ADVJKf/vdkvkZ+/DMiZap dLvFH0+r7UxKLeuAZvLftFlABGMF07P68kKOv40r0FaMxoYppnBuyiCM4qmf0otRei1c EVp2TY09t4WQBRdZZoQTtqWKlkqMJoYqchtQ0xhU/IqHPHjVBoTbQJiJf6nX2hGniggZ ixnLFB+dZhIMMu1w/N3q0spqWcLrJxhyDRsPGbEHBlllQFCd5A89x+bL9IQ7+jvBZh9J 9Y0BICQw0MRYUWcGZ5KNZ2pGMPAE1xbIStglr1P5B7C86kwwI/cGKdRjqyyA2g2P8PPd D+Rw== X-Gm-Message-State: AOJu0YwCx9/P/bcK5zIaAQONGNScwxA8zfNG1vMKlMREMgr2SRgRayQH 2XZrJuZTjzQTCaXjr8EfmjGjf03/wzOf/KtW7LZBKop0aiph/yBUqWPODg== X-Google-Smtp-Source: AGHT+IF8teEmKIG4mTsq3h0tqrtMmJixRzLVLm2FcMMGLN6zCMd0xYrgm/qX2FjdDzaKwNQ2Y2NGTA== X-Received: by 2002:a17:907:7e85:b0:a8d:1284:6de5 with SMTP id a640c23a62f3a-a93c49042e6mr270527766b.14.1727454810863; Fri, 27 Sep 2024 09:33:30 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v8 6/7] xen/riscv: page table handling Date: Fri, 27 Sep 2024 18:33:18 +0200 Message-ID: X-Mailer: git-send-email 2.46.1 In-Reply-To: References: MIME-Version: 1.0 Implement map_pages_to_xen() which requires several functions to manage page tables and entries: - pt_update() - pt_mapping_level() - pt_update_entry() - pt_next_level() - pt_check_entry() To support these operations, add functions for creating, mapping, and unmapping Xen tables: - create_table() - map_table() - unmap_table() Introduce PTE_SMALL to indicate that 4KB mapping is needed and PTE_POPULATE. In addition introduce flush_tlb_range_va() for TLB flushing across CPUs after updating the PTE for the requested mapping. Signed-off-by: Oleksii Kurochko --- xen/arch/riscv/Makefile | 1 + xen/arch/riscv/include/asm/flushtlb.h | 9 + xen/arch/riscv/include/asm/mm.h | 2 + xen/arch/riscv/include/asm/page.h | 80 ++++ xen/arch/riscv/include/asm/riscv_encoding.h | 2 + xen/arch/riscv/mm.c | 9 - xen/arch/riscv/pt.c | 421 ++++++++++++++++++++ 7 files changed, 515 insertions(+), 9 deletions(-) create mode 100644 xen/arch/riscv/pt.c diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile index 6832549133..a5eb2aed4b 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-y += entry.o obj-y += mm.o +obj-y += pt.o obj-$(CONFIG_RISCV_64) += riscv64/ obj-y += sbi.o obj-y += setup.o diff --git a/xen/arch/riscv/include/asm/flushtlb.h b/xen/arch/riscv/include/asm/flushtlb.h index f4a735fd6c..43214f5e95 100644 --- a/xen/arch/riscv/include/asm/flushtlb.h +++ b/xen/arch/riscv/include/asm/flushtlb.h @@ -5,12 +5,21 @@ #include #include +#include + /* Flush TLB of local processor for address va. */ static inline void flush_tlb_one_local(vaddr_t va) { asm volatile ( "sfence.vma %0" :: "r" (va) : "memory" ); } +/* Flush a range of VA's hypervisor mappings from the TLB of all processors. */ +static inline void flush_tlb_range_va(vaddr_t va, size_t size) +{ + BUG_ON(!sbi_has_rfence()); + sbi_remote_sfence_vma(NULL, va, size); +} + /* * Filter the given set of CPUs, removing those that definitely flushed their * TLB since @page_timestamp. diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h index a0bdc2bc3a..ce1557bb27 100644 --- a/xen/arch/riscv/include/asm/mm.h +++ b/xen/arch/riscv/include/asm/mm.h @@ -42,6 +42,8 @@ static inline void *maddr_to_virt(paddr_t ma) #define virt_to_mfn(va) __virt_to_mfn(va) #define mfn_to_virt(mfn) __mfn_to_virt(mfn) +#define mfn_from_pte(pte) maddr_to_mfn(pte_to_paddr(pte)) + struct page_info { /* Each frame can be threaded onto a doubly-linked list. */ diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h index eb79cb9409..89fa290697 100644 --- a/xen/arch/riscv/include/asm/page.h +++ b/xen/arch/riscv/include/asm/page.h @@ -21,6 +21,11 @@ #define XEN_PT_LEVEL_MAP_MASK(lvl) (~(XEN_PT_LEVEL_SIZE(lvl) - 1)) #define XEN_PT_LEVEL_MASK(lvl) (VPN_MASK << XEN_PT_LEVEL_SHIFT(lvl)) +/* + * PTE format: + * | XLEN-1 10 | 9 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 + * PFN reserved for SW D A G U X W R V + */ #define PTE_VALID BIT(0, UL) #define PTE_READABLE BIT(1, UL) #define PTE_WRITABLE BIT(2, UL) @@ -34,15 +39,49 @@ #define PTE_LEAF_DEFAULT (PTE_VALID | PTE_READABLE | PTE_WRITABLE) #define PTE_TABLE (PTE_VALID) +#define PAGE_HYPERVISOR_RO (PTE_VALID | PTE_READABLE) #define PAGE_HYPERVISOR_RW (PTE_VALID | PTE_READABLE | PTE_WRITABLE) +#define PAGE_HYPERVISOR_RX (PTE_VALID | PTE_READABLE | PTE_EXECUTABLE) #define PAGE_HYPERVISOR PAGE_HYPERVISOR_RW +/* + * The PTE format does not contain the following bits within itself; + * they are created artificially to inform the Xen page table + * handling algorithm. These bits should not be explicitly written + * to the PTE entry. + */ +#define PTE_SMALL BIT(10, UL) +#define PTE_POPULATE BIT(11, UL) + +#define PTE_ACCESS_MASK (PTE_READABLE | PTE_WRITABLE | PTE_EXECUTABLE) + /* Calculate the offsets into the pagetables for a given VA */ #define pt_linear_offset(lvl, va) ((va) >> XEN_PT_LEVEL_SHIFT(lvl)) #define pt_index(lvl, va) (pt_linear_offset((lvl), (va)) & VPN_MASK) +#define PAGETABLE_ORDER_MASK ((_AC(1, U) << PAGETABLE_ORDER) - 1) +#define TABLE_OFFSET(offs) (_AT(unsigned int, offs) & PAGETABLE_ORDER_MASK) + +#if RV_STAGE1_MODE > SATP_MODE_SV39 +#error "need to to update DECLARE_OFFSETS macros" +#else + +#define l0_table_offset(va) TABLE_OFFSET(pt_linear_offset(0, va)) +#define l1_table_offset(va) TABLE_OFFSET(pt_linear_offset(1, va)) +#define l2_table_offset(va) TABLE_OFFSET(pt_linear_offset(2, va)) + +/* Generate an array @var containing the offset for each level from @addr */ +#define DECLARE_OFFSETS(var, addr) \ + const unsigned int var[] = { \ + l0_table_offset(addr), \ + l1_table_offset(addr), \ + l2_table_offset(addr), \ + } + +#endif + /* Page Table entry */ typedef struct { #ifdef CONFIG_RISCV_64 @@ -68,6 +107,47 @@ static inline bool pte_is_valid(pte_t p) return p.pte & PTE_VALID; } +/* + * From the RISC-V spec: + * The V bit indicates whether the PTE is valid; if it is 0, all other bits + * in the PTE are don’t-cares and may be used freely by software. + * + * If V=1 the encoding of PTE R/W/X bits could be find in "the encoding + * of the permission bits" table. + * + * The encoding of the permission bits table: + * X W R Meaning + * 0 0 0 Pointer to next level of page table. + * 0 0 1 Read-only page. + * 0 1 0 Reserved for future use. + * 0 1 1 Read-write page. + * 1 0 0 Execute-only page. + * 1 0 1 Read-execute page. + * 1 1 0 Reserved for future use. + * 1 1 1 Read-write-execute page. + */ +static inline bool pte_is_table(pte_t p) +{ + /* + * According to the spec if V=1 and W=1 then R also needs to be 1 as + * R = 0 is reserved for future use ( look at the Table 4.5 ) so check + * in ASSERT that if (V==1 && W==1) then R isn't 0. + * + * PAGE_HYPERVISOR_RW contains PTE_VALID too. + */ + ASSERT(((p.pte & PAGE_HYPERVISOR_RW) != (PTE_VALID | PTE_WRITABLE))); + + return ((p.pte & (PTE_VALID | PTE_ACCESS_MASK)) == PTE_VALID); +} + +static inline bool pte_is_mapping(pte_t p) +{ + /* See pte_is_table() */ + ASSERT(((p.pte & PAGE_HYPERVISOR_RW) != (PTE_VALID | PTE_WRITABLE))); + + return (p.pte & PTE_VALID) && (p.pte & PTE_ACCESS_MASK); +} + static inline void invalidate_icache(void) { BUG_ON("unimplemented"); diff --git a/xen/arch/riscv/include/asm/riscv_encoding.h b/xen/arch/riscv/include/asm/riscv_encoding.h index 58abe5eccc..e31e94e77e 100644 --- a/xen/arch/riscv/include/asm/riscv_encoding.h +++ b/xen/arch/riscv/include/asm/riscv_encoding.h @@ -164,6 +164,7 @@ #define SSTATUS_SD SSTATUS64_SD #define SATP_MODE SATP64_MODE #define SATP_MODE_SHIFT SATP64_MODE_SHIFT +#define SATP_PPN_MASK SATP64_PPN #define HGATP_PPN HGATP64_PPN #define HGATP_VMID_SHIFT HGATP64_VMID_SHIFT @@ -174,6 +175,7 @@ #define SSTATUS_SD SSTATUS32_SD #define SATP_MODE SATP32_MODE #define SATP_MODE_SHIFT SATP32_MODE_SHIFT +#define SATP_PPN_MASK SATP32_PPN #define HGATP_PPN HGATP32_PPN #define HGATP_VMID_SHIFT HGATP32_VMID_SHIFT diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index b8ff91cf4e..e8430def14 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -369,12 +369,3 @@ int destroy_xen_mappings(unsigned long s, unsigned long e) BUG_ON("unimplemented"); return -1; } - -int map_pages_to_xen(unsigned long virt, - mfn_t mfn, - unsigned long nr_mfns, - unsigned int flags) -{ - BUG_ON("unimplemented"); - return -1; -} diff --git a/xen/arch/riscv/pt.c b/xen/arch/riscv/pt.c new file mode 100644 index 0000000000..a5552a4871 --- /dev/null +++ b/xen/arch/riscv/pt.c @@ -0,0 +1,421 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static inline mfn_t get_root_page(void) +{ + paddr_t root_maddr = pfn_to_paddr(csr_read(CSR_SATP) & SATP_PPN_MASK); + + return maddr_to_mfn(root_maddr); +} + +/* + * Sanity check a page table entry about to be updated as per an (MFN,flags) + * tuple. + * See the comment about the possible combination of (mfn, flags) in + * the comment above pt_update(). + */ +static bool pt_check_entry(pte_t entry, mfn_t mfn, unsigned int flags) +{ + /* Sanity check when modifying an entry. */ + if ( (flags & PTE_VALID) && mfn_eq(mfn, INVALID_MFN) ) + { + /* We don't allow modifying an invalid entry. */ + if ( !pte_is_valid(entry) ) + { + dprintk(XENLOG_ERR, "Modifying invalid entry is not allowed\n"); + return false; + } + + /* We don't allow modifying a table entry */ + if ( pte_is_table(entry) ) + { + dprintk(XENLOG_ERR, "Modifying a table entry is not allowed\n"); + return false; + } + } + /* Sanity check when inserting a mapping */ + else if ( flags & PTE_VALID ) + { + /* + * We don't allow replacing any valid entry. + * + * Note that the function pt_update() relies on this + * assumption and will skip the TLB flush (when Svvptc + * extension will be ratified). The function will need + * to be updated if the check is relaxed. + */ + if ( pte_is_valid(entry) ) + { + if ( pte_is_mapping(entry) ) + dprintk(XENLOG_ERR, "Changing MFN for valid PTE is not allowed (%#"PRI_mfn" -> %#"PRI_mfn")\n", + mfn_x(mfn_from_pte(entry)), mfn_x(mfn)); + else + dprintk(XENLOG_ERR, "Trying to replace table with mapping\n"); + return false; + } + } + /* Sanity check when removing a mapping. */ + else if ( !(flags & PTE_POPULATE) ) + { + /* We should be here with an invalid MFN. */ + ASSERT(mfn_eq(mfn, INVALID_MFN)); + + /* We don't allow removing a table */ + if ( pte_is_table(entry) ) + { + dprintk(XENLOG_ERR, "Removing a table is not allowed\n"); + return false; + } + } + /* Sanity check when populating the page-table. No check so far. */ + else + { + /* We should be here with an invalid MFN */ + ASSERT(mfn_eq(mfn, INVALID_MFN)); + } + + return true; +} + +static pte_t *map_table(mfn_t mfn) +{ + /* + * During early boot, map_domain_page() may be unusable. Use the + * PMAP to map temporarily a page-table. + */ + if ( system_state == SYS_STATE_early_boot ) + return pmap_map(mfn); + + return map_domain_page(mfn); +} + +static void unmap_table(const pte_t *table) +{ + /* + * During early boot, map_table() will not use map_domain_page() + * but the PMAP. + */ + if ( system_state == SYS_STATE_early_boot ) + pmap_unmap(table); + else + unmap_domain_page(table); +} + +static int create_table(pte_t *entry) +{ + mfn_t mfn; + void *p; + pte_t pte; + + if ( system_state != SYS_STATE_early_boot ) + { + struct page_info *pg = alloc_domheap_page(NULL, 0); + + if ( pg == NULL ) + return -ENOMEM; + + mfn = page_to_mfn(pg); + } + else + mfn = alloc_boot_pages(1, 1); + + p = map_table(mfn); + clear_page(p); + unmap_table(p); + + pte = pte_from_mfn(mfn, PTE_TABLE); + write_pte(entry, pte); + + return 0; +} + +#define XEN_TABLE_MAP_NONE 0 +#define XEN_TABLE_MAP_NOMEM 1 +#define XEN_TABLE_SUPER_PAGE 2 +#define XEN_TABLE_NORMAL 3 + +/* + * Take the currently mapped table, find the corresponding entry, + * and map the next table, if available. + * + * The alloc_tbl parameters indicates whether intermediate tables should + * be allocated when not present. + * + * Return values: + * XEN_TABLE_MAP_FAILED: Either alloc_only was set and the entry + * was empty, or allocating a new page failed. + * XEN_TABLE_NORMAL: next level or leaf mapped normally + * XEN_TABLE_SUPER_PAGE: The next entry points to a superpage. + */ +static int pt_next_level(bool alloc_tbl, pte_t **table, unsigned int offset) +{ + pte_t *entry; + mfn_t mfn; + + entry = *table + offset; + + if ( !pte_is_valid(*entry) ) + { + if ( !alloc_tbl ) + return XEN_TABLE_MAP_NONE; + + if ( create_table(entry) ) + return XEN_TABLE_MAP_NOMEM; + } + + if ( pte_is_mapping(*entry) ) + return XEN_TABLE_SUPER_PAGE; + + mfn = mfn_from_pte(*entry); + + unmap_table(*table); + *table = map_table(mfn); + + return XEN_TABLE_NORMAL; +} + +/* Update an entry at the level @target. */ +static int pt_update_entry(mfn_t root, vaddr_t virt, + mfn_t mfn, unsigned int target, + unsigned int flags) +{ + int rc; + unsigned int level = HYP_PT_ROOT_LEVEL; + pte_t *table; + /* + * The intermediate page table shouldn't be allocated when MFN isn't + * valid and we are not populating page table. + * This means we either modify permissions or remove an entry, or + * inserting brand new entry. + * + * See the comment above pt_update() for an additional explanation about + * combinations of (mfn, flags). + */ + bool alloc_tbl = !mfn_eq(mfn, INVALID_MFN) || (flags & PTE_POPULATE); + pte_t pte, *entry; + + /* convenience aliases */ + DECLARE_OFFSETS(offsets, virt); + + table = map_table(root); + for ( ; level > target; level-- ) + { + rc = pt_next_level(alloc_tbl, &table, offsets[level]); + if ( rc == XEN_TABLE_MAP_NOMEM ) + { + rc = -ENOMEM; + goto out; + } + + if ( rc == XEN_TABLE_MAP_NONE ) + { + rc = 0; + goto out; + } + + if ( rc != XEN_TABLE_NORMAL ) + break; + } + + if ( level != target ) + { + dprintk(XENLOG_ERR, + "%s: Shattering superpage is not supported\n", __func__); + rc = -EOPNOTSUPP; + goto out; + } + + entry = table + offsets[level]; + + rc = -EINVAL; + if ( !pt_check_entry(*entry, mfn, flags) ) + goto out; + + /* We are removing the page */ + if ( !(flags & PTE_VALID) ) + /* + * There is also a check in pt_check_entry() which check that + * mfn=INVALID_MFN + */ + pte.pte = 0; + else + { + /* We are inserting a mapping => Create new pte. */ + if ( !mfn_eq(mfn, INVALID_MFN) ) + pte = pte_from_mfn(mfn, PTE_VALID); + else /* We are updating the permission => Copy the current pte. */ + { + pte = *entry; + pte.pte &= ~PTE_ACCESS_MASK; + } + + /* update permission according to the flags */ + pte.pte |= (flags & PTE_ACCESS_MASK) | PTE_ACCESSED | PTE_DIRTY; + } + + write_pte(entry, pte); + + rc = 0; + + out: + unmap_table(table); + + return rc; +} + +/* Return the level where mapping should be done */ +static int pt_mapping_level(unsigned long vfn, mfn_t mfn, unsigned long nr, + unsigned int flags) +{ + unsigned int level = 0; + unsigned long mask; + unsigned int i; + + /* + * Use a larger mapping than 4K unless the caller specifically requests + * 4K mapping + */ + if ( unlikely(flags & PTE_SMALL) ) + return level; + + /* + * Don't take into account the MFN when removing mapping (i.e + * MFN_INVALID) to calculate the correct target order. + * + * `vfn` and `mfn` must be both superpage aligned. + * They are or-ed together and then checked against the size of + * each level. + * + * `left` ( variable declared in pt_update() ) is not included + * and checked separately to allow superpage mapping even if it + * is not properly aligned (the user may have asked to map 2MB + 4k). + */ + mask = !mfn_eq(mfn, INVALID_MFN) ? mfn_x(mfn) : 0; + mask |= vfn; + + for ( i = HYP_PT_ROOT_LEVEL; i != 0; i-- ) + { + if ( !(mask & (BIT(XEN_PT_LEVEL_ORDER(i), UL) - 1)) && + (nr >= BIT(XEN_PT_LEVEL_ORDER(i), UL)) ) + { + level = i; + break; + } + } + + return level; +} + +static DEFINE_SPINLOCK(pt_lock); + +/* + * If `mfn` equals `INVALID_MFN`, it indicates that the following page table + * update operation might be related to either: + * - populating the table (PTE_POPULATE will be set additionaly), + * - destroying a mapping (PTE_VALID=0), + * - modifying an existing mapping (PTE_VALID=1). + * + * If `mfn` != INVALID_MFN and flags has PTE_VALID bit set then it means that + * inserting will be done. + */ +static int pt_update(vaddr_t virt, mfn_t mfn, + unsigned long nr_mfns, unsigned int flags) +{ + int rc = 0; + unsigned long vfn = PFN_DOWN(virt); + unsigned long left = nr_mfns; + const mfn_t root = get_root_page(); + + /* + * It is bad idea to have mapping both writeable and + * executable. + * When modifying/creating mapping (i.e PTE_VALID is set), + * prevent any update if this happen. + */ + if ( (flags & PTE_VALID) && (flags & PTE_WRITABLE) && + (flags & PTE_EXECUTABLE) ) + { + dprintk(XENLOG_ERR, + "Mappings should not be both Writeable and Executable\n"); + return -EINVAL; + } + + if ( !IS_ALIGNED(virt, PAGE_SIZE) ) + { + dprintk(XENLOG_ERR, + "The virtual address is not aligned to the page-size\n"); + return -EINVAL; + } + + spin_lock(&pt_lock); + + while ( left ) + { + unsigned int order, level; + + level = pt_mapping_level(vfn, mfn, left, flags); + order = XEN_PT_LEVEL_ORDER(level); + + ASSERT(left >= BIT(order, UL)); + + rc = pt_update_entry(root, vfn << PAGE_SHIFT, mfn, level, flags); + if ( rc ) + break; + + vfn += 1UL << order; + if ( !mfn_eq(mfn, INVALID_MFN) ) + mfn = mfn_add(mfn, 1UL << order); + + left -= (1UL << order); + } + + /* Ensure that PTEs are all updated before flushing */ + RISCV_FENCE(rw, rw); + + spin_unlock(&pt_lock); + + /* + * Always flush TLB at the end of the function as non-present entries + * can be put in the TLB. + * + * The remote fence operation applies to the entire address space if + * either: + * - start and size are both 0, or + * - size is equal to 2^XLEN-1. + * + * TODO: come up with something which will allow not to flash the entire + * address space. + */ + flush_tlb_range_va(0, 0); + + return rc; +} + +int map_pages_to_xen(unsigned long virt, + mfn_t mfn, + unsigned long nr_mfns, + unsigned int flags) +{ + /* + * Ensure that flags has PTE_VALID bit as map_pages_to_xen() is supposed + * to create a mapping. + * + * Ensure that we have a valid MFN before proceeding. + * + * If the MFN is invalid, pt_update() might misinterpret the operation, + * treating it as either a population, a mapping destruction, + * or a mapping modification. + */ + ASSERT(!mfn_eq(mfn, INVALID_MFN) && (flags & PTE_VALID)); + + return pt_update(virt, mfn, nr_mfns, flags); +} From patchwork Fri Sep 27 16:33:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleksii Kurochko X-Patchwork-Id: 13814464 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 140E3CDD1CE for ; Fri, 27 Sep 2024 16:38:48 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.806466.1217877 (Exim 4.92) (envelope-from ) id 1suDzM-0000T8-TA; Fri, 27 Sep 2024 16:38:40 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 806466.1217877; Fri, 27 Sep 2024 16:38:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDzM-0000Sz-Q1; Fri, 27 Sep 2024 16:38:40 +0000 Received: by outflank-mailman (input) for mailman id 806466; Fri, 27 Sep 2024 16:38:39 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1suDuT-0001aC-UI for xen-devel@lists.xenproject.org; Fri, 27 Sep 2024 16:33:37 +0000 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [2a00:1450:4864:20::535]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 3c35a461-7cee-11ef-99a2-01e77a169b0f; Fri, 27 Sep 2024 18:33:32 +0200 (CEST) Received: by mail-ed1-x535.google.com with SMTP id 4fb4d7f45d1cf-5c5b9d2195eso2758619a12.1 for ; Fri, 27 Sep 2024 09:33:32 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a93c27d47a2sm150697966b.89.2024.09.27.09.33.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Sep 2024 09:33:31 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3c35a461-7cee-11ef-99a2-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727454812; x=1728059612; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ghl72hwaxwhJtVodRAQ4IqGk8w7bdQ1cXJih3Z6pDfI=; b=aJmNJ4bmjR1x27STdMBQx9CMBLQIQQGtNzyMZuDyfqLbc3QeSjojkmQ8kk+tZRFlrl Qbobq4JVaWnkZTHCsrCVX4qvvetK9C/7iS95GqYkbIAwauYE3K66Pac1DuZP00/lALQ2 ScBGutzmQ4LxL0L7sFtr09lh/C6xfqFid6b7VAul0X2CAn0MIzibofPUcYlfOKJyqtX9 hgM1NgpzPZekdFxWscRI/7GcOKKGd3KP7TQ2YzeuYSHVbE2dE0aP364+WCEeZJTkzTUl tfBV8HNu3/4KVfYGEQG3ihcewW8rYkFelWmKOE6NhcYifpLVnz3TdFfLp8vCyypvhWV9 1Mcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727454812; x=1728059612; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ghl72hwaxwhJtVodRAQ4IqGk8w7bdQ1cXJih3Z6pDfI=; b=ruTh7/1wrct3cPtL/JnijsI7ufxq/X/N+DDjDNKhYXqdEkhSxzndwv6IZsvD7KdA1F +ZPI0i1uAzDCAbgrvcyy8/pvrb0sD9sOss9rZ20dR9wxPAAX2tUoDzspBHVb43k78GK4 vhU6vkr1pdknSavXgpgt+DHBL9zDNRv+QO5yhwQKzBMcN1y3ZUWAWeqsicG1yD4CxBaz ofHTzcSnae0KKIVliWxaFoAH+uxCag1Lo4U4uqp6wD09iK/HHxQGxKeo4nOF/ClstVBq I3JWdNW7WVIDQvTi+vNnkN7mxWeaPy9i2gdu0A4b6VHJ1GROBUYkx4gVhRDvwqkbm5bZ nwWg== X-Gm-Message-State: AOJu0Yx5qUxLHzmn8JjiAova0hebdjM/UzRDoDaRVe9/HDQujcokNqAC rQJ/4Tp5KAVOXftXJbwV+jmBY7y3qRZe7gXszG8EdavkZ86UmylSWhZoAQ== X-Google-Smtp-Source: AGHT+IFg4M+WfEDQE2Zk/Wh79VNEHm6x6c0tNkZGB1AmvmEqyvMOU0ctCqPpEzyJeQRLNVjYWdLLug== X-Received: by 2002:a17:906:730d:b0:a7a:a0c2:8be9 with SMTP id a640c23a62f3a-a93c4908e28mr387347866b.18.1727454811793; Fri, 27 Sep 2024 09:33:31 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Bob Eshleman , Connor Davis , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini Subject: [PATCH v8 7/7] xen/riscv: introduce early_fdt_map() Date: Fri, 27 Sep 2024 18:33:19 +0200 Message-ID: <65c49e7aa25249cd94be3ce9b850d023c9dff731.1727449154.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.46.1 In-Reply-To: References: MIME-Version: 1.0 Introduce function which allows to map FDT to Xen. Also, initialization of device_tree_flattened happens using early_fdt_map(). Signed-off-by: Oleksii Kurochko Acked-by: Jan Beulich --- xen/arch/riscv/include/asm/mm.h | 2 ++ xen/arch/riscv/mm.c | 55 +++++++++++++++++++++++++++++++++ xen/arch/riscv/setup.c | 7 +++++ 3 files changed, 64 insertions(+) diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h index ce1557bb27..4b7b00b850 100644 --- a/xen/arch/riscv/include/asm/mm.h +++ b/xen/arch/riscv/include/asm/mm.h @@ -259,4 +259,6 @@ static inline unsigned int arch_get_dma_bitsize(void) void setup_fixmap_mappings(void); +void *early_fdt_map(paddr_t fdt_paddr); + #endif /* _ASM_RISCV_MM_H */ diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index e8430def14..4a628aef83 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -1,13 +1,16 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include #include +#include #include #include #include #include +#include #include #include @@ -369,3 +372,55 @@ int destroy_xen_mappings(unsigned long s, unsigned long e) BUG_ON("unimplemented"); return -1; } + +void * __init early_fdt_map(paddr_t fdt_paddr) +{ + /* We are using 2MB superpage for mapping the FDT */ + paddr_t base_paddr = fdt_paddr & XEN_PT_LEVEL_MAP_MASK(1); + paddr_t offset; + void *fdt_virt; + uint32_t size; + int rc; + + /* + * Check whether the physical FDT address is set and meets the minimum + * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be at + * least 8 bytes so that we always access the magic and size fields + * of the FDT header after mapping the first chunk, double check if + * that is indeed the case. + */ + BUILD_BUG_ON(MIN_FDT_ALIGN < 8); + if ( !fdt_paddr || fdt_paddr % MIN_FDT_ALIGN ) + return NULL; + + /* The FDT is mapped using 2MB superpage */ + BUILD_BUG_ON(BOOT_FDT_VIRT_START % MB(2)); + + rc = map_pages_to_xen(BOOT_FDT_VIRT_START, maddr_to_mfn(base_paddr), + MB(2) >> PAGE_SHIFT, + PAGE_HYPERVISOR_RO); + if ( rc ) + panic("Unable to map the device-tree.\n"); + + offset = fdt_paddr % XEN_PT_LEVEL_SIZE(1); + fdt_virt = (void *)BOOT_FDT_VIRT_START + offset; + + if ( fdt_magic(fdt_virt) != FDT_MAGIC ) + return NULL; + + size = fdt_totalsize(fdt_virt); + if ( size > BOOT_FDT_VIRT_SIZE ) + return NULL; + + if ( (offset + size) > MB(2) ) + { + rc = map_pages_to_xen(BOOT_FDT_VIRT_START + MB(2), + maddr_to_mfn(base_paddr + MB(2)), + MB(2) >> PAGE_SHIFT, + PAGE_HYPERVISOR_RO); + if ( rc ) + panic("Unable to map the device-tree\n"); + } + + return fdt_virt; +} diff --git a/xen/arch/riscv/setup.c b/xen/arch/riscv/setup.c index c4fadd36c6..a316901fd4 100644 --- a/xen/arch/riscv/setup.c +++ b/xen/arch/riscv/setup.c @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,12 @@ void __init noreturn start_xen(unsigned long bootcpu_id, setup_fixmap_mappings(); + device_tree_flattened = early_fdt_map(dtb_addr); + if ( !device_tree_flattened ) + panic("Invalid device tree blob at physical address %#lx. The DTB must be 8-byte aligned and must not exceed %lld bytes in size.\n\n" + "Please check your bootloader.\n", + dtb_addr, BOOT_FDT_VIRT_SIZE); + printk("All set up\n"); machine_halt();