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

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

KVM: s390: sigp: separate preparation handlers



This patch introduces in preparation for further code changes separate handler
functions for:
- SIGP (RE)START - will not be allowed to terminate pending orders
- SIGP (INITIAL) CPU RESET - will be allowed to terminate certain pending orders
- unknown sigp orders

All sigp orders that require user space intervention are logged.

Signed-off-by: default avatarDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Reviewed-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 3d95c7d2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#define SIGP_RESTART		      6
#define SIGP_STOP_AND_STORE_STATUS    9
#define SIGP_INITIAL_CPU_RESET	     11
#define SIGP_CPU_RESET		     12
#define SIGP_SET_PREFIX		     13
#define SIGP_STORE_STATUS_AT_ADDRESS 14
#define SIGP_SET_ARCHITECTURE	     18
+32 −15
Original line number Diff line number Diff line
@@ -284,11 +284,12 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu,
	return rc;
}

/* Test whether the destination CPU is available and not busy */
static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu)
static int __prepare_sigp_re_start(struct kvm_vcpu *vcpu,
				   struct kvm_vcpu *dst_vcpu, u8 order_code)
{
	struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int;
	int rc = SIGP_CC_ORDER_CODE_ACCEPTED;
	/* handle (RE)START in user space */
	int rc = -EOPNOTSUPP;

	spin_lock(&li->lock);
	if (li->action_bits & ACTION_STOP_ON_STOP)
@@ -298,6 +299,20 @@ static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu)
	return rc;
}

static int __prepare_sigp_cpu_reset(struct kvm_vcpu *vcpu,
				    struct kvm_vcpu *dst_vcpu, u8 order_code)
{
	/* handle (INITIAL) CPU RESET in user space */
	return -EOPNOTSUPP;
}

static int __prepare_sigp_unknown(struct kvm_vcpu *vcpu,
				  struct kvm_vcpu *dst_vcpu)
{
	/* handle unknown orders in user space */
	return -EOPNOTSUPP;
}

static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
			   u16 cpu_addr, u32 parameter, u64 *status_reg)
{
@@ -350,25 +365,27 @@ static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
		rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg);
		break;
	case SIGP_START:
		rc = sigp_check_callable(vcpu, dst_vcpu);
		if (rc == SIGP_CC_ORDER_CODE_ACCEPTED)
			rc = -EOPNOTSUPP;    /* Handle START in user space */
		rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code);
		break;
	case SIGP_RESTART:
		vcpu->stat.instruction_sigp_restart++;
		rc = sigp_check_callable(vcpu, dst_vcpu);
		if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) {
			VCPU_EVENT(vcpu, 4,
				   "sigp restart %x to handle userspace",
				   cpu_addr);
			/* user space must know about restart */
			rc = -EOPNOTSUPP;
		}
		rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code);
		break;
	case SIGP_INITIAL_CPU_RESET:
		rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code);
		break;
	case SIGP_CPU_RESET:
		rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code);
		break;
	default:
		rc = -EOPNOTSUPP;
		rc = __prepare_sigp_unknown(vcpu, dst_vcpu);
	}

	if (rc == -EOPNOTSUPP)
		VCPU_EVENT(vcpu, 4,
			   "sigp order %u -> cpu %x: handled in user space",
			   order_code, dst_vcpu->vcpu_id);

	return rc;
}