[PATCH v4 1/2] create SMAF module

2015-10-06 Thread Benjamin Gaignard
Thanks for your review I will add a lock in smaf_handle structure.

One of the goal of smaf is to create a standard kernel API to allocate
and secure buffers to avoid forking
while implementing buffer securing feature.

One concern about ION is that the selection of the heap is done by userland
so hardware constraints need to be known by the userland, which is
problematic from my point of view.
Compare to ION I have try to introduce features like securing API,
flexible allocator selection on kernel
and the possibility to add custom allocator and securing modules.

Benjamin



2015-10-06 3:58 GMT+02:00 Laura Abbott :
> On 10/05/2015 03:11 AM, Benjamin Gaignard wrote:
>>
>> diff --git a/drivers/smaf/smaf-core.c b/drivers/smaf/smaf-core.c
>> new file mode 100644
>> index 000..37914e7
>> --- /dev/null
>> +++ b/drivers/smaf/smaf-core.c
>> @@ -0,0 +1,736 @@
>> +/*
>> + * smaf.c
>> + *
>> + * Copyright (C) Linaro SA 2015
>> + * Author: Benjamin Gaignard  for Linaro.
>> + * License terms:  GNU General Public License (GPL), version 2
>> + */
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +struct smaf_handle {
>> +   struct dma_buf *dmabuf;
>> +   struct smaf_allocator *allocator;
>> +   struct dma_buf *db_alloc;
>> +   size_t length;
>> +   unsigned int flags;
>> +   int fd;
>> +   bool is_secure;
>> +   void *secure_ctx;
>> +};
>> +
>> +/**
>> + * struct smaf_device - smaf device node private data
>> + * @misc_dev:  the misc device
>> + * @head:  list of allocator
>> + * @lock:  list and secure pointer mutex
>> + * @secure:pointer to secure functions helpers
>> + */
>> +struct smaf_device {
>> +   struct miscdevice misc_dev;
>> +   struct list_head head;
>> +   /* list and secure pointer lock*/
>> +   struct mutex lock;
>> +   struct smaf_secure *secure;
>> +};
>> +
>> +static struct smaf_device smaf_dev;
>> +
>> +/**
>> + * smaf_allow_cpu_access return true if CPU can access to memory
>> + * if their is no secure module associated to SMAF assume that CPU can
>> get
>> + * access to the memory.
>> + */
>> +static bool smaf_allow_cpu_access(struct smaf_handle *handle,
>> + unsigned long flags)
>> +{
>> +   if (!handle->is_secure)
>> +   return true;
>> +
>> +   if (!smaf_dev.secure)
>> +   return true;
>> +
>> +   if (!smaf_dev.secure->allow_cpu_access)
>> +   return true;
>> +
>> +   return smaf_dev.secure->allow_cpu_access(handle->secure_ctx,
>> flags);
>> +}
>> +
>> +static int smaf_grant_access(struct smaf_handle *handle, struct device
>> *dev,
>> +dma_addr_t addr, size_t size,
>> +enum dma_data_direction dir)
>> +{
>> +   if (!handle->is_secure)
>> +   return 0;
>> +
>> +   if (!smaf_dev.secure)
>> +   return -EINVAL;
>> +
>> +   if (!smaf_dev.secure->grant_access)
>> +   return -EINVAL;
>> +
>> +   return smaf_dev.secure->grant_access(handle->secure_ctx,
>> +dev, addr, size, dir);
>> +}
>> +
>> +static void smaf_revoke_access(struct smaf_handle *handle, struct device
>> *dev,
>> +  dma_addr_t addr, size_t size,
>> +  enum dma_data_direction dir)
>> +{
>> +   if (!handle->is_secure)
>> +   return;
>> +
>> +   if (!smaf_dev.secure)
>> +   return;
>> +
>> +   if (!smaf_dev.secure->revoke_access)
>> +   return;
>> +
>> +   smaf_dev.secure->revoke_access(handle->secure_ctx,
>> +  dev, addr, size, dir);
>> +}
>> +
>> +static int smaf_secure_handle(struct smaf_handle *handle)
>> +{
>> +   if (handle->is_secure)
>> +   return 0;
>> +
>> +   if (!smaf_dev.secure)
>> +   return -EINVAL;
>> +
>> +   if (!smaf_dev.secure->create_context)
>> +   return -EINVAL;
>> +
>> +   handle->secure_ctx = smaf_dev.secure->create_context();
>> +
>> +   if (!handle->secure_ctx)
>> +   return -EINVAL;
>> +
>> +   handle->is_secure = true;
>> +   return 0;
>> +}
>> +
>> +static int smaf_unsecure_handle(struct smaf_handle *handle)
>> +{
>> +   if (!handle->is_secure)
>> +   return 0;
>> +
>> +   if (!smaf_dev.secure)
>> +   return -EINVAL;
>> +
>> +   if (!smaf_dev.secure->destroy_context)
>> +   return -EINVAL;
>> +
>> +   if (smaf_dev.secure->destroy_context(handle->secure_ctx))
>> +   return -EINVAL;
>> +
>> +   handle->secure_ctx = NULL;
>> +   handle->is_secure = false;
>> +   return 0;
>> +}
>
>
> All these functions need to be protected by a lock, otherwise the
> secure state could change. For 

[PATCH v4 1/2] create SMAF module

2015-10-06 Thread kbuild test robot
Hi Benjamin,

[auto build test ERROR on v4.3-rc4 -- if it's inappropriate base, please ignore]

config: s390-allmodconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=s390 

All error/warnings (new ones prefixed by >>):

   In file included from arch/s390/include/asm/elf.h:130:0,
from include/linux/elf.h:4,
from include/linux/module.h:15,
from drivers/smaf/smaf-core.c:16:
   drivers/smaf/smaf-core.c: In function 'smaf_unsecure_handle':
>> arch/s390/include/asm/mmu_context.h:33:41: error: expected identifier before 
>> 'do'
#define destroy_context(mm) do { } while (0)
^
>> drivers/smaf/smaf-core.c:136:23: note: in expansion of macro 
>> 'destroy_context'
 if (smaf_dev.secure->destroy_context(handle->secure_ctx))
  ^

vim +/destroy_context +136 drivers/smaf/smaf-core.c

10  #include 
11  #include 
12  #include 
13  #include 
14  #include 
15  #include 
  > 16  #include 
17  #include 
18  #include 
19  #include 
20  #include 
21  #include 
22  
23  struct smaf_handle {
24  struct dma_buf *dmabuf;
25  struct smaf_allocator *allocator;
26  struct dma_buf *db_alloc;
27  size_t length;
28  unsigned int flags;
29  int fd;
30  bool is_secure;
31  void *secure_ctx;
32  };
33  
34  /**
35   * struct smaf_device - smaf device node private data
36   * @misc_dev:   the misc device
37   * @head:   list of allocator
38   * @lock:   list and secure pointer mutex
39   * @secure: pointer to secure functions helpers
40   */
41  struct smaf_device {
42  struct miscdevice misc_dev;
43  struct list_head head;
44  /* list and secure pointer lock*/
45  struct mutex lock;
46  struct smaf_secure *secure;
47  };
48  
49  static struct smaf_device smaf_dev;
50  
51  /**
52   * smaf_allow_cpu_access return true if CPU can access to memory
53   * if their is no secure module associated to SMAF assume that CPU can 
get
54   * access to the memory.
55   */
56  static bool smaf_allow_cpu_access(struct smaf_handle *handle,
57unsigned long flags)
58  {
59  if (!handle->is_secure)
60  return true;
61  
62  if (!smaf_dev.secure)
63  return true;
64  
65  if (!smaf_dev.secure->allow_cpu_access)
66  return true;
67  
68  return smaf_dev.secure->allow_cpu_access(handle->secure_ctx, 
flags);
69  }
70  
71  static int smaf_grant_access(struct smaf_handle *handle, struct device 
*dev,
72   dma_addr_t addr, size_t size,
73   enum dma_data_direction dir)
74  {
75  if (!handle->is_secure)
76  return 0;
77  
78  if (!smaf_dev.secure)
79  return -EINVAL;
80  
81  if (!smaf_dev.secure->grant_access)
82  return -EINVAL;
83  
84  return smaf_dev.secure->grant_access(handle->secure_ctx,
85   dev, addr, size, dir);
86  }
87  
88  static void smaf_revoke_access(struct smaf_handle *handle, struct 
device *dev,
89 dma_addr_t addr, size_t size,
90 enum dma_data_direction dir)
91  {
92  if (!handle->is_secure)
93  return;
94  
95  if (!smaf_dev.secure)
96  return;
97  
98  if (!smaf_dev.secure->revoke_access)
99  return;
   100  
   101  smaf_dev.secure->revoke_access(handle->secure_ctx,
   102 dev, addr, size, dir);
   103  }
   104  
   105  static int smaf_secure_handle(struct smaf_handle *handle)
   106  {
   107  if (handle->is_secure)
   108  return 0;
   109  
   110  if (!smaf_dev.secure)
   111  return -EINVAL;
   112  
   113  if (!smaf_dev.secure->create_context)
   114  return -EINVAL;
   115  
   116  handle->secure_ctx = smaf_dev.secure->create_context();
   117  
   118  if (!handle->secure_ctx)
   119  return -EINVAL;
   120  
   121  handle->is_secure = true;
   122  return 0;
   123  }
   124  
   125  static int 

[PATCH v4 1/2] create SMAF module

2015-10-05 Thread Laura Abbott
On 10/05/2015 03:11 AM, Benjamin Gaignard wrote:
> diff --git a/drivers/smaf/smaf-core.c b/drivers/smaf/smaf-core.c
> new file mode 100644
> index 000..37914e7
> --- /dev/null
> +++ b/drivers/smaf/smaf-core.c
> @@ -0,0 +1,736 @@
> +/*
> + * smaf.c
> + *
> + * Copyright (C) Linaro SA 2015
> + * Author: Benjamin Gaignard  for Linaro.
> + * License terms:  GNU General Public License (GPL), version 2
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct smaf_handle {
> + struct dma_buf *dmabuf;
> + struct smaf_allocator *allocator;
> + struct dma_buf *db_alloc;
> + size_t length;
> + unsigned int flags;
> + int fd;
> + bool is_secure;
> + void *secure_ctx;
> +};
> +
> +/**
> + * struct smaf_device - smaf device node private data
> + * @misc_dev:the misc device
> + * @head:list of allocator
> + * @lock:list and secure pointer mutex
> + * @secure:  pointer to secure functions helpers
> + */
> +struct smaf_device {
> + struct miscdevice misc_dev;
> + struct list_head head;
> + /* list and secure pointer lock*/
> + struct mutex lock;
> + struct smaf_secure *secure;
> +};
> +
> +static struct smaf_device smaf_dev;
> +
> +/**
> + * smaf_allow_cpu_access return true if CPU can access to memory
> + * if their is no secure module associated to SMAF assume that CPU can get
> + * access to the memory.
> + */
> +static bool smaf_allow_cpu_access(struct smaf_handle *handle,
> +   unsigned long flags)
> +{
> + if (!handle->is_secure)
> + return true;
> +
> + if (!smaf_dev.secure)
> + return true;
> +
> + if (!smaf_dev.secure->allow_cpu_access)
> + return true;
> +
> + return smaf_dev.secure->allow_cpu_access(handle->secure_ctx, flags);
> +}
> +
> +static int smaf_grant_access(struct smaf_handle *handle, struct device *dev,
> +  dma_addr_t addr, size_t size,
> +  enum dma_data_direction dir)
> +{
> + if (!handle->is_secure)
> + return 0;
> +
> + if (!smaf_dev.secure)
> + return -EINVAL;
> +
> + if (!smaf_dev.secure->grant_access)
> + return -EINVAL;
> +
> + return smaf_dev.secure->grant_access(handle->secure_ctx,
> +  dev, addr, size, dir);
> +}
> +
> +static void smaf_revoke_access(struct smaf_handle *handle, struct device 
> *dev,
> +dma_addr_t addr, size_t size,
> +enum dma_data_direction dir)
> +{
> + if (!handle->is_secure)
> + return;
> +
> + if (!smaf_dev.secure)
> + return;
> +
> + if (!smaf_dev.secure->revoke_access)
> + return;
> +
> + smaf_dev.secure->revoke_access(handle->secure_ctx,
> +dev, addr, size, dir);
> +}
> +
> +static int smaf_secure_handle(struct smaf_handle *handle)
> +{
> + if (handle->is_secure)
> + return 0;
> +
> + if (!smaf_dev.secure)
> + return -EINVAL;
> +
> + if (!smaf_dev.secure->create_context)
> + return -EINVAL;
> +
> + handle->secure_ctx = smaf_dev.secure->create_context();
> +
> + if (!handle->secure_ctx)
> + return -EINVAL;
> +
> + handle->is_secure = true;
> + return 0;
> +}
> +
> +static int smaf_unsecure_handle(struct smaf_handle *handle)
> +{
> + if (!handle->is_secure)
> + return 0;
> +
> + if (!smaf_dev.secure)
> + return -EINVAL;
> +
> + if (!smaf_dev.secure->destroy_context)
> + return -EINVAL;
> +
> + if (smaf_dev.secure->destroy_context(handle->secure_ctx))
> + return -EINVAL;
> +
> + handle->secure_ctx = NULL;
> + handle->is_secure = false;
> + return 0;
> +}

All these functions need to be protected by a lock, otherwise the
secure state could change. For that matter, I think the smaf_handle
needs a lock to protect its state as well for places like map_dma_buf

>

> +static long smaf_ioctl(struct file *file, unsigned int cmd, unsigned long 
> arg)
> +{
> + switch (cmd) {
> + case SMAF_IOC_CREATE:
> + {
> + struct smaf_create_data data;
> + struct smaf_handle *handle;
> +
> + if (copy_from_user(, (void __user *)arg, _IOC_SIZE(cmd)))
> + return -EFAULT;
> +
> + handle = smaf_create_handle(data.length, data.flags);
> + if (!handle)
> + return -EINVAL;
> +
> + if (data.name[0]) {
> + /* user force allocator selection */
> + if (smaf_select_allocator_by_name(handle->dmabuf,
> +   data.name)) {
> + dma_buf_put(handle->dmabuf);

[PATCH v4 1/2] create SMAF module

2015-10-05 Thread Benjamin Gaignard
Secure Memory Allocation Framework goal is to be able
to allocate memory that can be securing.
There is so much ways to allocate and securing memory that SMAF
doesn't do it by itself but need help of additional modules.
To be sure to use the correct allocation method SMAF implement
deferred allocation (i.e. allocate memory when only really needed)

Allocation modules (smaf-alloctor.h):
SMAF could manage with multiple allocation modules at same time.
To select the good one SMAF call match() to be sure that a module
can allocate memory for a given list of devices. It is to the module
to check if the devices are compatible or not with it allocation
method.

Securing module (smaf-secure.h):
The way of how securing memory it is done is platform specific.
Secure module is responsible of grant/revoke memory access.

Signed-off-by: Benjamin Gaignard 
---
 drivers/Kconfig|   2 +
 drivers/Makefile   |   1 +
 drivers/smaf/Kconfig   |   5 +
 drivers/smaf/Makefile  |   1 +
 drivers/smaf/smaf-core.c   | 736 +
 include/linux/smaf-allocator.h |  54 +++
 include/linux/smaf-secure.h|  72 
 include/uapi/linux/smaf.h  |  52 +++
 8 files changed, 923 insertions(+)
 create mode 100644 drivers/smaf/Kconfig
 create mode 100644 drivers/smaf/Makefile
 create mode 100644 drivers/smaf/smaf-core.c
 create mode 100644 include/linux/smaf-allocator.h
 create mode 100644 include/linux/smaf-secure.h
 create mode 100644 include/uapi/linux/smaf.h

diff --git a/drivers/Kconfig b/drivers/Kconfig
index 46b4a8e..a488c20 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -188,4 +188,6 @@ source "drivers/nvdimm/Kconfig"

 source "drivers/nvmem/Kconfig"

+source "drivers/smaf/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index b250b36..693390b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -167,3 +167,4 @@ obj-$(CONFIG_THUNDERBOLT)   += thunderbolt/
 obj-$(CONFIG_CORESIGHT)+= hwtracing/coresight/
 obj-$(CONFIG_ANDROID)  += android/
 obj-$(CONFIG_NVMEM)+= nvmem/
+obj-$(CONFIG_SMAF) += smaf/
diff --git a/drivers/smaf/Kconfig b/drivers/smaf/Kconfig
new file mode 100644
index 000..d36651a
--- /dev/null
+++ b/drivers/smaf/Kconfig
@@ -0,0 +1,5 @@
+config SMAF
+   tristate "Secure Memory Allocation Framework"
+   depends on DMA_SHARED_BUFFER
+   help
+ Choose this option to enable Secure Memory Allocation Framework
diff --git a/drivers/smaf/Makefile b/drivers/smaf/Makefile
new file mode 100644
index 000..40cd882
--- /dev/null
+++ b/drivers/smaf/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SMAF) += smaf-core.o
diff --git a/drivers/smaf/smaf-core.c b/drivers/smaf/smaf-core.c
new file mode 100644
index 000..37914e7
--- /dev/null
+++ b/drivers/smaf/smaf-core.c
@@ -0,0 +1,736 @@
+/*
+ * smaf.c
+ *
+ * Copyright (C) Linaro SA 2015
+ * Author: Benjamin Gaignard  for Linaro.
+ * License terms:  GNU General Public License (GPL), version 2
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct smaf_handle {
+   struct dma_buf *dmabuf;
+   struct smaf_allocator *allocator;
+   struct dma_buf *db_alloc;
+   size_t length;
+   unsigned int flags;
+   int fd;
+   bool is_secure;
+   void *secure_ctx;
+};
+
+/**
+ * struct smaf_device - smaf device node private data
+ * @misc_dev:  the misc device
+ * @head:  list of allocator
+ * @lock:  list and secure pointer mutex
+ * @secure:pointer to secure functions helpers
+ */
+struct smaf_device {
+   struct miscdevice misc_dev;
+   struct list_head head;
+   /* list and secure pointer lock*/
+   struct mutex lock;
+   struct smaf_secure *secure;
+};
+
+static struct smaf_device smaf_dev;
+
+/**
+ * smaf_allow_cpu_access return true if CPU can access to memory
+ * if their is no secure module associated to SMAF assume that CPU can get
+ * access to the memory.
+ */
+static bool smaf_allow_cpu_access(struct smaf_handle *handle,
+ unsigned long flags)
+{
+   if (!handle->is_secure)
+   return true;
+
+   if (!smaf_dev.secure)
+   return true;
+
+   if (!smaf_dev.secure->allow_cpu_access)
+   return true;
+
+   return smaf_dev.secure->allow_cpu_access(handle->secure_ctx, flags);
+}
+
+static int smaf_grant_access(struct smaf_handle *handle, struct device *dev,
+dma_addr_t addr, size_t size,
+enum dma_data_direction dir)
+{
+   if (!handle->is_secure)
+   return 0;
+
+   if (!smaf_dev.secure)
+   return -EINVAL;
+
+   if (!smaf_dev.secure->grant_access)
+   return -EINVAL;
+
+   return smaf_dev.secure->grant_access(handle->secure_ctx,
+