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: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
committed by
Christian Borntraeger
parent
3d95c7d2d7
commit
b898383082
@@ -10,6 +10,7 @@
|
|||||||
#define SIGP_RESTART 6
|
#define SIGP_RESTART 6
|
||||||
#define SIGP_STOP_AND_STORE_STATUS 9
|
#define SIGP_STOP_AND_STORE_STATUS 9
|
||||||
#define SIGP_INITIAL_CPU_RESET 11
|
#define SIGP_INITIAL_CPU_RESET 11
|
||||||
|
#define SIGP_CPU_RESET 12
|
||||||
#define SIGP_SET_PREFIX 13
|
#define SIGP_SET_PREFIX 13
|
||||||
#define SIGP_STORE_STATUS_AT_ADDRESS 14
|
#define SIGP_STORE_STATUS_AT_ADDRESS 14
|
||||||
#define SIGP_SET_ARCHITECTURE 18
|
#define SIGP_SET_ARCHITECTURE 18
|
||||||
|
|||||||
@@ -284,11 +284,12 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test whether the destination CPU is available and not busy */
|
static int __prepare_sigp_re_start(struct kvm_vcpu *vcpu,
|
||||||
static int sigp_check_callable(struct kvm_vcpu *vcpu, struct kvm_vcpu *dst_vcpu)
|
struct kvm_vcpu *dst_vcpu, u8 order_code)
|
||||||
{
|
{
|
||||||
struct kvm_s390_local_interrupt *li = &dst_vcpu->arch.local_int;
|
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);
|
spin_lock(&li->lock);
|
||||||
if (li->action_bits & ACTION_STOP_ON_STOP)
|
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;
|
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,
|
static int handle_sigp_dst(struct kvm_vcpu *vcpu, u8 order_code,
|
||||||
u16 cpu_addr, u32 parameter, u64 *status_reg)
|
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);
|
rc = __sigp_sense_running(vcpu, dst_vcpu, status_reg);
|
||||||
break;
|
break;
|
||||||
case SIGP_START:
|
case SIGP_START:
|
||||||
rc = sigp_check_callable(vcpu, dst_vcpu);
|
rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code);
|
||||||
if (rc == SIGP_CC_ORDER_CODE_ACCEPTED)
|
|
||||||
rc = -EOPNOTSUPP; /* Handle START in user space */
|
|
||||||
break;
|
break;
|
||||||
case SIGP_RESTART:
|
case SIGP_RESTART:
|
||||||
vcpu->stat.instruction_sigp_restart++;
|
vcpu->stat.instruction_sigp_restart++;
|
||||||
rc = sigp_check_callable(vcpu, dst_vcpu);
|
rc = __prepare_sigp_re_start(vcpu, dst_vcpu, order_code);
|
||||||
if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) {
|
break;
|
||||||
VCPU_EVENT(vcpu, 4,
|
case SIGP_INITIAL_CPU_RESET:
|
||||||
"sigp restart %x to handle userspace",
|
rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code);
|
||||||
cpu_addr);
|
break;
|
||||||
/* user space must know about restart */
|
case SIGP_CPU_RESET:
|
||||||
rc = -EOPNOTSUPP;
|
rc = __prepare_sigp_cpu_reset(vcpu, dst_vcpu, order_code);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user