diff options
| -rw-r--r-- | MAINTAINERS | 5 | ||||
| -rw-r--r-- | arch/arm/kvm/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/kvm/mmu.c | 15 | ||||
| -rw-r--r-- | arch/x86/kvm/vmx.c | 53 | ||||
| -rw-r--r-- | virt/kvm/arm/vgic.c | 15 | ||||
| -rw-r--r-- | virt/kvm/assigned-dev.c | 3 | ||||
| -rw-r--r-- | virt/kvm/async_pf.c | 8 |
7 files changed, 70 insertions, 31 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index ea44a57f790e..6bef70b614c9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -5114,14 +5114,19 @@ F: drivers/s390/kvm/ | |||
| 5114 | 5114 | ||
| 5115 | KERNEL VIRTUAL MACHINE (KVM) FOR ARM | 5115 | KERNEL VIRTUAL MACHINE (KVM) FOR ARM |
| 5116 | M: Christoffer Dall <christoffer.dall@linaro.org> | 5116 | M: Christoffer Dall <christoffer.dall@linaro.org> |
| 5117 | M: Marc Zyngier <marc.zyngier@arm.com> | ||
| 5118 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
| 5117 | L: kvmarm@lists.cs.columbia.edu | 5119 | L: kvmarm@lists.cs.columbia.edu |
| 5118 | W: http://systems.cs.columbia.edu/projects/kvm-arm | 5120 | W: http://systems.cs.columbia.edu/projects/kvm-arm |
| 5119 | S: Supported | 5121 | S: Supported |
| 5120 | F: arch/arm/include/uapi/asm/kvm* | 5122 | F: arch/arm/include/uapi/asm/kvm* |
| 5121 | F: arch/arm/include/asm/kvm* | 5123 | F: arch/arm/include/asm/kvm* |
| 5122 | F: arch/arm/kvm/ | 5124 | F: arch/arm/kvm/ |
| 5125 | F: virt/kvm/arm/ | ||
| 5126 | F: include/kvm/arm_* | ||
| 5123 | 5127 | ||
| 5124 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) | 5128 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) |
| 5129 | M: Christoffer Dall <christoffer.dall@linaro.org> | ||
| 5125 | M: Marc Zyngier <marc.zyngier@arm.com> | 5130 | M: Marc Zyngier <marc.zyngier@arm.com> |
| 5126 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 5131 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 5127 | L: kvmarm@lists.cs.columbia.edu | 5132 | L: kvmarm@lists.cs.columbia.edu |
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 466bd299b1a8..4be5bb150bdd 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig | |||
| @@ -23,7 +23,7 @@ config KVM | |||
| 23 | select HAVE_KVM_CPU_RELAX_INTERCEPT | 23 | select HAVE_KVM_CPU_RELAX_INTERCEPT |
| 24 | select KVM_MMIO | 24 | select KVM_MMIO |
| 25 | select KVM_ARM_HOST | 25 | select KVM_ARM_HOST |
| 26 | depends on ARM_VIRT_EXT && ARM_LPAE | 26 | depends on ARM_VIRT_EXT && ARM_LPAE && !CPU_BIG_ENDIAN |
| 27 | ---help--- | 27 | ---help--- |
| 28 | Support hosting virtualized guest machines. You will also | 28 | Support hosting virtualized guest machines. You will also |
| 29 | need to select one or more of the processor modules below. | 29 | need to select one or more of the processor modules below. |
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 80bb1e6c2c29..16f804938b8f 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c | |||
| @@ -42,6 +42,8 @@ static unsigned long hyp_idmap_start; | |||
| 42 | static unsigned long hyp_idmap_end; | 42 | static unsigned long hyp_idmap_end; |
| 43 | static phys_addr_t hyp_idmap_vector; | 43 | static phys_addr_t hyp_idmap_vector; |
| 44 | 44 | ||
| 45 | #define pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t)) | ||
| 46 | |||
| 45 | #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) | 47 | #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) |
| 46 | 48 | ||
| 47 | static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) | 49 | static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) |
| @@ -293,14 +295,14 @@ void free_boot_hyp_pgd(void) | |||
| 293 | if (boot_hyp_pgd) { | 295 | if (boot_hyp_pgd) { |
| 294 | unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); | 296 | unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); |
| 295 | unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); | 297 | unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); |
| 296 | kfree(boot_hyp_pgd); | 298 | free_pages((unsigned long)boot_hyp_pgd, pgd_order); |
| 297 | boot_hyp_pgd = NULL; | 299 | boot_hyp_pgd = NULL; |
| 298 | } | 300 | } |
| 299 | 301 | ||
| 300 | if (hyp_pgd) | 302 | if (hyp_pgd) |
| 301 | unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); | 303 | unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); |
| 302 | 304 | ||
| 303 | kfree(init_bounce_page); | 305 | free_page((unsigned long)init_bounce_page); |
| 304 | init_bounce_page = NULL; | 306 | init_bounce_page = NULL; |
| 305 | 307 | ||
| 306 | mutex_unlock(&kvm_hyp_pgd_mutex); | 308 | mutex_unlock(&kvm_hyp_pgd_mutex); |
| @@ -330,7 +332,7 @@ void free_hyp_pgds(void) | |||
| 330 | for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) | 332 | for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) |
| 331 | unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); | 333 | unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); |
| 332 | 334 | ||
| 333 | kfree(hyp_pgd); | 335 | free_pages((unsigned long)hyp_pgd, pgd_order); |
| 334 | hyp_pgd = NULL; | 336 | hyp_pgd = NULL; |
| 335 | } | 337 | } |
| 336 | 338 | ||
| @@ -1024,7 +1026,7 @@ int kvm_mmu_init(void) | |||
| 1024 | size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start; | 1026 | size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start; |
| 1025 | phys_addr_t phys_base; | 1027 | phys_addr_t phys_base; |
| 1026 | 1028 | ||
| 1027 | init_bounce_page = kmalloc(PAGE_SIZE, GFP_KERNEL); | 1029 | init_bounce_page = (void *)__get_free_page(GFP_KERNEL); |
| 1028 | if (!init_bounce_page) { | 1030 | if (!init_bounce_page) { |
| 1029 | kvm_err("Couldn't allocate HYP init bounce page\n"); | 1031 | kvm_err("Couldn't allocate HYP init bounce page\n"); |
| 1030 | err = -ENOMEM; | 1032 | err = -ENOMEM; |
| @@ -1050,8 +1052,9 @@ int kvm_mmu_init(void) | |||
| 1050 | (unsigned long)phys_base); | 1052 | (unsigned long)phys_base); |
| 1051 | } | 1053 | } |
| 1052 | 1054 | ||
| 1053 | hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); | 1055 | hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); |
| 1054 | boot_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); | 1056 | boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); |
| 1057 | |||
| 1055 | if (!hyp_pgd || !boot_hyp_pgd) { | 1058 | if (!hyp_pgd || !boot_hyp_pgd) { |
| 1056 | kvm_err("Hyp mode PGD not allocated\n"); | 1059 | kvm_err("Hyp mode PGD not allocated\n"); |
| 1057 | err = -ENOMEM; | 1060 | err = -ENOMEM; |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1f68c5831924..33e8c028842f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) | |||
| 503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 | 503 | [number##_HIGH] = VMCS12_OFFSET(name)+4 |
| 504 | 504 | ||
| 505 | 505 | ||
| 506 | static const unsigned long shadow_read_only_fields[] = { | 506 | static unsigned long shadow_read_only_fields[] = { |
| 507 | /* | 507 | /* |
| 508 | * We do NOT shadow fields that are modified when L0 | 508 | * We do NOT shadow fields that are modified when L0 |
| 509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, | 509 | * traps and emulates any vmx instruction (e.g. VMPTRLD, |
| @@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = { | |||
| 526 | GUEST_LINEAR_ADDRESS, | 526 | GUEST_LINEAR_ADDRESS, |
| 527 | GUEST_PHYSICAL_ADDRESS | 527 | GUEST_PHYSICAL_ADDRESS |
| 528 | }; | 528 | }; |
| 529 | static const int max_shadow_read_only_fields = | 529 | static int max_shadow_read_only_fields = |
| 530 | ARRAY_SIZE(shadow_read_only_fields); | 530 | ARRAY_SIZE(shadow_read_only_fields); |
| 531 | 531 | ||
| 532 | static const unsigned long shadow_read_write_fields[] = { | 532 | static unsigned long shadow_read_write_fields[] = { |
| 533 | GUEST_RIP, | 533 | GUEST_RIP, |
| 534 | GUEST_RSP, | 534 | GUEST_RSP, |
| 535 | GUEST_CR0, | 535 | GUEST_CR0, |
| @@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = { | |||
| 558 | HOST_FS_SELECTOR, | 558 | HOST_FS_SELECTOR, |
| 559 | HOST_GS_SELECTOR | 559 | HOST_GS_SELECTOR |
| 560 | }; | 560 | }; |
| 561 | static const int max_shadow_read_write_fields = | 561 | static int max_shadow_read_write_fields = |
| 562 | ARRAY_SIZE(shadow_read_write_fields); | 562 | ARRAY_SIZE(shadow_read_write_fields); |
| 563 | 563 | ||
| 564 | static const unsigned short vmcs_field_to_offset_table[] = { | 564 | static const unsigned short vmcs_field_to_offset_table[] = { |
| @@ -3009,6 +3009,41 @@ static void free_kvm_area(void) | |||
| 3009 | } | 3009 | } |
| 3010 | } | 3010 | } |
| 3011 | 3011 | ||
| 3012 | static void init_vmcs_shadow_fields(void) | ||
| 3013 | { | ||
| 3014 | int i, j; | ||
| 3015 | |||
| 3016 | /* No checks for read only fields yet */ | ||
| 3017 | |||
| 3018 | for (i = j = 0; i < max_shadow_read_write_fields; i++) { | ||
| 3019 | switch (shadow_read_write_fields[i]) { | ||
| 3020 | case GUEST_BNDCFGS: | ||
| 3021 | if (!vmx_mpx_supported()) | ||
| 3022 | continue; | ||
| 3023 | break; | ||
| 3024 | default: | ||
| 3025 | break; | ||
| 3026 | } | ||
| 3027 | |||
| 3028 | if (j < i) | ||
| 3029 | shadow_read_write_fields[j] = | ||
| 3030 | shadow_read_write_fields[i]; | ||
| 3031 | j++; | ||
| 3032 | } | ||
| 3033 | max_shadow_read_write_fields = j; | ||
| 3034 | |||
| 3035 | /* shadowed fields guest access without vmexit */ | ||
| 3036 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
| 3037 | clear_bit(shadow_read_write_fields[i], | ||
| 3038 | vmx_vmwrite_bitmap); | ||
| 3039 | clear_bit(shadow_read_write_fields[i], | ||
| 3040 | vmx_vmread_bitmap); | ||
| 3041 | } | ||
| 3042 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
| 3043 | clear_bit(shadow_read_only_fields[i], | ||
| 3044 | vmx_vmread_bitmap); | ||
| 3045 | } | ||
| 3046 | |||
| 3012 | static __init int alloc_kvm_area(void) | 3047 | static __init int alloc_kvm_area(void) |
| 3013 | { | 3048 | { |
| 3014 | int cpu; | 3049 | int cpu; |
| @@ -3039,6 +3074,8 @@ static __init int hardware_setup(void) | |||
| 3039 | enable_vpid = 0; | 3074 | enable_vpid = 0; |
| 3040 | if (!cpu_has_vmx_shadow_vmcs()) | 3075 | if (!cpu_has_vmx_shadow_vmcs()) |
| 3041 | enable_shadow_vmcs = 0; | 3076 | enable_shadow_vmcs = 0; |
| 3077 | if (enable_shadow_vmcs) | ||
| 3078 | init_vmcs_shadow_fields(); | ||
| 3042 | 3079 | ||
| 3043 | if (!cpu_has_vmx_ept() || | 3080 | if (!cpu_has_vmx_ept() || |
| 3044 | !cpu_has_vmx_ept_4levels()) { | 3081 | !cpu_has_vmx_ept_4levels()) { |
| @@ -8803,14 +8840,6 @@ static int __init vmx_init(void) | |||
| 8803 | |||
