diff mbox series

riscv: rv32: Root page table address can be larger than 32-bit

Message ID 1564577101-29020-1-git-send-email-bmeng.cn@gmail.com
State Superseded
Headers show
Series riscv: rv32: Root page table address can be larger than 32-bit | expand

Commit Message

Bin Meng July 31, 2019, 12:45 p.m. UTC
For RV32, the root page table's PPN has 22 bits hence its address
bits could be larger than the maximum bits that target_ulong is
able to represent. Use hwaddr instead.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
---

 target/riscv/cpu_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Richard Henderson July 31, 2019, 5:35 p.m. UTC | #1
On 7/31/19 5:45 AM, Bin Meng wrote:
> -    target_ulong base;
> +    hwaddr base;
...
> -        target_ulong pte_addr = base + idx * ptesize;
> +        hwaddr pte_addr = base + idx * ptesize;

I believe that you either need

    base + (hwaddr)idx * ptesize

or change the type of idx to hwaddr above.

Otherwise the multiply overflows before it gets promoted with the add.


r~
Bin Meng Aug. 1, 2019, 1:53 a.m. UTC | #2
Hi Richard,

On Thu, Aug 1, 2019 at 1:35 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 7/31/19 5:45 AM, Bin Meng wrote:
> > -    target_ulong base;
> > +    hwaddr base;
> ...
> > -        target_ulong pte_addr = base + idx * ptesize;
> > +        hwaddr pte_addr = base + idx * ptesize;
>
> I believe that you either need
>
>     base + (hwaddr)idx * ptesize
>
> or change the type of idx to hwaddr above.
>
> Otherwise the multiply overflows before it gets promoted with the add.
>

I am not sure how (idx * ptesize) could overflow. It represents the
offset by a page table which is [0, 4096).

Regards,
Bin
Richard Henderson Aug. 1, 2019, 2:16 p.m. UTC | #3
On 7/31/19 6:53 PM, Bin Meng wrote:
> I am not sure how (idx * ptesize) could overflow. It represents the
> offset by a page table which is [0, 4096).

You're right, I mis-read what was going on there.

However, lower down, "target_ulong ppn" needs to be promoted to hwaddr, so that

    ppn = pte >> PTE_PPN_SHIFT;
    ...
    base = ppn << PGSHIFT;

does not overflow.  (Which is the part of the page table walk that I thought I
had gleaned from the patch without actually reading the entire function.)


r~
Bin Meng Aug. 1, 2019, 2:57 p.m. UTC | #4
On Thu, Aug 1, 2019 at 10:16 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 7/31/19 6:53 PM, Bin Meng wrote:
> > I am not sure how (idx * ptesize) could overflow. It represents the
> > offset by a page table which is [0, 4096).
>
> You're right, I mis-read what was going on there.
>
> However, lower down, "target_ulong ppn" needs to be promoted to hwaddr, so that
>
>     ppn = pte >> PTE_PPN_SHIFT;
>     ...
>     base = ppn << PGSHIFT;
>
> does not overflow.  (Which is the part of the page table walk that I thought I
> had gleaned from the patch without actually reading the entire function.)

Ah, yes. ppn should be promoted. Thanks for the review!

Regards,
Bin
Palmer Dabbelt Aug. 7, 2019, 8:55 p.m. UTC | #5
On Thu, Aug 1, 2019 at 7:58 AM Bin Meng <bmeng.cn@gmail.com> wrote:

> On Thu, Aug 1, 2019 at 10:16 PM Richard Henderson
> <richard.henderson@linaro.org> wrote:
> >
> > On 7/31/19 6:53 PM, Bin Meng wrote:
> > > I am not sure how (idx * ptesize) could overflow. It represents the
> > > offset by a page table which is [0, 4096).
> >
> > You're right, I mis-read what was going on there.
> >
> > However, lower down, "target_ulong ppn" needs to be promoted to hwaddr,
> so that
> >
> >     ppn = pte >> PTE_PPN_SHIFT;
> >     ...
> >     base = ppn << PGSHIFT;
> >
> > does not overflow.  (Which is the part of the page table walk that I
> thought I
> > had gleaned from the patch without actually reading the entire function.)
>
> Ah, yes. ppn should be promoted. Thanks for the review!
>

Did I miss a v2?
Bin Meng Aug. 8, 2019, 1:49 a.m. UTC | #6
Hi Palmer,

On Thu, Aug 8, 2019 at 4:55 AM Palmer Dabbelt <palmer@sifive.com> wrote:
>
> On Thu, Aug 1, 2019 at 7:58 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>>
>> On Thu, Aug 1, 2019 at 10:16 PM Richard Henderson
>> <richard.henderson@linaro.org> wrote:
>> >
>> > On 7/31/19 6:53 PM, Bin Meng wrote:
>> > > I am not sure how (idx * ptesize) could overflow. It represents the
>> > > offset by a page table which is [0, 4096).
>> >
>> > You're right, I mis-read what was going on there.
>> >
>> > However, lower down, "target_ulong ppn" needs to be promoted to hwaddr, so that
>> >
>> >     ppn = pte >> PTE_PPN_SHIFT;
>> >     ...
>> >     base = ppn << PGSHIFT;
>> >
>> > does not overflow.  (Which is the part of the page table walk that I thought I
>> > had gleaned from the patch without actually reading the entire function.)
>>
>> Ah, yes. ppn should be promoted. Thanks for the review!
>
>
> Did I miss a v2?

No, I will send a v2 soon.

Regards,
Bin
diff mbox series

Patch

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e32b612..3150a6a 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -176,7 +176,7 @@  static int get_physical_address(CPURISCVState *env, hwaddr *physical,
 
     *prot = 0;
 
-    target_ulong base;
+    hwaddr base;
     int levels, ptidxbits, ptesize, vm, sum;
     int mxr = get_field(env->mstatus, MSTATUS_MXR);
 
@@ -239,7 +239,7 @@  restart:
                            ((1 << ptidxbits) - 1);
 
         /* check that physical address of PTE is legal */
-        target_ulong pte_addr = base + idx * ptesize;
+        hwaddr pte_addr = base + idx * ptesize;
 
         if (riscv_feature(env, RISCV_FEATURE_PMP) &&
             !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),