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

Re: [PATCH 1/4] xen/arm: guest_walk: refuse a block descriptor where the granule has none



Hi Stefano,

On 07/11/2026 02:14, Stefano Stabellini wrote:
guest_walk_ld() accepted a block descriptor at any level. No granule has
level 0 blocks, and the 16KB and 64KB granules have no level 1 blocks
(ARM DDI 0487A.k D4.3.1): the translation table walk makes such an entry

It would be good to quote a specification that is a bit newer (A.k was release in 2016!). In recent spec (M.d), it seems you can have level 1 blocks for 16KiB and 64KiB when 52-bit is supported.

Looking at the logic in get_ipa_output_size() we are rejecting 52-bit at the moment. So the check you add is fine as-is. I think it would be made more clear in the commit message and ...

a Translation fault (AArch64.TranslationTableWalk(), J1.1.5). Refuse it.

Fixes: 7d623b358a45 ("arm/mem_access: Add long-descriptor based gpt")
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
Cc: Julien Grall <julien@xxxxxxx>
Cc: Bertrand Marquis <bertrand.marquis@xxxxxxx>
Cc: Michal Orzel <michal.orzel@xxxxxxx>
Cc: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
---
  xen/arch/arm/guest_walk.c | 9 +++++++++
  1 file changed, 9 insertions(+)

diff --git a/xen/arch/arm/guest_walk.c b/xen/arch/arm/guest_walk.c
index 09fe486598..e23457869b 100644
--- a/xen/arch/arm/guest_walk.c
+++ b/xen/arch/arm/guest_walk.c
@@ -533,6 +533,15 @@ static bool guest_walk_ld(const struct vcpu *v,
      if ( !lpae_is_valid(pte) || !lpae_is_mapping(pte, level) )
          return false;
+ /*
+     * A block descriptor is only supported at level 1 and level 2 with the
+     * 4KB granule, and only at level 2 with the 16KB and 64KB granules (ARM
+     * DDI 0487A.k D4.3.1). The block encoding at any other level generates a
+     * Translation fault (AArch64.TranslationTableWalk(), J1.1.5).

... the comment that this is only valid for 48-bit. I would also recommend to update the comment in get_ipa_output_size() to mention this check would need to be updated. Alternatively, you could check the ipa_sizes now.

+     */
+    if ( level == 0 || (level == 1 && gran != GRANULE_SIZE_INDEX_4K) )
+        return false;
+
      /* Make sure that the lower bits of the PTE's base address are zero. */
      mask = GENMASK_ULL(47, grainsizes[gran]);
      *ipa = (pfn_to_paddr(pte.walk.base) & mask) |

Cheers,

--
Julien Grall




 


Rackspace

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