[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v1 5/8] xen/riscv: introduce identity mapping
On 14.06.2023 11:47, Oleksii wrote: > On Mon, 2023-06-12 at 15:48 +0200, Jan Beulich wrote: >> On 06.06.2023 21:55, Oleksii Kurochko wrote: >>> The way how switch to virtual address was implemented in the >>> commit e66003e7be ("xen/riscv: introduce setup_initial_pages") >>> wasn't safe enough so identity mapping was introduced and >>> used. >> >> I don't think this is sufficient as a description. You want to make >> clear what the "not safe enough" is, and you also want to go into >> more detail as to the solution chosen. I'm particularly puzzled that >> you map just two singular pages ... > I'll update a descrption. > > I map two pages as it likely to be enough to switch from 1:1 mapping I dislike your use of "likely" here: Unless this code is meant to be redone anyway, it should just work. Everywhere. > world. My point is that we need 1:1 mapping only for few instructions > which are located in start() [ in .text.header section ]: > > li t0, XEN_VIRT_START > la t1, start > sub t1, t1, t0 > > /* Calculate proper VA after jump from 1:1 mapping */ > la t0, .L_primary_switched > sub t0, t0, t1 > > /* Jump from 1:1 mapping world */ > jr t0 > > And it is needed to map 1:1 cpu0_boot_stack to not to fault when > executing epilog of enable_mmu() function as it accesses a value on the > stack: > ffffffffc00001b0: 6422 ld s0,8(sp) > ffffffffc00001b2: 0141 addi sp,sp,16 > ffffffffc00001b4: 8082 ret > >> >>> @@ -35,8 +40,10 @@ static unsigned long phys_offset; >>> * >>> * It might be needed one more page table in case when Xen load >>> address >>> * isn't 2 MB aligned. >>> + * >>> + * 3 additional page tables are needed for identity mapping. >>> */ >>> -#define PGTBL_INITIAL_COUNT ((CONFIG_PAGING_LEVELS - 1) + 1) >>> +#define PGTBL_INITIAL_COUNT ((CONFIG_PAGING_LEVELS - 1) + 1 + 3) >> >> What is this 3 coming from? It feels like the value should (again) >> somehow depend on CONFIG_PAGING_LEVELS. > 3 is too much in the current case. It should be 2 more. > > The linker address is 0xFFFFFFFC00000000 thereby mapping the linker to > load addresses > we need 3 pages ( with the condition that the size of Xen won't be > larger than 2 MB ) and 1 page if the case when Xen load address isn't > 2MV aligned. > > We need 2 more page tables because Xen is loaded to address 0x80200000 > by OpenSBI and the load address isn't equal to the linker address so we > need additional 2 pages as the L2 table we already allocated when > mapping the linker to load addresses. > > And it looks like 2 is enough for Sv48, Sv57 as L4, L3 and L2 > pagetables will be already allocated during mapping the linker to load > addresses. I agree the root table will be there. But depending on load address, I don't think you can rely on any other tables to be re-usable from the Xen mappings you already have. So my gut feeling would be #define PGTBL_INITIAL_COUNT ((CONFIG_PAGING_LEVELS - 1) * 2 + 1) >>> @@ -232,22 +242,27 @@ void __init setup_initial_pagetables(void) >>> linker_start, >>> linker_end, >>> load_start); >>> + >>> + if ( linker_start == load_start ) >>> + return; >>> + >>> + setup_initial_mapping(&mmu_desc, >>> + load_start, >>> + load_start + PAGE_SIZE, >>> + load_start); >>> + >>> + setup_initial_mapping(&mmu_desc, >>> + (unsigned long)cpu0_boot_stack, >>> + (unsigned long)cpu0_boot_stack + >>> PAGE_SIZE, >> >> Shouldn't this be STACK_SIZE (and then also be prepared for >> STACK_SIZE > PAGE_SIZE)? > Yes, it will be better to use STACK_SIZE but for 1:1 mapping it will be > enough PAGE_SIZE as I mentioned above this only need for epilogue of > enable_mmu() function. But then it should still be the correct page of the stack that you map (the top one aiui). >>> -void __init noreturn noinline enable_mmu() >>> +/* >>> + * enable_mmu() can't be __init because __init section isn't part >>> of identity >>> + * mapping so it will cause an issue after MMU will be enabled. >>> + */ >> >> As hinted at above already - perhaps the identity mapping wants to be >> larger, up to covering the entire Xen image? Since it's temporary >> only anyway, you could even consider using a large page (and RWX >> permission). You already require no overlap of link and load >> addresses, >> so at least small page mappings ought to be possible for the entire >> image. > It makes sense and started to thought about that after I applied the > patch for Dom0 running... I think we can map 1 GB page which will cover > the whole Xen image. Also in that case we haven't to allocate 2 more > page tables. But you then need to be careful about not mapping space accesses to which may have side effects (i.e. non-RAM, which might be MMIO or holes). Otherwise speculative execution might cause surprises, unless such is excluded by other guarantees (of which I don't know). >>> --- a/xen/arch/riscv/riscv64/head.S >>> +++ b/xen/arch/riscv/riscv64/head.S >>> @@ -31,6 +31,36 @@ ENTRY(start) >>> >>> jal calc_phys_offset >>> >>> + jal setup_initial_pagetables >>> + >>> + jal enable_mmu >>> + >>> + /* >>> + * Calculate physical offset >>> + * >>> + * We can't re-use a value in phys_offset variable here as >>> + * phys_offset is located in .bss and this section isn't >>> + * 1:1 mapped and an access to it will cause MMU fault >>> + */ >>> + li t0, XEN_VIRT_START >>> + la t1, start >>> + sub t1, t1, t0 >> >> If I'm not mistaken this calculates start - XEN_VIRT_START, and ... >> >>> + /* Calculate proper VA after jump from 1:1 mapping */ >>> + la t0, .L_primary_switched >>> + sub t0, t0, t1 >> >> ... then this .L_primary_switched - (start - XEN_VIRT_START). Which >> can >> also be expressed as (.L_primary_switched - start) + XEN_VIRT_START, >> the first part of which gas ought to be able to resolve for you. But >> upon experimenting a little it looks like it can't. (I had thought of >> something along the lines of >> >> li t0, .L_primary_switched - start >> li t1, XEN_VIRT_START >> add t0, t0, t1 >> >> or even >> >> li t1, XEN_VIRT_START >> add t0, t1, %pcrel_lo(.L_primary_switched - start) >> >> .) > Calculation of ".L_primary_switched - start" might be an issue for gcc. > I tried to do something similar and recieved or "Error: can't resolve > .L_primary_switched - start" or "Error: illegal operands `li > t0,.L_primary_switched-start'" Matches the results of my experiments. If I can find time, I may want to look into why exactly gas is rejecting such. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |