[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] x86/mm: split struct sh_dirty_vram and make results private


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Mon, 2 Feb 2026 18:35:01 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uNvclFP+ywsf4WVRKqo9u/R56b0LpU3bJ+R+u0YqUx0=; b=u9Q//kh01PUhbLi63FMgdg38aV4Bs8XEBU1spQXAjd5rS1cwcTV4dwQf5k0Wx5Syo35xw7CHOtKp3Aq75YgLssEiKm4K2CG17xViSenZnN05eZEDzCoCVSnlkDi01GiEUVmLYIYEgiBSDuneKO5MdbMhH+Nmv/a0FsYOVYUffhI9Bad4GK7DitQocTP4lPDa7btQc35vuqu4O2Nlb06Bv6mcIN7vPLG+WmUQ9igWyleKF6uCy+O1KSxVqqHq7+Jto2Ky8x2Ve594p3PGWtNngGA68gLN3EIE68GGtH8X+902l70W76BdEA5OmgXkuksPF71roxXSEyqaZCp7m3F41A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=V/Iy5QDxEzuhh2nLpx1f0H/O9THpspzYyGIx6pn2aJ0B+uOlIVfDtF0xyVjS+6D/CKfpG7GyHagYMcXDv00fmP/EIR+/ZsMdf7GwBvyC+9P7WaPPGHc3StpK0tcS3PtTOG5jxxBIAZJ/DBhGDWcs6GbDpPyPe+i/ryqISZfMi4Vo3kuA4kCciJV7S36qNjXGnWTyJNjRHbIokHSXt5/yH7QWA+ui7ly2ZL4O8f4IuCXwVnOgMXMF7mzTy6HfzXb1OuhYnH329xpUBriwIEdOo27VziY8j023y7HmnKG4oni0zwMDNqL12FDm0RdF29nMvBxCw5yizp7xAsHqXwzyEA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Penny Zheng <Penny.Zheng@xxxxxxx>
  • Delivery-date: Mon, 02 Feb 2026 17:35:29 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

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@xxxxxxxx>

Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>

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.



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.