Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 275604
b: refs/heads/master
c: 860ca0e
h: refs/heads/master
v: v3
  • Loading branch information
Paul Menage authored and Tejun Heo committed Nov 18, 2011
1 parent 650a200 commit 17af5a1
Show file tree
Hide file tree
Showing 32 changed files with 358 additions and 311 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5c6b4e84cbc59996bb14f88d997870751d675f3f
refs/heads/master: 860ca0e6f72d21ded33ce14be9a53eb103f88441
3 changes: 2 additions & 1 deletion trunk/MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -1927,10 +1927,11 @@ S: Maintained
F: drivers/connector/

CONTROL GROUPS (CGROUPS)
M: Paul Menage <paul@paulmenage.org>
M: Tejun Heo <tj@kernel.org>
M: Li Zefan <lizf@cn.fujitsu.com>
L: containers@lists.linux-foundation.org
L: cgroups@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git
S: Maintained
F: include/linux/cgroup*
F: kernel/cgroup*
Expand Down
20 changes: 4 additions & 16 deletions trunk/arch/sparc/include/asm/pgtable_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ extern unsigned long *sparc_valid_addr_bitmap;
#define kern_addr_valid(addr) \
(test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))

extern int io_remap_pfn_range(struct vm_area_struct *vma,
unsigned long from, unsigned long pfn,
unsigned long size, pgprot_t prot);

/*
* For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
* its high 4 bits. These macros/functions put it there or get it from there.
Expand All @@ -439,22 +443,6 @@ extern unsigned long *sparc_valid_addr_bitmap;
#define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4))
#define GET_PFN(pfn) (pfn & 0x0fffffffUL)

extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
unsigned long, pgprot_t);

static inline int io_remap_pfn_range(struct vm_area_struct *vma,
unsigned long from, unsigned long pfn,
unsigned long size, pgprot_t prot)
{
unsigned long long offset, space, phys_base;

offset = ((unsigned long long) GET_PFN(pfn)) << PAGE_SHIFT;
space = GET_IOSPACE(pfn);
phys_base = offset | (space << 32ULL);

return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
}

#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
({ \
Expand Down
20 changes: 4 additions & 16 deletions trunk/arch/sparc/include/asm/pgtable_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,10 @@ static inline bool kern_addr_valid(unsigned long addr)

extern int page_in_phys_avail(unsigned long paddr);

extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long pfn,
unsigned long size, pgprot_t prot);

/*
* For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
* its high 4 bits. These macros/functions put it there or get it from there.
Expand All @@ -765,22 +769,6 @@ extern int page_in_phys_avail(unsigned long paddr);
#define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4))
#define GET_PFN(pfn) (pfn & 0x0fffffffffffffffUL)

extern int remap_pfn_range(struct vm_area_struct *, unsigned long, unsigned long,
unsigned long, pgprot_t);

static inline int io_remap_pfn_range(struct vm_area_struct *vma,
unsigned long from, unsigned long pfn,
unsigned long size, pgprot_t prot)
{
unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
int space = GET_IOSPACE(pfn);
unsigned long phys_base;

phys_base = offset | (((unsigned long) space) << 32UL);

return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
}

#include <asm-generic/pgtable.h>

/* We provide our own get_unmapped_area to cope with VA holes and
Expand Down
7 changes: 0 additions & 7 deletions trunk/arch/sparc/kernel/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
extern void fpload(unsigned long *fpregs, unsigned long *fsr);

#else /* CONFIG_SPARC32 */

#include <asm/trap_block.h>

struct popc_3insn_patch_entry {
unsigned int addr;
unsigned int insns[3];
Expand All @@ -60,10 +57,6 @@ extern struct popc_6insn_patch_entry __popc_6insn_patch,
__popc_6insn_patch_end;

extern void __init per_cpu_patch(void);
extern void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *,
struct sun4v_1insn_patch_entry *);
extern void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *,
struct sun4v_2insn_patch_entry *);
extern void __init sun4v_patch(void);
extern void __init boot_cpu_id_too_large(int cpu);
extern unsigned int dcache_parity_tl1_occurred;
Expand Down
27 changes: 0 additions & 27 deletions trunk/arch/sparc/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#include <asm/processor.h>
#include <asm/spitfire.h>

#include "entry.h"

#ifdef CONFIG_SPARC64

#include <linux/jump_label.h>
Expand Down Expand Up @@ -205,38 +203,13 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
}

#ifdef CONFIG_SPARC64
static void do_patch_sections(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs)
{
const Elf_Shdr *s, *sun4v_1insn = NULL, *sun4v_2insn = NULL;
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;

for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
if (!strcmp(".sun4v_1insn_patch", secstrings + s->sh_name))
sun4v_1insn = s;
if (!strcmp(".sun4v_2insn_patch", secstrings + s->sh_name))
sun4v_2insn = s;
}

if (sun4v_1insn && tlb_type == hypervisor) {
void *p = (void *) sun4v_1insn->sh_addr;
sun4v_patch_1insn_range(p, p + sun4v_1insn->sh_size);
}
if (sun4v_2insn && tlb_type == hypervisor) {
void *p = (void *) sun4v_2insn->sh_addr;
sun4v_patch_2insn_range(p, p + sun4v_2insn->sh_size);
}
}

int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
/* make jump label nops */
jump_label_apply_nops(me);

do_patch_sections(hdr, sechdrs);

/* Cheetah's I-cache is fully coherent. */
if (tlb_type == spitfire) {
unsigned long va;
Expand Down
48 changes: 19 additions & 29 deletions trunk/arch/sparc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,50 +234,40 @@ void __init per_cpu_patch(void)
}
}

void sun4v_patch_1insn_range(struct sun4v_1insn_patch_entry *start,
struct sun4v_1insn_patch_entry *end)
void __init sun4v_patch(void)
{
while (start < end) {
unsigned long addr = start->addr;
extern void sun4v_hvapi_init(void);
struct sun4v_1insn_patch_entry *p1;
struct sun4v_2insn_patch_entry *p2;

if (tlb_type != hypervisor)
return;

*(unsigned int *) (addr + 0) = start->insn;
p1 = &__sun4v_1insn_patch;
while (p1 < &__sun4v_1insn_patch_end) {
unsigned long addr = p1->addr;

*(unsigned int *) (addr + 0) = p1->insn;
wmb();
__asm__ __volatile__("flush %0" : : "r" (addr + 0));

start++;
p1++;
}
}

void sun4v_patch_2insn_range(struct sun4v_2insn_patch_entry *start,
struct sun4v_2insn_patch_entry *end)
{
while (start < end) {
unsigned long addr = start->addr;
p2 = &__sun4v_2insn_patch;
while (p2 < &__sun4v_2insn_patch_end) {
unsigned long addr = p2->addr;

*(unsigned int *) (addr + 0) = start->insns[0];
*(unsigned int *) (addr + 0) = p2->insns[0];
wmb();
__asm__ __volatile__("flush %0" : : "r" (addr + 0));

*(unsigned int *) (addr + 4) = start->insns[1];
*(unsigned int *) (addr + 4) = p2->insns[1];
wmb();
__asm__ __volatile__("flush %0" : : "r" (addr + 4));

start++;
p2++;
}
}

void __init sun4v_patch(void)
{
extern void sun4v_hvapi_init(void);

if (tlb_type != hypervisor)
return;

sun4v_patch_1insn_range(&__sun4v_1insn_patch,
&__sun4v_1insn_patch_end);

sun4v_patch_2insn_range(&__sun4v_2insn_patch,
&__sun4v_2insn_patch_end);

sun4v_hvapi_init();
}
Expand Down
18 changes: 8 additions & 10 deletions trunk/arch/sparc/kernel/signal32.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,23 +822,21 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
* want to handle. Thus you cannot kill init even with a SIGKILL even by
* mistake.
*/
void do_signal32(sigset_t *oldset, struct pt_regs * regs)
void do_signal32(sigset_t *oldset, struct pt_regs * regs,
int restart_syscall, unsigned long orig_i0)
{
struct k_sigaction ka;
unsigned long orig_i0;
int restart_syscall;
siginfo_t info;
int signr;

signr = get_signal_to_deliver(&info, &ka, regs, NULL);

restart_syscall = 0;
orig_i0 = 0;
if (pt_regs_is_syscall(regs) &&
(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
restart_syscall = 1;
orig_i0 = regs->u_regs[UREG_G6];
}
/* If the debugger messes with the program counter, it clears
* the "in syscall" bit, directing us to not perform a syscall
* restart.
*/
if (restart_syscall && !pt_regs_is_syscall(regs))
restart_syscall = 0;

if (signr > 0) {
if (restart_syscall)
Expand Down
30 changes: 5 additions & 25 deletions trunk/arch/sparc/kernel/signal_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,26 +519,10 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
siginfo_t info;
int signr;

/* It's a lot of work and synchronization to add a new ptrace
* register for GDB to save and restore in order to get
* orig_i0 correct for syscall restarts when debugging.
*
* Although it should be the case that most of the global
* registers are volatile across a system call, glibc already
* depends upon that fact that we preserve them. So we can't
* just use any global register to save away the orig_i0 value.
*
* In particular %g2, %g3, %g4, and %g5 are all assumed to be
* preserved across a system call trap by various pieces of
* code in glibc.
*
* %g7 is used as the "thread register". %g6 is not used in
* any fixed manner. %g6 is used as a scratch register and
* a compiler temporary, but it's value is never used across
* a system call. Therefore %g6 is usable for orig_i0 storage.
*/
if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
regs->u_regs[UREG_G6] = orig_i0;
restart_syscall = 1;
else
restart_syscall = 0;

if (test_thread_flag(TIF_RESTORE_SIGMASK))
oldset = &current->saved_sigmask;
Expand All @@ -551,12 +535,8 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
* the software "in syscall" bit, directing us to not perform
* a syscall restart.
*/
restart_syscall = 0;
if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) {
restart_syscall = 1;
orig_i0 = regs->u_regs[UREG_G6];
}

if (restart_syscall && !pt_regs_is_syscall(regs))
restart_syscall = 0;

if (signr > 0) {
if (restart_syscall)
Expand Down
42 changes: 14 additions & 28 deletions trunk/arch/sparc/kernel/signal_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,27 +529,11 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
siginfo_t info;
int signr;

/* It's a lot of work and synchronization to add a new ptrace
* register for GDB to save and restore in order to get
* orig_i0 correct for syscall restarts when debugging.
*
* Although it should be the case that most of the global
* registers are volatile across a system call, glibc already
* depends upon that fact that we preserve them. So we can't
* just use any global register to save away the orig_i0 value.
*
* In particular %g2, %g3, %g4, and %g5 are all assumed to be
* preserved across a system call trap by various pieces of
* code in glibc.
*
* %g7 is used as the "thread register". %g6 is not used in
* any fixed manner. %g6 is used as a scratch register and
* a compiler temporary, but it's value is never used across
* a system call. Therefore %g6 is usable for orig_i0 storage.
*/
if (pt_regs_is_syscall(regs) &&
(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
regs->u_regs[UREG_G6] = orig_i0;
(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
restart_syscall = 1;
} else
restart_syscall = 0;

if (current_thread_info()->status & TS_RESTORE_SIGMASK)
oldset = &current->saved_sigmask;
Expand All @@ -558,20 +542,22 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)

#ifdef CONFIG_COMPAT
if (test_thread_flag(TIF_32BIT)) {
extern void do_signal32(sigset_t *, struct pt_regs *);
do_signal32(oldset, regs);
extern void do_signal32(sigset_t *, struct pt_regs *,
int restart_syscall,
unsigned long orig_i0);
do_signal32(oldset, regs, restart_syscall, orig_i0);
return;
}
#endif

signr = get_signal_to_deliver(&info, &ka, regs, NULL);

restart_syscall = 0;
if (pt_regs_is_syscall(regs) &&
(regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
restart_syscall = 1;
orig_i0 = regs->u_regs[UREG_G6];
}
/* If the debugger messes with the program counter, it clears
* the software "in syscall" bit, directing us to not perform
* a syscall restart.
*/
if (restart_syscall && !pt_regs_is_syscall(regs))
restart_syscall = 0;

if (signr > 0) {
if (restart_syscall)
Expand Down
1 change: 0 additions & 1 deletion trunk/arch/sparc/kernel/sigutil_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <linux/types.h>
#include <linux/thread_info.h>
#include <linux/uaccess.h>
#include <linux/errno.h>

#include <asm/sigcontext.h>
#include <asm/fpumacro.h>
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/sparc/mm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ obj-$(CONFIG_SPARC64) += ultra.o tlb.o tsb.o gup.o
obj-y += fault_$(BITS).o
obj-y += init_$(BITS).o
obj-$(CONFIG_SPARC32) += loadmmu.o
obj-y += generic_$(BITS).o
obj-$(CONFIG_SPARC32) += extable.o btfixup.o srmmu.o iommu.o io-unit.o
obj-$(CONFIG_SPARC32) += hypersparc.o viking.o tsunami.o swift.o
obj-$(CONFIG_SPARC_LEON)+= leon_mm.o
Expand Down
Loading

0 comments on commit 17af5a1

Please sign in to comment.