mirror of
https://github.com/drasko/codezero.git
synced 2026-02-27 09:13:13 +01:00
shmat/shmget for utcbs are working for now.
faults on shared memory needs to be implemented.
This commit is contained in:
@@ -34,6 +34,10 @@ libmem_incpath = "../libmem"
|
|||||||
libl4_path = "../libl4"
|
libl4_path = "../libl4"
|
||||||
libl4_incpath1 = join(libl4_path, "include")
|
libl4_incpath1 = join(libl4_path, "include")
|
||||||
|
|
||||||
|
# libposix paths:
|
||||||
|
libposix_path = "../libposix"
|
||||||
|
libposix_incpath = join(libposix_path, "include")
|
||||||
|
|
||||||
# kernel paths:
|
# kernel paths:
|
||||||
kernel_incpath = join(project_root, "include")
|
kernel_incpath = join(project_root, "include")
|
||||||
|
|
||||||
@@ -52,13 +56,14 @@ env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
|||||||
# such as stdarg.h e.g. for variable args, as in printk().
|
# such as stdarg.h e.g. for variable args, as in printk().
|
||||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
|
||||||
LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path,\
|
LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path,\
|
||||||
"-L" + libmem_path],
|
"-L" + libmem_path, "-L" + libposix_path],
|
||||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||||
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
||||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||||
LIBS = [libc_name, 'gcc', 'libmc', 'libl4', 'gcc', libc_name],
|
LIBS = [libc_name, 'gcc', 'libmc', 'libl4', 'gcc', libc_name, "posix"],
|
||||||
CPPFLAGS = "-D__USERSPACE__",
|
CPPFLAGS = "-D__USERSPACE__",
|
||||||
CPPPATH = ['#include', libl4_incpath1, kernel_incpath, libc_incpath, libmem_incpath])
|
CPPPATH = ['#include', libl4_incpath1, kernel_incpath, libc_incpath, \
|
||||||
|
libposix_incpath, libmem_incpath])
|
||||||
|
|
||||||
src = [glob("src/*.c"), glob("*.c"), glob("src/arch/arm/*.c"), glob("src/memfs/*.c"), glob("src/lib/*.c")]
|
src = [glob("src/*.c"), glob("*.c"), glob("src/arch/arm/*.c"), glob("src/memfs/*.c"), glob("src/lib/*.c")]
|
||||||
objs = env.Object(src)
|
objs = env.Object(src)
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ import sys
|
|||||||
from os.path import join
|
from os.path import join
|
||||||
from string import split
|
from string import split
|
||||||
|
|
||||||
|
# libposix paths:
|
||||||
|
libposix_libpath = "../libposix"
|
||||||
|
libposix_incpath = "../libposix/include/posix"
|
||||||
|
|
||||||
project_root = "../.."
|
project_root = "../.."
|
||||||
kernel_headers = join(project_root, "include")
|
kernel_headers = join(project_root, "include")
|
||||||
config_h = join(project_root, "include/l4/config.h")
|
config_h = join(project_root, "include/l4/config.h")
|
||||||
@@ -17,7 +21,8 @@ env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
|||||||
LINKFLAGS = ['-nostdlib'],
|
LINKFLAGS = ['-nostdlib'],
|
||||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||||
ENV = {'PATH' : os.environ['PATH']},
|
ENV = {'PATH' : os.environ['PATH']},
|
||||||
LIBS = 'gcc')
|
LIBS = 'gcc',
|
||||||
|
CPPPATH = ['#include', libposix_incpath])
|
||||||
|
|
||||||
|
|
||||||
def extract_arch_subarch_plat(config_header):
|
def extract_arch_subarch_plat(config_header):
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include <l4/macros.h>
|
#include <l4/macros.h>
|
||||||
#include INC_GLUE(memlayout.h)
|
#include INC_GLUE(memlayout.h)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
|
||||||
__l4_ipc_t __l4_ipc = 0;
|
__l4_ipc_t __l4_ipc = 0;
|
||||||
__l4_map_t __l4_map = 0;
|
__l4_map_t __l4_map = 0;
|
||||||
@@ -71,6 +73,40 @@ static void *l4_utcb_page(void)
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialises a non-pager task's shared memory utcb page
|
||||||
|
* using posix semantics.
|
||||||
|
*/
|
||||||
|
int utcb_init(void)
|
||||||
|
{
|
||||||
|
int shmid;
|
||||||
|
void *shmaddr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise utcb only if we're not the pager.
|
||||||
|
* The pager does it differently for itself.
|
||||||
|
*/
|
||||||
|
if (self_tid() != PAGER_TID) {
|
||||||
|
|
||||||
|
/* Obtain our utcb page address */
|
||||||
|
utcb_page = l4_utcb_page();
|
||||||
|
printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__,
|
||||||
|
(unsigned long)utcb_page);
|
||||||
|
|
||||||
|
/* Use it as a key to create a shared memory region */
|
||||||
|
BUG_ON((shmid = shmget((key_t)utcb_page,
|
||||||
|
PAGE_SIZE, IPC_CREAT)) < 0);
|
||||||
|
printf("Shmget success. shmid: %d\n", shmid);
|
||||||
|
|
||||||
|
/* Attach to the region */
|
||||||
|
BUG_ON((shmaddr = shmat(shmid, utcb_page, 0)) < 0);
|
||||||
|
BUG_ON(shmaddr != utcb_page);
|
||||||
|
printf("Shmat success. Attached %d @ 0x%x\n", shmid, (unsigned long)shmaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void __l4_init(void)
|
void __l4_init(void)
|
||||||
{
|
{
|
||||||
kip = l4_kernel_interface(0, 0, 0);
|
kip = l4_kernel_interface(0, 0, 0);
|
||||||
@@ -89,11 +125,6 @@ void __l4_init(void)
|
|||||||
__l4_kmem_grant = (__l4_kmem_grant_t)kip->kmem_grant;
|
__l4_kmem_grant = (__l4_kmem_grant_t)kip->kmem_grant;
|
||||||
__l4_kmem_reclaim = (__l4_kmem_reclaim_t)kip->kmem_reclaim;
|
__l4_kmem_reclaim = (__l4_kmem_reclaim_t)kip->kmem_reclaim;
|
||||||
|
|
||||||
/* Initialise utcb only if we're not the pager */
|
utcb_init();
|
||||||
if (self_tid() != PAGER_TID) {
|
|
||||||
utcb_page = l4_utcb_page();
|
|
||||||
printf("%s: UTCB Read from mm0 as: 0x%x\n", __FUNCTION__,
|
|
||||||
(unsigned long)utcb_page);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
int errno;
|
int errno_variable;
|
||||||
|
|
||||||
int *__errno_location(void)
|
int *__errno_location(void)
|
||||||
{
|
{
|
||||||
return &errno;
|
return &errno_variable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ int l4_shmget(l4id_t key, int size, int shmflg)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/* Check if syscall itself was successful */
|
/* Check if syscall itself was successful */
|
||||||
if ((err = l4_get_retval()) < 0) {
|
if (IS_ERR(err = l4_get_retval())) {
|
||||||
printf("%s: SHMGET Error: %d.\n", __FUNCTION__, err);
|
printf("%s: SHMGET Error: %d.\n", __FUNCTION__, err);
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
}
|
}
|
||||||
/* Obtain shmid. */
|
|
||||||
return read_mr(L4SYS_ARG0);
|
/* Otherwise err has the positive id number */
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *l4_shmat(l4id_t shmid, const void *shmaddr, int shmflg)
|
void *l4_shmat(l4id_t shmid, const void *shmaddr, int shmflg)
|
||||||
@@ -50,13 +50,13 @@ void *l4_shmat(l4id_t shmid, const void *shmaddr, int shmflg)
|
|||||||
return PTR_ERR(err);
|
return PTR_ERR(err);
|
||||||
}
|
}
|
||||||
/* Check if syscall itself was successful */
|
/* Check if syscall itself was successful */
|
||||||
if ((err = l4_get_retval()) < 0) {
|
if (IS_ERR(err = l4_get_retval())) {
|
||||||
printf("%s: SHMAT Error: %d.\n", __FUNCTION__, err);
|
printf("%s: SHMAT Error: %d.\n", __FUNCTION__, err);
|
||||||
return PTR_ERR(err);
|
return PTR_ERR(err);
|
||||||
|
|
||||||
}
|
}
|
||||||
/* Obtain shm base. */
|
/* Obtain shm base. */
|
||||||
return (void *)read_mr(L4SYS_ARG0);
|
return (void *)err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l4_shmdt(const void *shmaddr)
|
int l4_shmdt(const void *shmaddr)
|
||||||
|
|||||||
@@ -60,11 +60,12 @@ env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
|
|||||||
# We don't use -nostdinc because sometimes we need standard headers,
|
# We don't use -nostdinc because sometimes we need standard headers,
|
||||||
# such as stdarg.h e.g. for variable args, as in printk().
|
# such as stdarg.h e.g. for variable args, as in printk().
|
||||||
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror' ],
|
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror' ],
|
||||||
LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path, "-L" + libmem_path],
|
LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path, \
|
||||||
|
"-L" + libposix_path, "-L" + libmem_path],
|
||||||
ASFLAGS = ['-D__ASSEMBLY__'],
|
ASFLAGS = ['-D__ASSEMBLY__'],
|
||||||
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
PROGSUFFIX = '.axf', # The suffix to use for final executable
|
||||||
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
|
||||||
LIBS = [libc_name, 'libl4', 'libmm', 'libmc', 'libkm', \
|
LIBS = [libc_name, 'libl4', 'libmm', 'libmc', 'libkm', 'libposix', \
|
||||||
'gcc', libc_name], # libgcc.a - This is required for division routines.
|
'gcc', libc_name], # libgcc.a - This is required for division routines.
|
||||||
CPPFLAGS = "-D__USERSPACE__",
|
CPPFLAGS = "-D__USERSPACE__",
|
||||||
CPPPATH = ['#include', libl4_incpath, libc_incpath, kernel_incpath, \
|
CPPPATH = ['#include', libl4_incpath, libc_incpath, kernel_incpath, \
|
||||||
|
|||||||
@@ -25,4 +25,6 @@ int do_munmap(void *vaddr, unsigned long size, struct tcb *task);
|
|||||||
int do_mmap(struct vm_file *mapfile, unsigned long f_offset, struct tcb *t,
|
int do_mmap(struct vm_file *mapfile, unsigned long f_offset, struct tcb *t,
|
||||||
unsigned long map_address, unsigned int flags, unsigned int pages);
|
unsigned long map_address, unsigned int flags, unsigned int pages);
|
||||||
|
|
||||||
|
int mmap_address_validate(unsigned long map_address, unsigned int vm_flags);
|
||||||
|
|
||||||
#endif /* __MM0_MMAP_H__ */
|
#endif /* __MM0_MMAP_H__ */
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ struct shm_descriptor {
|
|||||||
struct list_head list; /* SHM list, used by mm0 */
|
struct list_head list; /* SHM list, used by mm0 */
|
||||||
struct vm_file *owner;
|
struct vm_file *owner;
|
||||||
void *shm_addr; /* The virtual address for segment. */
|
void *shm_addr; /* The virtual address for segment. */
|
||||||
unsigned long size; /* Size of the area */
|
unsigned long size; /* Size of the area in pages */
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int refcnt;
|
int refcnt;
|
||||||
};
|
};
|
||||||
@@ -23,12 +23,6 @@ struct shm_descriptor {
|
|||||||
#define SHM_SHMMIN 1
|
#define SHM_SHMMIN 1
|
||||||
#define SHM_SHMMAX (PAGE_SIZE * 10)
|
#define SHM_SHMMAX (PAGE_SIZE * 10)
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: This flags the unique shm vaddr pool. If its not globally unique
|
|
||||||
* and shm areas are cached, on ARMv5 cache aliasing occurs.
|
|
||||||
*/
|
|
||||||
#define SHM_DISJOINT_VADDR_POOL
|
|
||||||
|
|
||||||
/* Initialises shared memory bookkeeping structures */
|
/* Initialises shared memory bookkeeping structures */
|
||||||
void shm_init();
|
void shm_init();
|
||||||
|
|
||||||
|
|||||||
@@ -458,17 +458,18 @@ int mmap_address_validate(unsigned long map_address, unsigned int vm_flags)
|
|||||||
} else
|
} else
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
* Shared mappings can *also* go in the utcb address space,
|
* Shared mappings can go in task, utcb, and shared
|
||||||
* taking in account that utcb's are shared mappings done
|
* memory address space,
|
||||||
* by individual tasks.
|
|
||||||
*/
|
*/
|
||||||
} else if (vm_flags & VMA_SHARED) {
|
} else if (vm_flags & VMA_SHARED) {
|
||||||
if ((map_address >= UTCB_AREA_START &&
|
if ((map_address >= UTCB_AREA_START &&
|
||||||
map_address < UTCB_AREA_END) ||
|
map_address < UTCB_AREA_END) ||
|
||||||
(map_address >= USER_AREA_START &&
|
(map_address >= USER_AREA_START &&
|
||||||
map_address < USER_AREA_END))
|
map_address < USER_AREA_END) ||
|
||||||
|
(map_address >= SHM_AREA_START &&
|
||||||
|
map_address < SHM_AREA_END))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
BUG();
|
BUG();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2007 Bahadir Balban
|
* Copyright (C) 2007, 2008 Bahadir Balban
|
||||||
*
|
*
|
||||||
* Posix shared memory implementation
|
* Posix shared memory implementation
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
#include <mmap.h>
|
#include <mmap.h>
|
||||||
|
#include <vm_area.h>
|
||||||
#include <l4/lib/string.h>
|
#include <l4/lib/string.h>
|
||||||
#include <kmalloc/kmalloc.h>
|
#include <kmalloc/kmalloc.h>
|
||||||
#include <l4lib/arch/syscalls.h>
|
#include <l4lib/arch/syscalls.h>
|
||||||
@@ -27,8 +28,6 @@
|
|||||||
/* The list of shared memory areas that are already set up and working */
|
/* The list of shared memory areas that are already set up and working */
|
||||||
static struct list_head shm_desc_list;
|
static struct list_head shm_desc_list;
|
||||||
|
|
||||||
/* The single global in-memory swap file for shared memory segments */
|
|
||||||
|
|
||||||
/* Unique shared memory ids */
|
/* Unique shared memory ids */
|
||||||
static struct id_pool *shm_ids;
|
static struct id_pool *shm_ids;
|
||||||
|
|
||||||
@@ -47,16 +46,16 @@ void shm_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* Attaches to given shm segment mapped at shm_addr if the shm descriptor
|
||||||
* Implement means to return back ipc results, i.e. sender always does ipc_sendrecv()
|
* does not already have a base address assigned. If neither shm_addr nor
|
||||||
* and it blocks on its own receive queue. Server then responds back without blocking.
|
* the descriptor has an address, allocates one from the shm address pool.
|
||||||
*
|
* FIXME: This pool is currently outside the range of mmap'able addresses.
|
||||||
* Later on: mmap can be done using vm_areas and phsyical pages can be accessed by vm_areas.
|
|
||||||
*/
|
*/
|
||||||
static int do_shmat(struct shm_descriptor *shm, void *shm_addr, int shmflg,
|
static void *do_shmat(struct shm_descriptor *shm, void *shm_addr, int shmflg,
|
||||||
l4id_t tid)
|
l4id_t tid)
|
||||||
{
|
{
|
||||||
struct tcb *task = find_task(tid);
|
struct tcb *task = find_task(tid);
|
||||||
|
unsigned int vmflags;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!task) {
|
if (!task) {
|
||||||
@@ -65,59 +64,60 @@ static int do_shmat(struct shm_descriptor *shm, void *shm_addr, int shmflg,
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (shm_addr)
|
||||||
* Currently shared memory base addresses are the same among all
|
shm_addr = (void *)page_align(shm_addr);
|
||||||
* processes for every unique shm segment. They line up easier on
|
|
||||||
* the shm swap file this way. Also currently shm_addr argument is
|
|
||||||
* ignored, and mm0 allocates shm segment addresses.
|
|
||||||
*/
|
|
||||||
if (shm->shm_addr)
|
|
||||||
shm_addr = shm->shm_addr;
|
|
||||||
else
|
|
||||||
shm_addr = address_new(&shm_vaddr_pool, __pfn(shm->size));
|
|
||||||
|
|
||||||
BUG_ON(!is_page_aligned(shm_addr));
|
/* Determine mmap flags for segment */
|
||||||
|
if (shmflg & SHM_RDONLY)
|
||||||
|
vmflags = VM_READ | VMA_SHARED | VMA_ANONYMOUS;
|
||||||
|
else
|
||||||
|
vmflags = VM_READ | VM_WRITE |
|
||||||
|
VMA_SHARED | VMA_ANONYMOUS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The first user of the segment who supplies a valid
|
||||||
|
* address sets the base address of the segment. Currently
|
||||||
|
* all tasks use the same address for each unique segment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* First user? */
|
||||||
|
if (!shm->refcnt)
|
||||||
|
if (mmap_address_validate((unsigned long)shm_addr, vmflags))
|
||||||
|
shm->shm_addr = shm_addr;
|
||||||
|
else
|
||||||
|
shm->shm_addr = address_new(&shm_vaddr_pool,
|
||||||
|
__pfn(shm->size));
|
||||||
|
else /* Address must be already assigned */
|
||||||
|
BUG_ON(!shm->shm_addr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mmap the area to the process as shared. Page fault handler would
|
* mmap the area to the process as shared. Page fault handler would
|
||||||
* handle allocating and paging-in the shared pages.
|
* handle allocating and paging-in the shared pages.
|
||||||
*
|
|
||||||
* For anon && shared pages do_mmap() handles allocation of the
|
|
||||||
* shm swap file and the file offset for the segment. The segment can
|
|
||||||
* be identified because segment virtual address is globally unique
|
|
||||||
* per segment and its the same for all the system tasks.
|
|
||||||
*/
|
*/
|
||||||
if ((err = do_mmap(0, 0, task, (unsigned long)shm_addr,
|
if ((err = do_mmap(0, 0, task, (unsigned long)shm->shm_addr,
|
||||||
VM_READ | VM_WRITE | VMA_ANONYMOUS | VMA_SHARED,
|
vmflags, shm->size)) < 0) {
|
||||||
shm->size)) < 0) {
|
|
||||||
printf("do_mmap: Mapping shm area failed with %d.\n", err);
|
printf("do_mmap: Mapping shm area failed with %d.\n", err);
|
||||||
BUG();
|
BUG();
|
||||||
} else
|
}
|
||||||
printf("%s: %s: Success.\n", __TASKNAME__, __FUNCTION__);
|
|
||||||
|
|
||||||
/* Now update the shared memory descriptor */
|
/* Now update the shared memory descriptor */
|
||||||
shm->refcnt++;
|
shm->refcnt++;
|
||||||
|
|
||||||
return 0;
|
return shm->shm_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *sys_shmat(l4id_t requester, l4id_t shmid, void *shmaddr, int shmflg)
|
int sys_shmat(l4id_t requester, l4id_t shmid, void *shmaddr, int shmflg)
|
||||||
{
|
{
|
||||||
struct shm_descriptor *shm_desc, *n;
|
struct shm_descriptor *shm_desc, *n;
|
||||||
int err;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(shm_desc, n, &shm_desc_list, list) {
|
list_for_each_entry_safe(shm_desc, n, &shm_desc_list, list) {
|
||||||
if (shm_desc->shmid == shmid) {
|
if (shm_desc->shmid == shmid) {
|
||||||
if ((err = do_shmat(shm_desc, shmaddr,
|
shmaddr = do_shmat(shm_desc, shmaddr,
|
||||||
shmflg, requester) < 0)) {
|
shmflg, requester);
|
||||||
l4_ipc_return(err);
|
l4_ipc_return((int)shmaddr);
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l4_ipc_return(0);
|
l4_ipc_return(-EINVAL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,42 +158,48 @@ int sys_shmdt(l4id_t requester, const void *shmaddr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct shm_descriptor *shm_new(key_t key)
|
static struct shm_descriptor *shm_new(key_t key, unsigned long npages)
|
||||||
{
|
{
|
||||||
/* It doesn't exist, so create a new one */
|
/* It doesn't exist, so create a new one */
|
||||||
struct shm_descriptor *shm_desc;
|
struct shm_descriptor *shm_desc;
|
||||||
|
|
||||||
if ((shm_desc = kzalloc(sizeof(struct shm_descriptor))) < 0)
|
if ((shm_desc = kzalloc(sizeof(struct shm_descriptor))) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
if ((shm_desc->shmid = id_new(shm_ids)) < 0)
|
if ((shm_desc->shmid = id_new(shm_ids)) < 0) {
|
||||||
|
kfree(shm_desc);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
BUG_ON(!npages);
|
||||||
shm_desc->key = (int)key;
|
shm_desc->key = (int)key;
|
||||||
|
shm_desc->size = npages;
|
||||||
INIT_LIST_HEAD(&shm_desc->list);
|
INIT_LIST_HEAD(&shm_desc->list);
|
||||||
list_add(&shm_desc->list, &shm_desc_list);
|
list_add(&shm_desc->list, &shm_desc_list);
|
||||||
|
|
||||||
return shm_desc;
|
return shm_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sys_shmget(key_t key, int size, int shmflg)
|
int sys_shmget(key_t key, int size, int shmflg)
|
||||||
{
|
{
|
||||||
struct shm_descriptor *shm_desc;
|
struct shm_descriptor *shm_desc;
|
||||||
|
unsigned long npages;
|
||||||
|
|
||||||
/* First check argument validity */
|
/* First check argument validity */
|
||||||
if (size > SHM_SHMMAX || size < SHM_SHMMIN) {
|
if (size > SHM_SHMMAX || size < SHM_SHMMIN) {
|
||||||
l4_ipc_return(-EINVAL);
|
l4_ipc_return(-EINVAL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else
|
||||||
|
npages = __pfn(page_align_up(size));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IPC_PRIVATE means create a no-key shm area, i.e. private to this
|
* IPC_PRIVATE means create a no-key shm area, i.e. private to this
|
||||||
* process so that it would only share it with its descendants.
|
* process so that it would only share it with its forked children.
|
||||||
*/
|
*/
|
||||||
if (key == IPC_PRIVATE) {
|
if (key == IPC_PRIVATE) {
|
||||||
key = -1; /* Our meaning of no key */
|
key = -1; /* Our meaning of no key */
|
||||||
if (!shm_new(key))
|
if (!(shm_desc = shm_new(key, npages)))
|
||||||
l4_ipc_return(-ENOSPC);
|
l4_ipc_return(-ENOSPC);
|
||||||
else
|
else
|
||||||
l4_ipc_return(0);
|
l4_ipc_return(shm_desc->shmid);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,9 +220,10 @@ int sys_shmget(key_t key, int size, int shmflg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Key doesn't exist and create set, so we create */
|
|
||||||
|
/* Key doesn't exist and create is set, so we create */
|
||||||
if (shmflg & IPC_CREAT)
|
if (shmflg & IPC_CREAT)
|
||||||
if (!(shm_desc = shm_new(key)))
|
if (!(shm_desc = shm_new(key, npages)))
|
||||||
l4_ipc_return(-ENOSPC);
|
l4_ipc_return(-ENOSPC);
|
||||||
else
|
else
|
||||||
l4_ipc_return(shm_desc->shmid);
|
l4_ipc_return(shm_desc->shmid);
|
||||||
|
|||||||
Reference in New Issue
Block a user