diff -Nur -x.svn linux-2.6.18-orig/arch/i386/Kconfig linux-2.6.18/arch/i386/Kconfig --- linux-2.6.18-orig/arch/i386/Kconfig 2008-01-23 15:22:10.000000000 +0900 +++ linux-2.6.18/arch/i386/Kconfig 2007-11-02 16:52:32.000000000 +0900 @@ -803,6 +803,8 @@ If unsure, say Y. +source "drivers/cabi/Kconfig" + endmenu config ARCH_ENABLE_MEMORY_HOTPLUG diff -Nur -x.svn linux-2.6.18-orig/arch/i386/kernel/syscall_table.S linux-2.6.18/arch/i386/kernel/syscall_table.S --- linux-2.6.18-orig/arch/i386/kernel/syscall_table.S 2008-01-23 15:22:03.000000000 +0900 +++ linux-2.6.18/arch/i386/kernel/syscall_table.S 2007-12-11 20:41:22.000000000 +0900 @@ -317,3 +317,7 @@ .long sys_tee /* 315 */ .long sys_vmsplice .long sys_move_pages +#ifdef CONFIG_CABI + .long sys_cabi /* 318 */ +#endif /* CONFIG_CABI */ + diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/account.c linux-2.6.18/drivers/cabi/common/account.c --- linux-2.6.18-orig/drivers/cabi/common/account.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/account.c 2008-01-23 11:40:35.000000000 +0900 @@ -0,0 +1,534 @@ +/* + * linux/drivers/cabi/cabi_account.c + * + * CABI -- CPU Accounting and Blocking Interfaces. + * + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * + * This software was developed by the Waseda University and Montavista Software, + * Inc. Funding for this project was provided by IPA (Information-technology + * Promotion Agency, Japan). This software may be used and distributed + * according to the terms of the GNU Public License, incorporated herein by + * reference. + * + * 2007 Modified by Midori Sugaya to change interfaces. + * 2006-9-12. Modified by Midori Sugaya to fix bugs in tick calculation + * and make adjustment for 2.6. + * 2006-2. Porting to kernel-2.6 Takeharu KATO (ARM, SH) + * 2005-2. New release based on LinuxRK. by Midori SUGAYA, Hirotaka + * ISHIKAWA. + * + * Futher details about this project can be obtained at + * http://dcl.info.waseda.ac.jp/osrg/ + * + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * This file is derived from software distributed under the following terms: + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Static variables for accounting + */ +struct list_head cabi_account_head; +static int last_cabi_id; + +/* + * Name : enable_account + * + * If CONFIG_CABI is on, this function is called. + * It is the main function to enable cpu resouce account functions. + */ + +void +enable_account (void) +{ + +#ifdef CONFIG_PROC_FS + cabi_proc_init(); +#endif + spin_lock_init(&cabi_lock); + INIT_LIST_HEAD(&cabi_account_head); + +} + +/* + * Name : disable_account + * + * It is the main function to disable account resouce account functions. + */ + +void +disable_account (void) +{ + +#ifdef CONFIG_PROC_FS + cabi_proc_destroy(); +#endif + +} + +/* + * Name: search_cabi (cabi_id) + * + * Search the accounting object (cabi) which is specified by the + * argument with cabi_id. Return the initial address of the + * accounting object. + */ + +struct cabi_account * +search_cabi(unsigned long cabi_id) +{ + struct list_head *cabi_list; + cabi_account_t cabi = NULL_ACCOUNT; + + cabi_list = &cabi_account_head; + + while (!list_empty(cabi_list)) { + cabi = list_entry(cabi_list, struct cabi_account, cabi_link); + + if (cabi->cabi_id == cabi_id) + break; + + cabi_list = cabi_list->next; + if (cabi_list == &cabi_account_head) { + cabi = NULL_ACCOUNT; + break; + } + } + return cabi; +} + +/* + * Name: get_cabi_id (void) + * + * Return unique accounting object id for the caller. In this + * function, duplicate ids and reserved ids are carafully + * asided from the id pools. CABI_ID_MAX keeps the maximum + * limit of the id which is defined in cabi.h header. + */ + +int +get_cabi_id(void) +{ + struct list_head *cabi_list; + cabi_account_t cabi = NULL_ACCOUNT; + int begin_cabi_id, cabi_id_error; + cabi_id_error = -1; + + begin_cabi_id = -1; + last_cabi_id++; + + cabi_list = &cabi_account_head; + cabi_list = cabi_list->next; + if (cabi_list == &cabi_account_head) { /* First AO create. */ + last_cabi_id = FIRST_CABI_ID; + return last_cabi_id; + } + while (!list_empty(cabi_list)) { /* Get cabi_id */ + cabi = list_entry(cabi_list, struct cabi_account, cabi_link); + /* cabi_id is full */ + if (last_cabi_id == begin_cabi_id) + return cabi_id_error; + /* selected cabi_id is for overload */ + if (OVERLOAD_CABI_ID == last_cabi_id) { + if (begin_cabi_id == -1) + begin_cabi_id = last_cabi_id; + ++last_cabi_id; + cabi_list = &cabi_account_head; + cabi_list = cabi_list->next; + continue; + } + /* selected cabi_id is already used */ + if (cabi->cabi_id == last_cabi_id) { + if (begin_cabi_id == -1) + begin_cabi_id = last_cabi_id; + ++last_cabi_id; + cabi_list = &cabi_account_head; + cabi_list = cabi_list->next; + continue; + } + /* selected cabi_id is MAX value */ + + if (last_cabi_id >= CABI_ID_MAX) { + if (begin_cabi_id == -1) + begin_cabi_id = last_cabi_id; + last_cabi_id = FIRST_CABI_ID; + cabi_list = &cabi_account_head; + cabi_list = cabi_list->next; + continue; + } + /* next cabi list */ + cabi_list = cabi_list->next; + + /* all lists were searched. */ + if (cabi_list == &cabi_account_head) + break; + } + return last_cabi_id; +} + + +/* + * Process list operations + */ +struct task_struct * +__cabi_find_process_by_pid(pid_t pid) +{ + struct task_struct *tsk = current; + + if (pid) + tsk = find_task_by_pid(pid); + return tsk; +} + +struct task_struct * +__cabi_find_idle_process(void) +{ + return idle_task(smp_processor_id()); +} + + +/* + * Name: cabi_account_create + * + * Create a accounting object. This function just create and setup + * id for accounting object. This is just a common operation to + * set up the accounting. + sys_cabi_account_create which is a interface of the system call. + */ + +cabi_account_t +cabi_account_create(struct cabi_uaccount *ucabi) +{ + + cabi_account_t cabi; + long get_id = 0; + int ret = CABI_ERROR; + + ENTER; + + /* create an accounting object */ + if((cabi = kzalloc(sizeof (struct cabi_account), SLAB_KERNEL)) == NULL) + return NULL; + + INIT_LIST_HEAD(&cabi->proc_list); + INIT_LIST_HEAD(&cabi->cabi_link); + list_add(&cabi->cabi_link, &cabi_account_head); + + /* + * Set up the unique id for cabi. + */ + if((get_id = get_cabi_id()) < 0) + goto error_del_list; + else + cabi->cabi_id = (unsigned int)get_id; + + cabi->type = ucabi->type; + + CABI_DBG; + /* Per resources */ + switch (ucabi->type) { + case CABI_CPU: + ret = setup_cpu_account (cabi, ucabi); + break; + case CABI_MEM: + ret = setup_mem_account (cabi, ucabi); + break; + default: + break; + } + if (ret) + goto error_del_list; + + CABI_DBG; + if (cabi->create) + ret = cabi->create (cabi, ucabi); + if (ret) + goto error_free_all; + +#ifdef CONFIG_PROC_FS + cabi_proc_account_create(cabi); +#endif + + return cabi; /* success */ + + +error_free_all: + CABI_DBG; + switch (ucabi->type) { + case CABI_CPU: + exit_cpu_account (cabi); + break; + case CABI_MEM: + exit_mem_account (cabi); + break; + default: + break; + } +error_del_list: + list_del(&cabi->cabi_link); + kfree(cabi); + return NULL; + +} + +/* + * Name: cabi_account_destroy + * + * Delete a accounting object from kernel memory. The function called from + * sys_cabi_account_destroy which is a interface of the system call. + */ + +int +cabi_account_destroy(unsigned long cabi_id) +{ + cabi_account_t cabi = NULL_ACCOUNT; + int ret = CABI_ERROR; + + ENTER; + + /* find the cabi address */ + if (!(cabi = search_cabi(cabi_id))) + return CABI_ENOEXIST; + + /* if account has attached pgrocesses */ + if (!list_empty(&cabi->proc_list)) + /* process is still attached. */ + return CABI_EATTACHED; + + CABI_DBG; + /* Per resources */ + switch (cabi->type) { + case CABI_CPU: + ret = exit_cpu_account (cabi); + break; + case CABI_MEM: + ret = exit_mem_account (cabi); + break; + default: + return CABI_EINVAL; + } + + /* delete cabi_link */ + list_del(&cabi->cabi_link); + INIT_LIST_HEAD(&cabi->cabi_link); + CABI_DBG; + +#ifdef CONFIG_PROC_FS + /* remove entry under /proc/cabi/ */ + cabi_proc_account_destroy(cabi); +#endif + + /* finally free a generic account object. */ + kfree(cabi); + + return CABI_SUCCESS; /* success */ +} + + +/* + * Name: cabi_account_set + * + * Set a parameter for accounting object. The function called from + * sys_cabi_account_set which is a interface of the system call. + */ + +int +cabi_account_set(unsigned long cabi_id, struct cabi_uaccount *ucabi) +{ + cabi_account_t cabi; + int ret = CABI_ERROR; + + ENTER; + + /* find the cabi address */ + if (!(cabi = search_cabi(cabi_id))) { + /* cabi dose not exist. */ + return CABI_ENOEXIST; + } + + /* Per resources */ + if (cabi->set) + ret = cabi->set (cabi, ucabi); + + if (ret) + return CABI_ERROR; + + return CABI_SUCCESS; /* success */ + +} + +/* + * Name: cabi_account_get + * + * Get a parameter for accounting object. The function called from + * sys_cabi_account_get which is a interface of the system call. + */ + +int +cabi_account_get(unsigned long cabi_id, struct cabi_uaccount *ucabi) +{ + cabi_account_t cabi; + int ret = CABI_ERROR; + + ENTER; + + /* find the cabi address */ + if (!(cabi = search_cabi(cabi_id))) { + /* cabi dose not exist. */ + return CABI_ENOEXIST; + } + + /* get common parameter */ + ucabi->cabi_id = cabi_id; + ucabi->type = cabi->type; + + /* Per resources */ + if (cabi->get) + ret = cabi->get (cabi, ucabi); + + if (ret) + return CABI_ERROR; + + return CABI_SUCCESS; /* success */ +} + +/* + * Name: cabi_account_attach + * + * Attach a process to specified accounting object. + */ + +int +cabi_account_attach(unsigned long cabi_id, struct task_struct *tsk) +{ + struct rs_proc_list *rs_proc; + cabi_account_t cabi; + unsigned long flags; + int ret = 0; + + ENTER; + + /* find the cabi address */ + if (!(cabi = search_cabi(cabi_id))) { + CABI_DBG; + /* did not exist. */ + return CABI_ENOEXIST; + } + CABI_DBG; + /* + * !!! Need to make sure cabi is really a account. + */ + LVAL_TASK_ACCOUNT(tsk) = cabi; + + /* show info */ + cabi_debug_info(cabi); + CABI_DBG; + + if((rs_proc = kzalloc(sizeof (struct rs_proc_list), SLAB_KERNEL)) == NULL) { + LVAL_TASK_ACCOUNT(tsk) = NULL; + return CABI_ENOMEM; + } + + CABI_DBG; + + /* set proc file system for the new belonged process */ + rs_proc->rs_proc_task = tsk; + rs_proc->rs_proc_pid = tsk->pid; + + CABI_DBG; + + local_save_flags(flags); + { + local_irq_disable(); + list_add(&rs_proc->rs_proc_list, &cabi->proc_list); + } + local_irq_restore(flags); + + /* Per resources */ + if (cabi->start) + ret = cabi->start (tsk); + + if (ret){ + /* remove rs_proc from the list */ + list_del(&rs_proc->rs_proc_list); + + /* free rs_proc */ + INIT_LIST_HEAD(&rs_proc->rs_proc_list); + kfree(rs_proc); + + /* detach resource set from task */ + LVAL_TASK_ACCOUNT(tsk) = NULL_ACCOUNT; + + return CABI_ERROR; + } + + CABI_DBG; + + return CABI_SUCCESS; +} + +/* + * Name: cabi_account_detach + * + * Detach a process from a specified accounting object. + */ + +int +cabi_account_detach(struct task_struct *tsk) +{ + cabi_account_t cabi = TASK_ACCOUNT(tsk); + struct rs_proc_list *rs_proc; + int ret = 0; + + ENTER; + + /* Per resources */ + if (cabi->end) + ret = cabi->end (tsk); + if (ret) + return CABI_ERROR; + + /* find rs_proc */ + list_for_each_entry(rs_proc, &cabi->proc_list, rs_proc_list) { + if (rs_proc->rs_proc_pid == tsk->pid) + break; + } + + /* show rs_proc info */ + cabi_debug_detach (rs_proc); + + /* remove rs_proc from the list */ + list_del(&rs_proc->rs_proc_list); + + /* free rs_proc */ + INIT_LIST_HEAD(&rs_proc->rs_proc_list); + kfree(rs_proc); + + /* detach resource set from task */ + LVAL_TASK_ACCOUNT(tsk) = NULL_ACCOUNT; + + CABI_DBG; + + return CABI_SUCCESS; +} diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/debug.c linux-2.6.18/drivers/cabi/common/debug.c --- linux-2.6.18-orig/drivers/cabi/common/debug.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/debug.c 2008-01-23 11:57:01.000000000 +0900 @@ -0,0 +1,656 @@ +/* + * linux/drivers/cabi/cabi_debug.c + * + * CABI -- CPU Accounting and Blocking Interfaces. + * + * Copyright (C) OS Research Group, Waseda University + * Nakajima Laboratory. + * + * 2007 Midori Sugaya + */ + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_CABI_CPU +/* + * For test + */ +int cabi_len = 0; +int cabi_debug_counter = 0; +unsigned long *start_address; +int cabi_dump_flag = 0; +int cabi_mask = 0x3ff; +int serial_number = 0; +/* + * 0x3f (63) + * 0x7f (127) + * 0xff (255) + * 0x1ff (511) + * 0x3ff (1023) + * 0xfff (4095) + * 0x13ff (5120) 1024*5 + */ +struct cabi_dump_struct +{ + int counter; + int logid; + unsigned long long tsc_time; + pid_t pid; + unsigned long cabi_id; +}; +struct cabi_dump_struct *cs; + +unsigned long buffer_counter = 0; +unsigned long serial_counter = 0; + +int cabi_dump_init (void) +{ + cs = kmalloc ((cabi_mask+1)* (sizeof (struct cabi_dump_struct)), SLAB_KERNEL); + bzero(cs, (cabi_mask+1) * (sizeof (struct cabi_dump_struct))); + buffer_counter = 0; + + if (!cs) { + printk ("Can not allocate memory!\n"); + return -1; + } + + cabi_dump_flag = 1; + return 0; +} + +void cabi_dump (int logid) +{ + + unsigned long long now; + unsigned long flag; + + if (cabi_dump_flag) { + cabi_spin_lock (flag); + (cs + buffer_counter)->counter = serial_counter++; + (cs + buffer_counter)->logid = logid; + cabi_eval_rdtsc(&now); + (cs + buffer_counter)->tsc_time = now; + (cs + buffer_counter)->pid = 0; + (cs + buffer_counter)->cabi_id = 0; + + buffer_counter++; + buffer_counter &= cabi_mask; + cabi_spin_unlock (flag); + } +} + +void cabi_dump_sched (int logid, struct task_struct *tsk) +{ + + unsigned long long now; + unsigned long flag; + + cabi_account_t cabi = TASK_ACCOUNT(tsk); + + + if (cabi_dump_flag) { + cabi_spin_lock (flag); + (cs + buffer_counter)->counter = serial_counter++; + (cs + buffer_counter)->logid = logid; + cabi_eval_rdtsc(&now); + (cs + buffer_counter)->tsc_time = now; + (cs + buffer_counter)->pid = tsk->pid; + + if (cabi == NULL) { + (cs + buffer_counter)->cabi_id = 0; + } else { + (cs + buffer_counter)->cabi_id = cabi->cabi_id; + } + buffer_counter++; + buffer_counter &= cabi_mask; + cabi_spin_unlock (flag); + } +} + +void cabi_dump_end (void) +{ + unsigned long flag; + cabi_dump_flag = 0; + buffer_counter = 0; + + cabi_spin_lock(flag); + kfree (cs); + cabi_spin_unlock(flag); + + +} +void cabi_dump_ex (int logid, struct task_struct *tsk, + cabi_account_t cabi) +{ + + unsigned long long now; + + + cabi_eval_rdtsc(&now); + + if (cabi_dump_flag) { + (cs + buffer_counter)->counter = serial_counter++; + (cs + buffer_counter)->logid = logid; + (cs + buffer_counter)->tsc_time = now; + if (tsk) + (cs + buffer_counter)->pid = tsk->pid; + else + (cs + buffer_counter)->pid = 0; + if (cabi) + (cs + buffer_counter)->cabi_id = cabi->cabi_id; + else + (cs + buffer_counter)->cabi_id = 0; + + buffer_counter++; + buffer_counter &= cabi_mask; + } +} + +unsigned long read_counter; +void cabi_dump_read (int flag) +{ + + unsigned long temp_counter; + unsigned long local_counter; + unsigned long flags; + int i; + + cabi_dump_flag = 0; + local_counter = 0; + + if (flag) { + temp_counter = buffer_counter; + temp_counter &= cabi_mask; + printk("logid = %d\n", (cs+temp_counter)->logid); + + if ((cs + temp_counter)->logid == 0) { + read_counter = 0; + } else { + read_counter = buffer_counter; + } + } + cabi_spin_lock(flags); + printk ("CABI-DUMP: LOOP %d\n", cabi_mask+1); + for (i=0; i< 127; i++) { + local_counter++; + + if ((cs+read_counter)->pid) { + printk ("CABI-DMPRD:%lu %d %d %llu %d %lu\n", + local_counter, + (cs + read_counter)->counter, + (cs + read_counter)->logid, + (cs + read_counter)->tsc_time, + (cs + read_counter)->pid, + (cs + read_counter)->cabi_id); + } else { + printk ("CABI-DMPRD:%lu %d %d %llu \n", + local_counter, + (cs + read_counter)->counter, + (cs + read_counter)->logid, + (cs + read_counter)->tsc_time); + } + read_counter++; + read_counter &= cabi_mask; + } + + cabi_spin_unlock(flags); +} + + +void +__debug_timespecs (struct timespec *c, struct timespec *t) +{ + cabi_debug("[debug_timespec] c (%lu %lu) t (%lu %lu)\n", + (unsigned long)c->tv_sec, + (unsigned long)c->tv_nsec, + (unsigned long)t->tv_sec, + (unsigned long)t->tv_nsec); +} + +void +cabi_debug_timespecs (struct timespec *c, struct timespec *t) +{ + __debug_timespecs (c,t); +} + +void +cabi_debug_timespec (struct timespec *t) +{ + + cabi_debug ("[debug_timespec] t (%lu %lu)\n", + (unsigned long)t->tv_sec, + (unsigned long)t->tv_nsec); +} + + +void cabi_debug_ct(cpu_capacity_quad_t qc, cpu_capacity_quad_t qt) +{ + cabi_debug("[debug_ct] qc %llu qt %llu\n", qc, qt); +} + +void +cabi_debug_capacity (cpu_capacity_t capacity) +{ + cabi_debug ("[capacity] capacity %lu.%02lu \n", + CAPACITY_INT(capacity), + CAPACITY_FRAC(capacity)); +} + +void +cabi_debug_param (cabi_account_t cabi) +{ + cabi_debug ("cpu_param policy %d op %d type %d\n", + cabi->cpu->pm->policy, + cabi->cpu->pm->operation, + cabi->cpu->pm->bind_proc_type); +} + +void +cabi_debug_sig_param (cabi_account_t cabi) +{ + cabi_debug ("[cabi_sig_param] signal : pid %d sig %d flag %d\n", + (int) CABI_SIGPID(cabi), (int) CABI_SIGNUM(cabi), + (int) CABI_SIGFLAG(cabi)); +} +#endif + +void +cabi_sanity_check_euid (struct task_struct *tsk) +{ + + cabi_debug("cabi_create: Permission denied. EUID [%d], UID [%d]\n", + tsk->euid, tsk->uid); +} + +int +pid_check (pid_t pid) +{ + if (pid < 0) { + cabi_debug("[bind_pid]: invalid pid (%d)\n", + (int) pid ); + return 1; + } + return 0; +} + +int +pgid_check (pid_t pgid) +{ + if (pgid == 0 || pgid < 0) { + cabi_debug("[bind_pgid]: invalid pgid %d.\n", + (int) pgid); + return 1; + } + return 0; +} + +int +cabi_id_check (unsigned long cabi_id) +{ + if (cabi_id == 0 || cabi_id == OVERLOAD_CABI_ID) { + cabi_debug("invalid cabi id %d\n", + (int) cabi_id); + return 1; + } + return 0; +} + +void +bind_pid_error (pid_t pid) +{ + cabi_debug ("[bind_pid] error invalid pid(%d)\n", pid); +} + + +void +cabi_account_attached(struct task_struct *tsk) +{ + + cabi_debug("account_attach_process: account already " + "attached pid(%d) cabi(0x%x) [%d]\n", + tsk->pid, (int) TASK_ACCOUNT(tsk), + (int) TASK_ACCOUNT(tsk)->cabi_id); +} + + +#ifdef CONFIG_CABI_CPU +int +cabi_sanity_check_ucabi (struct cabi_uaccount *ucabi) +{ + + ENTER; + + if (ucabi->cpu->cpu_time.tv_sec <= 0 && + ucabi->cpu->cpu_time.tv_nsec <= 0) { + cabi_debug("cpu_time sec %lu nsec %lu\n", + ucabi->cpu->cpu_time.tv_sec, + ucabi->cpu->cpu_time.tv_nsec); + return CABI_EINVAL; + } + + CABI_DBG; + if (ucabi->cpu->cpu_period.tv_sec <= 0 && + ucabi->cpu->cpu_period.tv_nsec <= 0) { + cabi_debug("period sec %lu nsec %lu\n", + ucabi->cpu->cpu_period.tv_sec, + ucabi->cpu->cpu_period.tv_nsec); + return CABI_EINVAL; + } + + CABI_DBG; + if (ucabi->cpu->pm.operation == OP_BLOCK) { + if (ucabi->cpu->pm.operation <= OP_NONE || + ucabi->cpu->pm.operation >= OP_UNKNOWN) + return CABI_EINVAL; + + CABI_DBG; + if (ucabi->cpu->pm.bind_proc_type < BIND_NORMAL_PROC || + ucabi->cpu->pm.bind_proc_type > BIND_IDLE_PROC) + return CABI_EINVAL; + } + + if (ucabi->cpu->pm.operation == CABI_SIGNAL) { + CABI_DBG; + if (ucabi->cpu->pm.operation == OP_SIGNAL) { + if (ucabi->cpu->pm.cabi_signal.pid < 0) + return CABI_EINVAL; + if (ucabi->cpu->pm.cabi_signal.sig < 0 || + ucabi->cpu->pm.cabi_signal.sig > 32) + return CABI_EINVAL; + } + } + EXIT; + return CABI_SUCCESS; +} + +int +cabi_sanity_check_operation (cabi_uaccount_t ucabi) +{ + ENTER; + switch (ucabi->cpu->pm.operation) { + case OP_BLOCK: + CABI_DBG; + if (ucabi->cpu->pm.operation != OP_BLOCK) + return -1; + break; + case OP_SIGNAL: + CABI_DBG; + if (ucabi->cpu->pm.operation != OP_SIGNAL) + return -1; + + // check signal validatations + if (!ucabi->cpu->pm.cabi_signal.pid) { + ucabi->cpu->pm.cabi_signal.flag = CABI_SEND_DEFL; + } else { + ucabi->cpu->pm.cabi_signal.flag = CABI_SEND_PID; + } + if (!ucabi->cpu->pm.cabi_signal.sig) { + // if signal number is null, set default + // signal which will do nothing. + ucabi->cpu->pm.operation = OP_NONE; + } + break; + default: + break; + } + EXIT; + + return 0; +} + +int +cabi_sanity_check_timespec_c_and_t ( + struct timespec *cpu_time, + struct timespec *cpu_period) +{ + + long time_sec, time_nsec, period_sec, period_nsec; + + ENTER; + + /* Initialize and check execution time parameter */ + time_sec = time_nsec = 0; + time_sec = cpu_time->tv_nsec / NANOSEC; + time_nsec = cpu_time->tv_nsec - time_sec * NANOSEC; + + if (time_sec > (long)(CABI_TIME_SEC_MAX - cpu_time->tv_sec)) { + cabi_debug("cpu_time is over %ld\n", time_sec); + return CABI_EINVAL; + } + time_sec += cpu_time->tv_sec; + + /* Initizalize and check the period parameter */ + period_sec = period_nsec = 0; + period_sec = cpu_period->tv_nsec / NANOSEC; + period_nsec = cpu_period->tv_nsec - period_sec * NANOSEC; + + + if (period_sec > (long)(CABI_TIME_SEC_MAX - cpu_period->tv_sec)) { + cabi_debug ("cpu_period is over max %ld\n", period_sec); + return CABI_EINVAL; + } + period_sec += cpu_period->tv_sec; + + + if (time_sec > period_sec) { + cabi_debug ("time_sec > period_sec error!.\n"); + return CABI_EINVAL; + } else if (time_sec == period_sec) { + if (time_nsec > period_nsec) { + cabi_debug ("time_nsec > period_nsec error.\n"); + return CABI_EINVAL; + + } + } + EXIT; + return CABI_SUCCESS; +} + +int +cabi_sanity_check_overload_id (void) +{ + + cabi_account_t cabi; + + if ((cabi = search_cabi(OVERLOAD_CABI_ID)) != NULL) { + cabi_debug ("[%d] idle cabi_id : %d\n", __LINE__, + (int)cabi->cabi_id); + return CABI_EINVAL; + } + return CABI_SUCCESS; +} + +int +cabi_sanity_check_sigoperation (struct cabi_uaccount *user_cabi) +{ + if (user_cabi->cpu->pm.operation != OP_SIGNAL) { + cabi_debug("invalid operation \n"); + return CABI_EINVAL; + } + cabi_debug ("[sys_create] idle cabi act : %d\n", + user_cabi->cpu->pm.operation); + return CABI_SUCCESS; +} + +void +cabi_sanity_check_parameter_to_copy (struct timespec *c, + struct timespec *t, struct cpu_param *p) +{ + cabi_debug ("[sys_create: %d] c(%d), t(%d), operation(%x)" + " bind_proc_type (%x)\n", + __LINE__, + (int) c->tv_nsec, + (int) t->tv_nsec, + p->operation, + p->bind_proc_type); +} +#endif + +/* cabi account attach */ +void cabi_debug_info (cabi_account_t cabi) +{ + CABI_DBG; + cabi_debug("cabi %x, id %lu\n", + (int)cabi, cabi->cabi_id); +} + +void cabi_debug_detach (struct rs_proc_list *rs_proc) +{ + CABI_DBG; + cabi_debug("[detach] rs_proc(0x%x) pid (%d)\n", + (int) rs_proc, rs_proc->rs_proc_pid); +} + +#ifdef CONFIG_CABI_CPU +void cabi_debug_state (cabi_account_t cabi) +{ + CABI_DBG; + cabi_debug ("cabi_cpu_state 0x%x \n", (int) cabi->cpu->cpu_state); +} + +/* replenish */ +void cabi_debug_ticks (cabi_account_t cabi) +{ + CABI_DBG; + cabi_debug ("[ticks] used %llu period %llu avail %llu cpu_time %llu\n", + cabi->cpu->cpu_period_used_ticks, + cabi->cpu->cpu_period_ticks, + cabi->cpu->cpu_period_available_ticks, + cabi->cpu->cpu_time_ticks); +} + +void cabi_debug_avail_ticks (cabi_account_t cabi) +{ + cabi_debug ("[avail_ticks] used %llu avail %llu cpu_time %llu\n", + cabi->cpu->cpu_period_used_ticks, + cabi->cpu->cpu_period_available_ticks, + cabi->cpu->cpu_time_ticks); +} + +void cabi_debug_tick (unsigned long long tick) +{ + cabi_debug("tick %llu\n", tick); +} + +/* cabi_sched.c */ +void cabi_debug_entities (cabi_account_t cabi01, + cabi_account_t cabi02) +{ + cabi_debug("cabi %x cabi %x\n", + (int) cabi01, (int) cabi02); +} +#endif + +/* cabi_signal.c */ +void cabi_debug_signal_pid (int pid) +{ + cabi_debug ("cabi_send_signal: invalid pid (%d).\n", pid); + cabi_debug ("No received process. (%d)\n", pid); +} + +void cabi_debug_signal_attrs (int pid, int sig, struct task_struct *tsk) +{ + cabi_debug ("cabi_send_signal: pid %d sig %d \n", pid, sig); + cabi_debug ("pid %d status %d\n", + (int) tsk->pid, (int)tsk->state); + cabi_debug ("signal_struct: count %d\n", + (int)tsk->signal->count.counter); +} + +#ifdef CONFIG_CABI_CPU +/* cabi_timer.c */ +void cabi_debug_times (struct timer_list *tmr, unsigned long jiffies) +{ + cabi_debug (" expires %lu, jiffies %lu)\n", + tmr->expires, jiffies); +} + +void cabi_debug_timer (struct timer_list *tmr) +{ + cabi_debug (" expires %lu \n", tmr->expires); +} + +/* kernel/sched.c */ +void cabi_debug_ksched (struct task_struct *prev, + struct task_struct *next) +{ + + cabi_account_t prev_cabi = TASK_ACCOUNT(prev); + cabi_account_t next_cabi = TASK_ACCOUNT(next); + + /* check */ + if (prev_cabi) { + cabi_debug ("\n[ksched:01] prev_cabi[%d] prev[%d] next[%d]\n", + (int) prev_cabi->cabi_id, + prev->pid, next->pid); + } + if (next_cabi) { + cabi_debug ("[ksched:02]next_cabi[%d] prev[%d] next[%d]\n", + (int) next_cabi->cabi_id, + prev->pid, next->pid); + } + + if (prev->pid == 0 || next->pid == 0) { + if (TASK_ACCOUNT(prev) || TASK_ACCOUNT(next)) { + cabi_debug ("[ksched:03] prev[%d] next[%d]\n", + prev->pid, next->pid); + } + } +} + +/* cabi dsv */ + +void check_sched_param (struct rs_proc_list *rs_proc) +{ + + struct sched_param param; + sys_sched_getparam (rs_proc->rs_proc_task->pid, ¶m); + cabi_debug ("[boost:] pid %d prio %d\n", + rs_proc->rs_proc_task->pid, + (int) param.sched_priority); +} + +/* cabi_timer.c */ +void check_hrtimer_res (void) +{ + struct timespec res; + hrtimer_get_res (CLOCK_REALTIME, &res); + cabi_debug ("[rep_prcess] hrtimer_get_res %llu %llu \n", + (unsigned long long) res.tv_sec, + (unsigned long long) res.tv_nsec); +} + +void check_rep_expires (ktime_t expires) +{ + cabi_debug ("[rep_process] expire %llu\n", + expires.tv64); + +} + +void check_enf_expires (ktime_t expires) +{ + cabi_debug ("[enf_process] expire %llu\n", + expires.tv64); + +} + +/* void check_exstate (ktime_t expires, cabi_account_t cabi) +{ + cabi_debug ("[enf_start] expires %lld " + "state %d no-call hrtimer\n", + expires.tv64, cabi->cpu_state); +}*/ + +void check_cancel (int ret) +{ + + cabi_debug ("[enf_cancel] hrtimer_try_to_cancel ret %d \n", ret); +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/init.c linux-2.6.18/drivers/cabi/common/init.c --- linux-2.6.18-orig/drivers/cabi/common/init.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/init.c 2008-01-23 11:40:43.000000000 +0900 @@ -0,0 +1,172 @@ + /* + * linux/drivers/cabi/cabi_init.c + * + * CABI -- CPU Accounting and Blocking Interfaces. + * + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * + * This software was developed by the Waseda University and Montavista Software, + * Inc. Funding for this project was provided by IPA (Information-technology + * Promotion Agency, Japan). This software may be used and distributed + * according to the terms of the GNU Public License, incorporated herein by + * reference. + * + * This project was developed under the direction of Dr. Tatsuo Nakajima. + * + * Authors: Midori Sugaya, Hirotaka Ishikawa + * + * Please send bug-reports/suggestions/comments to qos@dcl.info.waseda.ac.jp + * + * Futher details about this project can be obtained at + * http://dcl.info.waseda.ac.jp/osrg/ + * + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This file is derived from software distributed under the following terms: + */ +#include + +#include + + +extern void enable_account(void); +extern void enable_cpu_account(void); +extern void enable_mem_account(void); + +extern void disable_account(void); +extern void disable_cpu_account(void); +extern void disable_mem_account(void); + +#ifdef CONFIG_CABI_CPU +spinlock_t cabi_lock; +cpu_tick_data_t cabi_cpu_ticks_per_second; +cpu_tick_data_t cabi_cpu_ticks_per_jiffy; +cpu_tick_data_t cabi_timer_adjust; + +#ifdef CONFIG_X86 +#include +#define CHECK_TIME 5 +void +cabi_cpu_calibration_i386(void) +{ + + unsigned long first_jiffies, rem, ctps; + int i = CHECK_TIME; + cpu_tick_data_t begin, end, err, result; + + ENTER; + printk("CABI Calibrating cpu "); + + cabi_rdticks(&begin); + cabi_rdticks(&end); + err = end - begin; + +/* for debugging */ + /* wait for "start of" clock tick */ + first_jiffies = jiffies; + while (first_jiffies == jiffies) { + /* nothing */ + } + cabi_rdticks(&begin); + while (i-- > 0) { + first_jiffies = jiffies; + printk("."); + while (jiffies - first_jiffies < HZ) { + + } + } + cabi_rdticks(&end); + /* */ + + result = (end - begin - err); + cabi_cpu_ticks_per_second = result; + + /* use 64bit interface */ + ctps = div_long_long_rem(result, CHECK_TIME, &rem); + /* set the calculated result */ + cabi_cpu_ticks_per_second = (unsigned long long) ctps; + printk ("%llu\n", cabi_cpu_ticks_per_second); + + EXIT; +} +#else /* #ifdef CONFIG_X86 */ +void +cabi_cpu_calibration(void) +{ + printk("cabi initialize...\n"); + cabi_cpu_ticks_per_second = CABI_CLOCK; + { + cpu_tick_data_t t; + t = CABI_USECS_PER_JIFFY; + usec2tick(&t, &cabi_cpu_ticks_per_jiffy); + } +} +#endif /* #ifdef CONFIG_X86 */ + +#endif + +/* + * Enable/Disable CABI functions + */ +static void inline +cabi_enable(void) +{ + + enable_account(); + +#ifdef CONFIG_CABI_CPU + enable_cpu_account(); +#endif + +#ifdef CONFIG_CABI_MEM + enable_mem_account(); +#endif + +} + +static void inline +cabi_disable(void) +{ +#ifdef CONFIG_CABI_CPU + disable_cpu_account(); +#endif + +#ifdef CONFIG_CABI_MEM + disable_mem_account(); +#endif + +} + + +/* + * cabi_init should be called from kernel basic setup code (init/main.c) + * if CONFIG_CABI=y is set. + */ +void +cabi_init(void) +{ + + cabi_enable(); + +#ifdef CONFIG_CABI_CPU +#ifdef CONFIG_X86 + cabi_cpu_calibration_i386(); +#else + cabi_cpu_calibration(); +#endif /* #ifdef CONFIG_X86 */ +#endif + +} diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/Makefile linux-2.6.18/drivers/cabi/common/Makefile --- linux-2.6.18-orig/drivers/cabi/common/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/Makefile 2007-11-02 17:02:30.000000000 +0900 @@ -0,0 +1,17 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +obj-$(CONFIG_CABI) += procfs.o +obj-$(CONFIG_CABI) += init.o +obj-$(CONFIG_CABI) += signal.o +obj-$(CONFIG_CABI) += syscalls.o +obj-$(CONFIG_CABI) += account.o +obj-$(CONFIG_CABI) += debug.o +obj-$(CONFIG_X86) += udivdi3.o + diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/procfs.c linux-2.6.18/drivers/cabi/common/procfs.c --- linux-2.6.18-orig/drivers/cabi/common/procfs.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/procfs.c 2008-01-23 11:40:41.000000000 +0900 @@ -0,0 +1,86 @@ + /* + * linux/drivers/cabi/cabi_procfs.c - implements the interfaces for procfs. + * + * CABI -- CPU Accounting and Blocking Interfaces. + * + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * + * This software was developed by the Waseda University and Montavista Software, + * Inc. Funding for this project was provided by IPA (Information-technology + * Promotion Agency, Japan). This software may be used and distributed + * according to the terms of the GNU Public License, incorporated herein by + * reference. + * + * This project was developed under the direction of Dr. Tatsuo Nakajima. + * + * Authors: Midori Sugaya, Hirotaka Ishikawa + * + * Please send bug-reports/suggestions/comments to doly@dcl.info.waseda.ac.jp + * + * Futher details about this project can be obtained at + * http://dcl.info.waseda.ac.jp/osrg/ + * + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include + +#include + +#ifdef CONFIG_PROC_FS + +/* proc directories */ +struct proc_dir_entry *proc_cabi_dir; + +void __init +cabi_proc_init(void) +{ + /* proc directory entry */ + proc_cabi_dir = create_proc_entry("cabi", S_IFDIR, 0); + if (!proc_cabi_dir) { + printk("Cannot create /proc/cabi\n"); + } +} + +void +cabi_proc_account_create(cabi_account_t cabi) +{ + cabi_debug ("cabi_proc_account_create: cabi(0x%x) cabi_id (%d) \n", + (int) cabi, (int) cabi->cabi_id); + + if (cabi->proc_create) + cabi->proc_create (cabi); +} + +void +cabi_proc_account_destroy(cabi_account_t cabi) +{ + cabi_debug ("cabi_proc_account_destroy: cabi(%d)", + (int) cabi->cabi_id); + + if (cabi->proc_destroy) + cabi->proc_destroy (cabi); +} + +void +cabi_proc_destroy(void) +{ + remove_proc_entry("cabi", proc_cabi_dir); +} + + +#endif /* CONFIG_PROC_FS */ diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/signal.c linux-2.6.18/drivers/cabi/common/signal.c --- linux-2.6.18-orig/drivers/cabi/common/signal.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/signal.c 2008-01-23 11:40:39.000000000 +0900 @@ -0,0 +1,119 @@ + /* + * linux/drivers/cabi/cabi_signal.c + * + * CABI -- CPU Accounting and Blocking Interfaces. + * + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * + * This software was developed by the Waseda University and Montavista Software, + * Inc. Funding for this project was provided by IPA (Information-technology + * Promotion Agency, Japan). This software may be used and distributed + * according to the terms of the GNU Public License, incorporated herein by + * reference. + * + * This project was developed under the direction of Dr. Tatsuo Nakajima. + * + * Authors: Midori Sugaya, Hirotaka Ishikawa + * + * Please send bug-reports/suggestions/comments to qos@dcl.info.waseda.ac.jp + * + * Futher details about this project can be obtained at + * http://dcl.info.waseda.ac.jp/osrg/ + * + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This file is derived from software distributed under the following terms: + */ + /* + * Real-time and Multimedia Systems Laboratory + * Copyright (c) 1999 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Real-Time and Multimedia Systems Laboratory + * Attn: Prof. Raj Rajkumar + * Electrical and Computer Engineering, and Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * or via email to raj@ece.cmu.edu + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#include + +int +cabi_send_signal(struct cabi_account *cabi, int pid, int sig) +{ + + int error; + struct siginfo info; + struct task_struct *tsk; + + /* Set the siginfo */ + info.si_signo = sig; + info.si_errno = 0; + info.si_code = SI_KERNEL; + info.si_pid = 0; + info.si_uid = 0; + + if (sig <= 0) + return -EINVAL; + + /* This is only valid for normal process(not idle process). */ + if (pid <= 0) + return -EINVAL; + + /* search process by pid */ + if (!(tsk = __cabi_find_process_by_pid(pid))) { + + /* debug */ + cabi_debug_signal_pid (pid); + + /* return */ + error = -ESRCH; + return error; + } else { + + /* debug */ + cabi_debug_signal_attrs (pid, sig, tsk); + + /* send signal */ + error = send_sig_info(sig, &info, tsk); + +/* FIXME */ +#ifdef CONFIG_CABI_CPU + if (error > 0) { + cabi->cpu->signal_block = SIGNAL_ON; + cabi->cpu->signal_count++; + } +#endif + } + return error; +} diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/syscalls.c linux-2.6.18/drivers/cabi/common/syscalls.c --- linux-2.6.18-orig/drivers/cabi/common/syscalls.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/syscalls.c 2008-01-23 11:55:55.000000000 +0900 @@ -0,0 +1,593 @@ +/* + * linux/drivers/cabi/cabi_account.c + * + * CABI -- CPU Accounting and Blocking Interfaces. + * + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * + * This software was developed by the Waseda University and Montavista Software, + * Inc. Funding for this project was provided by IPA (Information-technology + * Promotion Agency, Japan). This software may be used and distributed + * according to the terms of the GNU Public License, incorporated herein by + * reference. + * + * 2007 Modified by Midori SUGAYA to change interfaces. + * 2005-2. New release based on LinuxRK. by Midori SUGAYA, Hirotaka + * ISHIKAWA. + * + * Futher details about this project can be obtained at + * http://dcl.info.waseda.ac.jp/osrg/ + * This is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * This file is derived from software distributed under the following terms: + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * - struct regist - is for manipulating the group of + * processes. Especially used in the binding procedure + * of the group of processes. + */ +struct rglist { + int count; + pid_t pid; + struct task_struct *tsk; + struct list_head rg_link; +}; +typedef struct rglist *rglist_t; +struct list_head rglist_head; + +/* + * Linux proc file system interface + */ +#include +#include + +extern int cabi_sanity_check_euid(struct task_struct *tsk); + +/* + * Name: sys_cabi_account_create + * + * Create a accounting object named cabi. Mainly sanitary checks + * of the parameters. + * + */ +static int +sys_cabi_account_create(struct cabi_uaccount *ucabi) +{ + struct cabi_uaccount user_cabi; + cabi_account_t cabi; + unsigned long ret; + + ENTER; + + /* permission check */ + if (current->euid) { + cabi_sanity_check_euid (current); + goto error_return; + } + + CABI_DBG; + /* parameter copy */ + if (copy_from_user(&user_cabi, ucabi, + sizeof (struct cabi_uaccount))) + goto error_return; + + /* parameter check */ + switch (ucabi->type) { + case CABI_CPU: + ret = check_cpu_params (&user_cabi); + break; + case CABI_MEM: + ret = check_mem_params (&user_cabi); + break; + default: + goto error_return; + } + if (ret != CABI_SUCCESS) + goto error_return; + + /* call create API */ + if ((cabi = cabi_account_create(&user_cabi)) == NULL) { + goto error_return; + } + + CABI_DBG; + /* copy the result vaule to return the caller */ + ret = copy_to_user(&ucabi->cabi_id, &cabi->cabi_id, + sizeof (cabi_object_t)); + + if (ret < 0) + goto error_return; + + return CABI_SUCCESS; + +error_return: + EXIT; + + return CABI_CREATE_ERR; + +} + + +/* + * Name: sys_cabi_account_set + * + * Set the parameters to a specified accounting object (cabi). + */ +static int +sys_cabi_account_set(unsigned long cabi_id, struct cabi_uaccount *ucabi) +{ + struct cabi_uaccount user_cabi; + int ret; + + ENTER; + + /* permission check */ + if (current->euid) { + cabi_sanity_check_euid (current); + return CABI_EACCESS; + } + + CABI_DBG; + /* null pointer check */ + if (!ucabi) + return CABI_EINVAL; + + CABI_DBG; + /* parameter copy */ + if (copy_from_user(&user_cabi, ucabi, + sizeof (struct cabi_uaccount))) + return CABI_EINVAL; + + CABI_DBG; + /* parameter check */ + switch (ucabi->type) { + case CABI_CPU: + ret = check_cpu_params (&user_cabi); + break; + case CABI_MEM: + ret = check_mem_params (&user_cabi); + break; + default: + ret = CABI_EINVAL; + } + if (ret != CABI_SUCCESS) + return ret; + + CABI_DBG; + ret = cabi_account_set(cabi_id, &user_cabi); + if (ret != CABI_SUCCESS) + return ret; + + EXIT; + return CABI_SUCCESS; + +} + + +/* + * Name: sys_cabi_account_get + * + * Get the parameters from a specified accounting object (cabi). + */ + +static int +sys_cabi_account_get(unsigned long cabi_id, struct cabi_uaccount *ucabi) +{ + cabi_account_t cabi = NULL_ACCOUNT; + int ret; + struct cabi_uaccount user_cabi; + + ENTER; + + /* null pointer check */ + if (!ucabi) + return CABI_EINVAL; + + /* find cabi address */ + if (!(cabi = search_cabi(cabi_id))) + return CABI_ENOEXIST; + + /* parameter copy */ + if (copy_from_user(&user_cabi, ucabi, + sizeof (struct cabi_uaccount))) + return CABI_EINVAL; + + ret = cabi_account_get(cabi_id, &user_cabi); + if (ret != CABI_SUCCESS) + return ret; + + /* parameter copy */ + if (copy_to_user(ucabi, &user_cabi, sizeof (user_cabi))) + return CABI_EINVAL; + + EXIT; + + return CABI_SUCCESS; +} + + +/* + * Name: sys_cabi_account_destory + * + * Destory a accounting object. + * + */ +static int +sys_cabi_account_destroy(unsigned long cabi_id) +{ + int ret; + + ENTER; + + /* permission check */ + if (current->euid) { + cabi_sanity_check_euid (current); + return CABI_EACCESS; + } + + + if (cabi_id <= 0) + return CABI_EINVAL; /* invalid argument */ + + ret = cabi_account_destroy(cabi_id); + + EXIT; + + return ret; +} + + +/* + * Name: sys_cabi_account_bind_pid + * + * Bind a process to a accounting object. + * + */ +static int +sys_cabi_account_bind_pid(unsigned long cabi_id, pid_t pid) +{ + + int ret; + struct task_struct *tsk; + + ENTER; + + /* permission check */ + if (current->euid) { + cabi_sanity_check_euid (current); + return CABI_EACCESS; + } + + /* parameter check */ + if (pid_check(pid)) { + return CABI_EINVAL; /* invalid argument */ + } + + /* find overload cabi address. */ + if (cabi_id == OVERLOAD_CABI_ID) { + if (pid != IDLE_PROCESS) { + bind_pid_error(pid); + return CABI_EINVAL; + } + if (!(tsk = __cabi_find_idle_process())) { + bind_pid_error(pid); + return CABI_EPNOEXIST; /* PID(0) dose not exist. */ + } + /* idle process attached. */ + } else { + if (!(tsk = __cabi_find_process_by_pid(pid))) { + bind_pid_error(pid); + return CABI_EPNOEXIST; /* PID dose not exist. */ + } + } + + /* if the task has been registered, rerun. */ + if (TASK_ACCOUNT(tsk)) { + cabi_account_attached (tsk); + if (cabi_id == TASK_ACCOUNT(tsk)->cabi_id) { + /* PID is already registered into AO. */ + return CABI_EREGIST; + } else { + /* PID is registered into another AO. */ + return CABI_ENOAVLE; + } + } + + /* call a function to attach */ + ret = cabi_account_attach(cabi_id, tsk); + + EXIT; + + return ret; + +} + + +/* + * Name: sys_cabi_account_bind_pgid + * + * Bind a grounp of processes to a accounting object. + * + */ +static int +sys_cabi_account_bind_pgid(unsigned long cabi_id, pid_t pgid) +{ + + cabi_account_t cabi; + struct rglist *rg, *tmp; + struct list_head *reg_list; + struct task_struct *tsk; + int i, ret; + int already_registered, shouldbe_registered, + group_member, rglist_count; + + ENTER; + + /* permission check */ + if (current->euid) { + cabi_sanity_check_euid (current); + return CABI_EACCESS; + } + + /* if pgid is 0 or < 0, error return */ + if (pgid_check (pgid)) { + return CABI_EINVAL; + } + + already_registered = shouldbe_registered = + group_member = rglist_count = 0; + + INIT_LIST_HEAD(&rglist_head); + + /* check cabi_id */ + if (cabi_id_check(cabi_id)) { + return CABI_EINVAL; /* invalid argument */ + } + + /* current(caller) check */ + if (TASK_ACCOUNT(current)) { + cabi = TASK_ACCOUNT(current); + if (cabi->cabi_id == cabi_id) { + already_registered++; + } else { + /* If the caller was already binded to other AO, we + * return error. */ + return CABI_ENOAVLE; + } + } else { + /* + * If the caller process has not bind any AO, we shoud + * bind it to the requested AO. But we will not do + * anything here, because for_each_task() routine picks + * up a process as a member of the target group process. + */ + } + + /* + * If the process which is belong to the same group should be + * bind the requested AO. + */ + read_lock(&tasklist_lock); + for_each_process(tsk) { + if (process_group(tsk) == pgid) { + group_member++; + printk("bind_pgid: tsk->pgid %d group_member %d\n", + process_group(tsk), group_member); + /* + * The process which has the right pgid was found. + * Next, we shoud check if this process has been + * already bind to other cabi, if so, error return. + */ + if (TASK_ACCOUNT(tsk)) { + printk("bind_pgid: this account already " + "attached to this process. " + " pid(%d) cabi(0x%x)\n", + tsk->pid, (int) TASK_ACCOUNT(tsk)); + /* + * If the process has been registered + * the requested cabi, count up, else + * error return. + */ + cabi = TASK_ACCOUNT(tsk); + if (cabi->cabi_id == cabi_id) { + already_registered++; + } else { + read_unlock(&tasklist_lock); + return CABI_ENOAVLE; + } + } else { + /* If the task has not been registered, + * we should bind it. But here, we only + * registerd the list. + */ + if((rg = kmalloc(sizeof + (struct rglist), SLAB_KERNEL)) == NULL) { + read_unlock(&tasklist_lock); + return CABI_ENOMEM; + } + bzero(rg, sizeof (struct rglist)); + INIT_LIST_HEAD(&rg->rg_link); + + rg->pid = tsk->pid; + rg->tsk = tsk; + + list_add(&rg->rg_link, &rglist_head); + rglist_count++; + shouldbe_registered++; + } + } + } + read_unlock(&tasklist_lock); + + if (group_member == 0) { + return CABI_EPGNOEXIST; + } else if (group_member == already_registered) { + return CABI_EREGIST; + } else { + /* regist processes */ + reg_list = &rglist_head; + for (i = 0; i < shouldbe_registered + 1; i++) { + if (reg_list == &rglist_head) { + reg_list = reg_list->next; + } else { + tmp = list_entry(reg_list, + struct rglist, rg_link); + if ((ret = + cabi_account_attach(cabi_id, + tmp->tsk))!= CABI_SUCCESS) { + return ret; + } + reg_list = reg_list->next; + } + } + } + + TEXIT; + + return CABI_SUCCESS; +} + + +/* + * Name: sys_cabi_account_unbind + * + * Unbind a process which has been attached to a specified + * accounting object. + * + */ +static int +sys_cabi_account_unbind(pid_t pid) +{ + + struct task_struct *tsk; + int ret; + + ENTER; + + /* permission check */ + if (current->euid) { + cabi_sanity_check_euid (current); + return CABI_EACCESS; + } + + /* pid check */ + if (pid_check(pid)) { + return CABI_EINVAL; /* Invalid argument */ + } + + /* find overload cabi address. */ + if (pid == IDLE_PROCESS) { + if (!(tsk = __cabi_find_idle_process())) { + printk("account_unbind: idle (%d) failed.\n", pid); + return CABI_EPNOEXIST; /* PID(0) dose not exist. */ + } + } else { + if (!(tsk = __cabi_find_process_by_pid(pid))) { + printk("account_unbind: invalid pid(%d)\n", pid); + return CABI_EPNOEXIST; /* PID dose not exist. */ + } + } + + if (!TASK_ACCOUNT(tsk)) { + printk("account_unbind: no account attached to " + "this process. pid(%d)\n", tsk->pid); + return CABI_ENOBIND; + } + + ret = cabi_account_detach(tsk); + + EXIT; + + return ret; +} + +#ifdef CONFIG_CABI_CPU +static int +sys_cabi_account_eval (int eventtype) +{ + + int flag; + + switch (eventtype) { + case 0: + cabi_dump_init(); + break; + case 1: /* this is the first time */ + flag = 1; + cabi_dump_read(flag); + break; + case 2: + flag = 0; + cabi_dump_read(flag); + break; + case 3: + cabi_dump_end(); + break; + default: + break; + + } + return 0; +} +#else +static int +sys_cabi_account_eval (int eventtype) +{ + return 0; +} +#endif + +asmlinkage int sys_cabi(unsigned int cmd, unsigned long arg) +{ + struct cabi_bind_id *bind_id; + struct cabi_uaccount *user; + + switch (cmd) { + case CABI_ACCOUNT_CREATE: + return sys_cabi_account_create((struct cabi_uaccount *)arg); + case CABI_ACCOUNT_DESTROY: + return sys_cabi_account_destroy(arg); + case CABI_ACCOUNT_BIND_PID: + bind_id = (struct cabi_bind_id *)arg; + return sys_cabi_account_bind_pid(bind_id->cabi_id, bind_id->id); + case CABI_ACCOUNT_BIND_PGID: + bind_id = (struct cabi_bind_id *)arg; + return sys_cabi_account_bind_pgid(bind_id->cabi_id, bind_id->id); + case CABI_ACCOUNT_UNBIND: + return sys_cabi_account_unbind((pid_t)arg); + case CABI_ACCOUNT_GET: + user = (struct cabi_uaccount *)arg; + return sys_cabi_account_get(user->cabi_id, user); + case CABI_ACCOUNT_SET: + user = (struct cabi_uaccount *)arg; + return sys_cabi_account_set(user->cabi_id, user); + case CABI_ACCOUNT_EVAL: + return sys_cabi_account_eval ((int)arg); + default: + printk(KERN_ERR "cabi: Unknown system call %d\n", cmd); + break; + } + + return -EINVAL; +} diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/common/udivdi3.S linux-2.6.18/drivers/cabi/common/udivdi3.S --- linux-2.6.18-orig/drivers/cabi/common/udivdi3.S 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/common/udivdi3.S 2007-11-02 16:58:32.000000000 +0900 @@ -0,0 +1,396 @@ + .file "libgcc2.c" + .version "01.01" +gcc2_compiled.: +.section .rodata + .type __clz_tab,@object +__clz_tab: +.byte 0 +.byte 1 +.byte 2 +.byte 2 +.byte 3 +.byte 3 +.byte 3 +.byte 3 +.byte 4 +.byte 4 +.byte 4 +.byte 4 +.byte 4 +.byte 4 +.byte 4 +.byte 4 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 5 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 6 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 7 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 +.byte 8 + .size __clz_tab,256 +.text + .align 4 +.globl __udivdi3 + .type __udivdi3,@function +__udivdi3: + subl $28,%esp + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + movl 56(%esp),%ebx + movl 60(%esp),%edi + movl 48(%esp),%eax + movl %eax,40(%esp) + movl 52(%esp),%edx + movl %edx,16(%esp) + testl %edi,%edi + jne .L25 + cmpl %edx,%ebx + jbe .L26 +#APP + divl %ebx +#NO_APP + movl %eax,%esi + jmp .L30 + .align 4 +.L26: + cmpl $0,56(%esp) + jne .L28 + movl $1,%eax + xorl %edx,%edx + divl %ebx + movl %eax,%ebx +.L28: + movl 16(%esp),%eax + xorl %edx,%edx +#APP + divl %ebx +#NO_APP + movl %eax,%edi + movl %edx,16(%esp) + movl 40(%esp),%eax +#APP + divl %ebx +#NO_APP + movl %eax,%esi + jmp .L30 + .align 4 +.L25: + cmpl %edi,16(%esp) + jae .L31 + xorl %edi,%edi + movl %edi,%esi + jmp .L30 + .align 4 +.L31: +#APP + bsrl %edi,%eax +#NO_APP + movl %eax,%esi + xorl $31,%esi + jne .L38 + cmpl %edi,16(%esp) + ja .L39 + cmpl %ebx,40(%esp) + jb .L45 +.L39: + movl $1,%esi + jmp .L45 + .align 4 +.L38: + movl $32,%ebp + subl %esi,%ebp + movl %esi,%ecx + sall %cl,%edi + movl %edi,20(%esp) + movl %ebx,%eax + movl %ebp,%ecx + shrl %cl,%eax + orl %eax,%edi + movl %esi,%ecx + sall %cl,%ebx + movl 16(%esp),%eax + movl %ebp,%ecx + shrl %cl,%eax + movl %eax,36(%esp) + movl 16(%esp),%eax + movl %esi,%ecx + sall %cl,%eax + movl %eax,20(%esp) + movl 40(%esp),%eax + movl %ebp,%ecx + shrl %cl,%eax + movl 20(%esp),%edx + orl %eax,%edx + movl %edx,16(%esp) + movl %esi,%ecx + sall %cl,40(%esp) + movl %edx,%eax + movl 36(%esp),%edx +#APP + divl %edi +#NO_APP + movl %eax,%esi + movl %edx,16(%esp) +#APP + mull %ebx +#NO_APP + movl %eax,%ebx + movl %edx,%edi + cmpl %edi,16(%esp) + jb .L44 + jne .L45 + cmpl %ebx,40(%esp) + jae .L45 +.L44: + decl %esi +.L45: + xorl %edi,%edi +.L30: + movl %esi,28(%esp) + movl %edi,32(%esp) + movl 28(%esp),%eax + movl 32(%esp),%edx + popl %ebx + popl %esi + popl %edi + popl %ebp + addl $28,%esp + ret +.Lfe1: + .size __udivdi3,.Lfe1-__udivdi3 + .ident "GCC: (GNU) 2.8.1" diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/examples/Makefile linux-2.6.18/drivers/cabi/examples/Makefile --- linux-2.6.18-orig/drivers/cabi/examples/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/examples/Makefile 2007-11-06 16:46:32.000000000 +0900 @@ -0,0 +1,7 @@ +all : + cd cpu; make + cd mem; make + +clean : + cd cpu; make clean + cd mem; make clean diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/Kconfig linux-2.6.18/drivers/cabi/Kconfig --- linux-2.6.18-orig/drivers/cabi/Kconfig 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/Kconfig 2007-11-02 16:58:33.000000000 +0900 @@ -0,0 +1,24 @@ +# +# CABI related configuration option +# + +menu "Resource Accounting and Binding Interface support (NEW)" + +config CABI + bool 'Resouce Accounting Support' + default n + ---help--- + Accounting and Binding Interface support. +config CABI_CPU + bool 'CPU support' + depends on CABI + default n + ---help--- + CPU Accounting and Binding Interface support. +config CABI_MEM + bool 'Memory support' + depends on CABI + default n + ---help--- + Memroy Accounting and Binding Interface support. +endmenu diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_bind_pgid.c linux-2.6.18/drivers/cabi/lib/cabi_account_bind_pgid.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_bind_pgid.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_bind_pgid.c 2007-12-11 20:25:54.000000000 +0900 @@ -0,0 +1,28 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * int sys_cabi_account_bind_pgid(unsigned long cabi_id, pid_t pgid) + */ +_syscall2(int, cabi_account_bind_pgid, unsigned long, cabi_id, pid_t, pgid) +#else +int cabi_account_bind_pgid(unsigned long cabi_id, pid_t pgid) +{ + struct cabi_bind_id bind; + + bind.cabi_id = cabi_id; + bind.id = pgid; + + return cabi(CABI_ACCOUNT_BIND_PGID, (unsigned long)&bind); +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_bind_pid.c linux-2.6.18/drivers/cabi/lib/cabi_account_bind_pid.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_bind_pid.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_bind_pid.c 2007-12-11 20:26:23.000000000 +0900 @@ -0,0 +1,29 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * int sys_cabi_account_bind_pid(unsigned long cabi_id, pid_t pid) + * + */ +_syscall2(int, cabi_account_bind_pid, unsigned long, cabi_id, pid_t, pid) +#else +int cabi_account_bind_pid(unsigned long cabi_id, pid_t pid) +{ + struct cabi_bind_id bind; + + bind.cabi_id = cabi_id; + bind.id = pid; + + return cabi(CABI_ACCOUNT_BIND_PID, (unsigned long)&bind); +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_create.c linux-2.6.18/drivers/cabi/lib/cabi_account_create.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_create.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_create.c 2007-12-11 20:26:41.000000000 +0900 @@ -0,0 +1,25 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * int sys_cabi_account_create(cabi_object_t objectid, cabi_account_t cpu) + */ +_syscall1(int, cabi_account_create, struct cabi_uaccount *, ucabi) +#else +int cabi_account_create(struct cabi_uaccount *ucabi) +{ + return cabi(CABI_ACCOUNT_CREATE, (unsigned long)ucabi); +} +#endif + + diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_destroy.c linux-2.6.18/drivers/cabi/lib/cabi_account_destroy.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_destroy.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_destroy.c 2007-12-11 20:27:06.000000000 +0900 @@ -0,0 +1,23 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * int sys_cabi_account_destroy (unsigned long cabi_id) + */ +_syscall1(int, cabi_account_destroy, unsigned long, cabi_id) +#else +int cabi_account_destroy(unsigned long cabi_id) +{ + return cabi(CABI_ACCOUNT_DESTROY, cabi_id); +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_eval.c linux-2.6.18/drivers/cabi/lib/cabi_account_eval.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_eval.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_eval.c 2007-12-11 20:27:24.000000000 +0900 @@ -0,0 +1,25 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * int sys_cabi_account_create(cabi_object_t objectid, cabi_account_t cpu) + */ +_syscall1(int, cabi_account_eval, int, eventtype) +#else +int cabi_account_eval(int eventtype) +{ + return cabi(CABI_ACCOUNT_EVAL, eventtype); +} +#endif + + diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_get.c linux-2.6.18/drivers/cabi/lib/cabi_account_get.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_get.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_get.c 2007-12-11 20:27:38.000000000 +0900 @@ -0,0 +1,24 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * cabi_uaccount_t sys_cabi_account_get (unsigned long cabi_id, cabi_uaccount_t, ucabi) + */ +_syscall2(int, cabi_account_get, unsigned long, cabi_id, cabi_uaccount_t, ucabi) +#else +int cabi_account_get(unsigned long cabi_id, struct cabi_uaccount *ucabi) +{ + ucabi->cabi_id = cabi_id; + return cabi(CABI_ACCOUNT_GET, (unsigned long)ucabi); +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_set.c linux-2.6.18/drivers/cabi/lib/cabi_account_set.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_set.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_set.c 2007-12-11 20:27:51.000000000 +0900 @@ -0,0 +1,24 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * int sys_cabi_account_set (unsigned long cabi_id, struct cabi_uaccount_t *cpu) + */ +_syscall2(int, cabi_account_set, unsigned long, cabi_id, struct cabi_uaccount *, ucabi) +#else +int cabi_account_set(unsigned long cabi_id, struct cabi_uaccount *ucabi) +{ + ucabi->cabi_id = cabi_id; + return cabi(CABI_ACCOUNT_SET, (unsigned long)ucabi); +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_account_unbind.c linux-2.6.18/drivers/cabi/lib/cabi_account_unbind.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_account_unbind.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_account_unbind.c 2007-12-11 20:28:04.000000000 +0900 @@ -0,0 +1,23 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include + +#if 0 +/* + * int sys_cabi_account_unbind (pid_t pid) + */ +_syscall1(int, cabi_account_unbind, pid_t, pid) +#else +int cabi_account_unbind(pid_t pid) +{ + return cabi(CABI_ACCOUNT_UNBIND, (unsigned long)pid); +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_create_bind.c linux-2.6.18/drivers/cabi/lib/cabi_create_bind.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_create_bind.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_create_bind.c 2007-12-11 20:28:19.000000000 +0900 @@ -0,0 +1,71 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include +#include +/* + * int cabi_overload_create(cabi_uaccount_t ucabi) + */ + +extern int cabi_account_create (struct cabi_uaccount *); +extern int cabi_account_bind_pid(unsigned long cabi_id, pid_t pid); +extern int cabi_account_destroy(unsigned long cabi_id); + +int +cabi_create_bind (struct cabi_uaccount *ucabi, pid_t pid) +{ + + int retval = -EPERM; + + /* If ucabi has not valid address. */ + if (!ucabi) { + return CABI_EINVAL; + } + + /* call cabi_account_create() */ + if (!(retval = cabi_account_create (ucabi))) { +#ifdef DEBUG_CABILIB + fprintf(stderr, "create_bind: account set create. object_id (%d)" + "user cabi address (0x%x)\n", + (int) ucabi->cabi_id, (int)ucabi); +#endif + } else { +#ifdef DEBUG_CABILIB + fprintf(stderr, "create_bind failed. (%d)\n", retval); +#endif + goto error; + } + + if (pid < 0) { +#ifdef DEBUG_CABILIB + fprintf(stderr, "create_bind: invalid pid(%d)\n", + (int)pid); +#endif + retval = CABI_EINVAL; /* Invalid argument */ + goto error; + } + + /* call cabi_account_bind_pid */ + if (!(retval = cabi_account_bind_pid(ucabi->cabi_id, pid))) { +#ifdef DEBUG_CABILIB + fprintf(stderr, "cabi_account_bind_pid: Account ID(%d)[%d]\n", + (int) ucabi->cabi_id, pid); +#endif + return CABI_SUCCESS; + } else { +#ifdef DEBUG_CABILIB + fprintf(stderr, "cabi_account_bind_pid() failed.\n"); +#endif + cabi_account_destroy(ucabi->cabi_id); + } + +error: + return retval; +} diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_overload_create.c linux-2.6.18/drivers/cabi/lib/cabi_overload_create.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_overload_create.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_overload_create.c 2008-01-23 13:29:27.000000000 +0900 @@ -0,0 +1,91 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include +#include +#include + +#define DEBUG_CABILIB 1 + +#ifndef CONFIG_CABI_CPU +/* This function is supported for cabi-cpu only. */ +int cabi_overload_create (struct cabi_uaccount *ucabi) +{ + return CABI_ERROR; +} + +#else +/* + * int cabi_overload_create(cabi_uaccount_t ucabi) + */ +extern int cabi_account_create (struct cabi_uaccount *); +extern int cabi_account_bind_pid (unsigned long cabi_id, pid_t pid); + +int +cabi_overload_create (struct cabi_uaccount *ucabi) +{ + + pid_t pid; + int ret; + + /* If ucabi has not valid address. */ + if (!ucabi) { + return CABI_EINVAL; + } + + ucabi->res.cpu->pm.bind_proc_type = BIND_IDLE_PROC; + +#ifdef DEBUG_CABILIB + printf ("pm.bind_proc_type (%x)\n", + ucabi->res.cpu->pm.bind_proc_type); +#endif + + if ((ret = cabi_account_create (ucabi)) == CABI_SUCCESS) { +#ifdef DEBUG_CABILIB + fprintf(stderr, "overload account set create. object_id (%d)" + "user cabi address (0x%x)\n", + (int) ucabi->cabi_id, (int)ucabi); +#endif + } else { +#ifdef DEBUG_CABILIB + fprintf(stderr, "overload cabi_account_create failed. (%d)\n", + ret); +#endif + return ret; + } + + /* if the system call has been success, then bind the idle process. */ + if (ucabi->cabi_id != OVERLOAD_CABI_ID) { +#ifdef DEBUG_CABILIB + fprintf (stderr, "cabi object_id(%d) did not set. error return.\n", (int) ucabi->cabi_id); +#endif + return CABI_EINVAL; + } + + /* set the idle process */ + pid = IDLE_PROCESS; + + if ((ret = cabi_account_bind_pid(ucabi->cabi_id, pid)) + == CABI_SUCCESS) { +#ifdef DEBUG_CABILIB + fprintf(stderr, "cabi_account_bind_pid: Account ID(%d)[%d]\n", + (int) ucabi->cabi_id, pid); +#endif + return CABI_SUCCESS; + } else { +#ifdef DEBUG_CABILIB + fprintf(stderr, "cabi_account_bind_pid() [idle] failed.\n"); +#endif + return ret; + } + free (ucabi); + return CABI_SUCCESS; +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_overload_destroy.c linux-2.6.18/drivers/cabi/lib/cabi_overload_destroy.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_overload_destroy.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_overload_destroy.c 2008-01-23 13:30:48.000000000 +0900 @@ -0,0 +1,49 @@ +/* + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * MontaVista Software, Inc. + * All Rights Reserved. + * any improvements or extensions that they make and grant Waseda University + * the rights to redistribute these changes. + * + */ + +#define __LIBRARY__ +#include +#include + +#ifndef CONFIG_CABI_CPU +/* This function is supported for cabi-cpu only. */ +int cabi_overload_destroy(void) +{ + return CABI_ERROR; +} +#else +/* + * int cabi_overload_destroy(void) + */ + +extern int cabi_account_unbind(pid_t pid); +extern int cabi_account_destroy(unsigned long cabi_id); + +int +cabi_overload_destroy(void) +{ + pid_t pid = IDLE_PROCESS; + int ret; + + if ((ret = cabi_account_unbind(pid)) != CABI_SUCCESS) { +#ifdef DEBUG_CABILIB + fprintf (stderr, "cabi_overload_destroy : unbind error. (%d)\n", ret); +#endif + return ret; + } + if ((ret = cabi_account_destroy(OVERLOAD_CABI_ID)) != CABI_SUCCESS) { +#ifdef DEBUG_CABILIB + fprintf (stderr, "cabi_overload_destroy : destroy error. (%d)\n", ret); +#endif + return ret; + } + + return ret; +} +#endif diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/cabi_syscall.c linux-2.6.18/drivers/cabi/lib/cabi_syscall.c --- linux-2.6.18-orig/drivers/cabi/lib/cabi_syscall.c 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/cabi_syscall.c 2007-12-11 20:31:15.000000000 +0900 @@ -0,0 +1,5 @@ +#define __LIBRARY__ +#include +#include + +_syscall2(int, cabi, int, cmd, unsigned long, arg) diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/Makefile linux-2.6.18/drivers/cabi/lib/Makefile --- linux-2.6.18-orig/drivers/cabi/lib/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/Makefile 2008-01-23 16:46:22.000000000 +0900 @@ -0,0 +1,26 @@ +INSTALL = /usr/bin/install -c -m 644 +KERNELDIR = ../../.. +CC = $(CROSS_COMPILE)gcc -g +AR = $(CROSS_COMPILE)ar +RANLIB = $(CROSS_COMPILE)ranlib +SOURCES = $(wildcard *.c) +OBJS = $(SOURCES:.c=.o) +CFLAGS = -O3 -Wall -I$(KERNELDIR)/include + +all: libcabi.so libcabi.a + +libcabi.a: $(OBJS) + $(AR) -r libcabi.a $(OBJS) + $(RANLIB) libcabi.a + +libcabi.so: $(OBJS) + $(CC) -fPIC $(OBJS) -shared -o libcabi.so + +clean: + rm -rf $(OBJS) libcabi.a + +install: libcabi.a + $(INSTALL) libcabi.a $(DESTDIR)/lib/libcabi.a + $(INSTALL) libcabi.so $(DESTDIR)/lib/libcabi.so + $(INSTALL) $(KERNELDIR)/include/cabi/cabi.h $(DESTDIR)/usr/include/cabi/cabi.h + $(INSTALL) $(KERNELDIR)/include/cabi/cabi_error.h $(DESTDIR)/usr/include/cabi/cabi_error.h diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/lib/README.cabi linux-2.6.18/drivers/cabi/lib/README.cabi --- linux-2.6.18-orig/drivers/cabi/lib/README.cabi 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/lib/README.cabi 2007-09-21 10:22:14.000000000 +0900 @@ -0,0 +1,11 @@ +README file for the cabi library. +=================================== +This file describes the brief instruction abount the cabi library +install. + +Before make, please add the link for kernel for header +directories as follows. + +#ln -sf /usr/src/linux/include/linux /usr/include/linux +#ln -sf /usr/src/linux/asm-i386 /usr/include/asm + diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/Makefile linux-2.6.18/drivers/cabi/Makefile --- linux-2.6.18-orig/drivers/cabi/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/Makefile 2007-11-02 16:58:33.000000000 +0900 @@ -0,0 +1,12 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +obj-$(CONFIG_CABI) += common/ +obj-$(CONFIG_CABI_CPU) += cpu/ +obj-$(CONFIG_CABI_MEM) += mem/ diff -Nur -x.svn linux-2.6.18-orig/drivers/cabi/README linux-2.6.18/drivers/cabi/README --- linux-2.6.18-orig/drivers/cabi/README 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/drivers/cabi/README 2007-11-02 16:58:33.000000000 +0900 @@ -0,0 +1,20 @@ +RABI (Resource Accounting and Blocking Interfaces) +================================================== + +- Rabi is the lighweight software to set fine grain +limitation for a process or group of processes. + +Introduction +------------- +A rabi is a integrated accounting interface of resources. +The resource list is here. +- CPU +- Memory +- xxx + +Programming Interface +---------------------- +The resouce class structure looks like: + +typedef int (*rabiclass_add) (struct rabi * + diff -Nur -x.svn linux-2.6.18-orig/drivers/Makefile linux-2.6.18/drivers/Makefile --- linux-2.6.18-orig/drivers/Makefile 2008-01-23 15:31:28.000000000 +0900 +++ linux-2.6.18/drivers/Makefile 2007-11-02 16:59:59.000000000 +0900 @@ -76,3 +76,4 @@ obj-$(CONFIG_SUPERH) += sh/ obj-$(CONFIG_GENERIC_TIME) += clocksource/ obj-$(CONFIG_DMA_ENGINE) += dma/ +obj-$(CONFIG_CABI) += cabi/ diff -Nur -x.svn linux-2.6.18-orig/include/asm-i386/unistd.h linux-2.6.18/include/asm-i386/unistd.h --- linux-2.6.18-orig/include/asm-i386/unistd.h 2008-01-23 15:12:45.000000000 +0900 +++ linux-2.6.18/include/asm-i386/unistd.h 2007-12-11 20:40:32.000000000 +0900 @@ -324,6 +324,10 @@ #define __NR_vmsplice 316 #define __NR_move_pages 317 +#ifdef CONFIG_CABI +#define __NR_cabi 318 +#endif + #ifdef __KERNEL__ #define NR_syscalls 318 diff -Nur -x.svn linux-2.6.18-orig/include/cabi/common.h linux-2.6.18/include/cabi/common.h --- linux-2.6.18-orig/include/cabi/common.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/include/cabi/common.h 2008-01-23 13:09:26.000000000 +0900 @@ -0,0 +1,280 @@ +/* + * include/cabi/common.h + * + * CABI -- Common Resource Accounting and Blocking Interfaces. + * + * Copyright (C) OS Research Group, Waseda University Nakajima Laboratory. + * + * This software was developed by the Waseda University and Montavista Software, + * Inc. Funding for this project was provided by IPA (Information-technology + * Promotion Agency, Japan). This software may be used and distributed + * according to the terms of the GNU Public License, incorporated herein by + * reference. + * + * 2007 Midori SUGAYA + * + */ +#ifndef CABI_CABI_H +#define CABI_CABI_H + +#ifdef CONFIG_X86 +#include +#endif /* #ifdef CONFIG_X86 */ + +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else +#include +#include +#include +#include +#include +#endif + +#include +#ifdef CONFIG_CABI_CPU +#include +#endif +#ifdef CONFIG_CABI_MEM +#include +#endif + + +#define OVERLOAD_CABI_ID 1 +#define FIRST_CABI_ID 2 +#define IDLE_PROCESS 0 +#define CABI_ID_MAX 2147483647 + +#define NULL_ACCOUNT NULL +#define NULL_UACCOUNT NULL +#define NULL_ACCOUNT_ID 0x0 + + +typedef unsigned long cabi_object_t; + +enum account_type { + CABI_CPU = 0x001, + CABI_MEM = 0x002, +}; +typedef enum account_type account_type_t; + +struct cabi_uaccount { + cabi_object_t cabi_id; + account_type_t type; + union { +#ifdef CONFIG_CABI_CPU + cpu_uaccount_t cpu; +#endif +#ifdef CONFIG_CABI_MEM + mem_uaccount_t mem; +#endif + } res; +}; +typedef struct cabi_uaccount *cabi_uaccount_t; + +#define CABI_ACCOUNT_CREATE 1 +#define CABI_ACCOUNT_DESTROY 2 +#define CABI_ACCOUNT_BIND_PID 3 +#define CABI_ACCOUNT_BIND_PGID 4 +#define CABI_ACCOUNT_UNBIND 5 +#define CABI_ACCOUNT_GET 6 +#define CABI_ACCOUNT_SET 7 +#define CABI_ACCOUNT_EVAL 8 + +struct cabi_bind_id { + unsigned long cabi_id; + pid_t id; +}; + +#ifdef __KERNEL__ /* for kernel and driver only */ + +/* list_head for AO list */ +extern struct list_head cabi_account_head; + +/* Accounting object */ +struct cabi_account { + cabi_object_t cabi_id; + account_type_t type; + struct list_head cabi_link; + struct list_head proc_list; + struct proc_dir_entry * proc_account_dir; + union { +#ifdef CONFIG_CABI_CPU + cpu_account_t cpu; +#endif +#ifdef CONFIG_CABI_MEM + mem_account_t mem; +#endif + } res; + + /* Common methods */ + int (* create) (struct cabi_account *, struct cabi_uaccount *); + int (* set) (struct cabi_account *, struct cabi_uaccount *); + int (* get) (struct cabi_account *, struct cabi_uaccount *); + int (* init) (struct cabi_account *); + int (* exit) (struct cabi_account *); + int (* start) (struct task_struct *); + int (* end) (struct task_struct *); + int (* proc_create) (struct cabi_account *); + int (* proc_destroy) (struct cabi_account *); +}; +typedef struct cabi_account *cabi_account_t; + +/* + * Process list + */ +struct rs_proc_list { + struct list_head rs_proc_list; + pid_t rs_proc_pid; + struct task_struct *rs_proc_task; + void *private_data; +}; + +/* + * include/linux/sched.h, we add cabi_info address. + * this is the reference macros. + */ +#define TASK_ACCOUNT(tsk) ((cabi_account_t)((tsk)->cabi_info)) +#define LVAL_TASK_ACCOUNT(tsk) ((tsk)->cabi_info) +#define CABI_ID(tsk) ((unsigned long)((tsk)->cabi_info->cabi_id)) + +/* Spin Lock & Unlock + * Usage: + * { + * unsigned long flags; + * cabi_spin_lock(flags); + * + * cabi_spin_unlock(flags); + * } + */ +extern spinlock_t cabi_lock; +#define cabi_spin_lock(flags) spin_lock_irqsave(&cabi_lock, flags) +#define cabi_spin_unlock(flags) spin_unlock_irqrestore(&cabi_lock, flags) + +/* + * Wrapper for kernel interface + */ +//#define malloc(s) kmalloc(s, SLAB_KERNEL) +//#define free(p) kfree(p) +#define bzero(p, s) memset(p, 0, s) + +/* + * Function prototypes, + */ +/* Functions for interface */ +extern struct cabi_account * cabi_account_create(struct cabi_uaccount *); +extern int cabi_account_destroy (unsigned long); +extern int cabi_account_attach (unsigned long, struct task_struct *); +extern int cabi_account_detach (struct task_struct *); +extern int cabi_account_set (unsigned long, struct cabi_uaccount *); +extern int cabi_account_get (unsigned long, struct cabi_uaccount *); + +/* Functions for proc file system */ +extern void __init cabi_proc_init(void); +extern void cabi_proc_destroy(void); +extern void cabi_proc_account_create(cabi_account_t); +extern void cabi_proc_account_destroy(cabi_account_t); + +/* Others */ +extern struct cabi_account * search_cabi(unsigned long); +extern struct task_struct * __cabi_find_process_by_pid(pid_t pid); +extern struct task_struct * __cabi_find_idle_process(void); +extern int cabi_send_signal(struct cabi_account *, int, int); + +/* + * Inline functions + */ +static inline struct rs_proc_list * +pid_to_rs_proc(pid_t pid, cabi_account_t cabi) +{ + struct rs_proc_list *rs_proc = NULL; + + list_for_each_entry(rs_proc, &cabi->proc_list, rs_proc_list) + if (rs_proc->rs_proc_pid == pid) { + return rs_proc; + } + return NULL; +} + +#ifdef CONFIG_CABI_CPU +extern int setup_cpu_account ( + struct cabi_account *, struct cabi_uaccount *); +extern int exit_cpu_account (struct cabi_account *); +extern int check_cpu_params (struct cabi_uaccount *); +#else +static inline int setup_cpu_account( + cabi_account_t cabi, cabi_uaccount_t ucabi) +{ + return 0; +} +static inline int exit_cpu_account(cabi_account_t cabi) +{ + return 0; +} +static inline int check_cpu_params(cabi_uaccount_t ucabi) +{ + return 0; +} +#endif + +#ifdef CONFIG_CABI_MEM +extern int setup_mem_account (struct cabi_account *, struct cabi_uaccount *); +extern int exit_mem_account (struct cabi_account *); +extern int check_mem_params (struct cabi_uaccount *); +#else +static inline int setup_mem_account(cabi_account_t cabi, cabi_uaccount_t ucabi) +{ + return 0; +} +static inline int exit_mem_account(cabi_account_t cabi) +{ + return 0; +} +static inline int check_mem_params(cabi_uaccount_t ucabi) +{ + return 0; +} +#endif + +#else /* __KERNEL__ (for library and app only) */ +/* + * Types for user level applications. + */ +typedef void *cabi_account_t; +//#define NULL_ACCOUNT NULL +/* + * System call prototype. + */ +extern int cabi(int cmd, unsigned long arg); + +/* + * library call prototypes. + */ +extern int cabi_account_create(struct cabi_uaccount *); +extern int cabi_account_destroy(unsigned long); +extern int cabi_account_bind_pid(unsigned long, pid_t); +extern int cabi_account_bind_pgid(unsigned long cabi_id, pid_t pgid); +extern int cabi_account_unbind(pid_t); +extern int cabi_account_get(unsigned long, struct cabi_uaccount *); +extern int cabi_account_set(unsigned long, struct cabi_uaccount *); +extern int cabi_account_eval(int eventtype); +extern int cabi_overload_create(struct cabi_uaccount *ucabi); +extern int cabi_overload_destroy(void); +extern int cabi_create_bind(struct cabi_uaccount *, pid_t); + +#endif /* __KERNEL__ */ + +#endif /* CABI_CABI_H */ diff -Nur -x.svn linux-2.6.18-orig/include/cabi/debug.h linux-2.6.18/include/cabi/debug.h --- linux-2.6.18-orig/include/cabi/debug.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/include/cabi/debug.h 2007-12-26 17:14:51.000000000 +0900 @@ -0,0 +1,211 @@ +/* + * Debug header of CABI + */ +#ifndef CABI_DEBUG_H +#define CABI_DEBUG_H + +#include + +/* + * Please change the definie to undef if you don't need to + * printk the debug codes. + */ +/* + * Define CABI_DEBUG to produce debug message to console + */ +/* #undef CABI_DEBUG */ +//#define CABI_DEBUG +#define CABI_TEST 1 + +/* + * The CABI version + */ +#define CABI_DATE "07/05/05" +#define CABI_VERSION "0.1v" + +/* + * Debug code + */ +/* assrt with traditional prinf/panic */ +#ifdef CONFIG_KERNEL_ASSERTS +/* kgdb stuff */ +#define assert(p) KERNEL_ASSERT(#p, p) +#else +#define assert(p) do { \ + if (!(p)) { \ + printk(KERN_CRIT "BUG at %s:%d assert(%s)\n", \ + __FILE__, __LINE__, #p); \ + BUG(); \ + } \ +} while (0) +#endif + +/* + * the general debug interface for cabi + */ + +#ifdef CABI_DEBUG +#define cabi_debug(fmt, arg...) \ + printk(KERN_NOTICE " " __FILE__": " fmt "" , ## arg) +#else +#define cabi_debug(fmt, arg...) +#endif + +#ifdef CABI_DEBUG +#define ENTER \ + cabi_debug("ENTER [%s;%d] \n", __FUNCTION__, __LINE__); +#define EXIT \ + cabi_debug("EXIT [%s:%d] \n", __FUNCTION__,__LINE__); + +#define CABI_DBG \ + cabi_debug("DBG [%s:%d] \n", __FUNCTION__,__LINE__); + +#else + +#define ENTER +#define EXIT +#define CDEBUG +#define CABI_DBG +#define CABI_DBG_AO +#define CABI_DBG_TIMESPEC +#define CABI_DBG_TG +#define CABI_WARNING +#define CABI_NOTICE +#define CABI_DEBUGX + +#endif // CABI_DEBUG + +/* + * Define CABI_TEST to produce cycle counter values to specific buffer. + */ +#if defined (CABI_TEST) && defined (CONFIG_CABI_CPU) + +#define cabi_test(fmt, arg...) \ + printk(KERN_NOTICE "" fmt "" , ## arg) +#define MAX_BUF_LEN 1024 + +extern char cabip[MAX_BUF_LEN]; +extern int cabi_len; +extern int cabi_debug_counter; + +static inline void cabi_eval_rdtsc (unsigned long long *data_p) +{ + rdtscll(*data_p); +} +static inline unsigned long long cabi_show_rdtsc(void) +{ + unsigned long long now; + cabi_eval_rdtsc (&now); + return now; +} +static inline void +cabi_print_enter (void) +{ + unsigned long long now; + + cabi_eval_rdtsc(&now); + cabi_len += sprintf (cabip+cabi_len, "%llu\n", now); +} + +static inline void +cabi_print_exit (void) +{ + unsigned long long now; + + cabi_eval_rdtsc(&now); + cabi_len += sprintf (cabip+cabi_len, "EXIT %llu %s %s \n", + now, __FILE__, __FUNCTION__); + +} +#define TENTER \ + cabi_test ("ENTER [%s:%d] %llu\n", __FUNCTION__, __LINE__, \ + cabi_show_rdtsc()); +#define TEXIT \ + cabi_test ("EXIT [%s:%d] %llu\n", __FUNCTION__, __LINE__, \ + cabi_show_rdtsc()); +/* +#define cabi_dump \ +do { \ + cabi_len += sprintf(cabip+cabi_len, "[%s:%d] %llu %d\n", __FUNCTION__,__LINE__, cabi_show_rdtsc(), cabi_debug_counter++); \ +} while(0) +*/ + +#else +#define TENTER +#define TEXIT +#endif + +/* + * Debug functions + */ + +/* extern parameters */ +extern struct cabi_uaccount *ucabi; +extern struct cpu_param *p; +extern struct cabi_account *cabi; +extern struct rs_proc_list *rs_proc; +extern struct timer_list *tmr; + +/* sanity_check_functions */ +extern int cabi_sanity_check_timespec_c_and_t (struct timespec *c, struct timespec *t); +extern int cabi_sanity_check_overload_id (void); +extern int cabi_sanity_check_ucabi (struct cabi_uaccount *ucabi); +extern int cabi_sanity_check_term_act (struct cabi_uaccount *ucabi); +extern void cabi_sanity_check_parameter_to_copy (struct timespec *c, struct timespec *t, struct cpu_param *p); +extern int cabi_sanity_check_operation (struct cabi_uaccount *ucabi); +extern void cabi_debug_timespecs (struct timespec *c, struct timespec *t); +extern void cabi_debug_timespec (struct timespec *t); +extern int cabi_sanity_check_sigoperation (struct cabi_uaccount *ucabi); + +/* just logging the values */ +extern void cabi_debug_capacity (unsigned long capacity); +extern void cabi_debug_ticks (struct cabi_account *); +extern void cabi_debug_ct (unsigned long long, unsigned long long); +extern void cabi_debug_sig_param(struct cabi_account *); +extern void cabi_debug_param (struct cabi_account *); + +extern int pid_check(pid_t); +extern void bind_pid_error(pid_t); +extern void cabi_account_attached(struct task_struct *); +extern int pgid_check(pid_t); +extern int cabi_id_check(unsigned long); + +extern void cabi_debug_info (struct cabi_account *); +extern void cabi_debug_state (struct cabi_account *); +extern void cabi_debug_detach (struct rs_proc_list *); +extern void cabi_debug_ticks (struct cabi_account *); +extern void cabi_debug_tick (unsigned long long tick); +extern void cabi_debug_avail_ticks (struct cabi_account *); + +/* cabi_isr.c */ +extern void cabi_debug_current(struct cabi_account *); + +/* cabi_sched.c */ +extern void cabi_debug_entities (struct cabi_account *, + struct cabi_account *); +/* kernel/sched.c */ +extern void cabi_debug_ksched (struct task_struct *, + struct task_struct *); +/* cabi_signal.c */ +extern void cabi_debug_signal_pid (int); +extern void cabi_debug_signal_attrs (int, int, struct task_struct *tsk); + +/* cabi_timer.c */ +extern void cabi_debug_times (struct timer_list *tmr, unsigned long); +extern void cabi_debug_timer (struct timer_list *tmr); +extern void check_hrtimer_res (void); +extern void check_rep_expires (ktime_t); +extern void check_enf_expires (ktime_t); +extern void check_cancel (int); +//extern void check_exstate (ktime_t, struct cabi_account *); + +/* */ +extern void cabi_dump (int); +extern void cabi_dump_ex (int, struct task_struct *, + struct cabi_account *); +extern int cabi_dump_init (void); +extern void cabi_dump_read (int); +extern void cabi_dump_end (void); +extern void cabi_dump_sched (int, struct task_struct *); + +#endif /* CABI_DEBUG_H */ diff -Nur -x.svn linux-2.6.18-orig/include/cabi/error.h linux-2.6.18/include/cabi/error.h --- linux-2.6.18-orig/include/cabi/error.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/include/cabi/error.h 2007-11-02 16:45:00.000000000 +0900 @@ -0,0 +1,22 @@ +#ifndef CABI_CABI_ERROR_H +#define CABI_CABI_ERROR_H + +#define CABI_SUCCESS 0 /* Success */ +#define CABI_ERROR 1 /* Error */ + +#define CABI_SYSERR 2 /* Linux system error */ +#define CABI_EINVAL 3 /* Invalid argument */ +#define CABI_EACCESS 4 /* No use authority */ + +#define CABI_ENOMEM 5 /* Memory allocation failed. */ +#define CABI_EATTACHED 6 /* Process is still attached. */ +#define CABI_ENOAVLE 7 /* PID is registered into another AO. */ +#define CABI_EREGIST 8 /* PID is already registered into AO. */ +#define CABI_ENOBIND 9 /* PID is not bound to AO. */ +#define CABI_ENOEXIST 10 /* AO dose not exist. */ +#define CABI_EPNOEXIST 11 /* PID dose not exist. */ +#define CABI_EPGNOEXIST 12 /* PGID dose not exist. */ +#define CABI_ENOCABIID 13 /* No more cabi id exist. */ +#define CABI_CREATE_ERR 14 /* cabi_account_create error. */ + +#endif /* CABI_CABI_ERROR_H */ diff -Nur -x.svn linux-2.6.18-orig/include/cabi/unistd.h linux-2.6.18/include/cabi/unistd.h --- linux-2.6.18-orig/include/cabi/unistd.h 1970-01-01 09:00:00.000000000 +0900 +++ linux-2.6.18/include/cabi/unistd.h 2007-11-02 17:02:30.000000000 +0900 @@ -0,0 +1,259 @@ +#ifndef _CABI_UNISTD_H_ +#define _CABI_UNISTD_H_ + +/* + * For x86 architecture + */ +#ifdef CONFIG_X86 +/* + * user-visible error numbers are in the range -1 - -128: see + * + */ +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-(128 + 1))) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ +#define _syscall0(type,name) \ +type name(void) \ +{ \ +long __res; \ +__asm__ volatile ("int $0x80" \ + : "=a" (__res) \ + : "0" (__NR_##name)); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \ + "int $0x80 ; pop %%ebx" \ + : "=a" (__res) \ + : "i" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ + struct { long __a1; long __a6; } __s = { (long)arg1, (long)arg6 }; \ +__asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \ + "movl 0(%2),%%ebx ; movl %1,%%eax ; int $0x80 ; " \ + "pop %%ebx ; pop %%ebp" \ + : "=a" (__res) \ + : "i" (__NR_##name),"0" ((long)(&__s)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ + : "memory"); \ +__syscall_return(type,__res); \ +} + +/* + * For ARM architecture + */ +#elif defined (CONFIG_ARM) +#define __sys2(x) #x +#define __sys1(x) __sys2(x) + +#ifndef __syscall +#if defined(__thumb__) || defined(__ARM_EABI__) +#define __SYS_REG(name) register long __sysreg __asm__("r7") = __NR_##name; +#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs +#define __syscall(name) "swi\t0" +#else +#define __SYS_REG(name) +#define __SYS_REG_LIST(regs...) regs +#define __syscall(name) "swi\t" __sys1(__NR_##name) "" +#endif +#endif + +#define __syscall_return(type, res) \ +do { \ + if ((unsigned long)(res) >= (unsigned long)(-129)) { \ + errno = -(res); \ + res = -1; \ + } \ + return (type) (res); \ +} while (0) + +#define _syscall0(type,name) \ +type name(void) { \ + __SYS_REG(name) \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST() \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __r4 __asm__("r4") = (long)arg5; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ + "r" (__r3), "r" (__r4) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \ + __SYS_REG(name) \ + register long __r0 __asm__("r0") = (long)arg1; \ + register long __r1 __asm__("r1") = (long)arg2; \ + register long __r2 __asm__("r2") = (long)arg3; \ + register long __r3 __asm__("r3") = (long)arg4; \ + register long __r4 __asm__("r4") = (long)arg5; \ + register long __r5 __asm__("r5") = (long)arg6; \ + register long __res_r0 __asm__("r0"); \ + long __res; \ + __asm__ __volatile__ ( \ + __syscall(name) \ + : "=r" (__res_r0) \ + : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ + "r" (__r3), "r" (__r4), "r" (__r5) ) \ + : "memory" ); \ + __res = __res_r0; \ + __syscall_return(type,__res); \ +} +#else + #error "Cabi doesn't support this architecture yet." +#endif /* CONFIG_X86 CONFIG_ARM */ +#endif /* _CABI_UNISTD_H_ */ diff -Nur -x.svn linux-2.6.18-orig/include/linux/init_task.h linux-2.6.18/include/linux/init_task.h --- linux-2.6.18-orig/include/linux/init_task.h 2008-01-23 15:14:40.000000000 +0900 +++ linux-2.6.18/include/linux/init_task.h 2008-01-23 15:29:36.000000000 +0900 @@ -6,6 +6,10 @@ #include #include +#ifdef CONFIG_CABI +#include +#endif + #define INIT_FDTABLE \ { \ .max_fds = NR_OPEN_DEFAULT, \ @@ -128,6 +132,7 @@ .pi_lock = SPIN_LOCK_UNLOCKED, \ INIT_TRACE_IRQFLAGS \ INIT_LOCKDEP \ + .cabi_info = NULL, \ } diff -Nur -x.svn linux-2.6.18-orig/include/linux/sched.h linux-2.6.18/include/linux/sched.h --- linux-2.6.18-orig/include/linux/sched.h 2008-01-23 15:14:41.000000000 +0900 +++ linux-2.6.18/include/linux/sched.h 2007-11-02 16:46:02.000000000 +0900 @@ -945,7 +945,10 @@ /* journalling filesystem info */ void *journal_info; - + +/* CPU Accounting System info */ + void *cabi_info; + /* VM state */ struct reclaim_state *reclaim_state; diff -Nur -x.svn linux-2.6.18-orig/init/main.c linux-2.6.18/init/main.c --- linux-2.6.18-orig/init/main.c 2008-01-23 15:17:35.000000000 +0900 +++ linux-2.6.18/init/main.c 2007-11-02 16:47:40.000000000 +0900 @@ -62,6 +62,10 @@ #include #endif +#ifdef CONFIG_CABI +extern void cabi_init(void); +#endif + /* * This is one of the first .c files built. Error out early if we have compiler * trouble. @@ -661,6 +665,10 @@ sysctl_init(); #endif +#ifdef CONFIG_CABI + cabi_init(); +#endif + do_initcalls(); } diff -Nur -x.svn linux-2.6.18-orig/kernel/exit.c linux-2.6.18/kernel/exit.c --- linux-2.6.18-orig/kernel/exit.c 2008-01-23 15:11:40.000000000 +0900 +++ linux-2.6.18/kernel/exit.c 2008-01-23 15:34:21.000000000 +0900 @@ -909,6 +909,15 @@ taskstats_exit_send(tsk, tidstats, group_dead, mycpu); taskstats_exit_free(tidstats); +#ifdef CONFIG_CABI + if (tsk->cabi_info) { +#ifdef DEBUG_CABI + printk("in exit, detach pid (%d) cabi(0x%x)\n", + tsk->pid, (int) tsk->cabi_info); +#endif + cabi_account_detach(tsk); + } +#endif exit_mm(tsk); if (group_dead) @@ -921,6 +930,7 @@ cpuset_exit(tsk); exit_keys(tsk); + if (group_dead && tsk->signal->leader) disassociate_ctty(1); diff -Nur -x.svn linux-2.6.18-orig/kernel/fork.c linux-2.6.18/kernel/fork.c --- linux-2.6.18-orig/kernel/fork.c 2008-01-23 15:11:40.000000000 +0900 +++ linux-2.6.18/kernel/fork.c 2007-11-02 16:42:46.000000000 +0900 @@ -53,6 +53,10 @@ #include #include +#ifdef CONFIG_CABI +#include +#endif + /* * Protected counters by write_lock_irq(&tasklist_lock) */ @@ -1201,6 +1205,20 @@ goto bad_fork_cleanup_namespace; } +#ifdef CONFIG_CABI + if (p->cabi_info) { + cabi_account_t cabi; + int cabi_account_attach(unsigned long, struct task_struct *); + cabi = p->cabi_info; + p->cabi_info = NULL; + cabi_account_attach(cabi->cabi_id, p); +#ifdef DEBUG_CABI + printk("in fork, attach pid(%d), cabi(0x%x)\n", + p->pid, (int) cabi); +#endif + } +#endif + if (clone_flags & CLONE_THREAD) { p->group_leader = current->group_leader; list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group); diff -Nur -x.svn linux-2.6.18-orig/Makefile linux-2.6.18/Makefile --- linux-2.6.18-orig/Makefile 2008-01-23 15:31:28.000000000 +0900 +++ linux-2.6.18/Makefile 2007-11-02 16:59:59.000000000 +0900 @@ -598,6 +598,10 @@ # # System.map is generated to document addresses of all kernel symbols +ifeq ($(strip $(CONFIG_CABI)),y) +libgcc=$(shell $(CC) -print-libgcc-file-name) +endif + vmlinux-init := $(head-y) $(init-y) vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y) vmlinux-all := $(vmlinux-init) $(vmlinux-main)