From: Cornelia Huck <cohuck@redhat.com>
To: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Ulrich.Weigand@de.ibm.com, david@redhat.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 v3.1 02/37] KVM: s390/interrupt: do not pin adapter interrupt pages
Date: Fri, 21 Feb 2020 11:41:58 +0100 [thread overview]
Message-ID: <20200221114158.2eeca512.cohuck@redhat.com> (raw)
In-Reply-To: <20200221080942.10334-1-borntraeger@de.ibm.com>
On Fri, 21 Feb 2020 03:09:42 -0500
Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> From: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
>
> The adapter interrupt page containing the indicator bits is currently
> pinned. That means that a guest with many devices can pin a lot of
> memory pages in the host. This also complicates the reference tracking
> which is needed for memory management handling of protected virtual
> machines. It might also have some strange side effects for madvise
> MADV_DONTNEED and other things.
>
> We can simply try to get the userspace page set the bits and free the
> page. By storing the userspace address in the irq routing entry instead
> of the guest address we can actually avoid many lookups and list walks
> so that this variant is very likely not slower.
>
> If userspace messes around with the memory slots the worst thing that
> can happen is that we write to some other memory within that process.
> As we get the the page with FOLL_WRITE this can also not be used to
> write to shared read-only pages.
>
> Signed-off-by: Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
> [borntraeger@de.ibm.com: patch simplification]
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> ---
> Documentation/virt/kvm/devices/s390_flic.rst | 11 +-
> arch/s390/include/asm/kvm_host.h | 3 -
> arch/s390/kvm/interrupt.c | 172 ++++++-------------
> 3 files changed, 52 insertions(+), 134 deletions(-)
(...)
> @@ -2456,12 +2378,13 @@ static int modify_io_adapter(struct kvm_device *dev,
> if (ret > 0)
> ret = 0;
> break;
> + /*
> + * We resolve the gpa to hva when setting the IRQ routing. the set_irq
> + * code uses get_user_pages_remote() to do the actual write.
> + */
What about:
"The following operations are no longer needed and therefore no-ops.
The gpa to hva translation is done when an IRQ route is set up. The
set_irq code uses get_user_pages_remote() to do the actual write."
> case KVM_S390_IO_ADAPTER_MAP:
> - ret = kvm_s390_adapter_map(dev->kvm, req.id, req.addr);
> - break;
> case KVM_S390_IO_ADAPTER_UNMAP:
> - ret = kvm_s390_adapter_unmap(dev->kvm, req.id, req.addr);
> - break;
> + return 0;
I think
ret = 0;
break;
would be better, as the other cases do not do a direct return, either.
> default:
> ret = -EINVAL;
> }
> @@ -2699,19 +2622,17 @@ static unsigned long get_ind_bit(__u64 addr, unsigned long bit_nr, bool swap)
> return swap ? (bit ^ (BITS_PER_LONG - 1)) : bit;
> }
>
> -static struct s390_map_info *get_map_info(struct s390_io_adapter *adapter,
> - u64 addr)
> +static struct page *get_map_page(struct kvm *kvm,
> + struct s390_io_adapter *adapter,
adapter seems to be unused in this function now? Should we remove it from the parameter list?
> + u64 uaddr)
> {
> - struct s390_map_info *map;
> -
> - if (!adapter)
> - return NULL;
> + struct page *page = NULL;
>
> - list_for_each_entry(map, &adapter->maps, list) {
> - if (map->guest_addr == addr)
> - return map;
> - }
> - return NULL;
> + down_read(&kvm->mm->mmap_sem);
> + get_user_pages_remote(NULL, kvm->mm, uaddr, 1, FOLL_WRITE,
> + &page, NULL, NULL);
> + up_read(&kvm->mm->mmap_sem);
> + return page;
> }
>
> static int adapter_indicators_set(struct kvm *kvm,
> @@ -2720,30 +2641,35 @@ static int adapter_indicators_set(struct kvm *kvm,
> {
> unsigned long bit;
> int summary_set, idx;
> - struct s390_map_info *info;
> + struct page *ind_page, *summary_page;
> void *map;
>
> - info = get_map_info(adapter, adapter_int->ind_addr);
> - if (!info)
> + ind_page = get_map_page(kvm, adapter, adapter_int->ind_addr);
> + if (!ind_page)
> return -1;
> - map = page_address(info->page);
> - bit = get_ind_bit(info->addr, adapter_int->ind_offset, adapter->swap);
> - set_bit(bit, map);
> - idx = srcu_read_lock(&kvm->srcu);
> - mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT);
> - set_page_dirty_lock(info->page);
> - info = get_map_info(adapter, adapter_int->summary_addr);
> - if (!info) {
> - srcu_read_unlock(&kvm->srcu, idx);
> + summary_page = get_map_page(kvm, adapter, adapter_int->summary_addr);
> + if (!summary_page) {
> + put_page(ind_page);
> return -1;
> }
> - map = page_address(info->page);
> - bit = get_ind_bit(info->addr, adapter_int->summary_offset,
> - adapter->swap);
> +
> + idx = srcu_read_lock(&kvm->srcu);
> + map = page_address(ind_page);
> + bit = get_ind_bit(adapter_int->ind_addr,
> + adapter_int->ind_offset, adapter->swap);
> + set_bit(bit, map);
> + mark_page_dirty(kvm, adapter_int->ind_addr >> PAGE_SHIFT);
> + set_page_dirty_lock(ind_page);
> + map = page_address(summary_page);
> + bit = get_ind_bit(adapter_int->summary_addr,
> + adapter_int->summary_offset, adapter->swap);
> summary_set = test_and_set_bit(bit, map);
> - mark_page_dirty(kvm, info->guest_addr >> PAGE_SHIFT);
> - set_page_dirty_lock(info->page);
> + mark_page_dirty(kvm, adapter_int->summary_addr >> PAGE_SHIFT);
> + set_page_dirty_lock(summary_page);
> srcu_read_unlock(&kvm->srcu, idx);
> +
> + put_page(ind_page);
> + put_page(summary_page);
> return summary_set ? 0 : 1;
> }
>
> @@ -2765,9 +2691,7 @@ static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e,
> adapter = get_io_adapter(kvm, e->adapter.adapter_id);
> if (!adapter)
> return -1;
> - down_read(&adapter->maps_lock);
> ret = adapter_indicators_set(kvm, adapter, &e->adapter);
> - up_read(&adapter->maps_lock);
> if ((ret > 0) && !adapter->masked) {
> ret = kvm_s390_inject_airq(kvm, adapter);
> if (ret == 0)
> @@ -2818,23 +2742,27 @@ int kvm_set_routing_entry(struct kvm *kvm,
> struct kvm_kernel_irq_routing_entry *e,
> const struct kvm_irq_routing_entry *ue)
> {
> - int ret;
> + u64 uaddr;
>
> switch (ue->type) {
> + /* we store the userspace addresses instead of the guest addresses */
> case KVM_IRQ_ROUTING_S390_ADAPTER:
> e->set = set_adapter_int;
> - e->adapter.summary_addr = ue->u.adapter.summary_addr;
> - e->adapter.ind_addr = ue->u.adapter.ind_addr;
> + uaddr = gmap_translate(kvm->arch.gmap, ue->u.adapter.summary_addr);
> + if (uaddr == -EFAULT)
> + return -EFAULT;
> + e->adapter.summary_addr = uaddr;
> + uaddr = gmap_translate(kvm->arch.gmap, ue->u.adapter.ind_addr);
> + if (uaddr == -EFAULT)
> + return -EFAULT;
> + e->adapter.ind_addr = uaddr;
> e->adapter.summary_offset = ue->u.adapter.summary_offset;
> e->adapter.ind_offset = ue->u.adapter.ind_offset;
> e->adapter.adapter_id = ue->u.adapter.adapter_id;
> - ret = 0;
> - break;
> + return 0;
> default:
> - ret = -EINVAL;
> + return -EINVAL;
> }
> -
> - return ret;
> }
>
> int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm,
next prev parent reply other threads:[~2020-02-21 10:42 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 [this message]
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
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=20200221114158.2eeca512.cohuck@redhat.com \
--to=cohuck@redhat.com \
--cc=Ulrich.Weigand@de.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=david@redhat.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.