OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [s390/] [mm/] [extable.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  arch/s390/mm/extable.c
3
 *
4
 *  S390 version
5
 *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
6
 *    Author(s): Hartmut Penner (hp@de.ibm.com)
7
 *
8
 *  Derived from "arch/i386/mm/extable.c"
9
 */
10
 
11
#include <linux/config.h>
12
#include <linux/module.h>
13
#include <linux/spinlock.h>
14
#include <asm/uaccess.h>
15
 
16
extern const struct exception_table_entry __start___ex_table[];
17
extern const struct exception_table_entry __stop___ex_table[];
18
 
19
static inline unsigned long
20
search_one_table(const struct exception_table_entry *first,
21
                 const struct exception_table_entry *last,
22
                 unsigned long value)
23
{
24
        while (first <= last) {
25
                const struct exception_table_entry *mid;
26
                long diff;
27
 
28
                mid = (last - first) / 2 + first;
29
                diff = mid->insn - value;
30
                if (diff == 0)
31
                        return mid->fixup;
32
                else if (diff < 0)
33
                        first = mid+1;
34
                else
35
                        last = mid-1;
36
        }
37
        return 0;
38
}
39
 
40
extern spinlock_t modlist_lock;
41
 
42
unsigned long
43
search_exception_table(unsigned long addr)
44
{
45
        unsigned long ret = 0;
46
        unsigned long flags;
47
 
48
#ifndef CONFIG_MODULES
49
        addr &= 0x7fffffff;  /* remove amode bit from address */
50
        /* There is only the kernel to search.  */
51
        ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
52
        if (ret) ret = FIX_PSW(ret);
53
        return ret;
54
#else
55
        /* The kernel is the last "module" -- no need to treat it special.  */
56
        struct module *mp;
57
        addr &= 0x7fffffff;  /* remove amode bit from address */
58
 
59
        spin_lock_irqsave(&modlist_lock, flags);
60
        for (mp = module_list; mp != NULL; mp = mp->next) {
61
                if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
62
                        continue;
63
                ret = search_one_table(mp->ex_table_start,
64
                                       mp->ex_table_end - 1, addr);
65
                if (ret) {
66
                        ret = FIX_PSW(ret);
67
                        break;
68
                }
69
        }
70
        spin_unlock_irqrestore(&modlist_lock, flags);
71
        return ret;
72
#endif
73
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.