aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorTrusted Logic <smc_support@trusted-logic.com>2011-09-30 22:28:04 -0700
committerDan Murphy <dmurphy@ti.com>2011-10-12 08:06:55 -0500
commit42b184990676ff8076da845475ba18d7bad39d40 (patch)
tree1e43565c4d246ed892d8dfd24ee1e14b2435b21d /security
parent053aa69f0565189c40886d0cc6a72a3018c32642 (diff)
downloadkernel_samsung_espresso10-42b184990676ff8076da845475ba18d7bad39d40.zip
kernel_samsung_espresso10-42b184990676ff8076da845475ba18d7bad39d40.tar.gz
kernel_samsung_espresso10-42b184990676ff8076da845475ba18d7bad39d40.tar.bz2
OMAP4: SMC: Fix MMU during invoke
During invoke command, fix a memory mapping issue. l2 descriptor to page. Change-Id: Ib8146e5f1ffcc50489c2f1699285e719b5440ff0 Signed-off-by: Gonzalo Alexandre <alexandre.gonzalo@trusted-logic.com> Signed-off-by: Trusted Logic <smc_support@trusted-logic.com> Signed-off-by: Bryan Buckley <bryan.buckley@ti.com>
Diffstat (limited to 'security')
-rw-r--r--security/smc/tf_comm.c68
1 files changed, 33 insertions, 35 deletions
diff --git a/security/smc/tf_comm.c b/security/smc/tf_comm.c
index ed05262..79b4034 100644
--- a/security/smc/tf_comm.c
+++ b/security/smc/tf_comm.c
@@ -487,6 +487,7 @@ inline struct page *tf_l2_page_descriptor_to_page(u32 l2_page_descriptor)
return pte_page(l2_page_descriptor & L2_DESCRIPTOR_ADDR_MASK);
}
+#define TF_DEFAULT_COMMON_DESCRIPTORS 0x0000044C
/*
* Returns the L1 descriptor for the 1KB-aligned coarse page table. The address
@@ -494,41 +495,26 @@ inline struct page *tf_l2_page_descriptor_to_page(u32 l2_page_descriptor)
*/
static void tf_get_l2_page_descriptor(
u32 *l2_page_descriptor,
- u32 flags, struct mm_struct *mm)
+ u32 flags, struct mm_struct *mm, struct vm_area_struct *vmas)
{
- unsigned long page_vaddr;
u32 descriptor;
struct page *page;
- bool unmap_page = false;
dprintk(KERN_INFO
- "tf_get_l2_page_descriptor():"
- "*l2_page_descriptor=%x\n",
- *l2_page_descriptor);
+ "%s *l2_page_descriptor=%x vm_flags=%lx\n",
+ __func__, *l2_page_descriptor, vmas->vm_flags);
if (*l2_page_descriptor == L2_DESCRIPTOR_FAULT)
return;
- page = (struct page *) (*l2_page_descriptor);
-
- page_vaddr = (unsigned long) page_address(page);
- if (page_vaddr == 0) {
- dprintk(KERN_INFO "page_address returned 0\n");
- /* Should we use kmap_atomic(page, KM_USER0) instead ? */
- page_vaddr = (unsigned long) kmap(page);
- if (page_vaddr == 0) {
- *l2_page_descriptor = L2_DESCRIPTOR_FAULT;
- dprintk(KERN_ERR "kmap returned 0\n");
- return;
- }
- unmap_page = true;
- }
-
- descriptor = tf_get_l2_descriptor_common(page_vaddr, mm);
- if (descriptor == 0) {
+ if (vmas->vm_flags & VM_IO) {
*l2_page_descriptor = L2_DESCRIPTOR_FAULT;
+ dprintk(KERN_ERR "Memory mapped I/O or similar detected\n");
return;
}
+ page = (struct page *) (*l2_page_descriptor);
+
+ descriptor = TF_DEFAULT_COMMON_DESCRIPTORS;
descriptor |= L2_PAGE_DESCRIPTOR_BASE;
descriptor |= (page_to_phys(page) & L2_DESCRIPTOR_ADDR_MASK);
@@ -540,8 +526,6 @@ static void tf_get_l2_page_descriptor(
/* read and write access */
descriptor |= L2_PAGE_DESCRIPTOR_AP_APX_READ_WRITE;
- if (unmap_page)
- kunmap(page);
*l2_page_descriptor = descriptor;
}
@@ -809,7 +793,8 @@ int tf_fill_descriptor_table(
tf_get_l2_page_descriptor(
&coarse_pg_table->descriptors[j],
flags,
- current->mm);
+ current->mm,
+ vmas[j]);
/*
* Reject Strongly-Ordered or Device Memory
*/
@@ -837,20 +822,33 @@ int tf_fill_descriptor_table(
for (j = page_shift;
j < pages_to_get;
j++) {
- unsigned long addr =
- (unsigned long) (buffer_offset_vaddr +
- ((j - page_shift) *
- PAGE_SIZE));
- coarse_pg_table->descriptors[j] =
- (u32) vmalloc_to_page((void *)addr);
- get_page((struct page *) coarse_pg_table->
- descriptors[j]);
+ void *addr =
+ (void *)(buffer_offset_vaddr +
+ (j - page_shift) * PAGE_SIZE);
+ if (!is_vmalloc_addr(addr)) {
+ dprintk(KERN_ERR
+ "tf_fill_descriptor_table: "
+ "cannot handle address %p\n",
+ addr);
+ goto error;
+ }
+ struct page *page = vmalloc_to_page(addr);
+ if (page == NULL) {
+ dprintk(KERN_ERR
+ "tf_fill_descriptor_table: "
+ "cannot map %p to page\n",
+ addr);
+ goto error;
+ }
+ coarse_pg_table->descriptors[j] = (u32)page;
+ get_page(page);
/* change coarse page "page address" */
tf_get_l2_page_descriptor(
&coarse_pg_table->descriptors[j],
flags,
- &init_mm);
+ &init_mm,
+ vmas[j]);
}
}