Skip to contentSkip to conversation

KVM: arm64: Simplify handling of GICv3 hardware with broken SEIS

PATCH Applied Will Deacon 3 participants 8 messages Oct 22, 2024 – Oct 25, 2024

Subsystems (2)
lore
Share & tools
lore

Will Deacon

author maintainer
#0 lore raw

cover KVM: arm64: Simplify handling of GICv3 hardware with broken SEIS

Hi folks,

While looking at reducing the host memory mapped into pKVM at EL2, I noticed that the GICv3 CPU interface emulation for hardware with broken SEIS implementations can be simplified and the corresponding mapping of 'kvm_vgic_global_state' can be dropped.

Please have a look!

Cheers,

Will

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
Cc Joey Gouly <[email protected]>
Cc Fuad Tabba <[email protected]>

--->8

Will Deacon (2):
KVM: arm64: Just advertise SEIS as 0 when emulating ICC_CTLR_EL1
KVM: arm64: Don't map 'kvm_vgic_global_state' at EL2 with pKVM

 arch/arm64/kvm/hyp/nvhe/setup.c | 17 -----------------
 arch/arm64/kvm/hyp/vgic-v3-sr.c |  3 ---
 2 files changed, 20 deletions(-)
Signature · 1 line
2.47.0.105.g07ac214952-goog
author maintainer
#1 lore raw

PATCH 1/2 KVM: arm64: Just advertise SEIS as 0 when emulating ICC_CTLR_EL1

ICC_CTLR_EL1 accesses from a guest are trapped and emulated on systems with broken SEIS support and without FEAT_GICv3_TDIR. On such systems, we mask SEIS support in 'kvm_vgic_global_state.ich_vtr_el2' and so the value of ICC_CTLR_EL1.SEIS visible to the guest is always zero.

Simplify the ICC_CTLR_EL1 read emulation to return 0 for the SEIS field, rather than reading an always-zero value from the global state.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
---
 arch/arm64/kvm/hyp/vgic-v3-sr.c | 3 ---
 1 file changed, 3 deletions(-)
arch/arm64/kvm/hyp/vgic-v3-sr.c +0 -3
index 18d4677002b1..3f9741e51d41 100644
@@ -1012,9 +1012,6 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
 	val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT;
 	/* IDbits */
 	val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT;
-	/* SEIS */
-	if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK)
-		val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT);
 	/* A3V */
 	val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
 	/* EOImode */
Signature · 1 line
2.47.0.105.g07ac214952-goog
maintainer Reviewed-by on v1 1/2
#2 lore raw

Re: [PATCH 1/2] KVM: arm64: Just advertise SEIS as 0 when emulating ICC_CTLR_EL1

Quoted 21 lines · Will Deacon

ICC_CTLR_EL1 accesses from a guest are trapped and emulated on systems with broken SEIS support and without FEAT_GICv3_TDIR. On such systems, we mask SEIS support in 'kvm_vgic_global_state.ich_vtr_el2' and so the value of ICC_CTLR_EL1.SEIS visible to the guest is always zero.

Simplify the ICC_CTLR_EL1 read emulation to return 0 for the SEIS field, rather than reading an always-zero value from the global state.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
---
 arch/arm64/kvm/hyp/vgic-v3-sr.c | 3 ---
 1 file changed, 3 deletions(-)
arch/arm64/kvm/hyp/vgic-v3-sr.c +0 -0
index 18d4677002b1..3f9741e51d41 100644

arch/arm64/kvm/hyp/vgic-v3-sr.c static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt) · line 1017

Quoted 9 lines
arch/arm64/kvm/hyp/vgic-v3-sr.c +0 -3
@@ -1012,9 +1012,6 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
 	val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT;
 	/* IDbits */
 	val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT;
-	/* SEIS */
-	if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK)
-		val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT);
 	/* A3V */
 	val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
 	/* EOImode */
	M.
Signature · 1 line
Without deviation from the norm, progress is not possible.
author maintainer
#3 lore raw

PATCH 2/2 KVM: arm64: Don't map 'kvm_vgic_global_state' at EL2 with pKVM

In reply to Will Deacon

Now that 'kvm_vgic_global_state' is no longer needed for ICC_CTLR_EL1 emulation on machines with a broken SEIS implementation, drop the pKVM hypervisor mapping of the page.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
---
 arch/arm64/kvm/hyp/nvhe/setup.c | 17 -----------------
 1 file changed, 17 deletions(-)
arch/arm64/kvm/hyp/nvhe/setup.c +0 -17
index 174007f3fadd..8fec099c2775 100644
@@ -95,7 +95,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 {
 	void *start, *end, *virt = hyp_phys_to_virt(phys);
 	unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
-	enum kvm_pgtable_prot prot;
 	int ret, i;
 
 	/* Recreate the hyp page-table using the early page allocator */
@@ -148,22 +147,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	}
 
 	pkvm_create_host_sve_mappings();
-
-	/*
-	 * Map the host sections RO in the hypervisor, but transfer the
-	 * ownership from the host to the hypervisor itself to make sure they
-	 * can't be donated or shared with another entity.
-	 *
-	 * The ownership transition requires matching changes in the host
-	 * stage-2. This will be done later (see finalize_host_mappings()) once
-	 * the hyp_vmemmap is addressable.
-	 */
-	prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
-	ret = pkvm_create_mappings(&kvm_vgic_global_state,
-				   &kvm_vgic_global_state + 1, prot);
-	if (ret)
-		return ret;
-
 	return 0;
 }
 
Signature · 1 line
2.47.0.105.g07ac214952-goog
maintainer Reviewed-by on v1 2/2
#4 lore raw

Re: [PATCH 2/2] KVM: arm64: Don't map 'kvm_vgic_global_state' at EL2 with pKVM

Quoted 36 lines · Will Deacon

Now that 'kvm_vgic_global_state' is no longer needed for ICC_CTLR_EL1 emulation on machines with a broken SEIS implementation, drop the pKVM hypervisor mapping of the page.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
---
 arch/arm64/kvm/hyp/nvhe/setup.c | 17 -----------------
 1 file changed, 17 deletions(-)
arch/arm64/kvm/hyp/nvhe/setup.c +0 -9
index 174007f3fadd..8fec099c2775 100644
@@ -95,7 +95,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 {
 	void *start, *end, *virt = hyp_phys_to_virt(phys);
 	unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
-	enum kvm_pgtable_prot prot;
 	int ret, i;
 
 	/* Recreate the hyp page-table using the early page allocator */
@@ -148,22 +147,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	}
 
 	pkvm_create_host_sve_mappings();
-
-	/*
-	 * Map the host sections RO in the hypervisor, but transfer the
-	 * ownership from the host to the hypervisor itself to make sure they
-	 * can't be donated or shared with another entity.
-	 *
-	 * The ownership transition requires matching changes in the host
-	 * stage-2. This will be done later (see finalize_host_mappings()) once

arch/arm64/kvm/hyp/nvhe/setup.c static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · line 151

Quoted 10 lines
arch/arm64/kvm/hyp/nvhe/setup.c +0 -8
-	 * the hyp_vmemmap is addressable.
-	 */
-	prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
-	ret = pkvm_create_mappings(&kvm_vgic_global_state,
-				   &kvm_vgic_global_state + 1, prot);
-	if (ret)
-		return ret;
-
 	return 0;
 }

Maybe add a note indicating that nVHE/hVHE still have that particular mapping via the rodata section?

	M.
Signature · 1 line
Without deviation from the norm, progress is not possible.
author maintainer
#5 lore raw

Re: [PATCH 2/2] KVM: arm64: Don't map 'kvm_vgic_global_state' at EL2 with pKVM

Quoted 43 lines · Marc Zyngier
Quoted 41 lines · Will Deacon

Now that 'kvm_vgic_global_state' is no longer needed for ICC_CTLR_EL1 emulation on machines with a broken SEIS implementation, drop the pKVM hypervisor mapping of the page.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
---
 arch/arm64/kvm/hyp/nvhe/setup.c | 17 -----------------
 1 file changed, 17 deletions(-)
arch/arm64/kvm/hyp/nvhe/setup.c +0 -14
index 174007f3fadd..8fec099c2775 100644
@@ -95,7 +95,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 {
 	void *start, *end, *virt = hyp_phys_to_virt(phys);
 	unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
-	enum kvm_pgtable_prot prot;
 	int ret, i;
 
 	/* Recreate the hyp page-table using the early page allocator */
@@ -148,22 +147,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	}
 
 	pkvm_create_host_sve_mappings();
-
-	/*
-	 * Map the host sections RO in the hypervisor, but transfer the
-	 * ownership from the host to the hypervisor itself to make sure they
-	 * can't be donated or shared with another entity.
-	 *
-	 * The ownership transition requires matching changes in the host
-	 * stage-2. This will be done later (see finalize_host_mappings()) once
-	 * the hyp_vmemmap is addressable.
-	 */
-	prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
-	ret = pkvm_create_mappings(&kvm_vgic_global_state,
-				   &kvm_vgic_global_state + 1, prot);
Quoted 8 lines

arch/arm64/kvm/hyp/nvhe/setup.c static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · line 151

Quoted 5 lines
arch/arm64/kvm/hyp/nvhe/setup.c +0 -3
-	if (ret)
-		return ret;
-
 	return 0;
 }

Maybe add a note indicating that nVHE/hVHE still have that particular mapping via the rodata section?

I can add something to the commit message, is that what you had in mind?

Quoted 1 line

Thanks!

Will

maintainer
#6 lore raw

Re: [PATCH 2/2] KVM: arm64: Don't map 'kvm_vgic_global_state' at EL2 with pKVM

Quoted 54 lines · Will Deacon
Quoted 43 lines · Marc Zyngier
Quoted 41 lines · Will Deacon

Now that 'kvm_vgic_global_state' is no longer needed for ICC_CTLR_EL1 emulation on machines with a broken SEIS implementation, drop the pKVM hypervisor mapping of the page.

Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
---
 arch/arm64/kvm/hyp/nvhe/setup.c | 17 -----------------
 1 file changed, 17 deletions(-)
arch/arm64/kvm/hyp/nvhe/setup.c +0 -14
index 174007f3fadd..8fec099c2775 100644
@@ -95,7 +95,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 {
 	void *start, *end, *virt = hyp_phys_to_virt(phys);
 	unsigned long pgt_size = hyp_s1_pgtable_pages() << PAGE_SHIFT;
-	enum kvm_pgtable_prot prot;
 	int ret, i;
 
 	/* Recreate the hyp page-table using the early page allocator */
@@ -148,22 +147,6 @@ static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size,
 	}
 
 	pkvm_create_host_sve_mappings();
-
-	/*
-	 * Map the host sections RO in the hypervisor, but transfer the
-	 * ownership from the host to the hypervisor itself to make sure they
-	 * can't be donated or shared with another entity.
-	 *
-	 * The ownership transition requires matching changes in the host
-	 * stage-2. This will be done later (see finalize_host_mappings()) once
-	 * the hyp_vmemmap is addressable.
-	 */
-	prot = pkvm_mkstate(PAGE_HYP_RO, PKVM_PAGE_SHARED_OWNED);
-	ret = pkvm_create_mappings(&kvm_vgic_global_state,
-				   &kvm_vgic_global_state + 1, prot);
Quoted 8 lines

arch/arm64/kvm/hyp/nvhe/setup.c static int recreate_hyp_mappings(phys_addr_t phys, unsigned long size, · line 151

Quoted 5 lines
arch/arm64/kvm/hyp/nvhe/setup.c +0 -3
-	if (ret)
-		return ret;
-
 	return 0;
 }

Maybe add a note indicating that nVHE/hVHE still have that particular mapping via the rodata section?

Quoted 1 line

I can add something to the commit message, is that what you had in mind?

Yes. But maybe Oliver can add that when applying the series?

Thanks,

	M.
Signature · 1 line
Without deviation from the norm, progress is not possible.
Applied
#7 lore raw
In reply to Will Deacon
Quoted 8 lines · Will Deacon

While looking at reducing the host memory mapped into pKVM at EL2, I noticed that the GICv3 CPU interface emulation for hardware with broken SEIS implementations can be simplified and the corresponding mapping of 'kvm_vgic_global_state' can be dropped.

Please have a look!

[...]

Included Marc's recommended changelog addition.

Applied to kvmarm/next, thanks!

[1/2] KVM: arm64: Just advertise SEIS as 0 when emulating ICC_CTLR_EL1

      https://git.kernel.org/kvmarm/kvmarm/c/ad361ed4771d
[2/2] KVM: arm64: Don't map 'kvm_vgic_global_state' at EL2 with pKVM
      https://git.kernel.org/kvmarm/kvmarm/c/8aaf3f7dce74

--
Best,
Oliver