diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-28 12:50:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-28 12:50:11 -0400 |
| commit | a1865769254dd4eefbc1e857d17bc2a77d5f8580 (patch) | |
| tree | 0e323458d99e2e1222da0157e80fc44e4313f5e2 | |
| parent | 0d8762c9ee40cf83d5dbf3a22843bc566912b592 (diff) | |
| parent | e45948b071d8be59044ac232d99a2ca83fd93266 (diff) | |
Merge branch 'kvm-updates/2.6.28' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm
* 'kvm-updates/2.6.28' of git://git.kernel.org/pub/scm/linux/kernel/git/avi/kvm:
KVM: ia64: Makefile fix for forcing to re-generate asm-offsets.h
KVM: Future-proof device assignment ABI
KVM: ia64: Fix halt emulation logic
KVM: Fix guest shared interrupt with in-kernel irqchip
KVM: MMU: sync root on paravirt TLB flush
| -rw-r--r-- | arch/ia64/include/asm/kvm_host.h | 6 | ||||
| -rw-r--r-- | arch/ia64/kvm/Makefile | 8 | ||||
| -rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 80 | ||||
| -rw-r--r-- | arch/ia64/kvm/kvm_fw.c | 9 | ||||
| -rw-r--r-- | arch/ia64/kvm/process.c | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/kvm_host.h | 3 | ||||
| -rw-r--r-- | arch/x86/kvm/i8254.c | 11 | ||||
| -rw-r--r-- | arch/x86/kvm/i8254.h | 1 | ||||
| -rw-r--r-- | arch/x86/kvm/mmu.c | 1 | ||||
| -rw-r--r-- | arch/x86/kvm/x86.c | 6 | ||||
| -rw-r--r-- | include/linux/kvm.h | 6 | ||||
| -rw-r--r-- | include/linux/kvm_host.h | 7 | ||||
| -rw-r--r-- | virt/kvm/irq_comm.c | 42 | ||||
| -rw-r--r-- | virt/kvm/kvm_main.c | 12 |
14 files changed, 138 insertions, 56 deletions
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 85db124d37f..c60d324da54 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h | |||
| @@ -365,7 +365,8 @@ struct kvm_vcpu_arch { | |||
| 365 | long itc_offset; | 365 | long itc_offset; |
| 366 | unsigned long itc_check; | 366 | unsigned long itc_check; |
| 367 | unsigned long timer_check; | 367 | unsigned long timer_check; |
| 368 | unsigned long timer_pending; | 368 | unsigned int timer_pending; |
| 369 | unsigned int timer_fired; | ||
| 369 | 370 | ||
| 370 | unsigned long vrr[8]; | 371 | unsigned long vrr[8]; |
| 371 | unsigned long ibr[8]; | 372 | unsigned long ibr[8]; |
| @@ -417,6 +418,9 @@ struct kvm_arch { | |||
| 417 | struct list_head assigned_dev_head; | 418 | struct list_head assigned_dev_head; |
| 418 | struct dmar_domain *intel_iommu_domain; | 419 | struct dmar_domain *intel_iommu_domain; |
| 419 | struct hlist_head irq_ack_notifier_list; | 420 | struct hlist_head irq_ack_notifier_list; |
| 421 | |||
| 422 | unsigned long irq_sources_bitmap; | ||
| 423 | unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; | ||
| 420 | }; | 424 | }; |
| 421 | 425 | ||
| 422 | union cpuid3_t { | 426 | union cpuid3_t { |
diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index cf37f8f490c..3ab4d6d5070 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile | |||
| @@ -29,13 +29,18 @@ define cmd_offsets | |||
| 29 | echo ""; \ | 29 | echo ""; \ |
| 30 | echo "#endif" ) > $@ | 30 | echo "#endif" ) > $@ |
| 31 | endef | 31 | endef |
| 32 | |||
| 32 | # We use internal rules to avoid the "is up to date" message from make | 33 | # We use internal rules to avoid the "is up to date" message from make |
| 33 | arch/ia64/kvm/asm-offsets.s: arch/ia64/kvm/asm-offsets.c | 34 | arch/ia64/kvm/asm-offsets.s: arch/ia64/kvm/asm-offsets.c \ |
| 35 | $(wildcard $(srctree)/arch/ia64/include/asm/*.h)\ | ||
| 36 | $(wildcard $(srctree)/include/linux/*.h) | ||
| 34 | $(call if_changed_dep,cc_s_c) | 37 | $(call if_changed_dep,cc_s_c) |
| 35 | 38 | ||
| 36 | $(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s | 39 | $(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s |
| 37 | $(call cmd,offsets) | 40 | $(call cmd,offsets) |
| 38 | 41 | ||
| 42 | FORCE : $(obj)/$(offsets-file) | ||
| 43 | |||
| 39 | # | 44 | # |
| 40 | # Makefile for Kernel-based Virtual Machine module | 45 | # Makefile for Kernel-based Virtual Machine module |
| 41 | # | 46 | # |
| @@ -53,7 +58,6 @@ endif | |||
| 53 | kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o | 58 | kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o |
| 54 | obj-$(CONFIG_KVM) += kvm.o | 59 | obj-$(CONFIG_KVM) += kvm.o |
| 55 | 60 | ||
| 56 | FORCE : $(obj)/$(offsets-file) | ||
| 57 | EXTRA_CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127 | 61 | EXTRA_CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127 |
| 58 | kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \ | 62 | kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \ |
| 59 | vtlb.o process.o | 63 | vtlb.o process.o |
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index a312c9e9b9e..3caac477de9 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
| @@ -385,6 +385,7 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 385 | struct kvm *kvm = vcpu->kvm; | 385 | struct kvm *kvm = vcpu->kvm; |
| 386 | struct call_data call_data; | 386 | struct call_data call_data; |
| 387 | int i; | 387 | int i; |
| 388 | |||
| 388 | call_data.ptc_g_data = p->u.ptc_g_data; | 389 | call_data.ptc_g_data = p->u.ptc_g_data; |
| 389 | 390 | ||
| 390 | for (i = 0; i < KVM_MAX_VCPUS; i++) { | 391 | for (i = 0; i < KVM_MAX_VCPUS; i++) { |
| @@ -418,33 +419,41 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) | |||
| 418 | ktime_t kt; | 419 | ktime_t kt; |
| 419 | long itc_diff; | 420 | long itc_diff; |
| 420 | unsigned long vcpu_now_itc; | 421 | unsigned long vcpu_now_itc; |
| 421 | |||
| 422 | unsigned long expires; | 422 | unsigned long expires; |
| 423 | struct hrtimer *p_ht = &vcpu->arch.hlt_timer; | 423 | struct hrtimer *p_ht = &vcpu->arch.hlt_timer; |
| 424 | unsigned long cyc_per_usec = local_cpu_data->cyc_per_usec; | 424 | unsigned long cyc_per_usec = local_cpu_data->cyc_per_usec; |
| 425 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); | 425 | struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); |
| 426 | 426 | ||
| 427 | vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset; | 427 | if (irqchip_in_kernel(vcpu->kvm)) { |
| 428 | 428 | ||
| 429 | if (time_after(vcpu_now_itc, vpd->itm)) { | 429 | vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset; |
| 430 | vcpu->arch.timer_check = 1; | ||
| 431 | return 1; | ||
| 432 | } | ||
| 433 | itc_diff = vpd->itm - vcpu_now_itc; | ||
| 434 | if (itc_diff < 0) | ||
| 435 | itc_diff = -itc_diff; | ||
| 436 | 430 | ||
| 437 | expires = div64_u64(itc_diff, cyc_per_usec); | 431 | if (time_after(vcpu_now_itc, vpd->itm)) { |
| 438 | kt = ktime_set(0, 1000 * expires); | 432 | vcpu->arch.timer_check = 1; |
| 439 | vcpu->arch.ht_active = 1; | 433 | return 1; |
| 440 | hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); | 434 | } |
| 435 | itc_diff = vpd->itm - vcpu_now_itc; | ||
| 436 | if (itc_diff < 0) | ||
| 437 | itc_diff = -itc_diff; | ||
| 438 | |||
| 439 | expires = div64_u64(itc_diff, cyc_per_usec); | ||
| 440 | kt = ktime_set(0, 1000 * expires); | ||
| 441 | |||
| 442 | down_read(&vcpu->kvm->slots_lock); | ||
| 443 | vcpu->arch.ht_active = 1; | ||
| 444 | hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); | ||
| 441 | 445 | ||
| 442 | if (irqchip_in_kernel(vcpu->kvm)) { | ||
| 443 | vcpu->arch.mp_state = KVM_MP_STATE_HALTED; | 446 | vcpu->arch.mp_state = KVM_MP_STATE_HALTED; |
| 444 | kvm_vcpu_block(vcpu); | 447 | kvm_vcpu_block(vcpu); |
| 445 | hrtimer_cancel(p_ht); | 448 | hrtimer_cancel(p_ht); |
| 446 | vcpu->arch.ht_active = 0; | 449 | vcpu->arch.ht_active = 0; |
| 447 | 450 | ||
| 451 | if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests)) | ||
| 452 | if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) | ||
| 453 | vcpu->arch.mp_state = | ||
| 454 | KVM_MP_STATE_RUNNABLE; | ||
| 455 | up_read(&vcpu->kvm->slots_lock); | ||
| 456 | |||
| 448 | if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) | 457 | if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) |
| 449 | return -EINTR; | 458 | return -EINTR; |
| 450 | return 1; | 459 | return 1; |
| @@ -484,10 +493,6 @@ static int (*kvm_vti_exit_handlers[])(struct kvm_vcpu *vcpu, | |||
| 484 | static const int kvm_vti_max_exit_handlers = | 493 | static const int kvm_vti_max_exit_handlers = |
| 485 | sizeof(kvm_vti_exit_handlers)/sizeof(*kvm_vti_exit_handlers); | 494 | sizeof(kvm_vti_exit_handlers)/sizeof(*kvm_vti_exit_handlers); |
| 486 | 495 | ||
| 487 | static void kvm_prepare_guest_switch(struct kvm_vcpu *vcpu) | ||
| 488 | { | ||
| 489 | } | ||
| 490 | |||
| 491 | static uint32_t kvm_get_exit_reason(struct kvm_vcpu *vcpu) | 496 | static uint32_t kvm_get_exit_reason(struct kvm_vcpu *vcpu) |
| 492 | { | 497 | { |
| 493 | struct exit_ctl_data *p_exit_data; | 498 | struct exit_ctl_data *p_exit_data; |
| @@ -600,8 +605,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
| 600 | 605 | ||
| 601 | again: | 606 | again: |
| 602 | preempt_disable(); | 607 | preempt_disable(); |
| 603 | |||
| 604 | kvm_prepare_guest_switch(vcpu); | ||
| 605 | local_irq_disable(); | 608 | local_irq_disable(); |
| 606 | 609 | ||
| 607 | if (signal_pending(current)) { | 610 | if (signal_pending(current)) { |
| @@ -614,7 +617,7 @@ again: | |||
| 614 | 617 | ||
| 615 | vcpu->guest_mode = 1; | 618 | vcpu->guest_mode = 1; |
| 616 | kvm_guest_enter(); | 619 | kvm_guest_enter(); |
| 617 | 620 | down_read(&vcpu->kvm->slots_lock); | |
| 618 | r = vti_vcpu_run(vcpu, kvm_run); | 621 | r = vti_vcpu_run(vcpu, kvm_run); |
| 619 | if (r < 0) { | 622 | if (r < 0) { |
| 620 | local_irq_enable(); | 623 | local_irq_enable(); |
| @@ -634,9 +637,8 @@ again: | |||
| 634 | * But we need to prevent reordering, hence this barrier(): | 637 | * But we need to prevent reordering, hence this barrier(): |
| 635 | */ | 638 | */ |
| 636 | barrier(); | 639 | barrier(); |
| 637 | |||
| 638 | kvm_guest_exit(); | 640 | kvm_guest_exit(); |
| 639 | 641 | up_read(&vcpu->kvm->slots_lock); | |
| 640 | preempt_enable(); | 642 | preempt_enable(); |
| 641 | 643 | ||
| 642 | r = kvm_handle_exit(kvm_run, vcpu); | ||
