@@ -29,6 +29,8 @@ Table of contents
2929- [ Exported symbol versioning] ( #exported-symbol-versioning )
3030- [ System calls] ( #system-calls )
3131- [ Symbol Namespaces] ( #symbol-namespaces )
32+ - [ Cross Compile] ( #cross-compile )
33+
3234
3335Patch analysis
3436--------------
@@ -259,7 +261,7 @@ index 9bff3b28c357..18374fd35bd9 100644
259261@@ -1751,6 +1751,8 @@ struct task_struct *fork_idle(int cpu)
260262 return task;
261263 }
262-
264+
263265+ #include <linux/livepatch.h>
264266+ #define KPATCH_SHADOW_NEWPID 0
265267 /*
@@ -277,7 +279,7 @@ index 9bff3b28c357..18374fd35bd9 100644
277279+ NULL, NULL);
278280+ if (newpid)
279281+ *newpid = ctr++;
280-
282+
281283 trace_sched_process_fork(current, p);
282284```
283285
@@ -294,7 +296,7 @@ index 39684c79e8e2..fe0259d057a3 100644
294296@@ -394,13 +394,19 @@ static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
295297 seq_putc(m, '\n');
296298 }
297-
299+
298300+ #include <linux/livepatch.h>
299301+ #define KPATCH_SHADOW_NEWPID 0
300302 static inline void task_context_switch_counts(struct seq_file *m,
@@ -309,7 +311,7 @@ index 39684c79e8e2..fe0259d057a3 100644
309311+ if (newpid)
310312+ seq_printf(m, "newpid:\t%d\n", *newpid);
311313 }
312-
314+
313315 static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
314316```
315317
@@ -324,7 +326,7 @@ index 148a7842928d..44b6fe61e912 100644
324326@@ -791,6 +791,8 @@ static void check_stack_usage(void)
325327 static inline void check_stack_usage(void) {}
326328 #endif
327-
329+
328330+ #include <linux/livepatch.h>
329331+ #define KPATCH_SHADOW_NEWPID 0
330332 void do_exit(long code)
@@ -333,7 +335,7 @@ index 148a7842928d..44b6fe61e912 100644
333335@@ -888,6 +890,8 @@ void do_exit(long code)
334336 check_stack_usage();
335337 exit_thread();
336-
338+
337339+ klp_shadow_free(tsk, KPATCH_SHADOW_NEWPID, NULL);
338340+
339341 /*
@@ -395,7 +397,7 @@ semantic of the associated object:
395397 aio_put_req(iocb);
396398+ if (klp_shadow_get(ctx, KPATCH_SHADOW_REQS_ACTIVE_V2))
397399+ atomic_dec(&ctx->reqs_active);
398-
400+
399401 /*
400402 * We have to order our ring_info tail store above and test
401403```
@@ -404,9 +406,9 @@ Likewise, shadow variable non-existence can be tested to continue applying the
404406* old* data semantic:
405407``` diff
406408@@ -310,7 +312,8 @@ static void free_ioctx(struct kioctx *ctx)
407-
409+
408410 avail = (head <= ctx->tail ? ctx->tail : ctx->nr_events) - head;
409-
411+
410412- atomic_sub(avail, &ctx->reqs_active);
411413+ if (!klp_shadow_get(ctx, KPATCH_SHADOW_REQS_ACTIVE_V2))
412414+ atomic_sub(avail, &ctx->reqs_active);
@@ -415,14 +417,14 @@ Likewise, shadow variable non-existence can be tested to continue applying the
415417 }
416418@@ -757,6 +762,8 @@ static long aio_read_events_ring(struct kioctx *ctx,
417419 pr_debug("%li h%u t%u\n", ret, head, ctx->tail);
418-
420+
419421 atomic_sub(ret, &ctx->reqs_active);
420422+ if (!klp_shadow_get(ctx, KPATCH_SHADOW_REQS_ACTIVE_V2))
421423+ atomic_sub(ret, &ctx->reqs_active);
422424 out:
423425 mutex_unlock(&ctx->ring_lock);
424426```
425-
427+
426428The previous example can be extended to use shadow variable storage to handle
427429locking semantic changes. Consider the [ upstream fix] ( https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1d147bfa64293b2723c4fec50922168658e613ba )
428430for CVE-2014 -2706, which added a ` ps_lock ` to ` struct sta_info ` to protect
@@ -439,7 +441,7 @@ index decd30c1e290..758533dda4d8 100644
439441@@ -287,6 +287,8 @@ static int sta_prepare_rate_control(struct ieee80211_local *local,
440442 return 0;
441443 }
442-
444+
443445+ #include <linux/livepatch.h>
444446+ #define KPATCH_SHADOW_PS_LOCK 2
445447 struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
@@ -450,12 +452,12 @@ index decd30c1e290..758533dda4d8 100644
450452 struct ieee80211_tx_latency_bin_ranges *tx_latency;
451453 int i;
452454+ spinlock_t *ps_lock;
453-
455+
454456 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
455457 if (!sta)
456458@@ -330,6 +333,10 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
457459 rcu_read_unlock();
458-
460+
459461 spin_lock_init(&sta->lock);
460462+ ps_lock = klp_shadow_alloc(sta, KPATCH_SHADOW_PS_LOCK,
461463+ sizeof(*ps_lock), gfp, NULL, NULL);
@@ -477,7 +479,7 @@ index 97a02d3f7d87..0edb0ed8dc60 100644
477479@@ -459,12 +459,15 @@ static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
478480 return 1;
479481 }
480-
482+
481483+ #include <linux/livepatch.h>
482484+ #define KPATCH_SHADOW_PS_LOCK 2
483485 static ieee80211_tx_result
@@ -487,7 +489,7 @@ index 97a02d3f7d87..0edb0ed8dc60 100644
487489 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
488490 struct ieee80211_local *local = tx->local;
489491+ spinlock_t *ps_lock;
490-
492+
491493 if (unlikely(!sta))
492494 return TX_CONTINUE;
493495@@ -478,6 +481,23 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
@@ -588,7 +590,7 @@ local. That way patching the function doesn't inadvertently reset the variable
588590to zero; instead the variable keeps its old value.
589591
590592To work around this limitation one needs to retain the reference to the static local.
591- This might be as simple as adding the variable back in the patched function in a
593+ This might be as simple as adding the variable back in the patched function in a
592594non-functional way and ensuring the compiler doesn't optimize it away.
593595
594596Code removal
@@ -607,7 +609,7 @@ diff -Nupr src.orig/fs/proc/cmdline.c src/fs/proc/cmdline.c
607609@@ -3,15 +3,15 @@
608610 #include <linux/proc_fs.h>
609611 #include <linux/seq_file.h>
610-
612+
611613- static int cmdline_proc_show(struct seq_file *m, void *v)
612614- {
613615- seq_printf(m, "%s\n", saved_command_line);
@@ -618,13 +620,13 @@ diff -Nupr src.orig/fs/proc/cmdline.c src/fs/proc/cmdline.c
618620+ seq_printf(m, "%s kpatch\n", saved_command_line);
619621+ return 0;
620622+ }
621-
623+
622624 static int cmdline_proc_open(struct inode *inode, struct file *file)
623625 {
624626- return single_open(file, cmdline_proc_show, NULL);
625627+ return single_open(file, cmdline_proc_show_v2, NULL);
626628 }
627-
629+
628630 static const struct file_operations cmdline_proc_fops = {
629631```
630632will generate an equivalent kpatch module to this patch (dead
@@ -636,7 +638,7 @@ diff -Nupr src.orig/fs/proc/cmdline.c src/fs/proc/cmdline.c
636638@@ -9,9 +9,15 @@ static int cmdline_proc_show(struct seq_
637639 return 0;
638640 }
639-
641+
640642+ static int cmdline_proc_show_v2(struct seq_file *m, void *v)
641643+ {
642644+ seq_printf(m, "%s kpatch\n", saved_command_line);
@@ -648,7 +650,7 @@ diff -Nupr src.orig/fs/proc/cmdline.c src/fs/proc/cmdline.c
648650- return single_open(file, cmdline_proc_show, NULL);
649651+ return single_open(file, cmdline_proc_show_v2, NULL);
650652 }
651-
653+
652654 static const struct file_operations cmdline_proc_fops = {
653655```
654656In both versions, ` kpatch-build ` will determine that only
@@ -964,3 +966,25 @@ ERROR: modpost: module livepatch-test uses symbol dma_buf_export from namespace
964966```
965967To manually import the required namespace, add the MODULE_IMPORT_NS() macro to
966968the patch source. For example: ` MODULE_IMPORT_NS("DMA_BUF") `
969+
970+ Cross Compile
971+ -------------
972+
973+ It is recommended to build the livepatch in the same environment (compiler/library/etc.) as
974+ the target kernel. When the target kernel was cross compiled for a different architecture,
975+ it is recommended to cross compile the livepatch.
976+
977+ There are two options to cross compile a livepatch.
978+
979+ To specify a separate set of cross compilers,
980+ we can set the ` CROSS_COMPILE ` environment variable. For example, to use ` aarch64-gcc ` and ` aarch64-ld ` ,
981+ we can run kpatch-build as
982+ ```
983+ CROSSCOMPILE=aarch64- kpatch-build ...
984+ ```
985+
986+ llvm/clang supports cross compile with the same binaries. To specify a cross compile target, we can
987+ use the TARGET_ARCH environment variable, for example:
988+ ```
989+ TARGET_ARCH=aarch64 kpatch-build ...
990+ ```
0 commit comments