@@ -57,6 +57,15 @@ struct hbind_params {
*/
#define HBIND_CMD_BIND 1
+/*
+ * HBIND_CMD_MIGRATE move existing memory to use listed target memory. This is
+ * a best effort.
+ *
+ * Additional dwords:
+ * [0] result ie number of pages that have been migrated.
+ */
+#define HBIND_CMD_MIGRATE 2
+
#define HBIND_IOCTL _IOWR('H', 0x00, struct hbind_params)
@@ -368,6 +368,39 @@ static int hbind_bind(struct mm_struct *mm, struct hbind_params *params,
}
+static int hbind_migrate(struct mm_struct *mm, struct hbind_params *params,
+ const uint32_t *targets, uint32_t *atoms)
+{
+ unsigned long size, npages;
+ int ret = -EINVAL;
+ unsigned i;
+
+ size = PAGE_ALIGN(params->end) - (params->start & PAGE_MASK);
+ npages = size >> PAGE_SHIFT;
+
+ for (i = 0; params->ntargets; ++i) {
+ struct hms_target *target;
+
+ target = hms_target_find(targets[i]);
+ if (target == NULL)
+ continue;
+
+ ret = target->hbind->migrate(target, mm, params->start,
+ params->end, params->natoms,
+ atoms);
+ hms_target_put(target);
+
+ if (ret)
+ continue;
+
+ if (atoms[0] >= npages)
+ break;
+ }
+
+ return ret;
+}
+
+
static long hbind_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{
uint32_t *targets, *_dtargets = NULL, _ftargets[HBIND_FIX_ARRAY];
@@ -458,6 +491,16 @@ static long hbind_ioctl(struct file *file, unsigned cmd, unsigned long arg)
if (ret)
goto out_mm;
break;
+ case HBIND_CMD_MIGRATE:
+ if (ndwords != 2) {
+ ret = -EINVAL;
+ goto out_mm;
+ }
+ ret = hbind_migrate(current->mm, ¶ms,
+ targets, atoms);
+ if (ret)
+ goto out_mm;
+ break;
default:
ret = -EINVAL;
goto out_mm;