mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 05:08:41 +08:00
mm/kmap: Provide the user tcb as parameter to map_user()
This allows mapping pages from others than the running task. Obiously this can only be done with proper preparations (the task in question cannot exit before the mapping is released).
This commit is contained in:
parent
c3d03f02fb
commit
95d1e52535
2 changed files with 34 additions and 17 deletions
|
@ -23,6 +23,16 @@
|
|||
#ifndef __INCLUDE_NUTTX_MM_KMAP_H
|
||||
#define __INCLUDE_NUTTX_MM_KMAP_H
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
struct tcb_s; /* Forward reference to TCB */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kmm_map_initialize
|
||||
*
|
||||
|
@ -81,6 +91,8 @@ void kmm_unmap(FAR void *kaddr);
|
|||
* a continuous virtual memory area.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the task whose address environment the mapping
|
||||
* belongs to.
|
||||
* uaddr - The user virtual address where mapping begins.
|
||||
* size - Size of the region.
|
||||
*
|
||||
|
@ -89,7 +101,7 @@ void kmm_unmap(FAR void *kaddr);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *kmm_map_user(FAR void *uaddr, size_t size);
|
||||
FAR void *kmm_map_user(FAR struct tcb_s *tcb, FAR void *uaddr, size_t size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: kmm_map_user_page
|
||||
|
@ -99,6 +111,8 @@ FAR void *kmm_map_user(FAR void *uaddr, size_t size);
|
|||
* returns the kernel addressable page pool virtual address.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the task whose address environment the mapping
|
||||
* belongs to.
|
||||
* uaddr - The virtual address of the user page.
|
||||
*
|
||||
* Returned Value:
|
||||
|
@ -106,6 +120,6 @@ FAR void *kmm_map_user(FAR void *uaddr, size_t size);
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *kmm_map_user_page(FAR void *uaddr);
|
||||
FAR void *kmm_map_user_page(FAR struct tcb_s *tcb, FAR void *uaddr);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_MM_KMAP_H */
|
||||
|
|
|
@ -76,11 +76,11 @@ static struct mm_map_s g_kmm_map;
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int get_user_pages(FAR void **pages, size_t npages, uintptr_t vaddr)
|
||||
static int get_user_pages(FAR struct tcb_s *tcb, FAR void **pages,
|
||||
size_t npages, uintptr_t vaddr)
|
||||
{
|
||||
FAR struct tcb_s *tcb = this_task();
|
||||
uintptr_t page;
|
||||
int i;
|
||||
uintptr_t page;
|
||||
int i;
|
||||
|
||||
/* Find the pages associated with the user virtual address space */
|
||||
|
||||
|
@ -170,19 +170,18 @@ errout_with_vaddr:
|
|||
* Map a single user page into kernel memory.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pages - Pointer to buffer that contains the physical page addresses.
|
||||
* npages - Amount of pages.
|
||||
* prot - Access right flags.
|
||||
* tcb - The tcb of the task whose address environment the mapping
|
||||
* belongs to.
|
||||
* vaddr - The virtual address of the page to map.
|
||||
*
|
||||
* Returned Value:
|
||||
* Pointer to the mapped virtual memory on success; NULL on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR void *map_single_user_page(uintptr_t vaddr)
|
||||
static FAR void *map_single_user_page(FAR struct tcb_s *tcb, uintptr_t vaddr)
|
||||
{
|
||||
FAR struct tcb_s *tcb = this_task();
|
||||
uintptr_t page;
|
||||
uintptr_t page;
|
||||
|
||||
/* Find the page associated with this virtual address */
|
||||
|
||||
|
@ -405,6 +404,8 @@ void kmm_unmap(FAR void *kaddr)
|
|||
* a continuous virtual memory area.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the task whose address environment the mapping
|
||||
* belongs to.
|
||||
* uaddr - The user virtual address where mapping begins.
|
||||
* size - Size of the region.
|
||||
*
|
||||
|
@ -413,7 +414,7 @@ void kmm_unmap(FAR void *kaddr)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *kmm_map_user(FAR void *uaddr, size_t size)
|
||||
FAR void *kmm_map_user(FAR struct tcb_s *tcb, FAR void *uaddr, size_t size)
|
||||
{
|
||||
FAR void **pages;
|
||||
uintptr_t vaddr;
|
||||
|
@ -446,7 +447,7 @@ FAR void *kmm_map_user(FAR void *uaddr, size_t size)
|
|||
{
|
||||
/* Yes, can simply return the kernel addressable virtual address */
|
||||
|
||||
vaddr = (uintptr_t)map_single_user_page(vaddr);
|
||||
vaddr = (uintptr_t)map_single_user_page(tcb, vaddr);
|
||||
return (FAR void *)(vaddr + offset);
|
||||
}
|
||||
|
||||
|
@ -460,7 +461,7 @@ FAR void *kmm_map_user(FAR void *uaddr, size_t size)
|
|||
|
||||
/* Fetch the physical pages for the user virtual address range */
|
||||
|
||||
ret = get_user_pages(pages, npages, vaddr);
|
||||
ret = get_user_pages(tcb, pages, npages, vaddr);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto errout_with_pages;
|
||||
|
@ -492,6 +493,8 @@ errout_with_pages:
|
|||
* returns the kernel addressable page pool virtual address.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb - The tcb of the task whose address environment the mapping
|
||||
* belongs to.
|
||||
* uaddr - The virtual address of the user page.
|
||||
*
|
||||
* Returned Value:
|
||||
|
@ -499,7 +502,7 @@ errout_with_pages:
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR void *kmm_map_user_page(FAR void *uaddr)
|
||||
FAR void *kmm_map_user_page(FAR struct tcb_s *tcb, FAR void *uaddr)
|
||||
{
|
||||
uintptr_t vaddr;
|
||||
uintptr_t offset;
|
||||
|
@ -522,7 +525,7 @@ FAR void *kmm_map_user_page(FAR void *uaddr)
|
|||
offset = vaddr & MM_PGMASK;
|
||||
vaddr = MM_PGALIGNDOWN(vaddr);
|
||||
|
||||
vaddr = (uintptr_t)map_single_user_page(vaddr);
|
||||
vaddr = (uintptr_t)map_single_user_page(tcb, vaddr);
|
||||
if (!vaddr)
|
||||
{
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in a new issue