]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kvm/lapic.c
KVM: MMU: do not write-protect large mappings
[linux-2.6-omap-h63xx.git] / arch / x86 / kvm / lapic.c
index ebc03f5ae162e2702974c122e27a580fa6556ac2..fd00f698692f2311a7933f654ce24989296bbcfb 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/current.h>
 #include <asm/apicdef.h>
 #include <asm/atomic.h>
+#include "kvm_cache_regs.h"
 #include "irq.h"
 
 #define PRId64 "d"
@@ -338,13 +339,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
                } else
                        apic_clear_vector(vector, apic->regs + APIC_TMR);
 
-               if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
-                       kvm_vcpu_kick(vcpu);
-               else if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) {
-                       vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
-                       if (waitqueue_active(&vcpu->wq))
-                               wake_up_interruptible(&vcpu->wq);
-               }
+               kvm_vcpu_kick(vcpu);
 
                result = (orig_irr == 0);
                break;
@@ -356,8 +351,9 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
        case APIC_DM_SMI:
                printk(KERN_DEBUG "Ignoring guest SMI\n");
                break;
+
        case APIC_DM_NMI:
-               printk(KERN_DEBUG "Ignoring guest NMI\n");
+               kvm_inject_nmi(vcpu);
                break;
 
        case APIC_DM_INIT:
@@ -382,8 +378,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
                if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
                        vcpu->arch.sipi_vector = vector;
                        vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED;
-                       if (waitqueue_active(&vcpu->wq))
-                               wake_up_interruptible(&vcpu->wq);
+                       kvm_vcpu_kick(vcpu);
                }
                break;
 
@@ -437,7 +432,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
 static void apic_set_eoi(struct kvm_lapic *apic)
 {
        int vector = apic_find_highest_isr(apic);
-
+       int trigger_mode;
        /*
         * Not every write EOI will has corresponding ISR,
         * one example is when Kernel check timer on setup_IO_APIC
@@ -449,7 +444,10 @@ static void apic_set_eoi(struct kvm_lapic *apic)
        apic_update_ppr(apic);
 
        if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR))
-               kvm_ioapic_update_eoi(apic->vcpu->kvm, vector);
+               trigger_mode = IOAPIC_LEVEL_TRIG;
+       else
+               trigger_mode = IOAPIC_EDGE_TRIG;
+       kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
 }
 
 static void apic_send_ipi(struct kvm_lapic *apic)
@@ -557,8 +555,7 @@ static void __report_tpr_access(struct kvm_lapic *apic, bool write)
        struct kvm_run *run = vcpu->run;
 
        set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests);
-       kvm_x86_ops->cache_regs(vcpu);
-       run->tpr_access.rip = vcpu->arch.rip;
+       run->tpr_access.rip = kvm_rip_read(vcpu);
        run->tpr_access.is_write = write;
 }
 
@@ -572,6 +569,8 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
 {
        u32 val = 0;
 
+       KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler);
+
        if (offset >= LAPIC_MMIO_LENGTH)
                return 0;
 
@@ -695,6 +694,8 @@ static void apic_mmio_write(struct kvm_io_device *this,
 
        offset &= 0xff0;
 
+       KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler);
+
        switch (offset) {
        case APIC_ID:           /* Local APIC ID */
                apic_set_reg(apic, APIC_ID, val);
@@ -780,7 +781,8 @@ static void apic_mmio_write(struct kvm_io_device *this,
 
 }
 
-static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr)
+static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr,
+                          int len, int size)
 {
        struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
        int ret = 0;
@@ -939,12 +941,11 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
        int result = 0;
        wait_queue_head_t *q = &apic->vcpu->wq;
 
-       atomic_inc(&apic->timer.pending);
-       set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
-       if (waitqueue_active(q)) {
-               apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+       if(!atomic_inc_and_test(&apic->timer.pending))
+               set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
+       if (waitqueue_active(q))
                wake_up_interruptible(q);
-       }
+
        if (apic_lvtt_period(apic)) {
                result = 1;
                apic->timer.dev.expires = ktime_add_ns(