Re: [PATCH/RFC] KVM: s390: protvirt: pass-through rc and rrc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



What about the following. I will rip out RC and RRC but add 
a 32bit flags field (which must be 0) and 3*64 bit reserved.


On 10.02.20 12:45, Christian Borntraeger wrote:
> This would be one variant to get the RC/RRC to userspace.
> 
> Signed-off-by: Christian Borntraeger <borntraeger@xxxxxxxxxx>
> ---
>  arch/s390/kvm/kvm-s390.c | 34 +++++++++++++++++++++++++---------
>  arch/s390/kvm/kvm-s390.h | 15 ++++++++-------
>  arch/s390/kvm/pv.c       | 30 ++++++++++++++++++++++--------
>  include/uapi/linux/kvm.h |  4 ++--
>  4 files changed, 57 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
> index e1bccbb41fdd..8dae9629b47f 100644
> --- a/arch/s390/kvm/kvm-s390.c
> +++ b/arch/s390/kvm/kvm-s390.c
> @@ -2172,6 +2172,8 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  	int r = 0;
>  	void __user *argp = (void __user *)cmd->data;
>  
> +	cmd->rc = 0;
> +	cmd->rrc = 0;
>  	switch (cmd->cmd) {
>  	case KVM_PV_VM_CREATE: {
>  		r = -EINVAL;
> @@ -2192,7 +2194,7 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  			mutex_unlock(&kvm->lock);
>  			break;
>  		}
> -		r = kvm_s390_pv_create_vm(kvm);
> +		r = kvm_s390_pv_create_vm(kvm, cmd);
>  		kvm_s390_vcpu_unblock_all(kvm);
>  		mutex_unlock(&kvm->lock);
>  		break;
> @@ -2205,7 +2207,7 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  		/* All VCPUs have to be destroyed before this call. */
>  		mutex_lock(&kvm->lock);
>  		kvm_s390_vcpu_block_all(kvm);
> -		r = kvm_s390_pv_destroy_vm(kvm);
> +		r = kvm_s390_pv_destroy_vm(kvm, cmd);
>  		if (!r)
>  			kvm_s390_pv_dealloc_vm(kvm);
>  		kvm_s390_vcpu_unblock_all(kvm);
> @@ -2237,7 +2239,7 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  		r = -EFAULT;
>  		if (!copy_from_user(hdr, (void __user *)parms.origin,
>  				   parms.length))
> -			r = kvm_s390_pv_set_sec_parms(kvm, hdr, parms.length);
> +			r = kvm_s390_pv_set_sec_parms(kvm, hdr, parms.length, cmd);
>  
>  		vfree(hdr);
>  		break;
> @@ -2253,7 +2255,7 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  		if (copy_from_user(&unp, argp, sizeof(unp)))
>  			break;
>  
> -		r = kvm_s390_pv_unpack(kvm, unp.addr, unp.size, unp.tweak);
> +		r = kvm_s390_pv_unpack(kvm, unp.addr, unp.size, unp.tweak, cmd);
>  		break;
>  	}
>  	case KVM_PV_VM_VERIFY: {
> @@ -2268,6 +2270,8 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  				  &ret);
>  		VM_EVENT(kvm, 3, "PROTVIRT VERIFY: rc %x rrc %x",
>  			 ret >> 16, ret & 0x0000ffff);
> +		cmd->rc = ret >> 16;
> +		cmd->rrc = ret & 0xffff;
>  		break;
>  	}
>  	default:
> @@ -2385,6 +2389,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
>  			break;
>  
>  		r = kvm_s390_handle_pv(kvm, &args);
> +
> +		if (copy_to_user(argp, &args, sizeof(args)))
> +			r = -EFAULT;
> +
>  		break;
>  	}
>  	default:
> @@ -2650,6 +2658,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>  
>  void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
>  {
> +	struct kvm_pv_cmd dummy;
> +
>  	VCPU_EVENT(vcpu, 3, "%s", "free cpu");
>  	trace_kvm_s390_destroy_vcpu(vcpu->vcpu_id);
>  	kvm_s390_clear_local_irqs(vcpu);
> @@ -2663,7 +2673,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
>  	if (vcpu->kvm->arch.use_cmma)
>  		kvm_s390_vcpu_unsetup_cmma(vcpu);
>  	if (kvm_s390_pv_handle_cpu(vcpu))
> -		kvm_s390_pv_destroy_cpu(vcpu);
> +		kvm_s390_pv_destroy_cpu(vcpu, &dummy);
>  	free_page((unsigned long)(vcpu->arch.sie_block));
>  
>  	kvm_vcpu_uninit(vcpu);
> @@ -2688,11 +2698,13 @@ static void kvm_free_vcpus(struct kvm *kvm)
>  
>  void kvm_arch_destroy_vm(struct kvm *kvm)
>  {
> +	struct kvm_pv_cmd dummy;
> +
>  	kvm_free_vcpus(kvm);
>  	sca_dispose(kvm);
>  	kvm_s390_gisa_destroy(kvm);
>  	if (kvm_s390_pv_is_protected(kvm)) {
> -		kvm_s390_pv_destroy_vm(kvm);
> +		kvm_s390_pv_destroy_vm(kvm, &dummy);
>  		kvm_s390_pv_dealloc_vm(kvm);
>  	}
>  	debug_unregister(kvm->arch.dbf);
> @@ -3153,6 +3165,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
>  {
>  	struct kvm_vcpu *vcpu;
>  	struct sie_page *sie_page;
> +	struct kvm_pv_cmd dummy;
>  	int rc = -EINVAL;
>  
>  	if (!kvm_is_ucontrol(kvm) && !sca_can_add_vcpu(kvm, id))
> @@ -3188,7 +3201,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
>  		goto out_free_sie_block;
>  
>  	if (kvm_s390_pv_is_protected(kvm)) {
> -		rc = kvm_s390_pv_create_cpu(vcpu);
> +		rc = kvm_s390_pv_create_cpu(vcpu, &dummy);
>  		if (rc) {
>  			kvm_vcpu_uninit(vcpu);
>  			goto out_free_sie_block;
> @@ -4511,19 +4524,22 @@ static int kvm_s390_handle_pv_vcpu(struct kvm_vcpu *vcpu,
>  	if (!kvm_s390_pv_is_protected(vcpu->kvm))
>  		return -EINVAL;
>  
> +	cmd->rc = 0;
> +	cmd->rrc = 0;
> +
>  	switch (cmd->cmd) {
>  	case KVM_PV_VCPU_CREATE: {
>  		if (kvm_s390_pv_handle_cpu(vcpu))
>  			return -EINVAL;
>  
> -		r = kvm_s390_pv_create_cpu(vcpu);
> +		r = kvm_s390_pv_create_cpu(vcpu, cmd);
>  		break;
>  	}
>  	case KVM_PV_VCPU_DESTROY: {
>  		if (!kvm_s390_pv_handle_cpu(vcpu))
>  			return -EINVAL;
>  
> -		r = kvm_s390_pv_destroy_cpu(vcpu);
> +		r = kvm_s390_pv_destroy_cpu(vcpu, cmd);
>  		break;
>  	}
>  	default:
> diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
> index 32c0c01d5df0..b77d5f565b5c 100644
> --- a/arch/s390/kvm/kvm-s390.h
> +++ b/arch/s390/kvm/kvm-s390.h
> @@ -199,14 +199,15 @@ static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm)
>  /* implemented in pv.c */
>  void kvm_s390_pv_dealloc_vm(struct kvm *kvm);
>  int kvm_s390_pv_alloc_vm(struct kvm *kvm);
> -int kvm_s390_pv_create_vm(struct kvm *kvm);
> -int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu);
> -int kvm_s390_pv_destroy_vm(struct kvm *kvm);
> -int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu);
> -int kvm_s390_pv_set_sec_parms(struct kvm *kvm, void *hdr, u64 length);
> +int kvm_s390_pv_create_vm(struct kvm *kvm, struct kvm_pv_cmd *cmd);
> +int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, struct kvm_pv_cmd *cmd);
> +int kvm_s390_pv_destroy_vm(struct kvm *kvm, struct kvm_pv_cmd *cmd);
> +int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, struct kvm_pv_cmd *cmd);
> +int kvm_s390_pv_set_sec_parms(struct kvm *kvm, void *hdr, u64 length,
> +			      struct kvm_pv_cmd *cmd);
>  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);
> +		       unsigned long tweak, struct kvm_pv_cmd *cmd);
> +int kvm_s390_pv_verify(struct kvm *kvm, struct kvm_pv_cmd *cmd);
>  
>  static inline bool kvm_s390_pv_is_protected(struct kvm *kvm)
>  {
> diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
> index c1778cb3f8ac..381dc3fefac4 100644
> --- a/arch/s390/kvm/pv.c
> +++ b/arch/s390/kvm/pv.c
> @@ -61,7 +61,7 @@ int kvm_s390_pv_alloc_vm(struct kvm *kvm)
>  	return -ENOMEM;
>  }
>  
> -int kvm_s390_pv_destroy_vm(struct kvm *kvm)
> +int kvm_s390_pv_destroy_vm(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  {
>  	int rc;
>  	u32 ret;
> @@ -72,10 +72,12 @@ int kvm_s390_pv_destroy_vm(struct kvm *kvm)
>  	atomic_set(&kvm->mm->context.is_protected, 0);
>  	VM_EVENT(kvm, 3, "PROTVIRT DESTROY VM: rc %x rrc %x",
>  		 ret >> 16, ret & 0x0000ffff);
> +	cmd->rc = ret >> 16;
> +	cmd->rrc = ret & 0xffff;
>  	return rc;
>  }
>  
> -int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu)
> +int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu, struct kvm_pv_cmd *cmd)
>  {
>  	int rc = 0;
>  	u32 ret;
> @@ -87,6 +89,8 @@ int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu)
>  
>  		VCPU_EVENT(vcpu, 3, "PROTVIRT DESTROY VCPU: cpu %d rc %x rrc %x",
>  			   vcpu->vcpu_id, ret >> 16, ret & 0x0000ffff);
> +		cmd->rc = ret >> 16;
> +		cmd->rrc = ret & 0xffff;
>  	}
>  
>  	free_pages(vcpu->arch.pv.stor_base,
> @@ -98,7 +102,7 @@ int kvm_s390_pv_destroy_cpu(struct kvm_vcpu *vcpu)
>  	return rc;
>  }
>  
> -int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu)
> +int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu, struct kvm_pv_cmd *cmd)
>  {
>  	int rc;
>  	struct uv_cb_csc uvcb = {
> @@ -124,9 +128,13 @@ int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu)
>  	VCPU_EVENT(vcpu, 3, "PROTVIRT CREATE VCPU: cpu %d handle %llx rc %x rrc %x",
>  		   vcpu->vcpu_id, uvcb.cpu_handle, uvcb.header.rc,
>  		   uvcb.header.rrc);
> +	cmd->rc = uvcb.header.rc;
> +	cmd->rrc = uvcb.header.rrc;
>  
>  	if (rc) {
> -		kvm_s390_pv_destroy_cpu(vcpu);
> +		struct kvm_pv_cmd dummy;
> +
> +		kvm_s390_pv_destroy_cpu(vcpu, &dummy);
>  		return -EINVAL;
>  	}
>  
> @@ -138,7 +146,7 @@ int kvm_s390_pv_create_cpu(struct kvm_vcpu *vcpu)
>  	return 0;
>  }
>  
> -int kvm_s390_pv_create_vm(struct kvm *kvm)
> +int kvm_s390_pv_create_vm(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>  {
>  	int rc;
>  
> @@ -162,12 +170,15 @@ int kvm_s390_pv_create_vm(struct kvm *kvm)
>  	VM_EVENT(kvm, 3, "PROTVIRT CREATE VM: handle %llx len %llx rc %x rrc %x",
>  		 uvcb.guest_handle, uvcb.guest_stor_len, uvcb.header.rc,
>  		 uvcb.header.rrc);
> +	cmd->rc = uvcb.header.rc;
> +	cmd->rrc = uvcb.header.rrc;
>  
>  	/* Outputs */
>  	kvm->arch.pv.handle = uvcb.guest_handle;
>  
>  	if (rc && (uvcb.header.rc & UVC_RC_NEED_DESTROY)) {
> -		kvm_s390_pv_destroy_vm(kvm);
> +		struct kvm_pv_cmd dummy;
> +		kvm_s390_pv_destroy_vm(kvm, &dummy);
>  		return -EINVAL;
>  	}
>  	kvm->arch.gmap->guest_handle = uvcb.guest_handle;
> @@ -176,7 +187,7 @@ int kvm_s390_pv_create_vm(struct kvm *kvm)
>  }
>  
>  int kvm_s390_pv_set_sec_parms(struct kvm *kvm,
> -			      void *hdr, u64 length)
> +			      void *hdr, u64 length, struct kvm_pv_cmd *cmd)
>  {
>  	int rc;
>  	struct uv_cb_ssc uvcb = {
> @@ -193,6 +204,9 @@ int kvm_s390_pv_set_sec_parms(struct kvm *kvm,
>  	rc = uv_call(0, (u64)&uvcb);
>  	VM_EVENT(kvm, 3, "PROTVIRT VM SET PARMS: rc %x rrc %x",
>  		 uvcb.header.rc, uvcb.header.rrc);
> +	cmd->rc = uvcb.header.rc;
> +	cmd->rrc = uvcb.header.rrc;
> +
>  	if (rc)
>  		return -EINVAL;
>  	return 0;
> @@ -219,7 +233,7 @@ static int unpack_one(struct kvm *kvm, unsigned long addr, u64 tweak[2])
>  }
>  
>  int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr, unsigned long size,
> -		       unsigned long tweak)
> +		       unsigned long tweak, struct kvm_pv_cmd *cmd)
>  {
>  	int rc = 0;
>  	u64 tw[2] = {tweak, 0};
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index eab741bc12c3..17c1a9556eac 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1508,8 +1508,8 @@ struct kvm_pv_cmd {
>  };
>  
>  /* Available with KVM_CAP_S390_PROTECTED */
> -#define KVM_S390_PV_COMMAND		_IOW(KVMIO, 0xc5, struct kvm_pv_cmd)
> -#define KVM_S390_PV_COMMAND_VCPU	_IOW(KVMIO, 0xc6, struct kvm_pv_cmd)
> +#define KVM_S390_PV_COMMAND		_IOWR(KVMIO, 0xc5, struct kvm_pv_cmd)
> +#define KVM_S390_PV_COMMAND_VCPU	_IOWR(KVMIO, 0xc6, struct kvm_pv_cmd)
>  
>  /* Secure Encrypted Virtualization command */
>  enum sev_cmd_id {
> 




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux