All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christian Borntraeger <borntraeger@de.ibm.com>
To: Cornelia Huck <cohuck@redhat.com>
Cc: david@redhat.com, Ulrich.Weigand@de.ibm.com,
	frankja@linux.ibm.com, frankja@linux.vnet.ibm.com,
	gor@linux.ibm.com, imbrenda@linux.ibm.com, kvm@vger.kernel.org,
	linux-s390@vger.kernel.org, mimu@linux.ibm.com, thuth@redhat.com
Subject: Re: [PATCH v4.5 09/36] KVM: s390: protvirt: Add initial vm and cpu lifecycle handling
Date: Wed, 26 Feb 2020 14:31:36 +0100	[thread overview]
Message-ID: <dcd80ccd-2d66-502f-62a1-3c794cfcde65@de.ibm.com> (raw)
In-Reply-To: <20200226132640.36c32fd3.cohuck@redhat.com>



On 26.02.20 13:26, Cornelia Huck wrote:
> On Tue, 25 Feb 2020 16:48:22 -0500
> Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> 
>> From: Janosch Frank <frankja@linux.ibm.com>
>>
>> This contains 3 main changes:
>> 1. changes in SIE control block handling for secure guests
>> 2. helper functions for create/destroy/unpack secure guests
>> 3. KVM_S390_PV_COMMAND ioctl to allow userspace dealing with secure
>> machines
>>
>> Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
>> [borntraeger@de.ibm.com: patch merging, splitting, fixing]
>> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
>> ---
>>  arch/s390/include/asm/kvm_host.h |  24 ++-
>>  arch/s390/include/asm/uv.h       |  69 ++++++++
>>  arch/s390/kvm/Makefile           |   2 +-
>>  arch/s390/kvm/kvm-s390.c         | 209 +++++++++++++++++++++++-
>>  arch/s390/kvm/kvm-s390.h         |  33 ++++
>>  arch/s390/kvm/pv.c               | 269 +++++++++++++++++++++++++++++++
>>  include/uapi/linux/kvm.h         |  31 ++++
>>  7 files changed, 633 insertions(+), 4 deletions(-)
>>  create mode 100644 arch/s390/kvm/pv.c
> 
> (...)
> 
>> +static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
>> +{
>> +	int r = 0;
>> +	u16 dummy;
>> +	void __user *argp = (void __user *)cmd->data;
>> +
>> +	switch (cmd->cmd) {
>> +	case KVM_PV_ENABLE: {
>> +		r = -EINVAL;
>> +		if (kvm_s390_pv_is_protected(kvm))
>> +			break;
>> +
>> +		/*
>> +		 *  FMT 4 SIE needs esca. As we never switch back to bsca from
>> +		 *  esca, we need no cleanup in the error cases below
>> +		 */
>> +		r = sca_switch_to_extended(kvm);
>> +		if (r)
>> +			break;
>> +
>> +		r = kvm_s390_pv_init_vm(kvm, &cmd->rc, &cmd->rrc);
>> +		if (r)
>> +			break;
>> +
>> +		r = kvm_s390_cpus_to_pv(kvm, &cmd->rc, &cmd->rrc);
>> +		if (r)
>> +			kvm_s390_pv_deinit_vm(kvm, &dummy, &dummy);
>> +		break;
>> +	}
>> +	case KVM_PV_DISABLE: {
>> +		r = -EINVAL;
>> +		if (!kvm_s390_pv_is_protected(kvm))
>> +			break;
>> +
>> +		r = kvm_s390_cpus_from_pv(kvm, &cmd->rc, &cmd->rrc);
>> +		/*
>> +		 * If a CPU could not be destroyed, destroy VM will also fail.
>> +		 * There is no point in trying to destroy it. Instead return
>> +		 * the rc and rrc from the first CPU that failed destroying.
>> +		 */
>> +		if (r)
>> +			break;
>> +		r = kvm_s390_pv_deinit_vm(kvm, &cmd->rc, &cmd->rrc);
>> +		break;
>> +	}
> 
> IIUC, we may end up in an odd state in the failure case, because we
> might not be able to free up the donated memory, depending on what goes
> wrong. Can userspace do anything useful with the vm if that happens?

The protected VM is still there. Depending on how many CPUs are still
available the secure guest can still run or not. But this is really
fine, no strange things will happen.
> 
> Even more important, userspace cannot cause repeated donations by
> repeatedly calling this ioctl, right?

No, we keep the handle exactly to avoid userspace to not be able
to do disable/enable in a loop.

> 
>> +	case KVM_PV_SET_SEC_PARMS: {
>> +		struct kvm_s390_pv_sec_parm parms = {};
>> +		void *hdr;
>> +
>> +		r = -EINVAL;
>> +		if (!kvm_s390_pv_is_protected(kvm))
>> +			break;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&parms, argp, sizeof(parms)))
>> +			break;
>> +
>> +		/* Currently restricted to 8KB */
>> +		r = -EINVAL;
>> +		if (parms.length > PAGE_SIZE * 2)
>> +			break;
>> +
>> +		r = -ENOMEM;
>> +		hdr = vmalloc(parms.length);
>> +		if (!hdr)
>> +			break;
>> +
>> +		r = -EFAULT;
>> +		if (!copy_from_user(hdr, (void __user *)parms.origin,
>> +				    parms.length))
>> +			r = kvm_s390_pv_set_sec_parms(kvm, hdr, parms.length,
>> +						      &cmd->rc, &cmd->rrc);
>> +
>> +		vfree(hdr);
>> +		break;
>> +	}
>> +	case KVM_PV_UNPACK: {
>> +		struct kvm_s390_pv_unp unp = {};
>> +
>> +		r = -EINVAL;
>> +		if (!kvm_s390_pv_is_protected(kvm))
>> +			break;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&unp, argp, sizeof(unp)))
>> +			break;
>> +
>> +		r = kvm_s390_pv_unpack(kvm, unp.addr, unp.size, unp.tweak,
>> +				       &cmd->rc, &cmd->rrc);
>> +		break;
>> +	}
>> +	case KVM_PV_VERIFY: {
>> +		r = -EINVAL;
>> +		if (!kvm_s390_pv_is_protected(kvm))
>> +			break;
>> +
>> +		r = uv_cmd_nodata(kvm_s390_pv_get_handle(kvm),
>> +				  UVC_CMD_VERIFY_IMG, &cmd->rc, &cmd->rrc);
>> +		KVM_UV_EVENT(kvm, 3, "PROTVIRT VERIFY: rc %x rrc %x", cmd->rc,
>> +			     cmd->rrc);
>> +		break;
>> +	}
>> +	default:
>> +		return -ENOTTY;
> 
> Nit: why not r = -ENOTTY, so you get a single exit point?

can do.

> 
>> +	}
>> +	return r;
>> +}
>> +
>>  long kvm_arch_vm_ioctl(struct file *filp,
>>  		       unsigned int ioctl, unsigned long arg)
>>  {
>> @@ -2262,6 +2419,27 @@ long kvm_arch_vm_ioctl(struct file *filp,
>>  		mutex_unlock(&kvm->slots_lock);
>>  		break;
>>  	}
>> +	case KVM_S390_PV_COMMAND: {
>> +		struct kvm_pv_cmd args;
>> +
>> +		r = 0;
>> +		if (!is_prot_virt_host()) {
>> +			r = -EINVAL;
>> +			break;
>> +		}
>> +		if (copy_from_user(&args, argp, sizeof(args))) {
>> +			r = -EFAULT;
>> +			break;
>> +		}
> 
> The api states that args.flags must be 0... better enforce that?


yes
@@ -2431,6 +2431,10 @@ long kvm_arch_vm_ioctl(struct file *filp,
                        r = -EFAULT;
                        break;
                }
+               if (args.flags) {
+                       r = -EINVAL;
+                       break;
+               }
                mutex_lock(&kvm->lock);
                r = kvm_s390_handle_pv(kvm, &args);
                mutex_unlock(&kvm->lock);



> 
>> +		mutex_lock(&kvm->lock);
>> +		r = kvm_s390_handle_pv(kvm, &args);
>> +		mutex_unlock(&kvm->lock);
>> +		if (copy_to_user(argp, &args, sizeof(args))) {
>> +			r = -EFAULT;
>> +			break;
>> +		}
>> +		break;
>> +	}
>>  	default:
>>  		r = -ENOTTY;
>>  	}
> 
> (...)
> 
>> @@ -2558,10 +2741,19 @@ static void kvm_free_vcpus(struct kvm *kvm)
>>  
>>  void kvm_arch_destroy_vm(struct kvm *kvm)
>>  {
>> +	u16 rc, rrc;
> 
> Nit: missing empty line.

ack.

> 
>>  	kvm_free_vcpus(kvm);
>>  	sca_dispose(kvm);
>> -	debug_unregister(kvm->arch.dbf);
>>  	kvm_s390_gisa_destroy(kvm);
>> +	/*
>> +	 * We are already at the end of life and kvm->lock is not taken.
>> +	 * This is ok as the file descriptor is closed by now and nobody
>> +	 * can mess with the pv state. To avoid lockdep_assert_held from
>> +	 * complaining we do not use kvm_s390_pv_is_protected.
>> +	 */
>> +	if (kvm_s390_pv_get_handle(kvm))
>> +		kvm_s390_pv_deinit_vm(kvm, &rc, &rrc);
>> +	debug_unregister(kvm->arch.dbf);
>>  	free_page((unsigned long)kvm->arch.sie_page2);
>>  	if (!kvm_is_ucontrol(kvm))
>>  		gmap_remove(kvm->arch.gmap);
> 
> (...)
> 
>> @@ -4540,6 +4744,9 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
>>  	if (mem->guest_phys_addr + mem->memory_size > kvm->arch.mem_limit)
>>  		return -EINVAL;
>>  
>> +	/* When we are protected we should not change the memory slots */
> 
> s/protected/protected,/

ack.

> 
>> +	if (kvm_s390_pv_is_protected(kvm))
>> +		return -EINVAL;
>>  	return 0;
>>  }
>>  
> 
> (...)
> 
>> +static int kvm_s390_pv_alloc_vm(struct kvm *kvm)
>> +{
>> +	unsigned long base = uv_info.guest_base_stor_len;
>> +	unsigned long virt = uv_info.guest_virt_var_stor_len;
> 
> base_len and virt_len? Makes the code below less confusing.

this makes some lines longer than 80 for no obvious benefit. I think I will keep
the names.


> 
>> +	unsigned long npages = 0, vlen = 0;
>> +	struct kvm_memory_slot *memslot;
>> +
>> +	kvm->arch.pv.stor_var = NULL;
>> +	kvm->arch.pv.stor_base = __get_free_pages(GFP_KERNEL, get_order(base));
>> +	if (!kvm->arch.pv.stor_base)
>> +		return -ENOMEM;
>> +
>> +	/*
>> +	 * Calculate current guest storage for allocation of the
>> +	 * variable storage, which is based on the length in MB.
>> +	 *
>> +	 * Slots are sorted by GFN
>> +	 */
>> +	mutex_lock(&kvm->slots_lock);
>> +	memslot = kvm_memslots(kvm)->memslots;
>> +	npages = memslot->base_gfn + memslot->npages;
>> +	mutex_unlock(&kvm->slots_lock);
>> +
>> +	kvm->arch.pv.guest_len = npages * PAGE_SIZE;
>> +
>> +	/* Allocate variable storage */
>> +	vlen = ALIGN(virt * ((npages * PAGE_SIZE) / HPAGE_SIZE), PAGE_SIZE);
>> +	vlen += uv_info.guest_virt_base_stor_len;
>> +	kvm->arch.pv.stor_var = vzalloc(vlen);
>> +	if (!kvm->arch.pv.stor_var)
>> +		goto out_err;
>> +	return 0;
>> +
>> +out_err:
>> +	kvm_s390_pv_dealloc_vm(kvm);
>> +	return -ENOMEM;
>> +}
>> +
>> +/* this should not fail, but if it does we must not free the donated memory */
> 
> s/does/does,/

ack

  reply	other threads:[~2020-02-26 13:31 UTC|newest]

Thread overview: 101+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-24 11:40 [PATCH v4 00/36] KVM: s390: Add support for protected VMs Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 01/36] mm/gup/writeback: add callbacks for inaccessible pages Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 02/36] KVM: s390/interrupt: do not pin adapter interrupt pages Christian Borntraeger
2020-02-25 10:18   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 03/36] s390/protvirt: introduce host side setup Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 04/36] s390/protvirt: add ultravisor initialization Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 05/36] s390/mm: provide memory management functions for protected KVM guests Christian Borntraeger
2020-02-25 10:32   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 06/36] s390/mm: add (non)secure page access exceptions handlers Christian Borntraeger
2020-02-25 10:37   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 07/36] KVM: s390: protvirt: Add UV debug trace Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 08/36] KVM: s390: add new variants of UV CALL Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 09/36] KVM: s390: protvirt: Add initial vm and cpu lifecycle handling Christian Borntraeger
2020-02-25 17:46   ` David Hildenbrand
2020-02-25 21:44     ` Christian Borntraeger
2020-02-25 22:29       ` David Hildenbrand
2020-02-25 21:48     ` [PATCH v4.5 " Christian Borntraeger
2020-02-25 22:37       ` David Hildenbrand
2020-02-26  8:12         ` Christian Borntraeger
2020-02-26  8:28           ` David Hildenbrand
2020-02-26  9:12             ` Christian Borntraeger
2020-02-26  9:15               ` David Hildenbrand
2020-02-26 10:01       ` Cornelia Huck
2020-02-26 10:52         ` Christian Borntraeger
2020-02-26 10:38       ` Cornelia Huck
2020-02-26 11:03         ` Christian Borntraeger
2020-02-26 12:26       ` Cornelia Huck
2020-02-26 13:31         ` Christian Borntraeger [this message]
2020-02-26 16:54           ` Cornelia Huck
2020-02-26 17:00             ` [PATCH v4.6 " Christian Borntraeger
2020-02-26 17:08               ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 10/36] KVM: s390: protvirt: Secure memory is not mergeable Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 11/36] KVM: s390/mm: Make pages accessible before destroying the guest Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 12/36] KVM: s390: protvirt: Handle SE notification interceptions Christian Borntraeger
2020-02-25 11:11   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 13/36] KVM: s390: protvirt: Instruction emulation Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 14/36] KVM: s390: protvirt: Implement interrupt injection Christian Borntraeger
2020-02-25 12:07   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 15/36] KVM: s390: protvirt: Add SCLP interrupt handling Christian Borntraeger
2020-02-25 12:11   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 16/36] KVM: s390: protvirt: Handle spec exception loops Christian Borntraeger
2020-02-24 19:14   ` David Hildenbrand
2020-02-24 11:40 ` [PATCH v4 17/36] KVM: s390: protvirt: Add new gprs location handling Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 18/36] KVM: S390: protvirt: Introduce instruction data area bounce buffer Christian Borntraeger
2020-02-24 19:13   ` David Hildenbrand
2020-02-25  7:50     ` Christian Borntraeger
2020-02-25  8:18       ` David Hildenbrand
2020-02-25 17:21       ` Cornelia Huck
2020-02-25 18:39         ` Christian Borntraeger
2020-02-25 17:19   ` Cornelia Huck
2020-02-25 18:37     ` Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 19/36] KVM: s390: protvirt: handle secure guest prefix pages Christian Borntraeger
2020-02-25 12:15   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 20/36] KVM: s390/mm: handle guest unpin events Christian Borntraeger
2020-02-25 12:18   ` Cornelia Huck
2020-02-25 14:21     ` Christian Borntraeger
2020-02-25 14:30       ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 21/36] KVM: s390: protvirt: Write sthyi data to instruction data area Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 22/36] KVM: s390: protvirt: STSI handling Christian Borntraeger
2020-02-24 19:00   ` David Hildenbrand
2020-02-24 11:40 ` [PATCH v4 23/36] KVM: s390: protvirt: disallow one_reg Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 24/36] KVM: s390: protvirt: Do only reset registers that are accessible Christian Borntraeger
2020-02-25 12:32   ` Cornelia Huck
2020-02-25 12:51     ` Janosch Frank
2020-02-25 13:06       ` Cornelia Huck
2020-02-25 13:08         ` Christian Borntraeger
2020-02-25 13:16           ` Cornelia Huck
2020-02-25 13:07     ` Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 25/36] KVM: s390: protvirt: Only sync fmt4 registers Christian Borntraeger
2020-02-25 12:36   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 26/36] KVM: s390: protvirt: Add program exception injection Christian Borntraeger
2020-02-24 11:40 ` [PATCH v4 27/36] KVM: s390: protvirt: UV calls in support of diag308 0, 1 Christian Borntraeger
2020-02-25 12:51   ` Cornelia Huck
2020-02-24 11:40 ` [PATCH v4 28/36] KVM: s390: protvirt: Report CPU state to Ultravisor Christian Borntraeger
2020-02-24 19:05   ` David Hildenbrand
2020-02-25  8:29     ` Christian Borntraeger
2020-02-25  8:41       ` David Hildenbrand
2020-02-25 13:01       ` Cornelia Huck
2020-02-25 13:21         ` Christian Borntraeger
2020-02-25 13:44           ` Cornelia Huck
2020-02-24 11:41 ` [PATCH v4 29/36] KVM: s390: protvirt: Support cmd 5 operation state Christian Borntraeger
2020-02-24 19:08   ` David Hildenbrand
2020-02-25  7:53     ` Christian Borntraeger
2020-02-25 13:21       ` Cornelia Huck
2020-02-24 11:41 ` [PATCH v4 30/36] KVM: s390: protvirt: Mask PSW interrupt bits for interception 104 and 112 Christian Borntraeger
2020-02-24 11:41 ` [PATCH v4 31/36] KVM: s390: protvirt: do not inject interrupts after start Christian Borntraeger
2020-02-24 11:41 ` [PATCH v4 32/36] KVM: s390: protvirt: Add UV cpu reset calls Christian Borntraeger
2020-02-24 11:41 ` [PATCH v4 33/36] DOCUMENTATION: Protected virtual machine introduction and IPL Christian Borntraeger
2020-02-25 16:22   ` Cornelia Huck
2020-02-25 16:42     ` Christian Borntraeger
2020-02-24 11:41 ` [PATCH v4 34/36] s390: protvirt: Add sysfs firmware interface for Ultravisor information Christian Borntraeger
2020-02-25 13:30   ` Cornelia Huck
2020-02-25 13:37   ` Cornelia Huck
2020-02-24 11:41 ` [PATCH v4 35/36] KVM: s390: protvirt: introduce and enable KVM_CAP_S390_PROTECTED Christian Borntraeger
2020-02-25 13:22   ` Cornelia Huck
2020-02-24 11:41 ` [PATCH v4 36/36] KVM: s390: protvirt: Add KVM api documentation Christian Borntraeger
2020-02-25 15:50   ` Cornelia Huck
2020-02-25 19:30     ` Christian Borntraeger
2020-02-27  8:47       ` [PATCH v4.1 " Christian Borntraeger
2020-02-27  9:04         ` Cornelia Huck
2020-02-26  9:35 ` [PATCH v4 00/36] KVM: s390: Add support for protected VMs Christian Borntraeger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=dcd80ccd-2d66-502f-62a1-3c794cfcde65@de.ibm.com \
    --to=borntraeger@de.ibm.com \
    --cc=Ulrich.Weigand@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=david@redhat.com \
    --cc=frankja@linux.ibm.com \
    --cc=frankja@linux.vnet.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=mimu@linux.ibm.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.