Changeset 8
- Timestamp:
- 10/15/05 18:00:42 (6 years ago)
- Files:
-
- arch/i386/kernel/callgate.c (modified) (5 diffs)
- arch/i386/kernel/entry.S (modified) (1 diff)
- arch/i386/kernel/process.c (modified) (3 diffs)
- arch/i386/kernel/traps.c (modified) (1 diff)
- include/asm-i386/processor.h (modified) (1 diff)
- include/linux/module.h (modified) (2 diffs)
- include/linux/sched.h (modified) (2 diffs)
- kernel/exit.c (modified) (2 diffs)
- kernel/fork.c (modified) (1 diff)
- kernel/module.c (modified) (5 diffs)
- .version (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
arch/i386/kernel/callgate.c
r7 r8 53 53 void *ring2_driver_helper; 54 54 55 56 55 void callgate_entry1(int oldcs, unsigned long param1); 57 56 void callgate_entry2(int oldcs, unsigned long param1, unsigned long param2); … … 76 75 "pushl 16(%ebp)\n\t" 77 76 "decl %ecx\n\t" 78 "cmpl $ 2, %ecx\n\t"77 "cmpl $3, %ecx\n\t" 79 78 "ja done2\n\t" 80 79 "call *callgate_table2(,%ecx,4)\n\t" … … 83 82 "leave\n\t" 84 83 "lret $8\n\t" 85 "callgate_table2: .long driver_printdiag, do_exit "84 "callgate_table2: .long driver_printdiag, do_exit, driver_exit" 86 85 ); 87 86 … … 161 160 "pushl %edx\n\t" 162 161 "call *%ebx\n\t" 163 "pushl %eax\n\t" 164 "pushl $2\n\t" 165 "lcall $0x108, $0\n\t" 162 "movl %eax, %ebx\n\t" 163 "movl $285, %eax\n\t" 164 "int $0x80\n\t" 165 //"pushl %eax\n\t" 166 // "pushl $3\n\t" 167 // "lcall $0x108, $0\n\t" 166 168 "end_of_driver_thread_helper:\n\t" 167 169 "ud2\n" … … 181 183 } 182 184 185 //Cannot call from no context (ie interrupt handler) 186 int calldriver(unsigned long addr, void *data, struct mm_struct *mm, unsigned long flags) 187 { 188 struct task_struct *tsk; 189 struct pt_regs *regs; 190 if (in_interrupt()) 191 { 192 printk(KERN_ERR "Cannot call driver code from interrupt handler\n"); 193 return -1; 194 } 195 /* 196 //try to find the stack! 197 stack=find_module_stack(addr); 198 if (!stack) { 199 printk(KERN_ERR "Could not find stack for code at address %x\n", (unsigned int) addr); 200 return -1; 201 } 202 pid=driver_thread(addr, data, stack, 0, ring); 203 tsk=find_task_by_pid(pid); 204 interruptible_sleep_on(&tsk->wait_kernexit); 205 return tsk->exit_code;*/ 206 207 tsk=find_worker_thread(addr); 208 if (!tsk) { 209 printk(KERN_ERR "Could not find worker thread for address %x\n", addr); 210 return -1; 211 } 212 if (!tsk->available) { 213 printk(KERN_ERR "Thread busy...increase size of driver thread pool\n"); 214 return -1; 215 } 216 tsk->available=0; 217 //Set memory map 218 if (mm) 219 tsk->mm=mm; 220 221 //Set new state for thread 222 //show_stack(tsk, NULL); 223 regs=task_pt_regs(tsk); 224 //show_regs(regs); 225 regs->ebx=addr; 226 regs->edx=(unsigned long) data; 227 if (tsk->ring == 1) { 228 regs->eip=(unsigned long) ring1_driver_helper; 229 } else if (tsk->ring == 2) { 230 regs->eip=(unsigned long) ring2_driver_helper; 231 } 232 else 233 BUG(); 234 235 //printk("Going...\n"); 236 //show_regs(regs); 237 wake_up_process(tsk); 238 239 interruptible_sleep_on(&tsk->wait_driverfinish); 240 return tsk->exit_code; 241 } 242 243 244 245 246 247 arch/i386/kernel/entry.S
r6 r8 913 913 .long sys_ni_syscall /* reserved for kexec */ 914 914 .long sys_printdiag 915 .long driver_exit /* 285*/ 915 916 916 917 syscall_table_size=(.-sys_call_table) arch/i386/kernel/process.c
r7 r8 346 346 } 347 347 */ 348 int driver_thread(unsigned long fn, void * arg,unsigned long flags, int ring)348 int create_driver_thread(unsigned long flags, int ring) 349 349 { 350 350 struct pt_regs regs; 351 unsigned char *stack_start=NULL; 351 void *stack_start=NULL; 352 void *orig_stack=NULL; 353 int pid; 352 354 memset(®s, 0, sizeof(regs)); 353 regs.ebx = (unsigned long) fn;354 regs.edx = (unsigned long) arg;355 // regs.ebx = (unsigned long) fn; 356 // regs.edx = (unsigned long) arg; 355 357 356 358 if (!ring1_driver_helper) … … 362 364 regs.xcs = __RING1_CS; 363 365 regs.xss = __RING1_DS; 364 regs.eip = (unsigned long) ring1_driver_helper;365 stack_start=(unsigned char*)__vmalloc(8192, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING1);366 // regs.eip = (unsigned long) ring1_driver_helper; 367 orig_stack= __vmalloc(8192, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING1); 366 368 // printk("Created ring 1 stack at %x", stack_start); 367 369 } … … 373 375 regs.xss = __RING2_DS; 374 376 regs.eip = (unsigned long) ring2_driver_helper; 375 stack_start=(unsigned char*)__vmalloc(8192, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING2);377 orig_stack= __vmalloc(8192, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING2); 376 378 // printk("Created ring 2 stack at %x", stack_start); 377 379 } 378 380 else 379 381 BUG(); 380 stack_start +=8152; //leave 40 bytes empty382 stack_start=(unsigned char*) orig_stack + 8152; //leave 40 bytes empty 381 383 regs.orig_eax = -1; 382 384 383 385 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; 384 385 386 /* Ok, create the new process.. */ 386 387 //printk("Calling do_fork"); 387 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, (unsigned long) stack_start, ®s, 0, NULL, NULL); 388 pid=do_fork(flags | CLONE_STOPPED | CLONE_VM | CLONE_UNTRACED, (unsigned long) stack_start, ®s, 0, NULL, NULL); 389 find_task_by_pid(pid)->orig_stack=orig_stack; 390 find_task_by_pid(pid)->available=1; 391 return pid; 388 392 } 389 393 /* arch/i386/kernel/traps.c
r6 r8 94 94 asmlinkage void machine_check(void); 95 95 96 static int kstack_depth_to_print = 24; 96 //NOTE: changed 97 static int kstack_depth_to_print = 48; 97 98 98 99 static int valid_stack_ptr(struct task_struct *task, void *p) include/asm-i386/processor.h
r6 r8 492 492 493 493 /*Create driver thread in other ring*/ 494 extern int driver_thread(unsigned long fn, void * arg, unsigned long flags, int ring); 494 extern int create_driver_thread(unsigned long flags, int ring); 495 495 496 496 497 extern unsigned long thread_saved_pc(struct task_struct *tsk); include/linux/module.h
r1 r8 48 48 extern int init_module(void); 49 49 extern void cleanup_module(void); 50 51 extern struct task_struct *find_worker_thread(unsigned long addr); 50 52 51 53 /* Archs provide a method of finding the correct exception table. */ … … 308 310 /* Fake kernel param for refcnt. */ 309 311 struct kernel_param refcnt_param; 312 313 /* Locatoin of stack in lower ring*/ 314 //void *stack_start; 315 316 /*task struct of worker thread*/ 317 struct task_struct *worker_thread; 318 319 /*ring we got loaded in*/ 320 unsigned int ring; 321 310 322 #endif 311 323 include/linux/sched.h
r1 r8 436 436 437 437 wait_queue_head_t wait_chldexit; /* for wait4() */ 438 wait_queue_head_t wait_driverfinish; /*FOR RING CYCLE*/ 438 439 struct completion *vfork_done; /* for vfork() */ 439 440 int __user *set_child_tid; /* CLONE_CHILD_SETTID */ … … 516 517 short il_next; /* could be shared with used_math */ 517 518 #endif 519 520 //NEW for RING CYCLE 521 int ring; 522 void *orig_stack; //for vfree() 523 int available; 518 524 }; 519 525 kernel/exit.c
r6 r8 814 814 exit_notify(tsk); 815 815 //NEW 816 wake_up(&tsk->wait_chldexit);816 //wake_up(&tsk->wait_kernexit); 817 817 schedule(); 818 818 BUG(); … … 830 830 831 831 EXPORT_SYMBOL(complete_and_exit); 832 833 asmlinkage void driver_exit(long exit_code) 834 { 835 //Make it look like we finished, but stick around 836 struct task_struct *tsk=current; 837 tsk->exit_code=exit_code; 838 tsk->state=TASK_UNINTERRUPTIBLE; 839 tsk->available=1; 840 wake_up(&tsk->wait_driverfinish); 841 schedule(); 842 //BUG(); 843 //for (;;) ; 844 845 } 832 846 833 847 asmlinkage long sys_exit(int error_code) kernel/fork.c
r1 r8 947 947 INIT_LIST_HEAD(&p->sibling); 948 948 init_waitqueue_head(&p->wait_chldexit); 949 init_waitqueue_head(&p->wait_driverfinish); 949 950 p->vfork_done = NULL; 950 951 spin_lock_init(&p->alloc_lock); kernel/module.c
r6 r8 39 39 #include <asm/pgalloc.h> 40 40 #include <asm/cacheflush.h> 41 41 #include <asm/callgate.h> 42 42 #if 0 43 43 #define DEBUGP printk … … 621 621 /* Final destruction now noone is using it. */ 622 622 up(&module_mutex); 623 mod->exit(); 623 // mod->exit(); 624 if (mod->exit) 625 calldriver((unsigned long) mod->exit, NULL, NULL, 0); 624 626 down(&module_mutex); 627 //NEW: get rid of threads 628 zap_other_threads(mod->worker_thread); 629 module_free(mod, mod->worker_thread->orig_stack); 625 630 free_module(mod); 626 631 down(¬ify_mutex); … … 1801 1806 struct module *mod; 1802 1807 int ret; 1803 struct task_struct *tsk;1808 int pid; 1804 1809 /* Must have permission */ 1805 1810 if (!capable(CAP_SYS_MODULE)) … … 1843 1848 //NEW CODE 1844 1849 //printk("Calling driver_thread..."); 1850 // mod->stack_start = (unsigned char*) __vmalloc(8192, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING2) +8152; 1851 /* 1845 1852 ret=driver_thread((unsigned long) mod->init, NULL, 0, 2); 1846 1853 tsk=find_task_by_pid(ret); 1847 1854 interruptible_sleep_on(&tsk->wait_chldexit); 1848 1855 ret=tsk->exit_code; 1849 printk("Driver thread finished with code %d", ret); 1856 printk("Driver thread finished with code %d", ret);*/ 1857 //FIXME: Figure out what ring to load module in (how?) 1858 mod->ring=2; 1859 pid=create_driver_thread(0, mod->ring); 1860 if (!pid) { 1861 printk("ERROR getting pid for worker thread\n"); 1862 //FIXME: Correct return code here? 1863 return -1; 1864 } 1865 mod->worker_thread=find_task_by_pid(pid); 1866 mod->worker_thread->ring=mod->ring; 1867 if (!mod->worker_thread) { 1868 printk("ERROR getting task struct for worker thread\n"); 1869 return -1; 1870 } 1871 ret=calldriver((unsigned long) mod->init, NULL, NULL, 0); 1850 1872 if (ret < 0) { 1851 1873 /* Init routine failed: abort. Try to protect us from 1852 1874 buggy refcounters. */ 1853 1854 1875 mod->state = MODULE_STATE_GOING; 1855 1876 down(¬ify_mutex); … … 1889 1910 } 1890 1911 1912 struct task_struct *find_worker_thread(unsigned long addr) 1913 { 1914 struct task_struct *tsk=NULL; 1915 struct module *mod; 1916 if (!addr) 1917 return NULL; 1918 spin_lock_irq(&modlist_lock); 1919 1920 list_for_each_entry(mod, &modules, list) { 1921 if (within(addr, mod->module_init, mod->init_size) || 1922 within(addr, mod->module_core, mod->core_size)) 1923 tsk=mod->worker_thread; 1924 } 1925 1926 1927 spin_unlock_irq(&modlist_lock); 1928 return tsk; 1929 } 1930 1891 1931 #ifdef CONFIG_KALLSYMS 1892 1932 static const char *get_ksymbol(struct module *mod, .version
r7 r8 1 72 1 93
