If a VM is started with device attached, the mem regions must be marked non-movable as the device attach hypercall right away allows the use of SLAT for IOMMU. Marking them non-movable forces mapping of the entire guest RAM in the SLAT at the time of region creation along with the region pinned. Also, because a device could be dynamically attached much later in a VM, create a boot parameter to disable movable pages that users can set if they anticipate such an action.
Signed-off-by: Mukesh R <[email protected]> --- drivers/hv/mshv_root.h | 1 + drivers/hv/mshv_root_main.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h index b9880d0bdc4d..d57c26950203 100644 --- a/drivers/hv/mshv_root.h +++ b/drivers/hv/mshv_root.h @@ -141,6 +141,7 @@ struct mshv_partition { pid_t pt_vmm_tgid; bool import_completed; bool pt_initialized; + bool pt_regions_pinned; #if IS_ENABLED(CONFIG_DEBUG_FS) struct dentry *pt_stats_dentry; struct dentry *pt_vp_dentry; diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c index a7864463961b..ac71534733bd 100644 --- a/drivers/hv/mshv_root_main.c +++ b/drivers/hv/mshv_root_main.c @@ -49,6 +49,10 @@ MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv"); static bool hv_nofull_mmio; /* don't map entire mmio region upon fault */ module_param(hv_nofull_mmio, bool, 0644); +static bool hv_no_movbl_pgs; /* disable movable pages completely */ +module_param(hv_no_movbl_pgs, bool, 0644); +MODULE_PARM_DESC(hv_no_movbl_pgs, "If set, don't do movable pages for VMs"); + struct mshv_root mshv_root; enum hv_scheduler_type hv_scheduler_type; @@ -1303,6 +1307,12 @@ static void mshv_async_hvcall_handler(void *data, u64 *status) *status = partition->async_hypercall_status; } +static bool mshv_do_pt_regions_pinned(struct mshv_partition *pt) +{ + return pt->pt_regions_pinned || mshv_partition_encrypted(pt) || + hv_no_movbl_pgs; +} + /* * NB: caller checks and makes sure mem->size is page aligned * Returns: 0 with regionpp updated on success, or -errno @@ -1333,7 +1343,7 @@ static int mshv_partition_create_region(struct mshv_partition *partition, if (is_mmio) rg->mreg_type = MSHV_REGION_TYPE_MMIO; - else if (mshv_partition_encrypted(partition) || + else if (mshv_do_pt_regions_pinned(partition) || !mshv_region_movable_init(rg)) rg->mreg_type = MSHV_REGION_TYPE_MEM_PINNED; else @@ -1808,6 +1818,9 @@ static long mshv_partition_ioctl_create_device(struct mshv_partition *partition, if (copy_to_user(uarg, &devargk, sizeof(devargk))) return -EFAULT; /* cleanup in mshv_device_fop_release() */ + /* For now, all regions must be pinned if there is device passthru. */ + partition->pt_regions_pinned = true; + return 0; undo_out: -- 2.51.2.vfs.0.1

