From 5b7ca4507d64de729011c145d8ee9a2731f9502f Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:21 +0800 Subject: [PATCH 01/16] coccinelle: Add rules to find str_lo{w}_hi{gh}() replacements As other rules done, we add rules for str_lo{w}_hi{gh}() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 7c631fd8abe2..e91d4eb30161 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -165,3 +165,41 @@ e << str_high_low_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_high_low(%s)" % e) + +@str_lo_hi depends on patch@ +expression E; +@@ +- ((E) ? "lo" : "hi") ++ str_lo_hi(E) + +@str_lo_hi_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "lo" : "hi") + +@script:python depends on report@ +p << str_lo_hi_r.P; +e << str_lo_hi_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_lo_hi(%s)" % e) + +@str_low_high depends on patch@ +expression E; +@@ +- ((E) ? "low" : "high") ++ str_low_high(E) + +@str_low_high_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "low" : "high") + +@script:python depends on report@ +p << str_low_high_r.P; +e << str_low_high_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_low_high(%s)" % e) -- 2.51.0 From dd2275d349c2f02ceb6cd37f89b8b9920c602488 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:22 +0800 Subject: [PATCH 02/16] coccinelle: Add rules to find str_enable{d}_disable{d}() replacements As other rules done, we add rules for str_enable{d}_ disable{d}() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index e91d4eb30161..bb6b851ee2aa 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -203,3 +203,41 @@ e << str_low_high_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_low_high(%s)" % e) + +@str_enable_disable depends on patch@ +expression E; +@@ +- ((E) ? "enable" : "disable") ++ str_enable_disable(E) + +@str_enable_disable_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "enable" : "disable") + +@script:python depends on report@ +p << str_enable_disable_r.P; +e << str_enable_disable_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_enable_disable(%s)" % e) + +@str_enabled_disabled depends on patch@ +expression E; +@@ +- ((E) ? "enabled" : "disabled") ++ str_enabled_disabled(E) + +@str_enabled_disabled_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "enabled" : "disabled") + +@script:python depends on report@ +p << str_enabled_disabled_r.P; +e << str_enabled_disabled_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e) -- 2.51.0 From ba4b514a6f4ac420d872b8f16245e3ffa05c10a5 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:23 +0800 Subject: [PATCH 03/16] coccinelle: Add rules to find str_read_write() replacements As other rules done, we add rules for str_read_write() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index bb6b851ee2aa..29c507d86ffd 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -241,3 +241,22 @@ e << str_enabled_disabled_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e) + +@str_read_write depends on patch@ +expression E; +@@ +- ((E) ? "read" : "write") ++ str_read_write(E) + +@str_read_write_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "read" : "write") + +@script:python depends on report@ +p << str_read_write_r.P; +e << str_read_write_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_read_write(%s)" % e) -- 2.51.0 From c81ca023c30691dcae543bd770e7a3a4c63263ff Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:24 +0800 Subject: [PATCH 04/16] coccinelle: Add rules to find str_write_read() replacements As other rules done, we add rules for str_write_read() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 29c507d86ffd..64f04da2e9f4 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -260,3 +260,22 @@ e << str_read_write_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_read_write(%s)" % e) + +@str_write_read depends on patch@ +expression E; +@@ +- ((E) ? "write" : "read") ++ str_write_read(E) + +@str_write_read_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "write" : "read") + +@script:python depends on report@ +p << str_write_read_r.P; +e << str_write_read_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_write_read(%s)" % e) -- 2.51.0 From 9b5b4810559d3716aef9fdc8d555e4db1a031749 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:25 +0800 Subject: [PATCH 05/16] coccinelle: Add rules to find str_on_off() replacements As other rules done, we add rules for str_on_off() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 64f04da2e9f4..34ff8f48965c 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -279,3 +279,22 @@ e << str_write_read_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_write_read(%s)" % e) + +@str_on_off depends on patch@ +expression E; +@@ +- ((E) ? "on" : "off") ++ str_on_off(E) + +@str_on_off_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "on" : "off") + +@script:python depends on report@ +p << str_on_off_r.P; +e << str_on_off_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_on_off(%s)" % e) -- 2.51.0 From 253244cdf16a755039f9078b0a785176712f2584 Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:26 +0800 Subject: [PATCH 06/16] coccinelle: Add rules to find str_yes_no() replacements As other rules done, we add rules for str_yes_no() to check the relative opportunities. Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 34ff8f48965c..96dc7090395d 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -298,3 +298,22 @@ e << str_on_off_r.E; @@ coccilib.report.print_report(p[0], "opportunity for str_on_off(%s)" % e) + +@str_yes_no depends on patch@ +expression E; +@@ +- ((E) ? "yes" : "no") ++ str_yes_no(E) + +@str_yes_no_r depends on !patch exists@ +expression E; +position P; +@@ +* ((E@P) ? "yes" : "no") + +@script:python depends on report@ +p << str_yes_no_r.P; +e << str_yes_no_r.E; +@@ + +coccilib.report.print_report(p[0], "opportunity for str_yes_no(%s)" % e) -- 2.51.0 From f584e3752ca7bb1f8849a85816b3c974f1aa67ec Mon Sep 17 00:00:00 2001 From: Hongbo Li Date: Wed, 11 Sep 2024 09:09:27 +0800 Subject: [PATCH 07/16] coccinelle: Remove unnecessary parentheses for only one possible change. The parentheses are only needed if there is a disjunction, ie a set of possible changes. If there is only one pattern, we can remove these parentheses. Just like the format: - x + y not: ( - x + y ) Signed-off-by: Hongbo Li Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 96dc7090395d..95e9a3b31f86 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -43,18 +43,14 @@ coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e) @str_up_down depends on patch@ expression E; @@ -( - ((E) ? "up" : "down") + str_up_down(E) -) @str_up_down_r depends on !patch exists@ expression E; position P; @@ -( * ((E@P) ? "up" : "down") -) @script:python depends on report@ p << str_up_down_r.P; @@ -66,18 +62,14 @@ coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e) @str_down_up depends on patch@ expression E; @@ -( - ((E) ? "down" : "up") + str_down_up(E) -) @str_down_up_r depends on !patch exists@ expression E; position P; @@ -( * ((E@P) ? "down" : "up") -) @script:python depends on report@ p << str_down_up_r.P; -- 2.51.0 From 4003ba664bd16f5a969cc883295a9eb5a5aef19e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 28 Sep 2024 21:26:22 +0200 Subject: [PATCH 08/16] Reduce Coccinelle choices in string_choices.cocci The isomorphism neg_if_exp negates the test of a ?: conditional, making it unnecessary to have an explicit case for a negated test with the branches inverted. At the same time, we can disable neg_if_exp in cases where a different API function may be more suitable for a negated test. Finally, in the non-patch cases, E matches an expression with parentheses around it, so there is no need to mention () explicitly in the pattern. The () are still needed in the patch cases, because we want to drop them, if they are present. Signed-off-by: Julia Lawall --- scripts/coccinelle/api/string_choices.cocci | 91 ++++++++++----------- 1 file changed, 41 insertions(+), 50 deletions(-) diff --git a/scripts/coccinelle/api/string_choices.cocci b/scripts/coccinelle/api/string_choices.cocci index 95e9a3b31f86..375045086912 100644 --- a/scripts/coccinelle/api/string_choices.cocci +++ b/scripts/coccinelle/api/string_choices.cocci @@ -14,23 +14,18 @@ expression E; - ((E == 1) ? "" : "s") + str_plural(E) | -- ((E != 1) ? "s" : "") -+ str_plural(E) -| - ((E > 1) ? "s" : "") + str_plural(E) ) -@str_plural_r depends on !patch exists@ +@str_plural_r depends on !patch@ expression E; position P; @@ ( -* ((E@P == 1) ? "" : "s") +* (E@P == 1) ? "" : "s" | -* ((E@P != 1) ? "s" : "") -| -* ((E@P > 1) ? "s" : "") +* (E@P > 1) ? "s" : "" ) @script:python depends on report@ @@ -40,17 +35,17 @@ e << str_plural_r.E; coccilib.report.print_report(p[0], "opportunity for str_plural(%s)" % e) -@str_up_down depends on patch@ +@str_up_down depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "up" : "down") + str_up_down(E) -@str_up_down_r depends on !patch exists@ +@str_up_down_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "up" : "down") +* E@P ? "up" : "down" @script:python depends on report@ p << str_up_down_r.P; @@ -59,17 +54,17 @@ e << str_up_down_r.E; coccilib.report.print_report(p[0], "opportunity for str_up_down(%s)" % e) -@str_down_up depends on patch@ +@str_down_up depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "down" : "up") + str_down_up(E) -@str_down_up_r depends on !patch exists@ +@str_down_up_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "down" : "up") +* E@P ? "down" : "up" @script:python depends on report@ p << str_down_up_r.P; @@ -78,17 +73,17 @@ e << str_down_up_r.E; coccilib.report.print_report(p[0], "opportunity for str_down_up(%s)" % e) -@str_true_false depends on patch@ +@str_true_false depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "true" : "false") + str_true_false(E) -@str_true_false_r depends on !patch exists@ +@str_true_false_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "true" : "false") +* E@P ? "true" : "false" @script:python depends on report@ p << str_true_false_r.P; @@ -97,17 +92,17 @@ e << str_true_false_r.E; coccilib.report.print_report(p[0], "opportunity for str_true_false(%s)" % e) -@str_false_true depends on patch@ +@str_false_true depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "false" : "true") + str_false_true(E) -@str_false_true_r depends on !patch exists@ +@str_false_true_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "false" : "true") +* E@P ? "false" : "true" @script:python depends on report@ p << str_false_true_r.P; @@ -116,21 +111,17 @@ e << str_false_true_r.E; coccilib.report.print_report(p[0], "opportunity for str_false_true(%s)" % e) -@str_hi_lo depends on patch@ +@str_hi_lo depends on patch disable neg_if_exp@ expression E; @@ -( - ((E) ? "hi" : "lo") + str_hi_lo(E) -) -@str_hi_lo_r depends on !patch exists@ +@str_hi_lo_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -( -* ((E@P) ? "hi" : "lo") -) +* E@P ? "hi" : "lo" @script:python depends on report@ p << str_hi_lo_r.P; @@ -139,17 +130,17 @@ e << str_hi_lo_r.E; coccilib.report.print_report(p[0], "opportunity for str_hi_lo(%s)" % e) -@str_high_low depends on patch@ +@str_high_low depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "high" : "low") + str_high_low(E) -@str_high_low_r depends on !patch exists@ +@str_high_low_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "high" : "low") +* E@P ? "high" : "low" @script:python depends on report@ p << str_high_low_r.P; @@ -158,17 +149,17 @@ e << str_high_low_r.E; coccilib.report.print_report(p[0], "opportunity for str_high_low(%s)" % e) -@str_lo_hi depends on patch@ +@str_lo_hi depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "lo" : "hi") + str_lo_hi(E) -@str_lo_hi_r depends on !patch exists@ +@str_lo_hi_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "lo" : "hi") +* E@P ? "lo" : "hi" @script:python depends on report@ p << str_lo_hi_r.P; @@ -177,17 +168,17 @@ e << str_lo_hi_r.E; coccilib.report.print_report(p[0], "opportunity for str_lo_hi(%s)" % e) -@str_low_high depends on patch@ +@str_low_high depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "low" : "high") + str_low_high(E) -@str_low_high_r depends on !patch exists@ +@str_low_high_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "low" : "high") +* E@P ? "low" : "high" @script:python depends on report@ p << str_low_high_r.P; @@ -202,11 +193,11 @@ expression E; - ((E) ? "enable" : "disable") + str_enable_disable(E) -@str_enable_disable_r depends on !patch exists@ +@str_enable_disable_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "enable" : "disable") +* E@P ? "enable" : "disable" @script:python depends on report@ p << str_enable_disable_r.P; @@ -221,11 +212,11 @@ expression E; - ((E) ? "enabled" : "disabled") + str_enabled_disabled(E) -@str_enabled_disabled_r depends on !patch exists@ +@str_enabled_disabled_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "enabled" : "disabled") +* E@P ? "enabled" : "disabled" @script:python depends on report@ p << str_enabled_disabled_r.P; @@ -234,17 +225,17 @@ e << str_enabled_disabled_r.E; coccilib.report.print_report(p[0], "opportunity for str_enabled_disabled(%s)" % e) -@str_read_write depends on patch@ +@str_read_write depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "read" : "write") + str_read_write(E) -@str_read_write_r depends on !patch exists@ +@str_read_write_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "read" : "write") +* E@P ? "read" : "write" @script:python depends on report@ p << str_read_write_r.P; @@ -253,17 +244,17 @@ e << str_read_write_r.E; coccilib.report.print_report(p[0], "opportunity for str_read_write(%s)" % e) -@str_write_read depends on patch@ +@str_write_read depends on patch disable neg_if_exp@ expression E; @@ - ((E) ? "write" : "read") + str_write_read(E) -@str_write_read_r depends on !patch exists@ +@str_write_read_r depends on !patch disable neg_if_exp@ expression E; position P; @@ -* ((E@P) ? "write" : "read") +* E@P ? "write" : "read" @script:python depends on report@ p << str_write_read_r.P; @@ -278,11 +269,11 @@ expression E; - ((E) ? "on" : "off") + str_on_off(E) -@str_on_off_r depends on !patch exists@ +@str_on_off_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "on" : "off") +* E@P ? "on" : "off" @script:python depends on report@ p << str_on_off_r.P; @@ -297,11 +288,11 @@ expression E; - ((E) ? "yes" : "no") + str_yes_no(E) -@str_yes_no_r depends on !patch exists@ +@str_yes_no_r depends on !patch@ expression E; position P; @@ -* ((E@P) ? "yes" : "no") +* E@P ? "yes" : "no" @script:python depends on report@ p << str_yes_no_r.P; -- 2.51.0 From 3f749befb0998472470d850b11b430477c0718cc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 29 Sep 2024 14:47:33 -0700 Subject: [PATCH 09/16] x86: kvm: fix build error MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The cpu_emergency_register_virt_callback() function is used unconditionally by the x86 kvm code, but it is declared (and defined) conditionally: #if IS_ENABLED(CONFIG_KVM_INTEL) || IS_ENABLED(CONFIG_KVM_AMD) void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); ... leading to a build error when neither KVM_INTEL nor KVM_AMD support is enabled: arch/x86/kvm/x86.c: In function ‘kvm_arch_enable_virtualization’: arch/x86/kvm/x86.c:12517:9: error: implicit declaration of function ‘cpu_emergency_register_virt_callback’ [-Wimplicit-function-declaration] 12517 | cpu_emergency_register_virt_callback(kvm_x86_ops.emergency_disable_virtualization_cpu); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/kvm/x86.c: In function ‘kvm_arch_disable_virtualization’: arch/x86/kvm/x86.c:12522:9: error: implicit declaration of function ‘cpu_emergency_unregister_virt_callback’ [-Wimplicit-function-declaration] 12522 | cpu_emergency_unregister_virt_callback(kvm_x86_ops.emergency_disable_virtualization_cpu); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fix the build by defining empty helper functions the same way the old cpu_emergency_disable_virtualization() function was dealt with for the same situation. Maybe we could instead have made the call sites conditional, since the callers (kvm_arch_{en,dis}able_virtualization()) have an empty weak fallback. I'll leave that to the kvm people to argue about, this at least gets the build going for that particular config. Fixes: 590b09b1d88e ("KVM: x86: Register "emergency disable" callbacks when virt is enabled") Cc: Paolo Bonzini Cc: Sean Christopherson Cc: Kai Huang Cc: Chao Gao Cc: Farrah Chen Signed-off-by: Linus Torvalds --- arch/x86/include/asm/reboot.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/include/asm/reboot.h b/arch/x86/include/asm/reboot.h index d0ef2a678d66..c02183d3cdd7 100644 --- a/arch/x86/include/asm/reboot.h +++ b/arch/x86/include/asm/reboot.h @@ -31,6 +31,8 @@ void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback); void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback); void cpu_emergency_disable_virtualization(void); #else +static inline void cpu_emergency_register_virt_callback(cpu_emergency_virt_cb *callback) {} +static inline void cpu_emergency_unregister_virt_callback(cpu_emergency_virt_cb *callback) {} static inline void cpu_emergency_disable_virtualization(void) {} #endif /* CONFIG_KVM_INTEL || CONFIG_KVM_AMD */ -- 2.51.0 From 9852d85ec9d492ebef56dc5f229416c925758edc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 29 Sep 2024 15:06:19 -0700 Subject: [PATCH 10/16] Linux 6.12-rc1 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 265dd990a9b6..187a4ce2728e 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 6 -PATCHLEVEL = 11 +PATCHLEVEL = 12 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = Baby Opossum Posse # *DOCUMENTATION* -- 2.51.0 From 1b57747e978f920fb2affd1952ed913276019115 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 14 Aug 2024 01:10:54 -0700 Subject: [PATCH 11/16] riscv: Enable cbo.zero only when all harts support Zicboz Currently, we enable cbo.zero for usermode on each hart that supports the Zicboz extension. This means that the [ms]envcfg CSR value may differ between harts. Other features, such as pointer masking and CFI, require setting [ms]envcfg bits on a per-thread basis. The combination of these two adds quite some complexity and overhead to context switching, as we would need to maintain two separate masks for the per-hart and per-thread bits. Andrew Jones, who originally added Zicboz support, writes[1][2]: I've approached Zicboz the same way I would approach all extensions, which is to be per-hart. I'm not currently aware of a platform that is / will be composed of harts where some have Zicboz and others don't, but there's nothing stopping a platform like that from being built. So, how about we add code that confirms Zicboz is on all harts. If any hart does not have it, then we complain loudly and disable it on all the other harts. If it was just a hardware description bug, then it'll get fixed. If there's actually a platform which doesn't have Zicboz on all harts, then, when the issue is reported, we can decide to not support it, support it with defconfig, or support it under a Kconfig guard which must be enabled by the user. Let's follow his suggested solution and require the extension to be available on all harts, so the envcfg CSR value does not need to change when a thread migrates between harts. Since we are doing this for all extensions with fields in envcfg, the CSR itself only needs to be saved/ restored when it is present on all harts. This should not be a regression as no known hardware has asymmetric Zicboz support, but if anyone reports seeing the warning, we will re-evaluate our solution. Link: https://lore.kernel.org/linux-riscv/20240322-168f191eeb8479b2ea169a5e@orel/ [1] Link: https://lore.kernel.org/linux-riscv/20240323-28943722feb57a41fb0ff488@orel/ [2] Reviewed-by: Andrew Jones Reviewed-by: Conor Dooley Reviewed-by: Deepak Gupta Signed-off-by: Samuel Holland Reviewed-by: Charlie Jenkins Tested-by: Charlie Jenkins Link: https://lore.kernel.org/r/20240814081126.956287-2-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt --- arch/riscv/kernel/cpufeature.c | 7 ++++++- arch/riscv/kernel/suspend.c | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 3a8eeaa9310c..e560a253e99b 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -28,6 +28,8 @@ #define NUM_ALPHA_EXTS ('z' - 'a' + 1) +static bool any_cpu_has_zicboz; + unsigned long elf_hwcap __read_mostly; /* Host ISA bitmap */ @@ -98,6 +100,7 @@ static int riscv_ext_zicboz_validate(const struct riscv_isa_ext_data *data, pr_err("Zicboz disabled as cboz-block-size present, but is not a power-of-2\n"); return -EINVAL; } + any_cpu_has_zicboz = true; return 0; } @@ -919,8 +922,10 @@ unsigned long riscv_get_elf_hwcap(void) void riscv_user_isa_enable(void) { - if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_ZICBOZ)) + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOZ)) csr_set(CSR_ENVCFG, ENVCFG_CBZE); + else if (any_cpu_has_zicboz) + pr_warn_once("Zicboz disabled as it is unavailable on some harts\n"); } #ifdef CONFIG_RISCV_ALTERNATIVE diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c index c8cec0cc5833..9a8a0dc035b2 100644 --- a/arch/riscv/kernel/suspend.c +++ b/arch/riscv/kernel/suspend.c @@ -14,7 +14,7 @@ void suspend_save_csrs(struct suspend_context *context) { - if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG)) + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_XLINUXENVCFG)) context->envcfg = csr_read(CSR_ENVCFG); context->tvec = csr_read(CSR_TVEC); context->ie = csr_read(CSR_IE); @@ -37,7 +37,7 @@ void suspend_save_csrs(struct suspend_context *context) void suspend_restore_csrs(struct suspend_context *context) { csr_write(CSR_SCRATCH, 0); - if (riscv_cpu_has_extension_unlikely(smp_processor_id(), RISCV_ISA_EXT_XLINUXENVCFG)) + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_XLINUXENVCFG)) csr_write(CSR_ENVCFG, context->envcfg); csr_write(CSR_TVEC, context->tvec); csr_write(CSR_IE, context->ie); -- 2.51.0 From 5fc7355f01376e69964bb21b685025b042c37acc Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 14 Aug 2024 01:10:55 -0700 Subject: [PATCH 12/16] riscv: Add support for per-thread envcfg CSR values Some bits in the [ms]envcfg CSR, such as the CFI state and pointer masking mode, need to be controlled on a per-thread basis. Support this by keeping a copy of the CSR value in struct thread_struct and writing it during context switches. It is safe to discard the old CSR value during the context switch because the CSR is modified only by software, so the CSR will remain in sync with the copy in thread_struct. Use ALTERNATIVE directly instead of riscv_has_extension_unlikely() to minimize branchiness in the context switching code. Since thread_struct is copied during fork(), setting the value for the init task sets the default value for all other threads. Reviewed-by: Andrew Jones Reviewed-by: Deepak Gupta Signed-off-by: Samuel Holland Reviewed-by: Charlie Jenkins Link: https://lore.kernel.org/r/20240814081126.956287-3-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/processor.h | 1 + arch/riscv/include/asm/switch_to.h | 8 ++++++++ arch/riscv/kernel/cpufeature.c | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h index efa1b3519b23..c1a492508835 100644 --- a/arch/riscv/include/asm/processor.h +++ b/arch/riscv/include/asm/processor.h @@ -102,6 +102,7 @@ struct thread_struct { unsigned long s[12]; /* s[0]: frame pointer */ struct __riscv_d_ext_state fstate; unsigned long bad_cause; + unsigned long envcfg; u32 riscv_v_flags; u32 vstate_ctrl; struct __riscv_v_ext_state vstate; diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h index 7594df37cc9f..9685cd85e57c 100644 --- a/arch/riscv/include/asm/switch_to.h +++ b/arch/riscv/include/asm/switch_to.h @@ -70,6 +70,13 @@ static __always_inline bool has_fpu(void) { return false; } #define __switch_to_fpu(__prev, __next) do { } while (0) #endif +static inline void __switch_to_envcfg(struct task_struct *next) +{ + asm volatile (ALTERNATIVE("nop", "csrw " __stringify(CSR_ENVCFG) ", %0", + 0, RISCV_ISA_EXT_XLINUXENVCFG, 1) + :: "r" (next->thread.envcfg) : "memory"); +} + extern struct task_struct *__switch_to(struct task_struct *, struct task_struct *); @@ -103,6 +110,7 @@ do { \ __switch_to_vector(__prev, __next); \ if (switch_to_should_flush_icache(__next)) \ local_flush_icache_all(); \ + __switch_to_envcfg(__next); \ ((last) = __switch_to(__prev, __next)); \ } while (0) diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index e560a253e99b..27bafc5dd62d 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -923,7 +923,7 @@ unsigned long riscv_get_elf_hwcap(void) void riscv_user_isa_enable(void) { if (riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOZ)) - csr_set(CSR_ENVCFG, ENVCFG_CBZE); + current->thread.envcfg |= ENVCFG_CBZE; else if (any_cpu_has_zicboz) pr_warn_once("Zicboz disabled as it is unavailable on some harts\n"); } -- 2.51.0 From 368546ebe7e74cb6e18f17768533ab7077392a8c Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 14 Aug 2024 01:10:56 -0700 Subject: [PATCH 13/16] riscv: Call riscv_user_isa_enable() only on the boot hart Now that the [ms]envcfg CSR value is maintained per thread, not per hart, riscv_user_isa_enable() only needs to be called once during boot, to set the value for the init task. This also allows it to be marked as __init. Reviewed-by: Andrew Jones Reviewed-by: Conor Dooley Reviewed-by: Deepak Gupta Signed-off-by: Samuel Holland Reviewed-by: Charlie Jenkins Link: https://lore.kernel.org/r/20240814081126.956287-4-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/cpufeature.h | 2 +- arch/riscv/kernel/cpufeature.c | 4 ++-- arch/riscv/kernel/smpboot.c | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h index 45f9c1171a48..ce9a995730c1 100644 --- a/arch/riscv/include/asm/cpufeature.h +++ b/arch/riscv/include/asm/cpufeature.h @@ -31,7 +31,7 @@ DECLARE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); /* Per-cpu ISA extensions. */ extern struct riscv_isainfo hart_isa[NR_CPUS]; -void riscv_user_isa_enable(void); +void __init riscv_user_isa_enable(void); #define _RISCV_ISA_EXT_DATA(_name, _id, _subset_exts, _subset_exts_size, _validate) { \ .name = #_name, \ diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 27bafc5dd62d..b3a057c36996 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -920,12 +920,12 @@ unsigned long riscv_get_elf_hwcap(void) return hwcap; } -void riscv_user_isa_enable(void) +void __init riscv_user_isa_enable(void) { if (riscv_has_extension_unlikely(RISCV_ISA_EXT_ZICBOZ)) current->thread.envcfg |= ENVCFG_CBZE; else if (any_cpu_has_zicboz) - pr_warn_once("Zicboz disabled as it is unavailable on some harts\n"); + pr_warn("Zicboz disabled as it is unavailable on some harts\n"); } #ifdef CONFIG_RISCV_ALTERNATIVE diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 0f8f1c95ac38..e36d20205bd7 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -233,8 +233,6 @@ asmlinkage __visible void smp_callin(void) numa_add_cpu(curr_cpuid); set_cpu_online(curr_cpuid, true); - riscv_user_isa_enable(); - /* * Remote cache and TLB flushes are ignored while the CPU is offline, * so flush them both right now just in case. -- 2.51.0 From 8727163a1ae304b5b4ac5952f593936ab9024d37 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 16 Oct 2024 13:27:42 -0700 Subject: [PATCH 14/16] dt-bindings: riscv: Add pointer masking ISA extensions The RISC-V Pointer Masking specification defines three extensions: Smmpm, Smnpm, and Ssnpm. Document the behavior of these extensions as following the ratified version 1.0 of the specification. Acked-by: Conor Dooley Reviewed-by: Charlie Jenkins Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20241016202814.4061541-2-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt --- .../devicetree/bindings/riscv/extensions.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml index 2cf2026cff57..28bf1daa1d27 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -128,6 +128,18 @@ properties: changes to interrupts as frozen at commit ccbddab ("Merge pull request #42 from riscv/jhauser-2023-RC4") of riscv-aia. + - const: smmpm + description: | + The standard Smmpm extension for M-mode pointer masking as + ratified at commit d70011dde6c2 ("Update to ratified state") + of riscv-j-extension. + + - const: smnpm + description: | + The standard Smnpm extension for next-mode pointer masking as + ratified at commit d70011dde6c2 ("Update to ratified state") + of riscv-j-extension. + - const: smstateen description: | The standard Smstateen extension for controlling access to CSRs @@ -147,6 +159,12 @@ properties: and mode-based filtering as ratified at commit 01d1df0 ("Add ability to manually trigger workflow. (#2)") of riscv-count-overflow. + - const: ssnpm + description: | + The standard Ssnpm extension for next-mode pointer masking as + ratified at commit d70011dde6c2 ("Update to ratified state") + of riscv-j-extension. + - const: sstc description: | The standard Sstc supervisor-level extension for time compare as -- 2.51.0 From 2e6f6ea452aa9fa9f150520fdecf6bda31954db4 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 16 Oct 2024 13:27:43 -0700 Subject: [PATCH 15/16] riscv: Add ISA extension parsing for pointer masking The RISC-V Pointer Masking specification defines three extensions: Smmpm, Smnpm, and Ssnpm. Add support for parsing each of them. The specific extension which provides pointer masking support to userspace (Supm) depends on the kernel's privilege mode, so provide a macro to abstract this selection. Smmpm implies the existence of the mseccfg CSR. As it is the only user of this CSR so far, there is no need for an Xlinuxmseccfg extension. Reviewed-by: Charlie Jenkins Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20241016202814.4061541-3-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/hwcap.h | 5 +++++ arch/riscv/kernel/cpufeature.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index 46d9de54179e..8608883da453 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -93,6 +93,9 @@ #define RISCV_ISA_EXT_ZCMOP 84 #define RISCV_ISA_EXT_ZAWRS 85 #define RISCV_ISA_EXT_SVVPTC 86 +#define RISCV_ISA_EXT_SMMPM 87 +#define RISCV_ISA_EXT_SMNPM 88 +#define RISCV_ISA_EXT_SSNPM 89 #define RISCV_ISA_EXT_XLINUXENVCFG 127 @@ -101,8 +104,10 @@ #ifdef CONFIG_RISCV_M_MODE #define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SMAIA +#define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SMNPM #else #define RISCV_ISA_EXT_SxAIA RISCV_ISA_EXT_SSAIA +#define RISCV_ISA_EXT_SUPM RISCV_ISA_EXT_SSNPM #endif #endif /* _ASM_RISCV_HWCAP_H */ diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index b3a057c36996..94596bca464e 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -377,9 +377,12 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_BUNDLE(zvksg, riscv_zvksg_bundled_exts), __RISCV_ISA_EXT_DATA(zvkt, RISCV_ISA_EXT_ZVKT), __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA), + __RISCV_ISA_EXT_DATA(smmpm, RISCV_ISA_EXT_SMMPM), + __RISCV_ISA_EXT_SUPERSET(smnpm, RISCV_ISA_EXT_SMNPM, riscv_xlinuxenvcfg_exts), __RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN), __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA), __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), + __RISCV_ISA_EXT_SUPERSET(ssnpm, RISCV_ISA_EXT_SSNPM, riscv_xlinuxenvcfg_exts), __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC), __RISCV_ISA_EXT_DATA(svinval, RISCV_ISA_EXT_SVINVAL), __RISCV_ISA_EXT_DATA(svnapot, RISCV_ISA_EXT_SVNAPOT), -- 2.51.0 From 29eedc7d1587f42f33ae209be45c89c424ee9c00 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 16 Oct 2024 13:27:44 -0700 Subject: [PATCH 16/16] riscv: Add CSR definitions for pointer masking Pointer masking is controlled via a two-bit PMM field, which appears in various CSRs depending on which extensions are implemented. Smmpm adds the field to mseccfg; Smnpm adds the field to menvcfg; Ssnpm adds the field to senvcfg. If the H extension is implemented, Ssnpm also defines henvcfg.PMM and hstatus.HUPMM. Reviewed-by: Charlie Jenkins Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20241016202814.4061541-4-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt --- arch/riscv/include/asm/csr.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 25966995da04..fe5d4eb9adea 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -119,6 +119,10 @@ /* HSTATUS flags */ #ifdef CONFIG_64BIT +#define HSTATUS_HUPMM _AC(0x3000000000000, UL) +#define HSTATUS_HUPMM_PMLEN_0 _AC(0x0000000000000, UL) +#define HSTATUS_HUPMM_PMLEN_7 _AC(0x2000000000000, UL) +#define HSTATUS_HUPMM_PMLEN_16 _AC(0x3000000000000, UL) #define HSTATUS_VSXL _AC(0x300000000, UL) #define HSTATUS_VSXL_SHIFT 32 #endif @@ -195,6 +199,10 @@ /* xENVCFG flags */ #define ENVCFG_STCE (_AC(1, ULL) << 63) #define ENVCFG_PBMTE (_AC(1, ULL) << 62) +#define ENVCFG_PMM (_AC(0x3, ULL) << 32) +#define ENVCFG_PMM_PMLEN_0 (_AC(0x0, ULL) << 32) +#define ENVCFG_PMM_PMLEN_7 (_AC(0x2, ULL) << 32) +#define ENVCFG_PMM_PMLEN_16 (_AC(0x3, ULL) << 32) #define ENVCFG_CBZE (_AC(1, UL) << 7) #define ENVCFG_CBCFE (_AC(1, UL) << 6) #define ENVCFG_CBIE_SHIFT 4 @@ -216,6 +224,12 @@ #define SMSTATEEN0_SSTATEEN0_SHIFT 63 #define SMSTATEEN0_SSTATEEN0 (_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT) +/* mseccfg bits */ +#define MSECCFG_PMM ENVCFG_PMM +#define MSECCFG_PMM_PMLEN_0 ENVCFG_PMM_PMLEN_0 +#define MSECCFG_PMM_PMLEN_7 ENVCFG_PMM_PMLEN_7 +#define MSECCFG_PMM_PMLEN_16 ENVCFG_PMM_PMLEN_16 + /* symbolic CSR names: */ #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 @@ -382,6 +396,8 @@ #define CSR_MIP 0x344 #define CSR_PMPCFG0 0x3a0 #define CSR_PMPADDR0 0x3b0 +#define CSR_MSECCFG 0x747 +#define CSR_MSECCFGH 0x757 #define CSR_MVENDORID 0xf11 #define CSR_MARCHID 0xf12 #define CSR_MIMPID 0xf13 -- 2.51.0