Merge "msm: ipa3: fix compatibility with ipa user space"

This commit is contained in:
Linux Build Service Account 2017-09-04 15:01:54 -07:00 committed by Gerrit - the friendly Code Review server
commit d727a95d2e
3 changed files with 142 additions and 7 deletions

View file

@ -143,6 +143,9 @@
#define IPA_IOC_ALLOC_NAT_MEM32 _IOWR(IPA_IOC_MAGIC, \
IPA_IOCTL_ALLOC_NAT_MEM, \
compat_uptr_t)
#define IPA_IOC_ALLOC_NAT_TABLE32 _IOWR(IPA_IOC_MAGIC, \
IPA_IOCTL_ALLOC_NAT_TABLE, \
compat_uptr_t)
#define IPA_IOC_V4_INIT_NAT32 _IOWR(IPA_IOC_MAGIC, \
IPA_IOCTL_V4_INIT_NAT, \
compat_uptr_t)
@ -152,6 +155,9 @@
#define IPA_IOC_V4_DEL_NAT32 _IOWR(IPA_IOC_MAGIC, \
IPA_IOCTL_V4_DEL_NAT, \
compat_uptr_t)
#define IPA_IOC_DEL_NAT_TABLE32 _IOWR(IPA_IOC_MAGIC, \
IPA_IOCTL_DEL_NAT_TABLE, \
compat_uptr_t)
#define IPA_IOC_GET_NAT_OFFSET32 _IOWR(IPA_IOC_MAGIC, \
IPA_IOCTL_GET_NAT_OFFSET, \
compat_uptr_t)
@ -207,6 +213,18 @@ struct ipa3_ioc_nat_alloc_mem32 {
compat_size_t size;
compat_off_t offset;
};
/**
* struct ipa_ioc_nat_ipv6ct_table_alloc32 - table memory allocation
* properties
* @size: input parameter, size of table in bytes
* @offset: output parameter, offset into page in case of system memory
*/
struct ipa_ioc_nat_ipv6ct_table_alloc32 {
compat_size_t size;
compat_off_t offset;
};
#endif
#define IPA_TZ_UNLOCK_ATTRIBUTE 0x0C0311
@ -703,8 +721,10 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
u8 header[128] = { 0 };
u8 *param = NULL;
struct ipa_ioc_nat_alloc_mem nat_mem;
struct ipa_ioc_nat_ipv6ct_table_alloc table_alloc;
struct ipa_ioc_v4_nat_init nat_init;
struct ipa_ioc_v4_nat_del nat_del;
struct ipa_ioc_nat_ipv6ct_table_del table_del;
struct ipa_ioc_rm_dependency rm_depend;
size_t sz;
int pre_entry;
@ -743,6 +763,26 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
break;
}
break;
case IPA_IOC_ALLOC_NAT_TABLE:
if (copy_from_user(&table_alloc, (const void __user *)arg,
sizeof(struct ipa_ioc_nat_ipv6ct_table_alloc))) {
retval = -EFAULT;
break;
}
if (ipa3_allocate_nat_table(&table_alloc)) {
retval = -EFAULT;
break;
}
if (table_alloc.offset &&
copy_to_user((void __user *)arg, &table_alloc, sizeof(
struct ipa_ioc_nat_ipv6ct_table_alloc))) {
retval = -EFAULT;
break;
}
break;
case IPA_IOC_V4_INIT_NAT:
if (copy_from_user((u8 *)&nat_init, (u8 *)arg,
sizeof(struct ipa_ioc_v4_nat_init))) {
@ -803,6 +843,18 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
}
break;
case IPA_IOC_DEL_NAT_TABLE:
if (copy_from_user(&table_del, (const void __user *)arg,
sizeof(struct ipa_ioc_nat_ipv6ct_table_del))) {
retval = -EFAULT;
break;
}
if (ipa3_del_nat_table(&table_del)) {
retval = -EFAULT;
break;
}
break;
case IPA_IOC_ADD_HDR:
if (copy_from_user(header, (u8 *)arg,
sizeof(struct ipa_ioc_add_hdr))) {
@ -3109,6 +3161,34 @@ static void ipa3_teardown_apps_pipes(void)
}
#ifdef CONFIG_COMPAT
static long compat_ipa3_nat_ipv6ct_alloc_table(unsigned long arg,
int (alloc_func)(struct ipa_ioc_nat_ipv6ct_table_alloc *))
{
long retval;
struct ipa_ioc_nat_ipv6ct_table_alloc32 table_alloc32;
struct ipa_ioc_nat_ipv6ct_table_alloc table_alloc;
retval = copy_from_user(&table_alloc32, (const void __user *)arg,
sizeof(struct ipa_ioc_nat_ipv6ct_table_alloc32));
if (retval)
return retval;
table_alloc.size = (size_t)table_alloc32.size;
table_alloc.offset = (off_t)table_alloc32.offset;
retval = alloc_func(&table_alloc);
if (retval)
return retval;
if (table_alloc.offset) {
table_alloc32.offset = (compat_off_t)table_alloc.offset;
retval = copy_to_user((void __user *)arg, &table_alloc32,
sizeof(struct ipa_ioc_nat_ipv6ct_table_alloc32));
}
return retval;
}
long compat_ipa3_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int retval = 0;
@ -3180,6 +3260,9 @@ long compat_ipa3_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
ret:
return retval;
case IPA_IOC_ALLOC_NAT_TABLE32:
return compat_ipa3_nat_ipv6ct_alloc_table(arg,
ipa3_allocate_nat_table);
case IPA_IOC_V4_INIT_NAT32:
cmd = IPA_IOC_V4_INIT_NAT;
break;
@ -3189,6 +3272,9 @@ ret:
case IPA_IOC_V4_DEL_NAT32:
cmd = IPA_IOC_V4_DEL_NAT;
break;
case IPA_IOC_DEL_NAT_TABLE32:
cmd = IPA_IOC_DEL_NAT_TABLE;
break;
case IPA_IOC_GET_NAT_OFFSET32:
cmd = IPA_IOC_GET_NAT_OFFSET;
break;

View file

@ -38,7 +38,6 @@
#include "ipa_uc_offload_i.h"
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
#define IPA_COOKIE 0x57831603
#define IPA_RT_RULE_COOKIE 0x57831604
#define IPA_RT_TBL_COOKIE 0x57831605
@ -1641,12 +1640,15 @@ int ipa3_reset_flt(enum ipa_ip_type ip);
* NAT
*/
int ipa3_allocate_nat_device(struct ipa_ioc_nat_alloc_mem *mem);
int ipa3_allocate_nat_table(
struct ipa_ioc_nat_ipv6ct_table_alloc *table_alloc);
int ipa3_nat_init_cmd(struct ipa_ioc_v4_nat_init *init);
int ipa3_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma);
int ipa3_nat_del_cmd(struct ipa_ioc_v4_nat_del *del);
int ipa3_del_nat_table(struct ipa_ioc_nat_ipv6ct_table_del *del);
/*
* Messaging

View file

@ -34,7 +34,6 @@ enum nat_table_type {
#define NAT_TABLE_ENTRY_SIZE_BYTE 32
#define NAT_INTEX_TABLE_ENTRY_SIZE_BYTE 4
static int ipa3_nat_vma_fault_remap(
struct vm_area_struct *vma, struct vm_fault *vmf)
{
@ -167,7 +166,7 @@ int ipa3_create_nat_device(void)
IPADBG("\n");
mutex_lock(&nat_ctx->lock);
nat_ctx->class = class_create(THIS_MODULE, NAT_DEV_NAME);
nat_ctx->class = class_create(THIS_MODULE, IPA_NAT_DEV_NAME);
if (IS_ERR(nat_ctx->class)) {
IPAERR("unable to create the class\n");
result = -ENODEV;
@ -176,7 +175,7 @@ int ipa3_create_nat_device(void)
result = alloc_chrdev_region(&nat_ctx->dev_num,
0,
1,
NAT_DEV_NAME);
IPA_NAT_DEV_NAME);
if (result) {
IPAERR("alloc_chrdev_region err.\n");
result = -ENODEV;
@ -185,7 +184,7 @@ int ipa3_create_nat_device(void)
nat_ctx->dev =
device_create(nat_ctx->class, NULL, nat_ctx->dev_num, nat_ctx,
"%s", NAT_DEV_NAME);
"%s", IPA_NAT_DEV_NAME);
if (IS_ERR(nat_ctx->dev)) {
IPAERR("device_create err:%ld\n", PTR_ERR(nat_ctx->dev));
@ -253,9 +252,10 @@ int ipa3_allocate_nat_device(struct ipa_ioc_nat_alloc_mem *mem)
IPADBG("passed memory size %zu\n", mem->size);
mutex_lock(&nat_ctx->lock);
if (strcmp(mem->dev_name, NAT_DEV_NAME)) {
if (strcmp(IPA_NAT_DEV_NAME, mem->dev_name)) {
IPAERR_RL("Nat device name mismatch\n");
IPAERR_RL("Expect: %s Recv: %s\n", NAT_DEV_NAME, mem->dev_name);
IPAERR_RL("Expect: %s Recv: %s\n",
IPA_NAT_DEV_NAME, mem->dev_name);
result = -EPERM;
goto bail;
}
@ -306,6 +306,34 @@ bail:
return result;
}
/**
* ipa3_allocate_nat_table() - Allocates memory for the NAT table
* @table_alloc: [in/out] memory parameters
*
* Called by NAT client to allocate memory for the table entries.
* Based on the request size either shared or system memory will be used.
*
* Returns: 0 on success, negative on failure
*/
int ipa3_allocate_nat_table(struct ipa_ioc_nat_ipv6ct_table_alloc *table_alloc)
{
int result;
struct ipa_ioc_nat_alloc_mem tmp;
strlcpy(tmp.dev_name, IPA_NAT_DEV_NAME, IPA_RESOURCE_NAME_MAX);
tmp.size = table_alloc->size;
tmp.offset = 0;
result = ipa3_allocate_nat_device(&tmp);
if (result)
goto bail;
table_alloc->offset = tmp.offset;
bail:
return result;
}
/* IOCTL function handlers */
/**
* ipa3_nat_init_cmd() - Post IP_V4_NAT_INIT command to IPA HW
@ -833,3 +861,22 @@ destroy_regwrt_imm_cmd:
bail:
return result;
}
/**
* ipa3_del_nat_table() - Delete the NAT table
* @del: [in] delete table parameters
*
* Called by NAT client to delete the table
*
* Returns: 0 on success, negative on failure
*/
int ipa3_del_nat_table(struct ipa_ioc_nat_ipv6ct_table_del *del)
{
struct ipa_ioc_v4_nat_del tmp;
tmp.table_index = del->table_index;
tmp.public_ip_addr = ipa3_ctx->nat_mem.public_ip_addr;
return ipa3_nat_del_cmd(&tmp);
}