<div dir="ltr"><div dir="ltr">On Fri, Sep 22, 2023 at 5:26 PM Aditya Gupta <<a href="mailto:adityag@linux.ibm.com">adityag@linux.ibm.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Fri, Sep 22, 2023 at 02:13:31PM +0800, lijiang wrote:<br>
> On Thu, Sep 21, 2023 at 7:26 PM Aditya Gupta <<a href="mailto:adityag@linux.ibm.com" target="_blank">adityag@linux.ibm.com</a>> wrote:<br>
> <br>
> > Hi Lianbo,<br>
> > Resending this, since skipped your mail from "To:" field by mistake.<br>
> ><br>
> ><br>
> No worries. I can also get your reply from the mail list.<br>
> <br>
> <br>
> > On Thu, Sep 21, 2023 at 05:46:32PM +0800, lijiang wrote:<br>
> > > On Thu, Sep 21, 2023 at 3:59 PM Aditya Gupta <<a href="mailto:adityag@linux.ibm.com" target="_blank">adityag@linux.ibm.com</a>><br>
> > wrote:<br>
> > ><br>
> > > > On 21/09/23 11:21, lijiang wrote:<br>
> > > ><br>
> > > > On Mon, Sep 18, 2023 at 7: 34 PM lijiang <lijiang@ redhat. com><br>
> > > > <lijiang@%E2%80%8Aredhat.%E2%80%8Acom> wrote: Hi, Aditya Thank you for<br>
> > > > the patch. On Mon, Sep 11, 2023 at 8: 00 PM <crash-utility-request@<br>
> > > > redhat. com> <crash-utility-request@%E2%80%8Aredhat.%E2%80%8Acom><br>
> > wrote:<br>
> > > > From: Aditya Gupta <adityag@ linux. ibm. com><br>
> > > > <adityag@%E2%80%8Alinux.%E2%80%8Aibm.%E2%80%8Acom> To:<br>
> > > > On Mon, Sep 18, 2023 at 7:34 PM lijiang <<a href="mailto:lijiang@redhat.com" target="_blank">lijiang@redhat.com</a>> wrote:<br>
> > > ><br>
> > > >> Hi, Aditya<br>
> > > >> Thank you for the patch.<br>
> > > >><br>
> > > >> On Mon, Sep 11, 2023 at 8:00 PM <<a href="mailto:crash-utility-request@redhat.com" target="_blank">crash-utility-request@redhat.com</a>><br>
> > wrote:<br>
> > > >><br>
> > > >><br>
> > > >>  ...<br>
> > > >><br>
> > > >>>  ppc64.c | 47 +++++++++++++++++++++++++++++++++--------------<br>
> > > >>>  1 file changed, 33 insertions(+), 14 deletions(-)<br>
> > > >>><br>
> > > >>> diff --git a/ppc64.c b/ppc64.c<br>
> > > >>> index fc34006f4863..1e84c5f56773 100644<br>
> > > >>> --- a/ppc64.c<br>
> > > >>> +++ b/ppc64.c<br>
> > > >>> @@ -1280,8 +1280,30 @@ void ppc64_vmemmap_init(void)<br>
> > > >>>         long backing_size, virt_addr_offset, phys_offset,<br>
> > list_offset;<br>
> > > >>>         ulong *vmemmap_list;<br>
> > > >>>         char *vmemmap_buf;<br>
> > > >>> -       struct machine_specific *ms;<br>
> > > >>> -<br>
> > > >>> +       struct machine_specific *ms = machdep->machspec;<br>
> > > >>> +<br>
> > > >>> +       ld = &list_data;<br>
> > > >>> +       BZERO(ld, sizeof(struct list_data));<br>
> > > >>> +<br>
> > > >>> +       /*<br>
> > > >>> +        * vmemmap_list is missing or set to 0 in the kernel would<br>
> > imply<br>
> > > >>> +        * vmemmap region is mapped in the kernel pagetable. So, read<br>
> > > >>> vmemmap_list<br>
> > > >>> +        * anyway and use the translation method accordingly.<br>
> > > >>> +        */<br>
> > > >>> +       readmem(symbol_value("vmemmap_list"), KVADDR, &ld->start,<br>
> > > >>> sizeof(void *),<br>
> > > >>> +               "vmemmap_list", RETURN_ON_ERROR);<br>
> > > >>> +       if (!ld->start) {<br>
> > > >>> +               /*<br>
> > > >>> +                * vmemmap_list is set to 0 or missing. Do kernel<br>
> > > >>> pagetable walk<br>
> > > >>> +                * for vmemmamp address translation.<br>
> > > >>> +                */<br>
> > > >>> +               ms->vmemmap_list = NULL;<br>
> > > >>> +               ms->vmemmap_cnt = 0;<br>
> > > >>> +<br>
> > > >>> +               machdep->flags |= VMEMMAP_AWARE;<br>
> > > >>> +               return;<br>
> > > >>> +       }<br>
> > > >>> +<br>
> > > >>><br>
> > > >><br>
> > > > I would suggest putting the 'readmem(symbol_value("vmemmap_list"),...)'<br>
> > > > after the 'kernel_symbol_exists("vmemmap_list")', and also check the<br>
> > > > returned value of readmem().<br>
> > > ><br>
> > > > Yes, I considered that, but the if condition checking for<br>
> > > > 'kernel_symbol_exists("vmemmap_list")' returns from the function if the<br>
> > > > symbol is not found, same with the readmem return value check earlier,<br>
> > we<br>
> > > > wanted to initialise the ms->vmemmap_list and machdep->flags before<br>
> > that.<br>
> > > ><br>
> > > ><br>
> > > It's true.<br>
> > ><br>
> > > For the current patch, if the symbol 'vmemmap_list' is not found, the<br>
> > > symbol_value() will invoke the error(FATAL, ...) and ultimately exit from<br>
> > > this function. It doesn't have any chance to execute the initialising<br>
> > code.<br>
> > ><br>
> ><br>
> > Got it, this would be an issue when 'vmemmap_list' is missing.<br>
> > Made a mistake here, Thanks, will add an if around the readmem, that should<br>
> > solve it, like this ?<br>
> ><br>
> >     if (kernel_symbol_exists("vmemmap_list"))<br>
> >         readmem(symbol_value("vmemmap_list"), KVADDR, &ld->start,<br>
> > sizeof(void *),<br>
> >                 "vmemmap_list", RETURN_ON_ERROR | QUIET);<br>
> ><br>
> > Will fix this in V2.<br>
> ><br>
> ><br>
> Ok, Thanks. For the ppc64_vmemmap_init() changes, does this work for you?<br>
> <br>
> diff --git a/ppc64.c b/ppc64.c<br>
> index fc34006..3e155a0 100644<br>
> --- a/ppc64.c<br>
> +++ b/ppc64.c<br>
> @@ -1280,10 +1280,34 @@ void ppc64_vmemmap_init(void)<br>
>   long backing_size, virt_addr_offset, phys_offset, list_offset;<br>
>   ulong *vmemmap_list;<br>
>   char *vmemmap_buf;<br>
> - struct machine_specific *ms;<br>
> -<br>
> - if (!(kernel_symbol_exists("vmemmap_list")) ||<br>
> -    !(kernel_symbol_exists("mmu_psize_defs")) ||<br>
> + struct machine_specific *ms = machdep->machspec;<br>
> +<br>
> + if (!kernel_symbol_exists("vmemmap_list"))<br>
> + return;<br>
<br>
Returning here is an issue, since 'machdep->flags |= VMEMMAP_AWARE' won't be<br>
run, and since 'ppc64_vmemmap_to_phys' checks for the flag before calling<br>
'ppc64_vtop_level4' for page traversal.<br></blockquote><div><br></div><div>Understood.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
So page traversal will not happen if the flag is not set. Ideally I will want<br>
the if (!ld->start) codeblock to run if vmemmap_list symbol is missing or the<br>
list is empty<br></blockquote><div><br></div><div>Now this is the point. I have no other issues, thank you for the explanation, Aditya.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Currently I am planning this diff for V2:<br>
<br>
    diff --git a/ppc64.c b/ppc64.c<br>
    index fc34006f4863..cd98a679c45e 100644<br>
    --- a/ppc64.c<br>
    +++ b/ppc64.c<br>
    @@ -1280,10 +1280,32 @@ void ppc64_vmemmap_init(void)<br>
            long backing_size, virt_addr_offset, phys_offset, list_offset;<br>
            ulong *vmemmap_list;<br>
            char *vmemmap_buf;<br>
    -       struct machine_specific *ms;<br>
    -<br>
    -       if (!(kernel_symbol_exists("vmemmap_list")) ||<br>
    -           !(kernel_symbol_exists("mmu_psize_defs")) ||<br>
    +       struct machine_specific *ms = machdep->machspec;<br>
    +<br>
    +       ld = &list_data;<br>
    +       BZERO(ld, sizeof(struct list_data));<br>
    +<br>
    +       /*<br>
    +        * vmemmap_list is missing or set to 0 in the kernel would imply<br>
    +        * vmemmap region is mapped in the kernel pagetable. So, read vmemmap_list<br>
    +        * anyway and use the translation method accordingly.<br>
    +        */<br>
    +       if (kernel_symbol_exists("vmemmap_list"))<br>
    +               readmem(symbol_value("vmemmap_list"), KVADDR, &ld->start,<br>
    +                               sizeof(void *), "vmemmap_list", RETURN_ON_ERROR|QUIET);<br>
<br>
        Here I add a check for 'kernel_symbol_exists' before<br>
        'symbol_value("vmemmap_list") is done<br>
<br>
    +       if (!ld->start) {<br>
    +               /*<br>
    +                * vmemmap_list is set to 0 or missing. Do kernel pagetable walk<br>
    +                * for vmemmap address translation.<br>
    +                */<br>
    +               ms->vmemmap_list = NULL;<br>
    +               ms->vmemmap_cnt = 0;<br>
    +<br>
    +               machdep->flags |= VMEMMAP_AWARE;<br>
    +               return;<br>
    +       }<br>
    +<br>
    +       if (!(kernel_symbol_exists("mmu_psize_defs")) ||<br>
                !(kernel_symbol_exists("mmu_vmemmap_psize")) ||<br>
    ...<br>
<br>
        Here I removed the kernel_symbol_exists("vmemmap_list")<br>
<br>
> +<br>
> + ld = &list_data;<br>
> + BZERO(ld, sizeof(struct list_data));<br>
> +<br>
> + /*<br>
> + * vmemmap_list is missing or set to 0 in the kernel would imply<br>
> + * vmemmap region is mapped in the kernel pagetable. So, read vmemmap_list<br>
> + * anyway and use the translation method accordingly.<br>
> + */<br>
> + readmem(symbol_value("vmemmap_list"), KVADDR, &ld->start, sizeof(void *),<br>
> + "vmemmap_list", RETURN_ON_ERROR|QUIET);<br>
> + if (!ld->start) {<br>
> + /*<br>
> + * vmemmap_list is set to 0 or missing. Do kernel pagetable walk<br>
> + * for vmemmamp address translation.<br>
> + */<br>
> + ms->vmemmap_list = NULL;<br>
> + ms->vmemmap_cnt = 0;<br>
> +<br>
> + machdep->flags |= VMEMMAP_AWARE;<br>
> + return;<br>
> + }<br>
> +<br>
> + if (!(kernel_symbol_exists("mmu_psize_defs")) ||<br>
>      !(kernel_symbol_exists("mmu_vmemmap_psize")) ||<br>
>      !STRUCT_EXISTS("vmemmap_backing") ||<br>
>      !STRUCT_EXISTS("mmu_psize_def") ||<br>
> @@ -1293,8 +1317,6 @@ void ppc64_vmemmap_init(void)<br>
>      !MEMBER_EXISTS("vmemmap_backing", "list"))<br>
>   return;<br>
> <br>
<br>
Yup, this is good, I will remove the kernel_symbol_exists check for<br>
vmemmap_list from if in next version, since it is handled earlier<br>
<br></blockquote><div>OK. Looks good to me.</div><div><br></div><div>Thanks.</div><div>Lianbo</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Thanks,<br>
Aditya Gupta<br>
<br>
> <br>
> BTW: I just got a system with the radix-mmu, and reproduced this issue.<br>
> # dmesg|grep mmu<br>
> [    0.000000] dt-cpu-ftrs: final cpu/mmu features = 0x0001b8eb8f5fb187<br>
> 0x3c007041<br>
> [    0.000000] radix-mmu: Page sizes from device-tree:<br>
> [    0.000000] radix-mmu: Page size shift = 12 AP=0x0<br>
> [    0.000000] radix-mmu: Page size shift = 16 AP=0x5<br>
> [    0.000000] radix-mmu: Page size shift = 21 AP=0x1<br>
> [    0.000000] radix-mmu: Page size shift = 30 AP=0x2<br>
> [    0.000000] radix-mmu: Mapped 0x0000000000000000-0x0000000002800000 with<br>
> 2.00 MiB pages (exec)<br>
> [    0.000000] radix-mmu: Mapped 0x0000000002800000-0x0000000040000000 with<br>
> 2.00 MiB pages<br>
> ...<br>
> <br>
> Thanks<br>
> Lianbo<br>
> <br>
> > And, the initialization code relies on the result of ld->start, once the<br>
> > > readmem() fails due to some reasons, it may also enter the<br>
> > > initialization code. I'm not sure if that is expected behavior(if yes,<br>
> > the<br>
> > > "RETURN_ON_ERROR|QUIET " would be good).<br>
> ><br>
> > Okay, even if readmem fails, we still go ahead and since ld was all zeros,<br>
> > 'if (!ld->start)' should remain true, for both cases when vmemmap_list is<br>
> > empty<br>
> > (head is NULL, hence ld->start=0), vmemmap_list symbol is not found or<br>
> > readmem<br>
> > fails (ld->start=0 since ld was all zeros due to BZERO).<br>
> ><br>
> > Will add "RETURN_ON_ERROR|QUIET" also in V2.<br>
> ><br>
> > ><br>
> > > If so, the kernel_symbol_exists("vmemmap_list") may be redundant. That<br>
> > can<br>
> > > be removed this time. What do you think?<br>
> > ><br>
> ><br>
> > True. Since the case of 'vmemmap_list' being empty, or symbol not being<br>
> > there,<br>
> > both get handled before this, that can be removed.<br>
> > Will do it in V2.<br>
> ><br>
> > Thanks,<br>
> > - Aditya Gupta<br>
> ><br>
> > > > The readmem used to be like this, which returns from function if<br>
> > readmem<br>
> > > > failed:<br>
> > > ><br>
> > > > -       if (!readmem(symbol_value("vmemmap_list"),<br>
> > > > -           KVADDR, &ld->start, sizeof(void *), "vmemmap_list",<br>
> > > > -           RETURN_ON_ERROR))<br>
> > > > -               return;<br>
> > > ><br>
> > > > So, intentionally I put it above the if and removed the return value<br>
> > > > check, since we don't want to depend on vmemmap_list symbol being<br>
> > there for<br>
> > > > newer kernels anymore.<br>
> > > > And to be future proof in case the address mapping moves to page table<br>
> > for<br>
> > > > Hash MMU case also, and since vmemmap_list is PowerPC specific, the<br>
> > symbol<br>
> > > > might also be removed.<br>
> > > ><br>
> > > ><br>
> > > Ok, got it, thanks for the information.<br>
> > ><br>
> > ><br>
> > > > But, if it's a coding guidelines requirement to handle the return<br>
> > values,<br>
> > > > I can think of how to handle the return value of readmem, any<br>
> > suggestions ?<br>
> > > ><br>
> > > ><br>
> > > No, it's not a coding guidelines requirement. :-)<br>
> > ><br>
> > > ><br>
> > > > And other changes are fine to me.<br>
> > > ><br>
> > > > Thank you for your reviews Lianbo :)<br>
> > > ><br>
> > > ><br>
> > > No problem.<br>
> > ><br>
> > > Thanks.<br>
> > > Lianbo<br>
> > ><br>
> > ><br>
> > > > Thanks,<br>
> > > > - Aditya Gupta<br>
> > > ><br>
> ><br>
> ><br>
> ><br>
<br>
</blockquote></div></div>