* [PATCH v2 9/9] hvc_console: Allow backends to set I/O buffer size
From: Geoff Levand @ 2020-05-09 18:58 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, Geert Uytterhoeven, Markus Elfring,
Emmanuel Nicolet
In-Reply-To: <cover.1589049250.git.geoff@infradead.org>
To allow HVC backends to set the I/O buffer sizes to values
that are most efficient for the backend, change the macro
definitions where the buffer sizes are set to be conditional
on whether or not the macros are already defined. Also,
rename the macros from N_OUTBUF to HVC_N_OUBUF and from
N_INBUF to HVC_N_INBUF.
Typical usage in the backend source file would be:
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
drivers/tty/hvc/hvc_console.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 436cc51c92c3..2928bad057fc 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -42,12 +42,15 @@
#define HVC_CLOSE_WAIT (HZ/100) /* 1/10 of a second */
/*
- * These sizes are most efficient for vio, because they are the
- * native transfer size. We could make them selectable in the
- * future to better deal with backends that want other buffer sizes.
+ * These default sizes are most efficient for vio, because they are
+ * the native transfer size.
*/
-#define N_OUTBUF 16
-#define N_INBUF 16
+#if !defined(HVC_N_OUTBUF)
+# define HVC_N_OUTBUF 16
+#endif
+#if !defined(HVC_N_INBUF)
+# define HVC_N_INBUF 16
+#endif
#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
@@ -151,7 +154,7 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
static void hvc_console_print(struct console *co, const char *b,
unsigned count)
{
- char c[N_OUTBUF] __ALIGNED__;
+ char c[HVC_N_OUTBUF] __ALIGNED__;
unsigned i = 0, n = 0;
int r, donecr = 0, index = co->index;
@@ -640,7 +643,7 @@ static int __hvc_poll(struct hvc_struct *hp, bool may_sleep)
{
struct tty_struct *tty;
int i, n, count, poll_mask = 0;
- char buf[N_INBUF] __ALIGNED__;
+ char buf[HVC_N_INBUF] __ALIGNED__;
unsigned long flags;
int read_total = 0;
int written_total = 0;
@@ -681,7 +684,7 @@ static int __hvc_poll(struct hvc_struct *hp, bool may_sleep)
read_again:
/* Read data if any */
- count = tty_buffer_request_room(&hp->port, N_INBUF);
+ count = tty_buffer_request_room(&hp->port, HVC_N_INBUF);
/* If flip is full, just reschedule a later read */
if (count == 0) {
--
2.20.1
^ permalink raw reply related
* [PATCH v2 8/9] powerpc/ps3: Fix kexec shutdown hang
From: Geoff Levand @ 2020-05-09 18:58 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, Geert Uytterhoeven, Markus Elfring,
Emmanuel Nicolet
In-Reply-To: <cover.1589049250.git.geoff@infradead.org>
The ps3_mm_region_destroy() and ps3_mm_vas_destroy() routines
are called very late in the shutdown via kexec's mmu_cleanup_all
routine. By the time mmu_cleanup_all runs it is too late to use
udbg_printf, and calling it will cause PS3 systems to hang.
Remove all debugging statements from ps3_mm_region_destroy() and
ps3_mm_vas_destroy() and replace any error reporting with calls
to lv1_panic.
With this change builds with 'DEBUG' defined will not cause kexec
reboots to hang, and builds with 'DEBUG' defined or not will end
in lv1_panic if an error is encountered.
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/platforms/ps3/mm.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 423be34f0f5f..f42fe4e86ce5 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -200,13 +200,14 @@ void ps3_mm_vas_destroy(void)
{
int result;
- DBG("%s:%d: map.vas_id = %llu\n", __func__, __LINE__, map.vas_id);
-
if (map.vas_id) {
result = lv1_select_virtual_address_space(0);
- BUG_ON(result);
- result = lv1_destruct_virtual_address_space(map.vas_id);
- BUG_ON(result);
+ result += lv1_destruct_virtual_address_space(map.vas_id);
+
+ if (result) {
+ lv1_panic(0);
+ }
+
map.vas_id = 0;
}
}
@@ -304,19 +305,20 @@ static void ps3_mm_region_destroy(struct mem_region *r)
int result;
if (!r->destroy) {
- pr_info("%s:%d: Not destroying high region: %llxh %llxh\n",
- __func__, __LINE__, r->base, r->size);
return;
}
- DBG("%s:%d: r->base = %llxh\n", __func__, __LINE__, r->base);
-
if (r->base) {
result = lv1_release_memory(r->base);
- BUG_ON(result);
+
+ if (result) {
+ lv1_panic(0);
+ }
+
r->size = r->base = r->offset = 0;
map.total = map.rm.size;
}
+
ps3_mm_set_repository_highmem(NULL);
}
--
2.20.1
^ permalink raw reply related
* [PATCH v2 2/9] powerpc/wrapper: Output linker map file
From: Geoff Levand @ 2020-05-09 18:58 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, Geert Uytterhoeven, Markus Elfring,
Emmanuel Nicolet
In-Reply-To: <cover.1589049250.git.geoff@infradead.org>
To aid debugging wrapper troubles, output a linker map file
'wrapper.map' when the build is verbose.
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/boot/wrapper | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index ed6266367bc0..35ace40d9fc2 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -29,6 +29,7 @@ set -e
# Allow for verbose output
if [ "$V" = 1 ]; then
set -x
+ map="-Map wrapper.map"
fi
# defaults
@@ -500,7 +501,7 @@ if [ "$platform" != "miboot" ]; then
text_start="-Ttext $link_address"
fi
#link everything
- ${CROSS}ld -m $format -T $lds $text_start $pie $nodl -o "$ofile" \
+ ${CROSS}ld -m $format -T $lds $text_start $pie $nodl -o "$ofile" $map \
$platformo $tmp $object/wrapper.a
rm $tmp
fi
--
2.20.1
^ permalink raw reply related
* [PATCH v2 3/9] powerpc/head_check: Avoid broken pipe
From: Geoff Levand @ 2020-05-09 18:58 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, Geert Uytterhoeven, Markus Elfring,
Emmanuel Nicolet
In-Reply-To: <cover.1589049250.git.geoff@infradead.org>
Remove the '-m4' option to grep to allow grep to process all of nm's
output. This avoids the nm warning:
nm terminated with signal 13 [Broken pipe]
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
arch/powerpc/tools/head_check.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/tools/head_check.sh b/arch/powerpc/tools/head_check.sh
index 37061fb9b58e..e32d3162e5ed 100644
--- a/arch/powerpc/tools/head_check.sh
+++ b/arch/powerpc/tools/head_check.sh
@@ -46,7 +46,7 @@ nm="$1"
vmlinux="$2"
# gcc-4.6-era toolchain make _stext an A (absolute) symbol rather than T
-$nm "$vmlinux" | grep -e " [TA] _stext$" -e " t start_first_256B$" -e " a text_start$" -e " t start_text$" -m4 > .tmp_symbols.txt
+$nm "$vmlinux" | grep -e " [TA] _stext$" -e " t start_first_256B$" -e " a text_start$" -e " t start_text$" > .tmp_symbols.txt
vma=$(cat .tmp_symbols.txt | grep -e " [TA] _stext$" | cut -d' ' -f1)
--
2.20.1
^ permalink raw reply related
* [PATCH v2 6/9] ps3disk: use the default segment boundary
From: Geoff Levand @ 2020-05-09 18:58 UTC (permalink / raw)
To: Michael Ellerman, Jens Axboe
Cc: linuxppc-dev, Geert Uytterhoeven, Markus Elfring,
Emmanuel Nicolet
In-Reply-To: <cover.1589049250.git.geoff@infradead.org>
From: Emmanuel Nicolet <emmanuel.nicolet@gmail.com>
Hi,
since commit dcebd755926b ("block: use bio_for_each_bvec() to compute
multi-page bvec count"), the kernel will bug_on on the PS3 because
bio_split() is called with sectors == 0:
kernel BUG at block/bio.c:1853!
Oops: Exception in kernel mode, sig: 5 [#1]
BE PAGE_SIZE=4K MMU=Hash PREEMPT SMP NR_CPUS=8 NUMA PS3
Modules linked in: firewire_sbp2 rtc_ps3(+) soundcore ps3_gelic(+) \
ps3rom(+) firewire_core ps3vram(+) usb_common crc_itu_t
CPU: 0 PID: 97 Comm: blkid Not tainted 5.3.0-rc4 #1
NIP: c00000000027d0d0 LR: c00000000027d0b0 CTR: 0000000000000000
REGS: c00000000135ae90 TRAP: 0700 Not tainted (5.3.0-rc4)
MSR: 8000000000028032 <SF,EE,IR,DR,RI> CR: 44008240 XER: 20000000
IRQMASK: 0
GPR00: c000000000289368 c00000000135b120 c00000000084a500 c000000004ff8300
GPR04: 0000000000000c00 c000000004c905e0 c000000004c905e0 000000000000ffff
GPR08: 0000000000000000 0000000000000001 0000000000000000 000000000000ffff
GPR12: 0000000000000000 c0000000008ef000 000000000000003e 0000000000080001
GPR16: 0000000000000100 000000000000ffff 0000000000000000 0000000000000004
GPR20: c00000000062fd7e 0000000000000001 000000000000ffff 0000000000000080
GPR24: c000000000781788 c00000000135b350 0000000000000080 c000000004c905e0
GPR28: c00000000135b348 c000000004ff8300 0000000000000000 c000000004c90000
NIP [c00000000027d0d0] .bio_split+0x28/0xac
LR [c00000000027d0b0] .bio_split+0x8/0xac
Call Trace:
[c00000000135b120] [c00000000027d130] .bio_split+0x88/0xac (unreliable)
[c00000000135b1b0] [c000000000289368] .__blk_queue_split+0x11c/0x53c
[c00000000135b2d0] [c00000000028f614] .blk_mq_make_request+0x80/0x7d4
[c00000000135b3d0] [c000000000283a8c] .generic_make_request+0x118/0x294
[c00000000135b4b0] [c000000000283d34] .submit_bio+0x12c/0x174
[c00000000135b580] [c000000000205a44] .mpage_bio_submit+0x3c/0x4c
[c00000000135b600] [c000000000206184] .mpage_readpages+0xa4/0x184
[c00000000135b750] [c0000000001ff8fc] .blkdev_readpages+0x24/0x38
[c00000000135b7c0] [c0000000001589f0] .read_pages+0x6c/0x1a8
[c00000000135b8b0] [c000000000158c74] .__do_page_cache_readahead+0x118/0x184
[c00000000135b9b0] [c0000000001591a8] .force_page_cache_readahead+0xe4/0xe8
[c00000000135ba50] [c00000000014fc24] .generic_file_read_iter+0x1d8/0x830
[c00000000135bb50] [c0000000001ffadc] .blkdev_read_iter+0x40/0x5c
[c00000000135bbc0] [c0000000001b9e00] .new_sync_read+0x144/0x1a0
[c00000000135bcd0] [c0000000001bc454] .vfs_read+0xa0/0x124
[c00000000135bd70] [c0000000001bc7a4] .ksys_read+0x70/0xd8
[c00000000135be20] [c00000000000a524] system_call+0x5c/0x70
Instruction dump:
7fe3fb78 482e30dc 7c0802a6 482e3085 7c9e2378 f821ff71 7ca42b78 7d3e00d0
7c7d1b78 79290fe0 7cc53378 69290001 <0b090000> 81230028 7bca0020 7929ba62
[ end trace 313fec760f30aa1f ]---
The problem originates from setting the segment boundary of the request
queue to -1UL. This makes get_max_segment_size() return zero when offset
is zero, whatever the max segment size. The test with BLK_SEG_BOUNDARY_MASK
fails and 'mask - (mask & offset) + 1' overflows to zero in the return
statement.
Not setting the segment boundary and using the default value
(BLK_SEG_BOUNDARY_MASK) fixes the problem.
Maybe BLK_SEG_BOUNDARY_MASK should be set to -1UL? It's currently set to
only 0xFFFFFFFFUL. I don't know if that would break anything.
Signed-off-by: Emmanuel Nicolet <emmanuel.nicolet@gmail.com>
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
drivers/block/ps3disk.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index c5c6487a19d5..7b55811c2a81 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -454,7 +454,6 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev)
queue->queuedata = dev;
blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
- blk_queue_segment_boundary(queue, -1UL);
blk_queue_dma_alignment(queue, dev->blk_size-1);
blk_queue_logical_block_size(queue, dev->blk_size);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 5/9] net/ps3_gelic_net: Remove duplicate error message
From: Geoff Levand @ 2020-05-09 18:58 UTC (permalink / raw)
To: Michael Ellerman, David S. Miller
Cc: linuxppc-dev, Geert Uytterhoeven, Markus Elfring,
Emmanuel Nicolet
In-Reply-To: <cover.1589049250.git.geoff@infradead.org>
From: Markus Elfring <elfring@users.sourceforge.net>
Remove an extra message for a memory allocation failure in
function gelic_descr_prepare_rx().
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
drivers/net/ethernet/toshiba/ps3_gelic_net.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
index 070dd6fa9401..8522f3898e0d 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
@@ -382,8 +382,6 @@ static int gelic_descr_prepare_rx(struct gelic_card *card,
descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
if (!descr->skb) {
descr->buf_addr = 0; /* tell DMAC don't touch memory */
- dev_info(ctodev(card),
- "%s:allocate skb failed !!\n", __func__);
return -ENOMEM;
}
descr->buf_size = cpu_to_be32(bufsize);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 4/9] drivers/ps3: Remove duplicate error messages
From: Geoff Levand @ 2020-05-09 18:58 UTC (permalink / raw)
To: Michael Ellerman
Cc: linuxppc-dev, Geert Uytterhoeven, Markus Elfring,
Emmanuel Nicolet
In-Reply-To: <cover.1589049250.git.geoff@infradead.org>
From: Markus Elfring <elfring@users.sourceforge.net>
Remove duplicate memory allocation failure error messages.
Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
drivers/ps3/ps3-lpm.c | 2 --
drivers/ps3/ps3-vuart.c | 1 -
2 files changed, 3 deletions(-)
diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c
index 83c45659bc9d..fcc346296e3a 100644
--- a/drivers/ps3/ps3-lpm.c
+++ b/drivers/ps3/ps3-lpm.c
@@ -1111,8 +1111,6 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
lpm_priv->tb_cache_internal = kzalloc(
lpm_priv->tb_cache_size + 127, GFP_KERNEL);
if (!lpm_priv->tb_cache_internal) {
- dev_err(sbd_core(), "%s:%u: alloc internal tb_cache "
- "failed\n", __func__, __LINE__);
result = -ENOMEM;
goto fail_malloc;
}
diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c
index ddaa5ea5801a..3b5878edc6c2 100644
--- a/drivers/ps3/ps3-vuart.c
+++ b/drivers/ps3/ps3-vuart.c
@@ -917,7 +917,6 @@ static int ps3_vuart_bus_interrupt_get(void)
vuart_bus_priv.bmp = kzalloc(sizeof(struct ports_bmp), GFP_KERNEL);
if (!vuart_bus_priv.bmp) {
- pr_debug("%s:%d: kzalloc failed.\n", __func__, __LINE__);
result = -ENOMEM;
goto fail_bmp_malloc;
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v8 8/8] powerpc/vdso: Provide __kernel_clock_gettime64() on vdso32
From: Christophe Leroy @ 2020-05-09 18:48 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Nathan Lynch, linux-arch, linux-kernel@vger.kernel.org,
Paul Mackerras, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, linuxppc-dev
In-Reply-To: <d3f303f1-8b2c-0c54-5380-0b9a370a4eb3@csgroup.eu>
Le 09/05/2020 à 17:54, Christophe Leroy a écrit :
>
>
> Le 28/04/2020 à 18:05, Arnd Bergmann a écrit :
>> On Tue, Apr 28, 2020 at 3:16 PM Christophe Leroy
>> <christophe.leroy@c-s.fr> wrote:
>>>
>>> Provides __kernel_clock_gettime64() on vdso32. This is the
>>> 64 bits version of __kernel_clock_gettime() which is
>>> y2038 compliant.
>>>
>>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>>
>> Looks good to me
>>
>> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
>>
>> There was a bug on ARM for the corresponding function, so far it is
>> unclear
>> if this was a problem related to particular hardware, the 32-bit
>> kernel code,
>> or the common implementation of clock_gettime64 in the vdso library,
>> see https://github.com/richfelker/musl-cross-make/issues/96
>>
>> Just to be sure that powerpc is not affected by the same issue, can you
>> confirm that repeatedly calling clock_gettime64 on powerpc32, alternating
>> between vdso and syscall, results in monotically increasing times?
>>
>
> I think that's one of the things vdsotest checks, so yes that's ok I think.
>
Here is the full result with vdsotest:
gettimeofday: syscall: 3715 nsec/call
gettimeofday: libc: 794 nsec/call
gettimeofday: vdso: 947 nsec/call
getcpu: syscall: 1614 nsec/call
getcpu: libc: 484 nsec/call
getcpu: vdso: 184 nsec/call
clock-gettime64-realtime-coarse: syscall: 3152 nsec/call
clock-gettime64-realtime-coarse: libc: not tested
clock-gettime64-realtime-coarse: vdso: 653 nsec/call
clock-getres-realtime-coarse: syscall: 2963 nsec/call
clock-getres-realtime-coarse: libc: 745 nsec/call
clock-getres-realtime-coarse: vdso: 553 nsec/call
clock-gettime-realtime-coarse: syscall: 5120 nsec/call
clock-gettime-realtime-coarse: libc: 731 nsec/call
clock-gettime-realtime-coarse: vdso: 577 nsec/call
clock-gettime64-realtime: syscall: 3719 nsec/call
clock-gettime64-realtime: libc: not tested
clock-gettime64-realtime: vdso: 976 nsec/call
clock-getres-realtime: syscall: 2496 nsec/call
clock-getres-realtime: libc: 745 nsec/call
clock-getres-realtime: vdso: 546 nsec/call
clock-gettime-realtime: syscall: 4800 nsec/call
clock-gettime-realtime: libc: 1080 nsec/call
clock-gettime-realtime: vdso: 1798 nsec/call
clock-gettime64-boottime: syscall: 4132 nsec/call
clock-gettime64-boottime: libc: not tested
clock-gettime64-boottime: vdso: 975 nsec/call
clock-getres-boottime: syscall: 2497 nsec/call
clock-getres-boottime: libc: 730 nsec/call
clock-getres-boottime: vdso: 546 nsec/call
clock-gettime-boottime: syscall: 3728 nsec/call
clock-gettime-boottime: libc: 1079 nsec/call
clock-gettime-boottime: vdso: 941 nsec/call
clock-gettime64-tai: syscall: 4148 nsec/call
clock-gettime64-tai: libc: not tested
clock-gettime64-tai: vdso: 955 nsec/call
clock-getres-tai: syscall: 2494 nsec/call
clock-getres-tai: libc: 730 nsec/call
clock-getres-tai: vdso: 545 nsec/call
clock-gettime-tai: syscall: 3729 nsec/call
clock-gettime-tai: libc: 1079 nsec/call
clock-gettime-tai: vdso: 927 nsec/call
clock-gettime64-monotonic-raw: syscall: 3677 nsec/call
clock-gettime64-monotonic-raw: libc: not tested
clock-gettime64-monotonic-raw: vdso: 1032 nsec/call
clock-getres-monotonic-raw: syscall: 2494 nsec/call
clock-getres-monotonic-raw: libc: 745 nsec/call
clock-getres-monotonic-raw: vdso: 545 nsec/call
clock-gettime-monotonic-raw: syscall: 3276 nsec/call
clock-gettime-monotonic-raw: libc: 1140 nsec/call
clock-gettime-monotonic-raw: vdso: 1002 nsec/call
clock-gettime64-monotonic-coarse: syscall: 4099 nsec/call
clock-gettime64-monotonic-coarse: libc: not tested
clock-gettime64-monotonic-coarse: vdso: 653 nsec/call
clock-getres-monotonic-coarse: syscall: 2962 nsec/call
clock-getres-monotonic-coarse: libc: 745 nsec/call
clock-getres-monotonic-coarse: vdso: 545 nsec/call
clock-gettime-monotonic-coarse: syscall: 4297 nsec/call
clock-gettime-monotonic-coarse: libc: 730 nsec/call
clock-gettime-monotonic-coarse: vdso: 592 nsec/call
clock-gettime64-monotonic: syscall: 3863 nsec/call
clock-gettime64-monotonic: libc: not tested
clock-gettime64-monotonic: vdso: 975 nsec/call
clock-getres-monotonic: syscall: 2494 nsec/call
clock-getres-monotonic: libc: 745 nsec/call
clock-getres-monotonic: vdso: 545 nsec/call
clock-gettime-monotonic: syscall: 3465 nsec/call
clock-gettime-monotonic: libc: 1079 nsec/call
clock-gettime-monotonic: vdso: 927 nsec/call
Christophe
^ permalink raw reply
* [PATCH fixes] powerpc/40x: Make more space for system call exception
From: Christophe Leroy @ 2020-05-09 17:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev, linux-kernel
When CONFIG_VIRT_CPU_ACCOUNTING is selected, system call exception
handler doesn't fit below 0xd00 and build fails.
As exception 0xd00 doesn't exist and is never generated by 40x,
comment it out in order to get more space for system call exception.
Reported-by: kbuild test robot <lkp@intel.com>
Fixes: 9e27086292aa ("powerpc/32: Warn and return ENOSYS on syscalls from kernel")
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/head_40x.S | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S
index 9bb663977e84..2cec543c38f0 100644
--- a/arch/powerpc/kernel/head_40x.S
+++ b/arch/powerpc/kernel/head_40x.S
@@ -344,8 +344,9 @@ _ENTRY(saved_ksp_limit)
/* 0x0C00 - System Call Exception */
START_EXCEPTION(0x0C00, SystemCall)
SYSCALL_ENTRY 0xc00
+/* Trap_0D is commented out to get more space for system call exception */
- EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD)
+/* EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD) */
EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_STD)
EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_STD)
--
2.25.0
^ permalink raw reply related
* [PATCH vdsotest] Add support for clock_gettime64() on powerpc32
From: Christophe Leroy @ 2020-05-09 16:18 UTC (permalink / raw)
To: nathanl, arnd; +Cc: linuxppc-dev
libc test is commented out because at the time being
very few libc if any supports clock_gettime64()
syscall number is hardcoded when it doesn't exists in unistd.h
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
Based on master from https://github.com/nathanlynch/vdsotest.git
src/clock-boottime.c | 4 +
src/clock-monotonic-coarse.c | 4 +
src/clock-monotonic-raw.c | 4 +
src/clock-monotonic.c | 4 +
src/clock-realtime-coarse.c | 4 +
src/clock-realtime.c | 4 +
src/clock-tai.c | 4 +
src/clock_gettime64_template.c | 401 +++++++++++++++++++++++++++++++++
8 files changed, 429 insertions(+)
create mode 100644 src/clock_gettime64_template.c
diff --git a/src/clock-boottime.c b/src/clock-boottime.c
index 9fb1ac48501d..07ef31d08614 100644
--- a/src/clock-boottime.c
+++ b/src/clock-boottime.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-monotonic-coarse.c b/src/clock-monotonic-coarse.c
index ca1df58691ca..da064188756f 100644
--- a/src/clock-monotonic-coarse.c
+++ b/src/clock-monotonic-coarse.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-monotonic-raw.c b/src/clock-monotonic-raw.c
index 5dbb1842e698..55373b94ecfd 100644
--- a/src/clock-monotonic-raw.c
+++ b/src/clock-monotonic-raw.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-monotonic.c b/src/clock-monotonic.c
index 44318ae1e1c2..a900d24598a1 100644
--- a/src/clock-monotonic.c
+++ b/src/clock-monotonic.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-realtime-coarse.c b/src/clock-realtime-coarse.c
index 8f33f9a2d30b..8f2e6242bf0d 100644
--- a/src/clock-realtime-coarse.c
+++ b/src/clock-realtime-coarse.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-realtime.c b/src/clock-realtime.c
index 079fd801e654..ab76329a6676 100644
--- a/src/clock-realtime.c
+++ b/src/clock-realtime.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-tai.c b/src/clock-tai.c
index ad0448adeba5..cb2511039ddc 100644
--- a/src/clock-tai.c
+++ b/src/clock-tai.c
@@ -7,3 +7,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock_gettime64_template.c b/src/clock_gettime64_template.c
new file mode 100644
index 000000000000..4752845148d6
--- /dev/null
+++ b/src/clock_gettime64_template.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2014 Mentor Graphics Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <errno.h>
+#include <error.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "compiler.h"
+#include "vdsotest.h"
+
+struct timespec64 {
+ long long tv_sec;
+ long tv_nsec;
+};
+
+#ifndef SYS_clock_gettime64
+#define SYS_clock_gettime64 403
+#endif
+
+static int (*clock_gettime64_vdso)(clockid_t id, struct timespec64 *ts);
+
+static bool vdso_has_clock_gettime64(void)
+{
+ return clock_gettime64_vdso != NULL;
+}
+
+static int clock_gettime64_syscall_wrapper(clockid_t id, struct timespec64 *ts)
+{
+ return syscall(SYS_clock_gettime64, id, ts);
+}
+
+static void clock_gettime64_syscall_nofail(clockid_t id, struct timespec64 *ts)
+{
+ int err;
+
+ err = clock_gettime64_syscall_wrapper(id, ts);
+ if (err)
+ error(EXIT_FAILURE, errno, "SYS_clock_gettime64");
+}
+
+static int clock_gettime64_vdso_wrapper(clockid_t id, struct timespec64 *ts)
+{
+ return DO_VDSO_CALL(clock_gettime64_vdso, int, 2, id, ts);
+}
+
+static void clock_gettime64_vdso_nofail(clockid_t id, struct timespec64 *ts)
+{
+ int err;
+
+ err = clock_gettime64_vdso_wrapper(id, ts);
+ if (err)
+ error(EXIT_FAILURE, errno, "clock_gettime");
+}
+
+static bool timespecs64_ordered(const struct timespec64 *first,
+ const struct timespec64 *second)
+{
+ if (first->tv_sec < second->tv_sec)
+ return true;
+
+ if (first->tv_sec == second->tv_sec)
+ return first->tv_nsec <= second->tv_nsec;
+
+ return false;
+}
+
+static bool timespec64_normalized(const struct timespec64 *ts)
+{
+ if (ts->tv_sec < 0)
+ return false;
+ if (ts->tv_nsec < 0)
+ return false;
+ if (ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
+ return true;
+}
+
+static void clock_gettime64_verify(struct ctx *ctx)
+{
+ struct timespec64 now;
+
+ clock_gettime64_syscall_nofail(CLOCK_ID, &now);
+
+ ctx_start_timer(ctx);
+
+ while (!test_should_stop(ctx)) {
+ struct timespec64 prev;
+
+ if (!vdso_has_clock_gettime64())
+ goto skip_vdso;
+
+ prev = now;
+
+ clock_gettime64_vdso_nofail(CLOCK_ID, &now);
+
+ if (!timespec64_normalized(&now)) {
+ log_failure(ctx, "timestamp obtained from libc/vDSO "
+ "not normalized:\n"
+ "\t[%ld, %ld]\n",
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ if (!timespecs64_ordered(&prev, &now)) {
+ log_failure(ctx, "timestamp obtained from libc/vDSO "
+ "predates timestamp\n"
+ "previously obtained from kernel:\n"
+ "\t[%ld, %ld] (kernel)\n"
+ "\t[%ld, %ld] (vDSO)\n",
+ (long int)prev.tv_sec, (long int)prev.tv_nsec,
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ skip_vdso:
+ prev = now;
+
+ clock_gettime64_syscall_nofail(CLOCK_ID, &now);
+
+ if (!timespec64_normalized(&now)) {
+ log_failure(ctx, "timestamp obtained from kernel "
+ "not normalized:\n"
+ "\t[%ld, %ld]\n",
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ if (!timespecs64_ordered(&prev, &now)) {
+ log_failure(ctx, "timestamp obtained from kernel "
+ "predates timestamp\n"
+ "previously obtained from libc/vDSO:\n"
+ "\t[%ld, %ld] (vDSO)\n"
+ "\t[%ld, %ld] (kernel)\n",
+ (long int)prev.tv_sec, (long int)prev.tv_nsec,
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ }
+
+ ctx_cleanup_timer(ctx);
+}
+
+static void clock_gettime64_bench(struct ctx *ctx, struct bench_results *res)
+{
+ struct timespec64 ts;
+
+ if (vdso_has_clock_gettime64()) {
+ BENCH(ctx, clock_gettime64_vdso_wrapper(CLOCK_ID, &ts),
+ &res->vdso_interval);
+ }
+
+/* BENCH(ctx, clock_gettime64(CLOCK_ID, &ts),
+ &res->libc_interval);
+*/
+ BENCH(ctx, clock_gettime64_syscall_wrapper(CLOCK_ID, &ts),
+ &res->sys_interval);
+}
+
+static void sys_clock_gettime64_simple(void *arg, struct syscall_result *res)
+{
+ int err;
+
+ syscall_prepare();
+ err = clock_gettime64_syscall_wrapper(CLOCK_ID, arg);
+ record_syscall_result(res, err, errno);
+}
+
+static void sys_clock_gettime64_prot(void *arg, struct syscall_result *res)
+{
+ void *buf;
+ int err;
+
+ buf = alloc_page((int)(unsigned long)arg);
+ syscall_prepare();
+ err = clock_gettime64_syscall_wrapper(CLOCK_ID, buf);
+ record_syscall_result(res, err, errno);
+ free_page(buf);
+}
+
+static void vdso_clock_gettime64_simple(void *arg, struct syscall_result *res)
+{
+ int err;
+
+ syscall_prepare();
+ err = clock_gettime64_vdso_wrapper(CLOCK_ID, arg);
+ record_syscall_result(res, err, errno);
+}
+
+static void vdso_clock_gettime64_prot(void *arg, struct syscall_result *res)
+{
+ void *buf;
+ int err;
+
+ buf = alloc_page((int)(unsigned long)arg);
+ syscall_prepare();
+ err = clock_gettime64_vdso_wrapper(CLOCK_ID, buf);
+ record_syscall_result(res, err, errno);
+ free_page(buf);
+}
+
+static void clock_gettime64_bogus_id(void *arg, struct syscall_result *res)
+{
+ struct timespec64 ts;
+ int err;
+
+ syscall_prepare();
+ err = arg ? clock_gettime64_syscall_wrapper((clockid_t)-1, &ts) :
+ clock_gettime64_vdso_wrapper((clockid_t)-1, &ts);
+
+ record_syscall_result(res, err, errno);
+}
+
+static void clock_gettime64_bogus_id_null(void *arg, struct syscall_result *res)
+{
+ int err;
+
+ syscall_prepare();
+ err = arg ? clock_gettime64_syscall_wrapper((clockid_t)-1, NULL) :
+ clock_gettime64_vdso_wrapper((clockid_t)-1, NULL);
+
+ record_syscall_result(res, err, errno);
+}
+
+static const struct child_params sys_clock_gettime64_abi_params[] = {
+
+ /* Kernel sanity checks */
+
+ {
+ .desc = "passing NULL to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_simple,
+ .arg = NULL,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ .desc = "passing UINTPTR_MAX to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_simple,
+ .arg = (void *)ADDR_SPACE_END,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ .desc = "passing PROT_NONE page to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_prot,
+ .arg = (void *)PROT_NONE,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ .desc = "passing PROT_READ page to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_prot,
+ .arg = (void *)PROT_READ,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ /* This will be duplicated across the different clock
+ * id modules. Oh well.
+ */
+ .desc = "passing bogus clock id to clock_gettime (syscall)",
+ .func = clock_gettime64_bogus_id,
+ .arg = (void *)true, /* force syscall */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+ {
+ /* This one too. */
+ .desc = "passing bogus clock id and NULL to clock_gettime (syscall)",
+ .func = clock_gettime64_bogus_id_null,
+ .arg = (void *)true, /* force syscall */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+};
+
+static const struct child_params vdso_clock_gettime64_abi_params[] = {
+ /* The below will be serviced by a vDSO, if present. */
+
+ {
+ .desc = "passing NULL to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_simple,
+ .arg = NULL,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ .desc = "passing UINTPTR_MAX to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_simple,
+ .arg = (void *)ADDR_SPACE_END,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ .desc = "passing PROT_NONE page to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_prot,
+ .arg = (void *)PROT_NONE,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ .desc = "passing PROT_READ page to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_prot,
+ .arg = (void *)PROT_READ,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ /* This will be duplicated across the different clock
+ * id modules. Oh well.
+ */
+ .desc = "passing bogus clock id to clock_gettime (VDSO)",
+ .func = clock_gettime64_bogus_id,
+ .arg = (void *)false, /* use vdso */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+ {
+ /* This one too. */
+ .desc = "passing bogus clock id and NULL to clock_gettime (VDSO)",
+ .func = clock_gettime64_bogus_id_null,
+ .arg = (void *)false, /* use vdso */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+};
+
+static void clock_gettime64_abi(struct ctx *ctx)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(sys_clock_gettime64_abi_params); i++)
+ run_as_child(ctx, &sys_clock_gettime64_abi_params[i]);
+
+ if (vdso_has_clock_gettime64()) {
+ for (i = 0; i < ARRAY_SIZE(vdso_clock_gettime64_abi_params); i++)
+ run_as_child(ctx, &vdso_clock_gettime64_abi_params[i]);
+ }
+}
+
+static void clock_gettime64_notes(struct ctx *ctx)
+{
+ if (!vdso_has_clock_gettime64())
+ printf("Note: vDSO version of clock_gettime64 not found\n");
+}
+
+static const char *clock_gettime64_vdso_names[] = {
+ "__kernel_clock_gettime64",
+ "__vdso_clock_gettime64",
+ NULL,
+};
+
+static void clock_gettime64_bind(void *sym)
+{
+ clock_gettime64_vdso = sym;
+}
+
+static const struct test_suite clock_gettime64_ts = {
+ .name = "clock-gettime64-" TS_SFX,
+ .bench = clock_gettime64_bench,
+ .verify = clock_gettime64_verify,
+ .abi = clock_gettime64_abi,
+ .notes = clock_gettime64_notes,
+ .vdso_names = clock_gettime64_vdso_names,
+ .bind = clock_gettime64_bind,
+};
+
+static void __constructor clock_gettime64_init(void)
+{
+ register_testsuite(&clock_gettime64_ts);
+}
base-commit: 7e4796a0695bdff3daca22630761264f5dff4680
--
2.25.0
^ permalink raw reply related
* [PATCH vdsotest] Add support for clock_gettime64() on powerpc32
From: Christophe Leroy @ 2020-05-09 16:12 UTC (permalink / raw)
To: nathan_lynch, arnd; +Cc: linuxppc-dev
libc test is commented out because at the time being
very few libc if any supports clock_gettime64()
syscall number is hardcoded when it doesn't exists in unistd.h
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
Based on master from https://github.com/nathanlynch/vdsotest.git
src/clock-boottime.c | 4 +
src/clock-monotonic-coarse.c | 4 +
src/clock-monotonic-raw.c | 4 +
src/clock-monotonic.c | 4 +
src/clock-realtime-coarse.c | 4 +
src/clock-realtime.c | 4 +
src/clock-tai.c | 4 +
src/clock_gettime64_template.c | 401 +++++++++++++++++++++++++++++++++
8 files changed, 429 insertions(+)
create mode 100644 src/clock_gettime64_template.c
diff --git a/src/clock-boottime.c b/src/clock-boottime.c
index 9fb1ac48501d..07ef31d08614 100644
--- a/src/clock-boottime.c
+++ b/src/clock-boottime.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-monotonic-coarse.c b/src/clock-monotonic-coarse.c
index ca1df58691ca..da064188756f 100644
--- a/src/clock-monotonic-coarse.c
+++ b/src/clock-monotonic-coarse.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-monotonic-raw.c b/src/clock-monotonic-raw.c
index 5dbb1842e698..55373b94ecfd 100644
--- a/src/clock-monotonic-raw.c
+++ b/src/clock-monotonic-raw.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-monotonic.c b/src/clock-monotonic.c
index 44318ae1e1c2..a900d24598a1 100644
--- a/src/clock-monotonic.c
+++ b/src/clock-monotonic.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-realtime-coarse.c b/src/clock-realtime-coarse.c
index 8f33f9a2d30b..8f2e6242bf0d 100644
--- a/src/clock-realtime-coarse.c
+++ b/src/clock-realtime-coarse.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-realtime.c b/src/clock-realtime.c
index 079fd801e654..ab76329a6676 100644
--- a/src/clock-realtime.c
+++ b/src/clock-realtime.c
@@ -3,3 +3,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock-tai.c b/src/clock-tai.c
index ad0448adeba5..cb2511039ddc 100644
--- a/src/clock-tai.c
+++ b/src/clock-tai.c
@@ -7,3 +7,7 @@
#include "clock_gettime_template.c"
#include "clock_getres_template.c"
+
+#if defined(__powerpc__) && !defined(__powerpc64__)
+#include "clock_gettime64_template.c"
+#endif
diff --git a/src/clock_gettime64_template.c b/src/clock_gettime64_template.c
new file mode 100644
index 000000000000..4752845148d6
--- /dev/null
+++ b/src/clock_gettime64_template.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright 2014 Mentor Graphics Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <errno.h>
+#include <error.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "compiler.h"
+#include "vdsotest.h"
+
+struct timespec64 {
+ long long tv_sec;
+ long tv_nsec;
+};
+
+#ifndef SYS_clock_gettime64
+#define SYS_clock_gettime64 403
+#endif
+
+static int (*clock_gettime64_vdso)(clockid_t id, struct timespec64 *ts);
+
+static bool vdso_has_clock_gettime64(void)
+{
+ return clock_gettime64_vdso != NULL;
+}
+
+static int clock_gettime64_syscall_wrapper(clockid_t id, struct timespec64 *ts)
+{
+ return syscall(SYS_clock_gettime64, id, ts);
+}
+
+static void clock_gettime64_syscall_nofail(clockid_t id, struct timespec64 *ts)
+{
+ int err;
+
+ err = clock_gettime64_syscall_wrapper(id, ts);
+ if (err)
+ error(EXIT_FAILURE, errno, "SYS_clock_gettime64");
+}
+
+static int clock_gettime64_vdso_wrapper(clockid_t id, struct timespec64 *ts)
+{
+ return DO_VDSO_CALL(clock_gettime64_vdso, int, 2, id, ts);
+}
+
+static void clock_gettime64_vdso_nofail(clockid_t id, struct timespec64 *ts)
+{
+ int err;
+
+ err = clock_gettime64_vdso_wrapper(id, ts);
+ if (err)
+ error(EXIT_FAILURE, errno, "clock_gettime");
+}
+
+static bool timespecs64_ordered(const struct timespec64 *first,
+ const struct timespec64 *second)
+{
+ if (first->tv_sec < second->tv_sec)
+ return true;
+
+ if (first->tv_sec == second->tv_sec)
+ return first->tv_nsec <= second->tv_nsec;
+
+ return false;
+}
+
+static bool timespec64_normalized(const struct timespec64 *ts)
+{
+ if (ts->tv_sec < 0)
+ return false;
+ if (ts->tv_nsec < 0)
+ return false;
+ if (ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
+ return true;
+}
+
+static void clock_gettime64_verify(struct ctx *ctx)
+{
+ struct timespec64 now;
+
+ clock_gettime64_syscall_nofail(CLOCK_ID, &now);
+
+ ctx_start_timer(ctx);
+
+ while (!test_should_stop(ctx)) {
+ struct timespec64 prev;
+
+ if (!vdso_has_clock_gettime64())
+ goto skip_vdso;
+
+ prev = now;
+
+ clock_gettime64_vdso_nofail(CLOCK_ID, &now);
+
+ if (!timespec64_normalized(&now)) {
+ log_failure(ctx, "timestamp obtained from libc/vDSO "
+ "not normalized:\n"
+ "\t[%ld, %ld]\n",
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ if (!timespecs64_ordered(&prev, &now)) {
+ log_failure(ctx, "timestamp obtained from libc/vDSO "
+ "predates timestamp\n"
+ "previously obtained from kernel:\n"
+ "\t[%ld, %ld] (kernel)\n"
+ "\t[%ld, %ld] (vDSO)\n",
+ (long int)prev.tv_sec, (long int)prev.tv_nsec,
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ skip_vdso:
+ prev = now;
+
+ clock_gettime64_syscall_nofail(CLOCK_ID, &now);
+
+ if (!timespec64_normalized(&now)) {
+ log_failure(ctx, "timestamp obtained from kernel "
+ "not normalized:\n"
+ "\t[%ld, %ld]\n",
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ if (!timespecs64_ordered(&prev, &now)) {
+ log_failure(ctx, "timestamp obtained from kernel "
+ "predates timestamp\n"
+ "previously obtained from libc/vDSO:\n"
+ "\t[%ld, %ld] (vDSO)\n"
+ "\t[%ld, %ld] (kernel)\n",
+ (long int)prev.tv_sec, (long int)prev.tv_nsec,
+ (long int)now.tv_sec, (long int)now.tv_nsec);
+ }
+
+ }
+
+ ctx_cleanup_timer(ctx);
+}
+
+static void clock_gettime64_bench(struct ctx *ctx, struct bench_results *res)
+{
+ struct timespec64 ts;
+
+ if (vdso_has_clock_gettime64()) {
+ BENCH(ctx, clock_gettime64_vdso_wrapper(CLOCK_ID, &ts),
+ &res->vdso_interval);
+ }
+
+/* BENCH(ctx, clock_gettime64(CLOCK_ID, &ts),
+ &res->libc_interval);
+*/
+ BENCH(ctx, clock_gettime64_syscall_wrapper(CLOCK_ID, &ts),
+ &res->sys_interval);
+}
+
+static void sys_clock_gettime64_simple(void *arg, struct syscall_result *res)
+{
+ int err;
+
+ syscall_prepare();
+ err = clock_gettime64_syscall_wrapper(CLOCK_ID, arg);
+ record_syscall_result(res, err, errno);
+}
+
+static void sys_clock_gettime64_prot(void *arg, struct syscall_result *res)
+{
+ void *buf;
+ int err;
+
+ buf = alloc_page((int)(unsigned long)arg);
+ syscall_prepare();
+ err = clock_gettime64_syscall_wrapper(CLOCK_ID, buf);
+ record_syscall_result(res, err, errno);
+ free_page(buf);
+}
+
+static void vdso_clock_gettime64_simple(void *arg, struct syscall_result *res)
+{
+ int err;
+
+ syscall_prepare();
+ err = clock_gettime64_vdso_wrapper(CLOCK_ID, arg);
+ record_syscall_result(res, err, errno);
+}
+
+static void vdso_clock_gettime64_prot(void *arg, struct syscall_result *res)
+{
+ void *buf;
+ int err;
+
+ buf = alloc_page((int)(unsigned long)arg);
+ syscall_prepare();
+ err = clock_gettime64_vdso_wrapper(CLOCK_ID, buf);
+ record_syscall_result(res, err, errno);
+ free_page(buf);
+}
+
+static void clock_gettime64_bogus_id(void *arg, struct syscall_result *res)
+{
+ struct timespec64 ts;
+ int err;
+
+ syscall_prepare();
+ err = arg ? clock_gettime64_syscall_wrapper((clockid_t)-1, &ts) :
+ clock_gettime64_vdso_wrapper((clockid_t)-1, &ts);
+
+ record_syscall_result(res, err, errno);
+}
+
+static void clock_gettime64_bogus_id_null(void *arg, struct syscall_result *res)
+{
+ int err;
+
+ syscall_prepare();
+ err = arg ? clock_gettime64_syscall_wrapper((clockid_t)-1, NULL) :
+ clock_gettime64_vdso_wrapper((clockid_t)-1, NULL);
+
+ record_syscall_result(res, err, errno);
+}
+
+static const struct child_params sys_clock_gettime64_abi_params[] = {
+
+ /* Kernel sanity checks */
+
+ {
+ .desc = "passing NULL to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_simple,
+ .arg = NULL,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ .desc = "passing UINTPTR_MAX to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_simple,
+ .arg = (void *)ADDR_SPACE_END,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ .desc = "passing PROT_NONE page to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_prot,
+ .arg = (void *)PROT_NONE,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ .desc = "passing PROT_READ page to clock_gettime (syscall)",
+ .func = sys_clock_gettime64_prot,
+ .arg = (void *)PROT_READ,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ },
+ {
+ /* This will be duplicated across the different clock
+ * id modules. Oh well.
+ */
+ .desc = "passing bogus clock id to clock_gettime (syscall)",
+ .func = clock_gettime64_bogus_id,
+ .arg = (void *)true, /* force syscall */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+ {
+ /* This one too. */
+ .desc = "passing bogus clock id and NULL to clock_gettime (syscall)",
+ .func = clock_gettime64_bogus_id_null,
+ .arg = (void *)true, /* force syscall */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+};
+
+static const struct child_params vdso_clock_gettime64_abi_params[] = {
+ /* The below will be serviced by a vDSO, if present. */
+
+ {
+ .desc = "passing NULL to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_simple,
+ .arg = NULL,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ .desc = "passing UINTPTR_MAX to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_simple,
+ .arg = (void *)ADDR_SPACE_END,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ .desc = "passing PROT_NONE page to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_prot,
+ .arg = (void *)PROT_NONE,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ .desc = "passing PROT_READ page to clock_gettime (VDSO)",
+ .func = vdso_clock_gettime64_prot,
+ .arg = (void *)PROT_READ,
+ .expected_ret = -1,
+ .expected_errno = EFAULT,
+ .signal_set = {
+ .mask = SIGNO_TO_BIT(SIGSEGV),
+ },
+ },
+ {
+ /* This will be duplicated across the different clock
+ * id modules. Oh well.
+ */
+ .desc = "passing bogus clock id to clock_gettime (VDSO)",
+ .func = clock_gettime64_bogus_id,
+ .arg = (void *)false, /* use vdso */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+ {
+ /* This one too. */
+ .desc = "passing bogus clock id and NULL to clock_gettime (VDSO)",
+ .func = clock_gettime64_bogus_id_null,
+ .arg = (void *)false, /* use vdso */
+ .expected_ret = -1,
+ .expected_errno = EINVAL,
+ },
+};
+
+static void clock_gettime64_abi(struct ctx *ctx)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(sys_clock_gettime64_abi_params); i++)
+ run_as_child(ctx, &sys_clock_gettime64_abi_params[i]);
+
+ if (vdso_has_clock_gettime64()) {
+ for (i = 0; i < ARRAY_SIZE(vdso_clock_gettime64_abi_params); i++)
+ run_as_child(ctx, &vdso_clock_gettime64_abi_params[i]);
+ }
+}
+
+static void clock_gettime64_notes(struct ctx *ctx)
+{
+ if (!vdso_has_clock_gettime64())
+ printf("Note: vDSO version of clock_gettime64 not found\n");
+}
+
+static const char *clock_gettime64_vdso_names[] = {
+ "__kernel_clock_gettime64",
+ "__vdso_clock_gettime64",
+ NULL,
+};
+
+static void clock_gettime64_bind(void *sym)
+{
+ clock_gettime64_vdso = sym;
+}
+
+static const struct test_suite clock_gettime64_ts = {
+ .name = "clock-gettime64-" TS_SFX,
+ .bench = clock_gettime64_bench,
+ .verify = clock_gettime64_verify,
+ .abi = clock_gettime64_abi,
+ .notes = clock_gettime64_notes,
+ .vdso_names = clock_gettime64_vdso_names,
+ .bind = clock_gettime64_bind,
+};
+
+static void __constructor clock_gettime64_init(void)
+{
+ register_testsuite(&clock_gettime64_ts);
+}
base-commit: 7e4796a0695bdff3daca22630761264f5dff4680
--
2.25.0
^ permalink raw reply related
* Re: [PATCH v8 8/8] powerpc/vdso: Provide __kernel_clock_gettime64() on vdso32
From: Christophe Leroy @ 2020-05-09 15:54 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Nathan Lynch, linux-arch, linux-kernel@vger.kernel.org,
Paul Mackerras, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, linuxppc-dev
In-Reply-To: <CAK8P3a2aXJRWjxWO8oMRX2AJkfeVeeoYbOPbpd9-UTgjqM4B7g@mail.gmail.com>
Le 28/04/2020 à 18:05, Arnd Bergmann a écrit :
> On Tue, Apr 28, 2020 at 3:16 PM Christophe Leroy
> <christophe.leroy@c-s.fr> wrote:
>>
>> Provides __kernel_clock_gettime64() on vdso32. This is the
>> 64 bits version of __kernel_clock_gettime() which is
>> y2038 compliant.
>>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>
> Looks good to me
>
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
>
> There was a bug on ARM for the corresponding function, so far it is unclear
> if this was a problem related to particular hardware, the 32-bit kernel code,
> or the common implementation of clock_gettime64 in the vdso library,
> see https://github.com/richfelker/musl-cross-make/issues/96
>
> Just to be sure that powerpc is not affected by the same issue, can you
> confirm that repeatedly calling clock_gettime64 on powerpc32, alternating
> between vdso and syscall, results in monotically increasing times?
>
I think that's one of the things vdsotest checks, so yes that's ok I think.
Christophe
^ permalink raw reply
* Re: ioremap() called early from pnv_pci_init_ioda_phb()
From: Christophe Leroy @ 2020-05-09 15:49 UTC (permalink / raw)
To: Qian Cai, Christophe Leroy, Michael Ellerman; +Cc: linuxppc-dev, LKML
In-Reply-To: <229E1896-0C06-418A-B7DE-40AEBFB44F85@lca.pw>
Le 08/05/2020 à 19:41, Qian Cai a écrit :
>
>
>> On May 8, 2020, at 10:39 AM, Qian Cai <cai@lca.pw> wrote:
>>
>> Booting POWER9 PowerNV has this message,
>>
>> "ioremap() called early from pnv_pci_init_ioda_phb+0x420/0xdfc. Use early_ioremap() instead”
>>
>> but use the patch below will result in leaks because it will never call early_iounmap() anywhere. However, it looks me it was by design that phb->regs mapping would be there forever where it would be used in pnv_ioda_get_inval_reg(), so is just that check_early_ioremap_leak() initcall too strong?
>>
>> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
>> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>> @@ -36,6 +36,7 @@
>> #include <asm/firmware.h>
>> #include <asm/pnv-pci.h>
>> #include <asm/mmzone.h>
>> +#include <asm/early_ioremap.h>
>>
>> #include <misc/cxl-base.h>
>>
>> @@ -3827,7 +3828,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
>> /* Get registers */
>> if (!of_address_to_resource(np, 0, &r)) {
>> phb->regs_phys = r.start;
>> - phb->regs = ioremap(r.start, resource_size(&r));
>> + phb->regs = early_ioremap(r.start, resource_size(&r));
>> if (phb->regs == NULL)
>> pr_err(" Failed to map registers !\n”);
>
> This will also trigger a panic with debugfs reads, so isn’t that this commit bogus at least for powerpc64?
>
> d538aadc2718 (“powerpc/ioremap: warn on early use of ioremap()")
No d538aadc2718 is not bogus. That's the point, we want to remove all
early usages of ioremap() in order to remove the hack with the
ioremap_bot stuff and all, and stick to the generic ioremap logic.
In order to do so, all early use of ioremap() has to be converted to
early_ioremap() or to fixmap or anything else that allows to do ioremaps
before the slab is ready.
early_ioremap() is for temporary mappings necessary at boottime. For
long lasting mappings, another method is to be used.
Now, the point is that other architectures like for instance x86 don't
seem to have to use early_ioremap() much. Powerpc is for instance doing
early mappings for PCI. Seems like x86 initialises PCI once slab is
ready. Can't powerpc do the same ?
Christophe
^ permalink raw reply
* Re: ioremap() called early from pnv_pci_init_ioda_phb()
From: Qian Cai @ 2020-05-09 15:37 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: linuxppc-dev, LKML
In-Reply-To: <1589013450.02gfmpktnp.astroid@bobo.none>
> On May 9, 2020, at 4:38 AM, Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Your patch to use early_ioremap is faulting? I wonder why?
Yes, I don’t know the reasons either. I suppose not many places in other parts of the kernel which keep using those addresses from early_ioremap() after system booted. Otherwise, we would see those leak warnings elsewhere.
Thus, we probably have to audit the code, and if still necessary, call early_ioremap() and then early_iounmap() followed by a ioremap() once slab allocator is available?
^ permalink raw reply
* Re: remove a few uses of ->queuedata
From: Dan Williams @ 2020-05-09 15:07 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, linux-xtensa, linux-raid, Sergey Senozhatsky,
linux-nvdimm, Geoff Levand, Linux Kernel Mailing List, Jim Paris,
linux-block, Minchan Kim, linux-m68k, Philip Kelleher,
linux-bcache, linuxppc-dev, Joshua Morris, Nitin Gupta, drbd-dev
In-Reply-To: <20200509082352.GB21834@lst.de>
On Sat, May 9, 2020 at 1:24 AM Christoph Hellwig <hch@lst.de> wrote:
>
> On Fri, May 08, 2020 at 11:04:45AM -0700, Dan Williams wrote:
> > On Fri, May 8, 2020 at 9:16 AM Christoph Hellwig <hch@lst.de> wrote:
> > >
> > > Hi all,
> > >
> > > various bio based drivers use queue->queuedata despite already having
> > > set up disk->private_data, which can be used just as easily. This
> > > series cleans them up to only use a single private data pointer.
> >
> > ...but isn't the queue pretty much guaranteed to be cache hot and the
> > gendisk cache cold? I'm not immediately seeing what else needs the
> > gendisk in the I/O path. Is there another motivation I'm missing?
>
> ->private_data is right next to the ->queue pointer, pat0 and part_tbl
> which are all used in the I/O submission path (generic_make_request /
> generic_make_request_checks). This is mostly a prep cleanup patch to
> also remove the pointless queue argument from ->make_request - then
> ->queue is an extra dereference and extra churn.
Ah ok. If the changelogs had been filled in with something like "In
preparation for removing @q from make_request_fn, stop using
->queuedata", I probably wouldn't have looked twice.
For the nvdimm/ driver updates you can add:
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
...or just let me know if you want me to pick those up through the nvdimm tree.
^ permalink raw reply
* Re: [PATCH 1/4] dma-mapping: move the remaining DMA API calls out of line
From: Alexey Kardashevskiy @ 2020-05-09 14:07 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Greg Kroah-Hartman, Joerg Roedel, linuxppc-dev, linux-kernel,
iommu, Robin Murphy, Lu Baolu
In-Reply-To: <20200509081946.GA21834@lst.de>
On 09/05/2020 18:19, Christoph Hellwig wrote:
> On Tue, May 05, 2020 at 02:18:37PM +1000, Alexey Kardashevskiy wrote:
>>
>>
>> On 17/04/2020 17:58, Christoph Hellwig wrote:
>>> On Wed, Apr 15, 2020 at 09:21:37PM +1000, Alexey Kardashevskiy wrote:
>>>> And the fact they were exported leaves possibility that there is a
>>>> driver somewhere relying on these symbols or distro kernel won't build
>>>> because the symbol disappeared from exports (I do not know what KABI
>>>> guarantees or if mainline kernel cares).
>>>
>>> We absolutely do not care. In fact for abuses of APIs that drivers
>>> should not use we almost care to make them private and break people
>>> abusing them.
>>
>> ok :)
>>
>>>> I do not care in particular but
>>>> some might, a line separated with empty lines in the commit log would do.
>>>
>>> I'll add a blurb for the next version.
>>
>>
>> Has it gone anywhere? Thanks,
>
> I've been hoping for the sg_buf helpers to land first, as they need
> backporting and would conflict. Do you urgently need the series?
Nah, not that urgent. Thanks,
--
Alexey
^ permalink raw reply
* Re: [PATCH v3] powerpc/64s/pgtable: fix an undefined behaviour
From: Qian Cai @ 2020-05-09 13:19 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, rashmicy, LKML
In-Reply-To: <952c3921-5aa8-bff5-9a87-baf5f901c535@c-s.fr>
> On Mar 6, 2020, at 1:56 AM, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
>
>
> Le 06/03/2020 à 05:48, Qian Cai a écrit :
>> Booting a power9 server with hash MMU could trigger an undefined
>> behaviour because pud_offset(p4d, 0) will do,
>> 0 >> (PAGE_SHIFT:16 + PTE_INDEX_SIZE:8 + H_PMD_INDEX_SIZE:10)
>> Fix it by converting pud_index() and friends to static inline
>> functions.
>> UBSAN: shift-out-of-bounds in arch/powerpc/mm/ptdump/ptdump.c:282:15
>> shift exponent 34 is too large for 32-bit type 'int'
>> CPU: 6 PID: 1 Comm: swapper/0 Not tainted 5.6.0-rc4-next-20200303+ #13
>> Call Trace:
>> dump_stack+0xf4/0x164 (unreliable)
>> ubsan_epilogue+0x18/0x78
>> __ubsan_handle_shift_out_of_bounds+0x160/0x21c
>> walk_pagetables+0x2cc/0x700
>> walk_pud at arch/powerpc/mm/ptdump/ptdump.c:282
>> (inlined by) walk_pagetables at arch/powerpc/mm/ptdump/ptdump.c:311
>> ptdump_check_wx+0x8c/0xf0
>> mark_rodata_ro+0x48/0x80
>> kernel_init+0x74/0x194
>> ret_from_kernel_thread+0x5c/0x74
>> Suggested-by: Christophe Leroy <christophe.leroy@c-s.fr>
>> Signed-off-by: Qian Cai <cai@lca.pw>
>
> Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
Michael, can you take a look at this patch when you have a chance? It looks falling through the cracks.
>
>> ---
>> v3: convert pud_index() etc to static inline functions.
>> v2: convert pud_offset() etc to static inline functions.
>> arch/powerpc/include/asm/book3s/64/pgtable.h | 23 ++++++++++++++++----
>> 1 file changed, 19 insertions(+), 4 deletions(-)
>> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
>> index 201a69e6a355..bd432c6706b9 100644
>> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
>> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
>> @@ -998,10 +998,25 @@ extern struct page *pgd_page(pgd_t pgd);
>> #define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS)
>> #define pgd_page_vaddr(pgd) __va(pgd_val(pgd) & ~PGD_MASKED_BITS)
>> -#define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1))
>> -#define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1))
>> -#define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1))
>> -#define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1))
>> +static inline unsigned long pgd_index(unsigned long address)
>> +{
>> + return (address >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1);
>> +}
>> +
>> +static inline unsigned long pud_index(unsigned long address)
>> +{
>> + return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
>> +}
>> +
>> +static inline unsigned long pmd_index(unsigned long address)
>> +{
>> + return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
>> +}
>> +
>> +static inline unsigned long pte_index(unsigned long address)
>> +{
>> + return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
>> +}
>> /*
>> * Find an entry in a page-table-directory. We combine the address region
^ permalink raw reply
* Re: [PATCH -next] soc: fsl: dpio: remove set but not used variable 'addr_cena'
From: Yuehaibing @ 2020-05-09 11:07 UTC (permalink / raw)
To: Roy.Pledge, leoyang.li, youri.querry_1
Cc: linuxppc-dev, linux-kernel, linux-arm-kernel
In-Reply-To: <20200508141028.38124-1-yuehaibing@huawei.com>
Pls ignore this duplicate.
On 2020/5/8 22:10, YueHaibing wrote:
> drivers/soc/fsl/dpio//qbman-portal.c:650:11: warning: variable 'addr_cena' set but not used [-Wunused-but-set-variable]
> uint64_t addr_cena;
> ^~~~~~~~~
>
> It is never used, so remove it.
>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> drivers/soc/fsl/dpio/qbman-portal.c | 2 --
> 1 file changed, 2 deletions(-)
>
> diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c
> index e2e9fbb58a72..0ce859b60888 100644
> --- a/drivers/soc/fsl/dpio/qbman-portal.c
> +++ b/drivers/soc/fsl/dpio/qbman-portal.c
> @@ -647,7 +647,6 @@ int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
> const uint32_t *cl = (uint32_t *)d;
> uint32_t eqcr_ci, eqcr_pi, half_mask, full_mask;
> int i, num_enqueued = 0;
> - uint64_t addr_cena;
>
> spin_lock(&s->access_spinlock);
> half_mask = (s->eqcr.pi_ci_mask>>1);
> @@ -700,7 +699,6 @@ int qbman_swp_enqueue_multiple_direct(struct qbman_swp *s,
>
> /* Flush all the cacheline without load/store in between */
> eqcr_pi = s->eqcr.pi;
> - addr_cena = (size_t)s->addr_cena;
> for (i = 0; i < num_enqueued; i++)
> eqcr_pi++;
> s->eqcr.pi = eqcr_pi & full_mask;
>
^ permalink raw reply
* Re: [PATCH 01/15] nfblock: use gendisk private_data
From: Geert Uytterhoeven @ 2020-05-09 10:38 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Jens Axboe, open list:TENSILICA XTENSA PORT (xtensa), linux-raid,
Sergey Senozhatsky, linux-nvdimm@lists.01.org, Geoff Levand,
Linux Kernel Mailing List, Jim Paris, linux-block, Minchan Kim,
linux-m68k, Philip Kelleher, linux-bcache, linuxppc-dev,
Joshua Morris, Nitin Gupta, Lars Ellenberg
In-Reply-To: <20200508161517.252308-2-hch@lst.de>
Hi Christoph,
On Fri, May 8, 2020 at 6:16 PM Christoph Hellwig <hch@lst.de> wrote:
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Thanks for your patch!
> --- a/arch/m68k/emu/nfblock.c
> +++ b/arch/m68k/emu/nfblock.c
> @@ -61,7 +61,7 @@ struct nfhd_device {
>
> static blk_qc_t nfhd_make_request(struct request_queue *queue, struct bio *bio)
> {
> - struct nfhd_device *dev = queue->queuedata;
> + struct nfhd_device *dev = bio->bi_disk->private_data;
> struct bio_vec bvec;
> struct bvec_iter iter;
> int dir, len, shift;
> @@ -122,7 +122,6 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
> if (dev->queue == NULL)
> goto free_dev;
>
> - dev->queue->queuedata = dev;
> blk_queue_logical_block_size(dev->queue, bsize);
>
> dev->disk = alloc_disk(16);
> @@ -136,6 +135,7 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
> sprintf(dev->disk->disk_name, "nfhd%u", dev_id);
> set_capacity(dev->disk, (sector_t)blocks * (bsize / 512));
> dev->disk->queue = dev->queue;
> + dev->disk->private_data = dev;
This is already set above, just before the quoted sprintf() call.
>
> add_disk(dev->disk);
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH fixes] powerpc/vdso32: Fallback on getres syscall when clock is unknown
From: Christophe Leroy @ 2020-05-09 9:42 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Aurelien Jarno
Cc: linuxppc-dev, linux-kernel
There are other clocks than the standard ones, for instance
per process clocks. Therefore, being above the last standard clock
doesn't mean it is a bad clock. So, fallback to syscall instead
of returning -EINVAL inconditionaly.
Fixes: e33ffc956b08 ("powerpc/vdso32: implement clock_getres entirely")
Cc: stable@vger.kernel.org
Reported-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/vdso32/gettimeofday.S | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index a3951567118a..e7f8f9f1b3f4 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -218,11 +218,11 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
blr
/*
- * invalid clock
+ * syscall fallback
*/
99:
- li r3, EINVAL
- crset so
+ li r0,__NR_clock_getres
+ sc
blr
.cfi_endproc
V_FUNCTION_END(__kernel_clock_getres)
--
2.25.0
^ permalink raw reply related
* Re: [PATCH RFC 2/4] powerpc: Add Microwatt platform
From: Nicholas Piggin @ 2020-05-09 9:10 UTC (permalink / raw)
To: Alistair Popple, linuxppc-dev
Cc: linuxppc-dev, Michael Neuling, Benjamin Herrenschmidt
In-Reply-To: <2771261.oJVn4HZnso@townsend>
Excerpts from Alistair Popple's message of May 9, 2020 6:36 pm:
> On Saturday, 9 May 2020 5:58:57 PM AEST Nicholas Piggin wrote:
>> Excerpts from Paul Mackerras's message of May 9, 2020 3:02 pm:
>> > Microwatt is a FPGA-based implementation of the Power ISA. It
>> > currently only implements little-endian 64-bit mode, and does
>> > not (yet) support SMP.
>> >
>> > This adds a new machine type to support FPGA-based SoCs with a
>> > Microwatt core.
>>
>> Very cool!
>>
>> Would there be any point sharing this with the "naked metal" platform
>> Alistair has for booting POWER in L3 without OPAL? Or is it easy enough
>> to have a several different simple 64s platforms?
>
> It looks pretty similar at the moment, I've been meaning to clean those
> patches up and send them upstream but Paul has beaten me to it. The main
> difference so far is how the console is setup. For booting cache contained I
> was using a device tree pointing at a standard UART driver and enabling the
> standard OF platform device tree probing.
Well I'd only merge them if you think it makes sense. If the platform is
a perfectly good abstraction for the differences and merging them would
just result in painful special cases it wouldn't be worthwhile. It's
clearly not a lot of code.
Thanks,
Nick
^ permalink raw reply
* Re: ioremap() called early from pnv_pci_init_ioda_phb()
From: Nicholas Piggin @ 2020-05-09 8:43 UTC (permalink / raw)
To: Qian Cai, Oliver O'Halloran; +Cc: linuxppc-dev, LKML
In-Reply-To: <CAOSf1CFNp6+k_y_87r7p2e8cKfX0rK-9wBxeR+K0e0y8R0_TNg@mail.gmail.com>
Excerpts from Oliver O'Halloran's message of May 9, 2020 6:11 pm:
> On Sat, May 9, 2020 at 12:41 AM Qian Cai <cai@lca.pw> wrote:
>>
>> Booting POWER9 PowerNV has this message,
>>
>> "ioremap() called early from pnv_pci_init_ioda_phb+0x420/0xdfc. Use early_ioremap() instead”
>>
>> but use the patch below will result in leaks because it will never call early_iounmap() anywhere. However, it looks me it was by design that phb->regs mapping would be there forever where it would be used in pnv_ioda_get_inval_reg(), so is just that check_early_ioremap_leak() initcall too strong?
>
> The warning there is junk. The PHBs are setup at boot and never torn
> down so we're not "leaking" the mapping. It's supposed to be there for
> the lifetime of the kernel.
>
> That said, we could probably move the PCI setup to a point later in
> boot where the normal ioremap can be be used. We would have to check
> for initcalls which depend on the PHBs being setup and delay those too
> though.
I think it helps to unify code a bit more and take special cases out of
ioremap to have all these early calls use early_ioremap.
We actually do want to move these later if possible too, on radix they
use memblock for page tables, and on hash they don't even set up proper
kernel page tables but just bolt PTEs into the hash table.
Thanks,
Nick
^ permalink raw reply
* [PATCH 09/15, fіxed] lightnvm: stop using ->queuedata
From: Christoph Hellwig @ 2020-05-09 8:38 UTC (permalink / raw)
To: Jens Axboe
Cc: linux-bcache, linux-xtensa, linux-raid, Sergey Senozhatsky,
linux-nvdimm, Geoff Levand, linux-kernel, Jim Paris, linux-block,
Minchan Kim, linux-m68k, Philip Kelleher, linuxppc-dev,
Joshua Morris, Nitin Gupta, drbd-dev
In-Reply-To: <20200508161517.252308-10-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
fixed the compilation in the print_ppa arguments
drivers/lightnvm/core.c | 1 -
drivers/lightnvm/pblk-init.c | 2 +-
drivers/lightnvm/pblk.h | 2 +-
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index db38a68abb6c0..85c5490cdfd2e 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -400,7 +400,6 @@ static int nvm_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create)
}
tdisk->private_data = targetdata;
- tqueue->queuedata = targetdata;
mdts = (dev->geo.csecs >> 9) * NVM_MAX_VLBA;
if (dev->geo.mdts) {
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 9a967a2e83dd7..bec904ec0f7c0 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -49,7 +49,7 @@ struct bio_set pblk_bio_set;
static blk_qc_t pblk_make_rq(struct request_queue *q, struct bio *bio)
{
- struct pblk *pblk = q->queuedata;
+ struct pblk *pblk = bio->bi_disk->private_data;
if (bio_op(bio) == REQ_OP_DISCARD) {
pblk_discard(pblk, bio);
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 86ffa875bfe16..49718105bc0dc 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -1255,7 +1255,7 @@ static inline int pblk_boundary_ppa_checks(struct nvm_tgt_dev *tgt_dev,
continue;
}
- print_ppa(tgt_dev->q->queuedata, ppa, "boundary", i);
+ print_ppa(tgt_dev->disk->q->private_data, ppa, "boundary", i);
return 1;
}
--
2.26.2
^ permalink raw reply related
* Re: ioremap() called early from pnv_pci_init_ioda_phb()
From: Nicholas Piggin @ 2020-05-09 8:38 UTC (permalink / raw)
To: Qian Cai, Christophe Leroy, Michael Ellerman; +Cc: linuxppc-dev, LKML
In-Reply-To: <229E1896-0C06-418A-B7DE-40AEBFB44F85@lca.pw>
Excerpts from Qian Cai's message of May 9, 2020 3:41 am:
>
>
>> On May 8, 2020, at 10:39 AM, Qian Cai <cai@lca.pw> wrote:
>>
>> Booting POWER9 PowerNV has this message,
>>
>> "ioremap() called early from pnv_pci_init_ioda_phb+0x420/0xdfc. Use early_ioremap() instead”
>>
>> but use the patch below will result in leaks because it will never call early_iounmap() anywhere. However, it looks me it was by design that phb->regs mapping would be there forever where it would be used in pnv_ioda_get_inval_reg(), so is just that check_early_ioremap_leak() initcall too strong?
>>
>> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
>> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
>> @@ -36,6 +36,7 @@
>> #include <asm/firmware.h>
>> #include <asm/pnv-pci.h>
>> #include <asm/mmzone.h>
>> +#include <asm/early_ioremap.h>
>>
>> #include <misc/cxl-base.h>
>>
>> @@ -3827,7 +3828,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
>> /* Get registers */
>> if (!of_address_to_resource(np, 0, &r)) {
>> phb->regs_phys = r.start;
>> - phb->regs = ioremap(r.start, resource_size(&r));
>> + phb->regs = early_ioremap(r.start, resource_size(&r));
>> if (phb->regs == NULL)
>> pr_err(" Failed to map registers !\n”);
>
> This will also trigger a panic with debugfs reads, so isn’t that this commit bogus at least for powerpc64?
Your patch to use early_ioremap is faulting? I wonder why?
Thanks,
Nick
>
> d538aadc2718 (“powerpc/ioremap: warn on early use of ioremap()")
>
> 11017.617022][T122068] Faulting instruction address: 0xc0000000000db564
> [11017.617257][T122066] Faulting instruction address: 0xc0000000000db564
> [11017.617950][T122073] Faulting instruction address: 0xc0000000000db564
> [11017.618888][T122064] BUG: Unable to handle kernel data access on read at 0xffffffffffe20e10
> [11017.618935][T122064] Faulting instruction address: 0xc0000000000db564
> [11017.737996][T122072]
> [11017.738010][T122073] Oops: Kernel access of bad area, sig: 11 [#2]
> [11017.738024][T122073] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=256 DEBUG_PAGEALLOC NUMA PowerNV
> [11017.738051][T122073] Modules linked in: brd ext4 crc16 mbcache jbd2 loop kvm_hv kvm ip_tables x_tables xfs sd_mod bnx2x ahci libahci tg3 mdio libata libphy firmware_class dm_mirror dm_region_hash dm_log dm_mod
> [11017.738110][T122073] CPU: 108 PID: 122073 Comm: read_all Tainted: G D W 5.7.0-rc4-next-20200508+ #4
> [11017.738138][T122073] NIP: c0000000000db564 LR: c00000000056f660 CTR: c0000000000db550
> [11017.738173][T122073] REGS: c000000374f6f980 TRAP: 0380 Tainted: G D W (5.7.0-rc4-next-20200508+)
> [11017.738234][T122073] MSR: 9000000000009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: 22002282 XER: 20040000
> [11017.738278][T122073] CFAR: c00000000056f65c IRQMASK: 0
> [11017.738278][T122073] GPR00: c00000000056f660 c000000374f6fc10 c000000001689400 c000201ffc41aa00
> [11017.738278][T122073] GPR04: c000000374f6fc70 0000000000000000 0000000000000000 0000000000000001
> [11017.738278][T122073] GPR08: 0000000000000000 ffffffffffe20000 0000000000000000 c0000008ee380080
> [11017.738278][T122073] GPR12: c0000000000db550 c000201fff671280 0000000000000000 0000000000000000
> [11017.738278][T122073] GPR16: 0000000000000002 0000000010040800 000000001001ccd8 000000001001cc80
> [11017.738278][T122073] GPR20: 000000001001cc98 000000001001ccc8 000000001001cca8 000000001001cb48
> [11017.738278][T122073] GPR24: 0000000000000000 0000000000000000 00000000000003ff 00007fffebb67390
> [11017.738278][T122073] GPR28: c000000374f6fd90 c000200c0c6a7550 0000000000000000 c000200c0c6a7500
> [11017.738542][T122073] NIP [c0000000000db564] pnv_eeh_dbgfs_get_inbB+0x14/0x30
> [11017.738579][T122073] LR [c00000000056f660] simple_attr_read+0xa0/0x180
> [11017.738613][T122073] Call Trace:
> [11017.738645][T122073] [c000000374f6fc10] [c00000000056f630] simple_attr_read+0x70/0x180 (unreliable)
> [11017.738672][T122073] [c000000374f6fcb0] [c00000000064a2e0] full_proxy_read+0x90/0xe0
> [11017.738686][T122073] [c000000374f6fd00] [c00000000051fe0c] __vfs_read+0x3c/0x70
> [11017.738722][T122073] [c000000374f6fd20] [c00000000051feec] vfs_read+0xac/0x170
> [11017.738757][T122073] [c000000374f6fd70] [c00000000052034c] ksys_read+0x7c/0x140
> [11017.738818][T122073] [c000000374f6fdc0] [c000000000038af4] system_call_exception+0x114/0x1e0
> [11017.738867][T122073] [c000000374f6fe20] [c00000000000c8f0] system_call_common+0xf0/0x278
> [11017.738916][T122073] Instruction dump:
> [11017.738948][T122073] 7c0004ac f9490d10 a14d0c78 38600000 b14d0c7a 4e800020 60000000 7c0802a6
> [11017.739001][T122073] 60000000 e9230278 e9290028 7c0004ac <e9290e10> 0c090000 4c00012c 38600000
^ permalink raw reply
* Re: [PATCH RFC 2/4] powerpc: Add Microwatt platform
From: Alistair Popple @ 2020-05-09 8:36 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Neuling, Nicholas Piggin, Benjamin Herrenschmidt,
linuxppc-dev
In-Reply-To: <1589010752.ygtog0nhjc.astroid@bobo.none>
On Saturday, 9 May 2020 5:58:57 PM AEST Nicholas Piggin wrote:
> Excerpts from Paul Mackerras's message of May 9, 2020 3:02 pm:
> > Microwatt is a FPGA-based implementation of the Power ISA. It
> > currently only implements little-endian 64-bit mode, and does
> > not (yet) support SMP.
> >
> > This adds a new machine type to support FPGA-based SoCs with a
> > Microwatt core.
>
> Very cool!
>
> Would there be any point sharing this with the "naked metal" platform
> Alistair has for booting POWER in L3 without OPAL? Or is it easy enough
> to have a several different simple 64s platforms?
It looks pretty similar at the moment, I've been meaning to clean those
patches up and send them upstream but Paul has beaten me to it. The main
difference so far is how the console is setup. For booting cache contained I
was using a device tree pointing at a standard UART driver and enabling the
standard OF platform device tree probing.
- Alistair
> I have an HPT conditional compile patch and a few other diet Kconfig
> things I'll now be better justified to try get merged :)
>
> Thanks,
> Nick
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox