mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] KVM: arm64: Per-vCPU TLB and I-cache flush in pKVM
@ 2026-10-14 12:55 Fuad Tabba
  2026-10-14 12:55 ` [PATCH 1/2] KVM: arm64: Track physical CPU number at EL2 Fuad Tabba
  2026-10-14 12:55 ` [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM Fuad Tabba
  0 siblings, 2 replies; 12+ messages in thread
From: Fuad Tabba @ 2026-10-14 12:55 UTC (permalink / raw)
  To: Marc Zyngier, Oliver Upton
  Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, Mark Rutland, Vincent Donnefort,
	Quentin Perret, Fuad Tabba, kvmarm, linux-arm-kernel,
	linux-kernel

Hi folks,

Since 6.14, protected and non-protected pKVM guests run on the
hypervisor's VMID. The host no longer flushes a CPU's TLBs and I-cache
when a different vCPU of the same VM is loaded there, so vCPUs of one
guest can hit each other's entries. This series adds the flush at EL2.

An earlier version of these patches was in Will's pKVM base series in
2022 [1], but didn't make it into its later versions.

This series is based on kvmarm/next because the hyp VM is allocated with
hyp_alloc() there, and the per-CPU array it adds is allocated the same
way.

Based on kvmarm/next (dd0bc00e3e920).

Cheers,
/fuad

[1] https://lore.kernel.org/all/20220519134204.5379-1-will@kernel.org/

Fuad Tabba (2):
  KVM: arm64: Track physical CPU number at EL2
  KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM

 arch/arm64/include/asm/kvm_hyp.h       |  3 +++
 arch/arm64/kvm/arm.c                   |  3 +++
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c     |  8 ++++++++
 arch/arm64/kvm/hyp/nvhe/hyp-smp.c      |  2 ++
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 21 ++++++++++++++++++---
 6 files changed, 37 insertions(+), 3 deletions(-)


base-commit: dd0bc00e3e9201fd49b62ff9cc07890c89003afe
-- 
2.39.5


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/2] KVM: arm64: Track physical CPU number at EL2
  2026-10-14 12:55 [PATCH 0/2] KVM: arm64: Per-vCPU TLB and I-cache flush in pKVM Fuad Tabba
@ 2026-10-14 12:55 ` Fuad Tabba
  2026-10-19 10:34   ` Marc Zyngier
  2026-10-14 12:55 ` [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM Fuad Tabba
  1 sibling, 1 reply; 12+ messages in thread
From: Fuad Tabba @ 2026-10-14 12:55 UTC (permalink / raw)
  To: Marc Zyngier, Oliver Upton
  Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, Mark Rutland, Vincent Donnefort,
	Quentin Perret, Fuad Tabba, kvmarm, linux-arm-kernel,
	linux-kernel

The nVHE hypervisor has no equivalent of smp_processor_id(), so EL2 code
has no index for the CPU it runs on.

Add a hyp per-CPU hyp_cpu_number, which the host writes in
cpu_prepare_hyp_mode() before it's deprivileged, and a
hyp_smp_processor_id() accessor to read it. The next patch uses it to
index per-CPU state in a hyp VM.

Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
 arch/arm64/include/asm/kvm_hyp.h  | 3 +++
 arch/arm64/kvm/arm.c              | 3 +++
 arch/arm64/kvm/hyp/nvhe/hyp-smp.c | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index b0e42be3d9eef..6c4169a14b73e 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -16,6 +16,9 @@
 DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 DECLARE_PER_CPU(unsigned long, kvm_hyp_vector);
 DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
+DECLARE_PER_CPU(int, hyp_cpu_number);
+
+#define hyp_smp_processor_id() (__this_cpu_read(hyp_cpu_number))
 
 /*
  * Unified accessors for registers that have a different encoding
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index d593ba9280933..0dd6667f1beea 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -116,6 +116,7 @@ DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);
 
 DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_base);
 DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
+DECLARE_KVM_NVHE_PER_CPU(int, hyp_cpu_number);
 
 DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
 
@@ -2351,6 +2352,8 @@ static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 	struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu);
 	unsigned long tcr;
 
+	*per_cpu_ptr_nvhe_sym(hyp_cpu_number, cpu) = cpu;
+
 	/*
 	 * Calculate the raw per-cpu offset without a translation from the
 	 * kernel's mapping to the linear mapping, and store it in tpidr_el2
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-smp.c b/arch/arm64/kvm/hyp/nvhe/hyp-smp.c
index 04d194583f1e4..9fcb92abd0b57 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-smp.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-smp.c
@@ -8,6 +8,8 @@
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
 
+DEFINE_PER_CPU(int, hyp_cpu_number);
+
 /*
  * nVHE copy of data structures tracking available CPU cores.
  * Only entries for CPUs that were online at KVM init are populated.
-- 
2.39.5


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-14 12:55 [PATCH 0/2] KVM: arm64: Per-vCPU TLB and I-cache flush in pKVM Fuad Tabba
  2026-10-14 12:55 ` [PATCH 1/2] KVM: arm64: Track physical CPU number at EL2 Fuad Tabba
@ 2026-10-14 12:55 ` Fuad Tabba
  2026-10-14 15:53   ` Joey Gouly
  2026-10-19 10:00   ` Vincent Donnefort
  1 sibling, 2 replies; 12+ messages in thread
From: Fuad Tabba @ 2026-10-14 12:55 UTC (permalink / raw)
  To: Marc Zyngier, Oliver Upton
  Cc: Joey Gouly, Steffen Eiden, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, Mark Rutland, Vincent Donnefort,
	Quentin Perret, Fuad Tabba, kvmarm, linux-arm-kernel,
	linux-kernel

All vCPUs of a VM share its VMID, so KVM flushes a physical CPU's TLBs
and I-cache for the VM whenever a different vCPU of that VM is loaded
there (vcpu_prepare_mmu()). Commit fce886a602073 ("KVM: arm64: Plumb the
pKVM MMU in KVM") moved pKVM guests, protected or not, onto the
hypervisor's stage-2 and VMID, and the host stopped flushing for them.
Nothing at EL2 flushes instead, so a vCPU can hit TLB and I-cache
entries that another vCPU of the same VM left on that CPU.

Track the last vCPU loaded on each physical CPU in the hyp VM, and flush
at EL2 in __pkvm_vcpu_load() when it changes.

Fixes: fce886a602073 ("KVM: arm64: Plumb the pKVM MMU in KVM")
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
 arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c     |  8 ++++++++
 arch/arm64/kvm/hyp/nvhe/pkvm.c         | 21 ++++++++++++++++++---
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
index 9abfe6b7e942b..02c8fc7a10904 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
@@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
 	unsigned short refcount;
 	hyp_spinlock_t lock;
 
+	/* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
+	int *last_vcpu_ran;
+
 	/*
 	 * The vCPU initialised RUNNABLE: claimed under vm_table_lock,
 	 * released only if its own init fails.
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index d715aa942577e..f0b77236c871e 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -827,11 +827,19 @@ DEFINE_KVM_HOST_HCALL(void, __pkvm_vcpu_load,
 	pkvm_handle_t, handle, unsigned int, vcpu_idx, u64, hcr_el2)
 {
 	struct pkvm_hyp_vcpu *hyp_vcpu;
+	int *last_ran;
 
 	hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
 	if (!hyp_vcpu)
 		return;
 
+	/* TLBs and I-cache are private to each vCPU, see vcpu_prepare_mmu(). */
+	last_ran = &pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu)->last_vcpu_ran[hyp_smp_processor_id()];
+	if (*last_ran != vcpu_idx) {
+		__kvm_flush_cpu_context(hyp_vcpu->vcpu.arch.hw_mmu);
+		*last_ran = vcpu_idx;
+	}
+
 	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
 		u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
 
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index ac020d0501d2e..f18fa762746c9 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -489,10 +489,11 @@ static void unpin_host_vcpus(struct pkvm_hyp_vcpu *hyp_vcpus[],
 }
 
 static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
-			     unsigned int nr_vcpus, pkvm_handle_t handle)
+			     int *last_vcpu_ran, unsigned int nr_vcpus, pkvm_handle_t handle)
 {
 	struct kvm_s2_mmu *mmu = &hyp_vm->kvm.arch.mmu;
 	int idx = vm_handle_to_idx(handle);
+	unsigned long cpu;
 
 	hyp_vm->kvm.arch.pkvm.handle = handle;
 
@@ -512,6 +513,10 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
 	mmu->vtcr = host_mmu.arch.mmu.vtcr;
 	mmu->arch = &hyp_vm->kvm.arch;
 	mmu->pgt = &hyp_vm->pgt;
+
+	for (cpu = 0; cpu < hyp_nr_cpus; cpu++)
+		last_vcpu_ran[cpu] = -1;
+	hyp_vm->last_vcpu_ran = last_vcpu_ran;
 }
 
 static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *host_vcpu)
@@ -887,6 +892,7 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
 	size_t vm_size, pgd_size;
 	unsigned int nr_vcpus;
 	pkvm_handle_t handle;
+	int *last_vcpu_ran;
 	void *pgd = NULL;
 	int ret;
 
@@ -915,13 +921,19 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
 		goto err_unpin_kvm;
 	}
 
+	last_vcpu_ran = hyp_alloc(array_size(hyp_nr_cpus, sizeof(*last_vcpu_ran)));
+	if (!last_vcpu_ran) {
+		ret = hyp_alloc_errno();
+		goto err_free_hyp_vm;
+	}
+
 	ret = -ENOMEM;
 
 	pgd = map_donated_memory_noclear(pgd_hva, pgd_size);
 	if (!pgd)
-		goto err_free_hyp_vm;
+		goto err_free_last_ran;
 
-	init_pkvm_hyp_vm(host_kvm, hyp_vm, nr_vcpus, handle);
+	init_pkvm_hyp_vm(host_kvm, hyp_vm, last_vcpu_ran, nr_vcpus, handle);
 
 	ret = kvm_guest_prepare_stage2(hyp_vm, pgd);
 	if (ret)
@@ -938,6 +950,8 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
 	kvm_guest_destroy_stage2(hyp_vm);
 err_remove_mappings:
 	unmap_donated_memory(pgd, pgd_size);
+err_free_last_ran:
+	hyp_free(last_vcpu_ran);
 err_free_hyp_vm:
 	hyp_free(hyp_vm);
 err_unpin_kvm:
@@ -1112,6 +1126,7 @@ int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
 		hyp_free(hyp_vcpu);
 	}
 
+	hyp_free(hyp_vm->last_vcpu_ran);
 	hyp_free(hyp_vm);
 	hyp_unpin_shared_mem(host_kvm, host_kvm + 1);
 	return 0;
-- 
2.39.5


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-14 12:55 ` [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM Fuad Tabba
@ 2026-10-14 15:53   ` Joey Gouly
  2026-10-19 11:43     ` Fuad Tabba
  2026-10-19 10:00   ` Vincent Donnefort
  1 sibling, 1 reply; 12+ messages in thread
From: Joey Gouly @ 2026-10-14 15:53 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: Marc Zyngier, Oliver Upton, Steffen Eiden, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Mark Rutland,
	Vincent Donnefort, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

Hi!

On Wed, Oct 14, 2026 at 01:55:10PM +0100, Fuad Tabba wrote:
> All vCPUs of a VM share its VMID, so KVM flushes a physical CPU's TLBs
> and I-cache for the VM whenever a different vCPU of that VM is loaded
> there (vcpu_prepare_mmu()). Commit fce886a602073 ("KVM: arm64: Plumb the
> pKVM MMU in KVM") moved pKVM guests, protected or not, onto the
> hypervisor's stage-2 and VMID, and the host stopped flushing for them.
> Nothing at EL2 flushes instead, so a vCPU can hit TLB and I-cache
> entries that another vCPU of the same VM left on that CPU.
> 
> Track the last vCPU loaded on each physical CPU in the hyp VM, and flush
> at EL2 in __pkvm_vcpu_load() when it changes.
> 
> Fixes: fce886a602073 ("KVM: arm64: Plumb the pKVM MMU in KVM")
> Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c     |  8 ++++++++
>  arch/arm64/kvm/hyp/nvhe/pkvm.c         | 21 ++++++++++++++++++---
>  3 files changed, 29 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> index 9abfe6b7e942b..02c8fc7a10904 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> @@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
>  	unsigned short refcount;
>  	hyp_spinlock_t lock;
>  
> +	/* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
> +	int *last_vcpu_ran;

Trying to think of a better way to reword this, it's an array indexed by
pCPU, not per cpu in the normal linux way. Unlike `mmu->last_vcpu_ran`
which really is per_cpu. Maybe I'm just being nitpicky, and it's fine as
is!

> +
>  	/*
>  	 * The vCPU initialised RUNNABLE: claimed under vm_table_lock,
>  	 * released only if its own init fails.
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index d715aa942577e..f0b77236c871e 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -827,11 +827,19 @@ DEFINE_KVM_HOST_HCALL(void, __pkvm_vcpu_load,
>  	pkvm_handle_t, handle, unsigned int, vcpu_idx, u64, hcr_el2)
>  {
>  	struct pkvm_hyp_vcpu *hyp_vcpu;
> +	int *last_ran;
>  
>  	hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
>  	if (!hyp_vcpu)
>  		return;
>  
> +	/* TLBs and I-cache are private to each vCPU, see vcpu_prepare_mmu(). */
> +	last_ran = &pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu)->last_vcpu_ran[hyp_smp_processor_id()];
> +	if (*last_ran != vcpu_idx) {
> +		__kvm_flush_cpu_context(hyp_vcpu->vcpu.arch.hw_mmu);
> +		*last_ran = vcpu_idx;
> +	}
> +
>  	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
>  		u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
>  
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index ac020d0501d2e..f18fa762746c9 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -489,10 +489,11 @@ static void unpin_host_vcpus(struct pkvm_hyp_vcpu *hyp_vcpus[],
>  }
>  
>  static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
> -			     unsigned int nr_vcpus, pkvm_handle_t handle)
> +			     int *last_vcpu_ran, unsigned int nr_vcpus, pkvm_handle_t handle)
>  {
>  	struct kvm_s2_mmu *mmu = &hyp_vm->kvm.arch.mmu;
>  	int idx = vm_handle_to_idx(handle);
> +	unsigned long cpu;
>  
>  	hyp_vm->kvm.arch.pkvm.handle = handle;
>  
> @@ -512,6 +513,10 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
>  	mmu->vtcr = host_mmu.arch.mmu.vtcr;
>  	mmu->arch = &hyp_vm->kvm.arch;
>  	mmu->pgt = &hyp_vm->pgt;
> +
> +	for (cpu = 0; cpu < hyp_nr_cpus; cpu++)
> +		last_vcpu_ran[cpu] = -1;
> +	hyp_vm->last_vcpu_ran = last_vcpu_ran;
>  }
>  
>  static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *host_vcpu)
> @@ -887,6 +892,7 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
>  	size_t vm_size, pgd_size;
>  	unsigned int nr_vcpus;
>  	pkvm_handle_t handle;
> +	int *last_vcpu_ran;
>  	void *pgd = NULL;
>  	int ret;
>  
> @@ -915,13 +921,19 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
>  		goto err_unpin_kvm;
>  	}
>  
> +	last_vcpu_ran = hyp_alloc(array_size(hyp_nr_cpus, sizeof(*last_vcpu_ran)));
> +	if (!last_vcpu_ran) {
> +		ret = hyp_alloc_errno();
> +		goto err_free_hyp_vm;
> +	}
> +
>  	ret = -ENOMEM;
>  
>  	pgd = map_donated_memory_noclear(pgd_hva, pgd_size);
>  	if (!pgd)
> -		goto err_free_hyp_vm;
> +		goto err_free_last_ran;
>  
> -	init_pkvm_hyp_vm(host_kvm, hyp_vm, nr_vcpus, handle);
> +	init_pkvm_hyp_vm(host_kvm, hyp_vm, last_vcpu_ran, nr_vcpus, handle);
>  
>  	ret = kvm_guest_prepare_stage2(hyp_vm, pgd);
>  	if (ret)
> @@ -938,6 +950,8 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
>  	kvm_guest_destroy_stage2(hyp_vm);
>  err_remove_mappings:
>  	unmap_donated_memory(pgd, pgd_size);
> +err_free_last_ran:
> +	hyp_free(last_vcpu_ran);
>  err_free_hyp_vm:
>  	hyp_free(hyp_vm);
>  err_unpin_kvm:
> @@ -1112,6 +1126,7 @@ int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
>  		hyp_free(hyp_vcpu);
>  	}
>  
> +	hyp_free(hyp_vm->last_vcpu_ran);
>  	hyp_free(hyp_vm);
>  	hyp_unpin_shared_mem(host_kvm, host_kvm + 1);
>  	return 0;

For the series:
Reviewed-by: Joey Gouly <joey.gouly@arm.com>

Thanks,
Joey

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-14 12:55 ` [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM Fuad Tabba
  2026-10-14 15:53   ` Joey Gouly
@ 2026-10-19 10:00   ` Vincent Donnefort
  2026-10-19 11:43     ` Fuad Tabba
  1 sibling, 1 reply; 12+ messages in thread
From: Vincent Donnefort @ 2026-10-19 10:00 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

On Wed, Oct 14, 2026 at 01:55:10PM +0100, Fuad Tabba wrote:
> All vCPUs of a VM share its VMID, so KVM flushes a physical CPU's TLBs
> and I-cache for the VM whenever a different vCPU of that VM is loaded
> there (vcpu_prepare_mmu()). Commit fce886a602073 ("KVM: arm64: Plumb the
> pKVM MMU in KVM") moved pKVM guests, protected or not, onto the
> hypervisor's stage-2 and VMID, and the host stopped flushing for them.
> Nothing at EL2 flushes instead, so a vCPU can hit TLB and I-cache
> entries that another vCPU of the same VM left on that CPU.
> 
> Track the last vCPU loaded on each physical CPU in the hyp VM, and flush
> at EL2 in __pkvm_vcpu_load() when it changes.
> 
> Fixes: fce886a602073 ("KVM: arm64: Plumb the pKVM MMU in KVM")
> Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
> ---
>  arch/arm64/kvm/hyp/include/nvhe/pkvm.h |  3 +++
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c     |  8 ++++++++
>  arch/arm64/kvm/hyp/nvhe/pkvm.c         | 21 ++++++++++++++++++---
>  3 files changed, 29 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> index 9abfe6b7e942b..02c8fc7a10904 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> @@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
>  	unsigned short refcount;
>  	hyp_spinlock_t lock;
>  
> +	/* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
> +	int *last_vcpu_ran;

Unlikely to be a problem in pratice, but vcpu_idx is "unsigned int". I wonder if
this shouldn't be unsigned int here too and initialised to UINT_MAX?

> +
>  	/*
>  	 * The vCPU initialised RUNNABLE: claimed under vm_table_lock,
>  	 * released only if its own init fails.
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index d715aa942577e..f0b77236c871e 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -827,11 +827,19 @@ DEFINE_KVM_HOST_HCALL(void, __pkvm_vcpu_load,
>  	pkvm_handle_t, handle, unsigned int, vcpu_idx, u64, hcr_el2)
>  {
>  	struct pkvm_hyp_vcpu *hyp_vcpu;
> +	int *last_ran;
>  
>  	hyp_vcpu = pkvm_load_hyp_vcpu(handle, vcpu_idx);
>  	if (!hyp_vcpu)
>  		return;
>  
> +	/* TLBs and I-cache are private to each vCPU, see vcpu_prepare_mmu(). */
> +	last_ran = &pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu)->last_vcpu_ran[hyp_smp_processor_id()];
> +	if (*last_ran != vcpu_idx) {
> +		__kvm_flush_cpu_context(hyp_vcpu->vcpu.arch.hw_mmu);
> +		*last_ran = vcpu_idx;
> +	}
> +
>  	if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) {
>  		u64 dfr0 = read_sysreg(id_aa64dfr0_el1);
>  
> diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> index ac020d0501d2e..f18fa762746c9 100644
> --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
> @@ -489,10 +489,11 @@ static void unpin_host_vcpus(struct pkvm_hyp_vcpu *hyp_vcpus[],
>  }
>  
>  static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
> -			     unsigned int nr_vcpus, pkvm_handle_t handle)
> +			     int *last_vcpu_ran, unsigned int nr_vcpus, pkvm_handle_t handle)
>  {
>  	struct kvm_s2_mmu *mmu = &hyp_vm->kvm.arch.mmu;
>  	int idx = vm_handle_to_idx(handle);
> +	unsigned long cpu;
>  
>  	hyp_vm->kvm.arch.pkvm.handle = handle;
>  
> @@ -512,6 +513,10 @@ static void init_pkvm_hyp_vm(struct kvm *host_kvm, struct pkvm_hyp_vm *hyp_vm,
>  	mmu->vtcr = host_mmu.arch.mmu.vtcr;
>  	mmu->arch = &hyp_vm->kvm.arch;
>  	mmu->pgt = &hyp_vm->pgt;
> +
> +	for (cpu = 0; cpu < hyp_nr_cpus; cpu++)
> +		last_vcpu_ran[cpu] = -1;
> +	hyp_vm->last_vcpu_ran = last_vcpu_ran;
>  }
>  
>  static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *host_vcpu)
> @@ -887,6 +892,7 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
>  	size_t vm_size, pgd_size;
>  	unsigned int nr_vcpus;
>  	pkvm_handle_t handle;
> +	int *last_vcpu_ran;
>  	void *pgd = NULL;
>  	int ret;
>  
> @@ -915,13 +921,19 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
>  		goto err_unpin_kvm;
>  	}
>  
> +	last_vcpu_ran = hyp_alloc(array_size(hyp_nr_cpus, sizeof(*last_vcpu_ran)));
> +	if (!last_vcpu_ran) {
> +		ret = hyp_alloc_errno();
> +		goto err_free_hyp_vm;
> +	}
> +
>  	ret = -ENOMEM;
>  
>  	pgd = map_donated_memory_noclear(pgd_hva, pgd_size);
>  	if (!pgd)
> -		goto err_free_hyp_vm;
> +		goto err_free_last_ran;
>  
> -	init_pkvm_hyp_vm(host_kvm, hyp_vm, nr_vcpus, handle);
> +	init_pkvm_hyp_vm(host_kvm, hyp_vm, last_vcpu_ran, nr_vcpus, handle);
>  
>  	ret = kvm_guest_prepare_stage2(hyp_vm, pgd);
>  	if (ret)
> @@ -938,6 +950,8 @@ int __pkvm_init_vm(struct kvm *host_kvm, void __kern *pgd_hva)
>  	kvm_guest_destroy_stage2(hyp_vm);
>  err_remove_mappings:
>  	unmap_donated_memory(pgd, pgd_size);
> +err_free_last_ran:
> +	hyp_free(last_vcpu_ran);
>  err_free_hyp_vm:
>  	hyp_free(hyp_vm);
>  err_unpin_kvm:
> @@ -1112,6 +1126,7 @@ int __pkvm_finalize_teardown_vm(pkvm_handle_t handle)
>  		hyp_free(hyp_vcpu);
>  	}
>  
> +	hyp_free(hyp_vm->last_vcpu_ran);
>  	hyp_free(hyp_vm);
>  	hyp_unpin_shared_mem(host_kvm, host_kvm + 1);
>  	return 0;
> -- 
> 2.39.5
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] KVM: arm64: Track physical CPU number at EL2
  2026-10-14 12:55 ` [PATCH 1/2] KVM: arm64: Track physical CPU number at EL2 Fuad Tabba
@ 2026-10-19 10:34   ` Marc Zyngier
  2026-10-19 11:43     ` Fuad Tabba
  0 siblings, 1 reply; 12+ messages in thread
From: Marc Zyngier @ 2026-10-19 10:34 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: Oliver Upton, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Mark Rutland,
	Vincent Donnefort, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

On Wed, 14 Oct 2026 13:55:09 +0100,
Fuad Tabba <fuad.tabba@linux.dev> wrote:
> 
> The nVHE hypervisor has no equivalent of smp_processor_id(), so EL2 code
> has no index for the CPU it runs on.
> 
> Add a hyp per-CPU hyp_cpu_number, which the host writes in
> cpu_prepare_hyp_mode() before it's deprivileged, and a
> hyp_smp_processor_id() accessor to read it. The next patch uses it to
> index per-CPU state in a hyp VM.
> 
> Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
> ---
>  arch/arm64/include/asm/kvm_hyp.h  | 3 +++
>  arch/arm64/kvm/arm.c              | 3 +++
>  arch/arm64/kvm/hyp/nvhe/hyp-smp.c | 2 ++
>  3 files changed, 8 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
> index b0e42be3d9eef..6c4169a14b73e 100644
> --- a/arch/arm64/include/asm/kvm_hyp.h
> +++ b/arch/arm64/include/asm/kvm_hyp.h
> @@ -16,6 +16,9 @@
>  DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
>  DECLARE_PER_CPU(unsigned long, kvm_hyp_vector);
>  DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
> +DECLARE_PER_CPU(int, hyp_cpu_number);
> +
> +#define hyp_smp_processor_id() (__this_cpu_read(hyp_cpu_number))
>

Do we really need this? I was hoping that TPIDR_EL2 would give us a
way to compute the CPU number more or less directly, without having to
maintain per-CPU variable (which is pretty backward, when you think
about it...).

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] KVM: arm64: Track physical CPU number at EL2
  2026-10-19 10:34   ` Marc Zyngier
@ 2026-10-19 11:43     ` Fuad Tabba
  0 siblings, 0 replies; 12+ messages in thread
From: Fuad Tabba @ 2026-10-19 11:43 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Oliver Upton, Joey Gouly, Steffen Eiden, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Mark Rutland,
	Vincent Donnefort, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

Hi Marc,

On Mon, 19 Oct 2026 11:34:23 +0100, Marc Zyngier <maz@kernel.org> wrote:
[...]
> > diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
[...]
> > +DECLARE_PER_CPU(int, hyp_cpu_number);
> > +
> > +#define hyp_smp_processor_id() (__this_cpu_read(hyp_cpu_number))
> >
> 
> Do we really need this? I was hoping that TPIDR_EL2 would give us a
> way to compute the CPU number more or less directly, without having to
> maintain per-CPU variable (which is pretty backward, when you think
> about it...).

No. There's no direct way from TPIDR_EL2 to the CPU number, since
init_hyp_mode() allocates each CPU's hyp per-CPU area separately, but
patch 2 can do without the number. I'll drop this patch in v2, and
patch 2 will keep the last vCPU in a per-CPU array indexed by the VM's
table entry.

Cheers,
/fuad

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-14 15:53   ` Joey Gouly
@ 2026-10-19 11:43     ` Fuad Tabba
  0 siblings, 0 replies; 12+ messages in thread
From: Fuad Tabba @ 2026-10-19 11:43 UTC (permalink / raw)
  To: Joey Gouly
  Cc: Marc Zyngier, Oliver Upton, Steffen Eiden, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Mark Rutland,
	Vincent Donnefort, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

Hi Joey,

On Wed, 14 Oct 2026 16:53:39 +0100, Joey Gouly <joey.gouly@arm.com> wrote:
[...]
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
[...]
> > @@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
> >          unsigned short refcount;
> >          hyp_spinlock_t lock;
> >  
> > +        /* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
> > +        int *last_vcpu_ran;
> 
> Trying to think of a better way to reword this, it's an array indexed by
> pCPU, not per cpu in the normal linux way. Unlike `mmu->last_vcpu_ran`
> which really is per_cpu. Maybe I'm just being nitpicky, and it's fine as
> is!

Agreed, "Per physical CPU" reads as a per_cpu variable, which it
wasn't. After Marc's comment on patch 1 [1], it's a real per-CPU
variable in v2, indexed by the VM's table entry.

Thanks,
/fuad

[1] https://lore.kernel.org/all/86y0buyo5s.wl-maz@kernel.org/

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-19 10:00   ` Vincent Donnefort
@ 2026-10-19 11:43     ` Fuad Tabba
  2026-10-19 12:39       ` Vincent Donnefort
  0 siblings, 1 reply; 12+ messages in thread
From: Fuad Tabba @ 2026-10-19 11:43 UTC (permalink / raw)
  To: Vincent Donnefort
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

Hi Vincent,

On Mon, 19 Oct 2026 11:00:15 +0100, Vincent Donnefort <vdonnefort@google.com> wrote:
[...]
> > diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
[...]
> > @@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
> >          unsigned short refcount;
> >          hyp_spinlock_t lock;
> >  
> > +        /* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
> > +        int *last_vcpu_ran;
> 
> Unlikely to be a problem in pratice, but vcpu_idx is "unsigned int". I wonder if
> this shouldn't be unsigned int here too and initialised to UINT_MAX?

I'd copied int and -1 from the host's mmu->last_vcpu_ran, but the
vcpu_idx it's comparing against here is unsigned int, so I'll switch to
unsigned int and UINT_MAX in v2.

Thanks,
/fuad

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-19 11:43     ` Fuad Tabba
@ 2026-10-19 12:39       ` Vincent Donnefort
  2026-10-19 12:42         ` Vincent Donnefort
  0 siblings, 1 reply; 12+ messages in thread
From: Vincent Donnefort @ 2026-10-19 12:39 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

On Mon, Oct 19, 2026 at 12:43:57PM +0100, Fuad Tabba wrote:
> Hi Vincent,
> 
> On Mon, 19 Oct 2026 11:00:15 +0100, Vincent Donnefort <vdonnefort@google.com> wrote:
> [...]
> > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> [...]
> > > @@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
> > >          unsigned short refcount;
> > >          hyp_spinlock_t lock;
> > >  
> > > +        /* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
> > > +        int *last_vcpu_ran;
> > 
> > Unlikely to be a problem in pratice, but vcpu_idx is "unsigned int". I wonder if
> > this shouldn't be unsigned int here too and initialised to UINT_MAX?
> 
> I'd copied int and -1 from the host's mmu->last_vcpu_ran, but the
> vcpu_idx it's comparing against here is unsigned int, so I'll switch to
> unsigned int and UINT_MAX in v2.
> 
> Thanks,
> /fuad

Also,

as it is always allocated when pkvm_hyp_vm is, Would it make sense to add this
to pkvm_get_hyp_vm_size() instead of allocating separately?

-- 
Vincent

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-19 12:39       ` Vincent Donnefort
@ 2026-10-19 12:42         ` Vincent Donnefort
  2026-10-19 12:45           ` Fuad Tabba
  0 siblings, 1 reply; 12+ messages in thread
From: Vincent Donnefort @ 2026-10-19 12:42 UTC (permalink / raw)
  To: Fuad Tabba
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Quentin Perret, Fuad Tabba, kvmarm,
	linux-arm-kernel, linux-kernel

On Mon, Oct 19, 2026 at 01:39:01PM +0100, Vincent Donnefort wrote:
> On Mon, Oct 19, 2026 at 12:43:57PM +0100, Fuad Tabba wrote:
> > Hi Vincent,
> > 
> > On Mon, 19 Oct 2026 11:00:15 +0100, Vincent Donnefort <vdonnefort@google.com> wrote:
> > [...]
> > > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > [...]
> > > > @@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
> > > >          unsigned short refcount;
> > > >          hyp_spinlock_t lock;
> > > >  
> > > > +        /* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
> > > > +        int *last_vcpu_ran;
> > > 
> > > Unlikely to be a problem in pratice, but vcpu_idx is "unsigned int". I wonder if
> > > this shouldn't be unsigned int here too and initialised to UINT_MAX?
> > 
> > I'd copied int and -1 from the host's mmu->last_vcpu_ran, but the
> > vcpu_idx it's comparing against here is unsigned int, so I'll switch to
> > unsigned int and UINT_MAX in v2.
> > 
> > Thanks,
> > /fuad
> 
> Also,
> 
> as it is always allocated when pkvm_hyp_vm is, Would it make sense to add this
> to pkvm_get_hyp_vm_size() instead of allocating separately?
> 
> -- 
> Vincent

Ha, I just saw your answer to Marc and you will switch to a per-cpu approach
anyway it seems?

-- 
Vincent

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM
  2026-10-19 12:42         ` Vincent Donnefort
@ 2026-10-19 12:45           ` Fuad Tabba
  0 siblings, 0 replies; 12+ messages in thread
From: Fuad Tabba @ 2026-10-19 12:45 UTC (permalink / raw)
  To: Vincent Donnefort
  Cc: Marc Zyngier, Oliver Upton, Joey Gouly, Steffen Eiden,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Mark Rutland, Quentin Perret, kvmarm, linux-arm-kernel,
	linux-kernel

On Mon, 19 Oct 2026 at 13:42, Vincent Donnefort <vdonnefort@google.com> wrote:
>
> On Mon, Oct 19, 2026 at 01:39:01PM +0100, Vincent Donnefort wrote:
> > On Mon, Oct 19, 2026 at 12:43:57PM +0100, Fuad Tabba wrote:
> > > Hi Vincent,
> > >
> > > On Mon, 19 Oct 2026 11:00:15 +0100, Vincent Donnefort <vdonnefort@google.com> wrote:
> > > [...]
> > > > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h
> > > [...]
> > > > > @@ -54,6 +54,9 @@ struct pkvm_hyp_vm {
> > > > >          unsigned short refcount;
> > > > >          hyp_spinlock_t lock;
> > > > >
> > > > > +        /* Per physical CPU, the vcpu_idx of the last vCPU of this VM loaded there. */
> > > > > +        int *last_vcpu_ran;
> > > >
> > > > Unlikely to be a problem in pratice, but vcpu_idx is "unsigned int". I wonder if
> > > > this shouldn't be unsigned int here too and initialised to UINT_MAX?
> > >
> > > I'd copied int and -1 from the host's mmu->last_vcpu_ran, but the
> > > vcpu_idx it's comparing against here is unsigned int, so I'll switch to
> > > unsigned int and UINT_MAX in v2.
> > >
> > > Thanks,
> > > /fuad
> >
> > Also,
> >
> > as it is always allocated when pkvm_hyp_vm is, Would it make sense to add this
> > to pkvm_get_hyp_vm_size() instead of allocating separately?
> >
> > --
> > Vincent
>
> Ha, I just saw your answer to Marc and you will switch to a per-cpu approach
> anyway it seems?

Yes. Now v2 (coming soon) doesn't allocate it at all. As you noticed,
after Marc's comment on patch 1 [1], I'm dropping that patch and made
this a static per-CPU array indexed by the VM's table entry.

Cheers,
/fuad

[1] https://lore.kernel.org/all/86y0buyo5s.wl-maz@kernel.org/

>
> --
> Vincent

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-10-19 12:46 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-14 12:55 [PATCH 0/2] KVM: arm64: Per-vCPU TLB and I-cache flush in pKVM Fuad Tabba
2026-10-14 12:55 ` [PATCH 1/2] KVM: arm64: Track physical CPU number at EL2 Fuad Tabba
2026-10-19 10:34   ` Marc Zyngier
2026-10-19 11:43     ` Fuad Tabba
2026-10-14 12:55 ` [PATCH 2/2] KVM: arm64: Ensure TLBs and I-cache are private to each vCPU in pKVM Fuad Tabba
2026-10-14 15:53   ` Joey Gouly
2026-10-19 11:43     ` Fuad Tabba
2026-10-19 10:00   ` Vincent Donnefort
2026-10-19 11:43     ` Fuad Tabba
2026-10-19 12:39       ` Vincent Donnefort
2026-10-19 12:42         ` Vincent Donnefort
2026-10-19 12:45           ` Fuad Tabba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®