efi/libstub: Implement printk-style logging
Use the efi_printk function in efi_info/efi_err, and add efi_debug. This allows formatted output at different log levels. Add the notion of a loglevel instead of just quiet/not-quiet, and parse the efi=debug kernel parameter in addition to quiet. Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Link: https://lore.kernel.org/r/20200520170223.GA3333632@rani.riverdale.lan/ Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
8fb331e10b
commit
23d5b73fbf
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/printk.h> /* For CONSOLE_LOGLEVEL_* */
|
||||||
#include <asm/efi.h>
|
#include <asm/efi.h>
|
||||||
|
|
||||||
#include "efistub.h"
|
#include "efistub.h"
|
||||||
@ -18,7 +19,7 @@
|
|||||||
bool efi_nochunk;
|
bool efi_nochunk;
|
||||||
bool efi_nokaslr;
|
bool efi_nokaslr;
|
||||||
bool efi_noinitrd;
|
bool efi_noinitrd;
|
||||||
bool efi_quiet;
|
int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT;
|
||||||
bool efi_novamap;
|
bool efi_novamap;
|
||||||
|
|
||||||
static bool efi_nosoftreserve;
|
static bool efi_nosoftreserve;
|
||||||
@ -58,6 +59,28 @@ int efi_printk(const char *fmt, ...)
|
|||||||
char printf_buf[256];
|
char printf_buf[256];
|
||||||
va_list args;
|
va_list args;
|
||||||
int printed;
|
int printed;
|
||||||
|
int loglevel = printk_get_level(fmt);
|
||||||
|
|
||||||
|
switch (loglevel) {
|
||||||
|
case '0' ... '9':
|
||||||
|
loglevel -= '0';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* Use loglevel -1 for cases where we just want to print to
|
||||||
|
* the screen.
|
||||||
|
*/
|
||||||
|
loglevel = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loglevel >= efi_loglevel)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (loglevel >= 0)
|
||||||
|
efi_puts("EFI stub: ");
|
||||||
|
|
||||||
|
fmt = printk_skip_level(fmt);
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
|
printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args);
|
||||||
@ -100,7 +123,7 @@ efi_status_t efi_parse_options(char const *cmdline)
|
|||||||
if (!strcmp(param, "nokaslr")) {
|
if (!strcmp(param, "nokaslr")) {
|
||||||
efi_nokaslr = true;
|
efi_nokaslr = true;
|
||||||
} else if (!strcmp(param, "quiet")) {
|
} else if (!strcmp(param, "quiet")) {
|
||||||
efi_quiet = true;
|
efi_loglevel = CONSOLE_LOGLEVEL_QUIET;
|
||||||
} else if (!strcmp(param, "noinitrd")) {
|
} else if (!strcmp(param, "noinitrd")) {
|
||||||
efi_noinitrd = true;
|
efi_noinitrd = true;
|
||||||
} else if (!strcmp(param, "efi") && val) {
|
} else if (!strcmp(param, "efi") && val) {
|
||||||
@ -114,6 +137,8 @@ efi_status_t efi_parse_options(char const *cmdline)
|
|||||||
efi_disable_pci_dma = true;
|
efi_disable_pci_dma = true;
|
||||||
if (parse_option_str(val, "no_disable_early_pci_dma"))
|
if (parse_option_str(val, "no_disable_early_pci_dma"))
|
||||||
efi_disable_pci_dma = false;
|
efi_disable_pci_dma = false;
|
||||||
|
if (parse_option_str(val, "debug"))
|
||||||
|
efi_loglevel = CONSOLE_LOGLEVEL_DEBUG;
|
||||||
} else if (!strcmp(param, "video") &&
|
} else if (!strcmp(param, "video") &&
|
||||||
val && strstarts(val, "efifb:")) {
|
val && strstarts(val, "efifb:")) {
|
||||||
efi_parse_option_graphics(val + strlen("efifb:"));
|
efi_parse_option_graphics(val + strlen("efifb:"));
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kern_levels.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <asm/efi.h>
|
#include <asm/efi.h>
|
||||||
|
|
||||||
@ -34,7 +35,7 @@
|
|||||||
extern bool efi_nochunk;
|
extern bool efi_nochunk;
|
||||||
extern bool efi_nokaslr;
|
extern bool efi_nokaslr;
|
||||||
extern bool efi_noinitrd;
|
extern bool efi_noinitrd;
|
||||||
extern bool efi_quiet;
|
extern int efi_loglevel;
|
||||||
extern bool efi_novamap;
|
extern bool efi_novamap;
|
||||||
|
|
||||||
extern const efi_system_table_t *efi_system_table;
|
extern const efi_system_table_t *efi_system_table;
|
||||||
@ -49,11 +50,12 @@ extern const efi_system_table_t *efi_system_table;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define efi_info(msg) do { \
|
#define efi_info(fmt, ...) \
|
||||||
if (!efi_quiet) efi_puts("EFI stub: "msg); \
|
efi_printk(KERN_INFO fmt, ##__VA_ARGS__)
|
||||||
} while (0)
|
#define efi_err(fmt, ...) \
|
||||||
|
efi_printk(KERN_ERR "ERROR: " fmt, ##__VA_ARGS__)
|
||||||
#define efi_err(msg) efi_puts("EFI stub: ERROR: "msg)
|
#define efi_debug(fmt, ...) \
|
||||||
|
efi_printk(KERN_DEBUG "DEBUG: " fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
/* Helper macros for the usual case of using simple C variables: */
|
/* Helper macros for the usual case of using simple C variables: */
|
||||||
#ifndef fdt_setprop_inplace_var
|
#ifndef fdt_setprop_inplace_var
|
||||||
|
Loading…
Reference in New Issue
Block a user