Changeset 16
- Timestamp:
- 10/29/05 20:46:21 (6 years ago)
- Files:
-
- arch/i386/kernel/callgate.c (modified) (5 diffs)
- arch/i386/kernel/process.c (modified) (6 diffs)
- arch/i386/kernel/signal.c (modified) (1 diff)
- arch/i386/kernel/traps.c (modified) (3 diffs)
- include/linux/module.h (modified) (3 diffs)
- include/linux/sched.h (modified) (3 diffs)
- kernel/fork.c (modified) (3 diffs)
- kernel/module.c (modified) (12 diffs)
- kernel/sched.c (modified) (5 diffs)
- .version (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
arch/i386/kernel/callgate.c
r15 r16 64 64 void *ring1_driver_helper; 65 65 void *ring2_driver_helper; 66 void *ring1_nop; 67 void *ring2_nop; 66 68 67 69 void callgate_entry1(int oldcs, unsigned long param1); … … 212 214 "ud2\n" 213 215 ".previous"); 216 217 extern void ring_nop(void); 218 extern void end_of_nop(void); 219 __asm__("ring_nop : ret \n\t" 220 "end_of_nop:ud2\n\t"); 214 221 void create_driver_helpers(void) 215 222 { … … 220 227 memcpy(ring1_driver_helper, driver_thread_helper, size_of_asm); 221 228 memcpy(ring2_driver_helper, driver_thread_helper, size_of_asm); 229 size_of_asm=end_of_nop - ring_nop; 230 231 ring1_nop=__vmalloc(size_of_asm, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING1); 232 ring2_nop=__vmalloc(size_of_asm, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING2); 233 234 memcpy(ring1_nop, ring_nop, size_of_asm); 235 memcpy(ring2_nop, ring_nop, size_of_asm); 222 236 create_callgate((unsigned long) callgate_entry1, 2, 1); 223 237 create_callgate((unsigned long) callgate_entry2, 2, 2); … … 257 271 if (!tsk) { 258 272 printk(KERN_ERR "Could not find worker thread for address %x\n", addr); 259 return -1; 273 printk(KERN_ERR "Probably all threads are currently in use, try increasing size of driver thread pool\n"); 274 return -EBUSY; 260 275 } 261 276 if (tsk->flags & PF_DEAD) { … … 263 278 return -ENODEV; 264 279 } 265 if (!tsk->available) {280 /*if (!tsk->available) { 266 281 printk(KERN_ERR "Thread busy...increase size of driver thread pool\n"); 267 282 return -1; 268 } 283 }*/ 269 284 tsk->available=0; 270 285 //Set memory map 271 286 if (mm) { 287 atomic_dec(&tsk->mm->mm_users); 288 atomic_dec(&tsk->mm->mm_count); 272 289 atomic_inc(&mm->mm_users); 273 290 atomic_inc(&mm->mm_count); arch/i386/kernel/process.c
r15 r16 62 62 extern void *ring1_driver_helper; 63 63 extern void *ring2_driver_helper; 64 65 extern void driver_exit(int error_code); 64 66 65 67 … … 347 349 } 348 350 */ 351 extern void *ring1_nop; 352 extern void *ring2_nop; 349 353 int create_driver_thread(unsigned long flags, int ring) 350 354 { … … 354 358 int pid; 355 359 memset(®s, 0, sizeof(regs)); 356 // regs.ebx = (unsigned long) fn; 360 357 361 // regs.edx = (unsigned long) arg; 358 362 … … 365 369 regs.xcs = __RING1_CS; 366 370 regs.xss = __RING1_DS; 367 // regs.eip = (unsigned long) ring1_driver_helper; 371 regs.ebx= (unsigned long) ring1_nop; 372 regs.eip = (unsigned long) ring1_driver_helper; 368 373 orig_stack= __vmalloc(8192, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING1); 369 374 // printk("Created ring 1 stack at %x", stack_start); … … 375 380 regs.xcs = __RING2_CS; 376 381 regs.xss = __RING2_DS; 382 regs.ebx=(unsigned long) ring2_nop; 377 383 regs.eip = (unsigned long) ring2_driver_helper; 378 384 orig_stack= __vmalloc(8192, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING2); … … 389 395 /* Ok, create the new process.. */ 390 396 //printk("Calling do_fork"); 391 pid=do_fork(flags | CLONE_ STOPPED | CLONE_VM | CLONE_UNTRACED | CLONE_PARENT, (unsigned long) stack_start, ®s, 0, NULL, NULL);397 pid=do_fork(flags | CLONE_VM | CLONE_UNTRACED | CLONE_PARENTINIT , (unsigned long) stack_start, ®s, 0, NULL, NULL); 392 398 find_task_by_pid(pid)->orig_stack=orig_stack; 393 find_task_by_pid(pid)->available= 1;399 find_task_by_pid(pid)->available=0; 394 400 return pid; 395 401 } arch/i386/kernel/signal.c
r15 r16 560 560 */ 561 561 // if ((regs->xcs & 3) != 3) 562 if ((regs->xcs & 3)==1)563 printk("Sending signal to ring 1 driver thread!\n");564 562 if (!(regs->xcs & 3)) 565 563 return 1; arch/i386/kernel/traps.c
r15 r16 27 27 #include <linux/ptrace.h> 28 28 #include <linux/version.h> 29 #include <linux/syscalls.h> 29 30 30 31 #ifdef CONFIG_EISA … … 437 438 DO_ERROR(12, SIGBUS, "stack segment", stack_segment) 438 439 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, get_cr2()) 440 void do_unload_module(void *myaddr) { 441 char *name; 442 int ret; 443 unsigned long addr=(unsigned long) myaddr; 444 printk("Attempting to unload module\n"); 445 name=find_module_by_thread(addr); 446 printk("Address we got was %x, module is %s\n", addr, name); 447 ret=sys_delete_module(name, 0); 448 printk("delete returned %d which is %d", ret, -ret); 449 } 450 static DECLARE_WORK(mytask, do_unload_module, NULL); 451 static struct workqueue_struct *mywq; 439 452 asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) 440 453 { … … 454 467 current->thread.error_code=error_code; 455 468 current->thread.trap_no=13; 469 current->exit_signal=-1; 456 470 force_sig(SIGKILL, current); 471 printk("Unloading module cleanly...\n"); 472 mywq=create_workqueue("gp"); 473 mytask.data=(void*) regs->eip; 474 //queue_work(mywq, &mytask); 457 475 return; 458 476 include/linux/module.h
r14 r16 28 28 #define MODULE_SUPPORTED_DEVICE(name) 29 29 30 //Number of threads in driver thread pool 31 #define NR_DRIVERTHREADS 10 32 30 33 /* v850 toolchain uses a `_' prefix for all user symbols */ 31 34 #ifndef MODULE_SYMBOL_PREFIX … … 52 55 53 56 extern struct task_struct *find_worker_thread(unsigned long addr); 57 extern char *find_module_by_thread(unsigned long addr); 54 58 55 59 /* Archs provide a method of finding the correct exception table. */ … … 317 321 318 322 /*task struct of worker thread*/ 319 struct task_struct *worker_thread ;323 struct task_struct *worker_threads[NR_DRIVERTHREADS]; 320 324 321 325 /*ring we got loaded in*/ include/linux/sched.h
r8 r16 55 55 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */ 56 56 #define CLONE_STOPPED 0x02000000 /* Start in stopped state */ 57 57 #define CLONE_PARENTINIT 0x04000000 58 58 /* 59 59 * List of flags we want to share for kernel threads, … … 739 739 extern int FASTCALL(wake_up_state(struct task_struct * tsk, unsigned int state)); 740 740 extern int FASTCALL(wake_up_process(struct task_struct * tsk)); 741 extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk ));741 extern void FASTCALL(wake_up_forked_process(struct task_struct * tsk, unsigned long clone_flags)); 742 742 #ifdef CONFIG_SMP 743 743 extern void kick_process(struct task_struct *tsk); … … 745 745 #else 746 746 static inline void kick_process(struct task_struct *tsk) { } 747 static inline void wake_up_forked_thread(struct task_struct * tsk )747 static inline void wake_up_forked_thread(struct task_struct * tsk, unsigned long clone_flags) 748 748 { 749 wake_up_forked_process(tsk );749 wake_up_forked_process(tsk, clone_flags); 750 750 } 751 751 #endif kernel/fork.c
r15 r16 1048 1048 if (clone_flags & CLONE_PARENT) 1049 1049 p->real_parent = current->real_parent; 1050 else if (clone_flags & CLONE_PARENTINIT) 1051 p->real_parent=&init_task; 1050 1052 else 1051 1053 p->real_parent = current; … … 1202 1204 * We'll start up with an immediate SIGSTOP. 1203 1205 */ 1204 /*sigaddset(&p->pending.signal, SIGSTOP);1205 set_tsk_thread_flag(p, TIF_SIGPENDING); */1206 sigaddset(&p->pending.signal, SIGSTOP); 1207 set_tsk_thread_flag(p, TIF_SIGPENDING); 1206 1208 } 1207 1209 … … 1219 1221 */ 1220 1222 if (clone_flags & CLONE_VM) 1221 wake_up_forked_thread(p );1223 wake_up_forked_thread(p, clone_flags); 1222 1224 else 1223 wake_up_forked_process(p );1225 wake_up_forked_process(p, clone_flags); 1224 1226 // } else { 1225 1227 if (clone_flags & CLONE_STOPPED) { 1226 1228 int cpu = get_cpu(); 1227 1229 1228 p->state = TASK_STOPPED;1230 //p->state = TASK_STOPPED; 1229 1231 if (cpu_is_offline(task_cpu(p))) 1230 1232 set_task_cpu(p, cpu); kernel/module.c
r15 r16 562 562 int ret, forced = 0; 563 563 unsigned long testargs; 564 int i; 564 565 if (!capable(CAP_SYS_MODULE)) 565 566 return -EPERM; 566 567 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) 568 return -EFAULT; 567 568 if ((unsigned long) name_user < TASK_SIZE ) { 569 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) 570 return -EFAULT; 571 } else { 572 if (strncpy(name, name_user, MODULE_NAME_LEN -1 ) < 0) 573 return -EFAULT; 574 } 569 575 name[MODULE_NAME_LEN-1] = '\0'; 570 576 … … 577 583 goto out; 578 584 } 579 580 585 if (!list_empty(&mod->modules_which_use_me)) { 581 586 /* Other modules depend on us: get rid of them first. */ … … 627 632 down(&module_mutex); 628 633 //NEW: get rid of threads 629 zap_other_threads(mod->worker_thread); 630 module_free(mod, mod->worker_thread->orig_stack); 634 for (i=0; i<NR_DRIVERTHREADS; i++) { 635 //zap_other_threads(mod->worker_threads[i]); 636 if (!(mod->worker_threads[i]->flags & PF_DEAD)) { 637 mod->worker_threads[i]->exit_signal=-1; 638 force_sig(SIGKILL, mod->worker_threads[i]); 639 wake_up_process(mod->worker_threads[i]); 640 } 641 642 module_free(mod, mod->worker_threads[i]->orig_stack); 643 } 631 644 free_module(mod); 645 print_modules(); 632 646 down(¬ify_mutex); 633 647 notifier_call_chain(&module_notify_list, MODULE_STATE_GONE, … … 1476 1490 /* Suck in entire file: we'll want most of it. */ 1477 1491 /* vmalloc barfs on "unusual" numbers. Check here */ 1478 //if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL)1492 //if (len > 64 * 1024 * 1024 || (hdr = vmalloc(len)) == NULL) 1479 1493 if (len > 64 * 1024 * 1024 || (hdr = __vmalloc(len, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, VMALLOC_RING1)) == NULL) 1480 1494 return ERR_PTR(-ENOMEM); … … 1604 1618 1605 1619 if (pcpuindex) { 1620 printk("wtf?\n"); 1606 1621 /* We have a special allocation for this section. */ 1607 1622 percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, … … 1614 1629 mod->percpu = percpu; 1615 1630 } 1631 //New 1632 else 1633 mod->percpu=0; 1616 1634 1617 1635 /* Determine total sizes, and put offsets in sh_entsize. For now … … 1636 1654 memset(ptr, 0, mod->init_size); 1637 1655 mod->module_init = ptr; 1638 1656 printk("percpu is currently %xn", mod->percpu); 1639 1657 /* Transfer each section which specifies SHF_ALLOC */ 1640 1658 DEBUGP("final section addresses:\n"); … … 1660 1678 /* Module has been moved. */ 1661 1679 mod = (void *)sechdrs[modindex].sh_addr; 1662 1680 printk("NOW it is %x\n", mod->percpu); 1663 1681 /* Now we've moved module, initialize linked lists, etc. */ 1664 1682 module_unload_init(mod); … … 1808 1826 int ret; 1809 1827 int pid; 1828 int i; 1810 1829 /* Must have permission */ 1811 1830 if (!capable(CAP_SYS_MODULE)) 1812 1831 return -EPERM; 1813 1814 1832 /* Only one module load at a time, please */ 1815 1833 if (down_interruptible(&module_mutex) != 0) … … 1858 1876 //FIXME: Figure out what ring to load module in (how?) 1859 1877 mod->ring=1; 1860 pid=create_driver_thread(0, mod->ring); 1861 if (!pid) { 1862 printk("ERROR getting pid for worker thread\n"); 1863 //FIXME: Correct return code here? 1864 return -1; 1878 for (i=0; i<NR_DRIVERTHREADS; i++) { 1879 pid=create_driver_thread(0, mod->ring); 1880 if (!pid) { 1881 printk("ERROR getting pid for worker thread\n"); 1882 //FIXME: Correct return code here? 1883 return -1; 1884 } 1885 mod->worker_threads[i]=find_task_by_pid(pid); 1886 if (!mod->worker_threads[i]) { 1887 printk("ERROR getting task struct for worker thread\n"); 1888 return -1; 1889 } 1890 mod->worker_threads[i]->ring=mod->ring; 1865 1891 } 1866 mod->worker_thread=find_task_by_pid(pid); 1867 mod->worker_thread->ring=mod->ring; 1868 if (!mod->worker_thread) { 1869 printk("ERROR getting task struct for worker thread\n"); 1870 return -1; 1871 } 1892 schedule(); 1893 printk("mod pointer is %x, per cpu is %d\n", mod, mod->percpu); 1872 1894 printk("Invoking init method...\n"); 1873 1895 ret=calldriver((unsigned long) mod->init, NULL, 0, NULL, 0); … … 1916 1938 struct task_struct *tsk=NULL; 1917 1939 struct module *mod; 1940 int i=0; 1918 1941 if (!addr) 1919 1942 return NULL; … … 1922 1945 list_for_each_entry(mod, &modules, list) { 1923 1946 if (within(addr, mod->module_init, mod->init_size) || 1924 within(addr, mod->module_core, mod->core_size)) 1925 tsk=mod->worker_thread; 1947 within(addr, mod->module_core, mod->core_size)) { 1948 //Now find an availalbe one 1949 while (i < NR_DRIVERTHREADS) { 1950 if (mod->worker_threads[i]->available) { 1951 tsk=mod->worker_threads[i]; 1952 goto out; 1953 } 1954 i++; 1955 } 1956 } 1926 1957 } 1927 1958 1928 1959 out: 1929 1960 spin_unlock_irq(&modlist_lock); 1930 1961 return tsk; 1962 } 1963 1964 char *find_module_by_thread(unsigned long addr) 1965 { 1966 struct module *mod; 1967 if (!addr) 1968 return NULL; 1969 spin_lock_irq(&modlist_lock); 1970 list_for_each_entry(mod, &modules, list) { 1971 if (within(addr, mod->module_init, mod->init_size) || 1972 within(addr, mod->module_core, mod->core_size)) { 1973 spin_unlock_irq(&modlist_lock); 1974 return mod->name; 1975 } 1976 } 1977 spin_unlock_irq(&modlist_lock); 1978 return NULL; 1931 1979 } 1932 1980 kernel/sched.c
r1 r16 927 927 * that must be done for every newly created process. 928 928 */ 929 void fastcall wake_up_forked_process(task_t * p )929 void fastcall wake_up_forked_process(task_t * p, unsigned long clone_flags) 930 930 { 931 931 unsigned long flags; … … 949 949 p->prio = effective_prio(p); 950 950 set_task_cpu(p, smp_processor_id()); 951 952 951 if (unlikely(!current->array)) 953 952 __activate_task(p, rq); … … 1270 1269 p->prio = effective_prio(p); 1271 1270 set_task_cpu(p, cpu); 1272 1273 1271 if (cpu == this_cpu) { 1274 1272 if (unlikely(!current->array)) … … 1289 1287 resched_task(rq->curr); 1290 1288 } 1291 1292 1289 double_rq_unlock(this_rq, rq); 1293 1290 local_irq_restore(flags); … … 3976 3973 rq->idle = current; 3977 3974 set_task_cpu(current, smp_processor_id()); 3978 wake_up_forked_process(current );3975 wake_up_forked_process(current, 0); 3979 3976 3980 3977 /* .version
r15 r16 1 1 461 181
