aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-07-04 14:29:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-07-04 14:29:59 -0400
commit1b3618b60a487fa219c5381a9c983a00c40e6477 (patch)
tree8aa708adba69aa30d5b65a0734a17e0668c3506b
parent14a6f1989dae9445d4532941bdd6bbad84f4c8da (diff)
parenta88464a8b0ffb2f8dfb69d3ab982169578b50f22 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "Except for the preempt notifiers fix, these are all small bugfixes that could have been waited for -rc2. Sending them now since I was taking care of Peter's patch anyway" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: kvm: add hyper-v crash msrs values KVM: x86: remove data variable from kvm_get_msr_common KVM: s390: virtio-ccw: don't overwrite config space values KVM: x86: keep track of LVT0 changes under APICv KVM: x86: properly restore LVT0 KVM: x86: make vapics_in_nmi_mode atomic sched, preempt_notifier: separate notifier registration from static_key inc/dec
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/include/uapi/asm/hyperv.h11
-rw-r--r--arch/x86/kvm/i8254.c2
-rw-r--r--arch/x86/kvm/lapic.c17
-rw-r--r--arch/x86/kvm/lapic.h1
-rw-r--r--arch/x86/kvm/x86.c4
-rw-r--r--drivers/s390/kvm/virtio_ccw.c11
-rw-r--r--include/linux/preempt.h2
-rw-r--r--kernel/sched/core.c17
-rw-r--r--virt/kvm/kvm_main.c3
10 files changed, 54 insertions, 16 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index c7fa57b529d2..2a7f5d782c33 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -607,7 +607,7 @@ struct kvm_arch {
607 struct kvm_pic *vpic; 607 struct kvm_pic *vpic;
608 struct kvm_ioapic *vioapic; 608 struct kvm_ioapic *vioapic;
609 struct kvm_pit *vpit; 609 struct kvm_pit *vpit;
610 int vapics_in_nmi_mode; 610 atomic_t vapics_in_nmi_mode;
611 struct mutex apic_map_lock; 611 struct mutex apic_map_lock;
612 struct kvm_apic_map *apic_map; 612 struct kvm_apic_map *apic_map;
613 613
diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h
index ce6068dbcfbc..8fba544e9cc4 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -199,6 +199,17 @@
199#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6 199#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
200#define HV_X64_MSR_STIMER3_COUNT 0x400000B7 200#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
201 201
202/* Hyper-V guest crash notification MSR's */
203#define HV_X64_MSR_CRASH_P0 0x40000100
204#define HV_X64_MSR_CRASH_P1 0x40000101
205#define HV_X64_MSR_CRASH_P2 0x40000102
206#define HV_X64_MSR_CRASH_P3 0x40000103
207#define HV_X64_MSR_CRASH_P4 0x40000104
208#define HV_X64_MSR_CRASH_CTL 0x40000105
209#define HV_X64_MSR_CRASH_CTL_NOTIFY (1ULL << 63)
210#define HV_X64_MSR_CRASH_PARAMS \
211 (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
212
202#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001 213#define HV_X64_MSR_HYPERCALL_ENABLE 0x00000001
203#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12 214#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT 12
204#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \ 215#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK \
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index 4dce6f8b6129..f90952f64e79 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -305,7 +305,7 @@ static void pit_do_work(struct kthread_work *work)
305 * LVT0 to NMI delivery. Other PIC interrupts are just sent to 305 * LVT0 to NMI delivery. Other PIC interrupts are just sent to
306 * VCPU0, and only if its LVT0 is in EXTINT mode. 306 * VCPU0, and only if its LVT0 is in EXTINT mode.
307 */ 307 */
308 if (kvm->arch.vapics_in_nmi_mode > 0) 308 if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0)
309 kvm_for_each_vcpu(i, vcpu, kvm) 309 kvm_for_each_vcpu(i, vcpu, kvm)
310 kvm_apic_nmi_wd_deliver(vcpu); 310 kvm_apic_nmi_wd_deliver(vcpu);
311 } 311 }
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 36e9de1b4127..954e98a8c2e3 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1257,16 +1257,17 @@ static void start_apic_timer(struct kvm_lapic *apic)
1257 1257
1258static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) 1258static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)
1259{ 1259{
1260 int nmi_wd_enabled = apic_lvt_nmi_mode(kvm_apic_get_reg(apic, APIC_LVT0)); 1260 bool lvt0_in_nmi_mode = apic_lvt_nmi_mode(lvt0_val);
1261 1261
1262 if (apic_lvt_nmi_mode(lvt0_val)) { 1262 if (apic->lvt0_in_nmi_mode != lvt0_in_nmi_mode) {
1263 if (!nmi_wd_enabled) { 1263 apic->lvt0_in_nmi_mode = lvt0_in_nmi_mode;
1264 if (lvt0_in_nmi_mode) {
1264 apic_debug("Receive NMI setting on APIC_LVT0 " 1265 apic_debug("Receive NMI setting on APIC_LVT0 "
1265 "for cpu %d\n", apic->vcpu->vcpu_id); 1266 "for cpu %d\n", apic->vcpu->vcpu_id);
1266 apic->vcpu->kvm->arch.vapics_in_nmi_mode++; 1267 atomic_inc(&apic->vcpu->kvm->arch.vapics_in_nmi_mode);
1267 } 1268 } else
1268 } else if (nmi_wd_enabled) 1269 atomic_dec(&apic->vcpu->kvm->arch.vapics_in_nmi_mode);
1269 apic->vcpu->kvm->arch.vapics_in_nmi_mode--; 1270 }
1270} 1271}
1271 1272
1272static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) 1273static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val)
@@ -1597,6 +1598,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
1597 if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_LINT0_REENABLED)) 1598 if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_LINT0_REENABLED))
1598 apic_set_reg(apic, APIC_LVT0, 1599 apic_set_reg(apic, APIC_LVT0,
1599 SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); 1600 SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
1601 apic_manage_nmi_watchdog(apic, kvm_apic_get_reg(apic, APIC_LVT0));
1600 1602
1601 apic_set_reg(apic, APIC_DFR, 0xffffffffU); 1603 apic_set_reg(apic, APIC_DFR, 0xffffffffU);
1602 apic_set_spiv(apic, 0xff); 1604 apic_set_spiv(apic, 0xff);
@@ -1822,6 +1824,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu,
1822 apic_update_ppr(apic); 1824 apic_update_ppr(apic);
1823 hrtimer_cancel(&apic->lapic_timer.timer); 1825 hrtimer_cancel(&apic->lapic_timer.timer);
1824 apic_update_lvtt(apic); 1826 apic_update_lvtt(apic);
1827 apic_manage_nmi_watchdog(apic, kvm_apic_get_reg(apic, APIC_LVT0));
1825 update_divide_count(apic); 1828 update_divide_count(apic);
1826 start_apic_timer(apic); 1829 start_apic_timer(apic);
1827 apic->irr_pending = true; 1830 apic->irr_pending = true;
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
index f2f4e10ab772..71952748222a 100644
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
@@ -26,6 +26,7 @@ struct kvm_lapic {
26 struct kvm_vcpu *vcpu; 26 struct kvm_vcpu *vcpu;
27 bool sw_enabled; 27 bool sw_enabled;
28 bool irr_pending; 28 bool irr_pending;
29 bool lvt0_in_nmi_mode;
29 /* Number of bits set in ISR. */ 30 /* Number of bits set in ISR. */
30 s16 isr_count; 31 s16 isr_count;
31 /* The highest vector set in ISR; if -1 - invalid, must scan ISR. */ 32 /* The highest vector set in ISR; if -1 - invalid, must scan ISR. */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ac165c2fb8e5..bbaf44e8f0d3 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2379,8 +2379,6 @@ static int get_msr_hyperv(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
2379 2379
2380int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) 2380int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2381{ 2381{
2382 u64 data;
2383
2384 switch (msr_info->index) { 2382 switch (msr_info->index) {
2385 case MSR_IA32_PLATFORM_ID: 2383 case MSR_IA32_PLATFORM_ID:
2386 case MSR_IA32_EBL_CR_POWERON: 2384 case MSR_IA32_EBL_CR_POWERON:
@@ -2453,7 +2451,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2453 /* TSC increment by tick */ 2451 /* TSC increment by tick */
2454 msr_info->data = 1000ULL; 2452 msr_info->data = 1000ULL;
2455 /* CPU multiplier */ 2453 /* CPU multiplier */
2456 data |= (((uint64_t)4ULL) << 40); 2454 msr_info->data |= (((uint64_t)4ULL) << 40);
2457 break; 2455 break;
2458 case MSR_EFER: 2456 case MSR_EFER:
2459 msr_info->data = vcpu->arch.efer; 2457 msr_info->data = vcpu->arch.efer;
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
index 6f1fa1773e76..f8d8fdb26b72 100644
--- a/drivers/s390/kvm/virtio_ccw.c
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -65,6 +65,7 @@ struct virtio_ccw_device {
65 bool is_thinint; 65 bool is_thinint;
66 bool going_away; 66 bool going_away;
67 bool device_lost; 67 bool device_lost;
68 unsigned int config_ready;
68 void *airq_info; 69 void *airq_info;
69}; 70};
70 71
@@ -833,8 +834,11 @@ static void virtio_ccw_get_config(struct virtio_device *vdev,
833 if (ret) 834 if (ret)
834 goto out_free; 835 goto out_free;
835 836
836 memcpy(vcdev->config, config_area, sizeof(vcdev->config)); 837 memcpy(vcdev->config, config_area, offset + len);
837 memcpy(buf, &vcdev->config[offset], len); 838 if (buf)
839 memcpy(buf, &vcdev->config[offset], len);
840 if (vcdev->config_ready < offset + len)
841 vcdev->config_ready = offset + len;
838 842
839out_free: 843out_free:
840 kfree(config_area); 844 kfree(config_area);
@@ -857,6 +861,9 @@ static void virtio_ccw_set_config(struct virtio_device *vdev,
857 if (!config_area) 861 if (!config_area)
858 goto out_free; 862 goto out_free;
859 863
864 /* Make sure we don't overwrite fields. */
865 if (vcdev->config_ready < offset)
866 virtio_ccw_get_config(vdev, 0, NULL, offset);
860 memcpy(&vcdev->config[offset], buf, len); 867 memcpy(&vcdev->config[offset], buf, len);
861 /* Write the config area to the host. */ 868 /* Write the config area to the host. */
862 memcpy(config_area, vcdev->config, sizeof(vcdev->config)); 869 memcpy(config_area, vcdev->config, sizeof(vcdev->config));
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 0f1534acaf60..84991f185173 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -293,6 +293,8 @@ struct preempt_notifier {
293 struct preempt_ops *ops; 293 struct preempt_ops *ops;
294}; 294};
295 295
296void preempt_notifier_inc(void);
297void preempt_notifier_dec(void);
296void preempt_notifier_register(struct preempt_notifier *notifier); 298void preempt_notifier_register(struct preempt_notifier *notifier);
297void preempt_notifier_unregister(struct preempt_notifier *notifier); 299void preempt_notifier_unregister(struct preempt_notifier *notifier);
298 300
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 5caa029dec5d..78b4bad10081 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2320,13 +2320,27 @@ void wake_up_new_task(struct task_struct *p)
2320 2320
2321static struct static_key preempt_notifier_key = STATIC_KEY_INIT_FALSE; 2321static struct static_key preempt_notifier_key = STATIC_KEY_INIT_FALSE;
2322 2322
2323void preempt_notifier_inc(void)
2324{
2325 static_key_slow_inc(&preempt_notifier_key);
2326}
2327EXPORT_SYMBOL_GPL(preempt_notifier_inc);
2328
2329void preempt_notifier_dec(void)
2330{
2331 static_key_slow_dec(&preempt_notifier_key);
2332}
2333EXPORT_SYMBOL_GPL(preempt_notifier_dec);
2334
2323/** 2335/**
2324 * preempt_notifier_register - tell me when current is being preempted & rescheduled 2336 * preempt_notifier_register - tell me when current is being preempted & rescheduled
2325 * @notifier: notifier struct to register 2337 * @notifier: notifier struct to register
2326 */ 2338 */
2327void preempt_notifier_register(struct preempt_notifier *notifier) 2339void preempt_notifier_register(struct preempt_notifier *notifier)
2328{ 2340{
2329 static_key_slow_inc(&preempt_notifier_key); 2341 if (!static_key_false(&preempt_notifier_key))
2342 WARN(1, "registering preempt_notifier while notifiers disabled\n");
2343
2330 hlist_add_head(&notifier->link, &current->preempt_notifiers); 2344 hlist_add_head(&notifier->link, &current->preempt_notifiers);
2331} 2345}
2332EXPORT_SYMBOL_GPL(preempt_notifier_register); 2346EXPORT_SYMBOL_GPL(preempt_notifier_register);
@@ -2340,7 +2354,6 @@ EXPORT_SYMBOL_GPL(preempt_notifier_register);
2340void preempt_notifier_unregister(struct preempt_notifier *notifier) 2354void preempt_notifier_unregister(struct preempt_notifier *notifier)
2341{ 2355{
2342 hlist_del(&notifier->link); 2356 hlist_del(&notifier->link);
2343 static_key_slow_dec(&preempt_notifier_key);
2344} 2357}
2345EXPORT_SYMBOL_GPL(preempt_notifier_unregister); 2358EXPORT_SYMBOL_GPL(preempt_notifier_unregister);
2346 2359
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 848af90b8091..8b8a44453670 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -553,6 +553,8 @@ static struct kvm *kvm_create_vm(unsigned long type)
553 list_add(&kvm->vm_list, &vm_list); 553 list_add(&kvm->vm_list, &vm_list);
554 spin_unlock(&kvm_lock); 554 spin_unlock(&kvm_lock);
555 555
556 preempt_notifier_inc();
557
556 return kvm; 558 return kvm;
557 559
558out_err: 560out_err:
@@ -620,6 +622,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
620 cleanup_srcu_struct(&kvm->irq_srcu); 622 cleanup_srcu_struct(&kvm->irq_srcu);
621 cleanup_srcu_struct(&kvm->srcu); 623 cleanup_srcu_struct(&kvm->srcu);
622 kvm_arch_free_vm(kvm); 624 kvm_arch_free_vm(kvm);
625 preempt_notifier_dec();
623 hardware_disable_all(); 626 hardware_disable_all();
624 mmdrop(mm); 627 mmdrop(mm);
625} 628}