Hi Alistair,

Thanks for your review.

(Sorry, just resend this email due to the incorrect line break in the
previous reply email.)

On 6/2/2025 1:11 PM, Alistair Francis wrote:
> On Thu, May 29, 2025 at 10:52 PM Nutty Liu
> <liujin...@lanxincomputing.com> wrote:
>> The original implementation incorrectly performed a bitwise AND
>> operation between the PPN of iova and PPN Mask, leading to an
>> incorrect PPN field in Translation-reponse register.
>>
>> The PPN of iova should be set entirely in the PPN field of
>> Translation-reponse register.
>>
>> Signed-off-by: Nutty Liu <liujin...@lanxincomputing.com>
>> ---
>>   hw/riscv/riscv-iommu.c | 3 +--
>>   1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
>> index a877e5da84..f529a6a3d7 100644
>> --- a/hw/riscv/riscv-iommu.c
>> +++ b/hw/riscv/riscv-iommu.c
>> @@ -1935,8 +1935,7 @@ static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
>>               iova = RISCV_IOMMU_TR_RESPONSE_FAULT | (((uint64_t) fault) << 
>> 10);
>>           } else {
>>               iova = iotlb.translated_addr & ~iotlb.addr_mask;
>> -            iova >>= TARGET_PAGE_BITS;
>> -            iova &= RISCV_IOMMU_TR_RESPONSE_PPN;
>> +            iova = set_field(0, RISCV_IOMMU_TR_RESPONSE_PPN, 
>> PPN_DOWN(iova));
> I don't see how this is different.
>
> PPN_DOWN(iova)
> is the same as
> iova >> TARGET_PAGE_BITS

Yes. The results of above operations are the same.

>
> and
>
> set_field(0, RISCV_IOMMU_TR_RESPONSE_PPN, PPN_DOWN(iova))
> should just return
> (0 & ~RISCV_IOMMU_TR_RESPONSE_PPN) |
>      (RISCV_IOMMU_TR_RESPONSE_PPN & PPN_DOWN(iova))

It's not correct.
Let me show the definitions of the related macros as follows.

1) The definition of 'set_field' in 'target/riscv/cpu_bits.h' is as below:

     #define set_field(reg, mask, val) (((reg) & ~(uint64_t)(mask)) | \
                                       (((uint64_t)(val) * ((mask) & ~((mask) 
<< 1))) & \
                                       (uint64_t)(mask)))

2) The definition of 'RISCV_IOMMU_TR_RESPONSE_PPN' in 
'hw/riscv/riscv-iommu-bits.h' is as follows:

     #define RISCV_IOMMU_PPN_FIELD GENMASK_ULL(53, 10)
     #define RISCV_IOMMU_TR_RESPONSE_PPN RISCV_IOMMU_PPN_FIELD

So the 'RISCV_IOMMU_TR_RESPONSE_PPN' is 0x3ffffffffffc00.


Let me give you an example as follows.

With the original implementation,
1) Assume: iova = 0x12345678;

2) iova >>= TARGET_PAGE_BITS;
The result is as follows:
   iova = 0x12345;

It's the same as PPN_DOWN(iova).
This is the correct value of PPN.

3) iova &= RISCV_IOMMU_TR_RESPONSE_PPN;
After substituting with 'iova = 0x12345', the result is as follows:
    iova = 0x12345 & 0x3ffffffffffc00;
The final 'iova' is as follows:
     iova = 0x12000;
This 'iova' will be set to Translation-reponse register finally by thebelow 
sentence.
    riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_TR_RESPONSE, iova);

Then the value of Translation-reponse register will be set to '0x12000'.
The PPN field is between bit 10 and bit 53.
So the PPN is 0x48 which is calculated by '0x12000 >> 10 = 0x48'.

It's incorrect. Actually the PPN field should be 0x12345.

It should be calculated as follows:
     iova = (iova << 10) & RISCV_IOMMU_TR_RESPONSE_PPN;
After substituting with 'iova = 0x12345', and the result is as follows:
     iova = (0x12345 << 10) & 0x3ffffffffffc00 = 0x48D1400
The correct value of Translation-reponse register should be '0x48D1400'.

4) With the new implementation,
     iova = set_field(0, RISCV_IOMMU_TR_RESPONSE_PPN, PPN_DOWN(iova));

It will set the bit 10 to bit 53 of 'iova' to PPN_DOWN(iova).
After substituting with 'iova = 0x12345', the final 'iova' is as follows:
     iova = 0x48D1400;
And then the correct 'iova' will be set to Translation-reponse register.

> Can you describe the issue with the original implementation and why
> this fixes it in the commit message?

Hope the above description and the example can help you understand.

Nutty,
Thanks

>
> Alistair
>
>>               /* We do not support superpages (> 4kbs) for now */
>>               iova &= ~RISCV_IOMMU_TR_RESPONSE_S;
>> --
>> 2.49.0.windows.1
>>

Reply via email to