public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Janosch Frank <frankja@linux.ibm.com>
To: Claudio Imbrenda <imbrenda@linux.ibm.com>, kvm@vger.kernel.org
Cc: cohuck@redhat.com, borntraeger@de.ibm.com, thuth@redhat.com,
	pasic@linux.ibm.com, david@redhat.com,
	linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v6 02/17] KVM: s390: pv: handle secure storage violations for protected guests
Date: Thu, 13 Jan 2022 10:54:52 +0100	[thread overview]
Message-ID: <5ed0347a-6b69-2848-2293-1b3edd562ea4@linux.ibm.com> (raw)
In-Reply-To: <20211203165814.73016-3-imbrenda@linux.ibm.com>

On 12/3/21 17:57, Claudio Imbrenda wrote:
> With upcoming patches, protected guests will be able to trigger secure
> storage violations in normal operation.
> 
> This patch adds handling of secure storage violations for protected
> guests.
> 
> Pages that trigger the exception will be made non-secure before
> attempting to use them again for a different secure guest.

I think we should extend this a bit.

With upcoming patches, protected guests will be able to trigger secure 
storage violations in normal operation. This happens if e.g. a protected 
guest is re-booted with lazy destroy enabled and the new guest is also 
protected.

When the new protected guest touches pages that haven't yet been 
destroyed and thus are accounted to the previous protected guest we will 
see the violation exception.

We handle this exception by first trying to destroy the page because we 
expect it to belong to a defunct protected guest where a destroy should 
be possible. If that fails, we will try to do a normal export of the page.


> 
> Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
> Acked-by: Janosch Frank <frankja@linux.ibm.com>
> ---
>   arch/s390/include/asm/uv.h |  1 +
>   arch/s390/kernel/uv.c      | 55 ++++++++++++++++++++++++++++++++++++++
>   arch/s390/mm/fault.c       | 10 +++++++
>   3 files changed, 66 insertions(+)
> 
> diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
> index 72d3e49c2860..cdbd340188ab 100644
> --- a/arch/s390/include/asm/uv.h
> +++ b/arch/s390/include/asm/uv.h
> @@ -356,6 +356,7 @@ static inline int is_prot_virt_host(void)
>   }
>   
>   int gmap_make_secure(struct gmap *gmap, unsigned long gaddr, void *uvcb);
> +int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr);
>   int uv_destroy_owned_page(unsigned long paddr);
>   int uv_convert_from_secure(unsigned long paddr);
>   int uv_convert_owned_from_secure(unsigned long paddr);
> diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
> index 386d4e42b8d3..f706456f6261 100644
> --- a/arch/s390/kernel/uv.c
> +++ b/arch/s390/kernel/uv.c
> @@ -334,6 +334,61 @@ int gmap_convert_to_secure(struct gmap *gmap, unsigned long gaddr)
>   }
>   EXPORT_SYMBOL_GPL(gmap_convert_to_secure);
>   
> +/**
> + * gmap_destroy_page - Destroy a guest page.
> + * @gmap the gmap of the guest
> + * @gaddr the guest address to destroy
> + *
> + * An attempt will be made to destroy the given guest page. If the attempt
> + * fails, an attempt is made to export the page. If both attempts fail, an
> + * appropriate error is returned.
> + */
> +int gmap_destroy_page(struct gmap *gmap, unsigned long gaddr)
> +{
> +	struct vm_area_struct *vma;
> +	unsigned long uaddr;
> +	struct page *page;
> +	int rc;
> +
> +	rc = -EFAULT;
> +	mmap_read_lock(gmap->mm);
> +
> +	uaddr = __gmap_translate(gmap, gaddr);
> +	if (IS_ERR_VALUE(uaddr))
> +		goto out;
> +	vma = vma_lookup(gmap->mm, uaddr);
> +	if (!vma)
> +		goto out;
> +	/*
> +	 * Huge pages should not be able to become secure
> +	 */

Could be one line

> +	if (is_vm_hugetlb_page(vma))
> +		goto out;
> +
> +	rc = 0;
> +	/* we take an extra reference here */

Because?

> +	page = follow_page(vma, uaddr, FOLL_WRITE | FOLL_GET);
> +	if (IS_ERR_OR_NULL(page))
> +		goto out;
> +	rc = uv_destroy_owned_page(page_to_phys(page));
> +	/*
> +	 * Fault handlers can race; it is possible that two CPUs will fault
> +	 * on the same secure page. One CPU can destroy the page, reboot,
> +	 * re-enter secure mode and import it, while the second CPU was
> +	 * stuck at the beginning of the handler. At some point the second
> +	 * CPU will be able to progress, and it will not be able to destroy
> +	 * the page. In that case we do not want to terminate the process,
> +	 * we instead try to export the page.
> +	 */

So when we export we always export a page that's owned by the new guest, 
do I get that right?

> +	if (rc)
> +		rc = uv_convert_owned_from_secure(page_to_phys(page));
> +	put_page(page);
> +out:
> +	mmap_read_unlock(gmap->mm);
> +	return rc;
> +}
> +EXPORT_SYMBOL_GPL(gmap_destroy_page);
> +
>   /*
>    * To be called with the page locked or with an extra reference! This will
>    * prevent gmap_make_secure from touching the page concurrently. Having 2
> diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
> index d30f5986fa85..a1928c89bbfa 100644
> --- a/arch/s390/mm/fault.c
> +++ b/arch/s390/mm/fault.c
> @@ -853,6 +853,16 @@ NOKPROBE_SYMBOL(do_non_secure_storage_access);
>   
>   void do_secure_storage_violation(struct pt_regs *regs)
>   {
> +	unsigned long gaddr = regs->int_parm_long & __FAIL_ADDR_MASK;
> +	struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
> +
> +	/*
> +	 * If the VM has been rebooted, its address space might still contain
> +	 * secure pages from the previous boot.
> +	 * Clear the page so it can be reused.
> +	 */
> +	if (!gmap_destroy_page(gmap, gaddr))
> +		return;
>   	/*
>   	 * Either KVM messed up the secure guest mapping or the same
>   	 * page is mapped into multiple secure guests.
> 


  reply	other threads:[~2022-01-13  9:55 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-03 16:57 [PATCH v6 00/17] KVM: s390: pv: implement lazy destroy for reboot Claudio Imbrenda
2021-12-03 16:57 ` [PATCH v6 01/17] KVM: s390: pv: leak the topmost page table when destroy fails Claudio Imbrenda
2021-12-03 16:57 ` [PATCH v6 02/17] KVM: s390: pv: handle secure storage violations for protected guests Claudio Imbrenda
2022-01-13  9:54   ` Janosch Frank [this message]
2021-12-03 16:58 ` [PATCH v6 03/17] KVM: s390: pv: handle secure storage exceptions for normal guests Claudio Imbrenda
2022-01-13  9:58   ` Janosch Frank
2021-12-03 16:58 ` [PATCH v6 04/17] KVM: s390: pv: refactor s390_reset_acc Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 05/17] KVM: s390: pv: usage counter instead of flag Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 06/17] KVM: s390: pv: add export before import Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 07/17] KVM: s390: pv: module parameter to fence lazy destroy Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 08/17] KVM: s390: pv: make kvm_s390_cpus_from_pv global Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 09/17] KVM: s390: pv: clear the state without memset Claudio Imbrenda
2022-01-13 10:30   ` Janosch Frank
2021-12-03 16:58 ` [PATCH v6 10/17] KVM: s390: pv: add mmu_notifier Claudio Imbrenda
2021-12-04  2:32   ` kernel test robot
2021-12-03 16:58 ` [PATCH v6 11/17] s390/mm: KVM: pv: when tearing down, try to destroy protected pages Claudio Imbrenda
2022-01-13 10:38   ` Janosch Frank
2021-12-03 16:58 ` [PATCH v6 12/17] KVM: s390: pv: refactoring of kvm_s390_pv_deinit_vm Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 13/17] KVM: s390: pv: cleanup leftover protected VMs if needed Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 14/17] KVM: s390: pv: asynchronous destroy for reboot Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 15/17] KVM: s390: pv: api documentation for asynchronous destroy Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 16/17] KVM: s390: pv: add KVM_CAP_S390_PROT_REBOOT_ASYNC Claudio Imbrenda
2021-12-03 16:58 ` [PATCH v6 17/17] KVM: s390: pv: avoid export before import if possible Claudio Imbrenda

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=5ed0347a-6b69-2848-2293-1b3edd562ea4@linux.ibm.com \
    --to=frankja@linux.ibm.com \
    --cc=borntraeger@de.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=david@redhat.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=pasic@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