aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/kvm_main.c')
-rw-r--r--drivers/kvm/kvm_main.c52
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);
281void kvm_vcpu_uninit(struct kvm_vcpu *vcpu) 281void 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}
603EXPORT_SYMBOL_GPL(set_cr8); 607EXPORT_SYMBOL_GPL(set_cr8);
604 608
605unsigned long get_cr8(struct kvm_vcpu *vcpu) 609unsigned 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}
609EXPORT_SYMBOL_GPL(get_cr8); 616EXPORT_SYMBOL_GPL(get_cr8);
610 617
611u64 kvm_get_apic_base(struct kvm_vcpu *vcpu) 618u64 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}
615EXPORT_SYMBOL_GPL(kvm_get_apic_base); 625EXPORT_SYMBOL_GPL(kvm_get_apic_base);
616 626
617void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data) 627void 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}
621EXPORT_SYMBOL_GPL(kvm_set_apic_base); 635EXPORT_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 */
1006static 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
989static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu, 1019static 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
1000static struct kvm_io_device *vcpu_find_pio_dev(struct kvm_vcpu *vcpu, 1030static 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);