Skip to content

Commit 1b13885

Browse files
committed
Merge tag 'kvm-x86-apic-6.20' of https://github.com/kvm-x86/linux into HEAD
KVM x86 APIC-ish changes for 6.20 - Fix a benign bug where KVM could use the wrong memslots (ignored SMM) when creating a vCPU-specific mapping of guest memory. - Clean up KVM's handling of marking mapped vCPU pages dirty. - Drop a pile of *ancient* sanity checks hidden behind in KVM's unused ASSERT() macro, most of which could be trivially triggered by the guest and/or user, and all of which were useless. - Fold "struct dest_map" into its sole user, "struct rtc_status", to make it more obvious what the weird parameter is used for, and to allow burying the RTC shenanigans behind CONFIG_KVM_IOAPIC=y. - Bury all of ioapic.h and KVM_IRQCHIP_KERNEL behind CONFIG_KVM_IOAPIC=y. - Add a regression test for recent APICv update fixes. - Rework KVM's handling of VMCS updates while L2 is active to temporarily switch to vmcs01 instead of deferring the update until the next nested VM-Exit. The deferred updates approach directly contributed to several bugs, was proving to be a maintenance burden due to the difficulty in auditing the correctness of deferred updates, and was polluting "struct nested_vmx" with a growing pile of booleans. - Handle "hardware APIC ISR", a.k.a. SVI, updates in kvm_apic_update_apicv() to consolidate the updates, and to co-locate SVI updates with the updates for KVM's own cache of ISR information. - Drop a dead function declaration.
2 parents 9123c5f + ac4f869 commit 1b13885

File tree

18 files changed

+334
-227
lines changed

18 files changed

+334
-227
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,7 +1232,9 @@ struct kvm_xen {
12321232

12331233
enum kvm_irqchip_mode {
12341234
KVM_IRQCHIP_NONE,
1235+
#ifdef CONFIG_KVM_IOAPIC
12351236
KVM_IRQCHIP_KERNEL, /* created with KVM_CREATE_IRQCHIP */
1237+
#endif
12361238
KVM_IRQCHIP_SPLIT, /* created with KVM_CAP_SPLIT_IRQCHIP */
12371239
};
12381240

arch/x86/kvm/hyperv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ static int synic_set_irq(struct kvm_vcpu_hv_synic *synic, u32 sint)
492492
irq.vector = vector;
493493
irq.level = 1;
494494

495-
ret = kvm_irq_delivery_to_apic(vcpu->kvm, vcpu->arch.apic, &irq, NULL);
495+
ret = kvm_irq_delivery_to_apic(vcpu->kvm, vcpu->arch.apic, &irq);
496496
trace_kvm_hv_synic_set_irq(vcpu->vcpu_id, sint, irq.vector, ret);
497497
return ret;
498498
}

arch/x86/kvm/ioapic.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@
3737
static int ioapic_service(struct kvm_ioapic *vioapic, int irq,
3838
bool line_status);
3939

40-
static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu,
41-
struct kvm_ioapic *ioapic,
42-
int trigger_mode,
43-
int pin);
44-
4540
static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic)
4641
{
4742
unsigned long result = 0;
@@ -82,7 +77,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic)
8277
static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
8378
{
8479
ioapic->rtc_status.pending_eoi = 0;
85-
bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_IDS);
80+
bitmap_zero(ioapic->rtc_status.map, KVM_MAX_VCPU_IDS);
8681
}
8782

8883
static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
@@ -97,7 +92,7 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
9792
{
9893
bool new_val, old_val;
9994
struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
100-
struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
95+
struct rtc_status *status = &ioapic->rtc_status;
10196
union kvm_ioapic_redirect_entry *e;
10297

10398
e = &ioapic->redirtbl[RTC_GSI];
@@ -107,17 +102,17 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
107102
return;
108103

109104
new_val = kvm_apic_pending_eoi(vcpu, e->fields.vector);
110-
old_val = test_bit(vcpu->vcpu_id, dest_map->map);
105+
old_val = test_bit(vcpu->vcpu_id, status->map);
111106

112107
if (new_val == old_val)
113108
return;
114109

115110
if (new_val) {
116-
__set_bit(vcpu->vcpu_id, dest_map->map);
117-
dest_map->vectors[vcpu->vcpu_id] = e->fields.vector;
111+
__set_bit(vcpu->vcpu_id, status->map);
112+
status->vectors[vcpu->vcpu_id] = e->fields.vector;
118113
ioapic->rtc_status.pending_eoi++;
119114
} else {
120-
__clear_bit(vcpu->vcpu_id, dest_map->map);
115+
__clear_bit(vcpu->vcpu_id, status->map);
121116
ioapic->rtc_status.pending_eoi--;
122117
rtc_status_pending_eoi_check_valid(ioapic);
123118
}
@@ -148,13 +143,12 @@ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic)
148143
static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu,
149144
int vector)
150145
{
151-
struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
146+
struct rtc_status *status = &ioapic->rtc_status;
152147

153148
/* RTC special handling */
154-
if (test_bit(vcpu->vcpu_id, dest_map->map) &&
155-
(vector == dest_map->vectors[vcpu->vcpu_id]) &&
156-
(test_and_clear_bit(vcpu->vcpu_id,
157-
ioapic->rtc_status.dest_map.map))) {
149+
if (test_bit(vcpu->vcpu_id, status->map) &&
150+
(vector == status->vectors[vcpu->vcpu_id]) &&
151+
(test_and_clear_bit(vcpu->vcpu_id, status->map))) {
158152
--ioapic->rtc_status.pending_eoi;
159153
rtc_status_pending_eoi_check_valid(ioapic);
160154
}
@@ -265,15 +259,15 @@ static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr)
265259
void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors)
266260
{
267261
struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
268-
struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
262+
struct rtc_status *status = &ioapic->rtc_status;
269263
union kvm_ioapic_redirect_entry *e;
270264
int index;
271265

272266
spin_lock(&ioapic->lock);
273267

274268
/* Make sure we see any missing RTC EOI */
275-
if (test_bit(vcpu->vcpu_id, dest_map->map))
276-
__set_bit(dest_map->vectors[vcpu->vcpu_id],
269+
if (test_bit(vcpu->vcpu_id, status->map))
270+
__set_bit(status->vectors[vcpu->vcpu_id],
277271
ioapic_handled_vectors);
278272

279273
for (index = 0; index < IOAPIC_NUM_PINS; index++) {
@@ -490,11 +484,11 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status)
490484
* if rtc_irq_check_coalesced returns false).
491485
*/
492486
BUG_ON(ioapic->rtc_status.pending_eoi != 0);
493-
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe,
494-
&ioapic->rtc_status.dest_map);
487+
ret = __kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe,
488+
&ioapic->rtc_status);
495489
ioapic->rtc_status.pending_eoi = (ret < 0 ? 0 : ret);
496490
} else
497-
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL);
491+
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe);
498492

499493
if (ret && irqe.trig_mode == IOAPIC_LEVEL_TRIG)
500494
entry->fields.remote_irr = 1;
@@ -564,7 +558,6 @@ static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu,
564558
kvm_lapic_suppress_eoi_broadcast(apic))
565559
return;
566560

567-
ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
568561
ent->fields.remote_irr = 0;
569562
if (!ent->fields.mask && (ioapic->irr & (1 << pin))) {
570563
++ioapic->irq_eoi[pin];
@@ -624,8 +617,6 @@ static int ioapic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
624617
if (!ioapic_in_range(ioapic, addr))
625618
return -EOPNOTSUPP;
626619

627-
ASSERT(!(addr & 0xf)); /* check alignment */
628-
629620
addr &= 0xff;
630621
spin_lock(&ioapic->lock);
631622
switch (addr) {
@@ -666,8 +657,6 @@ static int ioapic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
666657
if (!ioapic_in_range(ioapic, addr))
667658
return -EOPNOTSUPP;
668659

669-
ASSERT(!(addr & 0xf)); /* check alignment */
670-
671660
switch (len) {
672661
case 8:
673662
case 4:

arch/x86/kvm/ioapic.h

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
#include <kvm/iodev.h>
77
#include "irq.h"
88

9+
#ifdef CONFIG_KVM_IOAPIC
10+
911
struct kvm;
1012
struct kvm_vcpu;
1113

1214
#define IOAPIC_NUM_PINS KVM_IOAPIC_NUM_PINS
13-
#define MAX_NR_RESERVED_IOAPIC_PINS KVM_MAX_IRQ_ROUTES
1415
#define IOAPIC_VERSION_ID 0x11 /* IOAPIC version */
1516
#define IOAPIC_EDGE_TRIG 0
1617
#define IOAPIC_LEVEL_TRIG 1
@@ -37,7 +38,9 @@ struct kvm_vcpu;
3738

3839
#define RTC_GSI 8
3940

40-
struct dest_map {
41+
struct rtc_status {
42+
int pending_eoi;
43+
4144
/* vcpu bitmap where IRQ has been sent */
4245
DECLARE_BITMAP(map, KVM_MAX_VCPU_IDS);
4346

@@ -48,12 +51,6 @@ struct dest_map {
4851
u8 vectors[KVM_MAX_VCPU_IDS];
4952
};
5053

51-
52-
struct rtc_status {
53-
int pending_eoi;
54-
struct dest_map dest_map;
55-
};
56-
5754
union kvm_ioapic_redirect_entry {
5855
u64 bits;
5956
struct {
@@ -104,24 +101,6 @@ void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
104101
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
105102
bool mask);
106103

107-
#ifdef DEBUG
108-
#define ASSERT(x) \
109-
do { \
110-
if (!(x)) { \
111-
printk(KERN_EMERG "assertion failed %s: %d: %s\n", \
112-
__FILE__, __LINE__, #x); \
113-
BUG(); \
114-
} \
115-
} while (0)
116-
#else
117-
#define ASSERT(x) do { } while (0)
118-
#endif
119-
120-
static inline int ioapic_in_kernel(struct kvm *kvm)
121-
{
122-
return irqchip_full(kvm);
123-
}
124-
125104
void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu);
126105
void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector,
127106
int trigger_mode);
@@ -134,6 +113,13 @@ void kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
134113
void kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state);
135114
void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu,
136115
ulong *ioapic_handled_vectors);
116+
#endif /* CONFIG_KVM_IOAPIC */
117+
118+
static inline int ioapic_in_kernel(struct kvm *kvm)
119+
{
120+
return irqchip_full(kvm);
121+
}
122+
137123
void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
138124
ulong *ioapic_handled_vectors);
139125
void kvm_scan_ioapic_irq(struct kvm_vcpu *vcpu, u32 dest_id, u16 dest_mode,

arch/x86/kvm/irq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
235235

236236
kvm_msi_to_lapic_irq(kvm, e, &irq);
237237

238-
return kvm_irq_delivery_to_apic(kvm, NULL, &irq, NULL);
238+
return kvm_irq_delivery_to_apic(kvm, NULL, &irq);
239239
}
240240

241241
int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
@@ -258,7 +258,7 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
258258

259259
kvm_msi_to_lapic_irq(kvm, e, &irq);
260260

261-
if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL))
261+
if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r))
262262
return r;
263263
break;
264264

0 commit comments

Comments
 (0)