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

Commit a3a9c59a authored by David Hildenbrand's avatar David Hildenbrand Committed by Christian Borntraeger
Browse files

KVM: s390: SIGP SET PREFIX cleanup



This patch cleanes up the the SIGP SET PREFIX code.

A SIGP SET PREFIX irq may only be injected if the target vcpu is
stopped. Let's move the checking code into the injection code and
return -EBUSY if the target vcpu is not stopped.

Reviewed-by: default avatarJens Freimann <jfrei@linux.vnet.ibm.com>
Acked-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 9a022067
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1026,6 +1026,9 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
	trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_SET_PREFIX,
				   prefix->address, 0, 2);

	if (!is_vcpu_stopped(vcpu))
		return -EBUSY;

	*prefix = irq->u.prefix;
	set_bit(IRQ_PEND_SET_PREFIX, &li->pending_irqs);
	return 0;
+11 −19
Original line number Diff line number Diff line
@@ -176,41 +176,33 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
static int __sigp_set_prefix(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu,
			     u32 address, u64 *reg)
{
	struct kvm_s390_local_interrupt *li;
	struct kvm_s390_irq irq = {
		.type = KVM_S390_SIGP_SET_PREFIX,
		.u.prefix.address = address & 0x7fffe000u,
	};
	int rc;

	li = &dst_vcpu->arch.local_int;

	/*
	 * Make sure the new value is valid memory. We only need to check the
	 * first page, since address is 8k aligned and memory pieces are always
	 * at least 1MB aligned and have at least a size of 1MB.
	 */
	address &= 0x7fffe000u;
	if (kvm_is_error_gpa(vcpu->kvm, address)) {
	if (kvm_is_error_gpa(vcpu->kvm, irq.u.prefix.address)) {
		*reg &= 0xffffffff00000000UL;
		*reg |= SIGP_STATUS_INVALID_PARAMETER;
		return SIGP_CC_STATUS_STORED;
	}

	spin_lock(&li->lock);
	/* cpu must be in stopped state */
	if (!(atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
	rc = kvm_s390_inject_vcpu(dst_vcpu, &irq);
	if (rc == -EBUSY) {
		*reg &= 0xffffffff00000000UL;
		*reg |= SIGP_STATUS_INCORRECT_STATE;
		rc = SIGP_CC_STATUS_STORED;
		goto out_li;
		return SIGP_CC_STATUS_STORED;
	} else if (rc == 0) {
		VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x",
			   dst_vcpu->vcpu_id, irq.u.prefix.address);
	}

	li->irq.prefix.address = address;
	set_bit(IRQ_PEND_SET_PREFIX, &li->pending_irqs);
	kvm_s390_vcpu_wakeup(dst_vcpu);
	rc = SIGP_CC_ORDER_CODE_ACCEPTED;

	VCPU_EVENT(vcpu, 4, "set prefix of cpu %02x to %x", dst_vcpu->vcpu_id,
		   address);
out_li:
	spin_unlock(&li->lock);
	return rc;
}