aboutsummaryrefslogtreecommitdiffstats
path: root/virt
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-18 13:53:16 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-18 13:53:16 -0400
commit9b610fda0df5d0f0b0c64242e37441ad1b384aac (patch)
tree0ea14b15f2e6546f37fe18d8ac3dc83077ec0e55 /virt
parentb8f8c3cf0a4ac0632ec3f0e15e9dc0c29de917af (diff)
parent5b664cb235e97afbf34db9c4d77f08ebd725335e (diff)
Merge branch 'linus' into timers/nohz
Diffstat (limited to 'virt')
-rw-r--r--virt/kvm/ioapic.c54
-rw-r--r--virt/kvm/kvm_main.c14
2 files changed, 30 insertions, 38 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index 4232fd75dd2..44589088941 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
48static void ioapic_deliver(struct kvm_ioapic *vioapic, int irq); 48static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq);
49 49
50static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, 50static 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
136static void ioapic_inj_irq(struct kvm_ioapic *ioapic, 136static 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
149static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, 149static 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
189static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) 189static 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
251void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level) 252void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
@@ -268,35 +269,26 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
268 } 269 }
269} 270}
270 271
271static int get_eoi_gsi(struct kvm_ioapic *ioapic, int vector) 272static 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
281void 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);
296 278
297 ent->fields.remote_irr = 0; 279 ent->fields.remote_irr = 0;
298 if (!ent->fields.mask && (ioapic->irr & (1 << gsi))) 280 if (!ent->fields.mask && (ioapic->irr & (1 << gsi)))
299 ioapic_deliver(ioapic, gsi); 281 ioapic_service(ioapic, gsi);
282}
283
284void 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);
300} 292}
301 293
302static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr) 294static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 2d29e260da3..d4eae6af073 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1266,12 +1266,12 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
1266 case CPU_UP_CANCELED: 1266 case CPU_UP_CANCELED:
1267 printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", 1267 printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n",
1268 cpu); 1268 cpu);
1269 smp_call_function_single(cpu, hardware_disable, NULL, 0, 1); 1269 smp_call_function_single(cpu, hardware_disable, NULL, 1);
1270 break; 1270 break;
1271 case CPU_ONLINE: 1271 case CPU_ONLINE:
1272 printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", 1272 printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n",
1273 cpu); 1273 cpu);
1274 smp_call_function_single(cpu, hardware_enable, NULL, 0, 1); 1274 smp_call_function_single(cpu, hardware_enable, NULL, 1);
1275 break; 1275 break;
1276 } 1276 }
1277 return NOTIFY_OK; 1277 return NOTIFY_OK;
@@ -1286,7 +1286,7 @@ static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
1286 * in vmx root mode. 1286 * in vmx root mode.
1287 */ 1287 */
1288 printk(KERN_INFO "kvm: exiting hardware virtualization\n"); 1288 printk(KERN_INFO "kvm: exiting hardware virtualization\n");
1289 on_each_cpu(hardware_disable, NULL, 0, 1); 1289 on_each_cpu(hardware_disable, NULL, 1);
1290 } 1290 }
1291 return NOTIFY_OK; 1291 return NOTIFY_OK;
1292} 1292}
@@ -1474,12 +1474,12 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
1474 for_each_online_cpu(cpu) { 1474 for_each_online_cpu(cpu) {
1475 smp_call_function_single(cpu, 1475 smp_call_function_single(cpu,
1476 kvm_arch_check_processor_compat, 1476 kvm_arch_check_processor_compat,
1477 &r, 0, 1); 1477 &r, 1);
1478 if (r < 0) 1478 if (r < 0)
1479 goto out_free_1; 1479 goto out_free_1;
1480 } 1480 }
1481 1481
1482 on_each_cpu(hardware_enable, NULL, 0, 1); 1482 on_each_cpu(hardware_enable, NULL, 1);
1483 r = register_cpu_notifier(&kvm_cpu_notifier); 1483 r = register_cpu_notifier(&kvm_cpu_notifier);
1484 if (r) 1484 if (r)
1485 goto out_free_2; 1485 goto out_free_2;
@@ -1525,7 +1525,7 @@ out_free_3:
1525 unregister_reboot_notifier(&kvm_reboot_notifier); 1525 unregister_reboot_notifier(&kvm_reboot_notifier);
1526 unregister_cpu_notifier(&kvm_cpu_notifier); 1526 unregister_cpu_notifier(&kvm_cpu_notifier);
1527out_free_2: 1527out_free_2:
1528 on_each_cpu(hardware_disable, NULL, 0, 1); 1528 on_each_cpu(hardware_disable, NULL, 1);
1529out_free_1: 1529out_free_1:
1530 kvm_arch_hardware_unsetup(); 1530 kvm_arch_hardware_unsetup();
1531out_free_0: 1531out_free_0:
@@ -1547,7 +1547,7 @@ void kvm_exit(void)
1547 sysdev_class_unregister(&kvm_sysdev_class); 1547 sysdev_class_unregister(&kvm_sysdev_class);
1548 unregister_reboot_notifier(&kvm_reboot_notifier); 1548 unregister_reboot_notifier(&kvm_reboot_notifier);
1549 unregister_cpu_notifier(&kvm_cpu_notifier); 1549 unregister_cpu_notifier(&kvm_cpu_notifier);
1550 on_each_cpu(hardware_disable, NULL, 0, 1); 1550 on_each_cpu(hardware_disable, NULL, 1);
1551 kvm_arch_hardware_unsetup(); 1551 kvm_arch_hardware_unsetup();
1552 kvm_arch_exit(); 1552 kvm_arch_exit();
1553 kvm_exit_debug(); 1553 kvm_exit_debug();