Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4910443pxj; Tue, 25 May 2021 20:56:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxsrh+dycTZy70SpNPkihthmMob6AAktYAQeEV9ZBR7PW2LEjpM2hoy6l3LTT+nLailaBoW X-Received: by 2002:a92:7d07:: with SMTP id y7mr24365301ilc.68.1622001411934; Tue, 25 May 2021 20:56:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622001411; cv=none; d=google.com; s=arc-20160816; b=iDE8g9uly9o52G1lJJrR5cAHiOoXuAJBJDjGh3f51IE3iv916ADjQJoabmHpDIk7YD 4emKWDwJ2f9bmufGtqtP0V1qHkdByglmgwZYD7cZ++eiOr+zgX/q09G7wNZLgXAEXz5j f8W6HjiOgAzQhEh0H8tViZ3QFyl7QVhIcIUrTd2aCjZrDg4cShh2+pkfNX0ykmROV7ld yqPcQHF60wI4vxlCaPAcNwKgInqeQ81TquiQlxU5inZIL3s1WcmWuQdduv9x7lncItqg TOLxH4iSLOYWnjG0KNUvOJo1LWm1kFHAcpj8sbSpbaUOXXZpSZgTSa8kpun55dEFM4Ds fLsw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=jd6yU+uVBE0BgP5Ser6EKR7HR6AXECsyVtKpnfIn/ck=; b=PCvfmtWOq3EGHrQq1U97DHfujtFkAKRSJ3cqapkkuS9a0pfl3CmXwygwXXKjI7HWTG 9+9yJGIHi/EIf7mOIPERVZzX2ucVduundkUUxAUHcgpuwlZZy+B97M8egbhhstdsP54y F7xtYejPPcNX4TdPEAvLcJs5oJ2FQa+2mVN4gszZQUaq7z/6zec576s6U6zW3363tcx+ ZCyqh3DaY2m0itKCEurUZTpkADUdVVDiTW2fcSqyl2wJDVeuCewohWhWvFoVjhHWGcni DsxKHBDqS5wJ+pOHxUsGkO3rTt68M00yrlMmsW8RX/37g9HbfUZKV81AeA5y76O9C3V7 eunA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=LadW7WpD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r2si18728281jak.13.2021.05.25.20.56.36; Tue, 25 May 2021 20:56:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=LadW7WpD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232056AbhEYXvg (ORCPT + 99 others); Tue, 25 May 2021 19:51:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32840 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231947AbhEYXvf (ORCPT ); Tue, 25 May 2021 19:51:35 -0400 Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [IPv6:2a00:1450:4864:20::234]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1D3CC061574 for ; Tue, 25 May 2021 16:50:03 -0700 (PDT) Received: by mail-lj1-x234.google.com with SMTP id e11so40369786ljn.13 for ; Tue, 25 May 2021 16:50:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=jd6yU+uVBE0BgP5Ser6EKR7HR6AXECsyVtKpnfIn/ck=; b=LadW7WpDNanNx9z0d3aXjXKPaRU032oaYUYvNeNnJPUjUxErlcYcCyfaby+XAZioxk o561gN6m5AR2KyAyjPcEJpzDyRL5gGz3Nkvk8XwZkk3j3HiOZ3I35rTtXyxHcg69Ae/6 cQJSmZdyk4PvRy9SWWf07b36BjJqGH6wRfJ54o28XWGxFDabW9M4pDnIlfoUjK01j+ik NWZfIr8hWO7MdcsD0YIEXjvwkUdBJIQBA2roVUT29xjhlyPDc1TmrVYmJ4P+kOkAoJd8 +nc4BcLzFfM8DxuNZ1Y+TfPyHmozwuDwBv75V81XRIEO6Ti2rwyrWbv+5LucXLy7jobb QvDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=jd6yU+uVBE0BgP5Ser6EKR7HR6AXECsyVtKpnfIn/ck=; b=MOQgq+KM5xN1+eFkY791T47UgZRgkH6UiKpFtU4LFdqOnmIEjjH7p8tEY+Zr1bwfSn EdMz1qwuZ9kAu5f9d5suiwJRS6VG/SZERi+MOgp1O0G18ou8nTPEUllLDBj9hFXvT4wo ODiO7ZRV+lownVRjBLUXwIVPSTyp7abestsHx48aVdahOG6JGiiemDNz+IRIdUS9fLBH j17lvvStHv/vREmbXKAnJWm3rryBNiAPhHQMwMAWthkBIa79bPrJm+W6wxt41cPlIGvE 1fTBWiwEfNZaQKIuKV08kEwkbS6a0hT1kdCfJ41v20OooZBz6rN7uQ9cRwamqiv9JvWv 6low== X-Gm-Message-State: AOAM5324yIZqnVX8uNHTxWM8vswIggQVDOIOoTtrXlS9BpTiVG6fZAVv d4wxz9Z9r5CGjOi8HDSc0qfdZwGdCvGMWZ4n/eViCg== X-Received: by 2002:a2e:b4e9:: with SMTP id s9mr72951ljm.383.1621986601800; Tue, 25 May 2021 16:50:01 -0700 (PDT) MIME-Version: 1.0 References: <20210519200339.829146-1-axelrasmussen@google.com> <20210519200339.829146-9-axelrasmussen@google.com> In-Reply-To: <20210519200339.829146-9-axelrasmussen@google.com> From: David Matlack Date: Tue, 25 May 2021 16:49:35 -0700 Message-ID: Subject: Re: [PATCH v2 08/10] KVM: selftests: create alias mappings when using shared memory To: Axel Rasmussen Cc: Aaron Lewis , Alexander Graf , Andrew Jones , Andrew Morton , Ben Gardon , Emanuele Giuseppe Esposito , Eric Auger , Jacob Xu , Makarand Sonare , Oliver Upton , Paolo Bonzini , Peter Xu , Shuah Khan , Yanan Wang , kvm list , linux-kernel@vger.kernel.org, Linuxkselftest Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, May 19, 2021 at 1:04 PM Axel Rasmussen wrote: > > When a memory region is added with a src_type specifying that it should > use some kind of shared memory, also create an alias mapping to the same > underlying physical pages. > > And, add an API so tests can get access to these alias addresses. > Basically, for a guest physical address, let us look up the analogous > host *alias* address. > > In a future commit, we'll modify the demand paging test to take > advantage of this to exercise UFFD minor faults. The idea is, we > pre-fault the underlying pages *via the alias*. When the *guest* > faults, it gets a "minor" fault (PTEs don't exist yet, but a page is > already in the page cache). Then, the userfaultfd theads can handle the > fault: they could potentially modify the underlying memory *via the > alias* if they wanted to, and then they install the PTEs and let the > guest carry on via a UFFDIO_CONTINUE ioctl. > > Reviewed-by: Ben Gardon > Signed-off-by: Axel Rasmussen > --- > .../testing/selftests/kvm/include/kvm_util.h | 1 + > tools/testing/selftests/kvm/lib/kvm_util.c | 51 +++++++++++++++++++ > .../selftests/kvm/lib/kvm_util_internal.h | 2 + > 3 files changed, 54 insertions(+) > > diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h > index a8f022794ce3..0624f25a6803 100644 > --- a/tools/testing/selftests/kvm/include/kvm_util.h > +++ b/tools/testing/selftests/kvm/include/kvm_util.h > @@ -146,6 +146,7 @@ void virt_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, > void *addr_gpa2hva(struct kvm_vm *vm, vm_paddr_t gpa); > void *addr_gva2hva(struct kvm_vm *vm, vm_vaddr_t gva); > vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva); > +void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa); > > /* > * Address Guest Virtual to Guest Physical > diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c > index e4a8d0c43c5e..0b88d1bbc1e0 100644 > --- a/tools/testing/selftests/kvm/lib/kvm_util.c > +++ b/tools/testing/selftests/kvm/lib/kvm_util.c > @@ -811,6 +811,19 @@ void vm_userspace_mem_region_add(struct kvm_vm *vm, > > /* Add to linked-list of memory regions. */ > list_add(®ion->list, &vm->userspace_mem_regions); > + > + /* If shared memory, create an alias. */ > + if (region->fd >= 0) { > + region->mmap_alias = mmap(NULL, region->mmap_size, > + PROT_READ | PROT_WRITE, > + vm_mem_backing_src_alias(src_type)->flag, > + region->fd, 0); > + TEST_ASSERT(region->mmap_alias != MAP_FAILED, > + "mmap of alias failed, errno: %i", errno); > + > + /* Align host alias address */ > + region->host_alias = align(region->mmap_alias, alignment); > + } > } > > /* > @@ -1239,6 +1252,44 @@ vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva) > return -1; > } > > +/* > + * Address VM physical to Host Virtual *alias*. > + * > + * Input Args: > + * vm - Virtual Machine > + * gpa - VM physical address > + * > + * Output Args: None > + * > + * Return: > + * Equivalent address within the host virtual *alias* area, or NULL > + * (without failing the test) if the guest memory is not shared (so > + * no alias exists). > + * > + * When vm_create() and related functions are called with a shared memory > + * src_type, we also create a writable, shared alias mapping of the > + * underlying guest memory. This allows the host to manipulate guest memory > + * without mapping that memory in the guest's address space. And, for > + * userfaultfd-based demand paging, we can do so without triggering userfaults. > + */ > +void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa) > +{ > + struct userspace_mem_region *region; > + > + list_for_each_entry(region, &vm->userspace_mem_regions, list) { This patch fails to compile on top of with db0670ce3361 ("KVM: selftests: Keep track of memslots more efficiently"). This can be reproduced by checking out kvm/master and running `make -C tools/testing/selftests/kvm`. The following diff fixes the compilation error but I did not have time to test it yet: diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index c98db1846e1b..28e528c19d28 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -1374,19 +1374,17 @@ vm_paddr_t addr_hva2gpa(struct kvm_vm *vm, void *hva) void *addr_gpa2alias(struct kvm_vm *vm, vm_paddr_t gpa) { struct userspace_mem_region *region; + uintptr_t offset; - list_for_each_entry(region, &vm->userspace_mem_regions, list) { - if (!region->host_alias) - continue; + region = userspace_mem_region_find(vm, gpa, gpa); + if (!region) + return NULL; - if ((gpa >= region->region.guest_phys_addr) - && (gpa <= (region->region.guest_phys_addr - + region->region.memory_size - 1))) - return (void *) ((uintptr_t) region->host_alias - + (gpa - region->region.guest_phys_addr)); - } + if (!region->host_alias) + return NULL; - return NULL; + offset = gpa - region->region.guest_phys_addr; + return (void *) ((uintptr_t) region->host_alias + offset); } /* > + if (!region->host_alias) > + continue; > + > + if ((gpa >= region->region.guest_phys_addr) > + && (gpa <= (region->region.guest_phys_addr > + + region->region.memory_size - 1))) > + return (void *) ((uintptr_t) region->host_alias > + + (gpa - region->region.guest_phys_addr)); > + } > + > + return NULL; > +} > + > /* > * VM Create IRQ Chip > * > diff --git a/tools/testing/selftests/kvm/lib/kvm_util_internal.h b/tools/testing/selftests/kvm/lib/kvm_util_internal.h > index 91ce1b5d480b..a25af33d4a9c 100644 > --- a/tools/testing/selftests/kvm/lib/kvm_util_internal.h > +++ b/tools/testing/selftests/kvm/lib/kvm_util_internal.h > @@ -16,7 +16,9 @@ struct userspace_mem_region { > int fd; > off_t offset; > void *host_mem; > + void *host_alias; > void *mmap_start; > + void *mmap_alias; > size_t mmap_size; > struct list_head list; > }; > -- > 2.31.1.751.gd2f1c929bd-goog >