[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 5/8] xen/riscv: introduce identity mapping


  • To: Oleksii <oleksii.kurochko@xxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Wed, 14 Jun 2023 12:04:41 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=9Gs5SDCLc/imJXrCJIBf58B+16w/IX8Vx3OoprBkPtA=; b=OlF1kZ6I8vvtG5T8P8xxRGSZmGFLlutW6g9o0K/IXZ4ZusimnxItps2LN6snf09CQ+p1bp+1xqntCuV3GOcDKXOI2lnYiJ95q0nivUMbIudHN0tF3vIfst4zO3qy2bJne6pw29kL2naaNJ4wfpFp5BtzWP6S3NJag50pRgQDBFAd5g+dQJLBJI94mKMaj1qhCQH8oQxj5P3367p95TFUv7vjllu3zezAt7jvWpabDnljhajDA27zkYwa1IwLwViM+TL0w5z6wzVZFd+ej2pnOdsujoZW7EqRbbVu9ewteTylrsypH7dHJkshumQgDuWKuTnUNv4hzohE+rqJOGf1Ow==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=M6mkw856OVefNB8qX3viFEJqrv7xHkOV+Wr3nR+Lgke40gvhwS0Y8iKblwdAAhm4hkG4Slg2N8NySU+ZMAlVPFkTl92qMzhwgAZHaqaj/riToi5bvdUYcJU4q8W3TVbVdVEnBEeQ3pdXyx164yXWHDp4atHKB12tgBbE5YMaV81L0BrBvXWXWVLFEH+7J8OJxQeG8+H98MyYEEMUpPHeEFKO7vkP9CHZwg/+LT9+iLDfeGcuZTdUZBZuyFNyqE6Sw7HhQWp+LA7gU/MeLPTsQxYmQo8tDXzMycoEEX4rtJrr3QtKS1oUAEBow6YLOR8Uap/1RejreY56CT7FnoNQyA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Bob Eshleman <bobbyeshleman@xxxxxxxxx>, Alistair Francis <alistair.francis@xxxxxxx>, Connor Davis <connojdavis@xxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Wed, 14 Jun 2023 10:05:02 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.