diff options
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r-- | drivers/kvm/kvm_main.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index f879efbefcdf..401e3cdc4607 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -281,6 +281,7 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_init); | |||
281 | void kvm_vcpu_uninit(struct kvm_vcpu *vcpu) | 281 | void kvm_vcpu_uninit(struct kvm_vcpu *vcpu) |
282 | { | 282 | { |
283 | kvm_mmu_destroy(vcpu); | 283 | kvm_mmu_destroy(vcpu); |
284 | kvm_free_apic(vcpu->apic); | ||
284 | free_page((unsigned long)vcpu->pio_data); | 285 | free_page((unsigned long)vcpu->pio_data); |
285 | free_page((unsigned long)vcpu->run); | 286 | free_page((unsigned long)vcpu->run); |
286 | } | 287 | } |
@@ -598,25 +599,38 @@ void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) | |||
598 | inject_gp(vcpu); | 599 | inject_gp(vcpu); |
599 | return; | 600 | return; |
600 | } | 601 | } |
601 | vcpu->cr8 = cr8; | 602 | if (irqchip_in_kernel(vcpu->kvm)) |
603 | kvm_lapic_set_tpr(vcpu, cr8); | ||
604 | else | ||
605 | vcpu->cr8 = cr8; | ||
602 | } | 606 | } |
603 | EXPORT_SYMBOL_GPL(set_cr8); | 607 | EXPORT_SYMBOL_GPL(set_cr8); |
604 | 608 | ||
605 | unsigned long get_cr8(struct kvm_vcpu *vcpu) | 609 | unsigned long get_cr8(struct kvm_vcpu *vcpu) |
606 | { | 610 | { |
607 | return vcpu->cr8; | 611 | if (irqchip_in_kernel(vcpu->kvm)) |
612 | return kvm_lapic_get_cr8(vcpu); | ||
613 | else | ||
614 | return vcpu->cr8; | ||
608 | } | 615 | } |
609 | EXPORT_SYMBOL_GPL(get_cr8); | 616 | EXPORT_SYMBOL_GPL(get_cr8); |
610 | 617 | ||
611 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) | 618 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) |
612 | { | 619 | { |
613 | return vcpu->apic_base; | 620 | if (irqchip_in_kernel(vcpu->kvm)) |
621 | return vcpu->apic_base; | ||
622 | else | ||
623 | return vcpu->apic_base; | ||
614 | } | 624 | } |
615 | EXPORT_SYMBOL_GPL(kvm_get_apic_base); | 625 | EXPORT_SYMBOL_GPL(kvm_get_apic_base); |
616 | 626 | ||
617 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data) | 627 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data) |
618 | { | 628 | { |
619 | vcpu->apic_base = data; | 629 | /* TODO: reserve bits check */ |
630 | if (irqchip_in_kernel(vcpu->kvm)) | ||
631 | kvm_lapic_set_base(vcpu, data); | ||
632 | else | ||
633 | vcpu->apic_base = data; | ||
620 | } | 634 | } |
621 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); | 635 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); |
622 | 636 | ||
@@ -986,15 +1000,31 @@ static int emulator_write_std(unsigned long addr, | |||
986 | return X86EMUL_UNHANDLEABLE; | 1000 | return X86EMUL_UNHANDLEABLE; |
987 | } | 1001 | } |
988 | 1002 | ||
1003 | /* | ||
1004 | * Only apic need an MMIO device hook, so shortcut now.. | ||
1005 | */ | ||
1006 | static struct kvm_io_device *vcpu_find_pervcpu_dev(struct kvm_vcpu *vcpu, | ||
1007 | gpa_t addr) | ||
1008 | { | ||
1009 | struct kvm_io_device *dev; | ||
1010 | |||
1011 | if (vcpu->apic) { | ||
1012 | dev = &vcpu->apic->dev; | ||
1013 | if (dev->in_range(dev, addr)) | ||
1014 | return dev; | ||
1015 | } | ||
1016 | return NULL; | ||
1017 | } | ||
1018 | |||
989 | static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, | 1019 | static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, |
990 | gpa_t addr) | 1020 | gpa_t addr) |
991 | { | 1021 | { |
992 | /* | 1022 | struct kvm_io_device *dev; |
993 | * Note that its important to have this wrapper function because | 1023 | |
994 | * in the very near future we will be checking for MMIOs against | 1024 | dev = vcpu_find_pervcpu_dev(vcpu, addr); |
995 | * the LAPIC as well as the general MMIO bus | 1025 | if (dev == NULL) |
996 | */ | 1026 | dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr); |
997 | return kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr); | 1027 | return dev; |
998 | } | 1028 | } |
999 | 1029 | ||
1000 | static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, | 1030 | static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, |
@@ -2256,6 +2286,8 @@ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, | |||
2256 | { | 2286 | { |
2257 | if (irq->irq < 0 || irq->irq >= 256) | 2287 | if (irq->irq < 0 || irq->irq >= 256) |
2258 | return -EINVAL; | 2288 | return -EINVAL; |
2289 | if (irqchip_in_kernel(vcpu->kvm)) | ||
2290 | return -ENXIO; | ||
2259 | vcpu_load(vcpu); | 2291 | vcpu_load(vcpu); |
2260 | 2292 | ||
2261 | set_bit(irq->irq, vcpu->irq_pending); | 2293 | set_bit(irq->irq, vcpu->irq_pending); |