From: "Michael S. Tsirkin" <mst@redhat.com>
To: Cindy Lu <lulu@redhat.com>
Cc: alex.williamson@redhat.com, jasowang@redhat.com,
pbonzini@redhat.com, peterx@redhat.com, david@redhat.com,
f4bug@amsat.org, sgarzare@redhat.com, qemu-devel@nongnu.org
Subject: Re: [PATCH v10 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c
Date: Wed, 2 Nov 2022 08:45:00 -0400 [thread overview]
Message-ID: <20221102084431-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20221031125702.1445168-2-lulu@redhat.com>
On Mon, Oct 31, 2022 at 08:57:01PM +0800, Cindy Lu wrote:
> - Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
> change the name to memory_get_xlat_addr(). So we can use this
> function on other devices, such as vDPA device.
> - Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
> whether the memory is backed by a discard manager. then device can
> have its own warning.
>
> Signed-off-by: Cindy Lu <lulu@redhat.com>
This is in my tree now, pls note this if you repost so
I don't get confused.
> ---
> hw/vfio/common.c | 66 +++------------------------------------
> include/exec/memory.h | 4 +++
> softmmu/memory.c | 72 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 81 insertions(+), 61 deletions(-)
>
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index ace9562a9b..6bc02b32c8 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -578,45 +578,11 @@ static bool vfio_listener_skipped_section(MemoryRegionSection *section)
> static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> ram_addr_t *ram_addr, bool *read_only)
> {
> - MemoryRegion *mr;
> - hwaddr xlat;
> - hwaddr len = iotlb->addr_mask + 1;
> - bool writable = iotlb->perm & IOMMU_WO;
> -
> - /*
> - * The IOMMU TLB entry we have just covers translation through
> - * this IOMMU to its immediate target. We need to translate
> - * it the rest of the way through to memory.
> - */
> - mr = address_space_translate(&address_space_memory,
> - iotlb->translated_addr,
> - &xlat, &len, writable,
> - MEMTXATTRS_UNSPECIFIED);
> - if (!memory_region_is_ram(mr)) {
> - error_report("iommu map to non memory area %"HWADDR_PRIx"",
> - xlat);
> - return false;
> - } else if (memory_region_has_ram_discard_manager(mr)) {
> - RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> - MemoryRegionSection tmp = {
> - .mr = mr,
> - .offset_within_region = xlat,
> - .size = int128_make64(len),
> - };
> -
> - /*
> - * Malicious VMs can map memory into the IOMMU, which is expected
> - * to remain discarded. vfio will pin all pages, populating memory.
> - * Disallow that. vmstate priorities make sure any RamDiscardManager
> - * were already restored before IOMMUs are restored.
> - */
> - if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> - error_report("iommu map to discarded memory (e.g., unplugged via"
> - " virtio-mem): %"HWADDR_PRIx"",
> - iotlb->translated_addr);
> - return false;
> - }
> + bool ret, mr_has_discard_manager;
>
> + ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
> + &mr_has_discard_manager);
> + if (ret && mr_has_discard_manager) {
> /*
> * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
> * pages will remain pinned inside vfio until unmapped, resulting in a
> @@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> " intended via an IOMMU. It's possible to mitigate "
> " by setting/adjusting RLIMIT_MEMLOCK.");
> }
> -
> - /*
> - * Translation truncates length to the IOMMU page size,
> - * check that it did not truncate too much.
> - */
> - if (len & iotlb->addr_mask) {
> - error_report("iommu has granularity incompatible with target AS");
> - return false;
> - }
> -
> - if (vaddr) {
> - *vaddr = memory_region_get_ram_ptr(mr) + xlat;
> - }
> -
> - if (ram_addr) {
> - *ram_addr = memory_region_get_ram_addr(mr) + xlat;
> - }
> -
> - if (read_only) {
> - *read_only = !writable || mr->readonly;
> - }
> -
> - return true;
> + return ret;
> }
>
> static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
> diff --git a/include/exec/memory.h b/include/exec/memory.h
> index bfb1de8eea..d1e79c39dc 100644
> --- a/include/exec/memory.h
> +++ b/include/exec/memory.h
> @@ -713,6 +713,10 @@ void ram_discard_manager_register_listener(RamDiscardManager *rdm,
> void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
> RamDiscardListener *rdl);
>
> +bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> + ram_addr_t *ram_addr, bool *read_only,
> + bool *mr_has_discard_manager);
> +
> typedef struct CoalescedMemoryRange CoalescedMemoryRange;
> typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
>
> diff --git a/softmmu/memory.c b/softmmu/memory.c
> index 7ba2048836..bc0be3f62c 100644
> --- a/softmmu/memory.c
> +++ b/softmmu/memory.c
> @@ -33,6 +33,7 @@
> #include "qemu/accel.h"
> #include "hw/boards.h"
> #include "migration/vmstate.h"
> +#include "exec/address-spaces.h"
>
> //#define DEBUG_UNASSIGNED
>
> @@ -2121,6 +2122,77 @@ void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
> rdmc->unregister_listener(rdm, rdl);
> }
>
> +/* Called with rcu_read_lock held. */
> +bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
> + ram_addr_t *ram_addr, bool *read_only,
> + bool *mr_has_discard_manager)
> +{
> + MemoryRegion *mr;
> + hwaddr xlat;
> + hwaddr len = iotlb->addr_mask + 1;
> + bool writable = iotlb->perm & IOMMU_WO;
> +
> + if (mr_has_discard_manager) {
> + *mr_has_discard_manager = false;
> + }
> + /*
> + * The IOMMU TLB entry we have just covers translation through
> + * this IOMMU to its immediate target. We need to translate
> + * it the rest of the way through to memory.
> + */
> + mr = address_space_translate(&address_space_memory, iotlb->translated_addr,
> + &xlat, &len, writable, MEMTXATTRS_UNSPECIFIED);
> + if (!memory_region_is_ram(mr)) {
> + error_report("iommu map to non memory area %" HWADDR_PRIx "", xlat);
> + return false;
> + } else if (memory_region_has_ram_discard_manager(mr)) {
> + RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
> + MemoryRegionSection tmp = {
> + .mr = mr,
> + .offset_within_region = xlat,
> + .size = int128_make64(len),
> + };
> + if (mr_has_discard_manager) {
> + *mr_has_discard_manager = true;
> + }
> + /*
> + * Malicious VMs can map memory into the IOMMU, which is expected
> + * to remain discarded. vfio will pin all pages, populating memory.
> + * Disallow that. vmstate priorities make sure any RamDiscardManager
> + * were already restored before IOMMUs are restored.
> + */
> + if (!ram_discard_manager_is_populated(rdm, &tmp)) {
> + error_report("iommu map to discarded memory (e.g., unplugged via"
> + " virtio-mem): %" HWADDR_PRIx "",
> + iotlb->translated_addr);
> + return false;
> + }
> + }
> +
> + /*
> + * Translation truncates length to the IOMMU page size,
> + * check that it did not truncate too much.
> + */
> + if (len & iotlb->addr_mask) {
> + error_report("iommu has granularity incompatible with target AS");
> + return false;
> + }
> +
> + if (vaddr) {
> + *vaddr = memory_region_get_ram_ptr(mr) + xlat;
> + }
> +
> + if (ram_addr) {
> + *ram_addr = memory_region_get_ram_addr(mr) + xlat;
> + }
> +
> + if (read_only) {
> + *read_only = !writable || mr->readonly;
> + }
> +
> + return true;
> +}
> +
> void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
> {
> uint8_t mask = 1 << client;
> --
> 2.34.3
next prev parent reply other threads:[~2022-11-02 13:09 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-31 12:57 [PATCH v10 0/2] vhost-vdpa: add support for vIOMMU Cindy Lu
2022-10-31 12:57 ` [PATCH v10 1/2] vfio: move implement of vfio_get_xlat_addr() to memory.c Cindy Lu
2022-11-02 12:45 ` Michael S. Tsirkin [this message]
2022-10-31 12:57 ` [PATCH v10 2/2] vhost-vdpa: add support for vIOMMU Cindy Lu
2022-11-02 12:49 ` Michael S. Tsirkin
2022-11-02 10:54 ` [PATCH v10 0/2] " Michael S. Tsirkin
2022-11-02 12:39 ` Alex Williamson
2022-11-02 12:44 ` Michael S. Tsirkin
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=20221102084431-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=david@redhat.com \
--cc=f4bug@amsat.org \
--cc=jasowang@redhat.com \
--cc=lulu@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=sgarzare@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.