mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Steven Price <steven.price@arm.com>
To: Kohei Enju <enju.kohei@fujitsu.com>
Cc: kvm@vger.kernel.org, kvmarm@lists.linux.dev,
	Catalin Marinas <catalin.marinas@arm.com>,
	Marc Zyngier <maz@kernel.org>, Will Deacon <will@kernel.org>,
	James Morse <james.morse@arm.com>,
	Oliver Upton <oliver.upton@linux.dev>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, Joey Gouly <joey.gouly@arm.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Christoffer Dall <christoffer.dall@arm.com>,
	Fuad Tabba <tabba@google.com>,
	linux-coco@lists.linux.dev,
	Ganapatrao Kulkarni <gankulkarni@os.amperecomputing.com>,
	Gavin Shan <gshan@redhat.com>,
	Shanker Donthineni <sdonthineni@nvidia.com>,
	Alper Gun <alpergun@google.com>,
	"Aneesh Kumar K . V" <aneesh.kumar@kernel.org>,
	Emi Kisanuki <fj0570is@fujitsu.com>,
	Vishal Annapurve <vannapurve@google.com>,
	WeiLin.Chang@arm.com, Lorenzo Pieralisi <lpieralisi@kernel.org>
Subject: Re: [PATCH v15 12/37] KVM: arm64: CCA: Support the VGIC in realms
Date: Thu, 23 Jul 2026 15:46:58 +0100	[thread overview]
Message-ID: <1cd3327c-1eab-4022-9ab1-625ca8641e81@arm.com> (raw)
In-Reply-To: <amG3KHE4Tdd_Nvuz@FCCLS0092175.localdomain>

On 23/07/2026 07:56, Kohei Enju wrote:
> On 07/22 14:31, Steven Price wrote:
>> On 22/07/2026 09:27, Kohei Enju wrote:
>>> On 07/15 15:28, Steven Price wrote:
>>>> The RMM provides emulation of a VGIC to the realm guest. With RMM v2.0
>>>> the registers are passed in the system registers so this works similar
>>>> to a normal guest, but kvm_arch_vcpu_put() need reordering to early out,
>>>> and realm guests don't support GICv2 even if the host does.
>>>>
>>>> Signed-off-by: Steven Price <steven.price@arm.com>
>>>
>>> Hi Steven,
>>
>> Hi Kohei,
>>
>>> I've been testing this series and found that when the host CPU doesn't have
>>> ARM64_HAS_ICH_HCR_EL2_TDIR this series doesn't work as expected.
>>
>> Thanks for testing!
>>
>>> Since commit 2a28810cbb8b ("KVM: arm64: GICv3: Detect and work around the lack
>>> of ICV_DIR_EL1 trapping"), when the host CPU doesn't support this feature, KVM
>>> traps all GIC sysreg accesses in the common group. However, currently trap
>>> handlers for ICC_{PMR,RPR,CTLR}_EL1 registers are missing [0]. So when Realm
>>> guests try to access those registers, KVM traps them but just emits the warning
>>> shown in [1], and Realm guests fail to boot.
>>>
>>> As far as I can tell, the CCA requirements don't require the
>>> ARM64_HAS_ICH_HCR_EL2_TDIR feature. If that's the case, this seems to be a
>>> problem. Is there any workaround for this issue, or should we implement trap
>>> handlers for those registers?
>>
>> As Marc has already said in his reply, I'm really surprised you have a
>> CPU which implements CCA but doesn't have ARM64_HAS_ICH_HCR_EL2_TDIR.
>> Can you give some more details about the platform you are testing on?
> 
> Thank you for taking a look, Steve.
> 
> Unfortunately, due to the company's policy, I can't share any details
> about the platform I'm currently testing on. When the time is right,
> I'll be happy to do so.
> 
>>
>> Ultimately there are two options here - either don't support CCA (so
>> detect the lack of ARM64_HAS_ICH_HCR_EL2_TDIR and bail out early), or
>> plumb in the trap handlers - as commit 2a28810cbb8b points out this
>> isn't something we really want to support if we can avoid it.
> 
> Yes, the former makes perfect sense if there would be no systems that
> supports CCA without TDIR. However, if such systems do exist, I'd be
> interested in exploring the latter approach.
> 
>>
>> Hence I'm interested to know where this sits between "hacked up test
>> system" and "production hardware". E.g. if this is an emulator it might
>> be possible to just enable the CPU feature.
> 
> Again, I can't share that right now, but I'd like to share more when the
> time comes.

Given Marc's response for now I'm not going to add support for this. 
"When the time comes" we can revisit whether it makes sense to have 
upstream support and what that might look like.

However, I did ask an AI tool to have a go at implementing this, and it 
came up with the (very lightly tested) patch below. That might at least 
give you something you can test. It doesn't meet Marc's request that it
reuses the existing implementation, and it took the AI a few goes at
getting something that "works" so I suspect it might have bugs - I
haven't reviewed the code myself.

Thanks,
Steve

----8<----
From 7aaaa5089c05f19bf00df2b651fa4bd7d738384c Mon Sep 17 00:00:00 2001
From: Steven Price <steven.price@arm.com>
Date: Thu, 23 Jul 2026 11:49:36 +0100
Subject: [PATCH] KVM: arm64: CCA: Handle GICv3 CPU interface traps for realms

On CPUs that lack ICH_HCR_EL2.TDIR, KVM works around the missing DIR
trap by setting ICH_HCR_EL2.TC and trapping the GICv3 common CPU
interface registers. Normal guests handle these traps in hyp via the
VGIC CPU interface emulation, but realm guests exit through the RMM and
reach KVM's host-side sysreg emulation instead.

That path only handles ICC_DIR_EL1 and treats the rest of the trapped
common group as undefined. A realm guest can therefore take an
unexpected UNDEF when accessing registers such as ICC_PMR_EL1 or
ICC_CTLR_EL1 on systems that require the TC workaround.

Handle the GICv3 common CPU interface registers directly from the realm
sysreg exit path. Reads are satisfied from the saved VGIC state and
writes update the VGIC shadow state. For PMR and CTLR writes, also
restore the VMCR/APR state to the live GIC CPU interface before
re-entering the REC, matching the effect a direct guest sysreg write
would have had.

Signed-off-by: Steven Price <steven.price@arm.com>
---
 arch/arm64/kvm/rmi-exit.c | 119 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/arch/arm64/kvm/rmi-exit.c b/arch/arm64/kvm/rmi-exit.c
index 78d9189fd5ca..0fad8e68d920 100644
--- a/arch/arm64/kvm/rmi-exit.c
+++ b/arch/arm64/kvm/rmi-exit.c
@@ -3,17 +3,25 @@
  * Copyright (C) 2023-2026 ARM Ltd.
  */
 
+#include <linux/bitfield.h>
+#include <linux/irqchip/arm-gic-v3.h>
 #include <linux/kvm_host.h>
 #include <kvm/arm_hypercalls.h>
 #include <kvm/arm_psci.h>
 
 #include <linux/arm-smccc-rmi.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_hyp.h>
 #include <asm/kvm_rmi.h>
 #include <asm/kvm_mmu.h>
+#include <asm/sysreg.h>
+
+#include "vgic/vgic.h"
 
 typedef int (*exit_handler_fn)(struct kvm_vcpu *vcpu);
 
+#define GICV3_IDLE_PRIORITY	0xff
+
 static int rec_exit_reason_notimpl(struct kvm_vcpu *vcpu)
 {
 	vcpu_err(vcpu, "Unhandled exit reason from realm (ESR: %#llx)\n",
@@ -48,6 +56,114 @@ static int rec_exit_sync_iabt(struct kvm_vcpu *vcpu)
 	return -ENXIO;
 }
 
+static int rec_get_gicv3_bpr_min(void)
+{
+	return 8 - (FIELD_GET(ICH_VTR_EL2_PREbits,
+			      kvm_vgic_global_state.ich_vtr_el2) + 1);
+}
+
+static u8 rec_get_gicv3_active_priority(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpuif = &vcpu->arch.vgic_cpu.vgic_v3;
+	u8 prio = 0;
+
+	for (int i = 0; i <= vgic_v3_max_apr_idx(vcpu); i++) {
+		u32 val = cpuif->vgic_ap0r[i] | cpuif->vgic_ap1r[i];
+
+		if (!val) {
+			prio += 32;
+			continue;
+		}
+
+		return (prio + __ffs(val)) << rec_get_gicv3_bpr_min();
+	}
+
+	return GICV3_IDLE_PRIORITY;
+}
+
+static void rec_restore_gicv3_vmcr_aprs(struct kvm_vcpu *vcpu)
+{
+	preempt_disable();
+	kvm_call_hyp(__vgic_v3_restore_vmcr_aprs,
+		     &vcpu->arch.vgic_cpu.vgic_v3);
+	preempt_enable();
+}
+
+/*
+ * Realm exits are handled after the RMM has returned to the host, so use the
+ * saved VGIC shadow state instead of the hyp-side live sysreg helpers.
+ */
+static bool rec_exit_gicv3_sys_reg(struct kvm_vcpu *vcpu, bool is_write)
+{
+	struct realm_rec *rec = &vcpu->arch.rec;
+	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+	struct vgic_vmcr vmcr;
+	unsigned long esr = kvm_vcpu_get_esr(vcpu);
+	int rt = kvm_vcpu_sys_get_rt(vcpu);
+	u32 sysreg = esr_sys64_to_sysreg(esr);
+	u64 val;
+
+	if (!kvm_has_gicv3(vcpu->kvm))
+		return false;
+
+	vgic_get_vmcr(vcpu, &vmcr);
+
+	switch (sysreg) {
+	case SYS_ICC_DIR_EL1:
+		if (!is_write)
+			return false;
+
+		vgic_v3_deactivate(vcpu, rec->run->exit.gprs[rt]);
+		return true;
+	case SYS_ICC_PMR_EL1:
+		if (is_write) {
+			vmcr.pmr = FIELD_GET(ICC_PMR_EL1_MASK,
+					     rec->run->exit.gprs[rt]);
+			vgic_set_vmcr(vcpu, &vmcr);
+			rec_restore_gicv3_vmcr_aprs(vcpu);
+		} else {
+			rec->run->enter.gprs[rt] = FIELD_PREP(ICC_PMR_EL1_MASK,
+							      vmcr.pmr);
+		}
+
+		return true;
+	case SYS_ICC_CTLR_EL1:
+		if (is_write) {
+			val = rec->run->exit.gprs[rt];
+			vmcr.cbpr = FIELD_GET(ICC_CTLR_EL1_CBPR_MASK, val);
+			vmcr.eoim = FIELD_GET(ICC_CTLR_EL1_EOImode_MASK, val);
+			vgic_set_vmcr(vcpu, &vmcr);
+			rec_restore_gicv3_vmcr_aprs(vcpu);
+		} else {
+			val  = FIELD_PREP(ICC_CTLR_EL1_PRI_BITS_MASK,
+					  vgic_cpu->num_pri_bits - 1);
+			val |= FIELD_PREP(ICC_CTLR_EL1_ID_BITS_MASK,
+					  vgic_cpu->num_id_bits);
+			val |= FIELD_PREP(ICC_CTLR_EL1_SEIS_MASK,
+					  FIELD_GET(ICH_VTR_EL2_SEIS,
+						    kvm_vgic_global_state.ich_vtr_el2));
+			val |= FIELD_PREP(ICC_CTLR_EL1_A3V_MASK,
+					  FIELD_GET(ICH_VTR_EL2_A3V,
+						    kvm_vgic_global_state.ich_vtr_el2));
+			val |= FIELD_PREP(ICC_CTLR_EL1_CBPR_MASK,
+					  vmcr.cbpr);
+			val |= FIELD_PREP(ICC_CTLR_EL1_EOImode_MASK,
+					  vmcr.eoim);
+			rec->run->enter.gprs[rt] = val;
+		}
+
+		return true;
+	case SYS_ICC_RPR_EL1:
+		if (is_write)
+			return false;
+
+		rec->run->enter.gprs[rt] = rec_get_gicv3_active_priority(vcpu);
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int rec_exit_sys_reg(struct kvm_vcpu *vcpu)
 {
 	struct realm_rec *rec = &vcpu->arch.rec;
@@ -59,6 +175,9 @@ static int rec_exit_sys_reg(struct kvm_vcpu *vcpu)
 	if (is_write)
 		vcpu_set_reg(vcpu, rt, rec->run->exit.gprs[rt]);
 
+	if (rec_exit_gicv3_sys_reg(vcpu, is_write))
+		return 1;
+
 	ret = kvm_handle_sys_reg(vcpu);
 	if (!is_write)
 		rec->run->enter.gprs[rt] = vcpu_get_reg(vcpu, rt);
-- 
2.43.0



  reply	other threads:[~2026-07-23 14:47 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-15 14:28 [PATCH v15 00/37] arm64: Support for Arm CCA in KVM Steven Price
2026-07-15 14:28 ` [PATCH v15 01/37] KVM: arm64: Include kvm_emulate.h in kvm/arm_psci.h Steven Price
2026-07-15 14:28 ` [PATCH v15 02/37] KVM: arm64: Avoid including linux/kvm_host.h in kvm_pgtable.h Steven Price
2026-07-15 15:59   ` Marc Zyngier
2026-07-15 16:22     ` Steven Price
2026-07-15 14:28 ` [PATCH v15 03/37] arm64: mm: Handle Granule Protection Faults (GPFs) Steven Price
2026-07-15 14:28 ` [PATCH v15 04/37] KVM: arm64: CCA: Check for RMI support at KVM init Steven Price
2026-07-15 14:28 ` [PATCH v15 05/37] KVM: arm64: CCA: Check for LPA2 support Steven Price
2026-07-16  9:23   ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 06/37] KVM: arm64: CCA: Define the user ABI Steven Price
2026-07-16  9:40   ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 07/37] KVM: arm64: CCA: Add basic infrastructure for creating a realm Steven Price
2026-07-15 14:28 ` [PATCH v15 08/37] KVM: arm64: CCA: Don't expose unsupported capabilities for realm guests Steven Price
2026-07-15 14:28 ` [PATCH v15 09/37] KVM: arm64: CCA: Allow passing the machine type in KVM creation Steven Price
2026-07-15 16:14   ` Marc Zyngier
2026-07-16  9:17     ` Steven Price
2026-07-16  9:37       ` Marc Zyngier
2026-07-15 14:28 ` [PATCH v15 10/37] KVM: arm64: CCA: Tear down RTTs Steven Price
2026-07-15 14:28 ` [PATCH v15 11/37] KVM: arm64: CCA: Allocate and free RECs to match vCPUs Steven Price
2026-07-15 14:28 ` [PATCH v15 12/37] KVM: arm64: CCA: Support the VGIC in realms Steven Price
2026-07-22  8:27   ` Kohei Enju
2026-07-22  9:27     ` Marc Zyngier
2026-07-23  6:38       ` Kohei Enju
2026-07-23  8:07         ` Marc Zyngier
2026-07-23  9:02           ` Kohei Enju
2026-07-22 13:31     ` Steven Price
2026-07-23  6:56       ` Kohei Enju
2026-07-23 14:46         ` Steven Price [this message]
2026-07-24  5:40           ` Kohei Enju
2026-07-15 14:28 ` [PATCH v15 13/37] KVM: arm64: CCA: Support timers in realm RECs Steven Price
2026-07-27  9:21   ` Marc Zyngier
2026-07-29 10:47     ` Steven Price
2026-07-29 10:58       ` Marc Zyngier
2026-07-30  8:47         ` Steven Price
2026-07-15 14:28 ` [PATCH v15 14/37] KVM: arm64: CCA: Handle realm enter/exit Steven Price
2026-07-27  8:14   ` Kohei Enju
2026-07-30 13:58     ` Steven Price
2026-07-30 14:57       ` Suzuki K Poulose
2026-07-31  0:57         ` Kohei Enju
2026-07-27 15:01   ` Marc Zyngier
2026-07-30 16:17     ` Steven Price
2026-07-15 14:28 ` [PATCH v15 15/37] KVM: arm64: CCA: Handle RMI_EXIT_RIPAS_CHANGE Steven Price
2026-08-03 11:09   ` Marc Zyngier
2026-08-03 14:04     ` Steven Price
2026-08-03 14:48       ` Marc Zyngier
2026-08-03 15:30         ` Suzuki K Poulose
2026-08-04 12:20           ` Fuad Tabba
2026-08-04 13:19             ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 16/37] KVM: arm64: CCA: Handle realm MMIO emulation Steven Price
2026-08-03 11:27   ` Marc Zyngier
2026-08-03 14:57     ` Steven Price
2026-07-15 14:28 ` [PATCH v15 17/37] KVM: arm64: Expose support for private memory Steven Price
2026-07-16 10:25   ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 18/37] KVM: arm64: CCA: Create the realm descriptor Steven Price
2026-07-15 14:28 ` [PATCH v15 19/37] KVM: arm64: CCA: Activate realms on first vCPU run Steven Price
2026-08-03 12:29   ` Marc Zyngier
2026-08-03 15:18     ` Steven Price
2026-07-15 14:28 ` [PATCH v15 20/37] KVM: arm64: CCA: Allow populating initial contents Steven Price
2026-08-03 12:43   ` Marc Zyngier
2026-08-03 15:30     ` Steven Price
2026-07-15 14:28 ` [PATCH v15 21/37] KVM: arm64: CCA: Set RIPAS of initial memslots Steven Price
2026-07-15 14:28 ` [PATCH v15 22/37] KVM: arm64: CCA: Support runtime faulting of memory Steven Price
2026-07-15 14:28 ` [PATCH v15 23/37] KVM: arm64: CCA: Handle realm vCPU load Steven Price
2026-07-15 14:28 ` [PATCH v15 24/37] KVM: arm64: CCA: Validate register access for Realm VMs Steven Price
2026-07-15 14:28 ` [PATCH v15 25/37] KVM: arm64: CCA: Handle Realm PSCI requests Steven Price
2026-07-16 10:38   ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 26/37] KVM: arm64: WARN on injected undef exceptions Steven Price
2026-07-15 15:46   ` Marc Zyngier
2026-07-15 16:15     ` Steven Price
2026-07-15 16:25       ` Marc Zyngier
2026-07-15 16:31         ` Steven Price
2026-07-15 16:43           ` Marc Zyngier
2026-07-16  9:17             ` Steven Price
2026-07-15 14:28 ` [PATCH v15 27/37] KVM: arm64: CCA: Allow userspace to inject aborts Steven Price
2026-07-16 10:19   ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 28/37] KVM: arm64: CCA: Support RSI_HOST_CALL Steven Price
2026-07-16 10:22   ` Suzuki K Poulose
2026-07-15 14:28 ` [PATCH v15 29/37] KVM: arm64: CCA: Allow checking SVE on VM instance Steven Price
2026-07-15 14:28 ` [PATCH v15 30/37] KVM: arm64: CCA: Prevent Device mappings for realms Steven Price
2026-07-15 14:28 ` [PATCH v15 31/37] KVM: arm64: CCA: Propagate breakpoint and watchpoint counts to userspace Steven Price
2026-07-15 14:28 ` [PATCH v15 32/37] KVM: arm64: CCA: Set breakpoint parameters through SET_ONE_REG Steven Price
2026-07-15 14:28 ` [PATCH v15 33/37] KVM: arm64: CCA: Propagate max SVE vector length from the RMM Steven Price
2026-07-15 14:28 ` [PATCH v15 34/37] KVM: arm64: CCA: Configure max SVE vector length for a Realm Steven Price
2026-07-15 14:28 ` [PATCH v15 35/37] KVM: arm64: CCA: Provide register list for unfinalized RECs Steven Price
2026-07-15 14:28 ` [PATCH v15 36/37] KVM: arm64: CCA: Provide an accurate register list Steven Price
2026-07-15 14:28 ` [PATCH v15 37/37] KVM: arm64: CCA: Enable realms to be created Steven Price
2026-07-16  8:36 ` [PATCH v15 00/37] arm64: Support for Arm CCA in KVM Marc Zyngier
2026-07-16  9:20   ` Steven Price
2026-07-16  9:42     ` Marc Zyngier

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=1cd3327c-1eab-4022-9ab1-625ca8641e81@arm.com \
    --to=steven.price@arm.com \
    --cc=WeiLin.Chang@arm.com \
    --cc=alexandru.elisei@arm.com \
    --cc=alpergun@google.com \
    --cc=aneesh.kumar@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=christoffer.dall@arm.com \
    --cc=enju.kohei@fujitsu.com \
    --cc=fj0570is@fujitsu.com \
    --cc=gankulkarni@os.amperecomputing.com \
    --cc=gshan@redhat.com \
    --cc=james.morse@arm.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lpieralisi@kernel.org \
    --cc=maz@kernel.org \
    --cc=oliver.upton@linux.dev \
    --cc=sdonthineni@nvidia.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.com \
    --cc=vannapurve@google.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

all inboxes | Powered by JetHome®