[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v4 2/2] xen/riscv: introduce identity mapping
Hi all, I would like to ask for advice on whether it would be easier, less bug- provoking ( during identity mapping to remove of whole Xen ) to have a separate identity section that won't be more than PAGE_SIZE. Please take a look at the changes below. Comments are welcome. diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index 7d1a8beba8..ba4af48fc6 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -26,6 +26,8 @@ static unsigned long __ro_after_init phys_offset; #define LOAD_TO_LINK(addr) ((unsigned long)(addr) - phys_offset) #define LINK_TO_LOAD(addr) ((unsigned long)(addr) + phys_offset) +extern char _ident_start[], _ident_end[]; + /* * It is expected that Xen won't be more then 2 MB. * The check in xen.lds.S guarantees that. @@ -112,7 +114,9 @@ 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 = is_identity_mapping + ? PTE_LEAF_DEFAULT | PTE_EXECUTABLE + : PTE_LEAF_DEFAULT ; unsigned long addr = is_identity_mapping ? page_addr : LINK_TO_LOAD(page_addr); pte_t pte_to_be_written; @@ -248,9 +252,9 @@ void __init setup_initial_pagetables(void) return; setup_initial_mapping(&mmu_desc, - load_start, - load_end, - load_start); + (unsigned long)_ident_start, + (unsigned long)_ident_end, + (unsigned long)_ident_start); } void __init enable_mmu(void) @@ -264,6 +268,19 @@ void __init enable_mmu(void) RV_STAGE1_MODE << SATP_MODE_SHIFT); } +void __attribute__((naked)) __section(".ident") turn_on_mmu(unsigned long ra) +{ + /* Ensure page table writes precede loading the SATP */ + sfence_vma(); + + /* Enable the MMU and load the new pagetable for Xen */ + csr_write(CSR_SATP, + PFN_DOWN((unsigned long)stage1_pgtbl_root) | + RV_STAGE1_MODE << SATP_MODE_SHIFT); + + asm volatile( "jr %0\n" : : "r"(ra) ); +} + static void __init __remove_identity_mapping(pte_t *pgtbl, unsigned long load_start, unsigned int pt_level) @@ -297,20 +314,42 @@ static void __init __remove_identity_mapping(pte_t *pgtbl, void __init remove_identity_mapping(void) { - unsigned long load_start = LINK_TO_LOAD(_start); + unsigned int i; + pte_t *pgtbl; + unsigned int index, xen_index; + unsigned long ident_start = LINK_TO_LOAD(_ident_start); - if ( XEN_VIRT_START <= load_start ) + for ( pgtbl = stage1_pgtbl_root, i = CONFIG_PAGING_LEVELS; i; i-- ) { - early_printk("remove identity mapping algo expects that" - "XEN_VIRT_START > load_start\n"); - die(); - } + index = pt_index(i - 1, ident_start); + xen_index = pt_index(i - 1, XEN_VIRT_START); - __remove_identity_mapping(stage1_pgtbl_root, - LINK_TO_LOAD(_start), - CONFIG_PAGING_LEVELS - 1); + if ( index != xen_index ) + { + pgtbl[index].pte = 0; + break; + } + + pgtbl = (pte_t *)pte_to_paddr(pgtbl[index]); + } } +// void __init remove_identity_mapping(void) +// { +// unsigned long load_start = LINK_TO_LOAD(_start); + +// if ( XEN_VIRT_START <= load_start ) +// { +// early_printk("remove identity mapping algo expects that" +// "XEN_VIRT_START > load_start\n"); +// die(); +// } + +// __remove_identity_mapping(stage1_pgtbl_root, +// LINK_TO_LOAD(_start), +// CONFIG_PAGING_LEVELS - 1); +// } + /* * calc_phys_offset() should be used before MMU is enabled because access to * start() is PC-relative and in case when load_addr != linker_addr phys_offset diff --git a/xen/arch/riscv/riscv64/head.S b/xen/arch/riscv/riscv64/head.S index 613e25ea6f..bb529f6a11 100644 --- a/xen/arch/riscv/riscv64/head.S +++ b/xen/arch/riscv/riscv64/head.S @@ -41,14 +41,12 @@ ENTRY(start) jal setup_initial_pagetables - jal enable_mmu - /* Calculate proper VA after jump from 1:1 mapping */ la t0, .L_primary_switched sub t0, t0, s2 - /* Jump from 1:1 mapping world */ - jr t0 + mv a0, t0 + jal turn_on_mmu .L_primary_switched: /* diff --git a/xen/arch/riscv/xen.lds.S b/xen/arch/riscv/xen.lds.S index 31ccebadcb..ffa0225332 100644 --- a/xen/arch/riscv/xen.lds.S +++ b/xen/arch/riscv/xen.lds.S @@ -37,6 +37,13 @@ SECTIONS _etext = .; /* End of text section */ } :text + .ident : { + . = ALIGN(PAGE_SIZE); + _ident_start = .; + *(.ident) + _ident_end = .; + } :text + . = ALIGN(PAGE_SIZE); .rodata : { _srodata = .; /* Read-only data */ @@ -178,3 +185,5 @@ ASSERT(!SIZEOF(.got.plt), ".got.plt non-empty") * PGTBL_INITIAL_COUNT. */ ASSERT(_end - _start <= MB(2), "Xen too large for early-boot assumptions") + +ASSERT(_ident_end - _ident_start <= KB(4), "Identity section is bigger then 4Kb") ~ Oleksii
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |