Skip to content

Commit 9e01297

Browse files
committed
Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM updates from Marcelo Tosatti. * git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: lock slots_lock around device assignment KVM: VMX: Fix kvm_set_shared_msr() called in preemptible context KVM: unmap pages from the iommu when slots are removed KVM: PMU emulation: GLOBAL_CTRL MSR should be enabled on reset
2 parents 9b7f43a + 21a1416 commit 9e01297

File tree

5 files changed

+43
-21
lines changed

5 files changed

+43
-21
lines changed

arch/x86/kvm/pmu.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -459,17 +459,17 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu)
459459
pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1);
460460

461461
if (pmu->version == 1) {
462-
pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1;
463-
return;
462+
pmu->nr_arch_fixed_counters = 0;
463+
} else {
464+
pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
465+
X86_PMC_MAX_FIXED);
466+
pmu->counter_bitmask[KVM_PMC_FIXED] =
467+
((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
464468
}
465469

466-
pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f),
467-
X86_PMC_MAX_FIXED);
468-
pmu->counter_bitmask[KVM_PMC_FIXED] =
469-
((u64)1 << ((entry->edx >> 5) & 0xff)) - 1;
470-
pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1)
471-
| (((1ull << pmu->nr_arch_fixed_counters) - 1)
472-
<< X86_PMC_IDX_FIXED));
470+
pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
471+
(((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED);
472+
pmu->global_ctrl_mask = ~pmu->global_ctrl;
473473
}
474474

475475
void kvm_pmu_init(struct kvm_vcpu *vcpu)

arch/x86/kvm/vmx.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2210,9 +2210,12 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
22102210
msr = find_msr_entry(vmx, msr_index);
22112211
if (msr) {
22122212
msr->data = data;
2213-
if (msr - vmx->guest_msrs < vmx->save_nmsrs)
2213+
if (msr - vmx->guest_msrs < vmx->save_nmsrs) {
2214+
preempt_disable();
22142215
kvm_set_shared_msr(msr->index, msr->data,
22152216
msr->mask);
2217+
preempt_enable();
2218+
}
22162219
break;
22172220
}
22182221
ret = kvm_set_msr_common(vcpu, msr_index, data);

include/linux/kvm_host.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
596596

597597
#ifdef CONFIG_IOMMU_API
598598
int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
599+
void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot);
599600
int kvm_iommu_map_guest(struct kvm *kvm);
600601
int kvm_iommu_unmap_guest(struct kvm *kvm);
601602
int kvm_assign_device(struct kvm *kvm,
@@ -609,6 +610,11 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm,
609610
return 0;
610611
}
611612

613+
static inline void kvm_iommu_unmap_pages(struct kvm *kvm,
614+
struct kvm_memory_slot *slot)
615+
{
616+
}
617+
612618
static inline int kvm_iommu_map_guest(struct kvm *kvm)
613619
{
614620
return -ENODEV;

virt/kvm/iommu.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,13 @@ int kvm_iommu_map_guest(struct kvm *kvm)
240240
return -ENODEV;
241241
}
242242

243+
mutex_lock(&kvm->slots_lock);
244+
243245
kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type);
244-
if (!kvm->arch.iommu_domain)
245-
return -ENOMEM;
246+
if (!kvm->arch.iommu_domain) {
247+
r = -ENOMEM;
248+
goto out_unlock;
249+
}
246250

247251
if (!allow_unsafe_assigned_interrupts &&
248252
!iommu_domain_has_cap(kvm->arch.iommu_domain,
@@ -253,17 +257,16 @@ int kvm_iommu_map_guest(struct kvm *kvm)
253257
" module option.\n", __func__);
254258
iommu_domain_free(kvm->arch.iommu_domain);
255259
kvm->arch.iommu_domain = NULL;
256-
return -EPERM;
260+
r = -EPERM;
261+
goto out_unlock;
257262
}
258263

259264
r = kvm_iommu_map_memslots(kvm);
260265
if (r)
261-
goto out_unmap;
262-
263-
return 0;
266+
kvm_iommu_unmap_memslots(kvm);
264267

265-
out_unmap:
266-
kvm_iommu_unmap_memslots(kvm);
268+
out_unlock:
269+
mutex_unlock(&kvm->slots_lock);
267270
return r;
268271
}
269272

@@ -310,6 +313,11 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
310313
}
311314
}
312315

316+
void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot)
317+
{
318+
kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages);
319+
}
320+
313321
static int kvm_iommu_unmap_memslots(struct kvm *kvm)
314322
{
315323
int idx;
@@ -320,7 +328,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm)
320328
slots = kvm_memslots(kvm);
321329

322330
kvm_for_each_memslot(memslot, slots)
323-
kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages);
331+
kvm_iommu_unmap_pages(kvm, memslot);
324332

325333
srcu_read_unlock(&kvm->srcu, idx);
326334

@@ -335,7 +343,11 @@ int kvm_iommu_unmap_guest(struct kvm *kvm)
335343
if (!domain)
336344
return 0;
337345

346+
mutex_lock(&kvm->slots_lock);
338347
kvm_iommu_unmap_memslots(kvm);
348+
kvm->arch.iommu_domain = NULL;
349+
mutex_unlock(&kvm->slots_lock);
350+
339351
iommu_domain_free(domain);
340352
return 0;
341353
}

virt/kvm/kvm_main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,12 +808,13 @@ int __kvm_set_memory_region(struct kvm *kvm,
808808
if (r)
809809
goto out_free;
810810

811-
/* map the pages in iommu page table */
811+
/* map/unmap the pages in iommu page table */
812812
if (npages) {
813813
r = kvm_iommu_map_pages(kvm, &new);
814814
if (r)
815815
goto out_free;
816-
}
816+
} else
817+
kvm_iommu_unmap_pages(kvm, &old);
817818

818819
r = -ENOMEM;
819820
slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),

0 commit comments

Comments
 (0)