* [PATCH v2 1/4] KVM: arm64: Fix MMFR0 TGRAN advertisement for pVMs
2026-09-28 9:54 [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K Vincent Donnefort
@ 2026-09-28 9:54 ` Vincent Donnefort
2026-09-28 9:54 ` [PATCH v2 2/4] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping() Vincent Donnefort
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-09-28 9:54 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, fuad.tabba, qperret, weilin.chang,
Vincent Donnefort, stable
Protected VM ID register emulation leaves unlisted fields at 0. This
creates two issues for TGRAN:
* TGRAN16: 0 means non-implemented. It prevents 16KB protected VMs
from booting even when the hardware supports it.
* TGRAN4|TGRAN64: 0 means implemented. This may falsely advertise the
feature even when the hardware does not support it.
Advertise all the TGRAN fields in pvmid_aa64mmfr0 so that the hardware
support is properly propagated.
Cc: stable@vger.kernel.org
Fixes: 6c30bfb18d0b ("KVM: arm64: Add handlers for protected VM System Registers")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
---
arch/arm64/kvm/hyp/nvhe/sys_regs.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 8758c6801776..ec469d96516a 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -121,6 +121,9 @@ static const struct pvm_ftr_bits pvmid_aa64mmfr0[] = {
MAX_FEAT(ID_AA64MMFR0_EL1, SNSMEM, IMP),
MAX_FEAT(ID_AA64MMFR0_EL1, BIGENDEL0, IMP),
MAX_FEAT(ID_AA64MMFR0_EL1, EXS, IMP),
+ MAX_FEAT(ID_AA64MMFR0_EL1, TGRAN4, IMP),
+ MAX_FEAT(ID_AA64MMFR0_EL1, TGRAN16, IMP),
+ MAX_FEAT(ID_AA64MMFR0_EL1, TGRAN64, IMP),
FEAT_END
};
--
2.56.0.rc1.315.gc6ed9934b7-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 2/4] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping()
2026-09-28 9:54 [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K Vincent Donnefort
2026-09-28 9:54 ` [PATCH v2 1/4] KVM: arm64: Fix MMFR0 TGRAN advertisement for pVMs Vincent Donnefort
@ 2026-09-28 9:54 ` Vincent Donnefort
2026-09-28 9:54 ` [PATCH v2 3/4] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Vincent Donnefort
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-09-28 9:54 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, fuad.tabba, qperret, weilin.chang,
Vincent Donnefort
Pass the fault descriptor to fault_supports_stage2_huge_mapping() instead
of passing memslot and hva separately so it can access other s2fd
members such as vcpu. This implies to pass that same s2fd argument to
transparent_hugepage_adjust().
No functional change intended.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Wei-Lin Chang <weilin.chang@arm.com>
---
arch/arm64/kvm/mmu.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 2d44cd6a5aed..dc55b0792e34 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1362,12 +1362,21 @@ static void kvm_send_hwpoison_signal(unsigned long address, short lsb)
send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current);
}
-static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
- unsigned long hva,
+struct kvm_s2_fault_desc {
+ struct kvm_vcpu *vcpu;
+ phys_addr_t fault_ipa;
+ struct kvm_s2_trans *nested;
+ struct kvm_memory_slot *memslot;
+ unsigned long hva;
+};
+
+static bool fault_supports_stage2_huge_mapping(const struct kvm_s2_fault_desc *s2fd,
unsigned long map_size)
{
- gpa_t gpa_start;
+ struct kvm_memory_slot *memslot = s2fd->memslot;
+ unsigned long hva = s2fd->hva;
hva_t uaddr_start, uaddr_end;
+ gpa_t gpa_start;
size_t size;
/* The memslot and the VMA are guaranteed to be aligned to PAGE_SIZE */
@@ -1436,9 +1445,9 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
* Returns the size of the mapping.
*/
static long
-transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
- unsigned long hva, kvm_pfn_t *pfnp, gfn_t *gfnp)
+transparent_hugepage_adjust(const struct kvm_s2_fault_desc *s2fd, kvm_pfn_t *pfnp, gfn_t *gfnp)
{
+ struct kvm *kvm = s2fd->vcpu->kvm;
kvm_pfn_t pfn = *pfnp;
gfn_t gfn = *gfnp;
@@ -1447,8 +1456,8 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
* sure that the HVA and IPA are sufficiently aligned and that the
* block map is contained within the memslot.
*/
- if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) {
- int sz = get_user_mapping_size(kvm, hva);
+ if (fault_supports_stage2_huge_mapping(s2fd, PMD_SIZE)) {
+ int sz = get_user_mapping_size(kvm, s2fd->hva);
if (sz < 0)
return sz;
@@ -1606,14 +1615,6 @@ static enum kvm_pgtable_prot adjust_nested_exec_perms(struct kvm *kvm,
return prot;
}
-struct kvm_s2_fault_desc {
- struct kvm_vcpu *vcpu;
- phys_addr_t fault_ipa;
- struct kvm_s2_trans *nested;
- struct kvm_memory_slot *memslot;
- unsigned long hva;
-};
-
static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
{
bool write_fault, exec_fault;
@@ -1800,7 +1801,7 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
switch (vma_shift) {
#ifndef __PAGETABLE_PMD_FOLDED
case PUD_SHIFT:
- if (fault_supports_stage2_huge_mapping(s2fd->memslot, s2fd->hva, PUD_SIZE))
+ if (fault_supports_stage2_huge_mapping(s2fd, PUD_SIZE))
break;
fallthrough;
#endif
@@ -1808,7 +1809,7 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
vma_shift = PMD_SHIFT;
fallthrough;
case PMD_SHIFT:
- if (fault_supports_stage2_huge_mapping(s2fd->memslot, s2fd->hva, PMD_SIZE))
+ if (fault_supports_stage2_huge_mapping(s2fd, PMD_SIZE))
break;
fallthrough;
case CONT_PTE_SHIFT:
@@ -2058,9 +2059,7 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
if (perm_fault_granule > PAGE_SIZE) {
mapping_size = perm_fault_granule;
} else {
- mapping_size = transparent_hugepage_adjust(kvm, s2fd->memslot,
- s2fd->hva, &pfn,
- &gfn);
+ mapping_size = transparent_hugepage_adjust(s2fd, &pfn, &gfn);
if (mapping_size < 0) {
ret = mapping_size;
goto out_unlock;
--
2.56.0.rc1.315.gc6ed9934b7-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 3/4] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort()
2026-09-28 9:54 [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K Vincent Donnefort
2026-09-28 9:54 ` [PATCH v2 1/4] KVM: arm64: Fix MMFR0 TGRAN advertisement for pVMs Vincent Donnefort
2026-09-28 9:54 ` [PATCH v2 2/4] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping() Vincent Donnefort
@ 2026-09-28 9:54 ` Vincent Donnefort
2026-09-28 9:54 ` [PATCH v2 4/4] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort() Vincent Donnefort
2026-10-01 14:24 ` [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K Marc Zyngier
4 siblings, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-09-28 9:54 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, fuad.tabba, qperret, weilin.chang, Sashiko,
stable, Vincent Donnefort
From: Fuad Tabba <fuad.tabba@linux.dev>
gmem_abort() maps at s2fd->fault_ipa, which HPFAR_EL2 holds at 4K
granularity whatever the page size. The generic page-table code aligns
it, but pkvm_pgtable_stage2_map() looks up existing mappings over
[addr, addr + size), so on a pKVM host with pages larger than 4K a
guest_memfd-backed guest that faults past the first 4K of a page can
find its neighbour's mapping, get -EAGAIN and take the same fault
forever.
The memory fault exit reports s2fd->fault_ipa too, which for a nested
guest's fault is the nested IPA rather than the canonical one
kvm_gmem_get_pfn() failed on.
Take the addresses from kvm_s2_fault_vma_info instead, as
user_mem_abort() does, and report the canonical gfn in the memory fault
exit. kvm_s2_fault_get_vma_info() itself isn't called: a guest_memfd
memslot's userspace_addr doesn't need to be backed by a VMA.
Fixes: a7b57e0995927 ("KVM: arm64: Handle guest_memfd-backed guest page faults")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/20260913175105.A57AC1F000FF@smtp.kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/mmu.c | 67 ++++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 33 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index dc55b0792e34..5c89b6684b02 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1615,6 +1615,24 @@ static enum kvm_pgtable_prot adjust_nested_exec_perms(struct kvm *kvm,
return prot;
}
+struct kvm_s2_fault_vma_info {
+ unsigned long mmu_seq;
+ long vma_pagesize;
+ vm_flags_t vm_flags;
+ unsigned long max_map_size;
+ struct page *page;
+ kvm_pfn_t pfn;
+ gfn_t gfn;
+ bool device;
+ bool mte_allowed;
+ bool is_vma_cacheable;
+ bool map_writable;
+ bool map_non_cacheable;
+};
+
+static gfn_t get_canonical_gfn(const struct kvm_s2_fault_desc *s2fd,
+ const struct kvm_s2_fault_vma_info *s2vi);
+
static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
{
bool write_fault, exec_fault;
@@ -1622,12 +1640,10 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
- unsigned long mmu_seq;
- struct page *page;
+ struct kvm_s2_fault_vma_info s2vi = {};
struct kvm *kvm = s2fd->vcpu->kvm;
void *memcache = NULL;
- kvm_pfn_t pfn;
- gfn_t gfn;
+ gfn_t canonical_gfn;
int ret;
if (!perm_fault) {
@@ -1637,24 +1653,23 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
return ret;
}
- if (s2fd->nested)
- gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
- else
- gfn = s2fd->fault_ipa >> PAGE_SHIFT;
+ s2vi.vma_pagesize = PAGE_SIZE;
+ s2vi.gfn = ALIGN_DOWN(s2fd->fault_ipa, s2vi.vma_pagesize) >> PAGE_SHIFT;
+ canonical_gfn = get_canonical_gfn(s2fd, &s2vi);
write_fault = kvm_is_write_fault(s2fd->vcpu);
exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu);
VM_WARN_ON_ONCE(write_fault && exec_fault);
- mmu_seq = kvm->mmu_invalidate_seq;
+ s2vi.mmu_seq = kvm->mmu_invalidate_seq;
/* Pairs with the smp_wmb() in kvm_mmu_invalidate_end(). */
smp_rmb();
- ret = kvm_gmem_get_pfn(kvm, s2fd->memslot, gfn, &pfn, &page, NULL);
+ ret = kvm_gmem_get_pfn(kvm, s2fd->memslot, canonical_gfn, &s2vi.pfn, &s2vi.page, NULL);
if (ret) {
- kvm_prepare_memory_fault_exit(s2fd->vcpu, s2fd->fault_ipa, PAGE_SIZE,
- write_fault, exec_fault, false);
+ kvm_prepare_memory_fault_exit(s2fd->vcpu, gfn_to_gpa(canonical_gfn),
+ s2vi.vma_pagesize, write_fault, exec_fault, false);
return ret;
}
@@ -1671,7 +1686,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
prot = adjust_nested_exec_perms(kvm, s2fd->nested, prot);
kvm_fault_lock(kvm);
- if (mmu_invalidate_retry(kvm, mmu_seq)) {
+ if (mmu_invalidate_retry(kvm, s2vi.mmu_seq)) {
ret = -EAGAIN;
goto out_unlock;
}
@@ -1682,39 +1697,25 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
* PTE, which will be preserved.
*/
prot &= ~KVM_NV_GUEST_MAP_SZ;
- ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, s2fd->fault_ipa,
+ ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, gfn_to_gpa(s2vi.gfn),
prot, flags);
} else {
- ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
- __pfn_to_phys(pfn), prot,
+ ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(s2vi.gfn),
+ s2vi.vma_pagesize,
+ __pfn_to_phys(s2vi.pfn), prot,
memcache, flags);
}
out_unlock:
- kvm_release_faultin_page(kvm, page, !!ret, prot & KVM_PGTABLE_PROT_W);
+ kvm_release_faultin_page(kvm, s2vi.page, !!ret, prot & KVM_PGTABLE_PROT_W);
kvm_fault_unlock(kvm);
if ((prot & KVM_PGTABLE_PROT_W) && !ret)
- mark_page_dirty_in_slot(kvm, s2fd->memslot, gfn);
+ mark_page_dirty_in_slot(kvm, s2fd->memslot, canonical_gfn);
return ret != -EAGAIN ? ret : 0;
}
-struct kvm_s2_fault_vma_info {
- unsigned long mmu_seq;
- long vma_pagesize;
- vm_flags_t vm_flags;
- unsigned long max_map_size;
- struct page *page;
- kvm_pfn_t pfn;
- gfn_t gfn;
- bool device;
- bool mte_allowed;
- bool is_vma_cacheable;
- bool map_writable;
- bool map_non_cacheable;
-};
-
static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
{
unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE;
--
2.56.0.rc1.315.gc6ed9934b7-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 4/4] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort()
2026-09-28 9:54 [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K Vincent Donnefort
` (2 preceding siblings ...)
2026-09-28 9:54 ` [PATCH v2 3/4] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Vincent Donnefort
@ 2026-09-28 9:54 ` Vincent Donnefort
2026-10-01 14:24 ` [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K Marc Zyngier
4 siblings, 0 replies; 6+ messages in thread
From: Vincent Donnefort @ 2026-09-28 9:54 UTC (permalink / raw)
To: maz, oupton, kvmarm, linux-arm-kernel
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, fuad.tabba, qperret, weilin.chang,
Vincent Donnefort, stable
To paraphrase Marc in commit 08f97454b7fa ("KVM: arm64: Fix protected
mode handling of pages larger than 4kB"), pkvm_pgtable_stage2_map()
assumes the address passed as a parameter is aligned to the size of the
intended mapping, while HPFAR_EL2 gives the IPA minus the bottom 12
bits, regardless of the system page size configuration.
To fix this alignment, bring support for kvm_s2_fault_vma_info in
pkvm_mem_abort() and use its members where possible. They do contain the
page-alignment we need to fix the fault on system with pages larger than
4K.
Also, add a check at the start of pkvm_pgtable_stage2_map(), it does not
support !PAGE_ALIGNED arguments.
Fixes: ea03466e806f ("KVM: arm64: Handle aborts from protected VMs")
Cc: stable@vger.kernel.org
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
---
arch/arm64/kvm/mmu.c | 27 ++++++++++++++++++---------
arch/arm64/kvm/pkvm.c | 3 +++
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 5c89b6684b02..d48e4beab483 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1383,9 +1383,11 @@ static bool fault_supports_stage2_huge_mapping(const struct kvm_s2_fault_desc *s
if (map_size == PAGE_SIZE)
return true;
- /* pKVM only supports PMD_SIZE huge-mappings */
- if (is_protected_kvm_enabled() && map_size != PMD_SIZE)
- return false;
+ /* pKVM only supports PMD_SIZE huge-mappings for non-protected VMs */
+ if (is_protected_kvm_enabled()) {
+ if (vcpu_is_protected(s2fd->vcpu) || map_size != PMD_SIZE)
+ return false;
+ }
size = memslot->npages * PAGE_SIZE;
@@ -1630,6 +1632,9 @@ struct kvm_s2_fault_vma_info {
bool map_non_cacheable;
};
+static int kvm_s2_fault_get_vma_info(const struct kvm_s2_fault_desc *s2fd,
+ struct kvm_s2_fault_vma_info *s2vi);
+
static gfn_t get_canonical_gfn(const struct kvm_s2_fault_desc *s2fd,
const struct kvm_s2_fault_vma_info *s2vi);
@@ -1719,12 +1724,12 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
{
unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE;
+ struct kvm_s2_fault_vma_info s2vi = {};
struct kvm_vcpu *vcpu = s2fd->vcpu;
struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt;
struct mm_struct *mm = current->mm;
struct kvm *kvm = vcpu->kvm;
void *hyp_memcache;
- struct page *page;
int ret;
hyp_memcache = get_mmu_memcache(vcpu);
@@ -1732,12 +1737,16 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
if (ret)
return -ENOMEM;
+ ret = kvm_s2_fault_get_vma_info(s2fd, &s2vi);
+ if (ret)
+ return ret;
+
ret = account_locked_vm(mm, 1, true);
if (ret)
return ret;
mmap_read_lock(mm);
- ret = pin_user_pages(s2fd->hva, 1, flags, &page);
+ ret = pin_user_pages(s2fd->hva, 1, flags, &s2vi.page);
mmap_read_unlock(mm);
if (ret == -EHWPOISON) {
@@ -1747,7 +1756,7 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
} else if (ret != 1) {
ret = -EFAULT;
goto dec_account;
- } else if (!folio_test_swapbacked(page_folio(page))) {
+ } else if (!folio_test_swapbacked(page_folio(s2vi.page))) {
/*
* We really can't deal with page-cache pages returned by GUP
* because (a) we may trigger writeback of a page for which we
@@ -1767,8 +1776,8 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
}
write_lock(&kvm->mmu_lock);
- ret = pkvm_pgtable_stage2_map(pgt, s2fd->fault_ipa, PAGE_SIZE,
- page_to_phys(page), KVM_PGTABLE_PROT_RWX,
+ ret = pkvm_pgtable_stage2_map(pgt, gfn_to_gpa(s2vi.gfn), PAGE_SIZE,
+ page_to_phys(s2vi.page), KVM_PGTABLE_PROT_RWX,
hyp_memcache, 0);
write_unlock(&kvm->mmu_lock);
if (ret) {
@@ -1779,7 +1788,7 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
return 0;
unpin:
- unpin_user_pages(&page, 1);
+ unpin_user_page(s2vi.page);
dec_account:
account_locked_vm(mm, 1, false);
return ret;
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 8e4c6e4bec12..c298a5b9b12a 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -414,6 +414,9 @@ int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
u64 end = addr + size;
int ret;
+ if (WARN_ON_ONCE(!PAGE_ALIGNED(addr | size)))
+ return -EINVAL;
+
lockdep_assert_held_write(&kvm->mmu_lock);
mapping = pkvm_mapping_iter_first(&pgt->pkvm_mappings, addr, end - 1);
--
2.56.0.rc1.315.gc6ed9934b7-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K
2026-09-28 9:54 [PATCH v2 0/4] Fix guest_memfd and protected VMs on systems with pages larger than 4K Vincent Donnefort
` (3 preceding siblings ...)
2026-09-28 9:54 ` [PATCH v2 4/4] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort() Vincent Donnefort
@ 2026-10-01 14:24 ` Marc Zyngier
4 siblings, 0 replies; 6+ messages in thread
From: Marc Zyngier @ 2026-10-01 14:24 UTC (permalink / raw)
To: oupton, kvmarm, linux-arm-kernel, Vincent Donnefort
Cc: joey.gouly, seiden, suzuki.poulose, yuzenghui, catalin.marinas,
will, kernel-team, fuad.tabba, qperret, weilin.chang
On Mon, 28 Sep 2026 10:54:49 +0100, Vincent Donnefort wrote:
> This series allows booting protected VMs and guest_memfd-back VMs on
> systems with a page size larger than 4K.
>
> Currently, the fault handling assumes 4K alignment, as HPFAR_EL2
> provides the IPA minus the bottom 12 bits regardless of the system page
> size. This leads to mapping failures on 16K and 64K systems.
>
> [...]
Applied to next, thanks!
[1/4] KVM: arm64: Fix MMFR0 TGRAN advertisement for pVMs
commit: 6c29285e78b5e4811145ebda382ac0ba732ce56a
[2/4] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping()
commit: 10c5cc50f056a6425305557063ad70c3eb0e686b
[3/4] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort()
commit: 80b0b86dc5e4344e62a2fd3ee43d0ef816fe9122
[4/4] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort()
commit: 0cdcc1039200b3c4fbc2ae3f9b5c1be1bc9155e8
Again, a large number of conflicts (prefault, rmap). Please review the
conflict resolution.
Cheers,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 6+ messages in thread