Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cd8e300 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'kvm-updates/2.6.31' of git://git.kernel.org/pub/scm/virt/kvm/kvm

* 'kvm-updates/2.6.31' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (138 commits)
  KVM: Prevent overflow in largepages calculation
  KVM: Disable large pages on misaligned memory slots
  KVM: Add VT-x machine check support
  KVM: VMX: Rename rmode.active to rmode.vm86_active
  KVM: Move "exit due to NMI" handling into vmx_complete_interrupts()
  KVM: Disable CR8 intercept if tpr patching is active
  KVM: Do not migrate pending software interrupts.
  KVM: inject NMI after IRET from a previous NMI, not before.
  KVM: Always request IRQ/NMI window if an interrupt is pending
  KVM: Do not re-execute INTn instruction.
  KVM: skip_emulated_instruction() decode instruction if size is not known
  KVM: Remove irq_pending bitmap
  KVM: Do not allow interrupt injection from userspace if there is a pending event.
  KVM: Unprotect a page if #PF happens during NMI injection.
  KVM: s390: Verify memory in kvm run
  KVM: s390: Sanity check on validity intercept
  KVM: s390: Unlink vcpu on destroy - v2
  KVM: s390: optimize float int lock: spin_lock_bh --> spin_lock
  KVM: s390: use hrtimer for clock wakeup from idle - v2
  KVM: s390: Fix memory slot versus run - v3
  ...
parents ddbb8684 09f8ca74
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -371,6 +371,7 @@ struct kvm_vcpu_arch {
	int last_run_cpu;
	int vmm_tr_slot;
	int vm_tr_slot;
	int sn_rtc_tr_slot;

#define KVM_MP_STATE_RUNNABLE          0
#define KVM_MP_STATE_UNINITIALIZED     1
@@ -465,6 +466,7 @@ struct kvm_arch {
	unsigned long	vmm_init_rr;

	int		online_vcpus;
	int		is_sn2;

	struct kvm_ioapic *vioapic;
	struct kvm_vm_stat stat;
@@ -472,6 +474,7 @@ struct kvm_arch {

	struct list_head assigned_dev_head;
	struct iommu_domain *iommu_domain;
	int iommu_flags;
	struct hlist_head irq_ack_notifier_list;

	unsigned long irq_sources_bitmap;
@@ -578,6 +581,8 @@ struct kvm_vmm_info{
	kvm_vmm_entry 	*vmm_entry;
	kvm_tramp_entry *tramp_entry;
	unsigned long 	vmm_ivt;
	unsigned long	patch_mov_ar;
	unsigned long	patch_mov_ar_sn2;
};

int kvm_highest_pending_irq(struct kvm_vcpu *vcpu);
@@ -585,7 +590,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu);
int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run);
void kvm_sal_emul(struct kvm_vcpu *vcpu);

static inline void kvm_inject_nmi(struct kvm_vcpu *vcpu) {}
#endif /* __ASSEMBLY__*/

#endif
+2 −0
Original line number Diff line number Diff line
@@ -146,6 +146,8 @@
#define PAGE_GATE	__pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
#define PAGE_KERNEL	__pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
#define PAGE_KERNELRX	__pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
#define PAGE_KERNEL_UC	__pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX | \
				 _PAGE_MA_UC)

# ifndef __ASSEMBLY__

+3 −0
Original line number Diff line number Diff line
@@ -610,6 +610,9 @@ static struct irqaction ipi_irqaction = {
	.name =		"IPI"
};

/*
 * KVM uses this interrupt to force a cpu out of guest mode
 */
static struct irqaction resched_irqaction = {
	.handler =	dummy_handler,
	.flags =	IRQF_DISABLED,
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ if VIRTUALIZATION

config KVM
	tristate "Kernel-based Virtual Machine (KVM) support"
	depends on HAVE_KVM && EXPERIMENTAL
	depends on HAVE_KVM && MODULES && EXPERIMENTAL
	# for device assignment:
	depends on PCI
	select PREEMPT_NOTIFIERS
+170 −93
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@
#include <asm/div64.h>
#include <asm/tlb.h>
#include <asm/elf.h>
#include <asm/sn/addrs.h>
#include <asm/sn/clksupport.h>
#include <asm/sn/shub_mmr.h>

#include "misc.h"
#include "vti.h"
@@ -65,6 +68,16 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
	{ NULL }
};

static unsigned long kvm_get_itc(struct kvm_vcpu *vcpu)
{
#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
	if (vcpu->kvm->arch.is_sn2)
		return rtc_time();
	else
#endif
		return ia64_getreg(_IA64_REG_AR_ITC);
}

static void kvm_flush_icache(unsigned long start, unsigned long len)
{
	int l;
@@ -119,8 +132,7 @@ void kvm_arch_hardware_enable(void *garbage)
	unsigned long saved_psr;
	int slot;

	pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base),
				PAGE_KERNEL));
	pte = pte_val(mk_pte_phys(__pa(kvm_vmm_base), PAGE_KERNEL));
	local_irq_save(saved_psr);
	slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
	local_irq_restore(saved_psr);
@@ -283,6 +295,18 @@ static int handle_sal_call(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)

}

static int __apic_accept_irq(struct kvm_vcpu *vcpu, uint64_t vector)
{
	struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);

	if (!test_and_set_bit(vector, &vpd->irr[0])) {
		vcpu->arch.irq_new_pending = 1;
		kvm_vcpu_kick(vcpu);
		return 1;
	}
	return 0;
}

/*
 *  offset: address offset to IPI space.
 *  value:  deliver value.
@@ -292,20 +316,20 @@ static void vcpu_deliver_ipi(struct kvm_vcpu *vcpu, uint64_t dm,
{
	switch (dm) {
	case SAPIC_FIXED:
		kvm_apic_set_irq(vcpu, vector, 0);
		break;
	case SAPIC_NMI:
		kvm_apic_set_irq(vcpu, 2, 0);
		vector = 2;
		break;
	case SAPIC_EXTINT:
		kvm_apic_set_irq(vcpu, 0, 0);
		vector = 0;
		break;
	case SAPIC_INIT:
	case SAPIC_PMI:
	default:
		printk(KERN_ERR"kvm: Unimplemented Deliver reserved IPI!\n");
		break;
		return;
	}
	__apic_accept_irq(vcpu, vector);
}

static struct kvm_vcpu *lid_to_vcpu(struct kvm *kvm, unsigned long id,
@@ -413,6 +437,23 @@ static int handle_switch_rr6(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	return 1;
}

static int kvm_sn2_setup_mappings(struct kvm_vcpu *vcpu)
{
	unsigned long pte, rtc_phys_addr, map_addr;
	int slot;

	map_addr = KVM_VMM_BASE + (1UL << KVM_VMM_SHIFT);
	rtc_phys_addr = LOCAL_MMR_OFFSET | SH_RTC;
	pte = pte_val(mk_pte_phys(rtc_phys_addr, PAGE_KERNEL_UC));
	slot = ia64_itr_entry(0x3, map_addr, pte, PAGE_SHIFT);
	vcpu->arch.sn_rtc_tr_slot = slot;
	if (slot < 0) {
		printk(KERN_ERR "Mayday mayday! RTC mapping failed!\n");
		slot = 0;
	}
	return slot;
}

int kvm_emulate_halt(struct kvm_vcpu *vcpu)
{

@@ -426,7 +467,7 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)

	if (irqchip_in_kernel(vcpu->kvm)) {

		vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset;
		vcpu_now_itc = kvm_get_itc(vcpu) + vcpu->arch.itc_offset;

		if (time_after(vcpu_now_itc, vpd->itm)) {
			vcpu->arch.timer_check = 1;
@@ -447,10 +488,10 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
		hrtimer_cancel(p_ht);
		vcpu->arch.ht_active = 0;

		if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
		if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests) ||
				kvm_cpu_has_pending_timer(vcpu))
			if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
				vcpu->arch.mp_state =
					KVM_MP_STATE_RUNNABLE;
				vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;

		if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE)
			return -EINTR;
@@ -551,22 +592,35 @@ static int kvm_insert_vmm_mapping(struct kvm_vcpu *vcpu)
	if (r < 0)
		goto out;
	vcpu->arch.vm_tr_slot = r;

#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
	if (kvm->arch.is_sn2) {
		r = kvm_sn2_setup_mappings(vcpu);
		if (r < 0)
			goto out;
	}
#endif

	r = 0;
out:
	return r;

}

static void kvm_purge_vmm_mapping(struct kvm_vcpu *vcpu)
{

	struct kvm *kvm = vcpu->kvm;
	ia64_ptr_entry(0x3, vcpu->arch.vmm_tr_slot);
	ia64_ptr_entry(0x3, vcpu->arch.vm_tr_slot);

#if defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_GENERIC)
	if (kvm->arch.is_sn2)
		ia64_ptr_entry(0x3, vcpu->arch.sn_rtc_tr_slot);
#endif
}

static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu)
{
	unsigned long psr;
	int r;
	int cpu = smp_processor_id();

	if (vcpu->arch.last_run_cpu != cpu ||
@@ -578,36 +632,27 @@ static int kvm_vcpu_pre_transition(struct kvm_vcpu *vcpu)

	vcpu->arch.host_rr6 = ia64_get_rr(RR6);
	vti_set_rr6(vcpu->arch.vmm_rr);
	return kvm_insert_vmm_mapping(vcpu);
	local_irq_save(psr);
	r = kvm_insert_vmm_mapping(vcpu);
	local_irq_restore(psr);
	return r;
}

static void kvm_vcpu_post_transition(struct kvm_vcpu *vcpu)
{
	kvm_purge_vmm_mapping(vcpu);
	vti_set_rr6(vcpu->arch.host_rr6);
}

static int  vti_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
	union context *host_ctx, *guest_ctx;
	int r;

	/*Get host and guest context with guest address space.*/
	host_ctx = kvm_get_host_context(vcpu);
	guest_ctx = kvm_get_guest_context(vcpu);

	r = kvm_vcpu_pre_transition(vcpu);
	if (r < 0)
		goto out;
	kvm_vmm_info->tramp_entry(host_ctx, guest_ctx);
	kvm_vcpu_post_transition(vcpu);
	r = 0;
out:
	return r;
}

static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
	int r;
	/*
	 * down_read() may sleep and return with interrupts enabled
	 */
	down_read(&vcpu->kvm->slots_lock);

again:
	if (signal_pending(current)) {
@@ -616,26 +661,31 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
		goto out;
	}

	/*
	 * down_read() may sleep and return with interrupts enabled
	 */
	down_read(&vcpu->kvm->slots_lock);

	preempt_disable();
	local_irq_disable();

	vcpu->guest_mode = 1;
	/*Get host and guest context with guest address space.*/
	host_ctx = kvm_get_host_context(vcpu);
	guest_ctx = kvm_get_guest_context(vcpu);

	clear_bit(KVM_REQ_KICK, &vcpu->requests);

	r = kvm_vcpu_pre_transition(vcpu);
	if (r < 0)
		goto vcpu_run_fail;

	up_read(&vcpu->kvm->slots_lock);
	kvm_guest_enter();
	r = vti_vcpu_run(vcpu, kvm_run);
	if (r < 0) {
		local_irq_enable();
		preempt_enable();
		kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
		goto out;
	}

	/*
	 * Transition to the guest
	 */
	kvm_vmm_info->tramp_entry(host_ctx, guest_ctx);

	kvm_vcpu_post_transition(vcpu);

	vcpu->arch.launched = 1;
	vcpu->guest_mode = 0;
	set_bit(KVM_REQ_KICK, &vcpu->requests);
	local_irq_enable();

	/*
@@ -646,9 +696,10 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	 */
	barrier();
	kvm_guest_exit();
	up_read(&vcpu->kvm->slots_lock);
	preempt_enable();

	down_read(&vcpu->kvm->slots_lock);

	r = kvm_handle_exit(kvm_run, vcpu);

	if (r > 0) {
@@ -657,12 +708,20 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
	}

out:
	up_read(&vcpu->kvm->slots_lock);
	if (r > 0) {
		kvm_resched(vcpu);
		down_read(&vcpu->kvm->slots_lock);
		goto again;
	}

	return r;

vcpu_run_fail:
	local_irq_enable();
	preempt_enable();
	kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
	goto out;
}

static void kvm_set_mmio_data(struct kvm_vcpu *vcpu)
@@ -788,6 +847,9 @@ struct kvm *kvm_arch_create_vm(void)

	if (IS_ERR(kvm))
		return ERR_PTR(-ENOMEM);

	kvm->arch.is_sn2 = ia64_platform_is("sn2");

	kvm_init_vm(kvm);

	kvm->arch.online_vcpus = 0;
@@ -884,7 +946,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
	RESTORE_REGS(saved_gp);

	vcpu->arch.irq_new_pending = 1;
	vcpu->arch.itc_offset = regs->saved_itc - ia64_getreg(_IA64_REG_AR_ITC);
	vcpu->arch.itc_offset = regs->saved_itc - kvm_get_itc(vcpu);
	set_bit(KVM_REQ_RESUME, &vcpu->requests);

	vcpu_put(vcpu);
@@ -1043,10 +1105,6 @@ static void kvm_free_vmm_area(void)
	}
}

static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
}

static int vti_init_vpd(struct kvm_vcpu *vcpu)
{
	int i;
@@ -1165,7 +1223,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
		regs->cr_iip = PALE_RESET_ENTRY;

		/*Initialize itc offset for vcpus*/
		itc_offset = 0UL - ia64_getreg(_IA64_REG_AR_ITC);
		itc_offset = 0UL - kvm_get_itc(vcpu);
		for (i = 0; i < kvm->arch.online_vcpus; i++) {
			v = (struct kvm_vcpu *)((char *)vcpu +
					sizeof(struct kvm_vcpu_data) * i);
@@ -1237,6 +1295,7 @@ static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id)

	local_irq_save(psr);
	r = kvm_insert_vmm_mapping(vcpu);
	local_irq_restore(psr);
	if (r)
		goto fail;
	r = kvm_vcpu_init(vcpu, vcpu->kvm, id);
@@ -1254,13 +1313,11 @@ static int vti_vcpu_setup(struct kvm_vcpu *vcpu, int id)
		goto uninit;

	kvm_purge_vmm_mapping(vcpu);
	local_irq_restore(psr);

	return 0;
uninit:
	kvm_vcpu_uninit(vcpu);
fail:
	local_irq_restore(psr);
	return r;
}

@@ -1291,7 +1348,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
	vcpu->kvm = kvm;

	cpu = get_cpu();
	vti_vcpu_load(vcpu, cpu);
	r = vti_vcpu_setup(vcpu, id);
	put_cpu();

@@ -1427,7 +1483,7 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
	}
	for (i = 0; i < 4; i++)
		regs->insvc[i] = vcpu->arch.insvc[i];
	regs->saved_itc = vcpu->arch.itc_offset + ia64_getreg(_IA64_REG_AR_ITC);
	regs->saved_itc = vcpu->arch.itc_offset + kvm_get_itc(vcpu);
	SAVE_REGS(xtp);
	SAVE_REGS(metaphysical_rr0);
	SAVE_REGS(metaphysical_rr4);
@@ -1574,6 +1630,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,

void kvm_arch_flush_shadow(struct kvm *kvm)
{
	kvm_flush_remote_tlbs(kvm);
}

long kvm_arch_dev_ioctl(struct file *filp,
@@ -1616,6 +1673,35 @@ static int vti_cpu_has_kvm_support(void)
	return 0;
}


/*
 * On SN2, the ITC isn't stable, so copy in fast path code to use the
 * SN2 RTC, replacing the ITC based default verion.
 */
static void kvm_patch_vmm(struct kvm_vmm_info *vmm_info,
			  struct module *module)
{
	unsigned long new_ar, new_ar_sn2;
	unsigned long module_base;

	if (!ia64_platform_is("sn2"))
		return;

	module_base = (unsigned long)module->module_core;

	new_ar = kvm_vmm_base + vmm_info->patch_mov_ar - module_base;
	new_ar_sn2 = kvm_vmm_base + vmm_info->patch_mov_ar_sn2 - module_base;

	printk(KERN_INFO "kvm: Patching ITC emulation to use SGI SN2 RTC "
	       "as source\n");

	/*
	 * Copy the SN2 version of mov_ar into place. They are both
	 * the same size, so 6 bundles is sufficient (6 * 0x10).
	 */
	memcpy((void *)new_ar, (void *)new_ar_sn2, 0x60);
}

static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
			    struct module *module)
{
@@ -1639,6 +1725,7 @@ static int kvm_relocate_vmm(struct kvm_vmm_info *vmm_info,
		return -EFAULT;

	memcpy((void *)kvm_vmm_base, (void *)module_base, vmm_size);
	kvm_patch_vmm(vmm_info, module);
	kvm_flush_icache(kvm_vmm_base, vmm_size);

	/*Recalculate kvm_vmm_info based on new VMM*/
@@ -1792,38 +1879,24 @@ void kvm_arch_hardware_unsetup(void)
{
}

static void vcpu_kick_intr(void *info)
{
#ifdef DEBUG
	struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
	printk(KERN_DEBUG"vcpu_kick_intr %p \n", vcpu);
#endif
}

void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
{
	int ipi_pcpu = vcpu->cpu;
	int cpu = get_cpu();
	int me;
	int cpu = vcpu->cpu;

	if (waitqueue_active(&vcpu->wq))
		wake_up_interruptible(&vcpu->wq);

	if (vcpu->guest_mode && cpu != ipi_pcpu)
		smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0);
	me = get_cpu();
	if (cpu != me && (unsigned) cpu < nr_cpu_ids && cpu_online(cpu))
		if (!test_and_set_bit(KVM_REQ_KICK, &vcpu->requests))
			smp_send_reschedule(cpu);
	put_cpu();
}

int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig)
int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq)
{

	struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd);

	if (!test_and_set_bit(vec, &vpd->irr[0])) {
		vcpu->arch.irq_new_pending = 1;
		kvm_vcpu_kick(vcpu);
		return 1;
	}
	return 0;
	return __apic_accept_irq(vcpu, irq->vector);
}

int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest)
@@ -1836,20 +1909,18 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
	return 0;
}

struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
				       unsigned long bitmap)
int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2)
{
	struct kvm_vcpu *lvcpu = kvm->vcpus[0];
	int i;

	for (i = 1; i < kvm->arch.online_vcpus; i++) {
		if (!kvm->vcpus[i])
			continue;
		if (lvcpu->arch.xtp > kvm->vcpus[i]->arch.xtp)
			lvcpu = kvm->vcpus[i];
	return vcpu1->arch.xtp - vcpu2->arch.xtp;
}

	return lvcpu;
int kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
		int short_hand, int dest, int dest_mode)
{
	struct kvm_lapic *target = vcpu->arch.apic;
	return (dest_mode == 0) ?
		kvm_apic_match_physical_addr(target, dest) :
		kvm_apic_match_logical_addr(target, dest);
}

static int find_highest_bits(int *dat)
@@ -1888,6 +1959,12 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
	return 0;
}

int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu)
{
	/* do real check here */
	return 1;
}

int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
{
	return vcpu->arch.timer_fired;
@@ -1918,6 +1995,7 @@ static int vcpu_reset(struct kvm_vcpu *vcpu)
	long psr;
	local_irq_save(psr);
	r = kvm_insert_vmm_mapping(vcpu);
	local_irq_restore(psr);
	if (r)
		goto fail;

@@ -1930,7 +2008,6 @@ static int vcpu_reset(struct kvm_vcpu *vcpu)
	kvm_purge_vmm_mapping(vcpu);
	r = 0;
fail:
	local_irq_restore(psr);
	return r;
}

Loading