From patchwork Mon Aug 12 13:44:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 1971601 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=yz0gv24D; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linux.dev header.i=@linux.dev header.a=rsa-sha256 header.s=key1 header.b=w5xypioI; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WjG3n01vRz1yXl for ; Mon, 12 Aug 2024 23:45:09 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=7vIod1dz5A9pNYfOjGaETc1u3vzCYWxkNMtnxo43jDM=; b=yz0gv24DwuxTp/ ii0buPw5rSbdAsmhmGcDnVB6bPey7zK/8YzsNDokD2YZGJ7/X+Km6uUA2s02rPvXABfo9ozo93hzs kM0Lwj4zk+t+QTCNdLOvpXjMlWV3nOWk4LxmasebCsKYLzVVlOcOvmVYo5dMAIm8XMH1MmhKudIE4 pGqBWYxPCTjljnlIbqYfyacgTnX0/vR92s1hpeUyjeGCb+nAIu1LiWemOXM2dDSymogqcsJte/Tw2 IXad6flAW82H2V3InuIZMOA67BCB+Dsa55gK+tssX/EwkMGU6CRPTupCiTfXHSIOfgEbHFvE86bdD 7u4JMHYq5ZGNR+KpiRGA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdVMB-00000000Sqc-3IN3; Mon, 12 Aug 2024 13:45:07 +0000 Received: from out-176.mta1.migadu.com ([2001:41d0:203:375::b0]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdVM9-00000000Sod-1V12 for kvm-riscv@lists.infradead.org; Mon, 12 Aug 2024 13:45:07 +0000 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1723470302; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DuBDu2KUddhgkqZOSU6QLhFG2U5c0inzQs/uShG3O8A=; b=w5xypioI3FytLjkOanZ9Nl4x3LiXx4OOyGdEcco1jKcsDQ247PQndGSV3HcbpsbeyNUZvG wb/NumGWRxWgzAJEHqNyTP8mS+/e1N9kp+7Ou8a2zzvSFiIf9VerRLy34NWBGvA9WLlFHl 7Cod2CtfzNVli9NZU9P4057LYJLyQ4A= From: Andrew Jones To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org Cc: atishp@rivosinc.com, cade.richard@berkeley.edu, jamestiotio@gmail.com Subject: [kvm-unit-tests PATCH v2 3/7] riscv: Support up to 34-bit physical addresses on rv32, sort of Date: Mon, 12 Aug 2024 15:44:55 +0200 Message-ID: <20240812134451.112498-12-andrew.jones@linux.dev> In-Reply-To: <20240812134451.112498-9-andrew.jones@linux.dev> References: <20240812134451.112498-9-andrew.jones@linux.dev> MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240812_064505_707632_8AEB7157 X-CRM114-Status: GOOD ( 13.40 ) X-Spam-Score: -2.1 (--) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Change virt_to_phys() and phys_to_virt() to use phys_addr_t instead of unsigned long. This allows 32-bit builds to use physical addresses over 32 bits wide (the spec allows up to 34 bits). But, to kee [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.0 T_SCC_BODY_TEXT_LINE No description available. X-BeenThere: kvm-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kvm-riscv" Errors-To: kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Change virt_to_phys() and phys_to_virt() to use phys_addr_t instead of unsigned long. This allows 32-bit builds to use physical addresses over 32 bits wide (the spec allows up to 34 bits). But, to keep things simple, we don't expect physical addresses wider than 32 bits in most the library code (and that's ensured by sprinkling around some asserts). IOW, the support is really only for unit tests which want to test with an additional high memory region. Signed-off-by: Andrew Jones --- lib/riscv/asm/io.h | 4 ++-- lib/riscv/mmu.c | 32 ++++++++++++++++++++------------ lib/riscv/smp.c | 7 ++++++- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/riscv/asm/io.h b/lib/riscv/asm/io.h index 37a130e533c9..a48a9aa654dd 100644 --- a/lib/riscv/asm/io.h +++ b/lib/riscv/asm/io.h @@ -77,10 +77,10 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) void __iomem *ioremap(phys_addr_t phys_addr, size_t size); #define virt_to_phys virt_to_phys -unsigned long virt_to_phys(volatile void *address); +phys_addr_t virt_to_phys(volatile void *address); #define phys_to_virt phys_to_virt -void *phys_to_virt(unsigned long address); +void *phys_to_virt(phys_addr_t address); #include diff --git a/lib/riscv/mmu.c b/lib/riscv/mmu.c index 2c9c4f376ac9..6ab1f15a99ae 100644 --- a/lib/riscv/mmu.c +++ b/lib/riscv/mmu.c @@ -18,9 +18,16 @@ static int pte_index(uintptr_t vaddr, int level) return (vaddr >> (PGDIR_BITS * level + PAGE_SHIFT)) & PGDIR_MASK; } +static phys_addr_t pteval_to_phys_addr(pteval_t pteval) +{ + return (phys_addr_t)((pteval & PTE_PPN) >> PPN_SHIFT) << PAGE_SHIFT; +} + static pte_t *pteval_to_ptep(pteval_t pteval) { - return (pte_t *)(((pteval & PTE_PPN) >> PPN_SHIFT) << PAGE_SHIFT); + phys_addr_t paddr = pteval_to_phys_addr(pteval); + assert(paddr == __pa(paddr)); + return (pte_t *)__pa(paddr); } static pteval_t ptep_to_pteval(pte_t *ptep) @@ -106,7 +113,7 @@ void __mmu_enable(unsigned long satp) void mmu_enable(unsigned long mode, pgd_t *pgtable) { - unsigned long ppn = (unsigned long)pgtable >> PAGE_SHIFT; + unsigned long ppn = __pa(pgtable) >> PAGE_SHIFT; unsigned long satp = mode | ppn; assert(!(ppn & ~SATP_PPN)); @@ -118,6 +125,9 @@ void *setup_mmu(phys_addr_t top, void *opaque) struct mem_region *r; pgd_t *pgtable; + /* The initial page table uses an identity mapping. */ + assert(top == __pa(top)); + if (!__initial_pgtable) __initial_pgtable = alloc_page(); pgtable = __initial_pgtable; @@ -146,7 +156,8 @@ void __iomem *ioremap(phys_addr_t phys_addr, size_t size) pgd_t *pgtable = current_pgtable(); bool flush = true; - assert(sizeof(long) == 8 || !(phys_addr >> 32)); + /* I/O is always identity mapped. */ + assert(end == __pa(end)); if (!pgtable) { if (!__initial_pgtable) @@ -158,7 +169,7 @@ void __iomem *ioremap(phys_addr_t phys_addr, size_t size) mmu_set_range_ptes(pgtable, start, start, end, __pgprot(_PAGE_READ | _PAGE_WRITE), flush); - return (void __iomem *)(unsigned long)phys_addr; + return (void __iomem *)__pa(phys_addr); } phys_addr_t virt_to_pte_phys(pgd_t *pgtable, void *virt) @@ -179,27 +190,24 @@ phys_addr_t virt_to_pte_phys(pgd_t *pgtable, void *virt) if (!pte_val(*ptep)) return 0; - return __pa(pteval_to_ptep(pte_val(*ptep))) | offset_in_page(virt); + return pteval_to_phys_addr(pte_val(*ptep)) | offset_in_page(virt); } -unsigned long virt_to_phys(volatile void *address) +phys_addr_t virt_to_phys(volatile void *address) { unsigned long satp = csr_read(CSR_SATP); pgd_t *pgtable = (pgd_t *)((satp & SATP_PPN) << PAGE_SHIFT); - phys_addr_t paddr; if ((satp >> SATP_MODE_SHIFT) == 0) return __pa(address); - paddr = virt_to_pte_phys(pgtable, (void *)address); - assert(sizeof(long) == 8 || !(paddr >> 32)); - - return (unsigned long)paddr; + return virt_to_pte_phys(pgtable, (void *)address); } -void *phys_to_virt(unsigned long address) +void *phys_to_virt(phys_addr_t address) { /* @address must have an identity mapping for this to work. */ + assert(address == __pa(address)); assert(virt_to_phys(__va(address)) == address); return __va(address); } diff --git a/lib/riscv/smp.c b/lib/riscv/smp.c index 7e4bb5b76903..4d373e0a29a8 100644 --- a/lib/riscv/smp.c +++ b/lib/riscv/smp.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ secondary_func_t secondary_cinit(struct secondary_data *data) static void __smp_boot_secondary(int cpu, secondary_func_t func) { struct secondary_data *sp = alloc_pages(1) + SZ_8K - 16; + phys_addr_t sp_phys; struct sbiret ret; sp -= sizeof(struct secondary_data); @@ -43,7 +45,10 @@ static void __smp_boot_secondary(int cpu, secondary_func_t func) sp->stvec = csr_read(CSR_STVEC); sp->func = func; - ret = sbi_hart_start(cpus[cpu].hartid, (unsigned long)&secondary_entry, __pa(sp)); + sp_phys = virt_to_phys(sp); + assert(sp_phys == __pa(sp_phys)); + + ret = sbi_hart_start(cpus[cpu].hartid, (unsigned long)&secondary_entry, __pa(sp_phys)); assert(ret.error == SBI_SUCCESS); }