diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
| -rw-r--r-- | arch/x86/kvm/lapic.c | 43 |
1 files changed, 18 insertions, 25 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 73f43de69f67..6571926bfd33 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <asm/current.h> | 32 | #include <asm/current.h> |
| 33 | #include <asm/apicdef.h> | 33 | #include <asm/apicdef.h> |
| 34 | #include <asm/atomic.h> | 34 | #include <asm/atomic.h> |
| 35 | #include "kvm_cache_regs.h" | ||
| 35 | #include "irq.h" | 36 | #include "irq.h" |
| 36 | 37 | ||
| 37 | #define PRId64 "d" | 38 | #define PRId64 "d" |
| @@ -338,13 +339,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
| 338 | } else | 339 | } else |
| 339 | apic_clear_vector(vector, apic->regs + APIC_TMR); | 340 | apic_clear_vector(vector, apic->regs + APIC_TMR); |
| 340 | 341 | ||
| 341 | if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) | 342 | kvm_vcpu_kick(vcpu); |
| 342 | kvm_vcpu_kick(vcpu); | ||
| 343 | else if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) { | ||
| 344 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | ||
| 345 | if (waitqueue_active(&vcpu->wq)) | ||
| 346 | wake_up_interruptible(&vcpu->wq); | ||
| 347 | } | ||
| 348 | 343 | ||
| 349 | result = (orig_irr == 0); | 344 | result = (orig_irr == 0); |
| 350 | break; | 345 | break; |
| @@ -370,21 +365,18 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
| 370 | vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; | 365 | vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED; |
| 371 | kvm_vcpu_kick(vcpu); | 366 | kvm_vcpu_kick(vcpu); |
| 372 | } else { | 367 | } else { |
| 373 | printk(KERN_DEBUG | 368 | apic_debug("Ignoring de-assert INIT to vcpu %d\n", |
| 374 | "Ignoring de-assert INIT to vcpu %d\n", | 369 | vcpu->vcpu_id); |
| 375 | vcpu->vcpu_id); | ||
| 376 | } | 370 | } |
| 377 | |||
| 378 | break; | 371 | break; |
| 379 | 372 | ||
| 380 | case APIC_DM_STARTUP: | 373 | case APIC_DM_STARTUP: |
| 381 | printk(KERN_DEBUG "SIPI to vcpu %d vector 0x%02x\n", | 374 | apic_debug("SIPI to vcpu %d vector 0x%02x\n", |
| 382 | vcpu->vcpu_id, vector); | 375 | vcpu->vcpu_id, vector); |
| 383 | if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) { | 376 | if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) { |
| 384 | vcpu->arch.sipi_vector = vector; | 377 | vcpu->arch.sipi_vector = vector; |
| 385 | vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED; | 378 | vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED; |
| 386 | if (waitqueue_active(&vcpu->wq)) | 379 | kvm_vcpu_kick(vcpu); |
| 387 | wake_up_interruptible(&vcpu->wq); | ||
| 388 | } | 380 | } |
| 389 | break; | 381 | break; |
| 390 | 382 | ||
| @@ -438,7 +430,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector, | |||
| 438 | static void apic_set_eoi(struct kvm_lapic *apic) | 430 | static void apic_set_eoi(struct kvm_lapic *apic) |
| 439 | { | 431 | { |
| 440 | int vector = apic_find_highest_isr(apic); | 432 | int vector = apic_find_highest_isr(apic); |
| 441 | 433 | int trigger_mode; | |
| 442 | /* | 434 | /* |
| 443 | * Not every write EOI will has corresponding ISR, | 435 | * Not every write EOI will has corresponding ISR, |
| 444 | * one example is when Kernel check timer on setup_IO_APIC | 436 | * one example is when Kernel check timer on setup_IO_APIC |
| @@ -450,7 +442,10 @@ static void apic_set_eoi(struct kvm_lapic *apic) | |||
| 450 | apic_update_ppr(apic); | 442 | apic_update_ppr(apic); |
| 451 | 443 | ||
| 452 | if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR)) | 444 | if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR)) |
| 453 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector); | 445 | trigger_mode = IOAPIC_LEVEL_TRIG; |
| 446 | else | ||
| 447 | trigger_mode = IOAPIC_EDGE_TRIG; | ||
| 448 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | ||
| 454 | } | 449 | } |
| 455 | 450 | ||
| 456 | static void apic_send_ipi(struct kvm_lapic *apic) | 451 | static void apic_send_ipi(struct kvm_lapic *apic) |
| @@ -558,8 +553,7 @@ static void __report_tpr_access(struct kvm_lapic *apic, bool write) | |||
| 558 | struct kvm_run *run = vcpu->run; | 553 | struct kvm_run *run = vcpu->run; |
| 559 | 554 | ||
| 560 | set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests); | 555 | set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests); |
| 561 | kvm_x86_ops->cache_regs(vcpu); | 556 | run->tpr_access.rip = kvm_rip_read(vcpu); |
| 562 | run->tpr_access.rip = vcpu->arch.rip; | ||
| 563 | run->tpr_access.is_write = write; | 557 | run->tpr_access.is_write = write; |
| 564 | } | 558 | } |
| 565 | 559 | ||
| @@ -683,9 +677,9 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
| 683 | * Refer SDM 8.4.1 | 677 | * Refer SDM 8.4.1 |
| 684 | */ | 678 | */ |
| 685 | if (len != 4 || alignment) { | 679 | if (len != 4 || alignment) { |
| 686 | if (printk_ratelimit()) | 680 | /* Don't shout loud, $infamous_os would cause only noise. */ |
| 687 | printk(KERN_ERR "apic write: bad size=%d %lx\n", | 681 | apic_debug("apic write: bad size=%d %lx\n", |
| 688 | len, (long)address); | 682 | len, (long)address); |
| 689 | return; | 683 | return; |
| 690 | } | 684 | } |
| 691 | 685 | ||
| @@ -947,10 +941,9 @@ static int __apic_timer_fn(struct kvm_lapic *apic) | |||
| 947 | 941 | ||
| 948 | if(!atomic_inc_and_test(&apic->timer.pending)) | 942 | if(!atomic_inc_and_test(&apic->timer.pending)) |
| 949 | set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests); | 943 | set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests); |
| 950 | if (waitqueue_active(q)) { | 944 | if (waitqueue_active(q)) |
| 951 | apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | ||
| 952 | wake_up_interruptible(q); | 945 | wake_up_interruptible(q); |
| 953 | } | 946 | |
| 954 | if (apic_lvtt_period(apic)) { | 947 | if (apic_lvtt_period(apic)) { |
| 955 | result = 1; | 948 | result = 1; |
| 956 | apic->timer.dev.expires = ktime_add_ns( | 949 | apic->timer.dev.expires = ktime_add_ns( |
