Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S390x kpatch support #1203

Merged
merged 7 commits into from
Jun 29, 2022
Merged

Conversation

sumanthkorikkar
Copy link
Contributor

@sumanthkorikkar sumanthkorikkar commented Aug 2, 2021

Hi All,

Add s390x support for kpatch

Prerequisite gcc patches:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=a1c1b7a888ade6f21bc7c7f05a2cbff290273fcc
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=0990d93dd8a4268bff5bbe48aa26748cf63201c7
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=935b5226c385e34088c314374cbbe9e4995b9e44

Prerequisite kernel patches:
https://lore.kernel.org/live-patching/YObPhPkzRSqnzgK3@alley/T/#me6c2fcdbd4f582d5cc5c594bafb083ba814acdf9 - Yet to be upstream.
https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git/commit/?h=for-next&id=7561c14d8a4d1a24a40b1839d927d488e2d6345a
Recommended Patches:
torvalds/linux@de5012b
torvalds/linux@67ccddf

Tested on kernel 5.14:
KPATCHBUILD_OPTS="-v /home/extend/vmlinux -s /home/extend/linux-devel/linux/ -d" ./kpatch-test -d linux-5.14.0/ -q
build: combined module
load test: combined module
SUCCESS

Let me know your suggestions.
Thank you.

--
Sumanth

@joe-lawrence
Copy link
Contributor

@sumanthkorikkar : Hi Sumanth, thanks for posting. I'll try to give it a spin next week.

In the meantime, two quick questions:

  • For the gcc patches, do you know what the minimum version is that includes all of them?
  • For the kernel patch "[RFC PATCH] livepatch: Kick idle cpu's tasks to perform transition", did you ever follow up with the schedule folks that Petr suggested?

@sumanthkorikkar
Copy link
Contributor Author

sumanthkorikkar commented Aug 6, 2021

Hi Joe,

Thank you.

  1. I will check with Ilya. However, this should be back portable to rhel9.1.
  2. [RFC PATCH] livepatch: Kick idle cpu's tasks to perform transition - Vasily is working on next version.

@sumanthkorikkar
Copy link
Contributor Author

Hi @joe-lawrence

The gcc patches are back portable from gcc11.

Thanks.

@joe-lawrence
Copy link
Contributor

joe-lawrence commented Aug 18, 2021

Hi @joe-lawrence

The gcc patches are back portable from gcc11.

Great thanks for the update. FWIW, I tried with the stock rhel-alpha gcc and was able to build about 60% of the integration tests successfully. I haven't tried with an updated / backported gcc just yet, but I think that will fix the remaining cases.

By the way, if IBM can backport those commits to the upstream gcc-11 branch, they should be included as part of the rhel-9.1 gcc update.

Quick note about the github CI -- it ran make check and found a small nitpick in kpatch-build/kpatch-cc. With arch/s390/boot/compressed/* removed from the pattern list, it should test cleanly.

@joe-lawrence
Copy link
Contributor

Hi Sumanth,

I had better luck with the integration tests from this branch (https://github.com/joe-lawrence/kpatch/tree/integration-tests-kernel-5.14.0-0.rc3.29.el9) and the gcc backports that you mentioned. I did not try rebuilding the kernel with that version of gcc, so these may be false reports, but I found problems with two of the tests:

data_read_mostly.patch

[   73.060379] test_data_read_mostly: loading out-of-tree module taints kernel.
[   73.060389] test_data_read_mostly: tainting kernel with TAINT_LIVEPATCH
[   73.060502] test_data_read_mostly: module verification failed: signature and/or required key missing - tainting kernel
[   73.060681] module test_data_read_mostly: relocation error for symbol netdev_cmd_to_name (r_type 5, value 0xfffffc009b332194)

% grep netdev_cmd_to_name /proc/kallsyms 
000000001b783b20 T netdev_cmd_to_name
000000001bc54bd8 d __ksymtab_netdev_cmd_to_name
000000001bc64caf r __kstrtabns_netdev_cmd_to_name
000000001bc804e9 r __kstrtab_netdev_cmd_to_name

% readelf --wide --relocs test/integration/test-data-read-mostly.ko
Relocation section '.rela.s390_indirect_jump' at offset 0x95b0 contains 1 entry:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000000  000001a400000005 R_390_PC32             0000000000000000 netdev_cmd_to_name + 32

meminfo-string.patch

% kpatch-build ...
ERROR: no functional changes found. Check /root/.kpatch/build.log for more details.

% strings ~/.kpatch/tmp/orig/fs/proc/meminfo.o | grep -i VMALLOCCHUNK
VmallocChunk:   
% strings ~/.kpatch/tmp/patched/fs/proc/meminfo.o | grep -i VMALLOCCHUNK
VMALLOCCHUNK:

% diff -u <(objdump --no-addresses -D ~/.kpatch/tmp/orig/fs/proc/meminfo.o) <(objdump --no-addresses -D ~/.kpatch/tmp/patched/fs/proc/meminfo.o)
--- /dev/fd/63  2021-08-20 16:18:52.666565151 -0400
+++ /dev/fd/62  2021-08-20 16:18:52.666565151 -0400
@@ -1,5 +1,5 @@
 
-/root/.kpatch/tmp/orig/fs/proc/meminfo.o:     file format elf64-s390
+/root/.kpatch/tmp/patched/fs/proc/meminfo.o:     file format elf64-s390
 
 
 Disassembly of section .group:
@@ -345,9 +345,9 @@
        ...
 
 <.LC36>:
-       56 6d 61 6c             o       %r6,364(%r13,%r6)
-       6c 6f 63 43             md      %f6,835(%r15,%r6)
-       68 75 6e 6b             ld      %f7,3691(%r5,%r6)
+       56 4d 41 4c             o       %r4,332(%r13,%r4)
+       4c 4f 43 43             mh      %r4,835(%r15,%r4)
+       48 55 4e 4b             lh      %r5,3659(%r5,%r4)
        3a 20                   aer     %f2,%f0
        20 20                   lpdr    %f2,%f0
        ...

I did try putting the second one into gdb, and I think there may be something suspect with create-diff-object's rela_equal() for these symbols. I'm not very well versed in ppc64 vs. s390x TOC indirection, so that whole routine is a bit of a mystery to me... but I thought that might be where the .LC36 content would be compared. (Is it in rela_tocX->string, rela_tocX->sym->sec->data->d_buf, or ... ?)

@sumanthkorikkar
Copy link
Contributor Author

Hi Joe,

Thank you. I will check these cases.

@sumanthkorikkar
Copy link
Contributor Author

Hi @joe-lawrence

V2 changes:

  1. Removed the pattern arch/s390/boot/compressed/*

  2. data-read-mostly.patch,
    I have made adjustment to ensure .rela.s390_indirect_jump is not included.
    When the netdev_cmd_to_name text section is not found in kpatch module itself, then the PC32 could be out of range.
    This should not happen now.

  3. meminfo-string.patch
    On s390x, toc is not relevant, just the rela is returned on s390x case.
    When the symbol name has pattern LC/ L1^B* , then:
    rela->string should point to rela->sym->sec->data->d_buf + the value of the associated symbol.
    Otherwise:
    rela->string should point to rela->sym->sec->data->d_buf + rela->addend

Thank you.

Copy link
Contributor

@joe-lawrence joe-lawrence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @sumanthkorikkar , I haven't found much time to review the PR code, but I listed a few nits and questions when taking a quick look. I'll follow up with some more integration test results...

log_debug("lookup for %s: obj=%s sympos=%lu size=%lu",
sym->name, symbol.objname, symbol.sympos,
log_debug("lookup for %s: obj=%s sympos=%lu size=%lu\n",
sym->name, symbol.objname, symbol.sympos,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: adding \n is good, but the second line introduces spaces (in front of sym->name) instead of a tab

* They can be used as normal relas.
*/
if (strstr(rela->sym->name, "s390_indirect_jump"))
continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there instances where s390_indirect_jump relocation would have rela->need_dynrela set? FWIW, when building the integration tests, I didn't see any examples where this happened.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. You are right. I removed it.

@@ -193,7 +211,10 @@ void kpatch_create_rela_list(struct kpatch_elf *kelf, struct section *sec)
ERROR("could not find rela entry symbol\n");
if (rela->sym->sec &&
(rela->sym->sec->sh.sh_flags & SHF_STRINGS)) {
rela->string = rela->sym->sec->data->d_buf + rela->addend;
if(lc_string(rela))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: whitespace: s/if(/if (/

@joe-lawrence
Copy link
Contributor

Hi @sumanthkorikkar , I have been busy working on rebasing the integration tests for RHEL-9, which will be based on v5.14. It's been slow since I've been fighting a few x86_64 and ppc64le problems at the same time, but I think I'm getting close to finishing. I setup three branches:

With integration-tests-kernel-5.14.0-1.el9+workarounds+s390x, I can build all of the integration patches and load all but one with: make integration-slow KPATCH_BUILD_OPTS="--non-replace"

Two interesting things to report:

1 - bug-table-section.patch, gcc-isra.patch.build, gcc-mangled-3.patch, macro-callbacks.patch all build, but when inspecting their ~/.kpatch/build.log file, they all include a create-klp-module error like this:

make[3]: Entering directory '/root/.kpatch/src'
  LDS     /root/.kpatch/tmp/patch/kpatch.lds
  CC [M]  /root/.kpatch/tmp/patch/patch-hook.o
  LD [M]  /root/.kpatch/tmp/patch/test-macro-callbacks.o
  MODPOST /root/.kpatch/tmp/patch/Module.symvers
  CC [M]  /root/.kpatch/tmp/patch/test-macro-callbacks.mod.o
  LD [M]  /root/.kpatch/tmp/patch/test-macro-callbacks.ko
make[3]: Leaving directory '/root/.kpatch/src'
make[2]: Leaving directory '/root/.kpatch/tmp/patch'
/root/kpatch/kpatch-build/create-klp-module: ERROR: tmp.ko: kpatch_mark_grouped_sections: 803: symbol not found

However, kpatch-build produces a .ko and doesn't report failure. I don't believe this behavior is unique to this merge request, but we should definitely investigate why ERROR() doesn't seem to fail the build.

2 - bug-table-section.patch crashes on load once executing replacement code:

$ insmod ./livepatch-bug-table-section.ko
(wait for transition to finish)
$ sudo ls

[16986.671403] livepatch: enabling patch 'livepatch_bug_table_section'
[16986.672382] livepatch: 'livepatch_bug_table_section': starting patching transition
[16988.252413] livepatch: 'livepatch_bug_table_section': patching complete
[16996.297859] Unable to handle kernel pointer dereference in virtual kernel address space
[16996.297872] Failing address: c4a8000000005000 TEID: c4a8000000005403
[16996.297873] Fault in home space mode while using kernel ASCE.
[16996.297876] AS:000000018d274007 R3:00000001efff0007 S:00000001effef800 P:000000000000513d
[16996.297978] Oops: 0038 ilc:2 [#1] SMP
[16996.297982] Modules linked in: livepatch_bug_table_section(OEK) ...
[16996.298019] CPU: 1 PID: 1659633 Comm: sudo Kdump: loaded Tainted: G        W  OE K  --------- ---  5.14.0-1.el9.s390x #1
[16996.298021] Hardware name: IBM 8561 LT1 400 (KVM/Linux)
[16996.298022] Krnl PSW : 0704c00180000000 000003ff8045b706 (sysctl_head_grab+0x46/0xb0 [livepatch_bug_table_section])
[16996.298030]            R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 RI:0 EA:3
[16996.298032] Krnl GPRS: 0000000180000000 0000000100000000 0000000100000002 00000000805047f8
[16996.298034]            0000000000000001 0000000000000074 00000380066e7c38 000000018ce3ba08
[16996.298036]            0000000000000000 000000018ce3ba08 c4a8000000005820 000000018cdfac60
[16996.298037]            000000017d9e2200 000000018c6cfd40 00000380066e7af8 00000380066e7ac0
[16996.298044] Krnl Code: 000003ff8045b6f8: c4a800000000        lgrl    %r10,000003ff8045b6f8
           000003ff8045b6fe: 582003ac           l       %r2,940
          #000003ff8045b702: a7180000           lhi     %r1,0
          >000003ff8045b706: ba12a000           cs      %r1,%r2,0(%r10)
           000003ff8045b70a: ec16001b007e       cij     %r1,0,6,000003ff8045b740
           000003ff8045b710: e310b0180002       ltg     %r1,24(%r11)
           000003ff8045b716: a774001c           brc     7,000003ff8045b74e
           000003ff8045b71a: eb01b008006a       asi     8(%r11),1
[16996.298056] Call Trace:
[16996.298058]  [<000003ff8045b706>] sysctl_head_grab+0x46/0xb0 [livepatch_bug_table_section]
[16996.298062]  [<000000018c1c3486>] proc_sys_permission+0x56/0xc0
[16996.298068]  [<000000018c11ed7c>] inode_permission+0x10c/0x1e0
[16996.298072]  [<000000018c123006>] link_path_walk.part.0.constprop.0+0x256/0x350
[16996.298075]  [<000000018c12387a>] path_openat+0xaa/0x2b0
[16996.298077]  [<000000018c125790>] do_filp_open+0x90/0x130
[16996.298079]  [<000000018c10bcb8>] do_sys_openat2+0xa8/0x160
[16996.298081]  [<000000018c10c362>] do_sys_open+0x62/0x90
[16996.298083]  [<000000018c6aafdc>] __do_syscall+0x1bc/0x1f0
[16996.298088]  [<000000018c6b84b8>] system_call+0x78/0xa0
[16996.298092] Last Breaking-Event-Address:
[16996.298093]  [<000000018c6cfd40>] __func__.4+0xdc/0xe4
[16996.298099] Kernel panic - not syncing: Fatal exception: panic_on_oops

Let me know if you would like a vmlinux/ vmcore for this one.

@sumanthkorikkar
Copy link
Contributor Author

Hi @joe-lawrence,

Thank you. I am able to reproduce livepatch_bug_table_section crash in one of my machines. I will check these issues.

@sumanthkorikkar sumanthkorikkar force-pushed the s390x-kpatch-support branch 2 times, most recently from c01916b to 35423a6 Compare September 20, 2021 05:41
@sumanthkorikkar
Copy link
Contributor Author

sumanthkorikkar commented Sep 20, 2021

Hi @joe-lawrence,

v3 Changes:

  • Indentation changes
  • Handle error, when create-klp-module / create-kpatch-module fails
  • Handle group sections properly. The kpatch_mark_grouped_sections should be called before kpatch_reindex_elements() in create-klp-module. This ensures that the links (sec->sh.sh_link, sec->sh.sh_info) are still intact
    • Reason for OOPS: One of the rela entries (sysctl_lock) for .text.sysctl_grab_head was missing which lead to specification exception. Now, error handling is checked in kpatch-build - create-klp-module and rela entry sysctl_lock is present.
  • Removed dynrela - s390_indirect_jump check in kpatch_create_intermediate_sections.

Thank you

@sumanthkorikkar
Copy link
Contributor Author

  • Added Double quotes in checks

Copy link
Contributor

@joe-lawrence joe-lawrence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @sumanthkorikkar, thanks for updating, this PR is coming along nicely: I can build all and load all of the integration tests in integration-tests-kernel-5.14.0-1.el9+workarounds with the latest set of changes.

See review comments in the code, but some higher level PR feedback:

  • I opened kpatch-build: ignores ERROR() from create-kpatch-module and create-klp-module #1223 and suggest that you spin off the bug fix for ("kpatch-build: Handle error in create-klp-module") into its own PR. This will separate the s390x-specific work from incidental bugfixes along the way.
  • Before we merge, shouldn't ("Enable kpatch build support for s390x" to end of list") move to the back of the commit order? (Tacking them onto the end is good for review, but once we merge into the tree, we can flip on support as the final step.)
  • One additional level of testing we haven't talked about yet are the unit tests. Take a look at https://github.com/dynup/kpatch-unit-test-objs to see the git submodule that lives under this project's test/unit/objs. @sm00th : what kind of arch-specific unit tests would you like to see when we add s390x support?

@@ -22,7 +22,7 @@ GCC_PLUGINS_DIR := $(shell gcc -print-file-name=plugin)
PLUGIN_CFLAGS := $(filter-out -Wconversion, $(CFLAGS))
PLUGIN_CFLAGS += -shared -I$(GCC_PLUGINS_DIR)/include \
-Igcc-plugins -fPIC -fno-rtti -O2 -Wall
else
else ifneq ($(ARCH),s390x)
$(error Unsupported architecture ${ARCH}, check https://github.com/dynup/kpatch/#supported-architectures)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on how confident we feel after this PR, we could update the referenced README.md #supported-architectures section to include s390x. Or would you prefer we merge and test internally before advertising support.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this is merged, we can update s390x as supported in README.md.

data = groupsec->data->d_buf;
end = groupsec->data->d_buf + groupsec->data->d_size;
data++; /* skip first flag word (e.g. GRP_COMDAT) */
gsec = malloc(sizeof(*gsec));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be the only one who resorts to using Valgrind now and then to debug problems in this space, but can we clean up these new allocations. No need to worry about all the error path scenarios, but at least successful execution will run kpatch_elf_teardown() on its way out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Will do the cleanup of allocations.

continue;
data = sec->data->d_buf;
end = sec->data->d_buf + sec->data->d_size;
newdata = malloc(sec->data->d_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise for these allocations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleanup of this allocation performed in kpatch_free_groupsec.

sec->sh.sh_info = tsym->index;
data++;
}
sec->data->d_buf = newdata;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think this leaks the previous sec->data->d_buf ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldnt free it (Elf_Data). Modifying the memory referenced by sec->data->d_buf or Freeing this results in segfault.

@@ -1149,6 +1155,7 @@ else
rm -f checksum.tmp
"$TOOLSDIR"/create-kpatch-module "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o 2>&1 | logger 1
check_pipe_status create-kpatch-module
test "$rc" -ne 0 && die "create-kpatch-module: exited with return code: $rc"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See note in review summary about pulling this out into its own pull request. Also, just a style nit, but the rest of the script uses [[ $rc -ne 0 ]] && ... type syntax.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sure. I will send out a separate pull request for this

@@ -502,6 +535,8 @@ int main(int argc, char *argv[])
kpatch_create_shstrtab(kelf);
kpatch_create_strtab(kelf);
kpatch_create_symtab(kelf);
kpatch_dump_kelf(kelf);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed for future debug?

Copy link
Contributor Author

@sumanthkorikkar sumanthkorikkar Sep 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I wanted to print the final dump coming out of create-klp-module. For debugging, It was beneficial to me. However, we could also move it to the end.

@sm00th
Copy link
Contributor

sm00th commented Sep 22, 2021

@sm00th : what kind of arch-specific unit tests would you like to see when we add s390x support?

We can start off with the bulk of generic tests we have for x86 and add specific stuff later on as we encounter arch-specific issues.

@sumanthkorikkar
Copy link
Contributor Author

Hi @joe-lawrence,

v4 changes:

  • Separate pull request for handling error in kpatch-build. Remove this commit here.
  • Perform the group section handling cleanup operation in kpatch_free_groupsec.
    • kpatch_elf_teardown is being called for orig obj, patched obj and kelf_out. Hence introduced this function
  • Reorganized the commits.
    • Enable build support for s390x is the last commit.
  • Moved kpatch_dump_kelf to the end in create-klp-module.c

Thank you

@joe-lawrence
Copy link
Contributor

I've committed the GCC patches mentioned in #1203 (comment) to the releases/gcc-11 branch:

https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580562.html https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=4a62dfbb9a35db3031108db87569955728cc5f65 https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=2335aa8771acd06b082d3e15d9f21ae0a802afd7

Cool, thanks for the update, Ilya. Support for s390x is coming together nicely 👍

As far as the current outstanding kernel work is concerned, I think we're looking for PeterZ's recent patchset to help the large / idle cpu cause: [PATCH v2 00/11] sched,rcu,context_tracking,livepatch: Improve livepatch task transitions for idle and NOHZ_FULL Any kernel updates, aside from torvalds/linux@7561c14d8a4d, the already merged linker script update?

keiya-nobuta added a commit to keiya-nobuta/kpatch that referenced this pull request Oct 6, 2021
This commit is still dirty, and is jumbling cut & pasted referring
to dynup#1010 and dynup#1203.
keiya-nobuta added a commit to keiya-nobuta/kpatch that referenced this pull request Oct 6, 2021
This commit is still dirty because I'm jumbling cut & pasted
referring to dynup#1010 and dynup#1203.
@joe-lawrence
Copy link
Contributor

I've committed the GCC patches mentioned in #1203 (comment) to the releases/gcc-11 branch:
https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580562.html https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=4a62dfbb9a35db3031108db87569955728cc5f65 https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=2335aa8771acd06b082d3e15d9f21ae0a802afd7

Cool, thanks for the update, Ilya. Support for s390x is coming together nicely +1

As far as the current outstanding kernel work is concerned, I think we're looking for PeterZ's recent patchset to help the large / idle cpu cause: [PATCH v2 00/11] sched,rcu,context_tracking,livepatch: Improve livepatch task transitions for idle and NOHZ_FULL Any kernel updates, aside from torvalds/linux@7561c14, the already merged linker script update?

Sorry that should have read, "Are there any other post v5.14 kernel updates..." How about these additional patches from [PATCH 0/2] s390/ftrace: implement hotpatching:

@joe-lawrence
Copy link
Contributor

@sumanthkorikkar : Regarding kpatch_line_macro_change_only()... It was first implemented for x86_64 and accounts for trivial source code __LINE__ shifts in several kernel macros. These end up encoded in the instruction stream and detected by create-diff-object. The function attempts to spot them and filter out these trivial changes. Over time, most of those kernel macros changed such that line numbers were saved elsewhere, however, ASSERT_RTNL looks to be one that still encodes line numbers to this day (v5.14 on x86_64, ppc64le, aarch64, and s390x).

To test this out, try building:
line-offset.patch.txt

It should introduce about a half-dozen line number changes at all of the ASSERT_RTNL calls. Currently x86_64 and PowerPC implementations should skip those changes.

A few other notes:

  • PowerPC added kpatch_line_macro_change_only() support a bit after enabling the architecture for kpatch, so this could be considered in a follow up enhancement
  • For x86_64, we copied the kernel's tools/arch/x86/lib/insn.c and friends to aid instruction detection
  • For PowerPC, the implementation was much easier thanks to the simpler, fixed 32-bit instruction width

For s390x, I don't see an analog to the kernel's tools/arch/x86/lib/insn code... so we may need to create something similar or stripped down. (If nothing exists, we could probably task an intern with collating something out of the z/Architecture Reference Summary)

Vasily Gorbik and others added 6 commits May 20, 2022 15:50
symtab_read tries to skip '.dynsym' symbol table and only
read '.symtab' symbol table. Newer readelf from binutils 2.37
now adds section names (see the diff):

--- vmlinux.symtab      2022-02-18 02:10:06.691220932 +0100
+++ vmlinux.symtab.new  2022-02-18 01:16:06.161210458 +0100
Symbol table '.dynsym' contains 1541 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000100000     0 SECTION LOCAL  DEFAULT    1 .text
     2: 00000000017a3ac0     4 OBJECT  GLOBAL DEFAULT   19 sclp_console_pages
Symbol table '.symtab' contains 159980 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
-    41: 0000000001a93600     0 SECTION LOCAL  DEFAULT   41
-    42: 0000000001a9c678     0 SECTION LOCAL  DEFAULT   42
...
+    41: 0000000001a93600     0 SECTION LOCAL  DEFAULT   41 .dynsym
+    42: 0000000001a9c678     0 SECTION LOCAL  DEFAULT   42 .rela.dyn
...
     54: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS main.c

Simple matching of ".dynsym" in the line buffer is not enough anymore,
because it hits not just

Symbol table '.dynsym' contains 1541 entries:

line, but also

    41: 0000000001a93600     0 SECTION LOCAL  DEFAULT   41 .dynsym

skipping the rest of the file and leading to an error:

create-diff-object: ERROR: *.o: find_local_syms: 189: couldn't find matching
*.c local symbols in vmlinux symbol table

Limit matching only to lines containing "Symbol table" header.
This works with readelf from the binutils, as well as readelf from
elfutils (its output looks slightly different).

Symbol table [41] '.dynsym' contains 1541 entries:

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1. -mno-pic-data-is-text-relative prevents relative addressing between
   code and data. This is needed to avoid relocation error when klp text
   and data are too far apart

2. Avoid generation of LANCHOR symbols through -fno-section-anchors.
   kpatch-build does not handle it well.

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
* Add s390 specific checks
* Identify patchable functions.
* Dont mark expolines as dynrelas. These expolines are always included
  in final kernel module. This ensures that expoline functions and the
  kernel itself are not too far apart and avoids out of range
  relocation. However, this isnt a problem for other functions, as these
  relocations are performed via R_390_PLT32DBL using gcc option
  -mno-pic-data-is-text-relative.
* s390 maintains expoline tables to locate the expoline thunks. If
  needed,  the module loader could later replace these expoline thunks
  with normal indirect branch. Each element in the expoline table is of 4
  bytes. If there is a changed function in rela.s390_return*, then mark
  that specific rela symbol as included. This is already performed in the
  processing of special sections. Hence include it.

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Add object exclusion for s390

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
1. static const struct inet_sock fake_sk = {
	/* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */
	.sk.sk_bound_dev_if = 1,
	.pinet6 = (struct ipv6_pinfo *) &fake_pinfo,
};

gcc can place fake_sk in .data.rel.ro.local:
ndx 38, data 0x3ffb3280a58, size 960, name .data.rel.ro.local.fake_sk.1
ndx 39, data 0x3ffb32be5e8, size 24, name .rela.data.rel.ro.local.fake_sk.1

2. static LIST_HEAD(patch_objects);

gcc can place patch_objects relocation in .data.rel.local:
sym 56, type 1, bind 0, ndx 34, name patch_objects -> .data.rel.local

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
@sumanthkorikkar
Copy link
Contributor Author

sumanthkorikkar commented May 20, 2022

Thank you for the review. Rebased the changes and tested.

- gcc-mirror/gcc@8753b13 IBM Z: fix section type conflict with -mindirect-branch-table

**Prerequisite kernel patches:**
- 69505e3d9a39 bug: Use normal relative pointers in 'struct bug_entry'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most likely this will end up in 5.19, so it's probably safe to add a v5.19 header for this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

* Add s390 as supported.
* Add backporting information for the distros.

Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
@jpoimboe
Copy link
Member

@sumanthkorikkar Thanks for your patience! This looks good to me.

@joe-lawrence
Copy link
Contributor

I know there are still some upstream kernel patches that need to make their way down to distro kernels, but shall we merge this now before the main branch drifts any further? @sumanthkorikkar @jpoimboe

@jpoimboe
Copy link
Member

jpoimboe commented Jun 9, 2022

@joe-lawrence do we have the integration testing CI setup for testing s390 with a new enough kernel/toolchain? I think that would be helpful, maybe a separate issue can be opened to track that (for whatever "tracking" means considering our unfortunately large number of neglected open issues).

But we at least have unit tests, and these patches are very nicely self contained, so yeah, I think it would be a good idea to go ahead and merge this now before it starts getting conflicts again.

@sumanthkorikkar
Copy link
Contributor Author

I know there are still some upstream kernel patches that need to make their way down to distro kernels, but shall we merge this now before the main branch drifts any further? @sumanthkorikkar @jpoimboe

Yes, Looking forward to get this into the main branch. Thanks

@joe-lawrence
Copy link
Contributor

@joe-lawrence do we have the integration testing CI setup for testing s390 with a new enough kernel/toolchain? I think that would be helpful, maybe a separate issue can be opened to track that (for whatever "tracking" means considering our unfortunately large number of neglected open issues).

Compiler support should be available, we're still waiting on the external expolines MR and a subsequent ftrace backport (probably targeting 9.2 at this point). Since CI is run internally, we can always add it to one of our TODO lists.

@joe-lawrence
Copy link
Contributor

I know there are still some upstream kernel patches that need to make their way down to distro kernels, but shall we merge this now before the main branch drifts any further? @sumanthkorikkar @jpoimboe

Yes, Looking forward to get this into the main branch. Thanks

Great, thanks for all your work on this functionality.

Regarding kernel backports, I posted this question [1] the other day. It popped up as we noticed a missing expolines.o when building the tools/testing/selftests/bpf/bpf_testmod.ko (which builds as a sort of OOT module).

[1] https://lore.kernel.org/linux-s390/8569429d-57f8-a0cf-8b17-1291f6973d32@redhat.com/T/#u

@sumanthkorikkar
Copy link
Contributor Author

Regarding kernel backports, I posted this question [1] the other day. It popped up as we noticed a missing expolines.o when building the tools/testing/selftests/bpf/bpf_testmod.ko (which builds as a sort of OOT module).

[1] https://lore.kernel.org/linux-s390/8569429d-57f8-a0cf-8b17-1291f6973d32@redhat.com/T/#u

Noted. Thanks. We are looking into that.

@jpoimboe
Copy link
Member

Compiler support should be available, we're still waiting on the external expolines MR and a subsequent ftrace backport (probably targeting 9.2 at this point). Since CI is run internally, we can always add it to one of our TODO lists.

The CI could be on a v5.18 kernel which I think has all the prereqs.

@joe-lawrence
Copy link
Contributor

Compiler support should be available, we're still waiting on the external expolines MR and a subsequent ftrace backport (probably targeting 9.2 at this point). Since CI is run internally, we can always add it to one of our TODO lists.

The CI could be on a v5.18 kernel which I think has all the prereqs.

@sm00th : have we ever setup a CI instance running w/upstream kernel?

@sm00th
Copy link
Contributor

sm00th commented Jun 10, 2022

@sm00th : have we ever setup a CI instance running w/upstream kernel?

The beaker jobs have x86_64/ppc64le upstream kernel recipes. They test 5.10.11 atm, so will need config updates and maybe something else to switch over to 5.18.

@borntraeger
Copy link

Any update on this pull request? Is anything blocking this from being merged?

@joe-lawrence
Copy link
Contributor

Any update on this pull request? Is anything blocking this from being merged?

Nothing more to do for this PR, however we would like to add s390x support to our internal integration tests -- these automatically run whenever a PR is posted or updated and when the master branch is updated. Unfortunately the rhel kernel has not yet backported all the needed kernel patches (internal build/packaging is blocked on [1]), so that means we need to target an upstream v5.18 kernel. For that, the integration tests needed to be rebased [2] and tested for all three arches (x86_64, ppc64le, s390x). While doing so, I regenerated the unit test object files [3] so that they now include the external expolines. There is a bit more to it (bumping the unit test submodule reference, updating our internal integration test jobs, etc.) that are independent from this PR, but I was hoping to line all that up to run when we merge it. If the stars don't align by next week, I'll just merge the PR and manually kick off those internal jobs.

[1] https://lore.kernel.org/linux-s390/8569429d-57f8-a0cf-8b17-1291f6973d32@redhat.com/T/#u
[2] #1275
[3] dynup/kpatch-unit-test-objs#41

@joe-lawrence
Copy link
Contributor

5.18 integration tests merged, let's get this one in. I'll figure out internal testing later.

@joe-lawrence joe-lawrence merged commit dc7e5cb into dynup:master Jun 29, 2022
fengjixuchui added a commit to fengjixuchui/kpatch that referenced this pull request Jul 3, 2022
Merge pull request dynup#1203 from sumanthkorikkar/s390x-kpatch-support
bella485 pushed a commit to bella485/centos-stream-9 that referenced this pull request May 1, 2024
Upstream-status: RHEL-only
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2072713

s390x support in upstream kpatch tooling will have a requirement on
thunk-extern [1] as "external" expoline code will simplify binary ELF
comparison and generation of kpatch kernel modules.

Turning on CONFIG_EXPOLINE_EXTERN will place expolines in
arch/s390/lib/expoline.o, which must be available to any out-of-tree
module build.  Ship the file in the -devel package if it is found.

[1] dynup/kpatch#1203 (comment)

Signed-off-by: C. Erastus Toe <ctoe@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants