mirror of https://gitee.com/openkylin/linux.git
powerpc/xmon: add read-only mode
Operations which write to memory and special purpose registers should be restricted on systems with integrity guarantees (such as Secure Boot) and, optionally, to avoid self-destructive behaviors. Add a config option, XMON_DEFAULT_RO_MODE, to set default xmon behavior. The kernel cmdline options xmon=ro and xmon=rw override this default. The following xmon operations are affected: memops: disable memmove disable memset disable memzcan memex: no-op'd mwrite super_regs: no-op'd write_spr bpt_cmds: disable proc_call: disable Signed-off-by: Christopher M. Riedl <cmr@informatik.wtf> Reviewed-by: Oliver O'Halloran <oohall@gmail.com> Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
5d085ec04a
commit
0acb5f6456
|
@ -117,6 +117,14 @@ config XMON_DISASSEMBLY
|
|||
to say Y here, unless you're building for a memory-constrained
|
||||
system.
|
||||
|
||||
config XMON_DEFAULT_RO_MODE
|
||||
bool "Restrict xmon to read-only operations by default"
|
||||
depends on XMON
|
||||
default y
|
||||
help
|
||||
Operate xmon in read-only mode. The cmdline options 'xmon=rw' and
|
||||
'xmon=ro' override this default.
|
||||
|
||||
config DEBUGGER
|
||||
bool
|
||||
depends on KGDB || XMON
|
||||
|
|
|
@ -80,6 +80,7 @@ static int set_indicator_token = RTAS_UNKNOWN_SERVICE;
|
|||
#endif
|
||||
static unsigned long in_xmon __read_mostly = 0;
|
||||
static int xmon_on = IS_ENABLED(CONFIG_XMON_DEFAULT);
|
||||
static bool xmon_is_ro = IS_ENABLED(CONFIG_XMON_DEFAULT_RO_MODE);
|
||||
|
||||
static unsigned long adrs;
|
||||
static int size = 1;
|
||||
|
@ -202,6 +203,8 @@ static void dump_tlb_book3e(void);
|
|||
#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
|
||||
#endif
|
||||
|
||||
static const char *xmon_ro_msg = "Operation disabled: xmon in read-only mode\n";
|
||||
|
||||
static char *help_string = "\
|
||||
Commands:\n\
|
||||
b show breakpoints\n\
|
||||
|
@ -989,6 +992,10 @@ cmds(struct pt_regs *excp)
|
|||
memlocate();
|
||||
break;
|
||||
case 'z':
|
||||
if (xmon_is_ro) {
|
||||
printf(xmon_ro_msg);
|
||||
break;
|
||||
}
|
||||
memzcan();
|
||||
break;
|
||||
case 'i':
|
||||
|
@ -1042,6 +1049,10 @@ cmds(struct pt_regs *excp)
|
|||
set_lpp_cmd();
|
||||
break;
|
||||
case 'b':
|
||||
if (xmon_is_ro) {
|
||||
printf(xmon_ro_msg);
|
||||
break;
|
||||
}
|
||||
bpt_cmds();
|
||||
break;
|
||||
case 'C':
|
||||
|
@ -1055,6 +1066,10 @@ cmds(struct pt_regs *excp)
|
|||
bootcmds();
|
||||
break;
|
||||
case 'p':
|
||||
if (xmon_is_ro) {
|
||||
printf(xmon_ro_msg);
|
||||
break;
|
||||
}
|
||||
proccall();
|
||||
break;
|
||||
case 'P':
|
||||
|
@ -1777,6 +1792,11 @@ read_spr(int n, unsigned long *vp)
|
|||
static void
|
||||
write_spr(int n, unsigned long val)
|
||||
{
|
||||
if (xmon_is_ro) {
|
||||
printf(xmon_ro_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setjmp(bus_error_jmp) == 0) {
|
||||
catch_spr_faults = 1;
|
||||
sync();
|
||||
|
@ -2016,6 +2036,12 @@ mwrite(unsigned long adrs, void *buf, int size)
|
|||
char *p, *q;
|
||||
|
||||
n = 0;
|
||||
|
||||
if (xmon_is_ro) {
|
||||
printf(xmon_ro_msg);
|
||||
return n;
|
||||
}
|
||||
|
||||
if (setjmp(bus_error_jmp) == 0) {
|
||||
catch_memory_errors = 1;
|
||||
sync();
|
||||
|
@ -2880,9 +2906,17 @@ memops(int cmd)
|
|||
scanhex((void *)&mcount);
|
||||
switch( cmd ){
|
||||
case 'm':
|
||||
if (xmon_is_ro) {
|
||||
printf(xmon_ro_msg);
|
||||
break;
|
||||
}
|
||||
memmove((void *)mdest, (void *)msrc, mcount);
|
||||
break;
|
||||
case 's':
|
||||
if (xmon_is_ro) {
|
||||
printf(xmon_ro_msg);
|
||||
break;
|
||||
}
|
||||
memset((void *)mdest, mval, mcount);
|
||||
break;
|
||||
case 'd':
|
||||
|
@ -3792,6 +3826,14 @@ static int __init early_parse_xmon(char *p)
|
|||
} else if (strncmp(p, "on", 2) == 0) {
|
||||
xmon_init(1);
|
||||
xmon_on = 1;
|
||||
} else if (strncmp(p, "rw", 2) == 0) {
|
||||
xmon_init(1);
|
||||
xmon_on = 1;
|
||||
xmon_is_ro = false;
|
||||
} else if (strncmp(p, "ro", 2) == 0) {
|
||||
xmon_init(1);
|
||||
xmon_on = 1;
|
||||
xmon_is_ro = true;
|
||||
} else if (strncmp(p, "off", 3) == 0)
|
||||
xmon_on = 0;
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue