Skip to content

Commit 72c3bcd

Browse files
committed
KVM: x86: handle !lapic_in_kernel case in kvm_cpu_*_extint
Centralize handling of interrupts from the userspace APIC in kvm_cpu_has_extint and kvm_cpu_get_extint, since userspace APIC interrupts are handled more or less the same as ExtINTs are with split irqchip. This removes duplicated code from kvm_cpu_has_injectable_intr and kvm_cpu_has_interrupt, and makes the code more similar between kvm_cpu_has_{extint,interrupt} on one side and kvm_cpu_get_{extint,interrupt} on the other. Cc: [email protected] Reviewed-by: Filippo Sironi <[email protected]> Reviewed-by: David Woodhouse <[email protected]> Tested-by: David Woodhouse <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 545f639 commit 72c3bcd

File tree

2 files changed

+34
-51
lines changed

2 files changed

+34
-51
lines changed

arch/x86/kvm/irq.c

Lines changed: 33 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -41,28 +41,9 @@ static int pending_userspace_extint(struct kvm_vcpu *v)
4141
* non-APIC source without intack.
4242
*/
4343
static int kvm_cpu_has_extint(struct kvm_vcpu *v)
44-
{
45-
u8 accept = kvm_apic_accept_pic_intr(v);
46-
47-
if (accept) {
48-
if (irqchip_split(v->kvm))
49-
return pending_userspace_extint(v);
50-
else
51-
return v->kvm->arch.vpic->output;
52-
} else
53-
return 0;
54-
}
55-
56-
/*
57-
* check if there is injectable interrupt:
58-
* when virtual interrupt delivery enabled,
59-
* interrupt from apic will handled by hardware,
60-
* we don't need to check it here.
61-
*/
62-
int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
6344
{
6445
/*
65-
* FIXME: interrupt.injected represents an interrupt that it's
46+
* FIXME: interrupt.injected represents an interrupt whose
6647
* side-effects have already been applied (e.g. bit from IRR
6748
* already moved to ISR). Therefore, it is incorrect to rely
6849
* on interrupt.injected to know if there is a pending
@@ -75,6 +56,23 @@ int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
7556
if (!lapic_in_kernel(v))
7657
return v->arch.interrupt.injected;
7758

59+
if (!kvm_apic_accept_pic_intr(v))
60+
return 0;
61+
62+
if (irqchip_split(v->kvm))
63+
return pending_userspace_extint(v);
64+
else
65+
return v->kvm->arch.vpic->output;
66+
}
67+
68+
/*
69+
* check if there is injectable interrupt:
70+
* when virtual interrupt delivery enabled,
71+
* interrupt from apic will handled by hardware,
72+
* we don't need to check it here.
73+
*/
74+
int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v)
75+
{
7876
if (kvm_cpu_has_extint(v))
7977
return 1;
8078

@@ -91,20 +89,6 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_injectable_intr);
9189
*/
9290
int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
9391
{
94-
/*
95-
* FIXME: interrupt.injected represents an interrupt that it's
96-
* side-effects have already been applied (e.g. bit from IRR
97-
* already moved to ISR). Therefore, it is incorrect to rely
98-
* on interrupt.injected to know if there is a pending
99-
* interrupt in the user-mode LAPIC.
100-
* This leads to nVMX/nSVM not be able to distinguish
101-
* if it should exit from L2 to L1 on EXTERNAL_INTERRUPT on
102-
* pending interrupt or should re-inject an injected
103-
* interrupt.
104-
*/
105-
if (!lapic_in_kernel(v))
106-
return v->arch.interrupt.injected;
107-
10892
if (kvm_cpu_has_extint(v))
10993
return 1;
11094

@@ -118,30 +102,29 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
118102
*/
119103
static int kvm_cpu_get_extint(struct kvm_vcpu *v)
120104
{
121-
if (kvm_cpu_has_extint(v)) {
122-
if (irqchip_split(v->kvm)) {
123-
int vector = v->arch.pending_external_vector;
124-
125-
v->arch.pending_external_vector = -1;
126-
return vector;
127-
} else
128-
return kvm_pic_read_irq(v->kvm); /* PIC */
129-
} else
105+
if (!kvm_cpu_has_extint(v)) {
106+
WARN_ON(!lapic_in_kernel(v));
130107
return -1;
108+
}
109+
110+
if (!lapic_in_kernel(v))
111+
return v->arch.interrupt.nr;
112+
113+
if (irqchip_split(v->kvm)) {
114+
int vector = v->arch.pending_external_vector;
115+
116+
v->arch.pending_external_vector = -1;
117+
return vector;
118+
} else
119+
return kvm_pic_read_irq(v->kvm); /* PIC */
131120
}
132121

133122
/*
134123
* Read pending interrupt vector and intack.
135124
*/
136125
int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
137126
{
138-
int vector;
139-
140-
if (!lapic_in_kernel(v))
141-
return v->arch.interrupt.nr;
142-
143-
vector = kvm_cpu_get_extint(v);
144-
127+
int vector = kvm_cpu_get_extint(v);
145128
if (vector != -1)
146129
return vector; /* PIC */
147130

arch/x86/kvm/lapic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2465,7 +2465,7 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
24652465
struct kvm_lapic *apic = vcpu->arch.apic;
24662466
u32 ppr;
24672467

2468-
if (!kvm_apic_hw_enabled(apic))
2468+
if (!kvm_apic_present(vcpu))
24692469
return -1;
24702470

24712471
__apic_update_ppr(apic, &ppr);

0 commit comments

Comments
 (0)