diff options
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 53 | ||||
-rw-r--r-- | virt/kvm/assigned-dev.c | 3 | ||||
-rw-r--r-- | virt/kvm/async_pf.c | 8 |
4 files changed, 52 insertions, 17 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 6dc67b1fdb50..24815e784905 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5108,14 +5108,19 @@ F: drivers/s390/kvm/ | |||
5108 | 5108 | ||
5109 | KERNEL VIRTUAL MACHINE (KVM) FOR ARM | 5109 | KERNEL VIRTUAL MACHINE (KVM) FOR ARM |
5110 | M: Christoffer Dall <christoffer.dall@linaro.org> | 5110 | M: Christoffer Dall <christoffer.dall@linaro.org> |
5111 | M: Marc Zyngier <marc.zyngier@arm.com> | ||
5112 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
5111 | L: kvmarm@lists.cs.columbia.edu | 5113 | L: kvmarm@lists.cs.columbia.edu |
5112 | W: http://systems.cs.columbia.edu/projects/kvm-arm | 5114 | W: http://systems.cs.columbia.edu/projects/kvm-arm |
5113 | S: Supported | 5115 | S: Supported |
5114 | F: arch/arm/include/uapi/asm/kvm* | 5116 | F: arch/arm/include/uapi/asm/kvm* |
5115 | F: arch/arm/include/asm/kvm* | 5117 | F: arch/arm/include/asm/kvm* |
5116 | F: arch/arm/kvm/ | 5118 | F: arch/arm/kvm/ |
5119 | F: virt/kvm/arm/ | ||
5120 | F: include/kvm/arm_* | ||
5117 | 5121 | ||
5118 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) | 5122 | KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) |
5123 | M: Christoffer Dall <christoffer.dall@linaro.org> | ||
5119 | M: Marc Zyngier <marc.zyngier@arm.com> | 5124 | M: Marc Zyngier <marc.zyngier@arm.com> |
5120 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 5125 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
5121 | L: kvmarm@lists.cs.columbia.edu | 5126 | L: kvmarm@lists.cs.columbia.edu |
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 | 8840 | ||
8804 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); | 8841 | memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); |
8805 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); | 8842 | memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); |
8806 | /* shadowed read/write fields */ | ||
8807 | for (i = 0; i < max_shadow_read_write_fields; i++) { | ||
8808 | clear_bit(shadow_read_write_fields[i], vmx_vmwrite_bitmap); | ||
8809 | clear_bit(shadow_read_write_fields[i], vmx_vmread_bitmap); | ||
8810 | } | ||
8811 | /* shadowed read only fields */ | ||
8812 | for (i = 0; i < max_shadow_read_only_fields; i++) | ||
8813 | clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap); | ||
8814 | 8843 | ||
8815 | /* | 8844 | /* |
8816 | * Allow direct access to the PC debug port (it is often used for I/O | 8845 | * Allow direct access to the PC debug port (it is often used for I/O |
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 8db43701016f..bf06577fea51 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
@@ -395,7 +395,8 @@ static int assigned_device_enable_host_msix(struct kvm *kvm, | |||
395 | if (dev->entries_nr == 0) | 395 | if (dev->entries_nr == 0) |
396 | return r; | 396 | return r; |
397 | 397 | ||
398 | r = pci_enable_msix(dev->dev, dev->host_msix_entries, dev->entries_nr); | 398 | r = pci_enable_msix_exact(dev->dev, |
399 | dev->host_msix_entries, dev->entries_nr); | ||
399 | if (r) | 400 | if (r) |
400 | return r; | 401 | return r; |
401 | 402 | ||
diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c index 10df100c4514..06e6401d6ef4 100644 --- a/virt/kvm/async_pf.c +++ b/virt/kvm/async_pf.c | |||
@@ -101,7 +101,7 @@ static void async_pf_execute(struct work_struct *work) | |||
101 | if (waitqueue_active(&vcpu->wq)) | 101 | if (waitqueue_active(&vcpu->wq)) |
102 | wake_up_interruptible(&vcpu->wq); | 102 | wake_up_interruptible(&vcpu->wq); |
103 | 103 | ||
104 | mmdrop(mm); | 104 | mmput(mm); |
105 | kvm_put_kvm(vcpu->kvm); | 105 | kvm_put_kvm(vcpu->kvm); |
106 | } | 106 | } |
107 | 107 | ||
@@ -118,7 +118,7 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) | |||
118 | flush_work(&work->work); | 118 | flush_work(&work->work); |
119 | #else | 119 | #else |
120 | if (cancel_work_sync(&work->work)) { | 120 | if (cancel_work_sync(&work->work)) { |
121 | mmdrop(work->mm); | 121 | mmput(work->mm); |
122 | kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */ | 122 | kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */ |
123 | kmem_cache_free(async_pf_cache, work); | 123 | kmem_cache_free(async_pf_cache, work); |
124 | } | 124 | } |
@@ -183,7 +183,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva, | |||
183 | work->addr = hva; | 183 | work->addr = hva; |
184 | work->arch = *arch; | 184 | work->arch = *arch; |
185 | work->mm = current->mm; | 185 | work->mm = current->mm; |
186 | atomic_inc(&work->mm->mm_count); | 186 | atomic_inc(&work->mm->mm_users); |
187 | kvm_get_kvm(work->vcpu->kvm); | 187 | kvm_get_kvm(work->vcpu->kvm); |
188 | 188 | ||
189 | /* this can't really happen otherwise gfn_to_pfn_async | 189 | /* this can't really happen otherwise gfn_to_pfn_async |
@@ -201,7 +201,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva, | |||
201 | return 1; | 201 | return 1; |
202 | retry_sync: | 202 | retry_sync: |
203 | kvm_put_kvm(work->vcpu->kvm); | 203 | kvm_put_kvm(work->vcpu->kvm); |
204 | mmdrop(work->mm); | 204 | mmput(work->mm); |
205 | kmem_cache_free(async_pf_cache, work); | 205 | kmem_cache_free(async_pf_cache, work); |
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |