mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
vcsm: Add ioctl for custom cache flushing
This commit is contained in:
@@ -61,6 +61,8 @@ enum vmcs_sm_cmd_e {
|
|||||||
VMCS_SM_CMD_HOST_WALK_PID_ALLOC,
|
VMCS_SM_CMD_HOST_WALK_PID_ALLOC,
|
||||||
VMCS_SM_CMD_HOST_WALK_PID_MAP,
|
VMCS_SM_CMD_HOST_WALK_PID_MAP,
|
||||||
|
|
||||||
|
VMCS_SM_CMD_CLEAN_INVALID,
|
||||||
|
|
||||||
VMCS_SM_CMD_LAST /* Do no delete */
|
VMCS_SM_CMD_LAST /* Do no delete */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,6 +165,16 @@ struct vmcs_sm_ioctl_cache {
|
|||||||
unsigned int size;
|
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 */
|
/* IOCTL numbers */
|
||||||
#define VMCS_SM_IOCTL_MEM_ALLOC\
|
#define VMCS_SM_IOCTL_MEM_ALLOC\
|
||||||
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_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\
|
#define VMCS_SM_IOCTL_MEM_INVALID\
|
||||||
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_INVALID,\
|
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_INVALID,\
|
||||||
struct vmcs_sm_ioctl_cache)
|
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\
|
#define VMCS_SM_IOCTL_SIZE_USR_HDL\
|
||||||
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_SIZE_USR_HANDLE,\
|
_IOR(VMCS_SM_MAGIC_TYPE, VMCS_SM_CMD_SIZE_USR_HANDLE,\
|
||||||
|
|||||||
@@ -2732,6 +2732,55 @@ static long vc_sm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
|||||||
}
|
}
|
||||||
break;
|
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(¤t->mm->mmap_sem);
|
||||||
|
vcsm_vma_cache_clean_page_range(base, end);
|
||||||
|
up_read(¤t->mm->mmap_sem);
|
||||||
|
} else if (resource == NULL) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource)
|
||||||
|
vmcs_sm_release_resource(resource, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|||||||
Reference in New Issue
Block a user