From: Claudio Imbrenda <imbrenda@linux.ibm.com>
To: pbonzini@redhat.com
Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org,
frankja@linux.ibm.com, borntraeger@linux.ibm.com,
hca@linux.ibm.com, gor@linux.ibm.com, agordeev@linux.ibm.com,
thuth@redhat.com, david@redhat.com
Subject: [GIT PULL 28/42] KVM: s390: pv: handle secure storage violations for protected guests
Date: Thu, 21 Jul 2022 18:12:48 +0200 [thread overview]
Message-ID: <20220721161302.156182-29-imbrenda@linux.ibm.com> (raw)
In-Reply-To: <20220721161302.156182-1-imbrenda@linux.ibm.com>
A secure storage violation is triggered when a protected guest tries to
access secure memory that has been mapped erroneously, or that belongs
to a different protected guest or to the ultravisor.
With upcoming patches, protected guests will be able to trigger secure
storage violations in normal operation. This happens for example if a
protected guest is rebooted with deferred destroy enabled and the new
guest is also protected.
When the new protected guest touches pages that have not yet been
destroyed, and thus are accounted to the previous protected guest, a
secure storage violation is raised.
This patch adds handling of secure storage violations for protected
guests.
This exception is handled by first trying to destroy the page, because
it is expected to belong to a defunct protected guest where a destroy
should be possible. Note that a secure page can only be destroyed if
its protected VM does not have any CPUs, which only happens when the
protected VM is being terminated. If that fails, a normal export of
the page is attempted.
This means that pages that trigger the exception will be made
non-secure (in one way or another) before attempting to use them again
for a different secure guest.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Acked-by: Janosch Frank <frankja@linux.ibm.com>
Link: https://lore.kernel.org/r/20220628135619.32410-3-imbrenda@linux.ibm.com
Message-Id: <20220628135619.32410-3-imbrenda@linux.ibm.com>
Signed-off-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 18fe04c8547e..be3ef9dd6972 100644
--- a/arch/s390/include/asm/uv.h
+++ b/arch/s390/include/asm/uv.h
@@ -426,6 +426,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 c13d5a7b71f0..4c91a3dbc05b 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
+ */
+ if (is_vm_hugetlb_page(vma))
+ goto out;
+
+ rc = 0;
+ /* we take an extra reference here */
+ 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.
+ */
+ 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 e173b6187ad5..af1ac49168fb 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -837,6 +837,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.
--
2.36.1
next prev parent reply other threads:[~2022-07-21 16:13 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-21 16:12 [GIT PULL 00/42] KVM: s390: PCI, CPU topology, PV features Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 01/42] s390/sclp: detect the zPCI load/store interpretation facility Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 02/42] s390/sclp: detect the AISII facility Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 03/42] s390/sclp: detect the AENI facility Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 04/42] s390/sclp: detect the AISI facility Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 05/42] s390/airq: pass more TPI info to airq handlers Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 06/42] s390/airq: allow for airq structure that uses an input vector Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 07/42] s390/pci: externalize the SIC operation controls and routine Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 08/42] s390/pci: stash associated GISA designation Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 09/42] s390/pci: stash dtsm and maxstbl Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 10/42] vfio/pci: introduce CONFIG_VFIO_PCI_ZDEV_KVM Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 11/42] KVM: s390: pci: add basic kvm_zdev structure Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 12/42] KVM: s390: pci: do initial setup for AEN interpretation Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 13/42] KVM: s390: pci: enable host forwarding of Adapter Event Notifications Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 14/42] KVM: s390: mechanism to enable guest zPCI Interpretation Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 15/42] KVM: s390: pci: provide routines for enabling/disabling interrupt forwarding Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 16/42] KVM: s390: pci: add routines to start/stop interpretive execution Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 17/42] vfio-pci/zdev: add open/close device hooks Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 18/42] vfio-pci/zdev: add function handle to clp base capability Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 19/42] vfio-pci/zdev: different maxstbl for interpreted devices Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 20/42] KVM: s390: add KVM_S390_ZPCI_OP to manage guest zPCI devices Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 21/42] MAINTAINERS: additional files related kvm s390 pci passthrough Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 22/42] KVM: s390: drop unexpected word 'and' in the comments Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 23/42] s390: Add attestation query information Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 24/42] KVM: s390/pci: fix include duplicates Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 25/42] Documentation: kvm: extend KVM_S390_ZPCI_OP subheading underline Claudio Imbrenda
2022-07-22 1:40 ` Bagas Sanjaya
2022-07-21 16:12 ` [GIT PULL 26/42] KVM: s390: Add facility 197 to the allow list Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 27/42] KVM: s390: pv: leak the topmost page table when destroy fails Claudio Imbrenda
2022-07-21 16:12 ` Claudio Imbrenda [this message]
2022-07-21 16:12 ` [GIT PULL 29/42] KVM: s390: pv: handle secure storage exceptions for normal guests Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 30/42] KVM: s390: pv: refactor s390_reset_acc Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 31/42] KVM: s390: pv: usage counter instead of flag Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 32/42] KVM: s390: pv: add export before import Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 33/42] KVM: s390: pv: clear the state without memset Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 34/42] KVM: s390: pv: Add kvm_s390_cpus_from_pv to kvm-s390.h and add documentation Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 35/42] KVM: s390: pv: add mmu_notifier Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 36/42] s390/mm: KVM: pv: when tearing down, try to destroy protected pages Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 37/42] KVM: s390: pv: refactoring of kvm_s390_pv_deinit_vm Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 38/42] KVM: s390: pv: destroy the configuration before its memory Claudio Imbrenda
2022-07-21 16:12 ` [GIT PULL 39/42] KVM: s390: pv: don't present the ecall interrupt twice Claudio Imbrenda
2022-07-21 16:13 ` [GIT PULL 40/42] KVM: s390: Cleanup ipte lock access and SIIF facility checks Claudio Imbrenda
2022-07-21 16:13 ` [GIT PULL 41/42] KVM: s390: guest support for topology function Claudio Imbrenda
2022-07-21 16:13 ` [GIT PULL 42/42] KVM: s390: resetting the Topology-Change-Report Claudio Imbrenda
2022-07-22 7:17 ` [GIT PULL 00/42] KVM: s390: PCI, CPU topology, PV features Paolo Bonzini
2022-07-22 10:52 ` 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=20220721161302.156182-29-imbrenda@linux.ibm.com \
--to=imbrenda@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=david@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=pbonzini@redhat.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