[PATCH 2/5] xen/riscv: preset A/D bits in Xen's own page-table mappings
Baptiste Le Duc <[email protected]>
| Newsgroups | gmane.comp.emulators.xen.devel |
|---|---|
| Message-ID | <1787844809.8631fc262581453bbf619ec5b2062170.1a043dad225000c4f3@vates.tech> |
The previous patch made p2m_set_permission() always set the PTE A/D bits to map pages in G-stage, to avoid a page fault on platforms that implement neither Svade nor Svadu, or that declare both in the device tree. Xen's own page tables, built by setup_initial_mapping(), never go through p2m_set_permission() and need the same fix. Add PTE_ACCESSED to PTE_LEAF_DEFAULT and make it the minimal common leaf permission set by dropping PTE_WRITABLE. Rebuild PAGE_HYPERVISOR_RO, PAGE_HYPERVISOR_RW and PAGE_HYPERVISOR_RX from that common base, with PAGE_HYPERVISOR_RW also adding PTE_DIRTY. Switch setup_initial_mapping() to use these macros for its default, text, and rodata permissions instead of the equivalent raw bit lists. A PTE is a table entry iff PTE_VALID is set and R/W/X are all clear, so update pte_is_table() accordingly. Assisted-by: Claude:claude-opus-5 Signed-off-by: Baptiste Le Duc <[email protected]> --- xen/arch/riscv/include/asm/page.h | 14 ++++++++------ xen/arch/riscv/mm.c | 7 +++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/xen/arch/riscv/include/asm/page.h b/xen/arch/riscv/include/asm/page.h index b465a90325..5c02f64a17 100644 --- a/xen/arch/riscv/include/asm/page.h +++ b/xen/arch/riscv/include/asm/page.h @@ -46,12 +46,12 @@ #define PTE_PBMT_NOCACHE BIT(61, UL) #define PTE_PBMT_IO BIT(62, UL) -#define PTE_LEAF_DEFAULT (PTE_VALID | PTE_READABLE | PTE_WRITABLE) +#define PTE_LEAF_DEFAULT (PTE_VALID | PTE_READABLE | PTE_ACCESSED) #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_RO (PTE_LEAF_DEFAULT) +#define PAGE_HYPERVISOR_RW (PTE_LEAF_DEFAULT | PTE_WRITABLE | PTE_DIRTY) +#define PAGE_HYPERVISOR_RX (PTE_LEAF_DEFAULT | PTE_EXECUTABLE) #define PAGE_HYPERVISOR PAGE_HYPERVISOR_RW /* @@ -177,7 +177,8 @@ static inline bool pte_is_table(pte_t p) * * PAGE_HYPERVISOR_RW contains PTE_VALID too. */ - ASSERT(((p.pte & PAGE_HYPERVISOR_RW) != (PTE_VALID | PTE_WRITABLE))); + ASSERT((p.pte & (PTE_VALID | PTE_READABLE | PTE_WRITABLE)) != + (PTE_VALID | PTE_WRITABLE)); return ((p.pte & (PTE_VALID | PTE_ACCESS_MASK)) == PTE_VALID); } @@ -185,7 +186,8 @@ static inline bool pte_is_table(pte_t p) static inline bool pte_is_mapping(pte_t p) { /* See pte_is_table() */ - ASSERT(((p.pte & PAGE_HYPERVISOR_RW) != (PTE_VALID | PTE_WRITABLE))); + ASSERT((p.pte & (PTE_VALID | PTE_READABLE | PTE_WRITABLE)) != + (PTE_VALID | PTE_WRITABLE)); return (p.pte & PTE_VALID) && (p.pte & PTE_ACCESS_MASK); } diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index 4d3b8c2204..baff49cf09 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -140,7 +140,7 @@ static void __init setup_initial_mapping(struct mmu_desc *mmu_desc, case 1: /* Level 0 */ { unsigned long paddr = (page_addr - map_start) + pa_start; - unsigned int permissions = PTE_LEAF_DEFAULT; + unsigned int permissions = PAGE_HYPERVISOR_RW; unsigned long addr = is_identity_mapping ? page_addr : virt_to_maddr(page_addr); pte_t pte_to_be_written; @@ -149,11 +149,10 @@ static void __init setup_initial_mapping(struct mmu_desc *mmu_desc, if ( is_kernel_text(addr) || is_kernel_inittext(addr) ) - permissions = - PTE_EXECUTABLE | PTE_READABLE | PTE_VALID; + permissions = PAGE_HYPERVISOR_RX; if ( is_kernel_rodata(addr) ) - permissions = PTE_READABLE | PTE_VALID; + permissions = PAGE_HYPERVISOR_RO; pte_to_be_written = paddr_to_pte(paddr, permissions);