Skip to content

Commit 948e1a5

Browse files
author
Marc Zyngier
committed
KVM: arm64: Simplify vgic-v3 hypercalls
Consolidate the GICv3 VMCR accessor hypercalls into the APR save/restore hypercalls so that all of the EL2 GICv3 state is covered by a single pair of hypercalls. Signed-off-by: Fuad Tabba <tabba@google.com> Acked-by: Oliver Upton <oliver.upton@linux.dev> Link: https://lore.kernel.org/r/20240423150538.2103045-17-tabba@google.com Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 9c30fc6 commit 948e1a5

10 files changed

Lines changed: 38 additions & 76 deletions

File tree

arch/arm64/include/asm/kvm_asm.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,8 @@ enum __kvm_host_smccc_func {
7373
__KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_range,
7474
__KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context,
7575
__KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
76-
__KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr,
77-
__KVM_HOST_SMCCC_FUNC___vgic_v3_write_vmcr,
78-
__KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs,
79-
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs,
76+
__KVM_HOST_SMCCC_FUNC___vgic_v3_save_vmcr_aprs,
77+
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
8078
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_init_traps,
8179
__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
8280
__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
@@ -241,8 +239,6 @@ extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
241239
extern void __kvm_adjust_pc(struct kvm_vcpu *vcpu);
242240

243241
extern u64 __vgic_v3_get_gic_config(void);
244-
extern u64 __vgic_v3_read_vmcr(void);
245-
extern void __vgic_v3_write_vmcr(u32 vmcr);
246242
extern void __vgic_v3_init_lrs(void);
247243

248244
extern u64 __kvm_get_mdcr_el2(void);

arch/arm64/include/asm/kvm_hyp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if);
8080
void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if);
8181
void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if);
8282
void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if);
83-
void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if);
84-
void __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if);
83+
void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if);
84+
void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if);
8585
int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu);
8686

8787
#ifdef __KVM_NVHE_HYPERVISOR__

arch/arm64/kvm/arm.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -784,17 +784,16 @@ void kvm_vcpu_wfi(struct kvm_vcpu *vcpu)
784784
* doorbells to be signalled, should an interrupt become pending.
785785
*/
786786
preempt_disable();
787-
kvm_vgic_vmcr_sync(vcpu);
788787
vcpu_set_flag(vcpu, IN_WFI);
789-
vgic_v4_put(vcpu);
788+
kvm_vgic_put(vcpu);
790789
preempt_enable();
791790

792791
kvm_vcpu_halt(vcpu);
793792
vcpu_clear_flag(vcpu, IN_WFIT);
794793

795794
preempt_disable();
796795
vcpu_clear_flag(vcpu, IN_WFI);
797-
vgic_v4_load(vcpu);
796+
kvm_vgic_load(vcpu);
798797
preempt_enable();
799798
}
800799

arch/arm64/kvm/hyp/nvhe/hyp-main.c

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -175,16 +175,6 @@ static void handle___vgic_v3_get_gic_config(struct kvm_cpu_context *host_ctxt)
175175
cpu_reg(host_ctxt, 1) = __vgic_v3_get_gic_config();
176176
}
177177

178-
static void handle___vgic_v3_read_vmcr(struct kvm_cpu_context *host_ctxt)
179-
{
180-
cpu_reg(host_ctxt, 1) = __vgic_v3_read_vmcr();
181-
}
182-
183-
static void handle___vgic_v3_write_vmcr(struct kvm_cpu_context *host_ctxt)
184-
{
185-
__vgic_v3_write_vmcr(cpu_reg(host_ctxt, 1));
186-
}
187-
188178
static void handle___vgic_v3_init_lrs(struct kvm_cpu_context *host_ctxt)
189179
{
190180
__vgic_v3_init_lrs();
@@ -195,18 +185,18 @@ static void handle___kvm_get_mdcr_el2(struct kvm_cpu_context *host_ctxt)
195185
cpu_reg(host_ctxt, 1) = __kvm_get_mdcr_el2();
196186
}
197187

198-
static void handle___vgic_v3_save_aprs(struct kvm_cpu_context *host_ctxt)
188+
static void handle___vgic_v3_save_vmcr_aprs(struct kvm_cpu_context *host_ctxt)
199189
{
200190
DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1);
201191

202-
__vgic_v3_save_aprs(kern_hyp_va(cpu_if));
192+
__vgic_v3_save_vmcr_aprs(kern_hyp_va(cpu_if));
203193
}
204194

205-
static void handle___vgic_v3_restore_aprs(struct kvm_cpu_context *host_ctxt)
195+
static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *host_ctxt)
206196
{
207197
DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1);
208198

209-
__vgic_v3_restore_aprs(kern_hyp_va(cpu_if));
199+
__vgic_v3_restore_vmcr_aprs(kern_hyp_va(cpu_if));
210200
}
211201

212202
static void handle___pkvm_init(struct kvm_cpu_context *host_ctxt)
@@ -337,10 +327,8 @@ static const hcall_t host_hcall[] = {
337327
HANDLE_FUNC(__kvm_tlb_flush_vmid_range),
338328
HANDLE_FUNC(__kvm_flush_cpu_context),
339329
HANDLE_FUNC(__kvm_timer_set_cntvoff),
340-
HANDLE_FUNC(__vgic_v3_read_vmcr),
341-
HANDLE_FUNC(__vgic_v3_write_vmcr),
342-
HANDLE_FUNC(__vgic_v3_save_aprs),
343-
HANDLE_FUNC(__vgic_v3_restore_aprs),
330+
HANDLE_FUNC(__vgic_v3_save_vmcr_aprs),
331+
HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
344332
HANDLE_FUNC(__pkvm_vcpu_init_traps),
345333
HANDLE_FUNC(__pkvm_init_vm),
346334
HANDLE_FUNC(__pkvm_init_vcpu),

arch/arm64/kvm/hyp/vgic-v3-sr.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if)
330330
write_gicreg(0, ICH_HCR_EL2);
331331
}
332332

333-
void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if)
333+
static void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if)
334334
{
335335
u64 val;
336336
u32 nr_pre_bits;
@@ -363,7 +363,7 @@ void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if)
363363
}
364364
}
365365

366-
void __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if)
366+
static void __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if)
367367
{
368368
u64 val;
369369
u32 nr_pre_bits;
@@ -455,16 +455,35 @@ u64 __vgic_v3_get_gic_config(void)
455455
return val;
456456
}
457457

458-
u64 __vgic_v3_read_vmcr(void)
458+
static u64 __vgic_v3_read_vmcr(void)
459459
{
460460
return read_gicreg(ICH_VMCR_EL2);
461461
}
462462

463-
void __vgic_v3_write_vmcr(u32 vmcr)
463+
static void __vgic_v3_write_vmcr(u32 vmcr)
464464
{
465465
write_gicreg(vmcr, ICH_VMCR_EL2);
466466
}
467467

468+
void __vgic_v3_save_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if)
469+
{
470+
__vgic_v3_save_aprs(cpu_if);
471+
if (cpu_if->vgic_sre)
472+
cpu_if->vgic_vmcr = __vgic_v3_read_vmcr();
473+
}
474+
475+
void __vgic_v3_restore_vmcr_aprs(struct vgic_v3_cpu_if *cpu_if)
476+
{
477+
/*
478+
* If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
479+
* is dependent on ICC_SRE_EL1.SRE, and we have to perform the
480+
* VMCR_EL2 save/restore in the world switch.
481+
*/
482+
if (cpu_if->vgic_sre)
483+
__vgic_v3_write_vmcr(cpu_if->vgic_vmcr);
484+
__vgic_v3_restore_aprs(cpu_if);
485+
}
486+
468487
static int __vgic_v3_bpr_min(void)
469488
{
470489
/* See Pseudocode for VPriorityGroup */

arch/arm64/kvm/vgic/vgic-v2.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -464,17 +464,10 @@ void vgic_v2_load(struct kvm_vcpu *vcpu)
464464
kvm_vgic_global_state.vctrl_base + GICH_APR);
465465
}
466466

467-
void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu)
468-
{
469-
struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
470-
471-
cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR);
472-
}
473-
474467
void vgic_v2_put(struct kvm_vcpu *vcpu)
475468
{
476469
struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
477470

478-
vgic_v2_vmcr_sync(vcpu);
471+
cpu_if->vgic_vmcr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VMCR);
479472
cpu_if->vgic_apr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_APR);
480473
}

arch/arm64/kvm/vgic/vgic-v3.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -722,40 +722,21 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
722722
{
723723
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
724724

725-
/*
726-
* If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
727-
* is dependent on ICC_SRE_EL1.SRE, and we have to perform the
728-
* VMCR_EL2 save/restore in the world switch.
729-
*/
730-
if (likely(cpu_if->vgic_sre))
731-
kvm_call_hyp(__vgic_v3_write_vmcr, cpu_if->vgic_vmcr);
732-
733-
kvm_call_hyp(__vgic_v3_restore_aprs, cpu_if);
725+
kvm_call_hyp(__vgic_v3_restore_vmcr_aprs, cpu_if);
734726

735727
if (has_vhe())
736728
__vgic_v3_activate_traps(cpu_if);
737729

738730
WARN_ON(vgic_v4_load(vcpu));
739731
}
740732

741-
void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu)
742-
{
743-
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
744-
745-
if (likely(cpu_if->vgic_sre))
746-
cpu_if->vgic_vmcr = kvm_call_hyp_ret(__vgic_v3_read_vmcr);
747-
}
748-
749733
void vgic_v3_put(struct kvm_vcpu *vcpu)
750734
{
751735
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
752736

737+
kvm_call_hyp(__vgic_v3_save_vmcr_aprs, cpu_if);
753738
WARN_ON(vgic_v4_put(vcpu));
754739

755-
vgic_v3_vmcr_sync(vcpu);
756-
757-
kvm_call_hyp(__vgic_v3_save_aprs, cpu_if);
758-
759740
if (has_vhe())
760741
__vgic_v3_deactivate_traps(cpu_if);
761742
}

arch/arm64/kvm/vgic/vgic.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -939,17 +939,6 @@ void kvm_vgic_put(struct kvm_vcpu *vcpu)
939939
vgic_v3_put(vcpu);
940940
}
941941

942-
void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu)
943-
{
944-
if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
945-
return;
946-
947-
if (kvm_vgic_global_state.type == VGIC_V2)
948-
vgic_v2_vmcr_sync(vcpu);
949-
else
950-
vgic_v3_vmcr_sync(vcpu);
951-
}
952-
953942
int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu)
954943
{
955944
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;

arch/arm64/kvm/vgic/vgic.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address,
214214
void vgic_v2_init_lrs(void);
215215
void vgic_v2_load(struct kvm_vcpu *vcpu);
216216
void vgic_v2_put(struct kvm_vcpu *vcpu);
217-
void vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu);
218217

219218
void vgic_v2_save_state(struct kvm_vcpu *vcpu);
220219
void vgic_v2_restore_state(struct kvm_vcpu *vcpu);
@@ -253,7 +252,6 @@ bool vgic_v3_check_base(struct kvm *kvm);
253252

254253
void vgic_v3_load(struct kvm_vcpu *vcpu);
255254
void vgic_v3_put(struct kvm_vcpu *vcpu);
256-
void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu);
257255

258256
bool vgic_has_its(struct kvm *kvm);
259257
int kvm_vgic_register_its_device(void);

include/kvm/arm_vgic.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,6 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
388388

389389
void kvm_vgic_load(struct kvm_vcpu *vcpu);
390390
void kvm_vgic_put(struct kvm_vcpu *vcpu);
391-
void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu);
392391

393392
#define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel))
394393
#define vgic_initialized(k) ((k)->arch.vgic.initialized)

0 commit comments

Comments
 (0)