Skip to content

Commit cd7056a

Browse files
author
Marc Zyngier
committed
Merge remote-tracking branch 'kvmarm/misc-5.5' into kvmarm/next
2 parents a4b28f5 + ef2e78d commit cd7056a

File tree

16 files changed

+97
-63
lines changed

16 files changed

+97
-63
lines changed

arch/arm/include/asm/kvm_emulate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ static inline unsigned long *vcpu_hcr(const struct kvm_vcpu *vcpu)
9595
return (unsigned long *)&vcpu->arch.hcr;
9696
}
9797

98-
static inline void vcpu_clear_wfe_traps(struct kvm_vcpu *vcpu)
98+
static inline void vcpu_clear_wfx_traps(struct kvm_vcpu *vcpu)
9999
{
100100
vcpu->arch.hcr &= ~HCR_TWE;
101101
}
102102

103-
static inline void vcpu_set_wfe_traps(struct kvm_vcpu *vcpu)
103+
static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu)
104104
{
105105
vcpu->arch.hcr |= HCR_TWE;
106106
}

arch/arm/kvm/guest.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
2222

2323
struct kvm_stats_debugfs_item debugfs_entries[] = {
24+
VCPU_STAT(halt_successful_poll),
25+
VCPU_STAT(halt_attempted_poll),
26+
VCPU_STAT(halt_poll_invalid),
27+
VCPU_STAT(halt_wakeup),
2428
VCPU_STAT(hvc_exit_stat),
2529
VCPU_STAT(wfe_exit_stat),
2630
VCPU_STAT(wfi_exit_stat),

arch/arm64/include/asm/kvm_arm.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
* RW: 64bit by default, can be overridden for 32bit VMs
6262
* TAC: Trap ACTLR
6363
* TSC: Trap SMC
64-
* TVM: Trap VM ops (until M+C set in SCTLR_EL1)
6564
* TSW: Trap cache operations by set/way
6665
* TWE: Trap WFE
6766
* TWI: Trap WFI
@@ -74,7 +73,7 @@
7473
* SWIO: Turn set/way invalidates into set/way clean+invalidate
7574
*/
7675
#define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \
77-
HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \
76+
HCR_BSU_IS | HCR_FB | HCR_TAC | \
7877
HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
7978
HCR_FMO | HCR_IMO)
8079
#define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,18 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
5353
/* trap error record accesses */
5454
vcpu->arch.hcr_el2 |= HCR_TERR;
5555
}
56-
if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
56+
57+
if (cpus_have_const_cap(ARM64_HAS_STAGE2_FWB)) {
5758
vcpu->arch.hcr_el2 |= HCR_FWB;
59+
} else {
60+
/*
61+
* For non-FWB CPUs, we trap VM ops (HCR_EL2.TVM) until M+C
62+
* get set in SCTLR_EL1 such that we can detect when the guest
63+
* MMU gets turned on and do the necessary cache maintenance
64+
* then.
65+
*/
66+
vcpu->arch.hcr_el2 |= HCR_TVM;
67+
}
5868

5969
if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features))
6070
vcpu->arch.hcr_el2 &= ~HCR_RW;
@@ -77,14 +87,19 @@ static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu)
7787
return (unsigned long *)&vcpu->arch.hcr_el2;
7888
}
7989

80-
static inline void vcpu_clear_wfe_traps(struct kvm_vcpu *vcpu)
90+
static inline void vcpu_clear_wfx_traps(struct kvm_vcpu *vcpu)
8191
{
8292
vcpu->arch.hcr_el2 &= ~HCR_TWE;
93+
if (atomic_read(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count))
94+
vcpu->arch.hcr_el2 &= ~HCR_TWI;
95+
else
96+
vcpu->arch.hcr_el2 |= HCR_TWI;
8397
}
8498

85-
static inline void vcpu_set_wfe_traps(struct kvm_vcpu *vcpu)
99+
static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu)
86100
{
87101
vcpu->arch.hcr_el2 |= HCR_TWE;
102+
vcpu->arch.hcr_el2 |= HCR_TWI;
88103
}
89104

90105
static inline void vcpu_ptrauth_enable(struct kvm_vcpu *vcpu)

arch/arm64/kvm/guest.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
#define VCPU_STAT(x) { #x, offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU }
3535

3636
struct kvm_stats_debugfs_item debugfs_entries[] = {
37+
VCPU_STAT(halt_successful_poll),
38+
VCPU_STAT(halt_attempted_poll),
39+
VCPU_STAT(halt_poll_invalid),
40+
VCPU_STAT(halt_wakeup),
3741
VCPU_STAT(hvc_exit_stat),
3842
VCPU_STAT(wfe_exit_stat),
3943
VCPU_STAT(wfi_exit_stat),

drivers/irqchip/irq-gic-v4.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,17 @@ static int its_send_vpe_cmd(struct its_vpe *vpe, struct its_cmd_info *info)
141141
int its_schedule_vpe(struct its_vpe *vpe, bool on)
142142
{
143143
struct its_cmd_info info;
144+
int ret;
144145

145146
WARN_ON(preemptible());
146147

147148
info.cmd_type = on ? SCHEDULE_VPE : DESCHEDULE_VPE;
148149

149-
return its_send_vpe_cmd(vpe, &info);
150+
ret = its_send_vpe_cmd(vpe, &info);
151+
if (!ret)
152+
vpe->resident = on;
153+
154+
return ret;
150155
}
151156

152157
int its_invall_vpe(struct its_vpe *vpe)

include/kvm/arm_vgic.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ struct vgic_dist {
240240
* Contains the attributes and gpa of the LPI configuration table.
241241
* Since we report GICR_TYPER.CommonLPIAff as 0b00, we can share
242242
* one address across all redistributors.
243-
* GICv3 spec: 6.1.2 "LPI Configuration tables"
243+
* GICv3 spec: IHI 0069E 6.1.1 "LPI Configuration tables"
244244
*/
245245
u64 propbaser;
246246

@@ -378,8 +378,6 @@ static inline int kvm_vgic_get_max_vcpus(void)
378378
return kvm_vgic_global_state.max_gic_vcpus;
379379
}
380380

381-
int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);
382-
383381
/**
384382
* kvm_vgic_setup_default_irq_routing:
385383
* Setup a default flat gsi routing table mapping all SPIs
@@ -396,7 +394,7 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int irq,
396394
int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq,
397395
struct kvm_kernel_irq_routing_entry *irq_entry);
398396

399-
void kvm_vgic_v4_enable_doorbell(struct kvm_vcpu *vcpu);
400-
void kvm_vgic_v4_disable_doorbell(struct kvm_vcpu *vcpu);
397+
int vgic_v4_load(struct kvm_vcpu *vcpu);
398+
int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db);
401399

402400
#endif /* __KVM_ARM_VGIC_H */

include/linux/irqchip/arm-gic-v4.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@ struct its_vm {
3232
struct its_vpe {
3333
struct page *vpt_page;
3434
struct its_vm *its_vm;
35+
/* per-vPE VLPI tracking */
36+
atomic_t vlpi_count;
3537
/* Doorbell interrupt */
3638
int irq;
3739
irq_hw_number_t vpe_db_lpi;
40+
/* VPE resident */
41+
bool resident;
3842
/* VPE proxy mapping */
3943
int vpe_proxy_event;
4044
/*

virt/kvm/arm/arch_timer.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static inline bool userspace_irqchip(struct kvm *kvm)
8080
static void soft_timer_start(struct hrtimer *hrt, u64 ns)
8181
{
8282
hrtimer_start(hrt, ktime_add_ns(ktime_get(), ns),
83-
HRTIMER_MODE_ABS);
83+
HRTIMER_MODE_ABS_HARD);
8484
}
8585

8686
static void soft_timer_cancel(struct hrtimer *hrt)
@@ -697,11 +697,11 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
697697
update_vtimer_cntvoff(vcpu, kvm_phys_timer_read());
698698
ptimer->cntvoff = 0;
699699

700-
hrtimer_init(&timer->bg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
700+
hrtimer_init(&timer->bg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
701701
timer->bg_timer.function = kvm_bg_timer_expire;
702702

703-
hrtimer_init(&vtimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
704-
hrtimer_init(&ptimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
703+
hrtimer_init(&vtimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
704+
hrtimer_init(&ptimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
705705
vtimer->hrtimer.function = kvm_hrtimer_expire;
706706
ptimer->hrtimer.function = kvm_hrtimer_expire;
707707

virt/kvm/arm/arm.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,20 +348,24 @@ void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
348348
/*
349349
* If we're about to block (most likely because we've just hit a
350350
* WFI), we need to sync back the state of the GIC CPU interface
351-
* so that we have the lastest PMR and group enables. This ensures
351+
* so that we have the latest PMR and group enables. This ensures
352352
* that kvm_arch_vcpu_runnable has up-to-date data to decide
353353
* whether we have pending interrupts.
354+
*
355+
* For the same reason, we want to tell GICv4 that we need
356+
* doorbells to be signalled, should an interrupt become pending.
354357
*/
355358
preempt_disable();
356359
kvm_vgic_vmcr_sync(vcpu);
360+
vgic_v4_put(vcpu, true);
357361
preempt_enable();
358-
359-
kvm_vgic_v4_enable_doorbell(vcpu);
360362
}
361363

362364
void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu)
363365
{
364-
kvm_vgic_v4_disable_doorbell(vcpu);
366+
preempt_disable();
367+
vgic_v4_load(vcpu);
368+
preempt_enable();
365369
}
366370

367371
int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
@@ -412,9 +416,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
412416
kvm_make_request(KVM_REQ_RECORD_STEAL, vcpu);
413417

414418
if (single_task_running())
415-
vcpu_clear_wfe_traps(vcpu);
419+
vcpu_clear_wfx_traps(vcpu);
416420
else
417-
vcpu_set_wfe_traps(vcpu);
421+
vcpu_set_wfx_traps(vcpu);
418422

419423
vcpu_ptrauth_setup_lazy(vcpu);
420424
}

0 commit comments

Comments
 (0)