Subversion Repositories HelenOS

Compare Revisions

Regard whitespace Rev 1296 → Rev 1297

/kernel/trunk/generic/include/ddi/ddi.h
35,6 → 35,7
 
extern __native sys_physmem_map(ddi_memarg_t *uspace_mem_arg);
extern __native sys_iospace_enable(ddi_ioarg_t *uspace_io_arg);
extern __native sys_preempt_control(int enable);
 
/*
* Interface to be implemented by all architectures.
/kernel/trunk/generic/include/security/cap.h
41,6 → 41,7
#ifndef __CAP_H__
#define __CAP_H__
 
#include <syscall/sysarg64.h>
#include <arch/types.h>
#include <typedefs.h>
 
63,13 → 64,21
#define CAP_IO_MANAGER (1<<2)
 
/**
* CAP_PREEMPT_CONTROL allows its holder to disable interrupts
* CAP_PREEMPT_CONTROL allows its holder to disable/enable preemption.
*/
#define CAP_PREEMPT_CONTROL (1<<3)
 
/**
* CAP_IRQ_REG entitles its holder to register IRQ handlers.
*/
#define CAP_IRQ_REG (1<<4)
 
typedef __u32 cap_t;
 
extern void cap_set(task_t *t, cap_t caps);
extern cap_t cap_get(task_t *t);
 
extern __native sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps);
extern __native sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps);
 
#endif
/kernel/trunk/generic/include/syscall/syscall.h
32,7 → 32,6
typedef enum {
SYS_IO = 0,
SYS_TLS_SET = 1, /* Hardcoded in AMD64,IA32 uspace - psthread.S */
SYS_PREEMPT_CONTROL,
SYS_THREAD_CREATE,
SYS_THREAD_EXIT,
SYS_TASK_GET_ID,
53,8 → 52,11
SYS_IPC_HANGUP,
SYS_IPC_REGISTER_IRQ,
SYS_IPC_UNREGISTER_IRQ,
SYS_CAP_GRANT,
SYS_CAP_REVOKE,
SYS_MAP_PHYSMEM,
SYS_IOSPACE_ENABLE,
SYS_PREEMPT_CONTROL,
SYSCALL_END
} syscall_t;
 
/kernel/trunk/generic/include/syscall/sysarg64.h
0,0 → 1,41
/*
* Copyright (C) 2006 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/**
* @file sysarg64.h
* @brief Wrapper for explicit 64-bit arguments passed to syscalls.
*/
 
#ifndef __SYSARG64_H__
#define __SYSARG64_H__
 
typedef struct {
unsigned long long value;
} sysarg64_t;
 
#endif
/kernel/trunk/generic/src/main/kinit.c
159,7 → 159,7
/*
* Set capabilities to init userspace tasks.
*/
cap_set(utask, CAP_CAP | CAP_MEM_MANAGER | CAP_IO_MANAGER);
cap_set(utask, CAP_CAP | CAP_MEM_MANAGER | CAP_IO_MANAGER | CAP_PREEMPT_CONTROL);
if (!ipc_phone_0)
ipc_phone_0 = &utask->answerbox;
/kernel/trunk/generic/src/ddi/ddi.c
211,3 → 211,22
return (__native) ddi_iospace_enable((task_id_t) arg.task_id, (__address) arg.ioaddr, (size_t) arg.size);
}
 
/** Disable or enable preemption.
*
* @param enable If non-zero, the preemption counter will be decremented, leading to potential
* enabling of preemption. Otherwise the preemption counter will be incremented,
* preventing preemption from occurring.
*
* @return Zero on success or EPERM if callers capabilities are not sufficient.
*/
__native sys_preempt_control(int enable)
{
if (! cap_get(TASK) & CAP_PREEMPT_CONTROL)
return EPERM;
if (enable)
preemption_enable();
else
preemption_disable();
return 0;
}
/kernel/trunk/generic/src/security/cap.c
36,8 → 36,11
#include <security/cap.h>
#include <proc/task.h>
#include <synch/spinlock.h>
#include <syscall/sysarg64.h>
#include <syscall/copy.h>
#include <arch.h>
#include <typedefs.h>
#include <errno.h>
 
/** Set capabilities.
*
77,3 → 80,89
return caps;
}
 
/** Grant capabilities to a task.
*
* The calling task must have the CAP_CAP capability.
*
* @param uspace_taskid_arg Userspace structure holding destination task ID.
* @param caps Capabilities to grant.
*
* @return Zero on success or an error code from @ref errno.h.
*/
__native sys_cap_grant(sysarg64_t *uspace_taskid_arg, cap_t caps)
{
sysarg64_t taskid_arg;
task_t *t;
ipl_t ipl;
int rc;
if (!(cap_get(TASK) & CAP_CAP))
return (__native) EPERM;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (__native) rc;
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id((task_id_t) taskid_arg.value);
if (!t) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return (__native) ENOENT;
}
spinlock_unlock(&tasks_lock);
cap_set(t, cap_get(t) | caps);
interrupts_restore(ipl);
return 0;
}
 
/** Revoke capabilities from a task.
*
* The calling task must have the CAP_CAP capability or the caller must
* attempt to revoke capabilities from itself.
*
* @param uspace_taskid_arg Userspace structure holding destination task ID.
* @param caps Capabilities to revoke.
*
* @return Zero on success or an error code from @ref errno.h.
*/
__native sys_cap_revoke(sysarg64_t *uspace_taskid_arg, cap_t caps)
{
sysarg64_t taskid_arg;
task_t *t;
ipl_t ipl;
int rc;
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t));
if (rc != 0)
return (__native) rc;
 
ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id((task_id_t) taskid_arg.value);
if (!t) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return (__native) ENOENT;
}
spinlock_unlock(&tasks_lock);
 
/*
* Revoking capabilities is different from granting them in that
* a task can revoke capabilities from itself even if it
* doesn't have CAP_CAP.
*/
if (!(cap_get(TASK) & CAP_CAP) || !(t == TASK)) {
interrupts_restore(ipl);
return (__native) EPERM;
}
 
cap_set(t, cap_get(t) & ~caps);
interrupts_restore(ipl);
return 0;
}
/kernel/trunk/generic/src/mm/tlb.c
29,6 → 29,10
/**
* @file tlb.c
* @brief Generic TLB shootdown algorithm.
*
* The algorithm implemented here is based on the CMU TLB shootdown
* algorithm and is further simplified (e.g. all CPUs receive all TLB
* shootdown messages).
*/
 
#include <mm/tlb.h>
/kernel/trunk/generic/src/syscall/syscall.c
43,6 → 43,7
#include <ipc/sysipc.h>
#include <synch/futex.h>
#include <ddi/ddi.h>
#include <security/cap.h>
#include <syscall/copy.h>
 
static __native sys_io(int fd, const void * buf, size_t count) {
57,17 → 58,6
return count;
}
 
static __native sys_preempt_control(int enable)
{
if (! cap_get(TASK) & CAP_PREEMPT_CONTROL)
return EPERM;
if (enable)
preemption_enable();
else
preemption_disable();
return 0;
}
 
/** Dispatch system call */
__native syscall_handler(__native a1, __native a2, __native a3,
__native a4, __native id)
81,7 → 71,6
syshandler_t syscall_table[SYSCALL_END] = {
sys_io,
sys_tls_set,
sys_preempt_control,
 
/* Thread and task related syscalls. */
sys_thread_create,
111,7 → 100,12
sys_ipc_register_irq,
sys_ipc_unregister_irq,
 
/* Capabilities related syscalls. */
sys_cap_grant,
sys_cap_revoke,
 
/* DDI related syscalls. */
sys_physmem_map,
sys_iospace_enable
sys_iospace_enable,
sys_preempt_control
};
/kernel/trunk/generic/src/ipc/sysipc.c
39,6 → 39,7
#include <arch/interrupt.h>
#include <print.h>
#include <syscall/copy.h>
#include <security/cap.h>
 
#define GET_CHECK_PHONE(phone,phoneid,err) { \
if (phoneid > IPC_MAX_PHONES) { err; } \
490,8 → 491,11
/** Connect irq handler to task */
__native sys_ipc_register_irq(__native irq, irq_code_t *ucode)
{
if (!(cap_get(TASK) & CAP_IRQ_REG))
return EPERM;
 
if (irq >= IRQ_COUNT)
return -ELIMIT;
return (__native) ELIMIT;
 
irq_ipc_bind_arch(irq);
 
501,8 → 505,11
/* Disconnect irq handler from task */
__native sys_ipc_unregister_irq(__native irq)
{
if (!(cap_get(TASK) & CAP_IRQ_REG))
return EPERM;
 
if (irq >= IRQ_COUNT)
return -ELIMIT;
return (__native) ELIMIT;
 
ipc_irq_unregister(&TASK->answerbox, irq);