[Skiboot] [PATCH] RFC: stick nvram query strings in their own ELF section

Oliver O'Halloran oohall at gmail.com
Wed Oct 2 19:42:40 AEST 2019


Use some gross inline asm to put the string literals passed to
nvram_query_*() into a seperate ELF section. This lets you
parse the binary to work out what nvram query strings this
skiboot supports. e.g.

[    0.028952161,3] ELOG: Error getting buffer to log error
[    0.029276848,3] found nvram string: 'bootargs'
[    0.029604244,3] found nvram string: 'pci-eeh-verbose'
[    0.029819131,3] found nvram string: 'pcie-max-link-speed'
[    0.030040501,3] found nvram string: 'pci-tracing'
[    0.030253694,3] found nvram string: 'log-level-driver'
[    0.030454654,3] found nvram string: 'log-level-memory'
[    0.030662925,3] found nvram string: 'fast-reset'
[    0.030864669,3] found nvram string: 'fast-reset'
[    0.031050007,3] found nvram string: 'fast-reset'
[    0.031246412,3] found nvram string: 'npu2-hmi-verbose'
[    0.031445555,3] found nvram string: 'opal-sw-xstop'
[    0.031631956,3] found nvram string: 'uart-con-policy'
[    0.031824669,3] found nvram string: 'opal-stop-state-disable-mask'
[    0.032051434,3] found nvram string: 'pci-eeh-mmio'
[    0.032241467,3] found nvram string: 'pci-retry-all'
[    0.032422848,3] found nvram string: 'phb-rx-err-max'
[    0.032607484,3] found nvram string: 'opal-npu2-snarf-cpm'
[    0.032814999,3] found nvram string: 'nv_zcal_override'
[    0.033010036,3] found nvram string: 'opencapi-link-training'
[    0.033226760,3] found nvram string: 'force-secure-mode'
[    0.033410720,3] found nvram string: 'force-trusted-mode'
[    0.033572192,3] found nvram string: ''

Seems the linker is smart enough to de-duplicate string literals when
they're placed in .rodata, but not in a custom section. Maybe there's
some way to fix that.

Not-Signed-off-by: Oliver O'Halloran <oohall at gmail.com>
---
 core/init.c         |  9 +++++++++
 core/nvram-format.c |  8 ++++----
 include/nvram.h     | 25 +++++++++++++++++++++----
 skiboot.lds.S       |  6 ++++++
 4 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/core/init.c b/core/init.c
index cd333dcbd8c4..e4b260e336c6 100644
--- a/core/init.c
+++ b/core/init.c
@@ -845,9 +845,18 @@ static void per_thread_sanity_checks(void)
 	assert(cpu->state != cpu_state_no_cpu);
 }
 
+extern char __nvram_str_start;
+extern char __nvram_str_end;
+
 void pci_nvram_init(void)
 {
 	const char *nvram_speed;
+	const char *p;
+
+	for (p = &__nvram_str_start; p <= &__nvram_str_end; p++) {
+		prerror("found nvram string: '%s'\n", p);
+		p += strlen(p);
+	}
 
 	verbose_eeh = nvram_query_eq_safe("pci-eeh-verbose", "true");
 	if (verbose_eeh)
diff --git a/core/nvram-format.c b/core/nvram-format.c
index 15a4a2df1b6e..02c6e9f2422c 100644
--- a/core/nvram-format.c
+++ b/core/nvram-format.c
@@ -287,12 +287,12 @@ static const char *__nvram_query(const char *key, bool dangerous)
 	return NULL;
 }
 
-const char *nvram_query_safe(const char *key)
+const char *___nvram_query_safe(const char *key)
 {
 	return __nvram_query(key, false);
 }
 
-const char *nvram_query_dangerous(const char *key)
+const char *___nvram_query_dangerous(const char *key)
 {
 	return __nvram_query(key, true);
 }
@@ -319,12 +319,12 @@ static bool __nvram_query_eq(const char *key, const char *value, bool dangerous)
 	return !strcmp(s, value);
 }
 
-bool nvram_query_eq_safe(const char *key, const char *value)
+bool ___nvram_query_eq_safe(const char *key, const char *value)
 {
 	return __nvram_query_eq(key, value, false);
 }
 
-bool nvram_query_eq_dangerous(const char *key, const char *value)
+bool ___nvram_query_eq_dangerous(const char *key, const char *value)
 {
 	return __nvram_query_eq(key, value, true);
 }
diff --git a/include/nvram.h b/include/nvram.h
index b0568294b2c1..a955ffc5ed8f 100644
--- a/include/nvram.h
+++ b/include/nvram.h
@@ -4,6 +4,16 @@
 #ifndef __NVRAM_H
 #define __NVRAM_H
 
+#define nvram_str(str) \
+        ({const char *d; asm volatile ( \
+                ".section .xxx,\"aS\""         "\n\t" \
+		"1: .string  \"" str "\""   "\n\t" \
+                ".previous"             "\n\t" \
+                "addis %0, 2,1b at toc@ha" "\n\t" \
+                "addi  %0,%0,1b at toc@l"  "\n\t" \
+                : "=r"(d)); d;})
+
+
 int nvram_format(void *nvram_image, uint32_t nvram_size);
 int nvram_check(void *nvram_image, uint32_t nvram_size);
 void nvram_reinit(void);
@@ -11,9 +21,16 @@ bool nvram_validate(void);
 bool nvram_has_loaded(void);
 bool nvram_wait_for_load(void);
 
-const char *nvram_query_safe(const char *name);
-const char *nvram_query_dangerous(const char *name);
-bool nvram_query_eq_safe(const char *key, const char *value);
-bool nvram_query_eq_dangerous(const char *key, const char *value);
+const char *___nvram_query_safe(const char *name);
+const char *___nvram_query_dangerous(const char *name);
+bool ___nvram_query_eq_safe(const char *key, const char *value);
+bool ___nvram_query_eq_dangerous(const char *key, const char *value);
+
+
+#define nvram_query_safe(s) ___nvram_query_safe(nvram_str(s))
+#define nvram_query_dangerous(s) ___nvram_query_dangerous(nvram_str(s))
+
+#define nvram_query_eq_safe(s, v) ___nvram_query_eq_safe(nvram_str(s), v)
+#define nvram_query_eq_dangerous(s, v) ___nvram_query_eq_dangerous(nvram_str(s), v)
 
 #endif /* __NVRAM_H */
diff --git a/skiboot.lds.S b/skiboot.lds.S
index 5b4bb41a20dc..fde958a795ed 100644
--- a/skiboot.lds.S
+++ b/skiboot.lds.S
@@ -142,6 +142,12 @@ SECTIONS
 		__platforms_end = .;
 	}
 
+	.xxx : {
+		__nvram_str_start = .;
+		KEEP(*(.xxx))
+		__nvram_str_end = .;
+	}
+
 	/* Do I need to keep these ? */
 	.dynsym : { *(.dynsym)	}
 	.dynstr : { *(.dynstr)	}
-- 
2.21.0



More information about the Skiboot mailing list