/*************************************************************************** * * Copyright (C) 2001 International Business Machines * All rights reserved. * * This file is part of the GPFS mmfslinux kernel module. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *************************************************************************** */ /* @(#)85 1.24.1.1 src/avs/fs/mmfs/ts/kernext/gpl-linux/i386/ss_i386.c, mmfs, avs_rgpfs24, rgpfs24s007a 10/8/06 03:17:10 */ /* * Implementation of shared segment for GPFS daemon and GPFS kernel code. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Function spec: * * Return a user_regs_struct for a particular thread * * For a particular task id, cycle thru each task via * for_each_task(task_id) * * Look for the requested thread * task_structP->pid * * A couple of the registers are found within the thread sub structure * pointed to by the task structure. * task_structP->thread.fs * task_structP->thread.gs * * All the other regs are found via the stack pointer thread.esp0 * The stack pointer points at the last element in a * struct pt_regs . The elements of the pt_regs * grow down from the stack pointer offset. * * Thus if thread.esp0 is 0xC0000000 * pt_regs.ss 0xBFFFFFFC * pt_regs.esp 0xBFFFFFF8 * pt_regs.eflags 0xBFFFFFF4 * pt_regs.xcs 0xBFFFFFF0 * pt_regs.eip 0xBFFFFFEC * pt_regs.orig_eax 0xBFFFFFE8 * pt_regs.xes 0xBFFFFFE4 * pt_regs.xds 0xBFFFFFE0 * pt_regs.eax 0xBFFFFFDC * pt_regs.ebp 0xBFFFFFD8 * pt_regs.edi 0xBFFFFFD4 * pt_regs.esi 0xBFFFFFD0 * pt_regs.edx 0xBFFFFFCC * pt_regs.ecx 0xBFFFFFC8 * pt_regs.ebx 0xBFFFFFC4 */ int kxSaveThreadInfo(int tid, void* regP) { struct task_struct *g, *t; unsigned char *stackP; int rc = ENOENT; union { struct user_regs_struct userRegs; unsigned long regArray[0]; } u; #define STACKP(A) (*(unsigned long *)(stackP - \ (unsigned char *)(sizeof(struct pt_regs) - \ (long)&((struct pt_regs *)0)->A))) #define REGARRAY(A) \ u.regArray[(long)&(((struct user_regs_struct *)0)->A) / sizeof(long)] // read_lock(&tasklist_lock); rcu_read_lock(); DO_EACH_THREAD(g,t) { if (t->pid != tid) continue; REGARRAY(fs) = t->thread.fs; REGARRAY(gs) = t->thread.gs; stackP = (char *)t->thread.esp0; REGARRAY(ss) = STACKP(xss); REGARRAY(esp) = STACKP(esp); REGARRAY(eflags) = STACKP(eflags); REGARRAY(cs) = STACKP(xcs); REGARRAY(eip) = STACKP(eip); REGARRAY(orig_eax) = STACKP(orig_eax); REGARRAY(es) = STACKP(xes); REGARRAY(ds) = STACKP(xds); REGARRAY(eax) = STACKP(eax); REGARRAY(ebp) = STACKP(ebp); REGARRAY(edi) = STACKP(edi); REGARRAY(esi) = STACKP(esi); REGARRAY(edx) = STACKP(edx); REGARRAY(ecx) = STACKP(ecx); REGARRAY(ebx) = STACKP(ebx); rc = 0; goto found_it; } WHILE_EACH_THREAD(g,t); found_it: // read_unlock(&tasklist_lock); rcu_read_unlock(); if (rc == 0) rc = copy_to_user(regP, &u.userRegs, sizeof(struct user_regs_struct)); return rc; }