/*************************************************************************** * * 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. * *************************************************************************** */ /* @(#)39 1.2 src/avs/fs/mmfs/ts/kernext/gpl-linux/x86_64/ss_x86_64.c, mmfs, avs_rgpfs24, rgpfs240610b 9/15/04 23:29:31 */ /* * 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 /* * 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 * * Some of the registers are found within the thread_struct sub structure * pointed to by the task structure, see include/asm-x86_64/processor.h * * All the other regs are found via the stack pointer thread.rsp0 */ int kxSaveThreadInfo(int tid, void* regP) { struct task_struct *g,*t; int rc = ENOENT; struct pt_regs *kregsP; struct user_regs_struct userRegs; long data, i; read_lock(&tasklist_lock); DO_EACH_THREAD(g,t) { if (t->pid != tid) continue; userRegs.fs = t->thread.fs; userRegs.gs = t->thread.gs; userRegs.es = t->thread.es; userRegs.ds = t->thread.ds; userRegs.fs_base = t->thread.fsindex; /* ??? */ userRegs.gs_base = t->thread.gsindex; /* ??? */ /* Not really sure if this is always true, can't find any docs for this, * but it appears to work */ kregsP = (struct pt_regs*)(t->thread.rsp0 - sizeof(struct pt_regs)); /* user_regs_struct is identical to pt_regs up to the size of pt_regs */ memcpy(&userRegs, kregsP, sizeof(struct pt_regs)); /* I'm not proud of this code. I don't know why it works, * but it does. I'll have to figure out why one of these days */ userRegs.rsp = t->thread.userrsp; userRegs.r15 = kregsP->rbx; userRegs.r14 = kregsP->rbp; userRegs.r13 = kregsP->r12; userRegs.r12 = kregsP->r13; userRegs.rbp = kregsP->r14; userRegs.rbx = kregsP->r15; rc = 0; goto found_it; } WHILE_EACH_THREAD(g,t); found_it: read_unlock(&tasklist_lock); if (rc == 0) copy_to_user(regP, &userRegs, sizeof(struct user_regs_struct)); return rc; }