riscv-non-isa/riscv-iommu

why need to add `masked_upper_bits != mask`

Closed this issue · 2 comments

https://github.com/riscv-non-isa/riscv-iommu/blob/main/iommu_ref_model/libiommu/src/iommu_two_stage_trans.c#L103

why need to add masked_upper_bits != mask ? If a iova is ffff_ffff_ffff_ffff,which exceed the sv39/sv48/sv57 translate mode size, Is this iova is legal ?

    if ( (masked_upper_bits != 0 && masked_upper_bits != mask && SXL == 0) ||
         (masked_upper_bits != 0 && SXL == 1) ) goto page_fault;

    i = LEVELS - 1;
    a = iosatp.PPN * PAGESIZE;

Thanks.

why need to add masked_upper_bits != mask ?

Virtual addresses are always 64-bit wide or 32-bit wide. The range of valid 64-bit virtual addresses however depends on the virtual memory system mode. The rules to determine the validity of a virtual address are as follows :

  • Sv39: bits 63:39 must equal bit 38 (See also section 10.4.1 of Priv. Spec)
  • Sv48: Bits 63:48 must equal bit 47 (See also section 10.4.1 of Priv. Spec)
  • Sv57: Bits 63:57 must equal bit 56 (See also section 10.6.1 of Priv. Spec)

If a iova is ffff_ffff_ffff_ffff,which exceed the sv39/sv48/sv57 translate mode size, Is this iova is legal ?

The address 0xFFFF_FFFF_FFFF_FFFF is all of these modes. The valid address ranges are as follows:

  • Sv39: 0x0000_0000_0000_0000 to 0x0000_003F_FFFF_FFFF and 0xFFFF_FFC0_0000_0000 to 0xFFFF_FFFF_FFFF_FFFF
  • Sv48: 0x0000_0000_0000_0000 to 0x0000_7FFF_FFFF_FFFF and 0xFFFF_8000_0000_0000 to 0xFFFF_FFFF_FFFF_FFFF
  • Sv57: 0x0000_0000_0000_0000 to 0x00FF_FFFF_FFFF_FFFF and 0xFF00_0000_0000_0000 to 0xFFFF_FFFF_FFFF_FFFF

This effectively partitions the virtual memory space into two halves with a range of invalid addresses in the middle. This also ensures that all addresses that were valid in Sv39 are also valid in Sv48/Sv57, and all valid addresses of Sv48 are also valid in Sv57.

Thanks.