mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
KVM: APIC: kvm_apic_set_irq deliver all kinds of interrupts
Get rid of ioapic_inj_irq() and ioapic_inj_nmi() functions. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
parent
f5a1e9f895
commit
6da7e3f643
@ -585,7 +585,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu);
|
||||
int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
|
||||
void kvm_sal_emul(struct kvm_vcpu *vcpu);
|
||||
|
||||
static inline void kvm_inject_nmi(struct kvm_vcpu *vcpu) {}
|
||||
#endif /* __ASSEMBLY__*/
|
||||
|
||||
#endif
|
||||
|
@ -292,13 +292,13 @@ static void vcpu_deliver_ipi(struct kvm_vcpu *vcpu, uint64_t dm,
|
||||
{
|
||||
switch (dm) {
|
||||
case SAPIC_FIXED:
|
||||
kvm_apic_set_irq(vcpu, vector, 0);
|
||||
kvm_apic_set_irq(vcpu, vector, dm, 0);
|
||||
break;
|
||||
case SAPIC_NMI:
|
||||
kvm_apic_set_irq(vcpu, 2, 0);
|
||||
kvm_apic_set_irq(vcpu, 2, dm, 0);
|
||||
break;
|
||||
case SAPIC_EXTINT:
|
||||
kvm_apic_set_irq(vcpu, 0, 0);
|
||||
kvm_apic_set_irq(vcpu, 0, dm, 0);
|
||||
break;
|
||||
case SAPIC_INIT:
|
||||
case SAPIC_PMI:
|
||||
@ -1813,7 +1813,7 @@ void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig)
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig)
|
||||
{
|
||||
|
||||
struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);
|
||||
|
@ -20,6 +20,6 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
|
||||
int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig);
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig);
|
||||
|
||||
#endif
|
||||
|
@ -196,20 +196,30 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr);
|
||||
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig)
|
||||
static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
|
||||
int vector, int level, int trig_mode);
|
||||
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig)
|
||||
{
|
||||
struct kvm_lapic *apic = vcpu->arch.apic;
|
||||
int lapic_dmode;
|
||||
|
||||
if (!apic_test_and_set_irr(vec, apic)) {
|
||||
/* a new pending irq is set in IRR */
|
||||
if (trig)
|
||||
apic_set_vector(vec, apic->regs + APIC_TMR);
|
||||
else
|
||||
apic_clear_vector(vec, apic->regs + APIC_TMR);
|
||||
kvm_vcpu_kick(apic->vcpu);
|
||||
return 1;
|
||||
}
|
||||
switch (dmode) {
|
||||
case IOAPIC_LOWEST_PRIORITY:
|
||||
lapic_dmode = APIC_DM_LOWEST;
|
||||
break;
|
||||
case IOAPIC_FIXED:
|
||||
lapic_dmode = APIC_DM_FIXED;
|
||||
break;
|
||||
case IOAPIC_NMI:
|
||||
lapic_dmode = APIC_DM_NMI;
|
||||
break;
|
||||
default:
|
||||
printk(KERN_DEBUG"Ignoring delivery mode %d\n", dmode);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return __apic_accept_irq(apic, lapic_dmode, vec, 1, trig);
|
||||
}
|
||||
|
||||
static inline int apic_find_highest_isr(struct kvm_lapic *apic)
|
||||
@ -327,7 +337,7 @@ static int apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
|
||||
static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
|
||||
int vector, int level, int trig_mode)
|
||||
{
|
||||
int orig_irr, result = 0;
|
||||
int result = 0;
|
||||
struct kvm_vcpu *vcpu = apic->vcpu;
|
||||
|
||||
switch (delivery_mode) {
|
||||
@ -337,10 +347,11 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
|
||||
if (unlikely(!apic_enabled(apic)))
|
||||
break;
|
||||
|
||||
orig_irr = apic_test_and_set_irr(vector, apic);
|
||||
if (orig_irr && trig_mode) {
|
||||
apic_debug("level trig mode repeatedly for vector %d",
|
||||
vector);
|
||||
result = !apic_test_and_set_irr(vector, apic);
|
||||
if (!result) {
|
||||
if (trig_mode)
|
||||
apic_debug("level trig mode repeatedly for "
|
||||
"vector %d", vector);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -349,10 +360,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
|
||||
apic_set_vector(vector, apic->regs + APIC_TMR);
|
||||
} else
|
||||
apic_clear_vector(vector, apic->regs + APIC_TMR);
|
||||
|
||||
kvm_vcpu_kick(vcpu);
|
||||
|
||||
result = (orig_irr == 0);
|
||||
break;
|
||||
|
||||
case APIC_DM_REMRD:
|
||||
@ -364,12 +372,14 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
|
||||
break;
|
||||
|
||||
case APIC_DM_NMI:
|
||||
result = 1;
|
||||
kvm_inject_nmi(vcpu);
|
||||
kvm_vcpu_kick(vcpu);
|
||||
break;
|
||||
|
||||
case APIC_DM_INIT:
|
||||
if (level) {
|
||||
result = 1;
|
||||
if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
|
||||
printk(KERN_DEBUG
|
||||
"INIT on a runnable vcpu %d\n",
|
||||
@ -386,6 +396,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
|
||||
apic_debug("SIPI to vcpu %d vector 0x%02x\n",
|
||||
vcpu->vcpu_id, vector);
|
||||
if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
|
||||
result = 1;
|
||||
vcpu->arch.sipi_vector = vector;
|
||||
vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED;
|
||||
kvm_vcpu_kick(vcpu);
|
||||
|
@ -31,7 +31,7 @@ u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu);
|
||||
|
||||
int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest);
|
||||
int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda);
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig);
|
||||
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 dmode, u8 trig);
|
||||
|
||||
u64 kvm_get_apic_base(struct kvm_vcpu *vcpu);
|
||||
void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data);
|
||||
|
@ -142,25 +142,6 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
|
||||
}
|
||||
}
|
||||
|
||||
static int ioapic_inj_irq(struct kvm_ioapic *ioapic,
|
||||
struct kvm_vcpu *vcpu,
|
||||
u8 vector, u8 trig_mode, u8 delivery_mode)
|
||||
{
|
||||
ioapic_debug("irq %d trig %d deliv %d\n", vector, trig_mode,
|
||||
delivery_mode);
|
||||
|
||||
ASSERT((delivery_mode == IOAPIC_FIXED) ||
|
||||
(delivery_mode == IOAPIC_LOWEST_PRIORITY));
|
||||
|
||||
return kvm_apic_set_irq(vcpu, vector, trig_mode);
|
||||
}
|
||||
|
||||
static void ioapic_inj_nmi(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
kvm_inject_nmi(vcpu);
|
||||
kvm_vcpu_kick(vcpu);
|
||||
}
|
||||
|
||||
static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
|
||||
{
|
||||
union kvm_ioapic_redirect_entry entry = ioapic->redirtbl[irq];
|
||||
@ -193,21 +174,12 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq)
|
||||
__clear_bit(vcpu_id, deliver_bitmask);
|
||||
vcpu = ioapic->kvm->vcpus[vcpu_id];
|
||||
if (vcpu) {
|
||||
if (entry.fields.delivery_mode ==
|
||||
IOAPIC_LOWEST_PRIORITY ||
|
||||
entry.fields.delivery_mode == IOAPIC_FIXED) {
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
r += ioapic_inj_irq(ioapic, vcpu,
|
||||
r += kvm_apic_set_irq(vcpu,
|
||||
entry.fields.vector,
|
||||
entry.fields.trig_mode,
|
||||
entry.fields.delivery_mode);
|
||||
} else if (entry.fields.delivery_mode == IOAPIC_NMI) {
|
||||
r = 1;
|
||||
ioapic_inj_nmi(vcpu);
|
||||
} else
|
||||
ioapic_debug("unsupported delivery mode %x!\n",
|
||||
entry.fields.delivery_mode);
|
||||
} else
|
||||
ioapic_debug("null destination vcpu: "
|
||||
"mask=%x vector=%x delivery_mode=%x\n",
|
||||
|
@ -148,6 +148,7 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
r += kvm_apic_set_irq(vcpu, entry.fields.vector,
|
||||
entry.fields.dest_mode,
|
||||
entry.fields.trig_mode);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user