Skip to content

Commit 7236aae

Browse files
committed
parisc: Fix locking in pdc_iodc_print() firmware call
Utilize pdc_lock spinlock to protect parallel modifications of the iodc_dbuf[] buffer, check length to prevent buffer overflow of iodc_dbuf[], drop the iodc_retbuf[] buffer and fix some wrong indentings. Signed-off-by: Helge Deller <[email protected]> Cc: <[email protected]> # 6.0+
1 parent fe94cb1 commit 7236aae

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

arch/parisc/kernel/firmware.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,9 +1288,8 @@ void pdc_io_reset_devices(void)
12881288

12891289
#endif /* defined(BOOTLOADER) */
12901290

1291-
/* locked by pdc_console_lock */
1292-
static int __attribute__((aligned(8))) iodc_retbuf[32];
1293-
static char __attribute__((aligned(64))) iodc_dbuf[4096];
1291+
/* locked by pdc_lock */
1292+
static char iodc_dbuf[4096] __page_aligned_bss;
12941293

12951294
/**
12961295
* pdc_iodc_print - Console print using IODC.
@@ -1307,6 +1306,9 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
13071306
unsigned int i;
13081307
unsigned long flags;
13091308

1309+
count = min_t(unsigned int, count, sizeof(iodc_dbuf));
1310+
1311+
spin_lock_irqsave(&pdc_lock, flags);
13101312
for (i = 0; i < count;) {
13111313
switch(str[i]) {
13121314
case '\n':
@@ -1322,12 +1324,11 @@ int pdc_iodc_print(const unsigned char *str, unsigned count)
13221324
}
13231325

13241326
print:
1325-
spin_lock_irqsave(&pdc_lock, flags);
1326-
real32_call(PAGE0->mem_cons.iodc_io,
1327-
(unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
1328-
PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
1329-
__pa(iodc_retbuf), 0, __pa(iodc_dbuf), i, 0);
1330-
spin_unlock_irqrestore(&pdc_lock, flags);
1327+
real32_call(PAGE0->mem_cons.iodc_io,
1328+
(unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
1329+
PAGE0->mem_cons.spa, __pa(PAGE0->mem_cons.dp.layers),
1330+
__pa(pdc_result), 0, __pa(iodc_dbuf), i, 0);
1331+
spin_unlock_irqrestore(&pdc_lock, flags);
13311332

13321333
return i;
13331334
}
@@ -1354,10 +1355,11 @@ int pdc_iodc_getc(void)
13541355
real32_call(PAGE0->mem_kbd.iodc_io,
13551356
(unsigned long)PAGE0->mem_kbd.hpa, ENTRY_IO_CIN,
13561357
PAGE0->mem_kbd.spa, __pa(PAGE0->mem_kbd.dp.layers),
1357-
__pa(iodc_retbuf), 0, __pa(iodc_dbuf), 1, 0);
1358+
__pa(pdc_result), 0, __pa(iodc_dbuf), 1, 0);
13581359

13591360
ch = *iodc_dbuf;
1360-
status = *iodc_retbuf;
1361+
/* like convert_to_wide() but for first return value only: */
1362+
status = *(int *)&pdc_result;
13611363
spin_unlock_irqrestore(&pdc_lock, flags);
13621364

13631365
if (status == 0)

0 commit comments

Comments
 (0)