diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 77d8c0f4817d..2b2255b1f04b 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * Copyright (C) 2006 Qumranet, Inc. | 5 | * Copyright (C) 2006 Qumranet, Inc. |
6 | * Copyright (C) 2007 Novell | 6 | * Copyright (C) 2007 Novell |
7 | * Copyright (C) 2007 Intel | 7 | * Copyright (C) 2007 Intel |
8 | * Copyright 2009 Red Hat, Inc. and/or its affilates. | 8 | * Copyright 2009 Red Hat, Inc. and/or its affiliates. |
9 | * | 9 | * |
10 | * Authors: | 10 | * Authors: |
11 | * Dor Laor <dor.laor@qumranet.com> | 11 | * Dor Laor <dor.laor@qumranet.com> |
@@ -259,9 +259,10 @@ static inline int apic_find_highest_isr(struct kvm_lapic *apic) | |||
259 | 259 | ||
260 | static void apic_update_ppr(struct kvm_lapic *apic) | 260 | static void apic_update_ppr(struct kvm_lapic *apic) |
261 | { | 261 | { |
262 | u32 tpr, isrv, ppr; | 262 | u32 tpr, isrv, ppr, old_ppr; |
263 | int isr; | 263 | int isr; |
264 | 264 | ||
265 | old_ppr = apic_get_reg(apic, APIC_PROCPRI); | ||
265 | tpr = apic_get_reg(apic, APIC_TASKPRI); | 266 | tpr = apic_get_reg(apic, APIC_TASKPRI); |
266 | isr = apic_find_highest_isr(apic); | 267 | isr = apic_find_highest_isr(apic); |
267 | isrv = (isr != -1) ? isr : 0; | 268 | isrv = (isr != -1) ? isr : 0; |
@@ -274,7 +275,11 @@ static void apic_update_ppr(struct kvm_lapic *apic) | |||
274 | apic_debug("vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x", | 275 | apic_debug("vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x", |
275 | apic, ppr, isr, isrv); | 276 | apic, ppr, isr, isrv); |
276 | 277 | ||
277 | apic_set_reg(apic, APIC_PROCPRI, ppr); | 278 | if (old_ppr != ppr) { |
279 | apic_set_reg(apic, APIC_PROCPRI, ppr); | ||
280 | if (ppr < old_ppr) | ||
281 | kvm_make_request(KVM_REQ_EVENT, apic->vcpu); | ||
282 | } | ||
278 | } | 283 | } |
279 | 284 | ||
280 | static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) | 285 | static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr) |
@@ -391,6 +396,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
391 | break; | 396 | break; |
392 | } | 397 | } |
393 | 398 | ||
399 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
394 | kvm_vcpu_kick(vcpu); | 400 | kvm_vcpu_kick(vcpu); |
395 | break; | 401 | break; |
396 | 402 | ||
@@ -411,11 +417,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
411 | case APIC_DM_INIT: | 417 | case APIC_DM_INIT: |
412 | if (level) { | 418 | if (level) { |
413 | result = 1; | 419 | result = 1; |
414 | if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) | ||
415 | printk(KERN_DEBUG | ||
416 | "INIT on a runnable vcpu %d\n", | ||
417 | vcpu->vcpu_id); | ||
418 | vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; | 420 | vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; |
421 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
419 | kvm_vcpu_kick(vcpu); | 422 | kvm_vcpu_kick(vcpu); |
420 | } else { | 423 | } else { |
421 | apic_debug("Ignoring de-assert INIT to vcpu %d\n", | 424 | apic_debug("Ignoring de-assert INIT to vcpu %d\n", |
@@ -430,6 +433,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
430 | result = 1; | 433 | result = 1; |
431 | vcpu->arch.sipi_vector = vector; | 434 | vcpu->arch.sipi_vector = vector; |
432 | vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED; | 435 | vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED; |
436 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
433 | kvm_vcpu_kick(vcpu); | 437 | kvm_vcpu_kick(vcpu); |
434 | } | 438 | } |
435 | break; | 439 | break; |
@@ -475,6 +479,7 @@ static void apic_set_eoi(struct kvm_lapic *apic) | |||
475 | trigger_mode = IOAPIC_EDGE_TRIG; | 479 | trigger_mode = IOAPIC_EDGE_TRIG; |
476 | if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) | 480 | if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) |
477 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | 481 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); |
482 | kvm_make_request(KVM_REQ_EVENT, apic->vcpu); | ||
478 | } | 483 | } |
479 | 484 | ||
480 | static void apic_send_ipi(struct kvm_lapic *apic) | 485 | static void apic_send_ipi(struct kvm_lapic *apic) |
@@ -866,8 +871,8 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu) | |||
866 | 871 | ||
867 | hrtimer_cancel(&vcpu->arch.apic->lapic_timer.timer); | 872 | hrtimer_cancel(&vcpu->arch.apic->lapic_timer.timer); |
868 | 873 | ||
869 | if (vcpu->arch.apic->regs_page) | 874 | if (vcpu->arch.apic->regs) |
870 | __free_page(vcpu->arch.apic->regs_page); | 875 | free_page((unsigned long)vcpu->arch.apic->regs); |
871 | 876 | ||
872 | kfree(vcpu->arch.apic); | 877 | kfree(vcpu->arch.apic); |
873 | } | 878 | } |
@@ -1056,14 +1061,12 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) | |||
1056 | 1061 | ||
1057 | vcpu->arch.apic = apic; | 1062 | vcpu->arch.apic = apic; |
1058 | 1063 | ||
1059 | apic->regs_page = alloc_page(GFP_KERNEL); | 1064 | apic->regs = (void *)get_zeroed_page(GFP_KERNEL); |
1060 | if (apic->regs_page == NULL) { | 1065 | if (!apic->regs) { |
1061 | printk(KERN_ERR "malloc apic regs error for vcpu %x\n", | 1066 | printk(KERN_ERR "malloc apic regs error for vcpu %x\n", |
1062 | vcpu->vcpu_id); | 1067 | vcpu->vcpu_id); |
1063 | goto nomem_free_apic; | 1068 | goto nomem_free_apic; |
1064 | } | 1069 | } |
1065 | apic->regs = page_address(apic->regs_page); | ||
1066 | memset(apic->regs, 0, PAGE_SIZE); | ||
1067 | apic->vcpu = vcpu; | 1070 | apic->vcpu = vcpu; |
1068 | 1071 | ||
1069 | hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC, | 1072 | hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC, |
@@ -1152,6 +1155,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) | |||
1152 | update_divide_count(apic); | 1155 | update_divide_count(apic); |
1153 | start_apic_timer(apic); | 1156 | start_apic_timer(apic); |
1154 | apic->irr_pending = true; | 1157 | apic->irr_pending = true; |
1158 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
1155 | } | 1159 | } |
1156 | 1160 | ||
1157 | void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) | 1161 | void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) |