xen/arch/x86/Kconfig | 9 +++++++++ xen/arch/x86/domctl.c | 8 ++++---- xen/arch/x86/hvm/dm.c | 3 +++ xen/arch/x86/include/asm/domain.h | 2 ++ xen/arch/x86/include/asm/p2m.h | 2 ++ xen/arch/x86/include/asm/paging.h | 8 +++----- xen/arch/x86/mm/hap/hap.c | 22 +++++++++++++--------- xen/arch/x86/mm/p2m.c | 2 ++ xen/arch/x86/mm/paging.c | 2 ++ xen/include/hypercall-defs.c | 4 ++-- 10 files changed, 42 insertions(+), 20 deletions(-)
Creates a CONFIG_LOG_DIRTY Kconfig option with the following effects
when disabled:
* paging_domctl{,_cont} return -EOPNOTSUPP (XEN_DOMCTL_shadow_op).
* VRAM tracking via DMOP returns EOPNOTSUPP.
And compiles out all log-dirty tracking infra.
Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
---
RFC for the Kconfig help message.
---
xen/arch/x86/Kconfig | 9 +++++++++
xen/arch/x86/domctl.c | 8 ++++----
xen/arch/x86/hvm/dm.c | 3 +++
xen/arch/x86/include/asm/domain.h | 2 ++
xen/arch/x86/include/asm/p2m.h | 2 ++
xen/arch/x86/include/asm/paging.h | 8 +++-----
xen/arch/x86/mm/hap/hap.c | 22 +++++++++++++---------
xen/arch/x86/mm/p2m.c | 2 ++
xen/arch/x86/mm/paging.c | 2 ++
xen/include/hypercall-defs.c | 4 ++--
10 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index 61f58aa829..fbf044aa4d 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -146,6 +146,7 @@ config XEN_IBT
config SHADOW_PAGING
bool "Shadow Paging"
default !PV_SHIM_EXCLUSIVE
+ select LOG_DIRTY
depends on PV || HVM
help
@@ -166,6 +167,14 @@ config SHADOW_PAGING
config PAGING
def_bool HVM || SHADOW_PAGING
+config LOG_DIRTY
+ bool "Log-dirty page tracking" if EXPERT
+ depends on PAGING
+ default !PV_SHIM_EXCLUSIVE
+ help
+ Enable log-dirty infrastructure so Xen can track domain memory writes and
+ the dirty state of VRAM for device models and live migrations.
+
config BIGMEM
bool "big memory support"
default n
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index d9521808dc..61d43a21d0 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -220,15 +220,15 @@ long arch_do_domctl(
{
case XEN_DOMCTL_shadow_op:
-#ifdef CONFIG_PAGING
+ ret = -EOPNOTSUPP;
+ if ( !IS_ENABLED(CONFIG_LOG_DIRTY) )
+ break;
+
ret = paging_domctl(d, &domctl->u.shadow_op, u_domctl, 0);
if ( ret == -ERESTART )
return hypercall_create_continuation(
__HYPERVISOR_paging_domctl_cont, "h", u_domctl);
copyback = true;
-#else
- ret = -EOPNOTSUPP;
-#endif
break;
case XEN_DOMCTL_ioport_permission:
diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index 3b53471af0..94216aecc2 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -48,6 +48,9 @@ static int track_dirty_vram(struct domain *d, xen_pfn_t first_pfn,
unsigned int nr_frames,
const struct xen_dm_op_buf *buf)
{
+ if ( !IS_ENABLED(CONFIG_LOG_DIRTY) )
+ return -EOPNOTSUPP;
+
if ( nr_frames > (GB(1) >> PAGE_SHIFT) )
return -EINVAL;
diff --git a/xen/arch/x86/include/asm/domain.h b/xen/arch/x86/include/asm/domain.h
index 94b0cf7f1d..f09c13909f 100644
--- a/xen/arch/x86/include/asm/domain.h
+++ b/xen/arch/x86/include/asm/domain.h
@@ -226,7 +226,9 @@ struct paging_domain {
unsigned int p2m_pages; /* number of pages allocated to p2m */
/* log dirty support */
+#ifdef CONFIG_LOG_DIRTY
struct log_dirty_domain log_dirty;
+#endif /* CONFIG_LOG_DIRTY */
/* preemption handling */
struct {
diff --git a/xen/arch/x86/include/asm/p2m.h b/xen/arch/x86/include/asm/p2m.h
index 9016e88411..3c2dcacfa5 100644
--- a/xen/arch/x86/include/asm/p2m.h
+++ b/xen/arch/x86/include/asm/p2m.h
@@ -253,9 +253,11 @@ struct p2m_domain {
bool *sve);
int (*recalc)(struct p2m_domain *p2m,
unsigned long gfn);
+#ifdef CONFIG_LOG_DIRTY
void (*enable_hardware_log_dirty)(struct p2m_domain *p2m);
void (*disable_hardware_log_dirty)(struct p2m_domain *p2m);
void (*flush_hardware_cached_dirty)(struct p2m_domain *p2m);
+#endif /* CONFIG_LOG_DIRTY */
void (*change_entry_type_global)(struct p2m_domain *p2m,
p2m_type_t ot,
p2m_type_t nt);
diff --git a/xen/arch/x86/include/asm/paging.h b/xen/arch/x86/include/asm/paging.h
index 291ab386e8..980cdfa455 100644
--- a/xen/arch/x86/include/asm/paging.h
+++ b/xen/arch/x86/include/asm/paging.h
@@ -55,12 +55,9 @@
#define PG_translate 0
#define PG_external 0
#endif
-#if defined(CONFIG_PAGING) && !defined(CONFIG_PV_SHIM_EXCLUSIVE)
/* Enable log dirty mode */
-#define PG_log_dirty (XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY << PG_mode_shift)
-#else
-#define PG_log_dirty 0
-#endif
+#define PG_log_dirty IS_ENABLED(CONFIG_LOG_DIRTY) * \
+ (XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY << PG_mode_shift)
/* All paging modes. */
#define PG_MASK (PG_refcounts | PG_log_dirty | PG_translate | PG_external)
@@ -174,6 +171,7 @@ static inline void paging_log_dirty_init(struct domain *d,
const struct log_dirty_ops *ops) {}
static inline void paging_mark_dirty(struct domain *d, mfn_t gmfn) {}
static inline void paging_mark_pfn_dirty(struct domain *d, pfn_t pfn) {}
+static inline void paging_mark_pfn_clean(struct domain *d, pfn_t pfn) {}
static inline bool paging_mfn_is_dirty(struct domain *d, mfn_t gmfn) { return false; }
#endif /* PG_log_dirty */
diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c
index a337752bf4..21672db011 100644
--- a/xen/arch/x86/mm/hap/hap.c
+++ b/xen/arch/x86/mm/hap/hap.c
@@ -50,7 +50,7 @@ struct hap_dirty_vram {
* calling p2m_log_dirty_range(), which interrogates each vram
* page's p2m type looking for pages that have been made writable.
*/
-
+#ifdef CONFIG_LOG_DIRTY
int hap_track_dirty_vram(struct domain *d,
unsigned long begin_pfn,
unsigned int nr_frames,
@@ -161,6 +161,7 @@ out:
return rc;
}
+#endif /* CONFIG_LOG_DIRTY */
/************************************************/
/* HAP LOG DIRTY SUPPORT */
@@ -440,14 +441,17 @@ static bool cf_check flush_tlb(const unsigned long *vcpu_bitmap);
void hap_domain_init(struct domain *d)
{
- static const struct log_dirty_ops hap_ops = {
- .enable = hap_enable_log_dirty,
- .disable = hap_disable_log_dirty,
- .clean = hap_clean_dirty_bitmap,
- };
-
- /* Use HAP logdirty mechanism. */
- paging_log_dirty_init(d, &hap_ops);
+ if ( IS_ENABLED(CONFIG_LOG_DIRTY) )
+ {
+ static const struct log_dirty_ops hap_ops = {
+ .enable = hap_enable_log_dirty,
+ .disable = hap_disable_log_dirty,
+ .clean = hap_clean_dirty_bitmap,
+ };
+
+ /* Use HAP logdirty mechanism. */
+ paging_log_dirty_init(d, &hap_ops);
+ }
d->arch.paging.update_paging_modes = hap_update_paging_modes;
d->arch.paging.flush_tlb = flush_tlb;
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index e915da26a8..373382c28c 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -236,6 +236,7 @@ struct ioreq_server *p2m_get_ioreq_server(struct domain *d,
return s;
}
+#ifdef CONFIG_LOG_DIRTY
void p2m_enable_hardware_log_dirty(struct domain *d)
{
struct p2m_domain *p2m = p2m_get_hostp2m(d);
@@ -263,6 +264,7 @@ void p2m_flush_hardware_cached_dirty(struct domain *d)
p2m_unlock(p2m);
}
}
+#endif /* CONFIG_LOG_DIRTY */
/*
* Force a synchronous P2M TLB flush if a deferred flush is pending.
diff --git a/xen/arch/x86/mm/paging.c b/xen/arch/x86/mm/paging.c
index 2396f81ad5..13ee137db9 100644
--- a/xen/arch/x86/mm/paging.c
+++ b/xen/arch/x86/mm/paging.c
@@ -623,10 +623,12 @@ int paging_domain_init(struct domain *d)
INIT_PAGE_LIST_HEAD(&d->arch.paging.freelist);
mm_lock_init(&d->arch.paging.lock);
+#ifdef CONFIG_LOG_DIRTY
/* This must be initialized separately from the rest of the
* log-dirty init code as that can be called more than once and we
* don't want to leak any active log-dirty bitmaps */
d->arch.paging.log_dirty.top = INVALID_MFN;
+#endif /* CONFIG_LOG_DIRTY */
/*
* Shadow pagetables are the default, but we will use
diff --git a/xen/include/hypercall-defs.c b/xen/include/hypercall-defs.c
index 63755bb8df..be7ed832be 100644
--- a/xen/include/hypercall-defs.c
+++ b/xen/include/hypercall-defs.c
@@ -194,7 +194,7 @@ dm_op(domid_t domid, unsigned int nr_bufs, xen_dm_op_buf_t *bufs)
#ifdef CONFIG_SYSCTL
sysctl(xen_sysctl_t *u_sysctl)
#endif
-#if defined(CONFIG_X86) && defined(CONFIG_PAGING) && !defined(CONFIG_PV_SHIM_EXCLUSIVE)
+#if defined(CONFIG_LOG_DIRTY)
paging_domctl_cont(xen_domctl_t *u_domctl)
#endif
#ifndef CONFIG_PV_SHIM_EXCLUSIVE
@@ -292,7 +292,7 @@ dm_op compat do compat do do
hypfs_op do do do do do
#endif
mca do do - - -
-#if defined(CONFIG_X86) && defined(CONFIG_PAGING) && !defined(CONFIG_PV_SHIM_EXCLUSIVE)
+#if defined(CONFIG_LOG_DIRTY)
paging_domctl_cont do do do do -
#endif
base-commit: 1ee8b11c1106dca6b8fe0d54c0e79146bb6545f0
--
2.43.0
© 2016 - 2026 Red Hat, Inc.