Commit e44fc8c9 authored by Ekaterina Tumanova's avatar Ekaterina Tumanova Committed by Christian Borntraeger

KVM: s390: introduce post handlers for STSI

The Store System Information (STSI) instruction currently collects all
information it relays to the caller in the kernel. Some information,
however, is only available in user space. An example of this is the
guest name: The kernel always sets "KVMGuest", but user space knows the
actual guest name.

This patch introduces a new exit, KVM_EXIT_S390_STSI, guarded by a
capability that can be enabled by user space if it wants to be able to
insert such data. User space will be provided with the target buffer
and the requested STSI function code.
Reviewed-by: default avatarEric Farman <farman@linux.vnet.ibm.com>
Reviewed-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarEkaterina Tumanova <tumanova@linux.vnet.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 41408c28
...@@ -3304,3 +3304,31 @@ Returns: 0 on success, negative value on error ...@@ -3304,3 +3304,31 @@ Returns: 0 on success, negative value on error
Allows use of the vector registers introduced with z13 processor, and Allows use of the vector registers introduced with z13 processor, and
provides for the synchronization between host and user space. Will provides for the synchronization between host and user space. Will
return -EINVAL if the machine does not support vectors. return -EINVAL if the machine does not support vectors.
7.4 KVM_CAP_S390_USER_STSI
Architectures: s390
Parameters: none
This capability allows post-handlers for the STSI instruction. After
initial handling in the kernel, KVM exits to user space with
KVM_EXIT_S390_STSI to allow user space to insert further data.
Before exiting to userspace, kvm handlers should fill in s390_stsi field of
vcpu->run:
struct {
__u64 addr;
__u8 ar;
__u8 reserved;
__u8 fc;
__u8 sel1;
__u16 sel2;
} s390_stsi;
@addr - guest address of STSI SYSIB
@fc - function code
@sel1 - selector 1
@sel2 - selector 2
@ar - access register number
KVM handlers should exit to userspace with rc = -EREMOTE.
...@@ -565,6 +565,7 @@ struct kvm_arch{ ...@@ -565,6 +565,7 @@ struct kvm_arch{
int use_vectors; int use_vectors;
int user_cpu_state_ctrl; int user_cpu_state_ctrl;
int user_sigp; int user_sigp;
int user_stsi;
struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS];
wait_queue_head_t ipte_wq; wait_queue_head_t ipte_wq;
int ipte_lock_count; int ipte_lock_count;
......
...@@ -178,6 +178,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) ...@@ -178,6 +178,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_VM_ATTRIBUTES: case KVM_CAP_VM_ATTRIBUTES:
case KVM_CAP_MP_STATE: case KVM_CAP_MP_STATE:
case KVM_CAP_S390_USER_SIGP: case KVM_CAP_S390_USER_SIGP:
case KVM_CAP_S390_USER_STSI:
r = 1; r = 1;
break; break;
case KVM_CAP_S390_MEM_OP: case KVM_CAP_S390_MEM_OP:
...@@ -280,6 +281,10 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) ...@@ -280,6 +281,10 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
kvm->arch.use_vectors = MACHINE_HAS_VX; kvm->arch.use_vectors = MACHINE_HAS_VX;
r = MACHINE_HAS_VX ? 0 : -EINVAL; r = MACHINE_HAS_VX ? 0 : -EINVAL;
break; break;
case KVM_CAP_S390_USER_STSI:
kvm->arch.user_stsi = 1;
r = 0;
break;
default: default:
r = -EINVAL; r = -EINVAL;
break; break;
......
...@@ -496,6 +496,17 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem) ...@@ -496,6 +496,17 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem)
ASCEBC(mem->vm[0].cpi, 16); ASCEBC(mem->vm[0].cpi, 16);
} }
static void insert_stsi_usr_data(struct kvm_vcpu *vcpu, u64 addr, ar_t ar,
u8 fc, u8 sel1, u16 sel2)
{
vcpu->run->exit_reason = KVM_EXIT_S390_STSI;
vcpu->run->s390_stsi.addr = addr;
vcpu->run->s390_stsi.ar = ar;
vcpu->run->s390_stsi.fc = fc;
vcpu->run->s390_stsi.sel1 = sel1;
vcpu->run->s390_stsi.sel2 = sel2;
}
static int handle_stsi(struct kvm_vcpu *vcpu) static int handle_stsi(struct kvm_vcpu *vcpu)
{ {
int fc = (vcpu->run->s.regs.gprs[0] & 0xf0000000) >> 28; int fc = (vcpu->run->s.regs.gprs[0] & 0xf0000000) >> 28;
...@@ -556,11 +567,15 @@ static int handle_stsi(struct kvm_vcpu *vcpu) ...@@ -556,11 +567,15 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
rc = kvm_s390_inject_prog_cond(vcpu, rc); rc = kvm_s390_inject_prog_cond(vcpu, rc);
goto out; goto out;
} }
if (vcpu->kvm->arch.user_stsi) {
insert_stsi_usr_data(vcpu, operand2, ar, fc, sel1, sel2);
rc = -EREMOTE;
}
trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2); trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2);
free_page(mem); free_page(mem);
kvm_s390_set_psw_cc(vcpu, 0); kvm_s390_set_psw_cc(vcpu, 0);
vcpu->run->s.regs.gprs[0] = 0; vcpu->run->s.regs.gprs[0] = 0;
return 0; return rc;
out_no_data: out_no_data:
kvm_s390_set_psw_cc(vcpu, 3); kvm_s390_set_psw_cc(vcpu, 3);
out: out:
......
...@@ -172,6 +172,7 @@ struct kvm_pit_config { ...@@ -172,6 +172,7 @@ struct kvm_pit_config {
#define KVM_EXIT_S390_TSCH 22 #define KVM_EXIT_S390_TSCH 22
#define KVM_EXIT_EPR 23 #define KVM_EXIT_EPR 23
#define KVM_EXIT_SYSTEM_EVENT 24 #define KVM_EXIT_SYSTEM_EVENT 24
#define KVM_EXIT_S390_STSI 25
/* For KVM_EXIT_INTERNAL_ERROR */ /* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */ /* Emulate instruction failed. */
...@@ -309,6 +310,15 @@ struct kvm_run { ...@@ -309,6 +310,15 @@ struct kvm_run {
__u32 type; __u32 type;
__u64 flags; __u64 flags;
} system_event; } system_event;
/* KVM_EXIT_S390_STSI */
struct {
__u64 addr;
__u8 ar;
__u8 reserved;
__u8 fc;
__u8 sel1;
__u16 sel2;
} s390_stsi;
/* Fix the size of the union. */ /* Fix the size of the union. */
char padding[256]; char padding[256];
}; };
...@@ -780,6 +790,7 @@ struct kvm_ppc_smmu_info { ...@@ -780,6 +790,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_S390_USER_SIGP 106 #define KVM_CAP_S390_USER_SIGP 106
#define KVM_CAP_S390_VECTOR_REGISTERS 107 #define KVM_CAP_S390_VECTOR_REGISTERS 107
#define KVM_CAP_S390_MEM_OP 108 #define KVM_CAP_S390_MEM_OP 108
#define KVM_CAP_S390_USER_STSI 109
#ifdef KVM_CAP_IRQ_ROUTING #ifdef KVM_CAP_IRQ_ROUTING
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment