Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull KVM fixes from Paolo Bonzini:
"PPC:
- user-triggerable use-after-free in HPT resizing
- stale TLB entries in the guest
- trap-and-emulate (PR) KVM guests failing to start under pHyp

x86:
- Another "Spectre" fix.
- async pagefault fix
- Revert an old fix for x86 nested virtualization, which turned out
to do more harm than good
- Check shrinker registration return code, to avoid warnings from
upcoming 4.16 -mm patches"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: x86: Add memory barrier on vmcs field lookup
KVM: x86: emulate #UD while in guest mode
x86: kvm: propagate register_shrinker return code
KVM MMU: check pending exception before injecting APF
KVM: PPC: Book3S HV: Always flush TLB in kvmppc_alloc_reset_hpt()
KVM: PPC: Book3S PR: Fix WIMG handling under pHyp
KVM: PPC: Book3S HV: Fix use after free in case of multiple resize requests
KVM: PPC: Book3S HV: Drop prepare_done from struct kvm_resize_hpt

+89 -51
+1
arch/powerpc/kvm/book3s_64_mmu.c
··· 235 235 gpte->may_read = true; 236 236 gpte->may_write = true; 237 237 gpte->page_size = MMU_PAGE_4K; 238 + gpte->wimg = HPTE_R_M; 238 239 239 240 return 0; 240 241 }
+62 -30
arch/powerpc/kvm/book3s_64_mmu_hv.c
··· 65 65 u32 order; 66 66 67 67 /* These fields protected by kvm->lock */ 68 - int error; 69 - bool prepare_done; 70 68 71 - /* Private to the work thread, until prepare_done is true, 72 - * then protected by kvm->resize_hpt_sem */ 69 + /* Possible values and their usage: 70 + * <0 an error occurred during allocation, 71 + * -EBUSY allocation is in the progress, 72 + * 0 allocation made successfuly. 73 + */ 74 + int error; 75 + 76 + /* Private to the work thread, until error != -EBUSY, 77 + * then protected by kvm->lock. 78 + */ 73 79 struct kvm_hpt_info hpt; 74 80 }; 75 81 ··· 165 159 * Reset all the reverse-mapping chains for all memslots 166 160 */ 167 161 kvmppc_rmap_reset(kvm); 168 - /* Ensure that each vcpu will flush its TLB on next entry. */ 169 - cpumask_setall(&kvm->arch.need_tlb_flush); 170 162 err = 0; 171 163 goto out; 172 164 } ··· 180 176 kvmppc_set_hpt(kvm, &info); 181 177 182 178 out: 179 + if (err == 0) 180 + /* Ensure that each vcpu will flush its TLB on next entry. */ 181 + cpumask_setall(&kvm->arch.need_tlb_flush); 182 + 183 183 mutex_unlock(&kvm->lock); 184 184 return err; 185 185 } ··· 1421 1413 1422 1414 static void resize_hpt_release(struct kvm *kvm, struct kvm_resize_hpt *resize) 1423 1415 { 1424 - BUG_ON(kvm->arch.resize_hpt != resize); 1416 + if (WARN_ON(!mutex_is_locked(&kvm->lock))) 1417 + return; 1425 1418 1426 1419 if (!resize) 1427 1420 return; 1428 1421 1429 - if (resize->hpt.virt) 1430 - kvmppc_free_hpt(&resize->hpt); 1422 + if (resize->error != -EBUSY) { 1423 + if (resize->hpt.virt) 1424 + kvmppc_free_hpt(&resize->hpt); 1425 + kfree(resize); 1426 + } 1431 1427 1432 - kvm->arch.resize_hpt = NULL; 1433 - kfree(resize); 1428 + if (kvm->arch.resize_hpt == resize) 1429 + kvm->arch.resize_hpt = NULL; 1434 1430 } 1435 1431 1436 1432 static void resize_hpt_prepare_work(struct work_struct *work) ··· 1443 1431 struct kvm_resize_hpt, 1444 1432 work); 1445 1433 struct kvm *kvm = resize->kvm; 1446 - int err; 1434 + int err = 0; 1447 1435 1448 - resize_hpt_debug(resize, "resize_hpt_prepare_work(): order = %d\n", 1449 - resize->order); 1450 - 1451 - err = resize_hpt_allocate(resize); 1436 + if (WARN_ON(resize->error != -EBUSY)) 1437 + return; 1452 1438 1453 1439 mutex_lock(&kvm->lock); 1454 1440 1441 + /* Request is still current? */ 1442 + if (kvm->arch.resize_hpt == resize) { 1443 + /* We may request large allocations here: 1444 + * do not sleep with kvm->lock held for a while. 1445 + */ 1446 + mutex_unlock(&kvm->lock); 1447 + 1448 + resize_hpt_debug(resize, "resize_hpt_prepare_work(): order = %d\n", 1449 + resize->order); 1450 + 1451 + err = resize_hpt_allocate(resize); 1452 + 1453 + /* We have strict assumption about -EBUSY 1454 + * when preparing for HPT resize. 1455 + */ 1456 + if (WARN_ON(err == -EBUSY)) 1457 + err = -EINPROGRESS; 1458 + 1459 + mutex_lock(&kvm->lock); 1460 + /* It is possible that kvm->arch.resize_hpt != resize 1461 + * after we grab kvm->lock again. 1462 + */ 1463 + } 1464 + 1455 1465 resize->error = err; 1456 - resize->prepare_done = true; 1466 + 1467 + if (kvm->arch.resize_hpt != resize) 1468 + resize_hpt_release(kvm, resize); 1457 1469 1458 1470 mutex_unlock(&kvm->lock); 1459 1471 } ··· 1502 1466 1503 1467 if (resize) { 1504 1468 if (resize->order == shift) { 1505 - /* Suitable resize in progress */ 1506 - if (resize->prepare_done) { 1507 - ret = resize->error; 1508 - if (ret != 0) 1509 - resize_hpt_release(kvm, resize); 1510 - } else { 1469 + /* Suitable resize in progress? */ 1470 + ret = resize->error; 1471 + if (ret == -EBUSY) 1511 1472 ret = 100; /* estimated time in ms */ 1512 - } 1473 + else if (ret) 1474 + resize_hpt_release(kvm, resize); 1513 1475 1514 1476 goto out; 1515 1477 } ··· 1527 1493 ret = -ENOMEM; 1528 1494 goto out; 1529 1495 } 1496 + 1497 + resize->error = -EBUSY; 1530 1498 resize->order = shift; 1531 1499 resize->kvm = kvm; 1532 1500 INIT_WORK(&resize->work, resize_hpt_prepare_work); ··· 1583 1547 if (!resize || (resize->order != shift)) 1584 1548 goto out; 1585 1549 1586 - ret = -EBUSY; 1587 - if (!resize->prepare_done) 1588 - goto out; 1589 - 1590 1550 ret = resize->error; 1591 - if (ret != 0) 1551 + if (ret) 1592 1552 goto out; 1593 1553 1594 1554 ret = resize_hpt_rehash(resize); 1595 - if (ret != 0) 1555 + if (ret) 1596 1556 goto out; 1597 1557 1598 1558 resize_hpt_pivot(resize);
+2
arch/powerpc/kvm/book3s_pr.c
··· 60 60 #define MSR_USER32 MSR_USER 61 61 #define MSR_USER64 MSR_USER 62 62 #define HW_PAGE_SIZE PAGE_SIZE 63 + #define HPTE_R_M _PAGE_COHERENT 63 64 #endif 64 65 65 66 static bool kvmppc_is_split_real(struct kvm_vcpu *vcpu) ··· 558 557 pte.eaddr = eaddr; 559 558 pte.vpage = eaddr >> 12; 560 559 pte.page_size = MMU_PAGE_64K; 560 + pte.wimg = HPTE_R_M; 561 561 } 562 562 563 563 switch (kvmppc_get_msr(vcpu) & (MSR_DR|MSR_IR)) {
+12 -7
arch/x86/kvm/mmu.c
··· 3781 3781 bool kvm_can_do_async_pf(struct kvm_vcpu *vcpu) 3782 3782 { 3783 3783 if (unlikely(!lapic_in_kernel(vcpu) || 3784 - kvm_event_needs_reinjection(vcpu))) 3784 + kvm_event_needs_reinjection(vcpu) || 3785 + vcpu->arch.exception.pending)) 3785 3786 return false; 3786 3787 3787 3788 if (!vcpu->arch.apf.delivery_as_pf_vmexit && is_guest_mode(vcpu)) ··· 5466 5465 5467 5466 int kvm_mmu_module_init(void) 5468 5467 { 5468 + int ret = -ENOMEM; 5469 + 5469 5470 kvm_mmu_clear_all_pte_masks(); 5470 5471 5471 5472 pte_list_desc_cache = kmem_cache_create("pte_list_desc", 5472 5473 sizeof(struct pte_list_desc), 5473 5474 0, SLAB_ACCOUNT, NULL); 5474 5475 if (!pte_list_desc_cache) 5475 - goto nomem; 5476 + goto out; 5476 5477 5477 5478 mmu_page_header_cache = kmem_cache_create("kvm_mmu_page_header", 5478 5479 sizeof(struct kvm_mmu_page), 5479 5480 0, SLAB_ACCOUNT, NULL); 5480 5481 if (!mmu_page_header_cache) 5481 - goto nomem; 5482 + goto out; 5482 5483 5483 5484 if (percpu_counter_init(&kvm_total_used_mmu_pages, 0, GFP_KERNEL)) 5484 - goto nomem; 5485 + goto out; 5485 5486 5486 - register_shrinker(&mmu_shrinker); 5487 + ret = register_shrinker(&mmu_shrinker); 5488 + if (ret) 5489 + goto out; 5487 5490 5488 5491 return 0; 5489 5492 5490 - nomem: 5493 + out: 5491 5494 mmu_destroy_caches(); 5492 - return -ENOMEM; 5495 + return ret; 5493 5496 } 5494 5497 5495 5498 /*
+1 -8
arch/x86/kvm/svm.c
··· 361 361 { 362 362 struct vmcb_control_area *c, *h; 363 363 struct nested_state *g; 364 - u32 h_intercept_exceptions; 365 364 366 365 mark_dirty(svm->vmcb, VMCB_INTERCEPTS); 367 366 ··· 371 372 h = &svm->nested.hsave->control; 372 373 g = &svm->nested; 373 374 374 - /* No need to intercept #UD if L1 doesn't intercept it */ 375 - h_intercept_exceptions = 376 - h->intercept_exceptions & ~(1U << UD_VECTOR); 377 - 378 375 c->intercept_cr = h->intercept_cr | g->intercept_cr; 379 376 c->intercept_dr = h->intercept_dr | g->intercept_dr; 380 - c->intercept_exceptions = 381 - h_intercept_exceptions | g->intercept_exceptions; 377 + c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions; 382 378 c->intercept = h->intercept | g->intercept; 383 379 } 384 380 ··· 2196 2202 { 2197 2203 int er; 2198 2204 2199 - WARN_ON_ONCE(is_guest_mode(&svm->vcpu)); 2200 2205 er = emulate_instruction(&svm->vcpu, EMULTYPE_TRAP_UD); 2201 2206 if (er == EMULATE_USER_EXIT) 2202 2207 return 0;
+11 -6
arch/x86/kvm/vmx.c
··· 899 899 { 900 900 BUILD_BUG_ON(ARRAY_SIZE(vmcs_field_to_offset_table) > SHRT_MAX); 901 901 902 - if (field >= ARRAY_SIZE(vmcs_field_to_offset_table) || 903 - vmcs_field_to_offset_table[field] == 0) 902 + if (field >= ARRAY_SIZE(vmcs_field_to_offset_table)) 903 + return -ENOENT; 904 + 905 + /* 906 + * FIXME: Mitigation for CVE-2017-5753. To be replaced with a 907 + * generic mechanism. 908 + */ 909 + asm("lfence"); 910 + 911 + if (vmcs_field_to_offset_table[field] == 0) 904 912 return -ENOENT; 905 913 906 914 return vmcs_field_to_offset_table[field]; ··· 1895 1887 { 1896 1888 u32 eb; 1897 1889 1898 - eb = (1u << PF_VECTOR) | (1u << MC_VECTOR) | 1890 + eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR) | 1899 1891 (1u << DB_VECTOR) | (1u << AC_VECTOR); 1900 1892 if ((vcpu->guest_debug & 1901 1893 (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)) == ··· 1913 1905 */ 1914 1906 if (is_guest_mode(vcpu)) 1915 1907 eb |= get_vmcs12(vcpu)->exception_bitmap; 1916 - else 1917 - eb |= 1u << UD_VECTOR; 1918 1908 1919 1909 vmcs_write32(EXCEPTION_BITMAP, eb); 1920 1910 } ··· 5923 5917 return 1; /* already handled by vmx_vcpu_run() */ 5924 5918 5925 5919 if (is_invalid_opcode(intr_info)) { 5926 - WARN_ON_ONCE(is_guest_mode(vcpu)); 5927 5920 er = emulate_instruction(vcpu, EMULTYPE_TRAP_UD); 5928 5921 if (er == EMULATE_USER_EXIT) 5929 5922 return 0;