From: Claudio Imbrenda <imbrenda@linux.ibm.com>
To: kvm@vger.kernel.org
Cc: borntraeger@de.ibm.com, frankja@linux.ibm.com, thuth@redhat.com,
pasic@linux.ibm.com, david@redhat.com,
linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org,
scgl@linux.ibm.com, mimu@linux.ibm.com, nrb@linux.ibm.com
Subject: [PATCH v12 17/18] KVM: s390: pv: support for Destroy fast UVC
Date: Tue, 28 Jun 2022 15:56:18 +0200 [thread overview]
Message-ID: <20220628135619.32410-18-imbrenda@linux.ibm.com> (raw)
In-Reply-To: <20220628135619.32410-1-imbrenda@linux.ibm.com>
Add support for the Destroy Secure Configuration Fast Ultravisor call,
and take advantage of it for asynchronous destroy.
When supported, the protected guest is destroyed immediately using the
new UVC, leaving only the memory to be cleaned up asynchronously.
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/include/asm/uv.h | 10 +++++++
arch/s390/kvm/pv.c | 57 ++++++++++++++++++++++++++++++++------
2 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h
index ba64e0be03bb..8b255d26c5a7 100644
--- a/arch/s390/include/asm/uv.h
+++ b/arch/s390/include/asm/uv.h
@@ -34,6 +34,7 @@
#define UVC_CMD_INIT_UV 0x000f
#define UVC_CMD_CREATE_SEC_CONF 0x0100
#define UVC_CMD_DESTROY_SEC_CONF 0x0101
+#define UVC_CMD_DESTROY_SEC_CONF_FAST 0x0102
#define UVC_CMD_CREATE_SEC_CPU 0x0120
#define UVC_CMD_DESTROY_SEC_CPU 0x0121
#define UVC_CMD_CONV_TO_SEC_STOR 0x0200
@@ -77,6 +78,7 @@ enum uv_cmds_inst {
BIT_UVC_CMD_UNSHARE_ALL = 20,
BIT_UVC_CMD_PIN_PAGE_SHARED = 21,
BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22,
+ BIT_UVC_CMD_DESTROY_SEC_CONF_FAST = 23,
BIT_UVC_CMD_RETR_ATTEST = 28,
};
@@ -213,6 +215,14 @@ struct uv_cb_nodata {
u64 reserved20[4];
} __packed __aligned(8);
+/* Destroy Configuration Fast */
+struct uv_cb_destroy_fast {
+ struct uv_cb_header header;
+ u64 reserved08[2];
+ u64 handle;
+ u64 reserved20[5];
+} __packed __aligned(8);
+
/* Set Shared Access */
struct uv_cb_share {
struct uv_cb_header header;
diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c
index 512b8101e7cd..5bd1359711ae 100644
--- a/arch/s390/kvm/pv.c
+++ b/arch/s390/kvm/pv.c
@@ -200,6 +200,9 @@ static int kvm_s390_pv_dispose_one_leftover(struct kvm *kvm,
{
int cc;
+ /* It used the destroy-fast UVC, nothing left to do here */
+ if (!leftover->handle)
+ goto done_fast;
cc = uv_cmd_nodata(leftover->handle, UVC_CMD_DESTROY_SEC_CONF, rc, rrc);
KVM_UV_EVENT(kvm, 3, "PROTVIRT DESTROY LEFTOVER VM: rc %x rrc %x", *rc, *rrc);
WARN_ONCE(cc, "protvirt destroy leftover vm failed rc %x rrc %x", *rc, *rrc);
@@ -214,6 +217,7 @@ static int kvm_s390_pv_dispose_one_leftover(struct kvm *kvm,
free_pages(leftover->stor_base, get_order(uv_info.guest_base_stor_len));
free_pages(leftover->old_gmap_table, CRST_ALLOC_ORDER);
vfree(leftover->stor_var);
+done_fast:
atomic_dec(&kvm->mm->context.protected_count);
return 0;
}
@@ -247,6 +251,32 @@ static void kvm_s390_destroy_lower_2g(struct kvm *kvm)
srcu_read_unlock(&kvm->srcu, srcu_idx);
}
+static int kvm_s390_pv_deinit_vm_fast(struct kvm *kvm, u16 *rc, u16 *rrc)
+{
+ struct uv_cb_destroy_fast uvcb = {
+ .header.cmd = UVC_CMD_DESTROY_SEC_CONF_FAST,
+ .header.len = sizeof(uvcb),
+ .handle = kvm_s390_pv_get_handle(kvm),
+ };
+ int cc;
+
+ cc = uv_call_sched(0, (u64)&uvcb);
+ *rc = uvcb.header.rc;
+ *rrc = uvcb.header.rrc;
+ WRITE_ONCE(kvm->arch.gmap->guest_handle, 0);
+ KVM_UV_EVENT(kvm, 3, "PROTVIRT DESTROY VM FAST: rc %x rrc %x", *rc, *rrc);
+ WARN_ONCE(cc, "protvirt destroy vm fast failed rc %x rrc %x", *rc, *rrc);
+ /* Inteded memory leak on "impossible" error */
+ if (!cc)
+ kvm_s390_pv_dealloc_vm(kvm);
+ return cc ? -EIO : 0;
+}
+
+static inline bool is_destroy_fast_available(void)
+{
+ return test_bit_inv(BIT_UVC_CMD_DESTROY_SEC_CONF_FAST, uv_info.inst_calls_list);
+}
+
/**
* kvm_s390_pv_set_aside - Set aside a protected VM for later teardown.
* @kvm: the VM
@@ -268,6 +298,7 @@ static void kvm_s390_destroy_lower_2g(struct kvm *kvm)
int kvm_s390_pv_set_aside(struct kvm *kvm, u16 *rc, u16 *rrc)
{
struct pv_vm_to_be_destroyed *priv;
+ int res = 0;
/*
* If another protected VM was already prepared, refuse.
@@ -279,14 +310,21 @@ int kvm_s390_pv_set_aside(struct kvm *kvm, u16 *rc, u16 *rrc)
if (!priv)
return -ENOMEM;
- priv->stor_var = kvm->arch.pv.stor_var;
- priv->stor_base = kvm->arch.pv.stor_base;
- priv->handle = kvm_s390_pv_get_handle(kvm);
- priv->old_gmap_table = (unsigned long)kvm->arch.gmap->table;
- WRITE_ONCE(kvm->arch.gmap->guest_handle, 0);
- if (s390_replace_asce(kvm->arch.gmap)) {
+ if (is_destroy_fast_available()) {
+ res = kvm_s390_pv_deinit_vm_fast(kvm, rc, rrc);
+ } else {
+ priv->stor_var = kvm->arch.pv.stor_var;
+ priv->stor_base = kvm->arch.pv.stor_base;
+ priv->handle = kvm_s390_pv_get_handle(kvm);
+ priv->old_gmap_table = (unsigned long)kvm->arch.gmap->table;
+ WRITE_ONCE(kvm->arch.gmap->guest_handle, 0);
+ if (s390_replace_asce(kvm->arch.gmap))
+ res = -ENOMEM;
+ }
+
+ if (res) {
kfree(priv);
- return -ENOMEM;
+ return res;
}
kvm_s390_destroy_lower_2g(kvm);
@@ -463,6 +501,7 @@ static void kvm_s390_pv_mmu_notifier_release(struct mmu_notifier *subscription,
{
struct kvm *kvm = container_of(subscription, struct kvm, arch.pv.mmu_notifier);
u16 dummy;
+ int r;
/*
* No locking is needed since this is the last thread of the last user of this
@@ -471,7 +510,9 @@ static void kvm_s390_pv_mmu_notifier_release(struct mmu_notifier *subscription,
* unregistered. This means that if this notifier runs, then the
* struct kvm is still valid.
*/
- kvm_s390_cpus_from_pv(kvm, &dummy, &dummy);
+ r = kvm_s390_cpus_from_pv(kvm, &dummy, &dummy);
+ if (!r && is_destroy_fast_available())
+ kvm_s390_pv_deinit_vm_fast(kvm, &dummy, &dummy);
}
static const struct mmu_notifier_ops kvm_s390_pv_mmu_notifier_ops = {
--
2.36.1
next prev parent reply other threads:[~2022-06-28 13:57 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-28 13:56 [PATCH v12 00/18] KVM: s390: pv: implement lazy destroy for reboot Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 01/18] KVM: s390: pv: leak the topmost page table when destroy fails Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 02/18] KVM: s390: pv: handle secure storage violations for protected guests Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 03/18] KVM: s390: pv: handle secure storage exceptions for normal guests Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 04/18] KVM: s390: pv: refactor s390_reset_acc Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 05/18] KVM: s390: pv: usage counter instead of flag Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 06/18] KVM: s390: pv: add export before import Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 07/18] KVM: s390: pv: clear the state without memset Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 08/18] KVM: s390: pv: Add kvm_s390_cpus_from_pv to kvm-s390.h and add documentation Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 09/18] KVM: s390: pv: add mmu_notifier Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 10/18] s390/mm: KVM: pv: when tearing down, try to destroy protected pages Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 11/18] KVM: s390: pv: refactoring of kvm_s390_pv_deinit_vm Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 12/18] KVM: s390: pv: destroy the configuration before its memory Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 13/18] KVM: s390: pv: asynchronous destroy for reboot Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 14/18] KVM: s390: pv: api documentation for asynchronous destroy Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 15/18] KVM: s390: pv: add KVM_CAP_S390_PROTECTED_ASYNC_DISABLE Claudio Imbrenda
2022-06-28 13:56 ` [PATCH v12 16/18] KVM: s390: pv: avoid export before import if possible Claudio Imbrenda
2022-06-28 13:56 ` Claudio Imbrenda [this message]
2022-06-28 13:56 ` [PATCH v12 18/18] KVM: s390: pv: module parameter to fence asynchronous destroy Claudio Imbrenda
2022-07-14 6:59 ` [PATCH v12 00/18] KVM: s390: pv: implement lazy destroy for reboot Janosch Frank
2022-07-14 9:17 ` 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=20220628135619.32410-18-imbrenda@linux.ibm.com \
--to=imbrenda@linux.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=david@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=mimu@linux.ibm.com \
--cc=nrb@linux.ibm.com \
--cc=pasic@linux.ibm.com \
--cc=scgl@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