aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/kvm/vmx.c15
-rw-r--r--arch/x86/kvm/x86.c19
-rw-r--r--include/linux/kvm.h2
4 files changed, 32 insertions, 5 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 08732d7b6d98..e210b218df44 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -411,6 +411,7 @@ struct kvm_arch{
411 411
412 struct page *ept_identity_pagetable; 412 struct page *ept_identity_pagetable;
413 bool ept_identity_pagetable_done; 413 bool ept_identity_pagetable_done;
414 gpa_t ept_identity_map_addr;
414 415
415 unsigned long irq_sources_bitmap; 416 unsigned long irq_sources_bitmap;
416 unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; 417 unsigned long irq_states[KVM_IOAPIC_NUM_PINS];
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index c6256b98f078..686e1abb6816 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1719,7 +1719,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
1719 eptp = construct_eptp(cr3); 1719 eptp = construct_eptp(cr3);
1720 vmcs_write64(EPT_POINTER, eptp); 1720 vmcs_write64(EPT_POINTER, eptp);
1721 guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 : 1721 guest_cr3 = is_paging(vcpu) ? vcpu->arch.cr3 :
1722 VMX_EPT_IDENTITY_PAGETABLE_ADDR; 1722 vcpu->kvm->arch.ept_identity_map_addr;
1723 } 1723 }
1724 1724
1725 vmx_flush_tlb(vcpu); 1725 vmx_flush_tlb(vcpu);
@@ -2122,7 +2122,7 @@ static int init_rmode_identity_map(struct kvm *kvm)
2122 if (likely(kvm->arch.ept_identity_pagetable_done)) 2122 if (likely(kvm->arch.ept_identity_pagetable_done))
2123 return 1; 2123 return 1;
2124 ret = 0; 2124 ret = 0;
2125 identity_map_pfn = VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT; 2125 identity_map_pfn = kvm->arch.ept_identity_map_addr >> PAGE_SHIFT;
2126 r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE); 2126 r = kvm_clear_guest_page(kvm, identity_map_pfn, 0, PAGE_SIZE);
2127 if (r < 0) 2127 if (r < 0)
2128 goto out; 2128 goto out;
@@ -2191,14 +2191,15 @@ static int alloc_identity_pagetable(struct kvm *kvm)
2191 goto out; 2191 goto out;
2192 kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; 2192 kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT;
2193 kvm_userspace_mem.flags = 0; 2193 kvm_userspace_mem.flags = 0;
2194 kvm_userspace_mem.guest_phys_addr = VMX_EPT_IDENTITY_PAGETABLE_ADDR; 2194 kvm_userspace_mem.guest_phys_addr =
2195 kvm->arch.ept_identity_map_addr;
2195 kvm_userspace_mem.memory_size = PAGE_SIZE; 2196 kvm_userspace_mem.memory_size = PAGE_SIZE;
2196 r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0); 2197 r = __kvm_set_memory_region(kvm, &kvm_userspace_mem, 0);
2197 if (r) 2198 if (r)
2198 goto out; 2199 goto out;
2199 2200
2200 kvm->arch.ept_identity_pagetable = gfn_to_page(kvm, 2201 kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
2201 VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT); 2202 kvm->arch.ept_identity_map_addr >> PAGE_SHIFT);
2202out: 2203out:
2203 up_write(&kvm->slots_lock); 2204 up_write(&kvm->slots_lock);
2204 return r; 2205 return r;
@@ -3814,9 +3815,13 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
3814 if (alloc_apic_access_page(kvm) != 0) 3815 if (alloc_apic_access_page(kvm) != 0)
3815 goto free_vmcs; 3816 goto free_vmcs;
3816 3817
3817 if (enable_ept) 3818 if (enable_ept) {
3819 if (!kvm->arch.ept_identity_map_addr)
3820 kvm->arch.ept_identity_map_addr =
3821 VMX_EPT_IDENTITY_PAGETABLE_ADDR;
3818 if (alloc_identity_pagetable(kvm) != 0) 3822 if (alloc_identity_pagetable(kvm) != 0)
3819 goto free_vmcs; 3823 goto free_vmcs;
3824 }
3820 3825
3821 return &vmx->vcpu; 3826 return &vmx->vcpu;
3822 3827
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c7ec0c921c01..f4cb1baaa04b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1206,6 +1206,7 @@ int kvm_dev_ioctl_check_extension(long ext)
1206 case KVM_CAP_IOEVENTFD: 1206 case KVM_CAP_IOEVENTFD:
1207 case KVM_CAP_PIT2: 1207 case KVM_CAP_PIT2:
1208 case KVM_CAP_PIT_STATE2: 1208 case KVM_CAP_PIT_STATE2:
1209 case KVM_CAP_SET_IDENTITY_MAP_ADDR:
1209 r = 1; 1210 r = 1;
1210 break; 1211 break;
1211 case KVM_CAP_COALESCED_MMIO: 1212 case KVM_CAP_COALESCED_MMIO:
@@ -1906,6 +1907,13 @@ static int kvm_vm_ioctl_set_tss_addr(struct kvm *kvm, unsigned long addr)
1906 return ret; 1907 return ret;
1907} 1908}
1908 1909
1910static int kvm_vm_ioctl_set_identity_map_addr(struct kvm *kvm,
1911 u64 ident_addr)
1912{
1913 kvm->arch.ept_identity_map_addr = ident_addr;
1914 return 0;
1915}
1916
1909static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm, 1917static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
1910 u32 kvm_nr_mmu_pages) 1918 u32 kvm_nr_mmu_pages)
1911{ 1919{
@@ -2173,6 +2181,17 @@ long kvm_arch_vm_ioctl(struct file *filp,
2173 if (r < 0) 2181 if (r < 0)
2174 goto out; 2182 goto out;
2175 break; 2183 break;
2184 case KVM_SET_IDENTITY_MAP_ADDR: {
2185 u64 ident_addr;
2186
2187 r = -EFAULT;
2188 if (copy_from_user(&ident_addr, argp, sizeof ident_addr))
2189 goto out;
2190 r = kvm_vm_ioctl_set_identity_map_addr(kvm, ident_addr);
2191 if (r < 0)
2192 goto out;
2193 break;
2194 }
2176 case KVM_SET_MEMORY_REGION: { 2195 case KVM_SET_MEMORY_REGION: {
2177 struct kvm_memory_region kvm_mem; 2196 struct kvm_memory_region kvm_mem;
2178 struct kvm_userspace_memory_region kvm_userspace_mem; 2197 struct kvm_userspace_memory_region kvm_userspace_mem;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 230a91aa61c9..f8f8900fc5ec 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -435,6 +435,7 @@ struct kvm_ioeventfd {
435#define KVM_CAP_PIT_STATE2 35 435#define KVM_CAP_PIT_STATE2 35
436#endif 436#endif
437#define KVM_CAP_IOEVENTFD 36 437#define KVM_CAP_IOEVENTFD 36
438#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37
438 439
439#ifdef KVM_CAP_IRQ_ROUTING 440#ifdef KVM_CAP_IRQ_ROUTING
440 441
@@ -512,6 +513,7 @@ struct kvm_irqfd {
512#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46,\ 513#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46,\
513 struct kvm_userspace_memory_region) 514 struct kvm_userspace_memory_region)
514#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47) 515#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47)
516#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64)
515/* Device model IOC */ 517/* Device model IOC */
516#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60) 518#define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60)
517#define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level) 519#define KVM_IRQ_LINE _IOW(KVMIO, 0x61, struct kvm_irq_level)