Skip to content

Commit e2b6d94

Browse files
committed
Merge tag 'kvmarm-fixes-5.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 fixes for 5.15, take #2 - Properly refcount pages used as a concatenated stage-2 PGD - Fix missing unlock when detecting the use of MTE+VM_SHARED
2 parents 019057b + 6e6a8ef commit e2b6d94

File tree

4 files changed

+32
-3
lines changed

4 files changed

+32
-3
lines changed

arch/arm64/kvm/hyp/include/nvhe/gfp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct hyp_pool {
2424

2525
/* Allocation */
2626
void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order);
27+
void hyp_split_page(struct hyp_page *page);
2728
void hyp_get_page(struct hyp_pool *pool, void *addr);
2829
void hyp_put_page(struct hyp_pool *pool, void *addr);
2930

arch/arm64/kvm/hyp/nvhe/mem_protect.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,18 @@ const u8 pkvm_hyp_id = 1;
3535

3636
static void *host_s2_zalloc_pages_exact(size_t size)
3737
{
38-
return hyp_alloc_pages(&host_s2_pool, get_order(size));
38+
void *addr = hyp_alloc_pages(&host_s2_pool, get_order(size));
39+
40+
hyp_split_page(hyp_virt_to_page(addr));
41+
42+
/*
43+
* The size of concatenated PGDs is always a power of two of PAGE_SIZE,
44+
* so there should be no need to free any of the tail pages to make the
45+
* allocation exact.
46+
*/
47+
WARN_ON(size != (PAGE_SIZE << get_order(size)));
48+
49+
return addr;
3950
}
4051

4152
static void *host_s2_zalloc_page(void *pool)

arch/arm64/kvm/hyp/nvhe/page_alloc.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static inline void hyp_page_ref_inc(struct hyp_page *p)
152152

153153
static inline int hyp_page_ref_dec_and_test(struct hyp_page *p)
154154
{
155+
BUG_ON(!p->refcount);
155156
p->refcount--;
156157
return (p->refcount == 0);
157158
}
@@ -193,6 +194,20 @@ void hyp_get_page(struct hyp_pool *pool, void *addr)
193194
hyp_spin_unlock(&pool->lock);
194195
}
195196

197+
void hyp_split_page(struct hyp_page *p)
198+
{
199+
unsigned short order = p->order;
200+
unsigned int i;
201+
202+
p->order = 0;
203+
for (i = 1; i < (1 << order); i++) {
204+
struct hyp_page *tail = p + i;
205+
206+
tail->order = 0;
207+
hyp_set_page_refcounted(tail);
208+
}
209+
}
210+
196211
void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order)
197212
{
198213
unsigned short i = order;

arch/arm64/kvm/mmu.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,8 +1529,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
15291529
* when updating the PG_mte_tagged page flag, see
15301530
* sanitise_mte_tags for more details.
15311531
*/
1532-
if (kvm_has_mte(kvm) && vma->vm_flags & VM_SHARED)
1533-
return -EINVAL;
1532+
if (kvm_has_mte(kvm) && vma->vm_flags & VM_SHARED) {
1533+
ret = -EINVAL;
1534+
break;
1535+
}
15341536

15351537
if (vma->vm_flags & VM_PFNMAP) {
15361538
/* IO region dirty page logging not allowed */

0 commit comments

Comments
 (0)