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

Re: [PATCH v1 2/3] xen/riscv: setup initial pagetables



On Wed, 2023-03-08 at 16:17 +0100, Jan Beulich wrote:
> On 08.03.2023 15:54, Oleksii wrote:
> > Actually after my latest experiments it looks that we don't need to
> > calculate that things at all because for RISC-V it is  used
> > everywhere
> > PC-relative access.
> > Thereby it doesn't matter what is an address where Xen was loaded
> > and
> > linker address.
> > Right now I found only to cases which aren't PC-relative.
> > Please look at the patch below:
> > diff --git a/xen/arch/riscv/include/asm/config.h
> > b/xen/arch/riscv/include/asm/config.h
> > index 763a922a04..e1ba613d81 100644
> > --- a/xen/arch/riscv/include/asm/config.h
> > +++ b/xen/arch/riscv/include/asm/config.h
> > @@ -39,7 +39,7 @@
> >    name:
> >  #endif
> >  
> > -#define XEN_VIRT_START  _AT(UL, 0x80200000)
> > +#define XEN_VIRT_START  _AT(UL, 0x00200000)
> 
> I think this wants to remain the address where Xen actually runs, and
> where Xen is linked to. This ...
> 
> > --- a/xen/arch/riscv/traps.c
> > +++ b/xen/arch/riscv/traps.c
> > @@ -123,8 +123,14 @@ int do_bug_frame(const struct cpu_user_regs
> > *regs,
> > vaddr_t pc)
> >      const char *filename, *predicate;
> >      int lineno;
> >  
> > -    static const struct bug_frame* bug_frames[] = {
> > -        &__start_bug_frames[0],
> > +    /*
> > +     * force fill bug_frames array using auipc/addi instructions
> > to
> > +     * make addresses in bug_frames PC-relative.
> > +    */
> > +    const struct bug_frame * force = (const struct bug_frame *)
> > &__start_bug_frames[0];
> > +
> > +    const struct bug_frame* bug_frames[] = {
> > +        force,
> >          &__stop_bug_frames_0[0],
> >          &__stop_bug_frames_1[0],
> >          &__stop_bug_frames_2[0],
> 
> ... array would better be static anyway, and ...
> 
> > The changes related to <asm/config.h> are  only to make linker_addr
> > !=
> > load_address. So:
> > 1. The first issue with cpu0_boot_stack in the head.S file. When we
> > do:
> >       la      sp, cpu0_boot_stack
> >    Pseudo-instruction la will be transformed to auipc/addi OR
> > auipc/l{w|d}.
> >    It depends on an option: nopic, pic. [1]
> >    
> >    So the solution can be the following:
> >    * As it is done in the patch: add to the start of head.S
> > ".option  
> > nopic"
> >    * Change la to lla thereby it will be always generated
> > "auipc/addi"
> > to get an address of variable.
> > 
> > 2. The second issue is with the code in do_bug_frame() with
> > bug_frames
> > array:
> >    const struct bug_frame* bug_frames[] = {
> >         &__start_bug_frames[0],
> >         &__stop_bug_frames_0[0],
> >         &__stop_bug_frames_1[0],
> >         &__stop_bug_frames_2[0],
> >         &__stop_bug_frames_3[0],
> >     };
> >   In this case &{start,stop}bug_frames{,{0-3}} will be changed
> > to     
> > linker address. In case of when load_addr is 0x80200000 and
> > linker_addr
> > is 0x00200000 then &{start,stop}bug_frames{,{0-3}} will be equal to
> > 0x00200000 + X.
> 
> ... this "solution" to a problem you introduce by wrongly modifying
> the linked address would then need applying to any other similar code
> pattern found in Xen. Which is (I hope obviously) not a viable route.
> Instead code running before address translation is enable needs to be
> extra careful in what code and data items it accesses, and how.
> 
I modified the linked address only for the experiment ( when load_addr
!= linker_addr to emulate situation Julien told me about), so it's not
something I planned to send as a part of the final patch, and I
probably forgot to mention that in my previous mail.

It is only one place where we have to do a kind of 'force' and is
needed to make the current state of RISC-V Xen work in case we don't
have MMU enabled yet and linker_addr != load_addr. All other cases
where it is used something from the range (linker_start, linker_end)
will be managed by MMU.

If we can't use mentioned above solution, we still need to handle the
situation when linker_addr != load_addr and MMU isn't enabled yet.
Other options to do that:
1. add phys_offset ( | load_addr - linker_addr | ) everywhere where
bug_frames array is used: bug_frames[id] + phys_offset
2. Check somewhere at the start if linker_addr != load_addr, then throw
an error and panic().

Other options might exist. So I would appreciate it if you could
suggest me some.

Could you let me know if any options are suitable for handling a case
when linker_addr?
> >     To force using addresses related to load_addr  in bug_frames,
> > it is
> > necessary to declare a variable with getting an address of
> > &__{start,stop}bug_frames{,{0-3}} thereby it will generate the
> > code:
> >         2002c2:       00001797                auipc   a5,0x1
> >         2002c6:       d3e78793                addi    a5,a5,-706 #
> > 201000 <__start_bug_frames>
> >         2002ca:       faf43c23                sd      a5,-72(s0)
> >         2002ce:       00001797                auipc   a5,0x1
> >         2002d2:       d3a78793                addi    a5,a5,-710 #
> > 201008 <__stop_bug_frames_
> 
~ Oleksii



 


Rackspace

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