Re: [PATCH v5 18/21] arm64: Move "nokaslr" over to the early cpufeature infrastructure

From: Marc Zyngier
Date: Tue Jan 26 2021 - 01:31:31 EST


On 2021-01-25 12:54, Ard Biesheuvel wrote:
On Mon, 25 Jan 2021 at 11:53, Marc Zyngier <maz@xxxxxxxxxx> wrote:

Given that the early cpufeature infrastructure has borrowed quite
a lot of code from the kaslr implementation, let's reimplement
the matching of the "nokaslr" option with it.

Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx>
Acked-by: Catalin Marinas <catalin.marinas@xxxxxxx>
Acked-by: David Brazdil <dbrazdil@xxxxxxxxxx>
---
arch/arm64/kernel/idreg-override.c | 15 +++++++++++++
arch/arm64/kernel/kaslr.c | 36 ++----------------------------
2 files changed, 17 insertions(+), 34 deletions(-)

diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index cbb8eaa48742..3ccf51b84ba4 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -31,8 +31,22 @@ static const struct ftr_set_desc mmfr1 __initdata = {
},
};

+extern struct arm64_ftr_override kaslr_feature_override;
+
+static const struct ftr_set_desc kaslr __initdata = {

This should be __initconst not __initdata (below too)

+ .name = "kaslr",
+#ifdef CONFIG_RANDOMIZE_BASE
+ .override = &kaslr_feature_override,
+#endif
+ .fields = {
+ { "disabled", 0 },
+ {}
+ },
+};
+
static const struct ftr_set_desc * const regs[] __initdata = {
&mmfr1,
+ &kaslr,
};

static const struct {
@@ -41,6 +55,7 @@ static const struct {
} aliases[] __initdata = {
{ "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" },
{ "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" },
+ { "nokaslr", "kaslr.disabled=1" },
};


This struct now takes up
- ~100 bytes for the characters themselves (which btw are not emitted
into __initdata or __initconst)
- 6x8 bytes for the char pointers
- 6x24 bytes for the RELA relocations that annotate these pointers as
quantities that need to be relocated at boot (on a kernel built with
KASLR)

I know it's only a drop in the ocean, but in this case, where the
struct is statically declared and defined only once, and in the same
place, we could easily turn this into

static const struct {
char alias[24];
char param[20];
};

and get rid of all the overhead. The only slightly annoying thing is
that the array sizes need to be kept in sync with the largest instance
appearing in the array, but this is easy when the struct type is
declared in the same place where its only instance is defined.

Fair enough. I personally find the result butt-ugly, but I agree
that it certainly saves some memory. Does the following work for
you? I can even give symbolic names to the various constants (how
generous of me! ;-).

Thanks,

M.

diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index d1310438d95c..9e7043bdc808 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -14,15 +14,15 @@
#include <asm/setup.h>

struct ftr_set_desc {
- const char *name;
+ char name[20];
struct arm64_ftr_override *override;
struct {
- const char *name;
+ char name[20];
u8 shift;
} fields[];
};

-static const struct ftr_set_desc mmfr1 __initdata = {
+static const struct ftr_set_desc mmfr1 __initconst = {
.name = "id_aa64mmfr1",
.override = &id_aa64mmfr1_override,
.fields = {
@@ -31,7 +31,7 @@ static const struct ftr_set_desc mmfr1 __initdata = {
},
};

-static const struct ftr_set_desc pfr1 __initdata = {
+static const struct ftr_set_desc pfr1 __initconst = {
.name = "id_aa64pfr1",
.override = &id_aa64pfr1_override,
.fields = {
@@ -40,7 +40,7 @@ static const struct ftr_set_desc pfr1 __initdata = {
},
};

-static const struct ftr_set_desc isar1 __initdata = {
+static const struct ftr_set_desc isar1 __initconst = {
.name = "id_aa64isar1",
.override = &id_aa64isar1_override,
.fields = {
@@ -54,7 +54,7 @@ static const struct ftr_set_desc isar1 __initdata = {

extern struct arm64_ftr_override kaslr_feature_override;

-static const struct ftr_set_desc kaslr __initdata = {
+static const struct ftr_set_desc kaslr __initconst = {
.name = "kaslr",
#ifdef CONFIG_RANDOMIZE_BASE
.override = &kaslr_feature_override,
@@ -65,7 +65,7 @@ static const struct ftr_set_desc kaslr __initdata = {
},
};

-static const struct ftr_set_desc * const regs[] __initdata = {
+static const struct ftr_set_desc * const regs[] __initconst = {
&mmfr1,
&pfr1,
&isar1,
@@ -73,9 +73,9 @@ static const struct ftr_set_desc * const regs[] __initdata = {
};

static const struct {
- const char *alias;
- const char *feature;
-} aliases[] __initdata = {
+ char alias[30];
+ char feature[80];
+} aliases[] __initconst = {
{ "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" },
{ "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" },
{ "arm64.nobti", "id_aa64pfr1.bt=0" },

--
Jazz is not dead. It just smells funny...