Commit d7e1633a authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge branch 'kvm-ppc-next' of...

Merge branch 'kvm-ppc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc into HEAD
parents 14717e20 b1a4286b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/anon_inodes.h>
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/spinlock.h>
#include <linux/page-flags.h>
+31 −1
Original line number Diff line number Diff line
@@ -882,6 +882,24 @@ void kvmppc_set_fscr(struct kvm_vcpu *vcpu, u64 fscr)
}
#endif

static void kvmppc_setup_debug(struct kvm_vcpu *vcpu)
{
	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
		u64 msr = kvmppc_get_msr(vcpu);

		kvmppc_set_msr(vcpu, msr | MSR_SE);
	}
}

static void kvmppc_clear_debug(struct kvm_vcpu *vcpu)
{
	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
		u64 msr = kvmppc_get_msr(vcpu);

		kvmppc_set_msr(vcpu, msr & ~MSR_SE);
	}
}

int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
			  unsigned int exit_nr)
{
@@ -1207,9 +1225,17 @@ program_interrupt:
		break;
#endif
	case BOOK3S_INTERRUPT_MACHINE_CHECK:
		kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
		r = RESUME_GUEST;
		break;
	case BOOK3S_INTERRUPT_TRACE:
		if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
			run->exit_reason = KVM_EXIT_DEBUG;
			r = RESUME_HOST;
		} else {
			kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
			r = RESUME_GUEST;
		}
		break;
	default:
	{
@@ -1479,6 +1505,8 @@ static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
		goto out;
	}

	kvmppc_setup_debug(vcpu);

	/*
	 * Interrupts could be timers for the guest which we have to inject
	 * again, so let's postpone them until we're in the guest and if we
@@ -1501,6 +1529,8 @@ static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)

	ret = __kvmppc_vcpu_run(kvm_run, vcpu);

	kvmppc_clear_debug(vcpu);

	/* No need for kvm_guest_exit. It's done in handle_exit.
	   We also get here with interrupts enabled. */

+17 −12
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ static int ics_deliver_irq(struct kvmppc_xics *xics, u32 irq, u32 level)
	 * we are the only setter, thus concurrent access is undefined
	 * to begin with.
	 */
	if (level == 1 || level == KVM_INTERRUPT_SET_LEVEL)
	if ((level == 1 && state->lsi) || level == KVM_INTERRUPT_SET_LEVEL)
		state->asserted = 1;
	else if (level == 0 || level == KVM_INTERRUPT_UNSET) {
		state->asserted = 0;
@@ -280,7 +280,7 @@ static inline bool icp_try_update(struct kvmppc_icp *icp,
	if (!success)
		goto bail;

	XICS_DBG("UPD [%04x] - C:%02x M:%02x PP: %02x PI:%06x R:%d O:%d\n",
	XICS_DBG("UPD [%04lx] - C:%02x M:%02x PP: %02x PI:%06x R:%d O:%d\n",
		 icp->server_num,
		 old.cppr, old.mfrr, old.pending_pri, old.xisr,
		 old.need_resend, old.out_ee);
@@ -336,7 +336,7 @@ static bool icp_try_to_deliver(struct kvmppc_icp *icp, u32 irq, u8 priority,
	union kvmppc_icp_state old_state, new_state;
	bool success;

	XICS_DBG("try deliver %#x(P:%#x) to server %#x\n", irq, priority,
	XICS_DBG("try deliver %#x(P:%#x) to server %#lx\n", irq, priority,
		 icp->server_num);

	do {
@@ -1174,9 +1174,11 @@ static int xics_get_source(struct kvmppc_xics *xics, long irq, u64 addr)
			prio = irqp->saved_priority;
		}
		val |= prio << KVM_XICS_PRIORITY_SHIFT;
		if (irqp->lsi) {
			val |= KVM_XICS_LEVEL_SENSITIVE;
			if (irqp->asserted)
			val |= KVM_XICS_LEVEL_SENSITIVE | KVM_XICS_PENDING;
		else if (irqp->masked_pending || irqp->resend)
				val |= KVM_XICS_PENDING;
		} else if (irqp->masked_pending || irqp->resend)
			val |= KVM_XICS_PENDING;
		ret = 0;
	}
@@ -1228,9 +1230,13 @@ static int xics_set_source(struct kvmppc_xics *xics, long irq, u64 addr)
	irqp->priority = prio;
	irqp->resend = 0;
	irqp->masked_pending = 0;
	irqp->lsi = 0;
	irqp->asserted = 0;
	if ((val & KVM_XICS_PENDING) && (val & KVM_XICS_LEVEL_SENSITIVE))
	if (val & KVM_XICS_LEVEL_SENSITIVE) {
		irqp->lsi = 1;
		if (val & KVM_XICS_PENDING)
			irqp->asserted = 1;
	}
	irqp->exists = 1;
	arch_spin_unlock(&ics->lock);
	local_irq_restore(flags);
@@ -1249,11 +1255,10 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
	return ics_deliver_irq(xics, irq, level);
}

int kvm_set_msi(struct kvm_kernel_irq_routing_entry *irq_entry, struct kvm *kvm,
		int irq_source_id, int level, bool line_status)
int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *irq_entry,
			      struct kvm *kvm, int irq_source_id,
			      int level, bool line_status)
{
	if (!level)
		return -1;
	return kvm_set_irq(kvm, irq_source_id, irq_entry->gsi,
			   level, line_status);
}
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ struct ics_irq_state {
	u8  saved_priority;
	u8  resend;
	u8  masked_pending;
	u8  lsi;		/* level-sensitive interrupt */
	u8  asserted; /* Only for LSI */
	u8  exists;
};
+12 −10
Original line number Diff line number Diff line
@@ -800,9 +800,9 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
	}
}

int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
static int __kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
				unsigned int rt, unsigned int bytes,
		       int is_default_endian)
				int is_default_endian, int sign_extend)
{
	int idx, ret;
	bool host_swabbed;
@@ -827,7 +827,7 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
	vcpu->arch.mmio_host_swabbed = host_swabbed;
	vcpu->mmio_needed = 1;
	vcpu->mmio_is_write = 0;
	vcpu->arch.mmio_sign_extend = 0;
	vcpu->arch.mmio_sign_extend = sign_extend;

	idx = srcu_read_lock(&vcpu->kvm->srcu);

@@ -844,6 +844,13 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,

	return EMULATE_DO_MMIO;
}

int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
		       unsigned int rt, unsigned int bytes,
		       int is_default_endian)
{
	return __kvmppc_handle_load(run, vcpu, rt, bytes, is_default_endian, 0);
}
EXPORT_SYMBOL_GPL(kvmppc_handle_load);

/* Same as above, but sign extends */
@@ -851,12 +858,7 @@ int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu,
			unsigned int rt, unsigned int bytes,
			int is_default_endian)
{
	int r;

	vcpu->arch.mmio_sign_extend = 1;
	r = kvmppc_handle_load(run, vcpu, rt, bytes, is_default_endian);

	return r;
	return __kvmppc_handle_load(run, vcpu, rt, bytes, is_default_endian, 1);
}

int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,