source: gpfs_3.1_ker2.6.20/lpp/mmfs/src/gpl-linux/ia64/ss_ia64.c @ 16

Last change on this file since 16 was 16, checked in by rock, 16 years ago
File size: 6.7 KB
Line 
1/***************************************************************************
2 *
3 * Copyright (C) 2001 International Business Machines
4 * All rights reserved.
5 *
6 * This file is part of the GPFS mmfslinux kernel module.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 *  1. Redistributions of source code must retain the above copyright notice,
13 *     this list of conditions and the following disclaimer.
14 *  2. Redistributions in binary form must reproduce the above copyright
15 *     notice, this list of conditions and the following disclaimer in the
16 *     documentation and/or other materials provided with the distribution.
17 *  3. The name of the author may not be used to endorse or promote products
18 *     derived from this software without specific prior written
19 *     permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 *************************************************************************** */
33/* @(#)86       1.19.1.5  src/avs/fs/mmfs/ts/kernext/gpl-linux/ia64/ss_ia64.c, mmfs, avs_rgpfs24, rgpfs24s008a 11/17/06 10:04:58 */
34/*
35 * Implementation of shared segment for GPFS daemon and GPFS kernel code.
36 *
37 */
38
39#include <Shark-gpl.h>
40#include <Logger-gpl.h>
41#include <cxiSystem.h>
42#include <cxiIOBuffer.h>
43#include <cxiSharedSeg.h>
44#include <Trace.h>
45
46#include <linux/types.h>
47#include <linux/version.h>
48#include <linux/kernel.h>
49#include <linux/module.h>
50#include <linux/errno.h>
51#include <linux/slab.h>
52#include <linux/smp_lock.h>
53#include <linux/proc_fs.h>
54#include <linux/mm.h>
55#include <linux/fs.h>
56#include <linux/file.h>
57#include <linux/binfmts.h>
58#include <linux/vmalloc.h>
59#include <linux/signal.h>
60
61#include <asm/pgtable.h>
62#include <asm/pgalloc.h>
63#include <asm/io.h>
64#include <asm/uaccess.h>
65#include <asm/user.h>
66#include <asm/mman.h>
67#include <asm/atomic.h>
68#include <asm/ptrace.h>
69
70#include <verdep.h>
71#include <arch-gpl.h>
72
73#ifdef LEVEL_1
74struct ia64_pfs {
75  __u64 reserved0 : 62;
76  __u64 ppl : 2;
77};
78# define ia64_pfs(regs)   ((struct ia64_pfs *) &(regs)->ar_pfs)
79#endif
80
81int
82set_privilege_level(unsigned long progLevel)
83{
84#ifdef LEVEL_1
85  unsigned long cpl;
86  unsigned long new_cpl;
87  unsigned long ipsr;
88  unsigned long new_ipsr;
89  unsigned long pfs;
90  unsigned long new_pfs;
91        struct pt_regs *regs;
92
93        if (progLevel < 0 || progLevel > 3 || !cxiIsSuperUser())
94          return -1;
95
96#if LINUX_KERNEL_VERSION > 2061600
97        regs = task_pt_regs(current);
98#else
99        regs = ia64_task_regs(current);
100#endif
101        cpl = ia64_psr(regs)->cpl;
102        ipsr = regs->cr_ipsr;
103        pfs = regs->ar_pfs;
104
105        ia64_psr(regs)->cpl = progLevel; // set current privilege level
106        ia64_pfs(regs)->ppl = progLevel; // set previous privilege level
107
108        new_ipsr = regs->cr_ipsr;
109        new_pfs = regs->ar_pfs;
110
111        TRACE5(TRACE_SHARED, 2, TRCID_SS_022,
112               "set_privilege_level: cpl 0x%lX ipsr 0x%lX pfs 0x%lX new_ipsr 0x%lX new_pfs 0x%lX\n",
113               cpl, ipsr, pfs, new_ipsr, new_pfs);
114
115#endif
116  return 0;
117}
118
119int
120get_privilege_level()
121{
122  unsigned long cpl;
123        struct pt_regs *regs;
124  unsigned long ipsr;
125  unsigned long pfs;
126
127#if LINUX_KERNEL_VERSION > 2061600
128        regs = task_pt_regs(current);
129#else
130        regs = ia64_task_regs(current);
131#endif
132        cpl = ia64_psr(regs)->cpl;
133        ipsr = regs->cr_ipsr;
134        pfs = regs->ar_pfs;
135
136        TRACE3(TRACE_SHARED, 2, TRCID_SS_022X,
137               "get_privilege_level: cpl 0x%lX ipsr 0x%lX pfs 0x%lX\n",
138               cpl, ipsr, pfs);
139
140  return cpl;
141}
142
143int
144kxSaveThreadInfo(int tid, void* regP)
145{
146  struct sigcontext *sc = (struct sigcontext *)regP;
147  struct task_struct *g, *p;
148  struct pt_regs *pt;
149  int rc = ENOENT;
150
151  read_lock(&tasklist_lock);
152  DO_EACH_THREAD(g,p)
153  {
154    if (PROCESS_GROUP(current) == PROCESS_GROUP(p) &&
155        current->pid != tid && p->pid == tid)
156    {
157#if LINUX_KERNEL_VERSION > 2061600
158      pt = task_pt_regs(p);
159#else
160      pt = ia64_task_regs(p);
161#endif
162      read_unlock(&tasklist_lock);
163
164      rc = __put_user(pt->cr_iip, &sc->sc_ip);
165      rc |= __put_user(pt->ar_bspstore, &sc->sc_ar_bsp);
166      rc |= __put_user(pt->ar_pfs, &sc->sc_cfm);
167
168      return rc;
169    }
170  } WHILE_EACH_THREAD(g,p);
171  read_unlock(&tasklist_lock);
172  return -1;
173}   
174
175/* TLB flush routines for a single page or an address range.
176   These are not exported by the kernel (like flush_tlb_all)
177   and we want to do this at a finer granularity than flushing
178   the entire TLB cache.
179   The kernel serializes tlb cache flushes with the ptcg_lock,
180   but we don't have access to this. */
181
182void flush_tlb_page_ia64(unsigned long start_addr)
183{
184  unsigned long addr = start_addr & ~(PAGE_SIZE - 1);  /* page align */
185
186  /* ptc commands expect flush size starting at bit 2 of register */
187#ifdef CONFIG_SMP
188  __asm__ __volatile__ ("ptc.ga %0, %1;;"
189                        :
190                        : "r"(addr),
191                          "r"(PAGE_SHIFT << 2)
192                        : "memory");
193#else
194  __asm__ __volatile__ ("ptc.l %0, %1;;"
195                        :
196                        : "r"(addr),
197                          "r"(PAGE_SHIFT << 2)
198                        : "memory");
199#endif /* CONFIG_SMP */ 
200
201  /* need to serialize */
202  __asm__ __volatile__ ("srlz.i;;" : : : "memory");
203}
204
205void flush_tlb_range_ia64(unsigned long start_addr, unsigned long end_addr)
206{
207  unsigned long addr = start_addr & ~(PAGE_SIZE - 1);  /* page align */
208
209  while (addr < end_addr)
210  {
211    /* ptc commands expect flush size starting at bit 2 of register */
212#ifdef CONFIG_SMP
213    __asm__ __volatile__ ("ptc.ga %0, %1;;"
214                          :
215                          : "r"(addr),
216                            "r"(PAGE_SHIFT << 2)
217                          : "memory");
218#else
219    __asm__ __volatile__ ("ptc.l %0, %1;;"
220                          :
221                          : "r"(addr),
222                            "r"(PAGE_SHIFT << 2)
223                          : "memory");
224#endif /* CONFIG_SMP */ 
225
226  /* need to serialize */
227  __asm__ __volatile__ ("srlz.i;;" : : : "memory");
228
229    addr += PAGE_SIZE;
230  }
231}
Note: See TracBrowser for help on using the repository browser.