Skip to content

Commit 6e1d72f

Browse files
committed
Merge tag 'kvmarm-fixes-5.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into kvm-master
KVM/arm fixes for 5.8, take #2 - Make sure a vcpu becoming non-resident doesn't race against the doorbell delivery - Only advertise pvtime if accounting is enabled - Return the correct error code if reset fails with SVE - Make sure that pseudo-NMI functions are annotated as __always_inline
2 parents 5ecad24 + a3f574c commit 6e1d72f

File tree

6 files changed

+37
-8
lines changed

6 files changed

+37
-8
lines changed

arch/arm64/include/asm/arch_gicv3.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static inline u32 gic_read_pmr(void)
109109
return read_sysreg_s(SYS_ICC_PMR_EL1);
110110
}
111111

112-
static inline void gic_write_pmr(u32 val)
112+
static __always_inline void gic_write_pmr(u32 val)
113113
{
114114
write_sysreg_s(val, SYS_ICC_PMR_EL1);
115115
}

arch/arm64/include/asm/cpufeature.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ static inline bool system_supports_generic_auth(void)
675675
cpus_have_const_cap(ARM64_HAS_GENERIC_AUTH);
676676
}
677677

678-
static inline bool system_uses_irq_prio_masking(void)
678+
static __always_inline bool system_uses_irq_prio_masking(void)
679679
{
680680
return IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) &&
681681
cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING);

arch/arm64/kvm/pvtime.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <linux/arm-smccc.h>
55
#include <linux/kvm_host.h>
6+
#include <linux/sched/stat.h>
67

78
#include <asm/kvm_mmu.h>
89
#include <asm/pvclock-abi.h>
@@ -73,6 +74,11 @@ gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu)
7374
return base;
7475
}
7576

77+
static bool kvm_arm_pvtime_supported(void)
78+
{
79+
return !!sched_info_on();
80+
}
81+
7682
int kvm_arm_pvtime_set_attr(struct kvm_vcpu *vcpu,
7783
struct kvm_device_attr *attr)
7884
{
@@ -82,7 +88,8 @@ int kvm_arm_pvtime_set_attr(struct kvm_vcpu *vcpu,
8288
int ret = 0;
8389
int idx;
8490

85-
if (attr->attr != KVM_ARM_VCPU_PVTIME_IPA)
91+
if (!kvm_arm_pvtime_supported() ||
92+
attr->attr != KVM_ARM_VCPU_PVTIME_IPA)
8693
return -ENXIO;
8794

8895
if (get_user(ipa, user))
@@ -110,7 +117,8 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu,
110117
u64 __user *user = (u64 __user *)attr->addr;
111118
u64 ipa;
112119

113-
if (attr->attr != KVM_ARM_VCPU_PVTIME_IPA)
120+
if (!kvm_arm_pvtime_supported() ||
121+
attr->attr != KVM_ARM_VCPU_PVTIME_IPA)
114122
return -ENXIO;
115123

116124
ipa = vcpu->arch.steal.base;
@@ -125,7 +133,8 @@ int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
125133
{
126134
switch (attr->attr) {
127135
case KVM_ARM_VCPU_PVTIME_IPA:
128-
return 0;
136+
if (kvm_arm_pvtime_supported())
137+
return 0;
129138
}
130139
return -ENXIO;
131140
}

arch/arm64/kvm/reset.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ static int kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
245245
*/
246246
int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
247247
{
248-
int ret = -EINVAL;
248+
int ret;
249249
bool loaded;
250250
u32 pstate;
251251

@@ -269,15 +269,19 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
269269

270270
if (test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, vcpu->arch.features) ||
271271
test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, vcpu->arch.features)) {
272-
if (kvm_vcpu_enable_ptrauth(vcpu))
272+
if (kvm_vcpu_enable_ptrauth(vcpu)) {
273+
ret = -EINVAL;
273274
goto out;
275+
}
274276
}
275277

276278
switch (vcpu->arch.target) {
277279
default:
278280
if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
279-
if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1))
281+
if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1)) {
282+
ret = -EINVAL;
280283
goto out;
284+
}
281285
pstate = VCPU_RESET_PSTATE_SVC;
282286
} else {
283287
pstate = VCPU_RESET_PSTATE_EL1;

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,15 @@ static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
9090
!irqd_irq_disabled(&irq_to_desc(irq)->irq_data))
9191
disable_irq_nosync(irq);
9292

93+
/*
94+
* The v4.1 doorbell can fire concurrently with the vPE being
95+
* made non-resident. Ensure we only update pending_last
96+
* *after* the non-residency sequence has completed.
97+
*/
98+
raw_spin_lock(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vpe_lock);
9399
vcpu->arch.vgic_cpu.vgic_v3.its_vpe.pending_last = true;
100+
raw_spin_unlock(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vpe_lock);
101+
94102
kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu);
95103
kvm_vcpu_kick(vcpu);
96104

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4054,16 +4054,24 @@ static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
40544054
u64 val;
40554055

40564056
if (info->req_db) {
4057+
unsigned long flags;
4058+
40574059
/*
40584060
* vPE is going to block: make the vPE non-resident with
40594061
* PendingLast clear and DB set. The GIC guarantees that if
40604062
* we read-back PendingLast clear, then a doorbell will be
40614063
* delivered when an interrupt comes.
4064+
*
4065+
* Note the locking to deal with the concurrent update of
4066+
* pending_last from the doorbell interrupt handler that can
4067+
* run concurrently.
40624068
*/
4069+
raw_spin_lock_irqsave(&vpe->vpe_lock, flags);
40634070
val = its_clear_vpend_valid(vlpi_base,
40644071
GICR_VPENDBASER_PendingLast,
40654072
GICR_VPENDBASER_4_1_DB);
40664073
vpe->pending_last = !!(val & GICR_VPENDBASER_PendingLast);
4074+
raw_spin_unlock_irqrestore(&vpe->vpe_lock, flags);
40674075
} else {
40684076
/*
40694077
* We're not blocking, so just make the vPE non-resident

0 commit comments

Comments
 (0)