All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nuno Das Neves <nunodasneves@linux.microsoft.com>
To: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>,
	kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com
Cc: linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v8 6/6] Drivers: hv: Add support for movable memory regions
Date: Wed, 3 Dec 2025 12:36:07 -0800	[thread overview]
Message-ID: <5d309f95-84d0-462e-a463-16d303629907@linux.microsoft.com> (raw)
In-Reply-To: <176478627345.114132.10738191092601354463.stgit@skinsburskii-cloud-desktop.internal.cloudapp.net>

On 12/3/2025 10:24 AM, Stanislav Kinsburskii wrote:
> Introduce support for movable memory regions in the Hyper-V root partition
> driver to improve memory management flexibility and enable advanced use
> cases such as dynamic memory remapping.
> 
> Mirror the address space between the Linux root partition and guest VMs
> using HMM. The root partition owns the memory, while guest VMs act as
> devices with page tables managed via hypercalls. MSHV handles VP intercepts
> by invoking hmm_range_fault() and updating SLAT entries. When memory is
> reclaimed, HMM invalidates the relevant regions, prompting MSHV to clear
> SLAT entries; guest VMs will fault again on access.
> 
> Integrate mmu_interval_notifier for movable regions, implement handlers for
> HMM faults and memory invalidation, and update memory region mapping logic
> to support movable regions.
> 
> While MMU notifiers are commonly used in virtualization drivers, this
> implementation leverages HMM (Heterogeneous Memory Management) for its
> specialized functionality. HMM provides a framework for mirroring,
> invalidation, and fault handling, reducing boilerplate and improving
> maintainability compared to generic MMU notifiers.
> 
> Signed-off-by: Stanislav Kinsburskii <skinsburskii@linux.microsoft.com>
> ---
>  drivers/hv/Kconfig          |    2 
>  drivers/hv/mshv_regions.c   |  215 ++++++++++++++++++++++++++++++++++++++++++-
>  drivers/hv/mshv_root.h      |   17 +++
>  drivers/hv/mshv_root_main.c |  139 +++++++++++++++++++++++-----
>  4 files changed, 343 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
> index d4a8d349200c..7937ac0cbd0f 100644
> --- a/drivers/hv/Kconfig
> +++ b/drivers/hv/Kconfig
> @@ -76,6 +76,8 @@ config MSHV_ROOT
>  	depends on PAGE_SIZE_4KB
>  	select EVENTFD
>  	select VIRT_XFER_TO_GUEST_WORK
> +	select HMM_MIRROR
> +	select MMU_NOTIFIER
>  	default n
>  	help
>  	  Select this option to enable support for booting and running as root
> diff --git a/drivers/hv/mshv_regions.c b/drivers/hv/mshv_regions.c
> index 94f33754f545..afe03258caf0 100644
> --- a/drivers/hv/mshv_regions.c
> +++ b/drivers/hv/mshv_regions.c
> @@ -7,6 +7,8 @@
>   * Authors: Microsoft Linux virtualization team
>   */
>  
> +#include <linux/hmm.h>
> +#include <linux/hyperv.h>
>  #include <linux/kref.h>
>  #include <linux/mm.h>
>  #include <linux/vmalloc.h>
> @@ -15,6 +17,8 @@
>  
>  #include "mshv_root.h"
>  
> +#define MSHV_MAP_FAULT_IN_PAGES				PTRS_PER_PMD
> +
>  /**
>   * mshv_region_process_chunk - Processes a contiguous chunk of memory pages
>   *                             in a region.
> @@ -152,9 +156,6 @@ struct mshv_mem_region *mshv_region_create(u64 guest_pfn, u64 nr_pages,
>  	if (flags & BIT(MSHV_SET_MEM_BIT_EXECUTABLE))
>  		region->hv_map_flags |= HV_MAP_GPA_EXECUTABLE;
>  
> -	if (!is_mmio)
> -		region->flags.range_pinned = true;
> -

The parameter is_mmio is now unused in this function.

>  	kref_init(&region->refcount);
>  
>  	return region;
> @@ -239,7 +240,7 @@ int mshv_region_map(struct mshv_mem_region *region)
>  static void mshv_region_invalidate_pages(struct mshv_mem_region *region,
>  					 u64 page_offset, u64 page_count)
>  {
> -	if (region->flags.range_pinned)
> +	if (region->type == MSHV_REGION_TYPE_MEM_PINNED)
>  		unpin_user_pages(region->pages + page_offset, page_count);
>  
>  	memset(region->pages + page_offset, 0,
> @@ -313,6 +314,9 @@ static void mshv_region_destroy(struct kref *ref)
>  	struct mshv_partition *partition = region->partition;
>  	int ret;
>  
> +	if (region->type == MSHV_REGION_TYPE_MEM_MOVABLE)
> +		mshv_region_movable_fini(region);
> +
>  	if (mshv_partition_encrypted(partition)) {
>  		ret = mshv_region_share(region);
>  		if (ret) {
> @@ -339,3 +343,206 @@ int mshv_region_get(struct mshv_mem_region *region)
>  {
>  	return kref_get_unless_zero(&region->refcount);
>  }
> +
> +/**
> + * mshv_region_hmm_fault_and_lock - Handle HMM faults and lock the memory region
> + * @region: Pointer to the memory region structure
> + * @range: Pointer to the HMM range structure
> + *
> + * This function performs the following steps:
> + * 1. Reads the notifier sequence for the HMM range.
> + * 2. Acquires a read lock on the memory map.
> + * 3. Handles HMM faults for the specified range.
> + * 4. Releases the read lock on the memory map.
> + * 5. If successful, locks the memory region mutex.
> + * 6. Verifies if the notifier sequence has changed during the operation.
> + *    If it has, releases the mutex and returns -EBUSY to match with
> + *    hmm_range_fault() return code for repeating.
> + *
> + * Return: 0 on success, a negative error code otherwise.
> + */
> +static int mshv_region_hmm_fault_and_lock(struct mshv_mem_region *region,
> +					  struct hmm_range *range)
> +{
> +	int ret;
> +
> +	range->notifier_seq = mmu_interval_read_begin(range->notifier);
> +	mmap_read_lock(region->mni.mm);
> +	ret = hmm_range_fault(range);
> +	mmap_read_unlock(region->mni.mm);
> +	if (ret)
> +		return ret;
> +
> +	mutex_lock(&region->mutex);
> +
> +	if (mmu_interval_read_retry(range->notifier, range->notifier_seq)) {
> +		mutex_unlock(&region->mutex);
> +		cond_resched();
> +		return -EBUSY;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + * mshv_region_range_fault - Handle memory range faults for a given region.
> + * @region: Pointer to the memory region structure.
> + * @page_offset: Offset of the page within the region.
> + * @page_count: Number of pages to handle.
> + *
> + * This function resolves memory faults for a specified range of pages
> + * within a memory region. It uses HMM (Heterogeneous Memory Management)
> + * to fault in the required pages and updates the region's page array.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +static int mshv_region_range_fault(struct mshv_mem_region *region,
> +				   u64 page_offset, u64 page_count)
> +{
> +	struct hmm_range range = {
> +		.notifier = &region->mni,
> +		.default_flags = HMM_PFN_REQ_FAULT | HMM_PFN_REQ_WRITE,
> +	};
> +	unsigned long *pfns;
> +	int ret;
> +	u64 i;
> +
> +	pfns = kmalloc_array(page_count, sizeof(unsigned long), GFP_KERNEL);

nit: Prefer sizeof(*pfns)

<snip>

The rest looks fine to me. With the minor issues above fixed,
Reviewed-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>

      reply	other threads:[~2025-12-03 20:36 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-03 18:23 [PATCH v8 0/6] Introduce movable pages for Hyper-V guests Stanislav Kinsburskii
2025-12-03 18:24 ` [PATCH v8 1/6] Drivers: hv: Refactor and rename memory region handling functions Stanislav Kinsburskii
2025-12-03 18:24 ` [PATCH v8 2/6] Drivers: hv: Centralize guest memory region destruction Stanislav Kinsburskii
2025-12-03 18:24 ` [PATCH v8 3/6] Drivers: hv: Move region management to mshv_regions.c Stanislav Kinsburskii
2025-12-03 18:24 ` [PATCH v8 4/6] Drivers: hv: Fix huge page handling in memory region traversal Stanislav Kinsburskii
2025-12-03 19:47   ` Nuno Das Neves
2025-12-03 18:24 ` [PATCH v8 5/6] Drivers: hv: Add refcount and locking to mem regions Stanislav Kinsburskii
2025-12-03 19:26   ` Nuno Das Neves
2025-12-03 19:55     ` Stanislav Kinsburskii
2025-12-03 20:09       ` Nuno Das Neves
2025-12-03 18:24 ` [PATCH v8 6/6] Drivers: hv: Add support for movable memory regions Stanislav Kinsburskii
2025-12-03 20:36   ` Nuno Das Neves [this message]

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=5d309f95-84d0-462e-a463-16d303629907@linux.microsoft.com \
    --to=nunodasneves@linux.microsoft.com \
    --cc=decui@microsoft.com \
    --cc=haiyangz@microsoft.com \
    --cc=kys@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=skinsburskii@linux.microsoft.com \
    --cc=wei.liu@kernel.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.