@@ -36,6 +36,12 @@
#define UVC_CMD_SET_SEC_CONF_PARAMS 0x0300
#define UVC_CMD_UNPACK_IMG 0x0301
#define UVC_CMD_VERIFY_IMG 0x0302
+#define UVC_CMD_CPU_RESET 0x0310
+#define UVC_CMD_CPU_RESET_INITIAL 0x0311
+#define UVC_CMD_PERF_CONF_CLEAR_RESET 0x0320
+#define UVC_CMD_CPU_RESET_CLEAR 0x0321
+#define UVC_CMD_CPU_SET_STATE 0x0330
+#define UVC_CMD_SET_UNSHARED_ALL 0x0340
#define UVC_CMD_PIN_PAGE_SHARED 0x0341
#define UVC_CMD_UNPIN_PAGE_SHARED 0x0342
#define UVC_CMD_SET_SHARED_ACCESS 0x1000
@@ -56,6 +62,12 @@ enum uv_cmds_inst {
BIT_UVC_CMD_SET_SEC_PARMS = 11,
BIT_UVC_CMD_UNPACK_IMG = 13,
BIT_UVC_CMD_VERIFY_IMG = 14,
+ BIT_UVC_CMD_CPU_RESET = 15,
+ BIT_UVC_CMD_CPU_RESET_INITIAL = 16,
+ BIT_UVC_CMD_CPU_SET_STATE = 17,
+ BIT_UVC_CMD_PREPARE_CLEAR_RESET = 18,
+ BIT_UVC_CMD_CPU_PERFORM_CLEAR_RESET = 19,
+ BIT_UVC_CMD_REMOVE_SHARED_ACCES = 20,
BIT_UVC_CMD_PIN_PAGE_SHARED = 21,
BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22,
};
@@ -153,6 +165,19 @@ struct uv_cb_unp {
u64 reserved28[3];
} __packed __aligned(8);
+#define PV_CPU_STATE_OPR 1
+#define PV_CPU_STATE_STP 2
+#define PV_CPU_STATE_CHKSTP 3
+
+struct uv_cb_cpu_set_state {
+ struct uv_cb_header header;
+ u64 reserved08[2];
+ u64 cpu_handle;
+ u8 reserved20[7];
+ u8 state;
+ u64 reserved28[5];
+};
+
/*
* A common UV call struct for the following calls:
* Destroy cpu/config
@@ -13,6 +13,7 @@
#include <asm/pgalloc.h>
#include <asm/gmap.h>
#include <asm/virtio-ccw.h>
+#include <asm/uv.h>
#include "kvm-s390.h"
#include "trace.h"
#include "trace-s390.h"
@@ -2272,6 +2272,34 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
ret >> 16, ret & 0x0000ffff);
break;
}
+ case KVM_PV_VM_PERF_CLEAR_RESET: {
+ u32 ret;
+
+ r = -EINVAL;
+ if (!kvm_s390_pv_is_protected(kvm))
+ break;
+
+ r = uv_cmd_nodata(kvm_s390_pv_handle(kvm),
+ UVC_CMD_PERF_CONF_CLEAR_RESET,
+ &ret);
+ VM_EVENT(kvm, 3, "PROTVIRT PERF CLEAR: rc %x rrc %x",
+ ret >> 16, ret & 0x0000ffff);
+ break;
+ }
+ case KVM_PV_VM_UNSHARE: {
+ u32 ret;
+
+ r = -EINVAL;
+ if (!kvm_s390_pv_is_protected(kvm))
+ break;
+
+ r = uv_cmd_nodata(kvm_s390_pv_handle(kvm),
+ UVC_CMD_SET_UNSHARED_ALL,
+ &ret);
+ VM_EVENT(kvm, 3, "PROTVIRT UNSHARE: %d rc %x rrc %x",
+ r, ret >> 16, ret & 0x0000ffff);
+ break;
+ }
default:
return -ENOTTY;
}
@@ -208,6 +208,7 @@ int kvm_s390_pv_set_sec_parms(struct kvm *kvm, void *hdr, u64 length);
int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr, unsigned long size,
unsigned long tweak);
int kvm_s390_pv_verify(struct kvm *kvm);
+int kvm_s390_pv_set_cpu_state(struct kvm_vcpu *vcpu, u8 state);
static inline bool kvm_s390_pv_is_protected(struct kvm *kvm)
{
@@ -236,6 +237,7 @@ static inline int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr,
unsigned long size, unsigned long tweak)
{ return 0; }
static inline int kvm_s390_pv_verify(struct kvm *kvm) { return 0; }
+static inline int kvm_s390_pv_set_cpu_state(struct kvm_vcpu *vcpu, u8 state) { return 0; }
static inline bool kvm_s390_pv_is_protected(struct kvm *kvm) { return 0; }
static inline u64 kvm_s390_pv_handle(struct kvm *kvm) { return 0; }
static inline u64 kvm_s390_pv_handle_cpu(struct kvm_vcpu *vcpu) { return 0; }
@@ -255,3 +255,22 @@ int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr, unsigned long size,
VM_EVENT(kvm, 3, "PROTVIRT VM UNPACK: finished rc %x", rc);
return rc;
}
+
+int kvm_s390_pv_set_cpu_state(struct kvm_vcpu *vcpu, u8 state)
+{
+ int rc;
+ struct uv_cb_cpu_set_state uvcb = {
+ .header.cmd = UVC_CMD_CPU_SET_STATE,
+ .header.len = sizeof(uvcb),
+ .cpu_handle = kvm_s390_pv_handle_cpu(vcpu),
+ .state = state,
+ };
+
+ if (!kvm_s390_pv_handle_cpu(vcpu))
+ return -EINVAL;
+
+ rc = uv_call(0, (u64)&uvcb);
+ if (rc)
+ return -EINVAL;
+ return 0;
+}
@@ -1502,6 +1502,8 @@ enum pv_cmd_id {
KVM_PV_VM_SET_SEC_PARMS,
KVM_PV_VM_UNPACK,
KVM_PV_VM_VERIFY,
+ KVM_PV_VM_PERF_CLEAR_RESET,
+ KVM_PV_VM_UNSHARE,
KVM_PV_VCPU_CREATE,
KVM_PV_VCPU_DESTROY,
};