From nobody Fri Dec 19 22:06:12 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1653980960; cv=none; d=zohomail.com; s=zohoarc; b=KPcxUppe0Yk3Knec0QmixHpxeCaGxRV2lyPvE9flnp4nucwR5T0u71o+42JGFwSC2aHa3WUWF7N/SdJ1jOHsMwt18bxDpP2pywQmrg5UVqv7KSgyxp74EhLAlXDVaD5LXSkGrBijLAXfGYeWY2F6uIihF8NXB7eAMwN9frAik3E= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1653980960; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=eX+ztoF4ccJF8k/eqM9yWtCts93a8EoroUDLXMjz3+c=; b=BXB+ZyTZMW9h/1bJY7HuEepjTyV2uGb8pvvz5tr6JCK5zsl6sLiw+er6VIEgSfFnzHOn4WfESgW2tH+3pX4t0UG+XtUDlHEN3J6BcrN3Zcw4f2jgqVUeO9/OvY8fYzLwvp7qMj/jGS63SJDrSMXtt5d3KBKrQ0vr+QtcrPuMJkc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1653980960484467.2816487422317; Tue, 31 May 2022 00:09:20 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.339122.563948 (Exim 4.92) (envelope-from ) id 1nvvzi-0000qs-IN; Tue, 31 May 2022 07:08:46 +0000 Received: by outflank-mailman (output) from mailman id 339122.563948; Tue, 31 May 2022 07:08:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1nvvzi-0000qB-Eo; Tue, 31 May 2022 07:08:46 +0000 Received: by outflank-mailman (input) for mailman id 339122; Tue, 31 May 2022 06:57:58 +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 1nvvpG-00080v-8j for xen-devel@lists.xenproject.org; Tue, 31 May 2022 06:57:58 +0000 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [2a00:1450:4864:20::42c]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id fcff5801-e0ae-11ec-837f-e5687231ffcc; Tue, 31 May 2022 08:57:51 +0200 (CEST) Received: by mail-wr1-x42c.google.com with SMTP id s24so9970727wrb.10 for ; Mon, 30 May 2022 23:57:56 -0700 (PDT) Received: from localhost ([2a03:b0c0:1:d0::944:e002]) by smtp.gmail.com with ESMTPSA id m19-20020a05600c4f5300b003942a244f2esm1322707wmq.7.2022.05.30.23.57.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 May 2022 23:57:55 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version 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: fcff5801-e0ae-11ec-837f-e5687231ffcc DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eX+ztoF4ccJF8k/eqM9yWtCts93a8EoroUDLXMjz3+c=; b=No8PvNxyNem0mBq0AAqZNlO/B8Sa7VmBm0BYQzDRGDwhGgIwH771G5tX8l1C199ZEF XgihrXOLf/x4+LJNXBNgQp0UCE7iRUHBvFA6Pn/c5iNneoNOldgvVlXbv5DzW41yDYuL zqugKijI3zr0lemPTJjMjgXh+yPKQTn8fZg7T+nbpfp3B2JTFgWLs/MYDuYDQvBo5QTv gd3SHk+UvldhL+oTLuBCTrIcUFBtpRtU86s+8IC3gsBaL9krAWU0DJNeA+5pNm8PtTnh +FHvN72N2C1MA3BuwKcKDdqfc/WGBpXOECn+qqIoFYO8s4E9WNqgVlOg3kvTGkH1M2rl FRhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eX+ztoF4ccJF8k/eqM9yWtCts93a8EoroUDLXMjz3+c=; b=2aFI5eYNxMFS58qINv1UF1UFoFN8VGhg9eVteMpuPcixMI1pcahTkgEvkIJXZQhN6l OvAVBef9hOYRFaYiKfq2tVdncN2oH8Sgi/Lp7r8IrxQkRalyO9ofxaZ+nOJSRiIR5l7Z jQKD33vwTWft4lIAJNCUWoEowhSyeoCpZhFNwMJh2Wq9VSqYvS02vXXkmQ+/VyfNNOJd ra8lca3Xdlg/avGObql1AFaYr5zs1waBoaFzv2oHyODQWOJjJpZ4Vj2qDflW0o0MGTgG I9xEJt9ixa2IdEevlpr40eP/qpfhMjWnIa63EUsJKGr07UzRkBeetorWkuHsdEFx58ms 39/Q== X-Gm-Message-State: AOAM532vVjlAL04z+eDcjwEn5gsNeGgLK7qj825sEtVMW4F3tBoj5phB JCjkxv1/y/Ay0AH6/DNc82I6TX5V/Vc= X-Google-Smtp-Source: ABdhPJwpu7/xA7yXAXr68E7aFhi7RWpGZld0Yat8+AE4OcjjJKMVLWopCdMwcFhHh0eKynSB3/zAiw== X-Received: by 2002:adf:f38f:0:b0:210:30cf:6e4a with SMTP id m15-20020adff38f000000b0021030cf6e4amr8560078wro.676.1653980275934; Mon, 30 May 2022 23:57:55 -0700 (PDT) From: Xie Xun To: xen-devel@lists.xenproject.org Cc: Xie Xun , Bob Eshleman , Alistair Francis , Connor Davis Subject: [RFC PATCH 2/6] xen/riscv: Add early page table setup code. Date: Tue, 31 May 2022 14:57:08 +0800 Message-Id: <94a7c66306c31113c808f2a33664ab84b09db4ec.1653977696.git.xiexun162534@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1653980961866100002 Content-Type: text/plain; charset="utf-8" This code sets up initial page table. Signed-off-by: Xie Xun --- xen/arch/riscv/mm.c | 224 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index f366b1ca0c..074a2a4396 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -81,6 +81,17 @@ unsigned long xenheap_base_pdx __read_mostly; unsigned long frametable_virt_end __read_mostly; unsigned long frametable_base_pdx; =20 +/* + * xen_second_pagetable is indexed with the VPN[2] page table entry field + * xen_first_pagetable is accessed from the VPN[1] page table entry field + * xen_zeroeth_pagetable is accessed from the VPN[0] page table entry field + */ +pte_t xen_second_pagetable[PAGE_ENTRIES] __attribute__((__aligned__(4096))= ); +static pte_t xen_first_pagetable[PAGE_ENTRIES] + __attribute__((__aligned__(4096))); +static pte_t xen_zeroeth_pagetable[PAGE_ENTRIES] + __attribute__((__aligned__(4096))); + static pte_t xen_fixmap[PAGE_ENTRIES] __attribute__((__aligned__(4096))); =20 #define THIS_CPU_PGTABLE xen_second_pagetable @@ -374,6 +385,219 @@ unsigned long get_upper_mfn_bound(void) return max_page - 1; } =20 +/* Set up leaf pages in a first-level page table. */ +void setup_megapages(pte_t *first_pagetable, unsigned long virtual_start, + unsigned long physical_start, unsigned long page_cnt) +{ + unsigned long frame_addr =3D physical_start; + unsigned long end =3D physical_start + (page_cnt << PAGE_SHIFT); + unsigned long vaddr =3D virtual_start; + unsigned long index; + pte_t *p; + + BUG_ON(!IS_ALIGNED(physical_start, FIRST_SIZE)); + + while ( frame_addr < end ) + { + index =3D pagetable_first_index(vaddr); + p =3D &first_pagetable[index]; + p->pte =3D paddr_to_megapage_ppn(frame_addr); + p->pte |=3D PTE_LEAF_DEFAULT; + + frame_addr +=3D FIRST_SIZE; + vaddr +=3D FIRST_SIZE; + } +} + +#define resolve_early_addr(x) \ + ({ = \ + unsigned long * __##x; = \ + if ( load_addr_start <=3D x && x < load_addr_end ) = \ + __##x =3D (unsigned long *)x; = \ + else = \ + __##x =3D (unsigned long *)(x + load_addr_start - linker_addr_= start); \ + __##x; = \ + }) + +void __init clear_pagetables(unsigned long load_addr_start, + unsigned long load_addr_end, + unsigned long linker_addr_start, + unsigned long linker_addr_end) +{ + unsigned long *p; + unsigned long page; + unsigned long i; + + page =3D (unsigned long)&xen_second_pagetable[0]; + + p =3D resolve_early_addr(page); + for ( i =3D 0; i < ARRAY_SIZE(xen_second_pagetable); i++ ) + { + p[i] =3D 0ULL; + } + + page =3D (unsigned long)&xen_first_pagetable[0]; + p =3D resolve_early_addr(page); + for ( i =3D 0; i < ARRAY_SIZE(xen_first_pagetable); i++ ) + { + p[i] =3D 0ULL; + } + + page =3D (unsigned long)&xen_zeroeth_pagetable[0]; + p =3D resolve_early_addr(page); + for ( i =3D 0; i < ARRAY_SIZE(xen_zeroeth_pagetable); i++ ) + { + p[i] =3D 0ULL; + } +} + +void __attribute__((section(".entry"))) +setup_initial_pagetables(pte_t *second, pte_t *first, pte_t *zeroeth, + unsigned long map_start, unsigned long map_end, + unsigned long pa_start) +{ + unsigned long page_addr; + unsigned long index2; + unsigned long index1; + unsigned long index0; + + /* align start addresses */ + map_start &=3D ZEROETH_MAP_MASK; + pa_start &=3D ZEROETH_MAP_MASK; + + page_addr =3D map_start; + while ( page_addr < map_end ) + { + index2 =3D pagetable_second_index(page_addr); + index1 =3D pagetable_first_index(page_addr); + index0 =3D pagetable_zeroeth_index(page_addr); + + /* Setup level2 table */ + second[index2] =3D paddr_to_pte((unsigned long)first); + second[index2].pte |=3D PTE_TABLE; + + /* Setup level1 table */ + first[index1] =3D paddr_to_pte((unsigned long)zeroeth); + first[index1].pte |=3D PTE_TABLE; + + /* Setup level0 table */ + if ( !pte_is_valid(&zeroeth[index0]) ) + { + /* Update level0 table */ + zeroeth[index0] =3D paddr_to_pte((page_addr - map_start) + pa_= start); + zeroeth[index0].pte |=3D PTE_LEAF_DEFAULT; + } + + /* Point to next page */ + page_addr +=3D ZEROETH_SIZE; + } +} + +/* + * WARNING: load_addr() and linker_addr() are to be called only when the M= MU is + * disabled and only when executed by the primary CPU. They cannot refer = to + * any global variable or functions. + */ + +/* + * Convert an addressed layed out at link time to the address where it was= loaded + * by the bootloader. + */ +#define load_addr(linker_address) = \ + ({ = \ + unsigned long __linker_address =3D (unsigned long)(linker_address)= ; \ + if ( linker_addr_start <=3D __linker_address && = \ + __linker_address < linker_addr_end ) = \ + { = \ + __linker_address =3D = \ + __linker_address - linker_addr_start + load_addr_start; = \ + } = \ + __linker_address; = \ + }) + +/* Convert boot-time Xen address from where it was loaded by the boot load= er to the address it was layed out + * at link-time. + */ +#define linker_addr(load_address) = \ + ({ = \ + unsigned long __load_address =3D (unsigned long)(load_address); = \ + if ( load_addr_start <=3D __load_address && = \ + __load_address < load_addr_end ) = \ + { = \ + __load_address =3D = \ + __load_address - load_addr_start + linker_addr_start; = \ + } = \ + __load_address; = \ + }) + +/* + * _setup_initial_pagetables: + * + * 1) Build the page tables for Xen that map the following: + * 1.1) The physical location of Xen (where the bootloader loaded it) + * 1.2) The link-time location of Xen (where the linker expected Xen's + * addresses to be) + * 2) Load the page table into the SATP and enable the MMU + */ +void __attribute__((section(".entry"))) +_setup_initial_pagetables(unsigned long load_addr_start, + unsigned long load_addr_end, + unsigned long linker_addr_start, + unsigned long linker_addr_end) +{ + pte_t *second; + pte_t *first; + pte_t *zeroeth; + + clear_pagetables(load_addr_start, load_addr_end, + linker_addr_start, linker_addr_end); + + /* Get the addresses where the page tables were loaded */ + second =3D (pte_t *)load_addr(&xen_second_pagetable); + first =3D (pte_t *)load_addr(&xen_first_pagetable); + zeroeth =3D (pte_t *)load_addr(&xen_zeroeth_pagetable); + + /* + * Create a mapping of the load time address range to... the load time= address range. + * This mapping is used at boot time only. + */ + setup_initial_pagetables(second, first, zeroeth, load_addr_start, + load_addr_end, load_addr_start); + + /* + * Create a mapping from Xen's link-time addresses to where they were = actually loaded. + * + * TODO: Protect regions accordingly (e.g., protect text and rodata fr= om writes). + */ + setup_initial_pagetables(second, first, zeroeth, linker_addr(&_text_st= art), + linker_addr(&_text_end), load_addr(&_text_sta= rt)); + setup_initial_pagetables(second, first, zeroeth, linker_addr(&_init_st= art), + linker_addr(&_init_end), load_addr(&_init_sta= rt)); + setup_initial_pagetables(second, first, zeroeth, + linker_addr(&_cpuinit_start), + linker_addr(&_cpuinit_end), + load_addr(&_cpuinit_start)); + setup_initial_pagetables(second, first, zeroeth, + linker_addr(&_spinlock_start), + linker_addr(&_spinlock_end), + load_addr(&_spinlock_start)); + setup_initial_pagetables(second, first, zeroeth, + linker_addr(&_rodata_start), + linker_addr(&_rodata_end), + load_addr(&_rodata_start)); + setup_initial_pagetables(second, first, zeroeth, linker_addr_start, + linker_addr_end, load_addr_start); + + /* Ensure page table writes precede loading the SATP */ + asm volatile("sfence.vma"); + + /* Enable the MMU and load the new pagetable for Xen */ + csr_write(CSR_SATP, + (load_addr(xen_second_pagetable) >> PAGE_SHIFT) | SATP_MODE_= SV39 << SATP_MODE_SHIFT); + + phys_offset =3D load_addr_start - linker_addr_start; +} + /* * Map the table that pte points to. */ --=20 2.30.2