vcsm: Add ioctl for custom cache flushing

This commit is contained in:
popcornmix
2015-05-19 18:49:06 +01:00
parent b4eeb0d675
commit ef724874a7
2 changed files with 64 additions and 0 deletions

View File

@@ -61,6 +61,8 @@ enum vmcs_sm_cmd_e {
VMCS_SM_CMD_HOST_WALK_PID_ALLOC,
VMCS_SM_CMD_HOST_WALK_PID_MAP,
VMCS_SM_CMD_CLEAN_INVALID,
VMCS_SM_CMD_LAST /* Do no delete */
};
@@ -163,6 +165,16 @@ struct vmcs_sm_ioctl_cache {
unsigned int size;
};
struct vmcs_sm_ioctl_clean_invalid {
/* user -> kernel */
struct {
unsigned int cmd;
unsigned int handle;
unsigned int addr;
unsigned int size;
} s[8];
};
/* IOCTL numbers */
#define VMCS_SM_IOCTL_MEM_ALLOC\
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_ALLOC,\
@@ -191,6 +203,9 @@ struct vmcs_sm_ioctl_cache {
#define VMCS_SM_IOCTL_MEM_INVALID\
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_INVALID,\
struct vmcs_sm_ioctl_cache)
#define VMCS_SM_IOCTL_MEM_CLEAN_INVALID\
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_CLEAN_INVALID,\
struct vmcs_sm_ioctl_clean_invalid)
#define VMCS_SM_IOCTL_SIZE_USR_HDL\
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_SIZE_USR_HANDLE,\

View File

@@ -2732,6 +2732,55 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
break;
/* Flush/Invalidate the cache for a given mapping. */
case VMCS_SM_CMD_CLEAN_INVALID:
{
int i;
struct vmcs_sm_ioctl_clean_invalid ioparam;
/* Get parameter data. */
if (copy_from_user(&ioparam,
(void *)arg, sizeof(ioparam)) != 0) {
pr_err("[%s]: failed to copy-from-user for cmd %x\n",
__func__, cmdnr);
ret = -EFAULT;
goto out;
}
for (i=0; i<sizeof ioparam.s/sizeof *ioparam.s; i++) {
switch (ioparam.s[i].cmd) {
default: case 0: break; /* NOOP */
case 1: /* L1/L2 invalidate virtual range */
case 2: /* L1/L2 clean physical range */
case 3: /* L1/L2 clean+invalidate all */
{
/* Locate resource from GUID.
*/
resource =
vmcs_sm_acquire_resource(file_data, ioparam.s[i].handle);
if ((resource != NULL) && resource->res_cached) {
unsigned long base = ioparam.s[i].addr & ~(PAGE_SIZE-1);
unsigned long end = (ioparam.s[i].addr + ioparam.s[i].size + PAGE_SIZE-1) & ~(PAGE_SIZE-1);
resource->res_stats[ioparam.s[i].cmd == 1 ? INVALID:FLUSH]++;
/* L1/L2 cache flush */
down_read(&current->mm->mmap_sem);
vcsm_vma_cache_clean_page_range(base, end);
up_read(&current->mm->mmap_sem);
} else if (resource == NULL) {
ret = -EINVAL;
goto out;
}
if (resource)
vmcs_sm_release_resource(resource, 0);
}
break;
}
}
}
break;
default:
{
ret = -EINVAL;