From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Jan Beulich <jbeulich@suse.com>
Cc: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Penny Zheng <Penny.Zheng@amd.com>
Subject: Re: [PATCH] x86/mm: split struct sh_dirty_vram and make results private
Date: Mon, 2 Feb 2026 18:35:01 +0100 [thread overview]
Message-ID: <aYDgRamZZRNsYPXF@Mac.lan> (raw)
In-Reply-To: <3dce4f28-558b-495c-ac45-0f699da82458@suse.com>
On Wed, Nov 12, 2025 at 04:47:31PM +0100, Jan Beulich wrote:
> The types are local to the shadow and HAP subsystems respectively, and
> HAP has no need for the shadow-specific fields (i.e. it can get away with
> smaller allocations). In struct hvm_domain it therefore suffices to have
> a union of two (generally opaque) pointers.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Roger Pau Monné <roger.pau@citrix.com>
Just some minor suggestions below.
>
> --- a/xen/arch/x86/include/asm/hvm/domain.h
> +++ b/xen/arch/x86/include/asm/hvm/domain.h
> @@ -95,7 +95,10 @@ struct hvm_domain {
> struct list_head pinned_cacheattr_ranges;
>
> /* VRAM dirty support. Protect with the domain paging lock. */
> - struct sh_dirty_vram *dirty_vram;
> + union {
> + struct sh_dirty_vram *sh;
> + struct hap_dirty_vram *hap;
> + } dirty_vram;
Other in-place declared structures don't use this aligning. I have to
admit it looks somewhat odd for structs like this one.
>
> /* If one of vcpus of this domain is in no_fill_mode or
> * mtrr/pat between vcpus is not the same, set is_in_uc_mode
> --- a/xen/arch/x86/include/asm/paging.h
> +++ b/xen/arch/x86/include/asm/paging.h
> @@ -133,19 +133,6 @@ struct paging_mode {
> (DIV_ROUND_UP(PADDR_BITS - PAGE_SHIFT - (PAGE_SHIFT + 3), \
> PAGE_SHIFT - ilog2(sizeof(mfn_t))) + 1)
>
> -#ifdef CONFIG_HVM
> -/* VRAM dirty tracking support */
> -struct sh_dirty_vram {
> - unsigned long begin_pfn;
> - unsigned long end_pfn;
> -#ifdef CONFIG_SHADOW_PAGING
> - paddr_t *sl1ma;
> - uint8_t *dirty_bitmap;
> - s_time_t last_dirty;
> -#endif
> -};
> -#endif
> -
> #if PG_log_dirty
>
> /* log dirty initialization */
> --- a/xen/arch/x86/mm/hap/hap.c
> +++ b/xen/arch/x86/mm/hap/hap.c
> @@ -36,6 +36,11 @@
> /* HAP VRAM TRACKING SUPPORT */
> /************************************************/
>
> +struct hap_dirty_vram {
> + unsigned long begin_pfn;
> + unsigned long end_pfn;
> +};
> +
> /*
> * hap_track_dirty_vram()
> * Create the domain's dv_dirty_vram struct on demand.
> @@ -52,7 +57,7 @@ int hap_track_dirty_vram(struct domain *
> XEN_GUEST_HANDLE(void) guest_dirty_bitmap)
> {
> long rc = 0;
> - struct sh_dirty_vram *dirty_vram;
> + struct hap_dirty_vram *dirty_vram;
> uint8_t *dirty_bitmap = NULL;
>
> if ( nr_frames )
> @@ -66,17 +71,17 @@ int hap_track_dirty_vram(struct domain *
>
> paging_lock(d);
>
> - dirty_vram = d->arch.hvm.dirty_vram;
> + dirty_vram = d->arch.hvm.dirty_vram.hap;
> if ( !dirty_vram )
> {
> rc = -ENOMEM;
> - if ( (dirty_vram = xzalloc(struct sh_dirty_vram)) == NULL )
> + if ( (dirty_vram = xzalloc(struct hap_dirty_vram)) == NULL )
> {
> paging_unlock(d);
> goto out;
> }
>
> - d->arch.hvm.dirty_vram = dirty_vram;
> + d->arch.hvm.dirty_vram.hap = dirty_vram;
> }
>
> if ( begin_pfn != dirty_vram->begin_pfn ||
> @@ -132,7 +137,7 @@ int hap_track_dirty_vram(struct domain *
> {
> paging_lock(d);
>
> - dirty_vram = d->arch.hvm.dirty_vram;
> + dirty_vram = d->arch.hvm.dirty_vram.hap;
> if ( dirty_vram )
> {
> /*
> @@ -142,7 +147,7 @@ int hap_track_dirty_vram(struct domain *
> begin_pfn = dirty_vram->begin_pfn;
> nr_frames = dirty_vram->end_pfn - dirty_vram->begin_pfn;
> xfree(dirty_vram);
> - d->arch.hvm.dirty_vram = NULL;
> + d->arch.hvm.dirty_vram.hap = NULL;
> }
>
> paging_unlock(d);
> @@ -630,7 +635,7 @@ void hap_teardown(struct domain *d, bool
>
> d->arch.paging.mode &= ~PG_log_dirty;
>
> - XFREE(d->arch.hvm.dirty_vram);
> + XFREE(d->arch.hvm.dirty_vram.hap);
>
> out:
> paging_unlock(d);
> --- a/xen/arch/x86/mm/shadow/common.c
> +++ b/xen/arch/x86/mm/shadow/common.c
> @@ -2886,11 +2886,11 @@ void shadow_teardown(struct domain *d, b
> d->arch.paging.mode &= ~PG_log_dirty;
>
> #ifdef CONFIG_HVM
> - if ( is_hvm_domain(d) && d->arch.hvm.dirty_vram )
> + if ( is_hvm_domain(d) && d->arch.hvm.dirty_vram.sh )
> {
> - xfree(d->arch.hvm.dirty_vram->sl1ma);
> - xfree(d->arch.hvm.dirty_vram->dirty_bitmap);
> - XFREE(d->arch.hvm.dirty_vram);
> + xfree(d->arch.hvm.dirty_vram.sh->sl1ma);
> + xfree(d->arch.hvm.dirty_vram.sh->dirty_bitmap);
> + XFREE(d->arch.hvm.dirty_vram.sh);
> }
> #endif
>
> --- a/xen/arch/x86/mm/shadow/hvm.c
> +++ b/xen/arch/x86/mm/shadow/hvm.c
> @@ -1033,7 +1033,7 @@ int shadow_track_dirty_vram(struct domai
> p2m_lock(p2m_get_hostp2m(d));
> paging_lock(d);
>
> - dirty_vram = d->arch.hvm.dirty_vram;
> + dirty_vram = d->arch.hvm.dirty_vram.sh;
>
> if ( dirty_vram && (!nr_frames ||
> ( begin_pfn != dirty_vram->begin_pfn
> @@ -1043,8 +1043,8 @@ int shadow_track_dirty_vram(struct domai
> gdprintk(XENLOG_INFO, "stopping tracking VRAM %lx - %lx\n", dirty_vram->begin_pfn, dirty_vram->end_pfn);
> xfree(dirty_vram->sl1ma);
> xfree(dirty_vram->dirty_bitmap);
> - xfree(dirty_vram);
> - dirty_vram = d->arch.hvm.dirty_vram = NULL;
> + XFREE(dirty_vram);
> + d->arch.hvm.dirty_vram.sh = NULL;
It would be better if this was done the other way around, first set
the reference to NULL, then free the memory?
d->arch.hvm.dirty_vram.sh = NULL;
XFREE(dirty_vram);
> }
>
> if ( !nr_frames )
> @@ -1075,7 +1075,7 @@ int shadow_track_dirty_vram(struct domai
> goto out;
> dirty_vram->begin_pfn = begin_pfn;
> dirty_vram->end_pfn = end_pfn;
> - d->arch.hvm.dirty_vram = dirty_vram;
> + d->arch.hvm.dirty_vram.sh = dirty_vram;
>
> if ( (dirty_vram->sl1ma = xmalloc_array(paddr_t, nr_frames)) == NULL )
> goto out_dirty_vram;
> @@ -1202,8 +1202,8 @@ int shadow_track_dirty_vram(struct domai
> out_sl1ma:
> xfree(dirty_vram->sl1ma);
> out_dirty_vram:
> - xfree(dirty_vram);
> - dirty_vram = d->arch.hvm.dirty_vram = NULL;
> + XFREE(dirty_vram);
> + d->arch.hvm.dirty_vram.sh = NULL;
Similar here, I would change the order.
Thanks, Roger.
next prev parent reply other threads:[~2026-02-02 17:35 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-12 15:47 [PATCH] x86/mm: split struct sh_dirty_vram and make results private Jan Beulich
2026-02-02 17:35 ` Roger Pau Monné [this message]
2026-02-03 7:41 ` Jan Beulich
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=aYDgRamZZRNsYPXF@Mac.lan \
--to=roger.pau@citrix.com \
--cc=Penny.Zheng@amd.com \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=xen-devel@lists.xenproject.org \
/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.