From 03c7140c1a0336af3d4fca768de791b9c0e2b128 Mon Sep 17 00:00:00 2001 From: Yan Zhao Date: Tue, 25 Jun 2019 11:21:18 +0800 Subject: [PATCH] memory: assert on out of scope notification It is wrong for an entry to have parts out of scope of notifier's range. assert this condition. Out of scope mapping/unmapping would cause problem, as in below case: 1. initially there are two notifiers with ranges 0-0xfedfffff, 0xfef00000-0xffffffffffffffff, IOVAs from 0x3c000000 - 0x3c1fffff is in shadow page table. 2. in vfio, memory_region_register_iommu_notifier() is followed by memory_region_iommu_replay(), which will first call address space unmap, and walk and add back all entries in vtd shadow page table. e.g. (1) for notifier 0-0xfedfffff, IOVAs from 0 - 0xffffffff get unmapped, and IOVAs from 0x3c000000 - 0x3c1fffff get mapped (2) for notifier 0xfef00000-0xffffffffffffffff IOVAs from 0 - 0x7fffffffff get unmapped, but IOVAs from 0x3c000000 - 0x3c1fffff cannot get mapped back. Cc: Eric Auger Signed-off-by: Yan Zhao Message-Id: <1561432878-13754-1-git-send-email-yan.y.zhao@intel.com> Signed-off-by: Paolo Bonzini --- memory.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/memory.c b/memory.c index 8141486832..c90a2cf629 100644 --- a/memory.c +++ b/memory.c @@ -1942,16 +1942,18 @@ void memory_region_notify_one(IOMMUNotifier *notifier, IOMMUTLBEntry *entry) { IOMMUNotifierFlag request_flags; + hwaddr entry_end = entry->iova + entry->addr_mask; /* * Skip the notification if the notification does not overlap * with registered range. */ - if (notifier->start > entry->iova + entry->addr_mask || - notifier->end < entry->iova) { + if (notifier->start > entry_end || notifier->end < entry->iova) { return; } + assert(entry->iova >= notifier->start && entry_end <= notifier->end); + if (entry->perm & IOMMU_RW) { request_flags = IOMMU_NOTIFIER_MAP; } else {