summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0013-IOMMU-x86-disallow-device-assignment-to-PoD-guests.patch')
-rw-r--r--0013-IOMMU-x86-disallow-device-assignment-to-PoD-guests.patch229
1 files changed, 0 insertions, 229 deletions
diff --git a/0013-IOMMU-x86-disallow-device-assignment-to-PoD-guests.patch b/0013-IOMMU-x86-disallow-device-assignment-to-PoD-guests.patch
deleted file mode 100644
index 8416c96..0000000
--- a/0013-IOMMU-x86-disallow-device-assignment-to-PoD-guests.patch
+++ /dev/null
@@ -1,229 +0,0 @@
-From 838f6c211f7f05f107e1acdfb0977ab61ec0bf2e Mon Sep 17 00:00:00 2001
-From: Jan Beulich <jbeulich@suse.com>
-Date: Tue, 7 Jun 2022 14:03:20 +0200
-Subject: [PATCH 13/51] IOMMU/x86: disallow device assignment to PoD guests
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-While it is okay for IOMMU page tables to be set up for guests starting
-in PoD mode, actual device assignment may only occur once all PoD
-entries have been removed from the P2M. So far this was enforced only
-for boot-time assignment, and only in the tool stack.
-
-Also use the new function to replace p2m_pod_entry_count(): Its unlocked
-access to p2m->pod.entry_count wasn't really okay (irrespective of the
-result being stale by the time the caller gets to see it). Nor was the
-use of that function in line with the immediately preceding comment: A
-PoD guest isn't just one with a non-zero entry count, but also one with
-a non-empty cache (e.g. prior to actually launching the guest).
-
-To allow the tool stack to see a consistent snapshot of PoD state, move
-the tail of XENMEM_{get,set}_pod_target handling into a function, adding
-proper locking there.
-
-In libxl take the liberty to use the new local variable r also for a
-pre-existing call into libxc.
-
-Signed-off-by: Jan Beulich <jbeulich@suse.com>
-Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
-master commit: ad4312d764e8b40a1e45b64aac6d840a60c59f13
-master date: 2022-05-02 08:48:02 +0200
----
- xen/arch/x86/mm.c | 6 +---
- xen/arch/x86/mm/p2m-pod.c | 43 ++++++++++++++++++++++++++++-
- xen/common/vm_event.c | 2 +-
- xen/drivers/passthrough/x86/iommu.c | 3 +-
- xen/include/asm-x86/p2m.h | 21 +++++++-------
- 5 files changed, 57 insertions(+), 18 deletions(-)
-
-diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
-index e222d9aa98ee..4ee2de11051d 100644
---- a/xen/arch/x86/mm.c
-+++ b/xen/arch/x86/mm.c
-@@ -4777,7 +4777,6 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
- {
- xen_pod_target_t target;
- struct domain *d;
-- struct p2m_domain *p2m;
-
- if ( copy_from_guest(&target, arg, 1) )
- return -EFAULT;
-@@ -4812,10 +4811,7 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
- }
- else if ( rc >= 0 )
- {
-- p2m = p2m_get_hostp2m(d);
-- target.tot_pages = domain_tot_pages(d);
-- target.pod_cache_pages = p2m->pod.count;
-- target.pod_entries = p2m->pod.entry_count;
-+ p2m_pod_get_mem_target(d, &target);
-
- if ( __copy_to_guest(arg, &target, 1) )
- {
-diff --git a/xen/arch/x86/mm/p2m-pod.c b/xen/arch/x86/mm/p2m-pod.c
-index d8d1a0ce7ed7..a3c9d8a97423 100644
---- a/xen/arch/x86/mm/p2m-pod.c
-+++ b/xen/arch/x86/mm/p2m-pod.c
-@@ -20,6 +20,7 @@
- */
-
- #include <xen/event.h>
-+#include <xen/iocap.h>
- #include <xen/ioreq.h>
- #include <xen/mm.h>
- #include <xen/sched.h>
-@@ -362,7 +363,10 @@ p2m_pod_set_mem_target(struct domain *d, unsigned long target)
-
- ASSERT( pod_target >= p2m->pod.count );
-
-- ret = p2m_pod_set_cache_target(p2m, pod_target, 1/*preemptible*/);
-+ if ( has_arch_pdevs(d) || cache_flush_permitted(d) )
-+ ret = -ENOTEMPTY;
-+ else
-+ ret = p2m_pod_set_cache_target(p2m, pod_target, 1/*preemptible*/);
-
- out:
- pod_unlock(p2m);
-@@ -370,6 +374,23 @@ out:
- return ret;
- }
-
-+void p2m_pod_get_mem_target(const struct domain *d, xen_pod_target_t *target)
-+{
-+ struct p2m_domain *p2m = p2m_get_hostp2m(d);
-+
-+ ASSERT(is_hvm_domain(d));
-+
-+ pod_lock(p2m);
-+ lock_page_alloc(p2m);
-+
-+ target->tot_pages = domain_tot_pages(d);
-+ target->pod_cache_pages = p2m->pod.count;
-+ target->pod_entries = p2m->pod.entry_count;
-+
-+ unlock_page_alloc(p2m);
-+ pod_unlock(p2m);
-+}
-+
- int p2m_pod_empty_cache(struct domain *d)
- {
- struct p2m_domain *p2m = p2m_get_hostp2m(d);
-@@ -1387,6 +1408,9 @@ guest_physmap_mark_populate_on_demand(struct domain *d, unsigned long gfn,
- if ( !paging_mode_translate(d) )
- return -EINVAL;
-
-+ if ( has_arch_pdevs(d) || cache_flush_permitted(d) )
-+ return -ENOTEMPTY;
-+
- do {
- rc = mark_populate_on_demand(d, gfn, chunk_order);
-
-@@ -1408,3 +1432,20 @@ void p2m_pod_init(struct p2m_domain *p2m)
- for ( i = 0; i < ARRAY_SIZE(p2m->pod.mrp.list); ++i )
- p2m->pod.mrp.list[i] = gfn_x(INVALID_GFN);
- }
-+
-+bool p2m_pod_active(const struct domain *d)
-+{
-+ struct p2m_domain *p2m;
-+ bool res;
-+
-+ if ( !is_hvm_domain(d) )
-+ return false;
-+
-+ p2m = p2m_get_hostp2m(d);
-+
-+ pod_lock(p2m);
-+ res = p2m->pod.entry_count | p2m->pod.count;
-+ pod_unlock(p2m);
-+
-+ return res;
-+}
-diff --git a/xen/common/vm_event.c b/xen/common/vm_event.c
-index 70ab3ba406ff..21d2f0edf727 100644
---- a/xen/common/vm_event.c
-+++ b/xen/common/vm_event.c
-@@ -639,7 +639,7 @@ int vm_event_domctl(struct domain *d, struct xen_domctl_vm_event_op *vec)
-
- rc = -EXDEV;
- /* Disallow paging in a PoD guest */
-- if ( p2m_pod_entry_count(p2m_get_hostp2m(d)) )
-+ if ( p2m_pod_active(d) )
- break;
-
- /* domain_pause() not required here, see XSA-99 */
-diff --git a/xen/drivers/passthrough/x86/iommu.c b/xen/drivers/passthrough/x86/iommu.c
-index a36a6bd4b249..dc9936e16930 100644
---- a/xen/drivers/passthrough/x86/iommu.c
-+++ b/xen/drivers/passthrough/x86/iommu.c
-@@ -502,11 +502,12 @@ bool arch_iommu_use_permitted(const struct domain *d)
- {
- /*
- * Prevent device assign if mem paging, mem sharing or log-dirty
-- * have been enabled for this domain.
-+ * have been enabled for this domain, or if PoD is still in active use.
- */
- return d == dom_io ||
- (likely(!mem_sharing_enabled(d)) &&
- likely(!mem_paging_enabled(d)) &&
-+ likely(!p2m_pod_active(d)) &&
- likely(!p2m_get_hostp2m(d)->global_logdirty));
- }
-
-diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
-index 357a8087481e..f2af7a746ced 100644
---- a/xen/include/asm-x86/p2m.h
-+++ b/xen/include/asm-x86/p2m.h
-@@ -661,6 +661,12 @@ int p2m_pod_empty_cache(struct domain *d);
- * domain matches target */
- int p2m_pod_set_mem_target(struct domain *d, unsigned long target);
-
-+/* Obtain a consistent snapshot of PoD related domain state. */
-+void p2m_pod_get_mem_target(const struct domain *d, xen_pod_target_t *target);
-+
-+/* Check whether PoD is (still) active in a domain. */
-+bool p2m_pod_active(const struct domain *d);
-+
- /* Scan pod cache when offline/broken page triggered */
- int
- p2m_pod_offline_or_broken_hit(struct page_info *p);
-@@ -669,11 +675,6 @@ p2m_pod_offline_or_broken_hit(struct page_info *p);
- void
- p2m_pod_offline_or_broken_replace(struct page_info *p);
-
--static inline long p2m_pod_entry_count(const struct p2m_domain *p2m)
--{
-- return p2m->pod.entry_count;
--}
--
- void p2m_pod_init(struct p2m_domain *p2m);
-
- #else
-@@ -689,6 +690,11 @@ static inline int p2m_pod_empty_cache(struct domain *d)
- return 0;
- }
-
-+static inline bool p2m_pod_active(const struct domain *d)
-+{
-+ return false;
-+}
-+
- static inline int p2m_pod_offline_or_broken_hit(struct page_info *p)
- {
- return 0;
-@@ -699,11 +705,6 @@ static inline void p2m_pod_offline_or_broken_replace(struct page_info *p)
- ASSERT_UNREACHABLE();
- }
-
--static inline long p2m_pod_entry_count(const struct p2m_domain *p2m)
--{
-- return 0;
--}
--
- static inline void p2m_pod_init(struct p2m_domain *p2m) {}
-
- #endif
---
-2.35.1
-