public inbox for linux-s390@vger.kernel.org
 help / color / mirror / Atom feed
From: Christian Borntraeger <borntraeger@de.ibm.com>
To: David Hildenbrand <david@redhat.com>,
	Janosch Frank <frankja@linux.vnet.ibm.com>
Cc: KVM <kvm@vger.kernel.org>, Cornelia Huck <cohuck@redhat.com>,
	Thomas Huth <thuth@redhat.com>,
	Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
	Claudio Imbrenda <imbrenda@linux.ibm.com>,
	linux-s390 <linux-s390@vger.kernel.org>,
	Michael Mueller <mimu@linux.ibm.com>,
	Vasily Gorbik <gor@linux.ibm.com>,
	Janosch Frank <frankja@linux.ibm.com>
Subject: Re: [PATCH v3 09/37] KVM: s390: protvirt: Add initial vm and cpu lifecycle handling
Date: Thu, 20 Feb 2020 20:44:30 +0100	[thread overview]
Message-ID: <b9aa96ce-9701-cefb-68d8-76d1cba4d5c7@de.ibm.com> (raw)
In-Reply-To: <1f0c2c5a-5964-dc34-73af-7b1776391276@redhat.com>



On 20.02.20 14:02, David Hildenbrand wrote:
> 
>> +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;
>> +
>> +		r = kvm_s390_pv_alloc_vm(kvm);
>> +		if (r)
>> +			break;
>> +
>> +		/* FMT 4 SIE needs esca */
>> +		r = sca_switch_to_extended(kvm);
>> +		if (r) {
>> +			kvm_s390_pv_dealloc_vm(kvm);
>> +			kvm_s390_vcpu_unblock_all(kvm);
> 
> You forgot to remove that.

ack.
> 
>> +			mutex_unlock(&kvm->lock);
> 
> That's certainly wrong as well.

ack.

> 
>> +			break;
>> +		}
>> +		r = kvm_s390_pv_create_vm(kvm, &cmd->rc, &cmd->rrc);
>> +		if (!r)
>> +			r = kvm_s390_cpus_to_pv(kvm, &cmd->rc, &cmd->rrc);
>> +		if (r)
>> +			kvm_s390_pv_destroy_vm(kvm, &dummy, &dummy);
> 
> Should there be a kvm_s390_pv_dealloc_vm() as well?

Hmm yes. But only if destroy does not fail...... see below.

> 
>> +
>> +		break;
>> +	}
>> +	case KVM_PV_DISABLE: {
>> +		r = -EINVAL;
>> +		if (!kvm_s390_pv_is_protected(kvm))
>> +			break;
>> +
>> +		kvm_s390_cpus_from_pv(kvm, &cmd->rc, &cmd->rrc);
>> +		r = kvm_s390_pv_destroy_vm(kvm, &cmd->rc, &cmd->rrc);
>> +		if (!r)
>> +			kvm_s390_pv_dealloc_vm(kvm);
> 
> Hm, if destroy fails, the CPUs would already have been removed.
> 
> Is there a way to make kvm_s390_pv_destroy_vm() never fail? The return
> value is always ignored except here ... which looks wrong.

This should not fail. But if it does we should not free the memory that
we donated to the ultravisor. We then do have a memory leak, but this is 
necessary to keep the integrity of the host. 
I will fix the other places to only call dealloc when destroy succeeded.

Same for VCPU destroy. If that fails I should not free arch.pv.stor_base
will fix.


> 
>> +		break;
>> +	}
> 
> [...]
> 
>> @@ -2558,10 +2724,21 @@ static void kvm_free_vcpus(struct kvm *kvm)
>>  
>>  void kvm_arch_destroy_vm(struct kvm *kvm)
>>  {
>> +	u16 rc, rrc;
>>  	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)) {
> 
> I'd prefer something like kvm_s390_pv_is_protected_unlocked(), but I
> guess for these few use cases, this is fine.

yes lets leave it as is... :-)


> 
> 
>> +		kvm_s390_pv_destroy_vm(kvm, &rc, &rrc);
>> +		kvm_s390_pv_dealloc_vm(kvm);
>> +	}
>> +	debug_unregister(kvm->arch.dbf);
>>  	free_page((unsigned long)kvm->arch.sie_page2);
>>  	if (!kvm_is_ucontrol(kvm))
>>  		gmap_remove(kvm->arch.gmap);
>> @@ -2657,6 +2834,9 @@ static int sca_switch_to_extended(struct kvm *kvm)
>>  	unsigned int vcpu_idx;
>>  	u32 scaol, scaoh;
>>  
>> +	if (kvm->arch.use_esca)
>> +		return 0;
>> +
>>  	new_sca = alloc_pages_exact(sizeof(*new_sca), GFP_KERNEL|__GFP_ZERO);
>>  	if (!new_sca)
>>  		return -ENOMEM;
>> @@ -2908,6 +3088,7 @@ static void kvm_s390_vcpu_setup_model(struct kvm_vcpu *vcpu)
>>  static int kvm_s390_vcpu_setup(struct kvm_vcpu *vcpu)
>>  {
>>  	int rc = 0;
>> +	u16 uvrc, uvrrc;
>>  
>>  	atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH |
>>  						    CPUSTAT_SM |
>> @@ -2975,6 +3156,11 @@ static int kvm_s390_vcpu_setup(struct kvm_vcpu *vcpu)
>>  
>>  	kvm_s390_vcpu_crypto_setup(vcpu);
>>  
>> +	mutex_lock(&vcpu->kvm->lock);
>> +	if (kvm_s390_pv_is_protected(vcpu->kvm))
>> +		rc = kvm_s390_pv_create_cpu(vcpu, &uvrc, &uvrrc);
>> +	mutex_unlock(&vcpu->kvm->lock);
> 
> Do we have to cleanup anything? (e.g., cmma page) I *think*
> kvm_arch_vcpu_destroy() is not called when kvm_arch_vcpu_create() fails ...

Right we need to call kvm_s390_vcpu_unsetup_cmma. To me it looks like
this can be done unconditionally if rc!=0:

@@ -3156,8 +3158,11 @@ static int kvm_s390_vcpu_setup(struct kvm_vcpu *vcpu)
        kvm_s390_vcpu_crypto_setup(vcpu);
 
        mutex_lock(&vcpu->kvm->lock);
-       if (kvm_s390_pv_is_protected(vcpu->kvm))
+       if (kvm_s390_pv_is_protected(vcpu->kvm)) {
                rc = kvm_s390_pv_create_cpu(vcpu, &uvrc, &uvrrc);
+               if (rc)
+                       kvm_s390_vcpu_unsetup_cmma(vcpu);
+       }
        mutex_unlock(&vcpu->kvm->lock);
 
        return rc;


Everything else looks ok, no need to deallocate or so.

[...]

 */
>>  int kvm_s390_handle_wait(struct kvm_vcpu *vcpu);
>>  void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu);
>> diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
>> new file mode 100644
>> index 000000000000..67ea9a18ed8f
>> --- /dev/null
>> +++ b/arch/s390/kvm/pv.c
>> @@ -0,0 +1,256 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Hosting Secure Execution virtual machines
>> + *
>> + * Copyright IBM Corp. 2019
>> + *    Author(s): Janosch Frank <frankja@linux.ibm.com>
> 
> I'd assume you're an author as well at this point ;)

I personally prefer to not have authors in files and after all
I am just cleaning up so that Janosch can take care of QEMU.
But I will at least fixup the Copyright year.


> 
> [...]
> 
>> +
>> +int kvm_s390_pv_set_sec_parms(struct kvm *kvm, void *hdr, u64 length, u16 *rc,
>> +			      u16 *rrc)
>> +{
>> +	struct uv_cb_ssc uvcb = {
>> +		.header.cmd = UVC_CMD_SET_SEC_CONF_PARAMS,
>> +		.header.len = sizeof(uvcb),
>> +		.sec_header_origin = (u64)hdr,
>> +		.sec_header_len = length,
>> +		.guest_handle = kvm_s390_pv_get_handle(kvm),
>> +	};
>> +	int cc;
>> +
>> +	cc = uv_call(0, (u64)&uvcb);
> 
> int cc = ... could be done.
> 

ack. 
> 
>> +	*rc = uvcb.header.rc;
>> +	*rrc = uvcb.header.rrc;
>> +	KVM_UV_EVENT(kvm, 3, "PROTVIRT VM SET PARMS: rc %x rrc %x",
>> +		     *rc, *rrc);
>> +	if (cc)
>> +		return -EINVAL;
>> +	return 0;
>> +}
>> +
>> +static int unpack_one(struct kvm *kvm, unsigned long addr, u64 tweak[2],
>> +		      u16 *rc, u16 *rrc)
>> +{
>> +	struct uv_cb_unp uvcb = {
>> +		.header.cmd = UVC_CMD_UNPACK_IMG,
>> +		.header.len = sizeof(uvcb),
>> +		.guest_handle = kvm_s390_pv_get_handle(kvm),
>> +		.gaddr = addr,
>> +		.tweak[0] = tweak[0],
>> +		.tweak[1] = tweak[1],
>> +	};
>> +	int ret;
>> +
>> +	ret = gmap_make_secure(kvm->arch.gmap, addr, &uvcb);
> 
> ... similarly, with ret.


ack

> 
>> +	*rc = uvcb.header.rc;
>> +	*rrc = uvcb.header.rrc;
>> +
>> +	if (ret && ret != -EAGAIN)
>> +		KVM_UV_EVENT(kvm, 3, "PROTVIRT VM UNPACK: failed addr %llx with rc %x rrc %x",
>> +			     uvcb.gaddr, *rc, *rrc);
>> +	return ret;
>> +}
>> +
>> +int kvm_s390_pv_unpack(struct kvm *kvm, unsigned long addr, unsigned long size,
>> +		       unsigned long tweak, u16 *rc, u16 *rrc)
>> +{
>> +	u64 tw[2] = {tweak, 0};
> 
> I have no idea what tweaks are in this context. So I have to trust you
> guys on the implementation, because I don't understand it.

Its the crypto term. Basically similar idea like salt or nonce.

> 
> Especially, why can't we simply have
> 
> s/tweak/tweak/

? 

> 
> offset = 0;
> 
> while (offset < size) {
> 	...
> 	ret = unpack_one(kvm, addr, tweak, offset, rc, rrc);
> 				    ^ no idea what tweak is
> 	...
> 	... offset +=  PAGE_SIZE;
> }
> 
> But maybe I am missing what the whole array is about.

Both values (the initial 64bit value and the address) form the 128 bit
tweak for the decryption. So the offset is actually part of the tweak.

So yes we could rewrite that using offset and not passing through an array
but tweak + offset as separate u64.

will check if this makes it any clearer
> 
>> +	int ret = 0;
>> +
>> +	if (addr & ~PAGE_MASK || !size || size & ~PAGE_MASK)
>> +		return -EINVAL;
>> +
>> +	KVM_UV_EVENT(kvm, 3, "PROTVIRT VM UNPACK: start addr %lx size %lx",
>> +		     addr, size);
>> +
>> +	while (tw[1] < size) {

> +		ret = unpack_one(kvm, addr, tw, rc, rrc);
>> +		if (ret == -EAGAIN) {
>> +			cond_resched();
>> +			if (fatal_signal_pending(current))
>> +				break;
>> +			continue;
>> +		}
>> +		if (ret)
>> +			break;
>> +		addr += PAGE_SIZE;
>> +		tw[1] += PAGE_SIZE;
>> +	}
>> +	if (!ret)
>> +		KVM_UV_EVENT(kvm, 3, "%s", "PROTVIRT VM UNPACK: successful");
>> +	return ret;
>> +}
> 
> [...]
>> +enum pv_cmd_id {
>> +	KVM_PV_ENABLE,
>> +	KVM_PV_DISABLE,
>> +	KVM_PV_VM_SET_SEC_PARMS,
>> +	KVM_PV_VM_UNPACK,
>> +	KVM_PV_VM_VERIFY,
> 
> I wonder if we should just drop "_VM" from all of these ...

  reply	other threads:[~2020-02-20 19:44 UTC|newest]

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

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=b9aa96ce-9701-cefb-68d8-76d1cba4d5c7@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox