Skip to content

Commit 4155539

Browse files
author
Marc Zyngier
committed
KVM: arm64: nv: Enforce S2 alignment when contiguous bit is set
Despite KVM not using the contiguous bit for anything related to TLBs, the spec does require that the alignment defined by the contiguous bit for the page size and the level is enforced. Add the required checks to offset the point where PA and VA merge. Fixes: 61e30b9 ("KVM: arm64: nv: Implement nested Stage-2 page table walk logic") Reported-by: Alexandru Elisei <alexandru.elisei@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 5fddf9a commit 4155539

2 files changed

Lines changed: 24 additions & 5 deletions

File tree

arch/arm64/include/asm/kvm_nested.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,26 @@ static inline u64 kvm_encode_nested_level(struct kvm_s2_trans *trans)
205205
return FIELD_PREP(KVM_NV_GUEST_MAP_SZ, trans->level);
206206
}
207207

208+
/* Adjust alignment for the contiguous bit as per StageOA() */
209+
#define contiguous_bit_shift(d, wi, l) \
210+
({ \
211+
u8 shift = 0; \
212+
\
213+
if ((d) & PTE_CONT) { \
214+
switch (BIT((wi)->pgshift)) { \
215+
case SZ_4K: \
216+
shift = 4; \
217+
break; \
218+
case SZ_16K: \
219+
shift = (l) == 2 ? 5 : 7; \
220+
break; \
221+
case SZ_64K: \
222+
shift = 5; \
223+
break; \
224+
} \
225+
} \
226+
\
227+
shift; \
228+
})
229+
208230
#endif /* __ARM64_KVM_NESTED_H */

arch/arm64/kvm/nested.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,6 @@ static int walk_nested_s2_pgd(phys_addr_t ipa,
282282
return 1;
283283
}
284284

285-
/*
286-
* We don't use the contiguous bit in the stage-2 ptes, so skip check
287-
* for misprogramming of the contiguous bit.
288-
*/
289-
290285
if (check_output_size(wi, desc)) {
291286
out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
292287
out->upper_attr = desc;
@@ -299,6 +294,8 @@ static int walk_nested_s2_pgd(phys_addr_t ipa,
299294
return 1;
300295
}
301296

297+
addr_bottom += contiguous_bit_shift(desc, wi, level);
298+
302299
/* Calculate and return the result */
303300
paddr = (desc & GENMASK_ULL(47, addr_bottom)) |
304301
(ipa & GENMASK_ULL(addr_bottom - 1, 0));

0 commit comments

Comments
 (0)