From: Vincent Donnefort <vdonnefort@google.com>
To: maz@kernel.org, oupton@kernel.org, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org
Cc: joey.gouly@arm.com, seiden@linux.ibm.com, suzuki.poulose@arm.com,
yuzenghui@huawei.com, catalin.marinas@arm.com, will@kernel.org,
kernel-team@android.com, fuad.tabba@linux.dev,
Vincent Donnefort <vdonnefort@google.com>
Subject: [PATCH v2 2/4] KVM: arm64: pkvm: Fix missing reset of GICv3 LRs
Date: Thu, 22 Oct 2026 15:00:46 +0100 [thread overview]
Message-ID: <20261022140048.2522787-3-vdonnefort@google.com> (raw)
In-Reply-To: <20261022140048.2522787-1-vdonnefort@google.com>
The vGIC LRs are architecturally UNKNOWN when the CPU boots or resumes.
However, in protected mode, only the used ones are reset, because the
HVC __vgic_v3_init_lrs() is never called:
* During boot, vgic_present is only set in init_subsystems(), after
cpu_hyp_init() was called.
* During CPU hotplug, kvm_arch_enable_virtualization_cpu() never calls
it either because kvm_hyp_initialized is always set.
* During CPU resume, no notifier is registered for pKVM.
First, return the error of __hyp_reset_vectors(). On an error, we know
the hypervisor doesn't allow a reset. Only re-init what the host has
access to, no matter the KVM configuration, which is the vGIC LRs.
Then, cpu_hyp_init() is only called from init_subsystems and
kvm_arch_enable_virtualization_cpu(). Remove the kvm_hyp_initialized
gate: when pKVM is enabled, the cpu_hyp_reset() will just return an
error while for other modes, we already know kvm_hyp_initialized is
false at this point.
Finally, enable the PM notifiers for pKVM, it is now safe to do so. It
will ensure the host properly configures the vGIC LRs regardless of the
KVM configuration.
Fixes: fa8c3d65538a ("KVM: arm64: Keep nVHE EL2 vector installed")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/include/asm/virt.h | 2 +-
arch/arm64/kvm/arm.c | 51 +++++++++++++++++++----------------
2 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index b546703c3ab9..a5bde8cc5df5 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -83,7 +83,7 @@ extern u32 __boot_cpu_mode[2];
#define ARM64_VECTOR_TABLE_LEN SZ_2K
void __hyp_set_vectors(phys_addr_t phys_vector_base);
-void __hyp_reset_vectors(void);
+int __hyp_reset_vectors(void);
bool is_kvm_arm_initialised(void);
DECLARE_STATIC_KEY_FALSE(kvm_protected_mode_initialized);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 0576c2022ef5..4c4e2fb7b660 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -2246,10 +2246,12 @@ static void cpu_init_hyp_mode(void)
}
}
-static void cpu_hyp_reset(void)
+static int cpu_hyp_reset(void)
{
if (!is_kernel_in_hyp_mode())
- __hyp_reset_vectors();
+ return __hyp_reset_vectors() ? -EPERM : 0;
+
+ return 0;
}
/*
@@ -2300,32 +2302,39 @@ static void cpu_hyp_init_features(void)
kvm_timer_init_vhe();
kvm_debug_init_vhe();
}
-
- if (vgic_present)
- kvm_vgic_init_cpu_hardware();
}
static void cpu_hyp_reinit(void)
{
- cpu_hyp_reset();
- cpu_hyp_init_context();
- cpu_hyp_init_features();
+ if (!cpu_hyp_reset()) {
+ cpu_hyp_init_context();
+ cpu_hyp_init_features();
+ } else {
+ if (WARN_ON(!__this_cpu_read(kvm_hyp_initialized)))
+ return;
+ }
+
+ /*
+ * Even if the hypervisor didn't allow resetting the vectors we can
+ * reset what we have access to.
+ */
+ if (vgic_present)
+ kvm_vgic_init_cpu_hardware();
}
static void cpu_hyp_init(void *discard)
{
- if (!__this_cpu_read(kvm_hyp_initialized)) {
- cpu_hyp_reinit();
- __this_cpu_write(kvm_hyp_initialized, 1);
- }
+ cpu_hyp_reinit();
+ __this_cpu_write(kvm_hyp_initialized, 1);
}
static void cpu_hyp_uninit(void *discard)
{
- if (!is_protected_kvm_enabled() && __this_cpu_read(kvm_hyp_initialized)) {
- cpu_hyp_reset();
+ if (!__this_cpu_read(kvm_hyp_initialized))
+ return;
+
+ if (!cpu_hyp_reset())
__this_cpu_write(kvm_hyp_initialized, 0);
- }
}
int kvm_arch_enable_virtualization_cpu(void)
@@ -2353,8 +2362,7 @@ void kvm_arch_disable_virtualization_cpu(void)
kvm_timer_cpu_down();
kvm_vgic_cpu_down();
- if (!is_protected_kvm_enabled())
- cpu_hyp_uninit(NULL);
+ cpu_hyp_uninit(NULL);
}
#ifdef CONFIG_CPU_PM
@@ -2397,13 +2405,11 @@ static struct notifier_block hyp_init_cpu_pm_nb = {
static void __init hyp_cpu_pm_init(void)
{
- if (!is_protected_kvm_enabled())
- cpu_pm_register_notifier(&hyp_init_cpu_pm_nb);
+ cpu_pm_register_notifier(&hyp_init_cpu_pm_nb);
}
static void __init hyp_cpu_pm_exit(void)
{
- if (!is_protected_kvm_enabled())
- cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb);
+ cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb);
}
#else
static inline void __init hyp_cpu_pm_init(void)
@@ -2526,8 +2532,7 @@ static int __init init_subsystems(void)
if (err)
hyp_cpu_pm_exit();
- if (err || !is_protected_kvm_enabled())
- on_each_cpu(cpu_hyp_uninit, NULL, 1);
+ on_each_cpu(cpu_hyp_uninit, NULL, 1);
return err;
}
--
2.56.0.257.gf7497c7d27-goog
next prev parent reply other threads:[~2026-10-22 14:02 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-22 14:00 [PATCH v2 0/4] KVM: arm64: pkvm: Fix missing reset of GICv3 LRs Vincent Donnefort
2026-10-22 14:00 ` [PATCH v2 1/4] KVM: arm64: Make __vgic_v3_init_lrs HVC always available Vincent Donnefort
2026-10-22 17:34 ` Fuad Tabba
2026-10-22 14:00 ` Vincent Donnefort [this message]
2026-10-22 17:36 ` [PATCH v2 2/4] KVM: arm64: pkvm: Fix missing reset of GICv3 LRs Fuad Tabba
2026-10-23 7:59 ` Vincent Donnefort
2026-10-23 8:14 ` Fuad Tabba
2026-10-22 14:00 ` [PATCH v2 3/4] KVM: arm64: pkvm: Reset GICv3 LRs in the hypervisor Vincent Donnefort
2026-10-22 17:37 ` Fuad Tabba
2026-10-22 14:00 ` [PATCH v2 4/4] KVM: arm64: pkvm: Avoid trapping on HVC_RESET_VECTORS Vincent Donnefort
2026-10-22 17:38 ` Fuad Tabba
2026-10-23 8:01 ` Vincent Donnefort
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261022140048.2522787-3-vdonnefort@google.com \
--to=vdonnefort@google.com \
--cc=catalin.marinas@arm.com \
--cc=fuad.tabba@linux.dev \
--cc=joey.gouly@arm.com \
--cc=kernel-team@android.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=seiden@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox