Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
b4edf06c
Commit
b4edf06c
authored
Jul 16, 2020
by
Al Viro
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sparc32: switch to generic extables
Signed-off-by:
Al Viro
<
viro@zeniv.linux.org.uk
>
parent
c4da8e0d
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
22 additions
and
170 deletions
+22
-170
arch/sparc/include/asm/elf_64.h
arch/sparc/include/asm/elf_64.h
+0
-1
arch/sparc/include/asm/extable.h
arch/sparc/include/asm/extable.h
+2
-2
arch/sparc/include/asm/uaccess.h
arch/sparc/include/asm/uaccess.h
+3
-0
arch/sparc/include/asm/uaccess_32.h
arch/sparc/include/asm/uaccess_32.h
+0
-33
arch/sparc/include/asm/uaccess_64.h
arch/sparc/include/asm/uaccess_64.h
+0
-1
arch/sparc/kernel/unaligned_32.c
arch/sparc/kernel/unaligned_32.c
+5
-5
arch/sparc/mm/Makefile
arch/sparc/mm/Makefile
+1
-1
arch/sparc/mm/extable.c
arch/sparc/mm/extable.c
+0
-107
arch/sparc/mm/fault_32.c
arch/sparc/mm/fault_32.c
+11
-15
lib/extable.c
lib/extable.c
+0
-5
No files found.
arch/sparc/include/asm/elf_64.h
View file @
b4edf06c
...
...
@@ -8,7 +8,6 @@
#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/extable_64.h>
#include <asm/spitfire.h>
#include <asm/adi.h>
...
...
arch/sparc/include/asm/extable
_64
.h
→
arch/sparc/include/asm/extable.h
View file @
b4edf06c
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_EXTABLE
64
_H
#define __ASM_EXTABLE
64
_H
#ifndef __ASM_EXTABLE_H
#define __ASM_EXTABLE_H
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
...
...
arch/sparc/include/asm/uaccess.h
View file @
b4edf06c
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef ___ASM_SPARC_UACCESS_H
#define ___ASM_SPARC_UACCESS_H
#include <asm/extable.h>
#if defined(__sparc__) && defined(__arch64__)
#include <asm/uaccess_64.h>
#else
...
...
arch/sparc/include/asm/uaccess_32.h
View file @
b4edf06c
...
...
@@ -13,9 +13,6 @@
#include <asm/processor.h>
#define ARCH_HAS_SORT_EXTABLE
#define ARCH_HAS_SEARCH_EXTABLE
/* Sparc is not segmented, however we need to be able to fool access_ok()
* when doing system calls from kernel mode legitimately.
*
...
...
@@ -40,36 +37,6 @@
#define __access_ok(addr, size) (__user_ok((addr) & get_fs().seg, (size)))
#define access_ok(addr, size) __access_ok((unsigned long)(addr), size)
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
* the address at which the program should continue. No registers are
* modified, so it is entirely up to the continuation code to figure out
* what to do.
*
* All the routines below use bits of fixup code that are out of line
* with the main instruction path. This means when everything is well,
* we don't even have to jump over them. Further, they do not intrude
* on our cache or tlb entries.
*
* There is a special way how to put a range of potentially faulting
* insns (like twenty ldd/std's with now intervening other instructions)
* You specify address of first in insn and 0 in fixup and in the next
* exception_table_entry you specify last potentially faulting insn + 1
* and in fixup the routine which should handle the fault.
* That fixup code will get
* (faulting_insn_address - first_insn_in_the_range_address)/4
* in %g2 (ie. index of the faulting instruction in the range).
*/
struct
exception_table_entry
{
unsigned
long
insn
,
fixup
;
};
/* Returns 0 if exception not found and fixup otherwise. */
unsigned
long
search_extables_range
(
unsigned
long
addr
,
unsigned
long
*
g2
);
/* Uh, these should become the main single-value transfer routines..
* They automatically use the right size if we just have the right
* pointer type..
...
...
arch/sparc/include/asm/uaccess_64.h
View file @
b4edf06c
...
...
@@ -10,7 +10,6 @@
#include <linux/string.h>
#include <asm/asi.h>
#include <asm/spitfire.h>
#include <asm/extable_64.h>
#include <asm/processor.h>
...
...
arch/sparc/kernel/unaligned_32.c
View file @
b4edf06c
...
...
@@ -16,6 +16,7 @@
#include <linux/uaccess.h>
#include <linux/smp.h>
#include <linux/perf_event.h>
#include <linux/extable.h>
#include <asm/setup.h>
...
...
@@ -213,10 +214,10 @@ static inline int ok_for_kernel(unsigned int insn)
static
void
kernel_mna_trap_fault
(
struct
pt_regs
*
regs
,
unsigned
int
insn
)
{
unsigned
long
g2
=
regs
->
u_regs
[
UREG_G2
];
unsigned
long
fixup
=
search_extables_range
(
regs
->
pc
,
&
g2
);
const
struct
exception_table_entry
*
entry
;
if
(
!
fixup
)
{
entry
=
search_exception_tables
(
regs
->
pc
);
if
(
!
entry
)
{
unsigned
long
address
=
compute_effective_address
(
regs
,
insn
);
if
(
address
<
PAGE_SIZE
)
{
printk
(
KERN_ALERT
"Unable to handle kernel NULL pointer dereference in mna handler"
);
...
...
@@ -232,9 +233,8 @@ static void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn)
die_if_kernel
(
"Oops"
,
regs
);
/* Not reached */
}
regs
->
pc
=
fixup
;
regs
->
pc
=
entry
->
fixup
;
regs
->
npc
=
regs
->
pc
+
4
;
regs
->
u_regs
[
UREG_G2
]
=
g2
;
}
asmlinkage
void
kernel_unaligned_trap
(
struct
pt_regs
*
regs
,
unsigned
int
insn
)
...
...
arch/sparc/mm/Makefile
View file @
b4edf06c
...
...
@@ -8,7 +8,7 @@ ccflags-y := -Werror
obj-$(CONFIG_SPARC64)
+=
ultra.o tlb.o tsb.o
obj-y
+=
fault_
$(BITS)
.o
obj-y
+=
init_
$(BITS)
.o
obj-$(CONFIG_SPARC32)
+=
extable.o
srmmu.o iommu.o io-unit.o
obj-$(CONFIG_SPARC32)
+=
srmmu.o iommu.o io-unit.o
obj-$(CONFIG_SPARC32)
+=
srmmu_access.o
obj-$(CONFIG_SPARC32)
+=
hypersparc.o viking.o tsunami.o swift.o
obj-$(CONFIG_SPARC32)
+=
leon_mm.o
...
...
arch/sparc/mm/extable.c
deleted
100644 → 0
View file @
c4da8e0d
// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/sparc/mm/extable.c
*/
#include <linux/module.h>
#include <linux/extable.h>
#include <linux/uaccess.h>
void
sort_extable
(
struct
exception_table_entry
*
start
,
struct
exception_table_entry
*
finish
)
{
}
/* Caller knows they are in a range if ret->fixup == 0 */
const
struct
exception_table_entry
*
search_extable
(
const
struct
exception_table_entry
*
base
,
const
size_t
num
,
unsigned
long
value
)
{
int
i
;
/* Single insn entries are encoded as:
* word 1: insn address
* word 2: fixup code address
*
* Range entries are encoded as:
* word 1: first insn address
* word 2: 0
* word 3: last insn address + 4 bytes
* word 4: fixup code address
*
* Deleted entries are encoded as:
* word 1: unused
* word 2: -1
*
* See asm/uaccess.h for more details.
*/
/* 1. Try to find an exact match. */
for
(
i
=
0
;
i
<
num
;
i
++
)
{
if
(
base
[
i
].
fixup
==
0
)
{
/* A range entry, skip both parts. */
i
++
;
continue
;
}
/* A deleted entry; see trim_init_extable */
if
(
base
[
i
].
fixup
==
-
1
)
continue
;
if
(
base
[
i
].
insn
==
value
)
return
&
base
[
i
];
}
/* 2. Try to find a range match. */
for
(
i
=
0
;
i
<
(
num
-
1
);
i
++
)
{
if
(
base
[
i
].
fixup
)
continue
;
if
(
base
[
i
].
insn
<=
value
&&
base
[
i
+
1
].
insn
>
value
)
return
&
base
[
i
];
i
++
;
}
return
NULL
;
}
#ifdef CONFIG_MODULES
/* We could memmove them around; easier to mark the trimmed ones. */
void
trim_init_extable
(
struct
module
*
m
)
{
unsigned
int
i
;
bool
range
;
for
(
i
=
0
;
i
<
m
->
num_exentries
;
i
+=
range
?
2
:
1
)
{
range
=
m
->
extable
[
i
].
fixup
==
0
;
if
(
within_module_init
(
m
->
extable
[
i
].
insn
,
m
))
{
m
->
extable
[
i
].
fixup
=
-
1
;
if
(
range
)
m
->
extable
[
i
+
1
].
fixup
=
-
1
;
}
if
(
range
)
i
++
;
}
}
#endif
/* CONFIG_MODULES */
/* Special extable search, which handles ranges. Returns fixup */
unsigned
long
search_extables_range
(
unsigned
long
addr
,
unsigned
long
*
g2
)
{
const
struct
exception_table_entry
*
entry
;
entry
=
search_exception_tables
(
addr
);
if
(
!
entry
)
return
0
;
/* Inside range? Fix g2 and return correct fixup */
if
(
!
entry
->
fixup
)
{
*
g2
=
(
addr
-
entry
->
insn
)
/
4
;
return
(
entry
+
1
)
->
fixup
;
}
return
entry
->
fixup
;
}
arch/sparc/mm/fault_32.c
View file @
b4edf06c
...
...
@@ -23,6 +23,7 @@
#include <linux/interrupt.h>
#include <linux/kdebug.h>
#include <linux/uaccess.h>
#include <linux/extable.h>
#include <asm/page.h>
#include <asm/openprom.h>
...
...
@@ -114,8 +115,6 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
struct
vm_area_struct
*
vma
;
struct
task_struct
*
tsk
=
current
;
struct
mm_struct
*
mm
=
tsk
->
mm
;
unsigned
int
fixup
;
unsigned
long
g2
;
int
from_user
=
!
(
regs
->
psr
&
PSR_PS
);
int
code
;
vm_fault_t
fault
;
...
...
@@ -233,22 +232,19 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
/* Is this in ex_table? */
no_context:
g2
=
regs
->
u_regs
[
UREG_G2
];
if
(
!
from_user
)
{
fixup
=
search_extables_range
(
regs
->
pc
,
&
g2
)
;
/* Values below 10 are reserved for other things */
if
(
fixup
>
10
)
{
const
struct
exception_table_entry
*
entry
;
entry
=
search_exception_tables
(
regs
->
pc
);
#ifdef DEBUG_EXCEPTIONS
printk
(
"Exception: PC<%08lx> faddr<%08lx>
\n
"
,
regs
->
pc
,
address
);
printk
(
"EX_TABLE: insn<%08lx> fixup<%08x> g2<%08l
x>
\n
"
,
regs
->
pc
,
fixup
,
g2
);
printk
(
"Exception: PC<%08lx> faddr<%08lx>
\n
"
,
regs
->
pc
,
address
);
printk
(
"EX_TABLE: insn<%08lx> fixup<%08
x>
\n
"
,
regs
->
pc
,
entry
->
fixup
);
#endif
regs
->
u_regs
[
UREG_G2
]
=
g2
;
regs
->
pc
=
fixup
;
regs
->
npc
=
regs
->
pc
+
4
;
return
;
}
regs
->
pc
=
entry
->
fixup
;
regs
->
npc
=
regs
->
pc
+
4
;
return
;
}
unhandled_fault
(
address
,
tsk
,
regs
);
...
...
lib/extable.c
View file @
b4edf06c
...
...
@@ -21,7 +21,6 @@ static inline unsigned long ex_to_insn(const struct exception_table_entry *x)
}
#endif
#ifndef ARCH_HAS_SORT_EXTABLE
#ifndef ARCH_HAS_RELATIVE_EXTABLE
#define swap_ex NULL
#else
...
...
@@ -88,9 +87,6 @@ void trim_init_extable(struct module *m)
m
->
num_exentries
--
;
}
#endif
/* CONFIG_MODULES */
#endif
/* !ARCH_HAS_SORT_EXTABLE */
#ifndef ARCH_HAS_SEARCH_EXTABLE
static
int
cmp_ex_search
(
const
void
*
key
,
const
void
*
elt
)
{
...
...
@@ -120,4 +116,3 @@ search_extable(const struct exception_table_entry *base,
return
bsearch
(
&
value
,
base
,
num
,
sizeof
(
struct
exception_table_entry
),
cmp_ex_search
);
}
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment