Skip to content

Commit c5d9ae2

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "ARM: - Read HW interrupt pending state from the HW x86: - Don't truncate the performance event mask on AMD - Fix Xen runstate updates to be atomic when preempting vCPU - Fix for AMD AVIC interrupt injection race - Several other AMD fixes" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: x86/pmu: Use AMD64_RAW_EVENT_MASK for PERF_TYPE_RAW KVM: x86/pmu: Don't truncate the PerfEvtSeln MSR when creating a perf event KVM: SVM: fix race between interrupt delivery and AVIC inhibition KVM: SVM: set IRR in svm_deliver_interrupt KVM: SVM: extract avic_ring_doorbell selftests: kvm: Remove absent target file KVM: arm64: vgic: Read HW interrupt pending state from the HW KVM: x86/xen: Fix runstate updates to be atomic when preempting vCPU KVM: x86: SVM: move avic definitions from AMD's spec to svm.h KVM: x86: lapic: don't touch irr_pending in kvm_apic_update_apicv when inhibiting it KVM: x86: nSVM: deal with L1 hypervisor that intercepts interrupts but lets L2 control them KVM: x86: nSVM: expose clean bit support to the guest KVM: x86: nSVM/nVMX: set nested_run_pending on VM entry which is a result of RSM KVM: x86: nSVM: mark vmcb01 as dirty when restoring SMM saved state KVM: x86: nSVM: fix potential NULL derefernce on nested migration KVM: x86: SVM: don't passthrough SMAP/SMEP/PKE bits in !NPT && !gCR0.PG case Revert "svm: Add warning message for AVIC IPI invalid target"
2 parents a254a9d + 710c476 commit c5d9ae2

File tree

13 files changed

+232
-143
lines changed

13 files changed

+232
-143
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ unsigned long vgic_mmio_read_pending(struct kvm_vcpu *vcpu,
248248
IRQCHIP_STATE_PENDING,
249249
&val);
250250
WARN_RATELIMIT(err, "IRQ %d", irq->host_irq);
251+
} else if (vgic_irq_is_mapped_level(irq)) {
252+
val = vgic_get_phys_line_level(irq);
251253
} else {
252254
val = irq_is_pending(irq);
253255
}

arch/x86/include/asm/msr-index.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@
476476
#define MSR_AMD64_ICIBSEXTDCTL 0xc001103c
477477
#define MSR_AMD64_IBSOPDATA4 0xc001103d
478478
#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
479+
#define MSR_AMD64_SVM_AVIC_DOORBELL 0xc001011b
479480
#define MSR_AMD64_VM_PAGE_FLUSH 0xc001011e
480481
#define MSR_AMD64_SEV_ES_GHCB 0xc0010130
481482
#define MSR_AMD64_SEV 0xc0010131

arch/x86/include/asm/svm.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,42 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
220220
#define SVM_NESTED_CTL_SEV_ENABLE BIT(1)
221221
#define SVM_NESTED_CTL_SEV_ES_ENABLE BIT(2)
222222

223+
224+
/* AVIC */
225+
#define AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK (0xFF)
226+
#define AVIC_LOGICAL_ID_ENTRY_VALID_BIT 31
227+
#define AVIC_LOGICAL_ID_ENTRY_VALID_MASK (1 << 31)
228+
229+
#define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK (0xFFULL)
230+
#define AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK (0xFFFFFFFFFFULL << 12)
231+
#define AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK (1ULL << 62)
232+
#define AVIC_PHYSICAL_ID_ENTRY_VALID_MASK (1ULL << 63)
233+
#define AVIC_PHYSICAL_ID_TABLE_SIZE_MASK (0xFF)
234+
235+
#define AVIC_DOORBELL_PHYSICAL_ID_MASK (0xFF)
236+
237+
#define AVIC_UNACCEL_ACCESS_WRITE_MASK 1
238+
#define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0
239+
#define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF
240+
241+
enum avic_ipi_failure_cause {
242+
AVIC_IPI_FAILURE_INVALID_INT_TYPE,
243+
AVIC_IPI_FAILURE_TARGET_NOT_RUNNING,
244+
AVIC_IPI_FAILURE_INVALID_TARGET,
245+
AVIC_IPI_FAILURE_INVALID_BACKING_PAGE,
246+
};
247+
248+
249+
/*
250+
* 0xff is broadcast, so the max index allowed for physical APIC ID
251+
* table is 0xfe. APIC IDs above 0xff are reserved.
252+
*/
253+
#define AVIC_MAX_PHYSICAL_ID_COUNT 0xff
254+
255+
#define AVIC_HPA_MASK ~((0xFFFULL << 52) | 0xFFF)
256+
#define VMCB_AVIC_APIC_BAR_MASK 0xFFFFFFFFFF000ULL
257+
258+
223259
struct vmcb_seg {
224260
u16 selector;
225261
u16 attrib;

arch/x86/kvm/lapic.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2306,7 +2306,12 @@ void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
23062306
apic->irr_pending = true;
23072307
apic->isr_count = 1;
23082308
} else {
2309-
apic->irr_pending = (apic_search_irr(apic) != -1);
2309+
/*
2310+
* Don't clear irr_pending, searching the IRR can race with
2311+
* updates from the CPU as APICv is still active from hardware's
2312+
* perspective. The flag will be cleared as appropriate when
2313+
* KVM injects the interrupt.
2314+
*/
23102315
apic->isr_count = count_vectors(apic->regs + APIC_ISR);
23112316
}
23122317
}

arch/x86/kvm/pmu.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ static void kvm_perf_overflow(struct perf_event *perf_event,
9595
}
9696

9797
static void pmc_reprogram_counter(struct kvm_pmc *pmc, u32 type,
98-
unsigned config, bool exclude_user,
98+
u64 config, bool exclude_user,
9999
bool exclude_kernel, bool intr,
100100
bool in_tx, bool in_tx_cp)
101101
{
@@ -181,7 +181,8 @@ static int cmp_u64(const void *a, const void *b)
181181

182182
void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
183183
{
184-
unsigned config, type = PERF_TYPE_RAW;
184+
u64 config;
185+
u32 type = PERF_TYPE_RAW;
185186
struct kvm *kvm = pmc->vcpu->kvm;
186187
struct kvm_pmu_event_filter *filter;
187188
bool allow_event = true;
@@ -220,7 +221,7 @@ void reprogram_gp_counter(struct kvm_pmc *pmc, u64 eventsel)
220221
}
221222

222223
if (type == PERF_TYPE_RAW)
223-
config = eventsel & X86_RAW_EVENT_MASK;
224+
config = eventsel & AMD64_RAW_EVENT_MASK;
224225

225226
if (pmc->current_config == eventsel && pmc_resume_counter(pmc))
226227
return;

arch/x86/kvm/svm/avic.c

Lines changed: 23 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,6 @@
2727
#include "irq.h"
2828
#include "svm.h"
2929

30-
#define SVM_AVIC_DOORBELL 0xc001011b
31-
32-
#define AVIC_HPA_MASK ~((0xFFFULL << 52) | 0xFFF)
33-
34-
/*
35-
* 0xff is broadcast, so the max index allowed for physical APIC ID
36-
* table is 0xfe. APIC IDs above 0xff are reserved.
37-
*/
38-
#define AVIC_MAX_PHYSICAL_ID_COUNT 255
39-
40-
#define AVIC_UNACCEL_ACCESS_WRITE_MASK 1
41-
#define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0
42-
#define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF
43-
4430
/* AVIC GATAG is encoded using VM and VCPU IDs */
4531
#define AVIC_VCPU_ID_BITS 8
4632
#define AVIC_VCPU_ID_MASK ((1 << AVIC_VCPU_ID_BITS) - 1)
@@ -73,12 +59,6 @@ struct amd_svm_iommu_ir {
7359
void *data; /* Storing pointer to struct amd_ir_data */
7460
};
7561

76-
enum avic_ipi_failure_cause {
77-
AVIC_IPI_FAILURE_INVALID_INT_TYPE,
78-
AVIC_IPI_FAILURE_TARGET_NOT_RUNNING,
79-
AVIC_IPI_FAILURE_INVALID_TARGET,
80-
AVIC_IPI_FAILURE_INVALID_BACKING_PAGE,
81-
};
8262

8363
/* Note:
8464
* This function is called from IOMMU driver to notify
@@ -289,6 +269,22 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu)
289269
return 0;
290270
}
291271

272+
void avic_ring_doorbell(struct kvm_vcpu *vcpu)
273+
{
274+
/*
275+
* Note, the vCPU could get migrated to a different pCPU at any point,
276+
* which could result in signalling the wrong/previous pCPU. But if
277+
* that happens the vCPU is guaranteed to do a VMRUN (after being
278+
* migrated) and thus will process pending interrupts, i.e. a doorbell
279+
* is not needed (and the spurious one is harmless).
280+
*/
281+
int cpu = READ_ONCE(vcpu->cpu);
282+
283+
if (cpu != get_cpu())
284+
wrmsrl(MSR_AMD64_SVM_AVIC_DOORBELL, kvm_cpu_get_apicid(cpu));
285+
put_cpu();
286+
}
287+
292288
static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
293289
u32 icrl, u32 icrh)
294290
{
@@ -304,8 +300,13 @@ static void avic_kick_target_vcpus(struct kvm *kvm, struct kvm_lapic *source,
304300
kvm_for_each_vcpu(i, vcpu, kvm) {
305301
if (kvm_apic_match_dest(vcpu, source, icrl & APIC_SHORT_MASK,
306302
GET_APIC_DEST_FIELD(icrh),
307-
icrl & APIC_DEST_MASK))
308-
kvm_vcpu_wake_up(vcpu);
303+
icrl & APIC_DEST_MASK)) {
304+
vcpu->arch.apic->irr_pending = true;
305+
svm_complete_interrupt_delivery(vcpu,
306+
icrl & APIC_MODE_MASK,
307+
icrl & APIC_INT_LEVELTRIG,
308+
icrl & APIC_VECTOR_MASK);
309+
}
309310
}
310311
}
311312

@@ -345,8 +346,6 @@ int avic_incomplete_ipi_interception(struct kvm_vcpu *vcpu)
345346
avic_kick_target_vcpus(vcpu->kvm, apic, icrl, icrh);
346347
break;
347348
case AVIC_IPI_FAILURE_INVALID_TARGET:
348-
WARN_ONCE(1, "Invalid IPI target: index=%u, vcpu=%d, icr=%#0x:%#0x\n",
349-
index, vcpu->vcpu_id, icrh, icrl);
350349
break;
351350
case AVIC_IPI_FAILURE_INVALID_BACKING_PAGE:
352351
WARN_ONCE(1, "Invalid backing page\n");
@@ -669,52 +668,6 @@ void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
669668
return;
670669
}
671670

672-
int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec)
673-
{
674-
if (!vcpu->arch.apicv_active)
675-
return -1;
676-
677-
kvm_lapic_set_irr(vec, vcpu->arch.apic);
678-
679-
/*
680-
* Pairs with the smp_mb_*() after setting vcpu->guest_mode in
681-
* vcpu_enter_guest() to ensure the write to the vIRR is ordered before
682-
* the read of guest_mode, which guarantees that either VMRUN will see
683-
* and process the new vIRR entry, or that the below code will signal
684-
* the doorbell if the vCPU is already running in the guest.
685-
*/
686-
smp_mb__after_atomic();
687-
688-
/*
689-
* Signal the doorbell to tell hardware to inject the IRQ if the vCPU
690-
* is in the guest. If the vCPU is not in the guest, hardware will
691-
* automatically process AVIC interrupts at VMRUN.
692-
*/
693-
if (vcpu->mode == IN_GUEST_MODE) {
694-
int cpu = READ_ONCE(vcpu->cpu);
695-
696-
/*
697-
* Note, the vCPU could get migrated to a different pCPU at any
698-
* point, which could result in signalling the wrong/previous
699-
* pCPU. But if that happens the vCPU is guaranteed to do a
700-
* VMRUN (after being migrated) and thus will process pending
701-
* interrupts, i.e. a doorbell is not needed (and the spurious
702-
* one is harmless).
703-
*/
704-
if (cpu != get_cpu())
705-
wrmsrl(SVM_AVIC_DOORBELL, kvm_cpu_get_apicid(cpu));
706-
put_cpu();
707-
} else {
708-
/*
709-
* Wake the vCPU if it was blocking. KVM will then detect the
710-
* pending IRQ when checking if the vCPU has a wake event.
711-
*/
712-
kvm_vcpu_wake_up(vcpu);
713-
}
714-
715-
return 0;
716-
}
717-
718671
bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu)
719672
{
720673
return false;

arch/x86/kvm/svm/nested.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,18 +1457,6 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
14571457
!__nested_vmcb_check_save(vcpu, &save_cached))
14581458
goto out_free;
14591459

1460-
/*
1461-
* While the nested guest CR3 is already checked and set by
1462-
* KVM_SET_SREGS, it was set when nested state was yet loaded,
1463-
* thus MMU might not be initialized correctly.
1464-
* Set it again to fix this.
1465-
*/
1466-
1467-
ret = nested_svm_load_cr3(&svm->vcpu, vcpu->arch.cr3,
1468-
nested_npt_enabled(svm), false);
1469-
if (WARN_ON_ONCE(ret))
1470-
goto out_free;
1471-
14721460

14731461
/*
14741462
* All checks done, we can enter guest mode. Userspace provides
@@ -1494,6 +1482,20 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
14941482

14951483
svm_switch_vmcb(svm, &svm->nested.vmcb02);
14961484
nested_vmcb02_prepare_control(svm);
1485+
1486+
/*
1487+
* While the nested guest CR3 is already checked and set by
1488+
* KVM_SET_SREGS, it was set when nested state was yet loaded,
1489+
* thus MMU might not be initialized correctly.
1490+
* Set it again to fix this.
1491+
*/
1492+
1493+
ret = nested_svm_load_cr3(&svm->vcpu, vcpu->arch.cr3,
1494+
nested_npt_enabled(svm), false);
1495+
if (WARN_ON_ONCE(ret))
1496+
goto out_free;
1497+
1498+
14971499
kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu);
14981500
ret = 0;
14991501
out_free:

0 commit comments

Comments
 (0)