diff options
Diffstat (limited to 'arch/ia64/kvm/kvm-ia64.c')
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 73 |
1 files changed, 59 insertions, 14 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index cf8eae1855e6..a312c9e9b9ef 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/bitops.h> | 31 | #include <linux/bitops.h> |
32 | #include <linux/hrtimer.h> | 32 | #include <linux/hrtimer.h> |
33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
34 | #include <linux/intel-iommu.h> | ||
34 | 35 | ||
35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
36 | #include <asm/gcc_intrin.h> | 37 | #include <asm/gcc_intrin.h> |
@@ -38,12 +39,14 @@ | |||
38 | #include <asm/cacheflush.h> | 39 | #include <asm/cacheflush.h> |
39 | #include <asm/div64.h> | 40 | #include <asm/div64.h> |
40 | #include <asm/tlb.h> | 41 | #include <asm/tlb.h> |
42 | #include <asm/elf.h> | ||
41 | 43 | ||
42 | #include "misc.h" | 44 | #include "misc.h" |
43 | #include "vti.h" | 45 | #include "vti.h" |
44 | #include "iodev.h" | 46 | #include "iodev.h" |
45 | #include "ioapic.h" | 47 | #include "ioapic.h" |
46 | #include "lapic.h" | 48 | #include "lapic.h" |
49 | #include "irq.h" | ||
47 | 50 | ||
48 | static unsigned long kvm_vmm_base; | 51 | static unsigned long kvm_vmm_base; |
49 | static unsigned long kvm_vsa_base; | 52 | static unsigned long kvm_vsa_base; |
@@ -61,12 +64,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
61 | { NULL } | 64 | { NULL } |
62 | }; | 65 | }; |
63 | 66 | ||
64 | |||
65 | struct fdesc{ | ||
66 | unsigned long ip; | ||
67 | unsigned long gp; | ||
68 | }; | ||
69 | |||
70 | static void kvm_flush_icache(unsigned long start, unsigned long len) | 67 | static void kvm_flush_icache(unsigned long start, unsigned long len) |
71 | { | 68 | { |
72 | int l; | 69 | int l; |
@@ -184,12 +181,16 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
184 | switch (ext) { | 181 | switch (ext) { |
185 | case KVM_CAP_IRQCHIP: | 182 | case KVM_CAP_IRQCHIP: |
186 | case KVM_CAP_USER_MEMORY: | 183 | case KVM_CAP_USER_MEMORY: |
184 | case KVM_CAP_MP_STATE: | ||
187 | 185 | ||
188 | r = 1; | 186 | r = 1; |
189 | break; | 187 | break; |
190 | case KVM_CAP_COALESCED_MMIO: | 188 | case KVM_CAP_COALESCED_MMIO: |
191 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; | 189 | r = KVM_COALESCED_MMIO_PAGE_OFFSET; |
192 | break; | 190 | break; |
191 | case KVM_CAP_IOMMU: | ||
192 | r = intel_iommu_found(); | ||
193 | break; | ||
193 | default: | 194 | default: |
194 | r = 0; | 195 | r = 0; |
195 | } | 196 | } |
@@ -776,6 +777,7 @@ static void kvm_init_vm(struct kvm *kvm) | |||
776 | */ | 777 | */ |
777 | kvm_build_io_pmt(kvm); | 778 | kvm_build_io_pmt(kvm); |
778 | 779 | ||
780 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); | ||
779 | } | 781 | } |
780 | 782 | ||
781 | struct kvm *kvm_arch_create_vm(void) | 783 | struct kvm *kvm_arch_create_vm(void) |
@@ -1339,6 +1341,10 @@ static void kvm_release_vm_pages(struct kvm *kvm) | |||
1339 | 1341 | ||
1340 | void kvm_arch_destroy_vm(struct kvm *kvm) | 1342 | void kvm_arch_destroy_vm(struct kvm *kvm) |
1341 | { | 1343 | { |
1344 | kvm_iommu_unmap_guest(kvm); | ||
1345 | #ifdef KVM_CAP_DEVICE_ASSIGNMENT | ||
1346 | kvm_free_all_assigned_devices(kvm); | ||
1347 | #endif | ||
1342 | kfree(kvm->arch.vioapic); | 1348 | kfree(kvm->arch.vioapic); |
1343 | kvm_release_vm_pages(kvm); | 1349 | kvm_release_vm_pages(kvm); |
1344 | kvm_free_physmem(kvm); | 1350 | kvm_free_physmem(kvm); |
@@ -1440,17 +1446,24 @@ int kvm_arch_set_memory_region(struct kvm *kvm, | |||
1440 | int user_alloc) | 1446 | int user_alloc) |
1441 | { | 1447 | { |
1442 | unsigned long i; | 1448 | unsigned long i; |
1443 | struct page *page; | 1449 | unsigned long pfn; |
1444 | int npages = mem->memory_size >> PAGE_SHIFT; | 1450 | int npages = mem->memory_size >> PAGE_SHIFT; |
1445 | struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot]; | 1451 | struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot]; |
1446 | unsigned long base_gfn = memslot->base_gfn; | 1452 | unsigned long base_gfn = memslot->base_gfn; |
1447 | 1453 | ||
1448 | for (i = 0; i < npages; i++) { | 1454 | for (i = 0; i < npages; i++) { |
1449 | page = gfn_to_page(kvm, base_gfn + i); | 1455 | pfn = gfn_to_pfn(kvm, base_gfn + i); |
1450 | kvm_set_pmt_entry(kvm, base_gfn + i, | 1456 | if (!kvm_is_mmio_pfn(pfn)) { |
1451 | page_to_pfn(page) << PAGE_SHIFT, | 1457 | kvm_set_pmt_entry(kvm, base_gfn + i, |
1452 | _PAGE_AR_RWX|_PAGE_MA_WB); | 1458 | pfn << PAGE_SHIFT, |
1453 | memslot->rmap[i] = (unsigned long)page; | 1459 | _PAGE_AR_RWX | _PAGE_MA_WB); |
1460 | memslot->rmap[i] = (unsigned long)pfn_to_page(pfn); | ||
1461 | } else { | ||
1462 | kvm_set_pmt_entry(kvm, base_gfn + i, | ||
1463 | GPFN_PHYS_MMIO | (pfn << PAGE_SHIFT), | ||
1464 | _PAGE_MA_UC); | ||
1465 | memslot->rmap[i] = 0; | ||
1466 | } | ||
1454 | } | 1467 | } |
1455 | 1468 | ||
1456 | return 0; | 1469 | return 0; |
@@ -1794,11 +1807,43 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | |||
1794 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, | 1807 | int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu, |
1795 | struct kvm_mp_state *mp_state) | 1808 | struct kvm_mp_state *mp_state) |
1796 | { | 1809 | { |
1797 | return -EINVAL; | 1810 | vcpu_load(vcpu); |
1811 | mp_state->mp_state = vcpu->arch.mp_state; | ||
1812 | vcpu_put(vcpu); | ||
1813 | return 0; | ||
1814 | } | ||
1815 | |||
1816 | static int vcpu_reset(struct kvm_vcpu *vcpu) | ||
1817 | { | ||
1818 | int r; | ||
1819 | long psr; | ||
1820 | local_irq_save(psr); | ||
1821 | r = kvm_insert_vmm_mapping(vcpu); | ||
1822 | if (r) | ||
1823 | goto fail; | ||
1824 | |||
1825 | vcpu->arch.launched = 0; | ||
1826 | kvm_arch_vcpu_uninit(vcpu); | ||
1827 | r = kvm_arch_vcpu_init(vcpu); | ||
1828 | if (r) | ||
1829 | goto fail; | ||
1830 | |||
1831 | kvm_purge_vmm_mapping(vcpu); | ||
1832 | r = 0; | ||
1833 | fail: | ||
1834 | local_irq_restore(psr); | ||
1835 | return r; | ||
1798 | } | 1836 | } |
1799 | 1837 | ||
1800 | int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, | 1838 | int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, |
1801 | struct kvm_mp_state *mp_state) | 1839 | struct kvm_mp_state *mp_state) |
1802 | { | 1840 | { |
1803 | return -EINVAL; | 1841 | int r = 0; |
1842 | |||
1843 | vcpu_load(vcpu); | ||
1844 | vcpu->arch.mp_state = mp_state->mp_state; | ||
1845 | if (vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED) | ||
1846 | r = vcpu_reset(vcpu); | ||
1847 | vcpu_put(vcpu); | ||
1848 | return r; | ||
1804 | } | 1849 | } |