Skip to content

Commit 329f415

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Radim Krčmář: "KVM: - lock kvm_device list to prevent corruption on device creation. PPC: - split debugfs initialization from creation of the xics device to unlock the newly taken kvm lock earlier. s390: - prevent userspace from triggering two WARN_ON_ONCE. MIPS: - fix several issues in the management of TLB faults (Cc: stable)" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: MIPS: KVM: Propagate kseg0/mapped tlb fault errors MIPS: KVM: Fix gfn range check in kseg0 tlb faults MIPS: KVM: Add missing gfn range check MIPS: KVM: Fix mapped fault broken commpage handling KVM: Protect device ops->create and list_add with kvm->lock KVM: PPC: Move xics_debugfs_init out of create KVM: s390: reset KVM_REQ_MMU_RELOAD if mapping the prefix failed KVM: s390: set the prefix initially properly
2 parents a1e2103 + 89a1d43 commit 329f415

File tree

8 files changed

+118
-53
lines changed

8 files changed

+118
-53
lines changed

arch/arm/kvm/arm.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,9 +1009,13 @@ long kvm_arch_vm_ioctl(struct file *filp,
10091009

10101010
switch (ioctl) {
10111011
case KVM_CREATE_IRQCHIP: {
1012+
int ret;
10121013
if (!vgic_present)
10131014
return -ENXIO;
1014-
return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
1015+
mutex_lock(&kvm->lock);
1016+
ret = kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
1017+
mutex_unlock(&kvm->lock);
1018+
return ret;
10151019
}
10161020
case KVM_ARM_SET_DEVICE_ADDR: {
10171021
struct kvm_arm_device_addr dev_addr;

arch/mips/kvm/emulate.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,8 +1642,14 @@ enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst,
16421642

16431643
preempt_disable();
16441644
if (KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG0) {
1645-
if (kvm_mips_host_tlb_lookup(vcpu, va) < 0)
1646-
kvm_mips_handle_kseg0_tlb_fault(va, vcpu);
1645+
if (kvm_mips_host_tlb_lookup(vcpu, va) < 0 &&
1646+
kvm_mips_handle_kseg0_tlb_fault(va, vcpu)) {
1647+
kvm_err("%s: handling mapped kseg0 tlb fault for %lx, vcpu: %p, ASID: %#lx\n",
1648+
__func__, va, vcpu, read_c0_entryhi());
1649+
er = EMULATE_FAIL;
1650+
preempt_enable();
1651+
goto done;
1652+
}
16471653
} else if ((KVM_GUEST_KSEGX(va) < KVM_GUEST_KSEG0) ||
16481654
KVM_GUEST_KSEGX(va) == KVM_GUEST_KSEG23) {
16491655
int index;
@@ -1680,12 +1686,18 @@ enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst,
16801686
run, vcpu);
16811687
preempt_enable();
16821688
goto dont_update_pc;
1683-
} else {
1684-
/*
1685-
* We fault an entry from the guest tlb to the
1686-
* shadow host TLB
1687-
*/
1688-
kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb);
1689+
}
1690+
/*
1691+
* We fault an entry from the guest tlb to the
1692+
* shadow host TLB
1693+
*/
1694+
if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb)) {
1695+
kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
1696+
__func__, va, index, vcpu,
1697+
read_c0_entryhi());
1698+
er = EMULATE_FAIL;
1699+
preempt_enable();
1700+
goto done;
16891701
}
16901702
}
16911703
} else {
@@ -2659,7 +2671,12 @@ enum emulation_result kvm_mips_handle_tlbmiss(u32 cause,
26592671
* OK we have a Guest TLB entry, now inject it into the
26602672
* shadow host TLB
26612673
*/
2662-
kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb);
2674+
if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb)) {
2675+
kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
2676+
__func__, va, index, vcpu,
2677+
read_c0_entryhi());
2678+
er = EMULATE_FAIL;
2679+
}
26632680
}
26642681
}
26652682

arch/mips/kvm/mmu.c

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
9999
}
100100

101101
gfn = (KVM_GUEST_CPHYSADDR(badvaddr) >> PAGE_SHIFT);
102-
if (gfn >= kvm->arch.guest_pmap_npages) {
102+
if ((gfn | 1) >= kvm->arch.guest_pmap_npages) {
103103
kvm_err("%s: Invalid gfn: %#llx, BadVaddr: %#lx\n", __func__,
104104
gfn, badvaddr);
105105
kvm_mips_dump_host_tlbs();
@@ -138,35 +138,49 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
138138
unsigned long entryhi = 0, entrylo0 = 0, entrylo1 = 0;
139139
struct kvm *kvm = vcpu->kvm;
140140
kvm_pfn_t pfn0, pfn1;
141+
gfn_t gfn0, gfn1;
142+
long tlb_lo[2];
141143
int ret;
142144

143-
if ((tlb->tlb_hi & VPN2_MASK) == 0) {
144-
pfn0 = 0;
145-
pfn1 = 0;
146-
} else {
147-
if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo[0])
148-
>> PAGE_SHIFT) < 0)
149-
return -1;
150-
151-
if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo[1])
152-
>> PAGE_SHIFT) < 0)
153-
return -1;
154-
155-
pfn0 = kvm->arch.guest_pmap[
156-
mips3_tlbpfn_to_paddr(tlb->tlb_lo[0]) >> PAGE_SHIFT];
157-
pfn1 = kvm->arch.guest_pmap[
158-
mips3_tlbpfn_to_paddr(tlb->tlb_lo[1]) >> PAGE_SHIFT];
145+
tlb_lo[0] = tlb->tlb_lo[0];
146+
tlb_lo[1] = tlb->tlb_lo[1];
147+
148+
/*
149+
* The commpage address must not be mapped to anything else if the guest
150+
* TLB contains entries nearby, or commpage accesses will break.
151+
*/
152+
if (!((tlb->tlb_hi ^ KVM_GUEST_COMMPAGE_ADDR) &
153+
VPN2_MASK & (PAGE_MASK << 1)))
154+
tlb_lo[(KVM_GUEST_COMMPAGE_ADDR >> PAGE_SHIFT) & 1] = 0;
155+
156+
gfn0 = mips3_tlbpfn_to_paddr(tlb_lo[0]) >> PAGE_SHIFT;
157+
gfn1 = mips3_tlbpfn_to_paddr(tlb_lo[1]) >> PAGE_SHIFT;
158+
if (gfn0 >= kvm->arch.guest_pmap_npages ||
159+
gfn1 >= kvm->arch.guest_pmap_npages) {
160+
kvm_err("%s: Invalid gfn: [%#llx, %#llx], EHi: %#lx\n",
161+
__func__, gfn0, gfn1, tlb->tlb_hi);
162+
kvm_mips_dump_guest_tlbs(vcpu);
163+
return -1;
159164
}
160165

166+
if (kvm_mips_map_page(kvm, gfn0) < 0)
167+
return -1;
168+
169+
if (kvm_mips_map_page(kvm, gfn1) < 0)
170+
return -1;
171+
172+
pfn0 = kvm->arch.guest_pmap[gfn0];
173+
pfn1 = kvm->arch.guest_pmap[gfn1];
174+
161175
/* Get attributes from the Guest TLB */
162176
entrylo0 = mips3_paddr_to_tlbpfn(pfn0 << PAGE_SHIFT) |
163177
((_page_cachable_default >> _CACHE_SHIFT) << ENTRYLO_C_SHIFT) |
164-
(tlb->tlb_lo[0] & ENTRYLO_D) |
165-
(tlb->tlb_lo[0] & ENTRYLO_V);
178+
(tlb_lo[0] & ENTRYLO_D) |
179+
(tlb_lo[0] & ENTRYLO_V);
166180
entrylo1 = mips3_paddr_to_tlbpfn(pfn1 << PAGE_SHIFT) |
167181
((_page_cachable_default >> _CACHE_SHIFT) << ENTRYLO_C_SHIFT) |
168-
(tlb->tlb_lo[1] & ENTRYLO_D) |
169-
(tlb->tlb_lo[1] & ENTRYLO_V);
182+
(tlb_lo[1] & ENTRYLO_D) |
183+
(tlb_lo[1] & ENTRYLO_V);
170184

171185
kvm_debug("@ %#lx tlb_lo0: 0x%08lx tlb_lo1: 0x%08lx\n", vcpu->arch.pc,
172186
tlb->tlb_lo[0], tlb->tlb_lo[1]);
@@ -354,9 +368,15 @@ u32 kvm_get_inst(u32 *opc, struct kvm_vcpu *vcpu)
354368
local_irq_restore(flags);
355369
return KVM_INVALID_INST;
356370
}
357-
kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
358-
&vcpu->arch.
359-
guest_tlb[index]);
371+
if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu,
372+
&vcpu->arch.guest_tlb[index])) {
373+
kvm_err("%s: handling mapped seg tlb fault failed for %p, index: %u, vcpu: %p, ASID: %#lx\n",
374+
__func__, opc, index, vcpu,
375+
read_c0_entryhi());
376+
kvm_mips_dump_guest_tlbs(vcpu);
377+
local_irq_restore(flags);
378+
return KVM_INVALID_INST;
379+
}
360380
inst = *(opc);
361381
}
362382
local_irq_restore(flags);

arch/powerpc/kvm/book3s_xics.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,20 +1329,16 @@ static int kvmppc_xics_create(struct kvm_device *dev, u32 type)
13291329
xics->kvm = kvm;
13301330

13311331
/* Already there ? */
1332-
mutex_lock(&kvm->lock);
13331332
if (kvm->arch.xics)
13341333
ret = -EEXIST;
13351334
else
13361335
kvm->arch.xics = xics;
1337-
mutex_unlock(&kvm->lock);
13381336

13391337
if (ret) {
13401338
kfree(xics);
13411339
return ret;
13421340
}
13431341

1344-
xics_debugfs_init(xics);
1345-
13461342
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
13471343
if (cpu_has_feature(CPU_FTR_ARCH_206)) {
13481344
/* Enable real mode support */
@@ -1354,9 +1350,17 @@ static int kvmppc_xics_create(struct kvm_device *dev, u32 type)
13541350
return 0;
13551351
}
13561352

1353+
static void kvmppc_xics_init(struct kvm_device *dev)
1354+
{
1355+
struct kvmppc_xics *xics = (struct kvmppc_xics *)dev->private;
1356+
1357+
xics_debugfs_init(xics);
1358+
}
1359+
13571360
struct kvm_device_ops kvm_xics_ops = {
13581361
.name = "kvm-xics",
13591362
.create = kvmppc_xics_create,
1363+
.init = kvmppc_xics_init,
13601364
.destroy = kvmppc_xics_free,
13611365
.set_attr = xics_set_attr,
13621366
.get_attr = xics_get_attr,

arch/s390/kvm/kvm-s390.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1672,6 +1672,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
16721672
KVM_SYNC_CRS |
16731673
KVM_SYNC_ARCH0 |
16741674
KVM_SYNC_PFAULT;
1675+
kvm_s390_set_prefix(vcpu, 0);
16751676
if (test_kvm_facility(vcpu->kvm, 64))
16761677
vcpu->run->kvm_valid_regs |= KVM_SYNC_RICCB;
16771678
/* fprs can be synchronized via vrs, even if the guest has no vx. With
@@ -2361,8 +2362,10 @@ static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu)
23612362
rc = gmap_mprotect_notify(vcpu->arch.gmap,
23622363
kvm_s390_get_prefix(vcpu),
23632364
PAGE_SIZE * 2, PROT_WRITE);
2364-
if (rc)
2365+
if (rc) {
2366+
kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu);
23652367
return rc;
2368+
}
23662369
goto retry;
23672370
}
23682371

include/linux/kvm_host.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,8 +1113,20 @@ struct kvm_device {
11131113
/* create, destroy, and name are mandatory */
11141114
struct kvm_device_ops {
11151115
const char *name;
1116+
1117+
/*
1118+
* create is called holding kvm->lock and any operations not suitable
1119+
* to do while holding the lock should be deferred to init (see
1120+
* below).
1121+
*/
11161122
int (*create)(struct kvm_device *dev, u32 type);
11171123

1124+
/*
1125+
* init is called after create if create is successful and is called
1126+
* outside of holding kvm->lock.
1127+
*/
1128+
void (*init)(struct kvm_device *dev);
1129+
11181130
/*
11191131
* Destroy is responsible for freeing dev.
11201132
*

virt/kvm/arm/vgic/vgic-init.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
7373
int i, vcpu_lock_idx = -1, ret;
7474
struct kvm_vcpu *vcpu;
7575

76-
mutex_lock(&kvm->lock);
77-
78-
if (irqchip_in_kernel(kvm)) {
79-
ret = -EEXIST;
80-
goto out;
81-
}
76+
if (irqchip_in_kernel(kvm))
77+
return -EEXIST;
8278

8379
/*
8480
* This function is also called by the KVM_CREATE_IRQCHIP handler,
@@ -87,10 +83,8 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
8783
* the proper checks already.
8884
*/
8985
if (type == KVM_DEV_TYPE_ARM_VGIC_V2 &&
90-
!kvm_vgic_global_state.can_emulate_gicv2) {
91-
ret = -ENODEV;
92-
goto out;
93-
}
86+
!kvm_vgic_global_state.can_emulate_gicv2)
87+
return -ENODEV;
9488

9589
/*
9690
* Any time a vcpu is run, vcpu_load is called which tries to grab the
@@ -138,9 +132,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
138132
vcpu = kvm_get_vcpu(kvm, vcpu_lock_idx);
139133
mutex_unlock(&vcpu->mutex);
140134
}
141-
142-
out:
143-
mutex_unlock(&kvm->lock);
144135
return ret;
145136
}
146137

virt/kvm/kvm_main.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,11 @@ static void kvm_destroy_devices(struct kvm *kvm)
696696
{
697697
struct kvm_device *dev, *tmp;
698698

699+
/*
700+
* We do not need to take the kvm->lock here, because nobody else
701+
* has a reference to the struct kvm at this point and therefore
702+
* cannot access the devices list anyhow.
703+
*/
699704
list_for_each_entry_safe(dev, tmp, &kvm->devices, vm_node) {
700705
list_del(&dev->vm_node);
701706
dev->ops->destroy(dev);
@@ -2832,19 +2837,28 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
28322837
dev->ops = ops;
28332838
dev->kvm = kvm;
28342839

2840+
mutex_lock(&kvm->lock);
28352841
ret = ops->create(dev, cd->type);
28362842
if (ret < 0) {
2843+
mutex_unlock(&kvm->lock);
28372844
kfree(dev);
28382845
return ret;
28392846
}
2847+
list_add(&dev->vm_node, &kvm->devices);
2848+
mutex_unlock(&kvm->lock);
2849+
2850+
if (ops->init)
2851+
ops->init(dev);
28402852

28412853
ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
28422854
if (ret < 0) {
28432855
ops->destroy(dev);
2856+
mutex_lock(&kvm->lock);
2857+
list_del(&dev->vm_node);
2858+
mutex_unlock(&kvm->lock);
28442859
return ret;
28452860
}
28462861

2847-
list_add(&dev->vm_node, &kvm->devices);
28482862
kvm_get_kvm(kvm);
28492863
cd->fd = ret;
28502864
return 0;

0 commit comments

Comments
 (0)