Blame doc/patch-author-guide.md

Packit Service ac8aad
kpatch Patch Author Guide
Packit Service ac8aad
=========================
Packit Service ac8aad
Packit Service ac8aad
Because kpatch-build is relatively easy to use, it can be easy to assume that a
Packit Service ac8aad
successful patch module build means that the patch is safe to apply.  But in
Packit Service ac8aad
fact that's a very dangerous assumption.
Packit Service ac8aad
Packit Service ac8aad
There are many pitfalls that can be encountered when creating a live patch.
Packit Service ac8aad
This document attempts to guide the patch creation process.  It's a work in
Packit Service ac8aad
progress.  If you find it useful, please contribute!
Packit Service ac8aad
Packit Service ac8aad
Patch Analysis
Packit Service ac8aad
--------------
Packit Service ac8aad
Packit Service ac8aad
kpatch provides _some_ guarantees, but it does not guarantee that all patches
Packit Service ac8aad
are safe to apply.  Every patch must also be analyzed in-depth by a human.
Packit Service ac8aad
Packit Service ac8aad
The most important point here cannot be stressed enough.  Here comes the bold:
Packit Service ac8aad
Packit Service ac8aad
**Do not blindly apply patches.  There is no substitute for human analysis and
Packit Service ac8aad
reasoning on a per-patch basis.  All patches must be thoroughly analyzed by a
Packit Service ac8aad
human kernel expert who completely understands the patch and the affected code
Packit Service ac8aad
and how they relate to the live patching environment.**
Packit Service ac8aad
Packit Service ac8aad
kpatch vs livepatch vs kGraft
Packit Service ac8aad
-----------------------------
Packit Service ac8aad
Packit Service ac8aad
This document assumes that the kpatch core module is being used.  Other live
Packit Service ac8aad
patching systems (e.g., livepatch and kGraft) have different consistency
Packit Service ac8aad
models.  Each comes with its own guarantees, and there are some subtle
Packit Service ac8aad
differences.  The guidance in this document applies **only** to kpatch.
Packit Service ac8aad
Packit Service ac8aad
Patch upgrades
Packit Service ac8aad
--------------
Packit Service ac8aad
Packit Service ac8aad
Due to potential unexpected interactions between patches, it's highly
Packit Service ac8aad
recommended that when patching a system which has already been patched, the
Packit Service ac8aad
second patch should be a cumulative upgrade which is a superset of the first
Packit Service ac8aad
patch.
Packit Service ac8aad
Packit Service ac8aad
Data structure changes
Packit Service ac8aad
----------------------
Packit Service ac8aad
Packit Service ac8aad
kpatch patches functions, not data.  If the original patch involves a change to
Packit Service ac8aad
a data structure, the patch will require some rework, as changes to data
Packit Service ac8aad
structures are not allowed by default.
Packit Service ac8aad
Packit Service ac8aad
Usually you have to get creative.  There are several possible ways to handle
Packit Service ac8aad
this:
Packit Service ac8aad
Packit Service ac8aad
### Change the code which uses the data structure
Packit Service ac8aad
Packit Service ac8aad
Sometimes, instead of changing the data structure itself, you can change the
Packit Service ac8aad
code which uses it.
Packit Service ac8aad
Packit Service ac8aad
For example, consider this
Packit Service ac8aad
[patch](http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=54a20552e1eae07aa240fa370a0293e006b5faed).
Packit Service ac8aad
which has the following hunk:
Packit Service ac8aad
Packit Service ac8aad
```
Packit Service ac8aad
@@ -3270,6 +3277,7 @@ static int (*const svm_exit_handlers[])(struct vcpu_svm *svm) = {
Packit Service ac8aad
 	[SVM_EXIT_EXCP_BASE + PF_VECTOR]	= pf_interception,
Packit Service ac8aad
 	[SVM_EXIT_EXCP_BASE + NM_VECTOR]	= nm_interception,
Packit Service ac8aad
 	[SVM_EXIT_EXCP_BASE + MC_VECTOR]	= mc_interception,
Packit Service ac8aad
+	[SVM_EXIT_EXCP_BASE + AC_VECTOR]	= ac_interception,
Packit Service ac8aad
 	[SVM_EXIT_INTR]				= intr_interception,
Packit Service ac8aad
 	[SVM_EXIT_NMI]				= nmi_interception,
Packit Service ac8aad
 	[SVM_EXIT_SMI]				= nop_on_interception,
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
`svm_exit_handlers[]` is an array of function pointers.  The patch adds a
Packit Service ac8aad
`ac_interception` function pointer to the array at index `[SVM_EXIT_EXCP_BASE +
Packit Service ac8aad
AC_VECTOR]`.  That change is incompatible with kpatch.
Packit Service ac8aad
Packit Service ac8aad
Looking at the source file, we can see that this function pointer is only
Packit Service ac8aad
accessed by a single function, `handle_exit()`:
Packit Service ac8aad
Packit Service ac8aad
```
Packit Service ac8aad
        if (exit_code >= ARRAY_SIZE(svm_exit_handlers)
Packit Service ac8aad
            || !svm_exit_handlers[exit_code]) {
Packit Service ac8aad
                WARN_ONCE(1, "svm: unexpected exit reason 0x%x\n", exit_code);
Packit Service ac8aad
                kvm_queue_exception(vcpu, UD_VECTOR);
Packit Service ac8aad
                return 1;
Packit Service ac8aad
        }
Packit Service ac8aad
Packit Service ac8aad
        return svm_exit_handlers[exit_code](svm);
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
So an easy solution here is to just change the code to manually check for the
Packit Service ac8aad
new case before looking in the data structure:
Packit Service ac8aad
Packit Service ac8aad
```
Packit Service ac8aad
@@ -3580,6 +3580,9 @@ static int handle_exit(struct kvm_vcpu *vcpu)
Packit Service ac8aad
                return 1;
Packit Service ac8aad
        }
Packit Service ac8aad
Packit Service ac8aad
+       if (exit_code == SVM_EXIT_EXCP_BASE + AC_VECTOR)
Packit Service ac8aad
+               return ac_interception(svm);
Packit Service ac8aad
+
Packit Service ac8aad
        return svm_exit_handlers[exit_code](svm);
Packit Service ac8aad
 }
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
Not only is this an easy solution, it's also safer than touching data since
Packit Service ac8aad
kpatch creates a barrier between the calling of old functions and new
Packit Service ac8aad
functions.
Packit Service ac8aad
Packit Service ac8aad
### Use a kpatch callback macro
Packit Service ac8aad
Packit Service ac8aad
Kpatch supports livepatch style callbacks, as described by the kernel's
Packit Service ac8aad
[Documentation/livepatch/callbacks.txt](https://github.com/torvalds/linux/blob/master/Documentation/livepatch/callbacks.txt).
Packit Service ac8aad
Packit Service ac8aad
`kpatch-macros.h` defines the following macros that can be used to
Packit Service ac8aad
register such callbacks:
Packit Service ac8aad
Packit Service ac8aad
* `KPATCH_PRE_PATCH_CALLBACK` - executed before patching
Packit Service ac8aad
* `KPATCH_POST_PATCH_CALLBACK` - executed after patching
Packit Service ac8aad
* `KPATCH_PRE_UNPATCH_CALLBACK` - executed before unpatching, complements the
Packit Service ac8aad
                                  post-patch callback.
Packit Service ac8aad
* `KPATCH_POST_UNPATCH_CALLBACK` - executed after unpatching, complements the
Packit Service ac8aad
                                   pre-patch callback.
Packit Service ac8aad
Packit Service ac8aad
A pre-patch callback routine has the following signature:
Packit Service ac8aad
Packit Service ac8aad
```
Packit Service ac8aad
static int callback(patch_object *obj) { }
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
and any non-zero return status indicates failure to the kpatch core.  For more
Packit Service ac8aad
information on pre-patch callback failure, see the **Pre-patch return status**
Packit Service ac8aad
section below.
Packit Service ac8aad
Packit Service ac8aad
Post-patch, pre-unpatch, and post-unpatch callback routines all share the
Packit Service ac8aad
following signature:
Packit Service ac8aad
Packit Service ac8aad
```
Packit Service ac8aad
static void callback(patch_object *obj) { }
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
Generally pre-patch callbacks are paired with post-unpatch callbacks, meaning
Packit Service ac8aad
that anything the former allocates or sets up should be torn down by the former
Packit Service ac8aad
callback.  Likewise for post-patch and pre-unpatch callbacks.
Packit Service ac8aad
Packit Service ac8aad
#### Pre-patch return status
Packit Service ac8aad
Packit Service ac8aad
If kpatch is currently patching already-loaded objects (vmlinux always by
Packit Service ac8aad
definition as well as any currently loaded kernel modules), a non-zero pre-patch
Packit Service ac8aad
callback status results in the kpatch core reverting the current
Packit Service ac8aad
patch-in-progress.  The kpatch-module is rejected, completely reverted, and
Packit Service ac8aad
unloaded.
Packit Service ac8aad
Packit Service ac8aad
If kpatch is patching a newly loaded kernel module, then a failing pre-patch
Packit Service ac8aad
callback will only result in a WARN message.  This is non-intuitive and a
Packit Service ac8aad
deviation from livepatch callback behavior, but the result of a limitation of
Packit Service ac8aad
kpatch and linux module notifiers.
Packit Service ac8aad
Packit Service ac8aad
In both cases, if a pre-patch callback fails, none of its other callbacks will
Packit Service ac8aad
be executed.
Packit Service ac8aad
Packit Service ac8aad
#### Callback context
Packit Service ac8aad
Packit Service ac8aad
* For patches to vmlinux or already loaded kernel modules, callback functions
Packit Service ac8aad
will be run by `stop_machine` as part of applying or removing a patch.
Packit Service ac8aad
(Therefore the callbacks must not block or sleep.)
Packit Service ac8aad
Packit Service ac8aad
* For patches to kernel modules which haven't been loaded yet, a
Packit Service ac8aad
module-notifier will execute callbacks when the associated module is loaded
Packit Service ac8aad
into the `MODULE_STATE_COMING` state.  The pre and post-patch callbacks
Packit Service ac8aad
are called before any module_init code.
Packit Service ac8aad
Packit Service ac8aad
Example: a kpatch fix for CVE-2016-5389 could utilize the
Packit Service ac8aad
`KPATCH_PRE_PATCH_CALLBACK` and `KPATCH_POST_UNPATCH_CALLBACK` macros to modify
Packit Service ac8aad
variable `sysctl_tcp_challenge_ack_limit` in-place:
Packit Service ac8aad
Packit Service ac8aad
```
Packit Service ac8aad
+#include "kpatch-macros.h"
Packit Service ac8aad
+
Packit Service ac8aad
+static bool kpatch_write = false;
Packit Service ac8aad
+static int kpatch_pre_patch_tcp_send_challenge_ack(patch_object *obj)
Packit Service ac8aad
+{
Packit Service ac8aad
+	if (sysctl_tcp_challenge_ack_limit == 100) {
Packit Service ac8aad
+		sysctl_tcp_challenge_ack_limit = 1000;
Packit Service ac8aad
+		kpatch_write = true;
Packit Service ac8aad
+	}
Packit Service ac8aad
+	return 0;
Packit Service ac8aad
+}
Packit Service ac8aad
static void kpatch_post_unpatch_tcp_send_challenge_ack(patch_object *obj)
Packit Service ac8aad
+{
Packit Service ac8aad
+	if (kpatch_write && sysctl_tcp_challenge_ack_limit == 1000)
Packit Service ac8aad
+		sysctl_tcp_challenge_ack_limit = 100;
Packit Service ac8aad
+}
Packit Service ac8aad
+KPATCH_PRE_PATCH_CALLBACK(kpatch_pre_patch_tcp_send_challenge_ack);
Packit Service ac8aad
+KPATCH_POST_UNPATCH_CALLBACK(kpatch_post_unpatch_tcp_send_challenge_ack);
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
Don't forget to protect access to the data as needed. Please note that
Packit Service ac8aad
spinlocks and mutexes / sleeping locks can't be used from stop_machine
Packit Service ac8aad
context. Also note the pre-patch callback return code will be ignored by the
Packit Service ac8aad
kernel's module notifier, so it does not affect the target module or livepatch
Packit Service ac8aad
module status. This means:
Packit Service ac8aad
Packit Service ac8aad
* Pre-patch callbacks to loaded objects (vmlinux, loaded kernel modules) are
Packit Service ac8aad
  run from stop_machine(), so they may only inspect lock state (i.e.
Packit Service ac8aad
  spin_is_locked(), mutex_is_locked()) and optionally return -EBUSY to prevent
Packit Service ac8aad
  patching.
Packit Service ac8aad
Packit Service ac8aad
* Post-patch, pre-unpatch, and post-unpatch callbacks to loaded objects are
Packit Service ac8aad
  also run from stop_machine(), so the same locking context applies.  No
Packit Service ac8aad
  return status is supported.
Packit Service ac8aad
Packit Service ac8aad
* Deferred pre-patch callbacks to newly loading objects do not run from
Packit Service ac8aad
  stop_machine(), so they may spin or schedule, i.e. spin_lock(),
Packit Service ac8aad
  mutex_lock()).  Return status is ignored.
Packit Service ac8aad
Packit Service ac8aad
* Post-patch, pre-unpatch, and post-unpatch callbacks to unloading objects are
Packit Service ac8aad
  also *not* run from stop_machine(), so they may spin or sleep.  No return
Packit Service ac8aad
  status is supported.
Packit Service ac8aad
Packit Service ac8aad
Unfortunately there is no simple, all-case-inclusive kpatch callback
Packit Service ac8aad
implementation that handles data structures and mutual exclusion.
Packit Service ac8aad
Packit Service ac8aad
A few workarounds:
Packit Service ac8aad
Packit Service ac8aad
1. If a given lock/mutex is held and released by the same set of functions
Packit Service ac8aad
(that is, functions that take a lock/mutex always release it before
Packit Service ac8aad
returning), a trivial change to those functions can re-purpose kpatch's
Packit Service ac8aad
activeness safety check to avoid patching when the lock/mutex may be held.
Packit Service ac8aad
This assumes that all lock/mutex holders can be patched.
Packit Service ac8aad
Packit Service ac8aad
2. If it can be assured that all patch targets will be loaded before the
Packit Service ac8aad
kpatch patch module, pre-patch callbacks may return -EBUSY if the lock/mutex
Packit Service ac8aad
is held to block the patching.
Packit Service ac8aad
Packit Service ac8aad
3. Finally, if a kpatch is disabled or removed and while all patch targets are
Packit Service ac8aad
still loaded, then all unpatch callbacks will run from stop_machine() -- the
Packit Service ac8aad
unpatching cannot be stopped at this point and the callbacks cannot spin or
Packit Service ac8aad
sleep.
Packit Service ac8aad
Packit Service ac8aad
    With that in mind, it is probably easiest to omit unpatching callbacks
Packit Service ac8aad
at this point.
Packit Service ac8aad
Packit Service ac8aad
Also be careful when upgrading.  If patch A has a pre/post-patch callback which
Packit Service ac8aad
writes to X, and then you load patch B which is a superset of A, in some cases
Packit Service ac8aad
you may want to prevent patch B from writing to X, if A is already loaded.
Packit Service ac8aad
Packit Service ac8aad
Packit Service ac8aad
### Use a shadow variable
Packit Service ac8aad
Packit Service ac8aad
If you need to add a field to an existing data structure, or even many existing
Packit Service ac8aad
data structures, you can use the `kpatch_shadow_*()` functions:
Packit Service ac8aad
Packit Service ac8aad
* `kpatch_shadow_alloc` - allocates a new shadow variable associated with a
Packit Service ac8aad
  given object
Packit Service ac8aad
* `kpatch_shadow_get` - find and return a pointer to a shadow variable
Packit Service ac8aad
* `kpatch_shadow_free` - find and free a shadow variable
Packit Service ac8aad
Packit Service ac8aad
Example: The `shadow-newpid.patch` integration test demonstrates the usage of
Packit Service ac8aad
these functions.
Packit Service ac8aad
Packit Service ac8aad
A shadow PID variable is allocated in `do_fork()`: it is associated with the
Packit Service ac8aad
current `struct task_struct *p` value, given a string lookup key of "newpid",
Packit Service ac8aad
sized accordingly, and allocated as per `GFP_KERNEL` flag rules.
Packit Service ac8aad
Packit Service ac8aad
`kpatch_shadow_alloc` returns a pointer to the shadow variable, so we can
Packit Service ac8aad
dereference and make assignments as usual.  In this patch chunk, the shadow
Packit Service ac8aad
`newpid` is allocated then assigned to a rolling `ctr` counter value:
Packit Service ac8aad
```
Packit Service ac8aad
+		int *newpid;
Packit Service ac8aad
+		static int ctr = 0;
Packit Service ac8aad
+
Packit Service ac8aad
+		newpid = kpatch_shadow_alloc(p, "newpid", sizeof(*newpid),
Packit Service ac8aad
+					     GFP_KERNEL);
Packit Service ac8aad
+		if (newpid)
Packit Service ac8aad
+			*newpid = ctr++;
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
A shadow variable may also be accessed via `kpatch_shadow_get`.  Here the
Packit Service ac8aad
patch modifies `task_context_switch_counts()` to fetch the shadow variable
Packit Service ac8aad
associated with the current `struct task_struct *p` object and a "newpid" tag.
Packit Service ac8aad
As in the previous patch chunk, the shadow variable pointer may be accessed
Packit Service ac8aad
as an ordinary pointer type:
Packit Service ac8aad
```
Packit Service ac8aad
+	int *newpid;
Packit Service ac8aad
+
Packit Service ac8aad
 	seq_put_decimal_ull(m, "voluntary_ctxt_switches:\t", p->nvcsw);
Packit Service ac8aad
 	seq_put_decimal_ull(m, "\nnonvoluntary_ctxt_switches:\t", p->nivcsw);
Packit Service ac8aad
 	seq_putc(m, '\n');
Packit Service ac8aad
+
Packit Service ac8aad
+	newpid = kpatch_shadow_get(p, "newpid");
Packit Service ac8aad
+	if (newpid)
Packit Service ac8aad
+		seq_printf(m, "newpid:\t%d\n", *newpid);
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
A shadow variable is freed by calling `kpatch_shadow_free` and providing
Packit Service ac8aad
the object / string key combination.  Once freed, the shadow variable is not
Packit Service ac8aad
safe to access:
Packit Service ac8aad
```
Packit Service ac8aad
 	exit_task_work(tsk);
Packit Service ac8aad
 	exit_thread(tsk);
Packit Service ac8aad
 
Packit Service ac8aad
+	kpatch_shadow_free(tsk, "newpid");
Packit Service ac8aad
+
Packit Service ac8aad
 	/*
Packit Service ac8aad
 	 * Flush inherited counters to the parent - before the parent
Packit Service ac8aad
 	 * gets woken up by child-exit notifications.
Packit Service ac8aad
```
Packit Service ac8aad
Notes:
Packit Service ac8aad
* `kpatch_shadow_alloc` initializes only shadow variable metadata. It
Packit Service ac8aad
  allocates variable storage via `kmalloc` with the `gfp_t` flags it is
Packit Service ac8aad
  given, but otherwise leaves the area untouched. Initialization of a shadow
Packit Service ac8aad
  variable is the responsibility of the caller.
Packit Service ac8aad
* As soon as `kpatch_shadow_alloc` creates a shadow variable, its presence
Packit Service ac8aad
  will be reported by `kpatch_shadow_get`. Care should be taken to avoid any
Packit Service ac8aad
  potential race conditions between a kernel thread that allocates a shadow
Packit Service ac8aad
  variable and concurrent threads that may attempt to use it.
Packit Service ac8aad
Packit Service ac8aad
Data semantic changes
Packit Service ac8aad
---------------------
Packit Service ac8aad
Packit Service ac8aad
Part of the stable-tree [backport](https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/fs/aio.c?h=linux-3.10.y&id=6745cb91b5ec93a1b34221279863926fba43d0d7)
Packit Service ac8aad
to fix CVE-2014-0206 changed the reference count semantic of `struct
Packit Service ac8aad
kioctx.reqs_active`. Associating a shadow variable to new instances of this
Packit Service ac8aad
structure can be used by patched code to handle both new (post-patch) and
Packit Service ac8aad
existing (pre-patch) instances.
Packit Service ac8aad
Packit Service ac8aad
(This example is trimmed to highlight this use-case. Boilerplate code is also
Packit Service ac8aad
required to allocate/free a shadow variable called "reqs_active_v2" whenever a
Packit Service ac8aad
new `struct kioctx` is created/released. No values are ever assigned to the
Packit Service ac8aad
shadow variable.)
Packit Service ac8aad
Packit Service ac8aad
Shadow variable existence can be verified before applying the new data
Packit Service ac8aad
semantic of the associated object:
Packit Service ac8aad
```
Packit Service ac8aad
@@ -678,6 +688,9 @@ void aio_complete(struct kiocb *iocb, lo
Packit Service ac8aad
 put_rq:
Packit Service ac8aad
 	/* everything turned out well, dispose of the aiocb. */
Packit Service ac8aad
 	aio_put_req(iocb);
Packit Service ac8aad
+	reqs_active_v2 = kpatch_shadow_get(ctx, "reqs_active_v2");
Packit Service ac8aad
+	if (reqs_active_v2)
Packit Service ac8aad
+		atomic_dec(&ctx->reqs_active);
Packit Service ac8aad
 
Packit Service ac8aad
 	/*
Packit Service ac8aad
 	 * We have to order our ring_info tail store above and test
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
Likewise, shadow variable non-existence can be tested to continue applying the
Packit Service ac8aad
old data semantic:
Packit Service ac8aad
```
Packit Service ac8aad
@@ -705,6 +718,7 @@ static long aio_read_events_ring(struct
Packit Service ac8aad
 	unsigned head, pos;
Packit Service ac8aad
 	long ret = 0;
Packit Service ac8aad
 	int copy_ret;
Packit Service ac8aad
+	int *reqs_active_v2;
Packit Service ac8aad
 
Packit Service ac8aad
 	mutex_lock(&ctx->ring_lock);
Packit Service ac8aad
 
Packit Service ac8aad
@@ -756,7 +770,9 @@ static long aio_read_events_ring(struct
Packit Service ac8aad
 
Packit Service ac8aad
 	pr_debug("%li  h%u t%u\n", ret, head, ctx->tail);
Packit Service ac8aad
 
Packit Service ac8aad
-	atomic_sub(ret, &ctx->reqs_active);
Packit Service ac8aad
+	reqs_active_v2 = kpatch_shadow_get(ctx, "reqs_active_v2");
Packit Service ac8aad
+	if (!reqs_active_v2)
Packit Service ac8aad
+		atomic_sub(ret, &ctx->reqs_active);
Packit Service ac8aad
 out:
Packit Service ac8aad
 	mutex_unlock(&ctx->ring_lock);
Packit Service ac8aad
```
Packit Service ac8aad
 
Packit Service ac8aad
The previous example can be extended to use shadow variable storage to handle
Packit Service ac8aad
locking semantic changes.  Consider the [upstream fix](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1d147bfa64293b2723c4fec50922168658e613ba)
Packit Service ac8aad
for CVE-2014-2706, which added a `ps_lock` to `struct sta_info` to protect
Packit Service ac8aad
critical sections throughout `net/mac80211/sta_info.c`.
Packit Service ac8aad
Packit Service ac8aad
When allocating a new `struct sta_info`, allocate a corresponding "ps_lock"
Packit Service ac8aad
shadow variable large enough to hold a `spinlock_t` instance, then initialize
Packit Service ac8aad
the spinlock:
Packit Service ac8aad
```
Packit Service ac8aad
@@ -333,12 +336,16 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
Packit Service ac8aad
 	struct sta_info *sta;
Packit Service ac8aad
 	struct timespec uptime;
Packit Service ac8aad
 	int i;
Packit Service ac8aad
+	spinlock_t *ps_lock;
Packit Service ac8aad
 
Packit Service ac8aad
 	sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
Packit Service ac8aad
 	if (!sta)
Packit Service ac8aad
 		return NULL;
Packit Service ac8aad
 
Packit Service ac8aad
 	spin_lock_init(&sta->lock);
Packit Service ac8aad
+	ps_lock = kpatch_shadow_alloc(sta, "ps_lock", sizeof(*ps_lock), gfp);
Packit Service ac8aad
+	if (ps_lock)
Packit Service ac8aad
+		spin_lock_init(ps_lock);
Packit Service ac8aad
 	INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
Packit Service ac8aad
 	INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
Packit Service ac8aad
 	mutex_init(&sta->ampdu_mlme.mtx);
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
Patched code can reference the "ps_lock" shadow variable associated with a
Packit Service ac8aad
given `struct sta_info` to determine and apply the correct locking semantic
Packit Service ac8aad
for that instance:
Packit Service ac8aad
```
Packit Service ac8aad
@@ -471,6 +475,23 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
Packit Service ac8aad
 		       sta->sta.addr, sta->sta.aid, ac);
Packit Service ac8aad
 		if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
Packit Service ac8aad
 			purge_old_ps_buffers(tx->local);
Packit Service ac8aad
+
Packit Service ac8aad
+		/* sync with ieee80211_sta_ps_deliver_wakeup */
Packit Service ac8aad
+		ps_lock = kpatch_shadow_get(sta, "ps_lock");
Packit Service ac8aad
+		if (ps_lock) {
Packit Service ac8aad
+			spin_lock(ps_lock);
Packit Service ac8aad
+			/*
Packit Service ac8aad
+			 * STA woke up the meantime and all the frames on ps_tx_buf have
Packit Service ac8aad
+			 * been queued to pending queue. No reordering can happen, go
Packit Service ac8aad
+			 * ahead and Tx the packet.
Packit Service ac8aad
+			 */
Packit Service ac8aad
+			if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
Packit Service ac8aad
+			    !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
Packit Service ac8aad
+				spin_unlock(ps_lock);
Packit Service ac8aad
+				return TX_CONTINUE;
Packit Service ac8aad
+			}
Packit Service ac8aad
+		}
Packit Service ac8aad
+
Packit Service ac8aad
 		if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
Packit Service ac8aad
 			struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
Packit Service ac8aad
 			ps_dbg(tx->sdata,
Packit Service ac8aad
```
Packit Service ac8aad
Packit Service ac8aad
Init code changes
Packit Service ac8aad
-----------------
Packit Service ac8aad
Packit Service ac8aad
Any code which runs in an `__init` function or during module or device
Packit Service ac8aad
initialization is problematic, as it may have already run before the patch was
Packit Service ac8aad
applied.  The patch may require a pre-patch callback which detects whether such
Packit Service ac8aad
init code has run, and which rewrites or changes the original initialization to
Packit Service ac8aad
force it into the desired state.  Some changes involving hardware init are
Packit Service ac8aad
inherently incompatible with live patching.
Packit Service ac8aad
Packit Service ac8aad
Header file changes
Packit Service ac8aad
-------------------
Packit Service ac8aad
Packit Service ac8aad
When changing header files, be extra careful.  If data is being changed, you
Packit Service ac8aad
probably need to modify the patch.  See "Data struct changes" above.
Packit Service ac8aad
Packit Service ac8aad
If a function prototype is being changed, make sure it's not an exported
Packit Service ac8aad
function.  Otherwise it could break out-of-tree modules.  One way to
Packit Service ac8aad
workaround this is to define an entirely new copy of the function (with
Packit Service ac8aad
updated code) and patch in-tree callers to invoke it rather than the
Packit Service ac8aad
deprecated version.
Packit Service ac8aad
Packit Service ac8aad
Many header file changes result in a complete rebuild of the kernel tree, which
Packit Service ac8aad
makes kpatch-build have to compare every .o file in the kernel.  It slows the
Packit Service ac8aad
build down a lot, and can even fail to build if kpatch-build has any bugs
Packit Service ac8aad
lurking.  If it's a trivial header file change, like adding a macro, it's
Packit Service ac8aad
advisable to just move that macro into the .c file where it's needed to avoid
Packit Service ac8aad
changing the header file at all.
Packit Service ac8aad
Packit Service ac8aad
Dealing with unexpected changed functions
Packit Service ac8aad
-----------------------------------------
Packit Service ac8aad
Packit Service ac8aad
In general, it's best to patch as minimally as possible.  If kpatch-build is
Packit Service ac8aad
reporting some unexpected function changes, it's always a good idea to try to
Packit Service ac8aad
figure out why it thinks they changed.  In many cases you can change the source
Packit Service ac8aad
patch so that they no longer change.
Packit Service ac8aad
Packit Service ac8aad
Some examples:
Packit Service ac8aad
Packit Service ac8aad
* If a changed function was inlined, then the callers which inlined the
Packit Service ac8aad
  function will also change.  In this case there's nothing you can do to
Packit Service ac8aad
  prevent the extra changes.
Packit Service ac8aad
Packit Service ac8aad
* If a changed function was originally inlined, but turned into a callable
Packit Service ac8aad
  function after patching, consider adding `__always_inline` to the function
Packit Service ac8aad
  definition.  Likewise, if a function is only inlined after patching,
Packit Service ac8aad
  consider using `noinline` to prevent the compiler from doing so.
Packit Service ac8aad
Packit Service ac8aad
* If your patch adds a call to a function where the original version of the
Packit Service ac8aad
  function's ELF symbol has a .constprop or .isra suffix, and the corresponding
Packit Service ac8aad
  patched function doesn't, that means the patch caused gcc to no longer
Packit Service ac8aad
  perform an interprocedural optimization, which affects the function and all
Packit Service ac8aad
  its callers.  If you want to prevent this from happening, copy/paste the
Packit Service ac8aad
  function with a new name and call the new function from your patch.
Packit Service ac8aad
Packit Service ac8aad
* Moving around source code lines can introduce unique instructions if any
Packit Service ac8aad
  `__LINE__` preprocessor macros are in use. This can be mitigated by adding
Packit Service ac8aad
  any new functions to the bottom of source files, using newline whitespace to
Packit Service ac8aad
  maintain original line counts, etc. A more exact fix can be employed by
Packit Service ac8aad
  modifying the source code that invokes `__LINE__` and hard-coding the
Packit Service ac8aad
  original line number in place.
Packit Service ac8aad
Packit Service ac8aad
Removing references to static local variables
Packit Service ac8aad
---------------------------------------------
Packit Service ac8aad
Packit Service ac8aad
Removing references to static locals will fail to patch unless extra steps are taken.
Packit Service ac8aad
Static locals are basically global variables because they outlive the function's
Packit Service ac8aad
scope. They need to be correlated so that the new function will use the old static
Packit Service ac8aad
local. That way patching the function doesn't inadvertently reset the variable
Packit Service ac8aad
to zero; instead the variable keeps its old value.
Packit Service ac8aad
Packit Service ac8aad
To work around this limitation one needs to retain the reference to the static local.
Packit Service ac8aad
This might be as simple as adding the variable back in the patched function in a 
Packit Service ac8aad
non-functional way and ensuring the compiler doesn't optimize it away.
Packit Service ac8aad
Packit Service ac8aad
Code removal
Packit Service ac8aad
------------
Packit Service ac8aad
Packit Service ac8aad
Some fixes may replace or completely remove functions and references
Packit Service ac8aad
to them. Remember that kpatch modules can only add new functions and
Packit Service ac8aad
redirect existing functions, so "removed" functions will continue to exist in
Packit Service ac8aad
kernel address space as effectively dead code.
Packit Service ac8aad
Packit Service ac8aad
That means this patch (source code removal of `cmdline_proc_show`):
Packit Service ac8aad
```
Packit Service ac8aad
diff -Nupr src.orig/fs/proc/cmdline.c src/fs/proc/cmdline.c
Packit Service ac8aad
--- src.orig/fs/proc/cmdline.c	2016-11-30 19:39:49.317737234 +0000
Packit Service ac8aad
+++ src/fs/proc/cmdline.c	2016-11-30 19:39:52.696737234 +0000
Packit Service ac8aad
@@ -3,15 +3,15 @@
Packit Service ac8aad
 #include <linux/proc_fs.h>
Packit Service ac8aad
 #include <linux/seq_file.h>
Packit Service ac8aad
 
Packit Service ac8aad
-static int cmdline_proc_show(struct seq_file *m, void *v)
Packit Service ac8aad
-{
Packit Service ac8aad
-	seq_printf(m, "%s\n", saved_command_line);
Packit Service ac8aad
-	return 0;
Packit Service ac8aad
-}
Packit Service ac8aad
+static int cmdline_proc_show_v2(struct seq_file *m, void *v)
Packit Service ac8aad
+{
Packit Service ac8aad
+	seq_printf(m, "%s kpatch\n", saved_command_line);
Packit Service ac8aad
+	return 0;
Packit Service ac8aad
+}
Packit Service ac8aad
 
Packit Service ac8aad
 static int cmdline_proc_open(struct inode *inode, struct file *file)
Packit Service ac8aad
 {
Packit Service ac8aad
-	return single_open(file, cmdline_proc_show, NULL);
Packit Service ac8aad
+	return single_open(file, cmdline_proc_show_v2, NULL);
Packit Service ac8aad
 }
Packit Service ac8aad
 
Packit Service ac8aad
 static const struct file_operations cmdline_proc_fops = {
Packit Service ac8aad
```
Packit Service ac8aad
will generate an equivalent kpatch module to this patch (dead
Packit Service ac8aad
`cmdline_proc_show` left in source):
Packit Service ac8aad
```
Packit Service ac8aad
diff -Nupr src.orig/fs/proc/cmdline.c src/fs/proc/cmdline.c
Packit Service ac8aad
--- src.orig/fs/proc/cmdline.c	2016-11-30 19:39:49.317737234 +0000
Packit Service ac8aad
+++ src/fs/proc/cmdline.c	2016-11-30 19:39:52.696737234 +0000
Packit Service ac8aad
@@ -9,9 +9,15 @@ static int cmdline_proc_show(struct seq_
Packit Service ac8aad
 	return 0;
Packit Service ac8aad
 }
Packit Service ac8aad
 
Packit Service ac8aad
+static int cmdline_proc_show_v2(struct seq_file *m, void *v)
Packit Service ac8aad
+{
Packit Service ac8aad
+	seq_printf(m, "%s kpatch\n", saved_command_line);
Packit Service ac8aad
+	return 0;
Packit Service ac8aad
+}
Packit Service ac8aad
+
Packit Service ac8aad
 static int cmdline_proc_open(struct inode *inode, struct file *file)
Packit Service ac8aad
 {
Packit Service ac8aad
-	return single_open(file, cmdline_proc_show, NULL);
Packit Service ac8aad
+	return single_open(file, cmdline_proc_show_v2, NULL);
Packit Service ac8aad
 }
Packit Service ac8aad
 
Packit Service ac8aad
 static const struct file_operations cmdline_proc_fops = {
Packit Service ac8aad
```
Packit Service ac8aad
In both versions, `kpatch-build` will determine that only
Packit Service ac8aad
`cmdline_proc_open` has changed and that `cmdline_proc_show_v2` is a
Packit Service ac8aad
new function.
Packit Service ac8aad
Packit Service ac8aad
In some patching cases it might be necessary to completely remove the original
Packit Service ac8aad
function to avoid the compiler complaining about a defined, but unused
Packit Service ac8aad
function.  This will depend on symbol scope and kernel build options.
Packit Service ac8aad
Packit Service ac8aad
Other issues
Packit Service ac8aad
------------
Packit Service ac8aad
Packit Service ac8aad
When adding a call to `printk_once()`, `pr_warn_once()`, or any other "once"
Packit Service ac8aad
variation of `printk()`, you'll get the following eror:
Packit Service ac8aad
Packit Service ac8aad
```
Packit Service ac8aad
ERROR: vmx.o: 1 unsupported section change(s)
Packit Service ac8aad
vmx.o: WARNING: unable to correlate static local variable __print_once.60588 used by vmx_update_pi_irte, assuming variable is new
Packit Service ac8aad
vmx.o: changed function: vmx_update_pi_irte
Packit Service ac8aad
vmx.o: data section .data..read_mostly selected for inclusion
Packit Service ac8aad
/usr/lib/kpatch/create-diff-object: unreconcilable difference
Packit Service ac8aad
```
Packit Service ac8aad
This error occurs because the `printk_once()` adds a static local variable to
Packit Service ac8aad
the `.data..read_mostly` section.  kpatch-build strict disallows any changes to
Packit Service ac8aad
that section, because in some cases a change to this section indicates a bug.
Packit Service ac8aad
Packit Service ac8aad
To work around this issue, you'll need to manually implement your own "once"
Packit Service ac8aad
logic which doesn't store the static variable in the `.data..read_mostly`
Packit Service ac8aad
section.
Packit Service ac8aad
Packit Service ac8aad
For example, a `pr_warn_once()` can be replaced with:
Packit Service ac8aad
```
Packit Service ac8aad
	static bool print_once;
Packit Service ac8aad
	...
Packit Service ac8aad
	if (!print_once) {
Packit Service ac8aad
		print_once = true;
Packit Service ac8aad
		pr_warn("...");
Packit Service ac8aad
	}
Packit Service ac8aad
```