This document describes what the WSA x86_64 KPM port does, how it diverges from the ARM64 KernelPatch flow used by mainline ReSukiSU and SukiSU, and what is intentionally not implemented.
The public KPM ecosystem grew on top of KernelPatch, which is built around AArch64 specifics:
- ARM64 fixed length 4 byte instructions.
- ARM64 branch helper macros and inline hook trampoline encoding.
- ARM64 system register access patterns (
mrs sp_el0,tcr_el1). - AArch64 ELF and
R_AARCH64_*relocations. - ARM64 syscall numbers and
compat_sys_call_tablesemantics. - ARM64 boot image /
Imageparsing inkptools.
WSA runs an x86_64 Linux kernel, so a normal ReSukiSU build with CONFIG_KPM=y exposes the API surface but does not provide a real x86_64 backend behind it.
Implemented:
- Android x86_64
ksud kpmcommand path enabled for ReSukiSU Manager. - x86_64
ET_RELKPM ELF loader with bounds checks on header, sections, strings, relocations and entry points. - x86_64 RELA relocation handling for the relocation types kernel style modules need:
R_X86_64_64,R_X86_64_PC32,R_X86_64_PLT32,R_X86_64_PC64,R_X86_64_32,R_X86_64_32S,R_X86_64_GOTPCREL,R_X86_64_GOTPCRELX,R_X86_64_REX_GOTPCRELX. - KernelPatch style compatibility symbols:
kpver,kver,kp_malloc,kp_free,compat_copy_to_user,symbol_lookup_name,hotpatch,hook,hook_wrap,fp_hook,fp_hook_wrap. - x86_64 inline hook backend that uses the kernel
insndecoder for length and RIP relative fixup. text_poke_bp()based install and restore for normalJMP rel32hooks undertext_mutex.RW+NXtoROXpage transitions for trampolines and wrapper stubs.synchronize_rcu_tasks_rude()plussynchronize_rcu_tasks()before generated executable buffers are freed, with free refused if the finalRW+NXpermission transition fails.- Refusal of unsafe or conflicting hook targets owned by ftrace, kprobes, alternatives, jump labels or static calls.
- Refusal of patching from IRQ or atomic context.
- Native x86_64 syscall-table wrappers through
hook_syscalln,fp_wrap_syscallnandinline_wrap_syscalln.
Intentionally not implemented in this release:
- Compat syscall-table wrapping; compat syscall install calls return
EOPNOTSUPP. - ARM64 branch helper APIs (
branch_from_to,branch_relative,branch_absolute,ret_absolute). - ARM64
kpimgstyle boot time patching of the kernel image.
The formal x86_64 ABI contract is in KernelSU/docs/KPM_X86_64_ABI.md. The current loader marker is ReSukiSU-x86_64-KPM-loader/0.21 with ABI version 1.
Patch hygiene and rebase rules are in KernelSU/docs/UPSTREAMING_X86_64.md.
KPM modules are x86_64 ET_REL ELF objects that expose these sections:
.kpm.infotext metadata: name, version, license, author, description..kpm.initinitialization entry (KPM_INIT)..kpm.exitcleanup entry (KPM_EXIT)..kpm.ctl0optional first control entry (KPM_CTL0)..kpm.ctl1optional second control entry (KPM_CTL1).
Lifecycle:
load -> kpm_init(args, "load-file", reserved)
ctl -> kpm_ctl0(ctl_args, out_msg, outlen)
ctl -> kpm_ctl1(a1, a2, a3)
unload -> kpm_exit(reserved)
The loader exports kpm_loader_abi_version, kpm_abi_version, kpm_loader_feature_bits and kpm_feature_bits so modules can detect optional x86_64 runtime capabilities. The event string is part of the ABI; modules must treat load-file as the x86_64 file-load event and must not special-case the older documentation-only load spelling.
The source-level porting checklist is in KernelSU/docs/KPM_X86_64_PORTING.md. WSA module compatibility rows and evidence requirements are tracked in KPM_MODULE_COMPATIBILITY.md.
Normal in range inline hook:
- The patcher acquires
text_mutex. text_poke_bp()installs a 5 byteJMP rel32to a per hook trampoline. The breakpoint emulation step uses the new jump itself.- The trampoline contains the relocated original prologue, copied with the kernel
insndecoder, with RIP relative operands rewritten and overflowing displacements rejected with-ERANGE. - The trampoline pages start
RW+NX, are populated, then transition toROX.
Restore:
- The patcher acquires
text_mutex. text_poke_bp()writes the original prologue bytes back. The breakpoint emulation step uses the previous jump bytes so that any in flight CPU continues into the trampoline rather than into a half restored prologue.synchronize_rcu_tasks_rude()andsynchronize_rcu_tasks()are called before the trampoline pages are freed, so no task can still be running inside them.- Before
module_memfree(), generated executable buffers are switched back toRW+NX. If that transition fails, the loader logs the failure and keeps the allocation resident instead of freeing pages with stale executable permissions.
Far jump fallback:
- If the trampoline cannot be reached from the hooked function with a 5 byte
JMP rel32, the install path falls back to a 14 byte absolute jump emitted by the existing ReSukiSU x86_64 text writer.
Refusal predicates at install time include:
- The address must lie inside core kernel text.
ftrace_location()andis_ftrace_trampoline()must be clean.get_kprobe()must return null.- The address must not lie inside
.entry.text,.noinstr.text, exception tables, alternatives, jump labels or static call tables.
hotpatch(addrs, values, cnt)snapshots all original 32 bit values before commit and rolls back earlier writes if a later write fails.unloadmarks a module as unloading before calling.kpm.exit;controlreturns-EBUSYwhile this is in progress.- If
.kpm.exitreturns an error, the module remains loaded rather than freeing executable memory that hooks or callbacks may still reference. ksud kpmpropagates negative kernel return codes as command failures instead of reporting success.ksud kpm doctor --jsonreports loader reachability, module count, safe mode and KPM directory hardening.- Generated executable memory free is fail-closed: a failed
RW+NXtransition is treated as a hard cleanup error and the buffer is intentionally retained for diagnosis.
ReSukiSU Manager must ship an Android x86_64 libksud.so with the ksud kpm command path. The local guard checks an APK or extracted library:
KernelSU/scripts/check-manager-kpm-x86.sh /path/to/ReSukiSU-Manager.apkThe release checklist should record the Manager APK version, APK SHA256, guard output, ksud kpm version, ksud kpm doctor --json and ksud kpm audit --json. See KernelSU/docs/MANAGER_X86_64.md.
For out of tree x86_64 KPM modules:
-mcmodel=kernel -mno-red-zone -mno-sse -mno-mmx -mno-avx -fno-jump-tables -fcf-protection=none -mretpoline-external-thunk -fno-pic -fno-plt -fno-common
Rationale:
-mcmodel=kernelkeeps the kernel[-2 GB, 0)code model.-mno-red-zone,-mno-sse,-mno-mmx,-mno-avxmatch the kernel ABI.-fno-jump-tableskeeps prologues hookable.-fcf-protection=noneavoids generatingendbr64from user toolchain in places the loader does not expect.-mretpoline-external-thunkroutes indirect calls through the kernel retpoline thunks.-fno-pic -fno-plt -fno-commonkeep the object file structure that the loader expects.
The x86_64 validation suite covers:
- Basic KPM ABI (
load,info,control,unload). - Hotpatch and function pointer hook capability checks.
- Inline hook install, trampoline call and restore checks.
hook_wrapandfp_hook_wrapchecks for argument counts up to 12.- x86_64 instruction relocation cases including RIP relative MOV / LEA, ENDBR64, 10 byte
movabs, refusal ofcall rel32and short branches in the prologue. - Malformed
.kpm.inforejection. - Native syscall wrapper load/unload and compat syscall rejection.
- Hook ownership tagging from a
.kpm.ctl0callback. 500loops across5capability modules, for2500total load / control / unload cycles.- Final
kpm num = 0. - Kernel log clean for
BUG,WARNING,Oops, general protection faults, invalid opcode reports and use after free reports.
The current local known-good row is WSA package 2407.40000.4.0 on Windows build 26200 with Memory Integrity enabled. Kernel #36 (f6c7694e5d1c04f063ba6229ddf190634664c62b1fe6c62fbe6c6ec625819af1) passed with loader ReSukiSU-x86_64-KPM-loader/0.21:
cd KernelSU
RUN_WSA=1 ADB="/mnt/d/Programy/Path Tools/adb.exe" ADB_TARGET=127.0.0.1:58526 \
KSUD=/data/adb/ksud REMOTE_DIR=/data/local/tmp/kpm-test CONTROL_LOOPS=20 \
bash scripts/kpm-x86-preflight.sh
cd ..
ADB="/mnt/d/Programy/Path Tools/adb.exe" ADB_TARGET=127.0.0.1:58526 \
bash scripts/wsa-kpm-boot-smoke.shThe stock WSA configuration does not enable KASAN, KCSAN, DEBUG_WX, IBT, CFI or FineIBT. The detailed matrix, exact commands and result template live in KPM_DEBUG_VALIDATION.md. Validation rows that need these configs are tracked here for future debug kernel runs:
- CFI / IBT / FineIBT compliance (Clang LTO +
CONFIG_CFI_CLANG=y+CONFIG_X86_KERNEL_IBT=y+CONFIG_FINEIBT=y). endbr64preservation under IBT (hook atfunc+4).text_poke_bpatomicity under multi CPU stress with concurrentperf record -a -F 8000.KASAN_VMALLOC,KCSAN,KFENCE,DEBUG_WX,PROVE_LOCKING,DEBUG_LIST,DEBUG_KMEMLEAK24 hour stress soak.- Longer AFL++ / libFuzzer runs beyond the smoke harness and generated example/mutation seed corpus.
- ftrace / kprobes / livepatch coexistence.
- ARM64
.kpmbinaries cannot load on this x86_64 kernel. - Source level KPMs port cleanly when they avoid ARM64 inline asm, ARM64 syscall numbers, ARM64 system registers and ARM64 branch helpers. Use
KernelSU/docs/KPM_X86_64_PORTING.mdandKernelSU/scripts/check-kpm-module-x86.shbefore claiming compatibility for a real module. - WSA does not have most vendor specific Android drivers, so KPMs that target a specific phone vendor (
qti_battery_charger,xperia_ii_battery_age, vendor freezers) cannot work on WSA regardless of architecture.