diff options
author | Trusted Logic <smc_support@trusted-logic.com> | 2011-09-30 22:28:04 -0700 |
---|---|---|
committer | Dan Murphy <dmurphy@ti.com> | 2011-10-12 08:06:55 -0500 |
commit | 42b184990676ff8076da845475ba18d7bad39d40 (patch) | |
tree | 1e43565c4d246ed892d8dfd24ee1e14b2435b21d /security | |
parent | 053aa69f0565189c40886d0cc6a72a3018c32642 (diff) | |
download | kernel_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.c | 68 |
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]); } } |