Skip to content

Commit 1a5304f

Browse files
committed
Merge tag 'parisc-for-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc updates from Helge Deller: "Two important fixes in here: - The argument pointer register was wrong when calling 64-bit firmware functions, which may cause random memory corruption or crashes. - Ensure page alignment in cache flush functions, otherwise not all memory might get flushed. The rest are cleanups (mmap implementation, panic path) and usual smaller updates. Summary: - Calculate correct argument pointer in real64_call_asm() - Cleanup mmap implementation regarding color alignment (John David Anglin) - Spinlock fixes in panic path (Guilherme G. Piccoli) - build doc update for parisc64 (Randy Dunlap) - Ensure page alignment in flush functions" * tag 'parisc-for-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: Fix argument pointer in real64_call_asm() parisc: Cleanup mmap implementation regarding color alignment parisc: Drop HP-UX constants and structs from grfioctl.h parisc: Ensure page alignment in flush functions parisc: Replace regular spinlock with spin_trylock on panic path parisc: update kbuild doc. aliases for parisc64 parisc: Limit amount of kgdb breakpoints on parisc
2 parents b408242 + 6e3220b commit 1a5304f

9 files changed

Lines changed: 104 additions & 154 deletions

File tree

Documentation/kbuild/kbuild.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ directory name found in the arch/ directory.
160160
But some architectures such as x86 and sparc have aliases.
161161

162162
- x86: i386 for 32 bit, x86_64 for 64 bit
163+
- parisc: parisc64 for 64 bit
163164
- sparc: sparc32 for 32 bit, sparc64 for 64 bit
164165

165166
CROSS_COMPILE

arch/parisc/include/asm/grfioctl.h

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -59,42 +59,4 @@
5959
#define CRT_ID_LEGO 0x35ACDA30 /* Lego FX5, FX10 ... */
6060
#define CRT_ID_PINNACLE 0x35ACDA16 /* Pinnacle FXe */
6161

62-
/* structure for ioctl(GCDESCRIBE) */
63-
64-
#define gaddr_t unsigned long /* FIXME: PA2.0 (64bit) portable ? */
65-
66-
struct grf_fbinfo {
67-
unsigned int id; /* upper 32 bits of graphics id */
68-
unsigned int mapsize; /* mapped size of framebuffer */
69-
unsigned int dwidth, dlength;/* x and y sizes */
70-
unsigned int width, length; /* total x and total y size */
71-
unsigned int xlen; /* x pitch size */
72-
unsigned int bpp, bppu; /* bits per pixel and used bpp */
73-
unsigned int npl, nplbytes; /* # of planes and bytes per plane */
74-
char name[32]; /* name of the device (from ROM) */
75-
unsigned int attr; /* attributes */
76-
gaddr_t fbbase, regbase;/* framebuffer and register base addr */
77-
gaddr_t regions[6]; /* region bases */
78-
};
79-
80-
#define GCID _IOR('G', 0, int)
81-
#define GCON _IO('G', 1)
82-
#define GCOFF _IO('G', 2)
83-
#define GCAON _IO('G', 3)
84-
#define GCAOFF _IO('G', 4)
85-
#define GCMAP _IOWR('G', 5, int)
86-
#define GCUNMAP _IOWR('G', 6, int)
87-
#define GCMAP_HPUX _IO('G', 5)
88-
#define GCUNMAP_HPUX _IO('G', 6)
89-
#define GCLOCK _IO('G', 7)
90-
#define GCUNLOCK _IO('G', 8)
91-
#define GCLOCK_MINIMUM _IO('G', 9)
92-
#define GCUNLOCK_MINIMUM _IO('G', 10)
93-
#define GCSTATIC_CMAP _IO('G', 11)
94-
#define GCVARIABLE_CMAP _IO('G', 12)
95-
#define GCTERM _IOWR('G',20,int) /* multi-headed Tomcat */
96-
#define GCDESCRIBE _IOR('G', 21, struct grf_fbinfo)
97-
#define GCFASTLOCK _IO('G', 26)
98-
9962
#endif /* __ASM_PARISC_GRFIOCTL_H */
100-

arch/parisc/include/asm/kgdb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#define NUMREGBYTES sizeof(struct parisc_gdb_regs)
1818
#define BUFMAX 4096
1919

20+
#define KGDB_MAX_BREAKPOINTS 40
21+
2022
#define CACHE_FLUSH_IS_SAFE 1
2123

2224
#ifndef __ASSEMBLY__

arch/parisc/include/asm/pdc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
8080
int pdc_do_reset(void);
8181
int pdc_soft_power_info(unsigned long *power_reg);
8282
int pdc_soft_power_button(int sw_control);
83+
int pdc_soft_power_button_panic(int sw_control);
8384
void pdc_io_reset(void);
8485
void pdc_io_reset_devices(void);
8586
int pdc_iodc_getc(void);

arch/parisc/kernel/firmware.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,15 +1232,18 @@ int __init pdc_soft_power_info(unsigned long *power_reg)
12321232
}
12331233

12341234
/*
1235-
* pdc_soft_power_button - Control the soft power button behaviour
1236-
* @sw_control: 0 for hardware control, 1 for software control
1235+
* pdc_soft_power_button{_panic} - Control the soft power button behaviour
1236+
* @sw_control: 0 for hardware control, 1 for software control
12371237
*
12381238
*
12391239
* This PDC function places the soft power button under software or
12401240
* hardware control.
1241-
* Under software control the OS may control to when to allow to shut
1242-
* down the system. Under hardware control pressing the power button
1241+
* Under software control the OS may control to when to allow to shut
1242+
* down the system. Under hardware control pressing the power button
12431243
* powers off the system immediately.
1244+
*
1245+
* The _panic version relies on spin_trylock to prevent deadlock
1246+
* on panic path.
12441247
*/
12451248
int pdc_soft_power_button(int sw_control)
12461249
{
@@ -1254,6 +1257,22 @@ int pdc_soft_power_button(int sw_control)
12541257
return retval;
12551258
}
12561259

1260+
int pdc_soft_power_button_panic(int sw_control)
1261+
{
1262+
int retval;
1263+
unsigned long flags;
1264+
1265+
if (!spin_trylock_irqsave(&pdc_lock, flags)) {
1266+
pr_emerg("Couldn't enable soft power button\n");
1267+
return -EBUSY; /* ignored by the panic notifier */
1268+
}
1269+
1270+
retval = mem_pdc_call(PDC_SOFT_POWER, PDC_SOFT_POWER_ENABLE, __pa(pdc_result), sw_control);
1271+
spin_unlock_irqrestore(&pdc_lock, flags);
1272+
1273+
return retval;
1274+
}
1275+
12571276
/*
12581277
* pdc_io_reset - Hack to avoid overlapping range registers of Bridges devices.
12591278
* Primarily a problem on T600 (which parisc-linux doesn't support) but

arch/parisc/kernel/pacache.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,7 @@ ENDPROC_CFI(flush_icache_page_asm)
889889
ENTRY_CFI(flush_kernel_dcache_page_asm)
890890
88: ldil L%dcache_stride, %r1
891891
ldw R%dcache_stride(%r1), %r23
892+
depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */
892893

893894
#ifdef CONFIG_64BIT
894895
depdi,z 1, 63-PAGE_SHIFT,1, %r25
@@ -925,6 +926,7 @@ ENDPROC_CFI(flush_kernel_dcache_page_asm)
925926
ENTRY_CFI(purge_kernel_dcache_page_asm)
926927
88: ldil L%dcache_stride, %r1
927928
ldw R%dcache_stride(%r1), %r23
929+
depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */
928930

929931
#ifdef CONFIG_64BIT
930932
depdi,z 1, 63-PAGE_SHIFT,1, %r25

arch/parisc/kernel/real2.S

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,6 @@ ENTRY_CFI(real64_call_asm)
235235
/* save fn */
236236
copy %arg2, %r31
237237

238-
/* set up the new ap */
239-
ldo 64(%arg1), %r29
240-
241238
/* load up the arg registers from the saved arg area */
242239
/* 32-bit calling convention passes first 4 args in registers */
243240
ldd 0*REG_SZ(%arg1), %arg0 /* note overwriting arg0 */
@@ -249,7 +246,9 @@ ENTRY_CFI(real64_call_asm)
249246
ldd 7*REG_SZ(%arg1), %r19
250247
ldd 1*REG_SZ(%arg1), %arg1 /* do this one last! */
251248

249+
/* set up real-mode stack and real-mode ap */
252250
tophys_r1 %sp
251+
ldo -16(%sp), %r29 /* Reference param save area */
253252

254253
b,l rfi_virt2real,%r2
255254
nop

arch/parisc/kernel/sys_parisc.c

Lines changed: 63 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,26 @@
2525
#include <linux/random.h>
2626
#include <linux/compat.h>
2727

28-
/* we construct an artificial offset for the mapping based on the physical
29-
* address of the kernel mapping variable */
30-
#define GET_LAST_MMAP(filp) \
31-
(filp ? ((unsigned long) filp->f_mapping) >> 8 : 0UL)
32-
#define SET_LAST_MMAP(filp, val) \
33-
{ /* nothing */ }
34-
35-
static int get_offset(unsigned int last_mmap)
36-
{
37-
return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT;
38-
}
28+
/*
29+
* Construct an artificial page offset for the mapping based on the physical
30+
* address of the kernel file mapping variable.
31+
*/
32+
#define GET_FILP_PGOFF(filp) \
33+
(filp ? (((unsigned long) filp->f_mapping) >> 8) \
34+
& ((SHM_COLOUR-1) >> PAGE_SHIFT) : 0UL)
3935

40-
static unsigned long shared_align_offset(unsigned int last_mmap,
36+
static unsigned long shared_align_offset(unsigned long filp_pgoff,
4137
unsigned long pgoff)
4238
{
43-
return (get_offset(last_mmap) + pgoff) << PAGE_SHIFT;
39+
return (filp_pgoff + pgoff) << PAGE_SHIFT;
4440
}
4541

4642
static inline unsigned long COLOR_ALIGN(unsigned long addr,
47-
unsigned int last_mmap, unsigned long pgoff)
43+
unsigned long filp_pgoff, unsigned long pgoff)
4844
{
4945
unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1);
5046
unsigned long off = (SHM_COLOUR-1) &
51-
(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
52-
47+
shared_align_offset(filp_pgoff, pgoff);
5348
return base + off;
5449
}
5550

@@ -98,126 +93,91 @@ static unsigned long mmap_upper_limit(struct rlimit *rlim_stack)
9893
return PAGE_ALIGN(STACK_TOP - stack_base);
9994
}
10095

96+
enum mmap_allocation_direction {UP, DOWN};
10197

102-
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
103-
unsigned long len, unsigned long pgoff, unsigned long flags)
98+
static unsigned long arch_get_unmapped_area_common(struct file *filp,
99+
unsigned long addr, unsigned long len, unsigned long pgoff,
100+
unsigned long flags, enum mmap_allocation_direction dir)
104101
{
105102
struct mm_struct *mm = current->mm;
106103
struct vm_area_struct *vma, *prev;
107-
unsigned long task_size = TASK_SIZE;
108-
int do_color_align, last_mmap;
104+
unsigned long filp_pgoff;
105+
int do_color_align;
109106
struct vm_unmapped_area_info info;
110107

111-
if (len > task_size)
108+
if (unlikely(len > TASK_SIZE))
112109
return -ENOMEM;
113110

114111
do_color_align = 0;
115112
if (filp || (flags & MAP_SHARED))
116113
do_color_align = 1;
117-
last_mmap = GET_LAST_MMAP(filp);
114+
filp_pgoff = GET_FILP_PGOFF(filp);
118115

119116
if (flags & MAP_FIXED) {
120-
if ((flags & MAP_SHARED) && last_mmap &&
121-
(addr - shared_align_offset(last_mmap, pgoff))
117+
/* Even MAP_FIXED mappings must reside within TASK_SIZE */
118+
if (TASK_SIZE - len < addr)
119+
return -EINVAL;
120+
121+
if ((flags & MAP_SHARED) && filp &&
122+
(addr - shared_align_offset(filp_pgoff, pgoff))
122123
& (SHM_COLOUR - 1))
123124
return -EINVAL;
124-
goto found_addr;
125+
return addr;
125126
}
126127

127128
if (addr) {
128-
if (do_color_align && last_mmap)
129-
addr = COLOR_ALIGN(addr, last_mmap, pgoff);
129+
if (do_color_align)
130+
addr = COLOR_ALIGN(addr, filp_pgoff, pgoff);
130131
else
131132
addr = PAGE_ALIGN(addr);
132133

133134
vma = find_vma_prev(mm, addr, &prev);
134-
if (task_size - len >= addr &&
135+
if (TASK_SIZE - len >= addr &&
135136
(!vma || addr + len <= vm_start_gap(vma)) &&
136137
(!prev || addr >= vm_end_gap(prev)))
137-
goto found_addr;
138+
return addr;
138139
}
139140

140-
info.flags = 0;
141141
info.length = len;
142+
info.align_mask = do_color_align ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
143+
info.align_offset = shared_align_offset(filp_pgoff, pgoff);
144+
145+
if (dir == DOWN) {
146+
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
147+
info.low_limit = PAGE_SIZE;
148+
info.high_limit = mm->mmap_base;
149+
addr = vm_unmapped_area(&info);
150+
if (!(addr & ~PAGE_MASK))
151+
return addr;
152+
VM_BUG_ON(addr != -ENOMEM);
153+
154+
/*
155+
* A failed mmap() very likely causes application failure,
156+
* so fall back to the bottom-up function here. This scenario
157+
* can happen with large stack limits and large mmap()
158+
* allocations.
159+
*/
160+
}
161+
162+
info.flags = 0;
142163
info.low_limit = mm->mmap_legacy_base;
143164
info.high_limit = mmap_upper_limit(NULL);
144-
info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
145-
info.align_offset = shared_align_offset(last_mmap, pgoff);
146-
addr = vm_unmapped_area(&info);
147-
148-
found_addr:
149-
if (do_color_align && !last_mmap && !(addr & ~PAGE_MASK))
150-
SET_LAST_MMAP(filp, addr - (pgoff << PAGE_SHIFT));
151-
152-
return addr;
165+
return vm_unmapped_area(&info);
153166
}
154167

155-
unsigned long
156-
arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
157-
const unsigned long len, const unsigned long pgoff,
158-
const unsigned long flags)
168+
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
169+
unsigned long len, unsigned long pgoff, unsigned long flags)
159170
{
160-
struct vm_area_struct *vma, *prev;
161-
struct mm_struct *mm = current->mm;
162-
unsigned long addr = addr0;
163-
int do_color_align, last_mmap;
164-
struct vm_unmapped_area_info info;
165-
166-
/* requested length too big for entire address space */
167-
if (len > TASK_SIZE)
168-
return -ENOMEM;
169-
170-
do_color_align = 0;
171-
if (filp || (flags & MAP_SHARED))
172-
do_color_align = 1;
173-
last_mmap = GET_LAST_MMAP(filp);
174-
175-
if (flags & MAP_FIXED) {
176-
if ((flags & MAP_SHARED) && last_mmap &&
177-
(addr - shared_align_offset(last_mmap, pgoff))
178-
& (SHM_COLOUR - 1))
179-
return -EINVAL;
180-
goto found_addr;
181-
}
182-
183-
/* requesting a specific address */
184-
if (addr) {
185-
if (do_color_align && last_mmap)
186-
addr = COLOR_ALIGN(addr, last_mmap, pgoff);
187-
else
188-
addr = PAGE_ALIGN(addr);
189-
190-
vma = find_vma_prev(mm, addr, &prev);
191-
if (TASK_SIZE - len >= addr &&
192-
(!vma || addr + len <= vm_start_gap(vma)) &&
193-
(!prev || addr >= vm_end_gap(prev)))
194-
goto found_addr;
195-
}
196-
197-
info.flags = VM_UNMAPPED_AREA_TOPDOWN;
198-
info.length = len;
199-
info.low_limit = PAGE_SIZE;
200-
info.high_limit = mm->mmap_base;
201-
info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
202-
info.align_offset = shared_align_offset(last_mmap, pgoff);
203-
addr = vm_unmapped_area(&info);
204-
if (!(addr & ~PAGE_MASK))
205-
goto found_addr;
206-
VM_BUG_ON(addr != -ENOMEM);
207-
208-
/*
209-
* A failed mmap() very likely causes application failure,
210-
* so fall back to the bottom-up function here. This scenario
211-
* can happen with large stack limits and large mmap()
212-
* allocations.
213-
*/
214-
return arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
215-
216-
found_addr:
217-
if (do_color_align && !last_mmap && !(addr & ~PAGE_MASK))
218-
SET_LAST_MMAP(filp, addr - (pgoff << PAGE_SHIFT));
171+
return arch_get_unmapped_area_common(filp,
172+
addr, len, pgoff, flags, UP);
173+
}
219174

220-
return addr;
175+
unsigned long arch_get_unmapped_area_topdown(struct file *filp,
176+
unsigned long addr, unsigned long len, unsigned long pgoff,
177+
unsigned long flags)
178+
{
179+
return arch_get_unmapped_area_common(filp,
180+
addr, len, pgoff, flags, DOWN);
221181
}
222182

223183
static int mmap_is_legacy(void)

0 commit comments

Comments
 (0)