Skip to content

Commit 5e806c5

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: Reject shared table walks in the hyp code
Exclusive table walks are the only supported table walk in the hyp, as there is no construct like RCU available in the hypervisor code. Reject any attempt to do a shared table walk by returning an error and allowing the caller to clean up the mess. Suggested-by: Will Deacon <[email protected]> Signed-off-by: Oliver Upton <[email protected]> Acked-by: Will Deacon <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b7833bf commit 5e806c5

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,18 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
229229
return pteref;
230230
}
231231

232-
static inline void kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker) {}
232+
static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
233+
{
234+
/*
235+
* Due to the lack of RCU (or a similar protection scheme), only
236+
* non-shared table walkers are allowed in the hypervisor.
237+
*/
238+
if (walker->flags & KVM_PGTABLE_WALK_SHARED)
239+
return -EPERM;
240+
241+
return 0;
242+
}
243+
233244
static inline void kvm_pgtable_walk_end(struct kvm_pgtable_walker *walker) {}
234245

235246
static inline bool kvm_pgtable_walk_lock_held(void)
@@ -247,10 +258,12 @@ static inline kvm_pte_t *kvm_dereference_pteref(struct kvm_pgtable_walker *walke
247258
return rcu_dereference_check(pteref, !(walker->flags & KVM_PGTABLE_WALK_SHARED));
248259
}
249260

250-
static inline void kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
261+
static inline int kvm_pgtable_walk_begin(struct kvm_pgtable_walker *walker)
251262
{
252263
if (walker->flags & KVM_PGTABLE_WALK_SHARED)
253264
rcu_read_lock();
265+
266+
return 0;
254267
}
255268

256269
static inline void kvm_pgtable_walk_end(struct kvm_pgtable_walker *walker)

arch/arm64/kvm/hyp/pgtable.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,10 @@ int kvm_pgtable_walk(struct kvm_pgtable *pgt, u64 addr, u64 size,
289289
};
290290
int r;
291291

292-
kvm_pgtable_walk_begin(walker);
292+
r = kvm_pgtable_walk_begin(walker);
293+
if (r)
294+
return r;
295+
293296
r = _kvm_pgtable_walk(pgt, &walk_data);
294297
kvm_pgtable_walk_end(walker);
295298

0 commit comments

Comments
 (0)