This patch series adds test coverage for BPF sockaddr hooks and their
interactions with kernel socket functions (i.e. kernel_bind(),
kernel_connect(), kernel_sendmsg(), sock_sendmsg(),
kernel_getpeername(), and kernel_getsockname()) while also rounding out
IPv4 and IPv6 sockaddr hook coverage in prog_tests/sock_addr.c.
As with v1 of this patch series, we add regression coverage for the
issues addressed by these patches,
- commit 0bdf399342c5("net: Avoid address overwrite in kernel_connect")
- commit 86a7e0b69bd5("net: prevent rewrite of msg_name in sock_sendmsg()")
- commit c889a99a21bf("net: prevent address rewrite in kernel_bind()")
- commit 01b2885d9415("net: Save and restore msg_namelen in sock_sendmsg")
but broaden the focus a bit.
In order to extend prog_tests/sock_addr.c to test these kernel
functions, we add a set of new kfuncs that wrap individual socket
operations to bpf_testmod and invoke them through set of corresponding
SYSCALL programs (progs/sock_addr_kern.c). Each test case can be
configured to use a different set of "sock_ops" depending on whether it
is testing kernel calls (kernel_bind(), kernel_connect(), etc.) or
system calls (bind(), connect(), etc.).
=======
Patches
=======
* Patch 1 fixes the sock_addr bind test program to work for big endian
architectures such as s390x.
* Patch 2 introduces the new kfuncs to bpf_testmod.
* Patch 3 introduces the BPF program which allows us to invoke these
kfuncs invividually from the test program.
* Patch 4 lays the groundwork for IPv4 and IPv6 sockaddr hook coverage
by migrating much of the environment setup logic from
bpf/test_sock_addr.sh into prog_tests/sock_addr.c and adds test cases
to cover bind4/6, connect4/6, sendmsg4/6 and recvmsg4/6 hooks.
* Patch 5 makes the set of socket operations for each test case
configurable, laying the groundwork for Patch 6.
* Patch 6 introduces two sets of sock_ops that invoke the kernel
equivalents of connect(), bind(), etc. and uses these to add coverage
for the kernel socket functions.
=======
Changes
=======
v1->v2
------
* Dropped test_progs/sock_addr_kern.c and the sock_addr_kern test module
in favor of simply expanding bpf_testmod and test_progs/sock_addr.c.
* Migrated environment setup logic from bpf/test_sock_addr.sh into
prog_tests/sock_addr.c rather than invoking the script from the test
program.
* Added kfuncs to bpf_testmod as well as the sock_addr_kern BPF program
to enable us to invoke kernel socket functions from
test_progs/sock_addr.c.
* Added test coverage for kernel socket functions to
test_progs/sock_addr.c.
Link: https://lore.kernel.org/bpf/20240329191907.1808635-1-jrife@google.com/T/#u
Jordan Rife (6):
selftests/bpf: Fix bind program for big endian systems
selftests/bpf: Implement socket kfuncs for bpf_testmod
selftests/bpf: Implement BPF programs for kernel socket operations
selftests/bpf: Add IPv4 and IPv6 sockaddr test cases
selftests/bpf: Make sock configurable for each test case
selftests/bpf: Add kernel socket operation tests
.../selftests/bpf/bpf_testmod/bpf_testmod.c | 139 +++
.../bpf/bpf_testmod/bpf_testmod_kfunc.h | 27 +
.../selftests/bpf/prog_tests/sock_addr.c | 940 +++++++++++++++---
.../testing/selftests/bpf/progs/bind4_prog.c | 18 +-
.../testing/selftests/bpf/progs/bind6_prog.c | 18 +-
tools/testing/selftests/bpf/progs/bind_prog.h | 19 +
.../selftests/bpf/progs/sock_addr_kern.c | 65 ++
7 files changed, 1077 insertions(+), 149 deletions(-)
create mode 100644 tools/testing/selftests/bpf/progs/bind_prog.h
create mode 100644 tools/testing/selftests/bpf/progs/sock_addr_kern.c
--
2.44.0.478.gd926399ef9-goog
Clean up the KVM clock mess somewhat so that it is either based on the guest
TSC ("master clock" mode), or on the host CLOCK_MONOTONIC_RAW in cases where
the TSC isn't usable.
Eliminate the third variant where it was based directly on the *host* TSC,
due to bugs in e.g. __get_kvmclock().
Kill off the last vestiges of the KVM clock being based on CLOCK_MONOTONIC
instead of CLOCK_MONOTONIC_RAW and thus being subject to NTP skew.
Fix up migration support to allow the KVM clock to be saved/restored as an
arithmetic function of the guest TSC, since that's what it actually is in
the *common* case so it can be migrated precisely. Or at least to within
±1 ns which is good enough, as discussed in
https://lore.kernel.org/kvm/c8dca08bf848e663f192de6705bf04aa3966e856.camel@…
In v2 of this series, TSC synchronization is improved and simplified a bit
too, and we allow masterclock mode to be used even when the guest TSCs are
out of sync, as long as they're running at the same *rate*. The different
*offset* shouldn't matter.
And the kvm_get_time_scale() function annoyed me by being entirely opaque,
so I studied it until my brain hurt and then added some comments.
In v2 I also dropped the commits which were removing the periodic clock
syncs. Those are going to be needed still but *only* for non-masterclock
mode, which I'll do next. Along with ensuring that a masterclock update
while already in masterclock mode doesn't jump the clock, and just does
the same as KVM_SET_CLOCK_GUEST does to preserve it.
Needs a *lot* more testing. I think I'm almost done refactoring the code,
so should focus on building up the tests next.
(I do still hate that we're abusing KVM_GET_CLOCK just to get the tuple
of {host_tsc, CLOCK_REALTIME} without even *caring* about the eponymous
KVM clock. Especially as this information is (a) fundamentally what the
vDSO gettimeofday() exposes to us anyway, (b) using CLOCK_REALTIME not
TAI, (c) not available on other platforms, for example for migrating
the Arm arch counter.)
David Woodhouse (13):
KVM: x86/xen: Do not corrupt KVM clock in kvm_xen_shared_info_init()
KVM: x86: Improve accuracy of KVM clock when TSC scaling is in force
KVM: x86: Explicitly disable TSC scaling without CONSTANT_TSC
KVM: x86: Add KVM_VCPU_TSC_SCALE and fix the documentation on TSC migration
KVM: x86: Avoid NTP frequency skew for KVM clock on 32-bit host
KVM: x86: Fix KVM clock precision in __get_kvmclock()
KVM: x86: Fix software TSC upscaling in kvm_update_guest_time()
KVM: x86: Simplify and comment kvm_get_time_scale()
KVM: x86: Remove implicit rdtsc() from kvm_compute_l1_tsc_offset()
KVM: x86: Improve synchronization in kvm_synchronize_tsc()
KVM: x86: Kill cur_tsc_{nsec,offset,write} fields
KVM: x86: Allow KVM master clock mode when TSCs are offset from each other
KVM: x86: Factor out kvm_use_master_clock()
Jack Allister (2):
KVM: x86: Add KVM_[GS]ET_CLOCK_GUEST for accurate KVM clock migration
KVM: selftests: Add KVM/PV clock selftest to prove timer correction
Documentation/virt/kvm/api.rst | 37 ++
Documentation/virt/kvm/devices/vcpu.rst | 115 +++-
arch/x86/include/asm/kvm_host.h | 15 +-
arch/x86/include/uapi/asm/kvm.h | 6 +
arch/x86/kvm/svm/svm.c | 3 +-
arch/x86/kvm/vmx/vmx.c | 2 +-
arch/x86/kvm/x86.c | 687 +++++++++++++++-------
arch/x86/kvm/xen.c | 4 +-
include/uapi/linux/kvm.h | 3 +
tools/testing/selftests/kvm/Makefile | 1 +
tools/testing/selftests/kvm/x86_64/pvclock_test.c | 192 ++++++
11 files changed, 822 insertions(+), 243 deletions(-)
This patch series ended up much larger than expected, please bear with
me! The goal here is to support vendor extensions, starting at probing
the device tree and ending with reporting to userspace.
The main design objective was to allow vendors to operate independently
of each other. This has been achieved by delegating vendor extensions to
a their own files and then accumulating the extensions in
arch/riscv/kernel/vendor_extensions.c.
Each vendor will have their own list of extensions they support.
There is a new hwprobe key RISCV_HWPROBE_KEY_VENDOR_EXT_THEAD_0 that is
used to request which thead vendor extensions are supported on the
current platform. This allows future vendors to allocate hwprobe keys
for their vendor.
On to the xtheadvector specific code. xtheadvector is a custom extension
that is based upon riscv vector version 0.7.1 [1]. All of the vector
routines have been modified to support this alternative vector version
based upon whether xtheadvector was determined to be supported at boot.
I have tested this with an Allwinner Nezha board. I ran into issues
booting the board on 6.9-rc1 so I applied these patches to 6.8. There
are a couple of minor merge conflicts that do arrise when doing that, so
please let me know if you have been able to boot this board with a 6.9
kernel. I used SkiffOS [2] to manage building the image, but upgraded
the U-Boot version to Samuel Holland's more up-to-date version [3] and
changed out the device tree used by U-Boot with the device trees that
are present in upstream linux and this series. Thank you Samuel for all
of the work you did to make this task possible.
To test the integration, I used the riscv vector kselftests. I modified
the test cases to be able to more easily extend them, and then added a
xtheadvector target that works by calling hwprobe and swapping out the
vector asm if needed.
[1] https://github.com/T-head-Semi/thead-extension-spec/blob/95358cb2cca9489361…
[2] https://github.com/skiffos/SkiffOS/tree/master/configs/allwinner/nezha
[3] https://github.com/smaeul/u-boot/commit/2e89b706f5c956a70c989cd31665f1429e9…
Signed-off-by: Charlie Jenkins <charlie(a)rivosinc.com>
---
Changes in v4:
- Disable vector immediately if vlenb from the device tree is not
homogeneous
- Hide vendor extension code behind a hidden config that vendor
extensions select to eliminate the code when kernel is compiled
without vendor extensions
- Clear up naming conventions and introduce some defines to make the
vendor extension code clearer
- Link to v3: https://lore.kernel.org/r/20240420-dev-charlie-support_thead_vector_6_9-v3-…
Changes in v3:
- Allow any hardware to support any vendor extension, rather than
restricting the vendor extensions to the same vendor as the hardware
- Introduce config options to enable/disable a vendor's extensions
- Link to v2: https://lore.kernel.org/r/20240415-dev-charlie-support_thead_vector_6_9-v2-…
Changes in v2:
- Added commit hash to xtheadvector
- Simplified riscv,isa vector removal fix to not mess with the DT
riscv,vendorid
- Moved riscv,vendorid parsing into a different patch and cache the
value to be used by alternative patching
- Reduce riscv,vendorid missing severity to "info"
- Separate vendor extension list to vendor files
- xtheadvector no longer puts v in the elf_hwcap
- Only patch vendor extension if all harts are associated with the same
vendor. This is the best chance the kernel has for working properly if
there are multiple vendors.
- Split hwprobe vendor keys out into vendor file
- Add attribution for Heiko's patches
- Link to v1: https://lore.kernel.org/r/20240411-dev-charlie-support_thead_vector_6_9-v1-…
---
Charlie Jenkins (14):
dt-bindings: riscv: Add xtheadvector ISA extension description
riscv: vector: Use vlenb from DT
riscv: dts: allwinner: Add xtheadvector to the D1/D1s devicetree
riscv: Extend cpufeature.c to detect vendor extensions
riscv: Introduce vendor variants of extension helpers
riscv: cpufeature: Extract common elements from extension checking
riscv: Convert xandespmu to use the vendor extension framework
riscv: csr: Add CSR encodings for VCSR_VXRM/VCSR_VXSAT
riscv: Add xtheadvector instruction definitions
riscv: vector: Support xtheadvector save/restore
riscv: hwprobe: Add thead vendor extension probing
riscv: hwprobe: Document thead vendor extensions and xtheadvector extension
selftests: riscv: Fix vector tests
selftests: riscv: Support xtheadvector in vector tests
Conor Dooley (1):
dt-bindings: riscv: cpus: add a vlen register length property
Heiko Stuebner (1):
RISC-V: define the elements of the VCSR vector CSR
Documentation/arch/riscv/hwprobe.rst | 10 +
Documentation/devicetree/bindings/riscv/cpus.yaml | 6 +
.../devicetree/bindings/riscv/extensions.yaml | 10 +
arch/riscv/Kconfig | 2 +
arch/riscv/Kconfig.vendor | 44 +++
arch/riscv/boot/dts/allwinner/sun20i-d1s.dtsi | 3 +-
arch/riscv/errata/andes/errata.c | 2 +
arch/riscv/errata/sifive/errata.c | 3 +
arch/riscv/errata/thead/errata.c | 3 +
arch/riscv/include/asm/cpufeature.h | 98 ++++---
arch/riscv/include/asm/csr.h | 13 +
arch/riscv/include/asm/hwcap.h | 1 -
arch/riscv/include/asm/hwprobe.h | 4 +-
arch/riscv/include/asm/switch_to.h | 2 +-
arch/riscv/include/asm/vector.h | 247 +++++++++++++----
arch/riscv/include/asm/vendor_extensions.h | 95 +++++++
arch/riscv/include/asm/vendor_extensions/andes.h | 19 ++
arch/riscv/include/asm/vendor_extensions/thead.h | 45 ++++
.../include/asm/vendor_extensions/thead_hwprobe.h | 11 +
arch/riscv/include/uapi/asm/hwprobe.h | 3 +-
arch/riscv/include/uapi/asm/vendor/thead.h | 3 +
arch/riscv/kernel/Makefile | 2 +
arch/riscv/kernel/cpufeature.c | 155 ++++++++---
arch/riscv/kernel/kernel_mode_vector.c | 8 +-
arch/riscv/kernel/process.c | 4 +-
arch/riscv/kernel/signal.c | 6 +-
arch/riscv/kernel/sys_hwprobe.c | 9 +
arch/riscv/kernel/vector.c | 25 +-
arch/riscv/kernel/vendor_extensions.c | 69 +++++
arch/riscv/kernel/vendor_extensions/Makefile | 5 +
arch/riscv/kernel/vendor_extensions/andes.c | 35 +++
arch/riscv/kernel/vendor_extensions/thead.c | 36 +++
.../riscv/kernel/vendor_extensions/thead_hwprobe.c | 42 +++
drivers/perf/riscv_pmu_sbi.c | 9 +-
tools/testing/selftests/riscv/vector/.gitignore | 3 +-
tools/testing/selftests/riscv/vector/Makefile | 17 +-
.../selftests/riscv/vector/v_exec_initval_nolibc.c | 93 +++++++
tools/testing/selftests/riscv/vector/v_helpers.c | 67 +++++
tools/testing/selftests/riscv/vector/v_helpers.h | 7 +
tools/testing/selftests/riscv/vector/v_initval.c | 22 ++
.../selftests/riscv/vector/v_initval_nolibc.c | 68 -----
.../selftests/riscv/vector/vstate_exec_nolibc.c | 20 +-
.../testing/selftests/riscv/vector/vstate_prctl.c | 295 ++++++++++++---------
43 files changed, 1283 insertions(+), 338 deletions(-)
---
base-commit: 4cece764965020c22cff7665b18a012006359095
change-id: 20240411-dev-charlie-support_thead_vector_6_9-1591fc2a431d
--
- Charlie
Hello,
kernel test robot noticed "kernel-selftests.sgx.make.fail" on:
commit: 8092162335554c8ef5e7f50eff68aa9cfbdbf865 ("selftests/harness: remove use of LINE_MAX")
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git master
[test failed on linus/master 98369dccd2f8e16bf4c6621053af7aa4821dcf8e]
[test failed on linux-next/master b0a2c79c6f3590b74742cbbc76687014d47972d8]
in testcase: kernel-selftests
version: kernel-selftests-x86_64-c7864053-1_20240419
with following parameters:
group: sgx
compiler: gcc-13
test machine: 16 threads 1 sockets Intel(R) Xeon(R) E-2278G CPU @ 3.40GHz (Coffee Lake) with 32G memory
(please refer to attached dmesg/kmsg for entire log/backtrace)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang(a)intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202404301040.3bea5782-oliver.sang@intel.com
KERNEL SELFTESTS: linux_headers_dir is /usr/src/linux-headers-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865
2024-04-29 15:02:59 ln -sf /usr/sbin/iptables-nft /usr/bin/iptables
2024-04-29 15:02:59 ln -sf /usr/sbin/ip6tables-nft /usr/bin/ip6tables
2024-04-29 15:02:59 sed -i s/default_timeout=45/default_timeout=300/ kselftest/runner.sh
2024-04-29 15:02:59 make -j16 -C sgx
make: Entering directory '/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx'
gcc -Wall -Werror -g -I/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/../../../tools/include -fPIC -c main.c -o /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/main.o
gcc -Wall -Werror -g -I/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/../../../tools/include -fPIC -c load.c -o /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/load.o
gcc -Wall -Werror -g -I/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/../../../tools/include -fPIC -c sigstruct.c -o /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/sigstruct.o
gcc -Wall -Werror -g -I/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/../../../tools/include -fPIC -c call.S -o /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/call.o
gcc -Wall -Werror -g -I/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/../../../tools/include -fPIC -c sign_key.S -o /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/sign_key.o
gcc -Wall -Werror -static-pie -nostdlib -ffreestanding -fPIE -fno-stack-protector -mrdrnd -I/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/../../../tools/include test_encl.c test_encl_bootstrap.S -o /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/test_encl.elf -Wl,-T,test_encl.lds,--build-id=none
/usr/bin/ld: warning: /tmp/lkp/cct4g3SV.o: missing .note.GNU-stack section implies executable stack
/usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
In file included from main.c:21:
../kselftest_harness.h: In function ‘__run_test’:
../kselftest_harness.h:1166:13: error: implicit declaration of function ‘asprintf’; did you mean ‘vsprintf’? [-Werror=implicit-function-declaration]
1166 | if (asprintf(&test_name, "%s%s%s.%s", f->name,
| ^~~~~~~~
| vsprintf
cc1: all warnings being treated as errors
make: *** [Makefile:36: /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/main.o] Error 1
make: Leaving directory '/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx'
2024-04-29 15:03:00 make quicktest=1 run_tests -C sgx
make: Entering directory '/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx'
gcc -Wall -Werror -g -I/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/../../../tools/include -fPIC -c main.c -o /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/main.o
In file included from main.c:21:
../kselftest_harness.h: In function ‘__run_test’:
../kselftest_harness.h:1166:13: error: implicit declaration of function ‘asprintf’; did you mean ‘vsprintf’? [-Werror=implicit-function-declaration]
1166 | if (asprintf(&test_name, "%s%s%s.%s", f->name,
| ^~~~~~~~
| vsprintf
cc1: all warnings being treated as errors
make: *** [Makefile:36: /usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx/main.o] Error 1
make: Leaving directory '/usr/src/perf_selftests-x86_64-rhel-8.3-kselftests-8092162335554c8ef5e7f50eff68aa9cfbdbf865/tools/testing/selftests/sgx'
The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20240430/202404301040.3bea5782-oliv…
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Fixes clang compilation warnings by adding explicit unsigned conversion:
parse_vdso.c:206:22: warning: passing 'const char *' to parameter of
type 'const unsigned char *' converts between pointers to integer types
where one is of the unique plain 'char' type and the other is not
[-Wpointer-sign]
ver_hash = elf_hash(version);
^~~~~~~
parse_vdso.c:59:52: note: passing argument to parameter 'name' here
static unsigned long elf_hash(const unsigned char *name)
^
parse_vdso.c:207:46: warning: passing 'const char *' to parameter of
type 'const unsigned char *' converts between pointers to integer types
where one is of the unique plain 'char' type and the other is not
[-Wpointer-sign]
ELF(Word) chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
^~~~
parse_vdso.c:59:52: note: passing argument to parameter 'name' here
static unsigned long elf_hash(const unsigned char *name)
Fixes: 98eedc3a9dbf ("Document the vDSO and add a reference parser")
Signed-off-by: Edward Liaw <edliaw(a)google.com>
---
v2: update commit message with correct compiler warning
v3: fix checkpatch errors and indentation
---
tools/testing/selftests/vDSO/parse_vdso.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
index 413f75620a35..9e29ff0657ea 100644
--- a/tools/testing/selftests/vDSO/parse_vdso.c
+++ b/tools/testing/selftests/vDSO/parse_vdso.c
@@ -203,8 +203,9 @@ void *vdso_sym(const char *version, const char *name)
if (!vdso_info.valid)
return 0;
- ver_hash = elf_hash(version);
- ELF(Word) chain = vdso_info.bucket[elf_hash(name) % vdso_info.nbucket];
+ ver_hash = elf_hash((const unsigned char *)version);
+ ELF(Word) chain = vdso_info.bucket[
+ elf_hash((const unsigned char *)name) % vdso_info.nbucket];
for (; chain != STN_UNDEF; chain = vdso_info.chain[chain]) {
ELF(Sym) *sym = &vdso_info.symtab[chain];
--
2.45.0.rc0.197.gbae5840b3b-goog
From: Willem de Bruijn <willemb(a)google.com>
Detect packets with ip_summed CHECKSUM_PARTIAL and skip these. These
should not exist, as the test sends individual packets between two
hosts. But if (HW) GRO is on, with randomized content sometimes
subsequent packets can be coalesced.
In this case the GSO packet checksum is converted to a pseudo checksum
in anticipation of sending out as TSO/USO. So the field will not match
the expected value.
Do not count these as test errors.
Signed-off-by: Willem de Bruijn <willemb(a)google.com>
---
tools/testing/selftests/net/csum.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/net/csum.c b/tools/testing/selftests/net/csum.c
index 90eb06fefa59..b9f3fc3c3426 100644
--- a/tools/testing/selftests/net/csum.c
+++ b/tools/testing/selftests/net/csum.c
@@ -682,7 +682,7 @@ static int recv_verify_packet_ipv6(void *nh, int len)
}
/* return whether auxdata includes TP_STATUS_CSUM_VALID */
-static bool recv_verify_packet_csum(struct msghdr *msg)
+static uint32_t recv_get_packet_csum_status(struct msghdr *msg)
{
struct tpacket_auxdata *aux = NULL;
struct cmsghdr *cm;
@@ -706,7 +706,7 @@ static bool recv_verify_packet_csum(struct msghdr *msg)
if (!aux)
error(1, 0, "cmsg: no auxdata");
- return aux->tp_status & TP_STATUS_CSUM_VALID;
+ return aux->tp_status;
}
static int recv_packet(int fd)
@@ -716,6 +716,7 @@ static int recv_packet(int fd)
char ctrl[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
struct pkt *buf = (void *)_buf;
struct msghdr msg = {0};
+ uint32_t tp_status;
struct iovec iov;
int len, ret;
@@ -737,6 +738,17 @@ static int recv_packet(int fd)
if (len == -1)
error(1, errno, "recv p");
+ tp_status = recv_get_packet_csum_status(&msg);
+
+ /* GRO might coalesce randomized packets. Such GSO packets are
+ * then reinitialized for csum offload (CHECKSUM_PARTIAL), with
+ * a pseudo csum. Do not try to validate these checksums.
+ */
+ if (tp_status & TP_STATUS_CSUMNOTREADY) {
+ fprintf(stderr, "cmsg: GSO packet has partial csum: skip\n");
+ continue;
+ }
+
if (cfg_family == PF_INET6)
ret = recv_verify_packet_ipv6(buf, len);
else
@@ -753,7 +765,7 @@ static int recv_packet(int fd)
* Do not fail if kernel does not validate a good csum:
* Absence of validation does not imply invalid.
*/
- if (recv_verify_packet_csum(&msg) && cfg_bad_csum) {
+ if (tp_status & TP_STATUS_CSUM_VALID && cfg_bad_csum) {
fprintf(stderr, "cmsg: expected bad csum, pf_packet returns valid\n");
bad_validations++;
}
--
2.45.0.rc1.225.g2a3ae87e7f-goog
From: Willem de Bruijn <willemb(a)google.com>
Run tools/testing/selftest/net/csum.c as part of drv-net.
This binary covers multiple scenarios, based on arguments given,
for both IPv4 and IPv6:
- Accept UDP correct checksum
- Detect UDP invalid checksum
- Accept TCP correct checksum
- Detect TCP invalid checksum
- Transmit UDP: basic checksum offload
- Transmit UDP: zero checksum conversion
The test direction is reversed between receive and transmit tests, so
that the NIC under test is always the local machine.
In total this adds up to 12 testcases, with more to follow. For
conciseness, I replaced individual functions with a function factory.
It saves a lot of boilerplate, but is a little harder to follow, so
partially here as a point for discussion.
Also detect hardware offload feature availability using Ethtool
netlink and skip tests when either feature is off. This need may be
common for offload feature tests and eventually deserving of a thin
wrapper in lib.py.
Missing are the PF_PACKET based send tests ('-P'). These use
virtio_net_hdr to program hardware checksum offload. Which requires
looking up the local MAC address and (harder) the MAC of the next hop.
I'll have to give it some though how to do that robustly and where
that code would belong.
Tested on Google cloud:
make -C tools/testing/selftests/ \
TARGETS="drivers/net drivers/net/hw net" \
install INSTALL_PATH=/tmp/ksft
cd /tmp/ksft
sudo NETIF=ens4 REMOTE_TYPE=ssh \
REMOTE_ARGS="root(a)10.40.0.2" \
LOCAL_V4="10.40.0.1"
REMOTE_V4="10.40.0.2" \
LOCAL_V6="<REDACTED>" \
REMOTE_V6="<REDACTED>" \
./run_kselftest.sh -t drivers/net/hw:csum.py
TAP version 13
1..1
# timeout set to 0
# selftests: drivers/net/hw: csum.py
# KTAP version 1
# 1..12
# ok 1 csum.ipv4_rx_tcp
# ok 2 csum.ipv4_rx_tcp_invalid
# ok 3 csum.ipv4_rx_udp
# ok 4 csum.ipv4_rx_udp_invalid
# ok 5 csum.ipv4_tx_udp_csum_offload
# ok 6 csum.ipv4_tx_udp_zero_checksum
# ok 7 csum.ipv6_rx_tcp
# ok 8 csum.ipv6_rx_tcp_invalid
# ok 9 csum.ipv6_rx_udp
# ok 10 csum.ipv6_rx_udp_invalid
# ok 11 csum.ipv6_tx_udp_csum_offload
# ok 12 csum.ipv6_tx_udp_zero_checksum
# # Totals: pass:12 fail:0 xfail:0 xpass:0 skip:0 error:0
ok 1 selftests: drivers/net/hw: csum.py
Warning that for now transmit errors are not detected, as for those
the receiver runs remotely and failures with bkg are ignored.
Signed-off-by: Willem de Bruijn <willemb(a)google.com>
---
.../testing/selftests/drivers/net/hw/Makefile | 1 +
.../testing/selftests/drivers/net/hw/csum.py | 114 ++++++++++++++++++
2 files changed, 115 insertions(+)
create mode 100755 tools/testing/selftests/drivers/net/hw/csum.py
diff --git a/tools/testing/selftests/drivers/net/hw/Makefile b/tools/testing/selftests/drivers/net/hw/Makefile
index 1dd732855d76..4933d045ab66 100644
--- a/tools/testing/selftests/drivers/net/hw/Makefile
+++ b/tools/testing/selftests/drivers/net/hw/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+ OR MIT
TEST_PROGS = \
+ csum.py \
devlink_port_split.py \
ethtool.sh \
ethtool_extended_state.sh \
diff --git a/tools/testing/selftests/drivers/net/hw/csum.py b/tools/testing/selftests/drivers/net/hw/csum.py
new file mode 100755
index 000000000000..e40c510f303d
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/hw/csum.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+"""Run the tools/testing/selftests/net/csum testsuite."""
+
+from os import path
+
+from lib.py import ksft_run, ksft_exit, KsftSkipEx
+from lib.py import EthtoolFamily, NetDrvEpEnv
+from lib.py import bkg, cmd, wait_port_listen
+
+def test_receive(cfg, ipv4=False, extra_args=None):
+ """Test local nic checksum receive. Remote host sends crafted packets."""
+ if not cfg.have_rx_csum:
+ raise KsftSkipEx(f"Test requires rx checksum offload on {cfg.ifname}")
+
+ if ipv4:
+ ip_args = f"-4 -S {cfg.remote_v4} -D {cfg.v4}"
+ else:
+ ip_args = f"-6 -S {cfg.remote_v6} -D {cfg.v6}"
+
+ rx_cmd = f"{cfg.bin_local} -i {cfg.ifname} -n 100 {ip_args} -r 1 -R {extra_args}"
+ tx_cmd = f"{cfg.bin_remote} -i {cfg.ifname} -n 100 {ip_args} -r 1 -T {extra_args}"
+
+ with bkg(rx_cmd, exit_wait=True):
+ wait_port_listen(34000, proto='udp')
+ cmd(tx_cmd, host=cfg.remote)
+
+
+def test_transmit(cfg, ipv4=False, extra_args=None):
+ """Test local nic checksum transmit. Remote host verifies packets."""
+ if not cfg.have_tx_csum:
+ raise KsftSkipEx(f"Test requires tx checksum offload on {cfg.ifname}")
+
+ if ipv4:
+ ip_args = f"-4 -S {cfg.v4} -D {cfg.remote_v4}"
+ else:
+ ip_args = f"-6 -S {cfg.v6} -D {cfg.remote_v6}"
+
+ # Cannot randomize input when calculating zero checksum
+ if extra_args != "-U -Z":
+ extra_args += " -r 1"
+
+ rx_cmd = f"{cfg.bin_remote} -i {cfg.ifname} -L 1 -n 100 {ip_args} -R {extra_args}"
+ tx_cmd = f"{cfg.bin_local} -i {cfg.ifname} -L 1 -n 100 {ip_args} -T {extra_args}"
+
+ with bkg(rx_cmd, host=cfg.remote, exit_wait=True):
+ wait_port_listen(34000, proto='udp', host=cfg.remote)
+ cmd(tx_cmd)
+
+
+def test_builder(name, cfg, ipv4=False, tx=False, extra_args=""):
+ """Construct specific tests from the common template.
+
+ Most tests follow the same basic pattern, differing only in
+ Direction of the test and optional flags passed to csum."""
+ def f(cfg):
+ if ipv4:
+ cfg.require_v4()
+ else:
+ cfg.require_v6()
+
+ if tx:
+ test_transmit(cfg, ipv4, extra_args)
+ else:
+ test_receive(cfg, ipv4, extra_args)
+
+ if ipv4:
+ f.__name__ = "ipv4_" + name
+ else:
+ f.__name__ = "ipv6_" + name
+ return f
+
+
+def check_nic_features(cfg) -> None:
+ """Test whether Tx and Rx checksum offload are enabled.
+
+ If the device under test has either off, then skip the relevant tests."""
+ cfg.have_tx_csum = False
+ cfg.have_rx_csum = False
+
+ ethnl = EthtoolFamily()
+ features = ethnl.features_get({"header": {"dev-index": cfg.ifindex}})
+ for f in features["active"]["bits"]["bit"]:
+ if f["name"] == "tx-checksum-ip-generic":
+ cfg.have_tx_csum = True
+ elif f["name"] == "rx-checksum":
+ cfg.have_rx_csum = True
+
+
+def main() -> None:
+ with NetDrvEpEnv(__file__, nsim_test=False) as cfg:
+ check_nic_features(cfg)
+
+ cfg.bin_local = path.abspath(path.dirname(__file__) + "/../../../net/csum")
+ cfg.bin_remote = cfg.remote.deploy(cfg.bin_local)
+
+ cases = []
+ for ipv4 in [True, False]:
+ cases.append(test_builder("rx_tcp", cfg, ipv4, False, "-t"))
+ cases.append(test_builder("rx_tcp_invalid", cfg, ipv4, False, "-t -E"))
+
+ cases.append(test_builder("rx_udp", cfg, ipv4, False, ""))
+ cases.append(test_builder("rx_udp_invalid", cfg, ipv4, False, "-E"))
+
+ cases.append(test_builder("tx_udp_csum_offload", cfg, ipv4, True, "-U"))
+ cases.append(test_builder("tx_udp_zero_checksum", cfg, ipv4, True, "-U -Z"))
+
+ ksft_run(cases=cases, args=(cfg, ))
+ ksft_exit()
+
+
+if __name__ == "__main__":
+ main()
--
2.45.0.rc1.225.g2a3ae87e7f-goog
In order to build with clang at all, in order to see these symptoms, one
must first apply Valentin Obst's build fix for LLVM [1]. Once that is
done, then when building with clang, via:
make LLVM=1 -C tools/testing/selftests
...clang emits a "format string is empty" warning. (gcc also emits a
similar warning.)
Fix by passing NULL, instead of "", for the msg argument to
ksft_test_result_code(). This removes dozens of warnings and a few
errors (some tests have -Werror set).
[1] https://lore.kernel.org/all/20240329-selftests-libmk-llvm-rfc-v1-1-2f9ed7d1…
Cc: Valentin Obst <kernel(a)valentinobst.de>
Cc: Kees Cook <keescook(a)chromium.org>
Cc: Nick Desaulniers <ndesaulniers(a)google.com>
Cc: Nathan Chancellor <nathan(a)kernel.org>
Cc: Shuah Khan <shuah(a)kernel.org>
Cc: Justin Stitt <justinstitt(a)google.com>
Cc: Bill Wendling <morbo(a)google.com>
Signed-off-by: John Hubbard <jhubbard(a)nvidia.com>
---
tools/testing/selftests/kselftest_harness.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index d98702b6955d..456b8694e678 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -1207,8 +1207,10 @@ void __run_test(struct __fixture_metadata *f,
else
diagnostic = "unknown";
- ksft_test_result_code(t->exit_code, test_name,
- diagnostic ? "%s" : NULL, diagnostic);
+ if (diagnostic)
+ ksft_test_result_code(t->exit_code, test_name, "%s", diagnostic);
+ else
+ ksft_test_result_code(t->exit_code, test_name, NULL);
free(test_name);
}
base-commit: 18daea77cca626f590fb140fc11e3a43c5d41354
prerequisite-patch-id: b901ece2a5b78503e2fb5480f20e304d36a0ea27
--
2.45.0