diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-06 08:23:39 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-06 08:23:39 -0400 |
commit | 68083e05d72d94f347293d8cc0067050ba904bfa (patch) | |
tree | 842e71365bd90866be7add181661a4039d891564 /virt | |
parent | 7baac8b91f9871ba8cb09af84de4ae1d86d07812 (diff) | |
parent | b7279469d66b55119784b8b9529c99c1955fe747 (diff) |
Merge commit 'v2.6.26-rc9' into cpus4096
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/ioapic.c | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index 4232fd75dd20..1dcf9f3d1107 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #else | 45 | #else |
46 | #define ioapic_debug(fmt, arg...) | 46 | #define ioapic_debug(fmt, arg...) |
47 | #endif | 47 | #endif |
48 | static void ioapic_deliver(struct kvm_ioapic *vioapic, int irq); | 48 | static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq); |
49 | 49 | ||
50 | static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, | 50 | static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, |
51 | unsigned long addr, | 51 | unsigned long addr, |
@@ -89,8 +89,8 @@ static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) | |||
89 | pent = &ioapic->redirtbl[idx]; | 89 | pent = &ioapic->redirtbl[idx]; |
90 | 90 | ||
91 | if (!pent->fields.mask) { | 91 | if (!pent->fields.mask) { |
92 | ioapic_deliver(ioapic, idx); | 92 | int injected = ioapic_deliver(ioapic, idx); |
93 | if (pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) | 93 | if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) |
94 | pent->fields.remote_irr = 1; | 94 | pent->fields.remote_irr = 1; |
95 | } | 95 | } |
96 | if (!pent->fields.trig_mode) | 96 | if (!pent->fields.trig_mode) |
@@ -133,7 +133,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) | |||
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | static void ioapic_inj_irq(struct kvm_ioapic *ioapic, | 136 | static int ioapic_inj_irq(struct kvm_ioapic *ioapic, |
137 | struct kvm_vcpu *vcpu, | 137 | struct kvm_vcpu *vcpu, |
138 | u8 vector, u8 trig_mode, u8 delivery_mode) | 138 | u8 vector, u8 trig_mode, u8 delivery_mode) |
139 | { | 139 | { |
@@ -143,7 +143,7 @@ static void ioapic_inj_irq(struct kvm_ioapic *ioapic, | |||
143 | ASSERT((delivery_mode == IOAPIC_FIXED) || | 143 | ASSERT((delivery_mode == IOAPIC_FIXED) || |
144 | (delivery_mode == IOAPIC_LOWEST_PRIORITY)); | 144 | (delivery_mode == IOAPIC_LOWEST_PRIORITY)); |
145 | 145 | ||
146 | kvm_apic_set_irq(vcpu, vector, trig_mode); | 146 | return kvm_apic_set_irq(vcpu, vector, trig_mode); |
147 | } | 147 | } |
148 | 148 | ||
149 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | 149 | static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, |
@@ -186,7 +186,7 @@ static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, | |||
186 | return mask; | 186 | return mask; |
187 | } | 187 | } |
188 | 188 | ||
189 | static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | 189 | static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) |
190 | { | 190 | { |
191 | u8 dest = ioapic->redirtbl[irq].fields.dest_id; | 191 | u8 dest = ioapic->redirtbl[irq].fields.dest_id; |
192 | u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode; | 192 | u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode; |
@@ -195,7 +195,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
195 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; | 195 | u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; |
196 | u32 deliver_bitmask; | 196 | u32 deliver_bitmask; |
197 | struct kvm_vcpu *vcpu; | 197 | struct kvm_vcpu *vcpu; |
198 | int vcpu_id; | 198 | int vcpu_id, r = 0; |
199 | 199 | ||
200 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " | 200 | ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " |
201 | "vector=%x trig_mode=%x\n", | 201 | "vector=%x trig_mode=%x\n", |
@@ -204,7 +204,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
204 | deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode); | 204 | deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode); |
205 | if (!deliver_bitmask) { | 205 | if (!deliver_bitmask) { |
206 | ioapic_debug("no target on destination\n"); | 206 | ioapic_debug("no target on destination\n"); |
207 | return; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | switch (delivery_mode) { | 210 | switch (delivery_mode) { |
@@ -216,7 +216,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
216 | vcpu = ioapic->kvm->vcpus[0]; | 216 | vcpu = ioapic->kvm->vcpus[0]; |
217 | #endif | 217 | #endif |
218 | if (vcpu != NULL) | 218 | if (vcpu != NULL) |
219 | ioapic_inj_irq(ioapic, vcpu, vector, | 219 | r = ioapic_inj_irq(ioapic, vcpu, vector, |
220 | trig_mode, delivery_mode); | 220 | trig_mode, delivery_mode); |
221 | else | 221 | else |
222 | ioapic_debug("null lowest prio vcpu: " | 222 | ioapic_debug("null lowest prio vcpu: " |
@@ -234,7 +234,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
234 | deliver_bitmask &= ~(1 << vcpu_id); | 234 | deliver_bitmask &= ~(1 << vcpu_id); |
235 | vcpu = ioapic->kvm->vcpus[vcpu_id]; | 235 | vcpu = ioapic->kvm->vcpus[vcpu_id]; |
236 | if (vcpu) { | 236 | if (vcpu) { |
237 | ioapic_inj_irq(ioapic, vcpu, vector, | 237 | r = ioapic_inj_irq(ioapic, vcpu, vector, |
238 | trig_mode, delivery_mode); | 238 | trig_mode, delivery_mode); |
239 | } | 239 | } |
240 | } | 240 | } |
@@ -246,6 +246,7 @@ static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) | |||
246 | delivery_mode); | 246 | delivery_mode); |
247 | break; | 247 | break; |
248 | } | 248 | } |
249 | return r; | ||
249 | } | 250 | } |
250 | 251 | ||
251 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | 252 | void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) |
@@ -268,28 +269,9 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) | |||
268 | } | 269 | } |
269 | } | 270 | } |
270 | 271 | ||
271 | static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector) | 272 | static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi) |
272 | { | 273 | { |
273 | int i; | ||
274 | |||
275 | for (i = 0; i < IOAPIC_NUM_PINS; i++) | ||
276 | if (ioapic->redirtbl[i].fields.vector == vector) | ||
277 | return i; | ||
278 | return -1; | ||
279 | } | ||
280 | |||
281 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) | ||
282 | { | ||
283 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | ||
284 | union ioapic_redir_entry *ent; | 274 | union ioapic_redir_entry *ent; |
285 | int gsi; | ||
286 | |||
287 | gsi = get_eoi_gsi(ioapic, vector); | ||
288 | if (gsi == -1) { | ||
289 | printk(KERN_WARNING "Can't find redir item for %d EOI\n", | ||
290 | vector); | ||
291 | return; | ||
292 | } | ||
293 | 275 | ||
294 | ent = &ioapic->redirtbl[gsi]; | 276 | ent = &ioapic->redirtbl[gsi]; |
295 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); | 277 | ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG); |
@@ -299,6 +281,16 @@ void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) | |||
299 | ioapic_deliver(ioapic, gsi); | 281 | ioapic_deliver(ioapic, gsi); |
300 | } | 282 | } |
301 | 283 | ||
284 | void kvm_ioapic_update_eoi(struct kvm *kvm, int vector) | ||
285 | { | ||
286 | struct kvm_ioapic *ioapic = kvm->arch.vioapic; | ||
287 | int i; | ||
288 | |||
289 | for (i = 0; i < IOAPIC_NUM_PINS; i++) | ||
290 | if (ioapic->redirtbl[i].fields.vector == vector) | ||
291 | __kvm_ioapic_update_eoi(ioapic, i); | ||
292 | } | ||
293 | |||
302 | static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr) | 294 | static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr) |
303 | { | 295 | { |
304 | struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private; | 296 | struct kvm_ioapic *ioapic = (struct kvm_ioapic *)this->private; |