diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2008-10-20 04:20:02 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:51:46 -0500 |
commit | 8fdb2351d51b040146f10a624387bbd102d851c0 (patch) | |
tree | c28ff5ec61f51cb1a04b7e29923e4ce3f2aba421 /arch/x86/kvm/lapic.c | |
parent | 291fd39bfc2089c2dae79cf2d7cfca81b14ca769 (diff) |
KVM: x86: Fix and refactor NMI watchdog emulation
This patch refactors the NMI watchdog delivery patch, consolidating
tests and providing a proper API for delivering watchdog events.
An included micro-optimization is to check only for apic_hw_enabled in
kvm_apic_local_deliver (the test for LVT mask is covering the
soft-disabled case already).
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Acked-by: Sheng Yang <sheng@linux.intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 304f9ddbdd51..0b0d413f0af5 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -973,14 +973,12 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu) | |||
973 | return 0; | 973 | return 0; |
974 | } | 974 | } |
975 | 975 | ||
976 | int kvm_apic_local_deliver(struct kvm_vcpu *vcpu, int lvt_type) | 976 | static int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) |
977 | { | 977 | { |
978 | struct kvm_lapic *apic = vcpu->arch.apic; | 978 | u32 reg = apic_get_reg(apic, lvt_type); |
979 | int vector, mode, trig_mode; | 979 | int vector, mode, trig_mode; |
980 | u32 reg; | ||
981 | 980 | ||
982 | if (apic && apic_enabled(apic)) { | 981 | if (apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) { |
983 | reg = apic_get_reg(apic, lvt_type); | ||
984 | vector = reg & APIC_VECTOR_MASK; | 982 | vector = reg & APIC_VECTOR_MASK; |
985 | mode = reg & APIC_MODE_MASK; | 983 | mode = reg & APIC_MODE_MASK; |
986 | trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; | 984 | trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; |
@@ -989,9 +987,12 @@ int kvm_apic_local_deliver(struct kvm_vcpu *vcpu, int lvt_type) | |||
989 | return 0; | 987 | return 0; |
990 | } | 988 | } |
991 | 989 | ||
992 | static inline int __inject_apic_timer_irq(struct kvm_lapic *apic) | 990 | void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu) |
993 | { | 991 | { |
994 | return kvm_apic_local_deliver(apic->vcpu, APIC_LVTT); | 992 | struct kvm_lapic *apic = vcpu->arch.apic; |
993 | |||
994 | if (apic) | ||
995 | kvm_apic_local_deliver(apic, APIC_LVT0); | ||
995 | } | 996 | } |
996 | 997 | ||
997 | static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) | 998 | static enum hrtimer_restart apic_timer_fn(struct hrtimer *data) |
@@ -1086,9 +1087,8 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) | |||
1086 | { | 1087 | { |
1087 | struct kvm_lapic *apic = vcpu->arch.apic; | 1088 | struct kvm_lapic *apic = vcpu->arch.apic; |
1088 | 1089 | ||
1089 | if (apic && apic_lvt_enabled(apic, APIC_LVTT) && | 1090 | if (apic && atomic_read(&apic->timer.pending) > 0) { |
1090 | atomic_read(&apic->timer.pending) > 0) { | 1091 | if (kvm_apic_local_deliver(apic, APIC_LVTT)) |
1091 | if (__inject_apic_timer_irq(apic)) | ||
1092 | atomic_dec(&apic->timer.pending); | 1092 | atomic_dec(&apic->timer.pending); |
1093 | } | 1093 | } |
1094 | } | 1094 | } |