aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r--arch/parisc/kernel/drivers.c3
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c3
-rw-r--r--arch/parisc/kernel/pci.c13
-rw-r--r--arch/parisc/kernel/perf.c38
-rw-r--r--arch/parisc/kernel/perf_images.h4
-rw-r--r--arch/parisc/kernel/process.c35
-rw-r--r--arch/parisc/kernel/ptrace.c8
-rw-r--r--arch/parisc/kernel/signal.c2
-rw-r--r--arch/parisc/kernel/signal32.c102
-rw-r--r--arch/parisc/kernel/signal32.h127
-rw-r--r--arch/parisc/kernel/syscall.S2
-rw-r--r--arch/parisc/kernel/syscall_table.S19
-rw-r--r--arch/parisc/kernel/traps.c3
13 files changed, 287 insertions, 72 deletions
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index 2d804e2d16d1..3d569a485a1a 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -408,11 +408,10 @@ static void setup_bus_id(struct parisc_device *padev)
408 408
409struct parisc_device * create_tree_node(char id, struct device *parent) 409struct parisc_device * create_tree_node(char id, struct device *parent)
410{ 410{
411 struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL); 411 struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL);
412 if (!dev) 412 if (!dev)
413 return NULL; 413 return NULL;
414 414
415 memset(dev, 0, sizeof(*dev));
416 dev->hw_path = id; 415 dev->hw_path = id;
417 dev->id.hw_type = HPHW_FAULTY; 416 dev->id.hw_type = HPHW_FAULTY;
418 417
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index f40a777dd388..1d00c365f2b1 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -48,9 +48,6 @@ EXPORT_SYMBOL(strrchr);
48EXPORT_SYMBOL(strstr); 48EXPORT_SYMBOL(strstr);
49EXPORT_SYMBOL(strpbrk); 49EXPORT_SYMBOL(strpbrk);
50 50
51#include <linux/pm.h>
52EXPORT_SYMBOL(pm_power_off);
53
54#include <asm/atomic.h> 51#include <asm/atomic.h>
55EXPORT_SYMBOL(__xchg8); 52EXPORT_SYMBOL(__xchg8);
56EXPORT_SYMBOL(__xchg32); 53EXPORT_SYMBOL(__xchg32);
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 88cba49c5301..79c7db2705fd 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -47,18 +47,17 @@
47 * this makes the boot time much longer than necessary. 47 * this makes the boot time much longer than necessary.
48 * 20ms seems to work for all the HP PCI implementations to date. 48 * 20ms seems to work for all the HP PCI implementations to date.
49 * 49 *
50 * XXX: turn into a #defined constant in <asm/pci.h> ? 50 * #define pci_post_reset_delay 50
51 */ 51 */
52int pci_post_reset_delay = 50;
53 52
54struct pci_port_ops *pci_port; 53struct pci_port_ops *pci_port __read_mostly;
55struct pci_bios_ops *pci_bios; 54struct pci_bios_ops *pci_bios __read_mostly;
56 55
57int pci_hba_count = 0; 56static int pci_hba_count __read_mostly;
58 57
59/* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */ 58/* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */
60#define PCI_HBA_MAX 32 59#define PCI_HBA_MAX 32
61struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX]; 60static struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX] __read_mostly;
62 61
63 62
64/******************************************************************** 63/********************************************************************
@@ -259,8 +258,10 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
259void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 258void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
260 struct pci_bus_region *region) 259 struct pci_bus_region *region)
261{ 260{
261#ifdef CONFIG_64BIT
262 struct pci_bus *bus = dev->bus; 262 struct pci_bus *bus = dev->bus;
263 struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data); 263 struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
264#endif
264 265
265 if (res->flags & IORESOURCE_MEM) { 266 if (res->flags & IORESOURCE_MEM) {
266 res->start = PCI_HOST_ADDR(hba, region->start); 267 res->start = PCI_HOST_ADDR(hba, region->start);
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index 11d406cd0b3e..53f861c82f93 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -68,20 +68,20 @@ struct rdr_tbl_ent {
68}; 68};
69 69
70static int perf_processor_interface __read_mostly = UNKNOWN_INTF; 70static int perf_processor_interface __read_mostly = UNKNOWN_INTF;
71static int perf_enabled __read_mostly = 0; 71static int perf_enabled __read_mostly;
72static spinlock_t perf_lock; 72static spinlock_t perf_lock;
73struct parisc_device *cpu_device __read_mostly = NULL; 73struct parisc_device *cpu_device __read_mostly;
74 74
75/* RDRs to write for PCX-W */ 75/* RDRs to write for PCX-W */
76static int perf_rdrs_W[] = 76static const int perf_rdrs_W[] =
77 { 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; 77 { 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
78 78
79/* RDRs to write for PCX-U */ 79/* RDRs to write for PCX-U */
80static int perf_rdrs_U[] = 80static const int perf_rdrs_U[] =
81 { 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; 81 { 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 };
82 82
83/* RDR register descriptions for PCX-W */ 83/* RDR register descriptions for PCX-W */
84static struct rdr_tbl_ent perf_rdr_tbl_W[] = { 84static const struct rdr_tbl_ent perf_rdr_tbl_W[] = {
85 { 19, 1, 8 }, /* RDR 0 */ 85 { 19, 1, 8 }, /* RDR 0 */
86 { 16, 1, 16 }, /* RDR 1 */ 86 { 16, 1, 16 }, /* RDR 1 */
87 { 72, 2, 0 }, /* RDR 2 */ 87 { 72, 2, 0 }, /* RDR 2 */
@@ -117,7 +117,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_W[] = {
117}; 117};
118 118
119/* RDR register descriptions for PCX-U */ 119/* RDR register descriptions for PCX-U */
120static struct rdr_tbl_ent perf_rdr_tbl_U[] = { 120static const struct rdr_tbl_ent perf_rdr_tbl_U[] = {
121 { 19, 1, 8 }, /* RDR 0 */ 121 { 19, 1, 8 }, /* RDR 0 */
122 { 32, 1, 16 }, /* RDR 1 */ 122 { 32, 1, 16 }, /* RDR 1 */
123 { 20, 1, 0 }, /* RDR 2 */ 123 { 20, 1, 0 }, /* RDR 2 */
@@ -156,7 +156,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_U[] = {
156 * A non-zero write_control in the above tables is a byte offset into 156 * A non-zero write_control in the above tables is a byte offset into
157 * this array. 157 * this array.
158 */ 158 */
159static uint64_t perf_bitmasks[] = { 159static const uint64_t perf_bitmasks[] = {
160 0x0000000000000000ul, /* first dbl word must be zero */ 160 0x0000000000000000ul, /* first dbl word must be zero */
161 0xfdffe00000000000ul, /* RDR0 bitmask */ 161 0xfdffe00000000000ul, /* RDR0 bitmask */
162 0x003f000000000000ul, /* RDR1 bitmask */ 162 0x003f000000000000ul, /* RDR1 bitmask */
@@ -173,7 +173,7 @@ static uint64_t perf_bitmasks[] = {
173 * Write control bitmasks for Pa-8700 processor given 173 * Write control bitmasks for Pa-8700 processor given
174 * somethings have changed slightly. 174 * somethings have changed slightly.
175 */ 175 */
176static uint64_t perf_bitmasks_piranha[] = { 176static const uint64_t perf_bitmasks_piranha[] = {
177 0x0000000000000000ul, /* first dbl word must be zero */ 177 0x0000000000000000ul, /* first dbl word must be zero */
178 0xfdffe00000000000ul, /* RDR0 bitmask */ 178 0xfdffe00000000000ul, /* RDR0 bitmask */
179 0x003f000000000000ul, /* RDR1 bitmask */ 179 0x003f000000000000ul, /* RDR1 bitmask */
@@ -186,7 +186,7 @@ static uint64_t perf_bitmasks_piranha[] = {
186 0xfffc000000000000ul 186 0xfffc000000000000ul
187}; 187};
188 188
189static uint64_t *bitmask_array; /* array of bitmasks to use */ 189static const uint64_t *bitmask_array; /* array of bitmasks to use */
190 190
191/****************************************************************************** 191/******************************************************************************
192 * Function Prototypes 192 * Function Prototypes
@@ -200,7 +200,7 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun
200static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 200static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
201static void perf_start_counters(void); 201static void perf_start_counters(void);
202static int perf_stop_counters(uint32_t *raddr); 202static int perf_stop_counters(uint32_t *raddr);
203static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num); 203static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num);
204static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer); 204static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer);
205static int perf_rdr_clear(uint32_t rdr_num); 205static int perf_rdr_clear(uint32_t rdr_num);
206static int perf_write_image(uint64_t *memaddr); 206static int perf_write_image(uint64_t *memaddr);
@@ -444,7 +444,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
444 uint32_t raddr[4]; 444 uint32_t raddr[4];
445 int error = 0; 445 int error = 0;
446 446
447 lock_kernel();
448 switch (cmd) { 447 switch (cmd) {
449 448
450 case PA_PERF_ON: 449 case PA_PERF_ON:
@@ -477,8 +476,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
477 error = -ENOTTY; 476 error = -ENOTTY;
478 } 477 }
479 478
480 unlock_kernel();
481
482 return error; 479 return error;
483} 480}
484 481
@@ -655,7 +652,7 @@ static int perf_stop_counters(uint32_t *raddr)
655 * Retrieve a pointer to the description of what this 652 * Retrieve a pointer to the description of what this
656 * RDR contains. 653 * RDR contains.
657 */ 654 */
658static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num) 655static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num)
659{ 656{
660 if (perf_processor_interface == ONYX_INTF) { 657 if (perf_processor_interface == ONYX_INTF) {
661 return &perf_rdr_tbl_U[rdr_num]; 658 return &perf_rdr_tbl_U[rdr_num];
@@ -673,7 +670,7 @@ static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer)
673{ 670{
674 uint64_t data, data_mask = 0; 671 uint64_t data, data_mask = 0;
675 uint32_t width, xbits, i; 672 uint32_t width, xbits, i;
676 struct rdr_tbl_ent *tentry; 673 const struct rdr_tbl_ent *tentry;
677 674
678 tentry = perf_rdr_get_entry(rdr_num); 675 tentry = perf_rdr_get_entry(rdr_num);
679 if ((width = tentry->width) == 0) 676 if ((width = tentry->width) == 0)
@@ -721,7 +718,7 @@ static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer)
721 */ 718 */
722static int perf_rdr_clear(uint32_t rdr_num) 719static int perf_rdr_clear(uint32_t rdr_num)
723{ 720{
724 struct rdr_tbl_ent *tentry; 721 const struct rdr_tbl_ent *tentry;
725 int32_t i; 722 int32_t i;
726 723
727 tentry = perf_rdr_get_entry(rdr_num); 724 tentry = perf_rdr_get_entry(rdr_num);
@@ -753,10 +750,11 @@ static int perf_write_image(uint64_t *memaddr)
753 uint64_t buffer[MAX_RDR_WORDS]; 750 uint64_t buffer[MAX_RDR_WORDS];
754 uint64_t *bptr; 751 uint64_t *bptr;
755 uint32_t dwords; 752 uint32_t dwords;
756 uint32_t *intrigue_rdr; 753 const uint32_t *intrigue_rdr;
757 uint64_t *intrigue_bitmask, tmp64; 754 const uint64_t *intrigue_bitmask;
755 uint64_t tmp64;
758 void __iomem *runway; 756 void __iomem *runway;
759 struct rdr_tbl_ent *tentry; 757 const struct rdr_tbl_ent *tentry;
760 int i; 758 int i;
761 759
762 /* Clear out counters */ 760 /* Clear out counters */
@@ -830,7 +828,7 @@ static int perf_write_image(uint64_t *memaddr)
830 */ 828 */
831static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer) 829static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer)
832{ 830{
833 struct rdr_tbl_ent *tentry; 831 const struct rdr_tbl_ent *tentry;
834 int32_t i; 832 int32_t i;
835 833
836printk("perf_rdr_write\n"); 834printk("perf_rdr_write\n");
diff --git a/arch/parisc/kernel/perf_images.h b/arch/parisc/kernel/perf_images.h
index d9562fe3f75c..7fef9644df47 100644
--- a/arch/parisc/kernel/perf_images.h
+++ b/arch/parisc/kernel/perf_images.h
@@ -25,7 +25,7 @@
25 25
26#define PCXU_IMAGE_SIZE 584 26#define PCXU_IMAGE_SIZE 584
27 27
28static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = { 28static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = {
29/* 29/*
30 * CPI: 30 * CPI:
31 * 31 *
@@ -2093,7 +2093,7 @@ static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = {
2093}; 2093};
2094#define PCXW_IMAGE_SIZE 576 2094#define PCXW_IMAGE_SIZE 576
2095 2095
2096static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] = { 2096static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = {
2097/* 2097/*
2098 * CPI: FROM CPI.IDF (Image 0) 2098 * CPI: FROM CPI.IDF (Image 0)
2099 * 2099 *
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c
index 5da41677e70b..e8dea4177113 100644
--- a/arch/parisc/kernel/process.c
+++ b/arch/parisc/kernel/process.c
@@ -54,27 +54,6 @@
54#include <asm/uaccess.h> 54#include <asm/uaccess.h>
55#include <asm/unwind.h> 55#include <asm/unwind.h>
56 56
57static int hlt_counter __read_mostly;
58
59/*
60 * Power off function, if any
61 */
62void (*pm_power_off)(void);
63
64void disable_hlt(void)
65{
66 hlt_counter++;
67}
68
69EXPORT_SYMBOL(disable_hlt);
70
71void enable_hlt(void)
72{
73 hlt_counter--;
74}
75
76EXPORT_SYMBOL(enable_hlt);
77
78void default_idle(void) 57void default_idle(void)
79{ 58{
80 barrier(); 59 barrier();
@@ -102,12 +81,7 @@ void cpu_idle(void)
102} 81}
103 82
104 83
105#ifdef __LP64__ 84#define COMMAND_GLOBAL F_EXTEND(0xfffe0030)
106#define COMMAND_GLOBAL 0xfffffffffffe0030UL
107#else
108#define COMMAND_GLOBAL 0xfffe0030
109#endif
110
111#define CMD_RESET 5 /* reset any module */ 85#define CMD_RESET 5 /* reset any module */
112 86
113/* 87/*
@@ -162,6 +136,7 @@ void machine_halt(void)
162 */ 136 */
163} 137}
164 138
139void (*chassis_power_off)(void);
165 140
166/* 141/*
167 * This routine is called from sys_reboot to actually turn off the 142 * This routine is called from sys_reboot to actually turn off the
@@ -170,8 +145,8 @@ void machine_halt(void)
170void machine_power_off(void) 145void machine_power_off(void)
171{ 146{
172 /* If there is a registered power off handler, call it. */ 147 /* If there is a registered power off handler, call it. */
173 if(pm_power_off) 148 if (chassis_power_off)
174 pm_power_off(); 149 chassis_power_off();
175 150
176 /* Put the soft power button back under hardware control. 151 /* Put the soft power button back under hardware control.
177 * If the user had already pressed the power button, the 152 * If the user had already pressed the power button, the
@@ -187,6 +162,8 @@ void machine_power_off(void)
187 KERN_EMERG "Please power this system off now."); 162 KERN_EMERG "Please power this system off now.");
188} 163}
189 164
165void (*pm_power_off)(void) = machine_power_off;
166EXPORT_SYMBOL(pm_power_off);
190 167
191/* 168/*
192 * Create a kernel thread 169 * Create a kernel thread
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 27160e8bf15b..413292f1a4a3 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
91 int copied; 91 int copied;
92 92
93#ifdef __LP64__ 93#ifdef __LP64__
94 if (is_compat_task(child)) { 94 if (personality(child->personality) == PER_LINUX32) {
95 unsigned int tmp; 95 unsigned int tmp;
96 96
97 addr &= 0xffffffffL; 97 addr &= 0xffffffffL;
@@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
123 case PTRACE_POKEDATA: 123 case PTRACE_POKEDATA:
124 ret = 0; 124 ret = 0;
125#ifdef __LP64__ 125#ifdef __LP64__
126 if (is_compat_task(child)) { 126 if (personality(child->personality) == PER_LINUX32) {
127 unsigned int tmp = (unsigned int)data; 127 unsigned int tmp = (unsigned int)data;
128 DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", 128 DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
129 request == PTRACE_POKETEXT ? "TEXT" : "DATA", 129 request == PTRACE_POKETEXT ? "TEXT" : "DATA",
@@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
146 case PTRACE_PEEKUSR: { 146 case PTRACE_PEEKUSR: {
147 ret = -EIO; 147 ret = -EIO;
148#ifdef __LP64__ 148#ifdef __LP64__
149 if (is_compat_task(child)) { 149 if (personality(child->personality) == PER_LINUX32) {
150 unsigned int tmp; 150 unsigned int tmp;
151 151
152 if (addr & (sizeof(int)-1)) 152 if (addr & (sizeof(int)-1))
@@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
205 goto out_tsk; 205 goto out_tsk;
206 } 206 }
207#ifdef __LP64__ 207#ifdef __LP64__
208 if (is_compat_task(child)) { 208 if (personality(child->personality) == PER_LINUX32) {
209 if (addr & (sizeof(int)-1)) 209 if (addr & (sizeof(int)-1))
210 goto out_tsk; 210 goto out_tsk;
211 if ((addr = translate_usr_offset(addr)) < 0) 211 if ((addr = translate_usr_offset(addr)) < 0)
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 3a25a7bd673e..05767e83cf2d 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -317,7 +317,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
317 317
318 if(personality(current->personality) == PER_LINUX32) { 318 if(personality(current->personality) == PER_LINUX32) {
319 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); 319 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
320 err |= compat_copy_siginfo_to_user(&compat_frame->info, info); 320 err |= copy_siginfo_to_user32(&compat_frame->info, info);
321 DBG(1,"SETUP_RT_FRAME: 1\n"); 321 DBG(1,"SETUP_RT_FRAME: 1\n");
322 compat_val = (compat_int_t)current->sas_ss_sp; 322 compat_val = (compat_int_t)current->sas_ss_sp;
323 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp); 323 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp);
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c
index 0792e20efef3..a6b4231cafa1 100644
--- a/arch/parisc/kernel/signal32.c
+++ b/arch/parisc/kernel/signal32.c
@@ -31,7 +31,6 @@
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/errno.h> 32#include <linux/errno.h>
33 33
34#include <asm/compat_signal.h>
35#include <asm/uaccess.h> 34#include <asm/uaccess.h>
36 35
37#include "signal32.h" 36#include "signal32.h"
@@ -398,3 +397,104 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __
398 397
399 return err; 398 return err;
400} 399}
400
401int
402copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
403{
404 unsigned long tmp;
405 int err;
406
407 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
408 return -EFAULT;
409
410 err = __get_user(to->si_signo, &from->si_signo);
411 err |= __get_user(to->si_errno, &from->si_errno);
412 err |= __get_user(to->si_code, &from->si_code);
413
414 if (to->si_code < 0)
415 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
416 else {
417 switch (to->si_code >> 16) {
418 case __SI_CHLD >> 16:
419 err |= __get_user(to->si_utime, &from->si_utime);
420 err |= __get_user(to->si_stime, &from->si_stime);
421 err |= __get_user(to->si_status, &from->si_status);
422 default:
423 err |= __get_user(to->si_pid, &from->si_pid);
424 err |= __get_user(to->si_uid, &from->si_uid);
425 break;
426 case __SI_FAULT >> 16:
427 err |= __get_user(tmp, &from->si_addr);
428 to->si_addr = (void __user *) tmp;
429 break;
430 case __SI_POLL >> 16:
431 err |= __get_user(to->si_band, &from->si_band);
432 err |= __get_user(to->si_fd, &from->si_fd);
433 break;
434 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
435 case __SI_MESGQ >> 16:
436 err |= __get_user(to->si_pid, &from->si_pid);
437 err |= __get_user(to->si_uid, &from->si_uid);
438 err |= __get_user(to->si_int, &from->si_int);
439 break;
440 }
441 }
442 return err;
443}
444
445int
446copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
447{
448 unsigned int addr;
449 int err;
450
451 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
452 return -EFAULT;
453
454 /* If you change siginfo_t structure, please be sure
455 this code is fixed accordingly.
456 It should never copy any pad contained in the structure
457 to avoid security leaks, but must copy the generic
458 3 ints plus the relevant union member.
459 This routine must convert siginfo from 64bit to 32bit as well
460 at the same time. */
461 err = __put_user(from->si_signo, &to->si_signo);
462 err |= __put_user(from->si_errno, &to->si_errno);
463 err |= __put_user((short)from->si_code, &to->si_code);
464 if (from->si_code < 0)
465 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
466 else {
467 switch (from->si_code >> 16) {
468 case __SI_CHLD >> 16:
469 err |= __put_user(from->si_utime, &to->si_utime);
470 err |= __put_user(from->si_stime, &to->si_stime);
471 err |= __put_user(from->si_status, &to->si_status);
472 default:
473 err |= __put_user(from->si_pid, &to->si_pid);
474 err |= __put_user(from->si_uid, &to->si_uid);
475 break;
476 case __SI_FAULT >> 16:
477 /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
478 err |= __put_user(from->_sifields._pad[0], &to->si_addr);
479 break;
480 case __SI_POLL >> 16:
481 err |= __put_user(from->si_band, &to->si_band);
482 err |= __put_user(from->si_fd, &to->si_fd);
483 break;
484 case __SI_TIMER >> 16:
485 err |= __put_user(from->si_tid, &to->si_tid);
486 err |= __put_user(from->si_overrun, &to->si_overrun);
487 addr = (unsigned long) from->si_ptr;
488 err |= __put_user(addr, &to->si_ptr);
489 break;
490 case __SI_RT >> 16: /* Not generated by the kernel as of now. */
491 case __SI_MESGQ >> 16:
492 err |= __put_user(from->si_uid, &to->si_uid);
493 err |= __put_user(from->si_pid, &to->si_pid);
494 addr = (unsigned long) from->si_ptr;
495 err |= __put_user(addr, &to->si_ptr);
496 break;
497 }
498 }
499 return err;
500}
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h
index 4d1569e717cc..e39b38a67a87 100644
--- a/arch/parisc/kernel/signal32.h
+++ b/arch/parisc/kernel/signal32.h
@@ -20,8 +20,34 @@
20#define _PARISC64_KERNEL_SIGNAL32_H 20#define _PARISC64_KERNEL_SIGNAL32_H
21 21
22#include <linux/compat.h> 22#include <linux/compat.h>
23#include <asm/compat_signal.h> 23
24#include <asm/compat_rt_sigframe.h> 24typedef compat_uptr_t compat_sighandler_t;
25
26typedef struct compat_sigaltstack {
27 compat_uptr_t ss_sp;
28 compat_int_t ss_flags;
29 compat_size_t ss_size;
30} compat_stack_t;
31
32/* Most things should be clean enough to redefine this at will, if care
33 is taken to make libc match. */
34
35struct compat_sigaction {
36 compat_sighandler_t sa_handler;
37 compat_uint_t sa_flags;
38 compat_sigset_t sa_mask; /* mask last for extensibility */
39};
40
41/* 32-bit ucontext as seen from an 64-bit kernel */
42struct compat_ucontext {
43 compat_uint_t uc_flags;
44 compat_uptr_t uc_link;
45 compat_stack_t uc_stack; /* struct compat_sigaltstack (12 bytes)*/
46 /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */
47 compat_uint_t pad[1];
48 struct compat_sigcontext uc_mcontext;
49 compat_sigset_t uc_sigmask; /* mask last for extensibility */
50};
25 51
26/* ELF32 signal handling */ 52/* ELF32 signal handling */
27 53
@@ -29,6 +55,103 @@ struct k_sigaction32 {
29 struct compat_sigaction sa; 55 struct compat_sigaction sa;
30}; 56};
31 57
58typedef struct compat_siginfo {
59 int si_signo;
60 int si_errno;
61 int si_code;
62
63 union {
64 int _pad[((128/sizeof(int)) - 3)];
65
66 /* kill() */
67 struct {
68 unsigned int _pid; /* sender's pid */
69 unsigned int _uid; /* sender's uid */
70 } _kill;
71
72 /* POSIX.1b timers */
73 struct {
74 compat_timer_t _tid; /* timer id */
75 int _overrun; /* overrun count */
76 char _pad[sizeof(unsigned int) - sizeof(int)];
77 compat_sigval_t _sigval; /* same as below */
78 int _sys_private; /* not to be passed to user */
79 } _timer;
80
81 /* POSIX.1b signals */
82 struct {
83 unsigned int _pid; /* sender's pid */
84 unsigned int _uid; /* sender's uid */
85 compat_sigval_t _sigval;
86 } _rt;
87
88 /* SIGCHLD */
89 struct {
90 unsigned int _pid; /* which child */
91 unsigned int _uid; /* sender's uid */
92 int _status; /* exit code */
93 compat_clock_t _utime;
94 compat_clock_t _stime;
95 } _sigchld;
96
97 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
98 struct {
99 unsigned int _addr; /* faulting insn/memory ref. */
100 } _sigfault;
101
102 /* SIGPOLL */
103 struct {
104 int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
105 int _fd;
106 } _sigpoll;
107 } _sifields;
108} compat_siginfo_t;
109
110int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from);
111int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from);
112
113/* In a deft move of uber-hackery, we decide to carry the top half of all
114 * 64-bit registers in a non-portable, non-ABI, hidden structure.
115 * Userspace can read the hidden structure if it *wants* but is never
116 * guaranteed to be in the same place. Infact the uc_sigmask from the
117 * ucontext_t structure may push the hidden register file downards
118 */
119struct compat_regfile {
120 /* Upper half of all the 64-bit registers that were truncated
121 on a copy to a 32-bit userspace */
122 compat_int_t rf_gr[32];
123 compat_int_t rf_iasq[2];
124 compat_int_t rf_iaoq[2];
125 compat_int_t rf_sar;
126};
127
128#define COMPAT_SIGRETURN_TRAMP 4
129#define COMPAT_SIGRESTARTBLOCK_TRAMP 5
130#define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \
131 COMPAT_SIGRESTARTBLOCK_TRAMP)
132
133struct compat_rt_sigframe {
134 /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c
135 Secondary to that it must protect the ERESTART_RESTARTBLOCK
136 trampoline we left on the stack (we were bad and didn't
137 change sp so we could run really fast.) */
138 compat_uint_t tramp[COMPAT_TRAMP_SIZE];
139 compat_siginfo_t info;
140 struct compat_ucontext uc;
141 /* Hidden location of truncated registers, *must* be last. */
142 struct compat_regfile regs;
143};
144
145/*
146 * The 32-bit ABI wants at least 48 bytes for a function call frame:
147 * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of
148 * which Linux/parisc uses is sp-20 for the saved return pointer...)
149 * Then, the stack pointer must be rounded to a cache line (64 bytes).
150 */
151#define SIGFRAME32 64
152#define FUNCTIONCALLFRAME32 48
153#define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32)
154
32void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); 155void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
33void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); 156void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
34int do_sigaltstack32 (const compat_stack_t __user *uss32, 157int do_sigaltstack32 (const compat_stack_t __user *uss32,
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index d66163492890..af88afef41bd 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -650,6 +650,8 @@ end_linux_gateway_page:
650#define LWS_ENTRY(_name_) .word (lws_##_name_ - linux_gateway_page) 650#define LWS_ENTRY(_name_) .word (lws_##_name_ - linux_gateway_page)
651#endif 651#endif
652 652
653 .section .rodata,"a"
654
653 .align 4096 655 .align 4096
654 /* Light-weight-syscall table */ 656 /* Light-weight-syscall table */
655 /* Start of lws table. */ 657 /* Start of lws table. */
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 32cbc0489324..51d2480627d1 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -374,5 +374,24 @@
374 ENTRY_SAME(keyctl) 374 ENTRY_SAME(keyctl)
375 ENTRY_SAME(ioprio_set) 375 ENTRY_SAME(ioprio_set)
376 ENTRY_SAME(ioprio_get) 376 ENTRY_SAME(ioprio_get)
377 ENTRY_SAME(inotify_init)
378 ENTRY_SAME(inotify_add_watch) /* 270 */
379 ENTRY_SAME(inotify_rm_watch)
380 ENTRY_COMP(pselect6)
381 ENTRY_COMP(ppoll)
382 ENTRY_SAME(migrate_pages)
383 ENTRY_COMP(openat) /* 275 */
384 ENTRY_SAME(mkdirat)
385 ENTRY_SAME(mknodat)
386 ENTRY_SAME(fchownat)
387 ENTRY_COMP(futimesat)
388 ENTRY_COMP(newfstatat) /* 280 */
389 ENTRY_SAME(unlinkat)
390 ENTRY_SAME(renameat)
391 ENTRY_SAME(linkat)
392 ENTRY_SAME(symlinkat)
393 ENTRY_SAME(readlinkat) /* 285 */
394 ENTRY_SAME(fchmodat)
395 ENTRY_SAME(faccessat)
377 /* Nothing yet */ 396 /* Nothing yet */
378 397
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 15914f0235a0..ff200608c851 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -193,10 +193,9 @@ void show_stack(struct task_struct *task, unsigned long *s)
193 193
194HERE: 194HERE:
195 asm volatile ("copy %%r30, %0" : "=r"(sp)); 195 asm volatile ("copy %%r30, %0" : "=r"(sp));
196 r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL); 196 r = kzalloc(sizeof(struct pt_regs), GFP_KERNEL);
197 if (!r) 197 if (!r)
198 return; 198 return;
199 memset(r, 0, sizeof(struct pt_regs));
200 r->iaoq[0] = (unsigned long)&&HERE; 199 r->iaoq[0] = (unsigned long)&&HERE;
201 r->gr[2] = (unsigned long)__builtin_return_address(0); 200 r->gr[2] = (unsigned long)__builtin_return_address(0);
202 r->gr[30] = sp; 201 r->gr[30] = sp;