Message ID | 56D9C9F802000078000D992D@prv-mh.provo.novell.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
> +static void do_inc_thresh(unsigned char key, struct cpu_user_regs *regs) > +{ > + ++*lower_thresh_adj; > + do_adj_thresh(key); > +} > + > +static void do_dec_thresh(unsigned char key, struct cpu_user_regs *regs) > +{ > + if ( *lower_thresh_adj ) > + --*lower_thresh_adj; > + do_adj_thresh(key); > +} > + > +static void __putstr(const char *); > +static void printk_start_of_line(const char *); > + > +static void do_loglvl_op(const struct xen_sysctl_loglvl_thresh *op, > + int *lower, int *upper, const char *which) > +{ > + if ( op->lower_thresh < 0 && op->upper_thresh < 0 ) > + return; > + > + if ( op->lower_thresh >= 0 ) > + *lower = op->lower_thresh; > + > + if ( op->upper_thresh >= 0 ) > + *upper = op->upper_thresh; > + ..snip.. > + case XEN_SYSCTL_LOGLVL_set: > + if ( (op->host.lower_thresh >= 0 && op->host.upper_thresh >= 0 && > + op->host.lower_thresh > op->host.upper_thresh) || > + (op->guest.lower_thresh >= 0 && op->guest.upper_thresh >= 0 && > + op->guest.lower_thresh > op->guest.upper_thresh) ) > + return -EINVAL; > + > + do_loglvl_op(&op->host, &xenlog_lower_thresh, > + &xenlog_upper_thresh, "standard"); The keyboard and the sysctl both allow the user to go beyound the XENLOG_ values we have. That is you could set the lower and upper threshold to be at 9 (or more) say. It will have the same effect as XENLOG_DEBUG (which is 4) as printk_prefix_check seems to have a simple < check. But perhaps to be correct only accept only proper values? Not allow the system admin to set the level to say 31415?
>>> On 04.03.16 at 21:55, <konrad.wilk@oracle.com> wrote: >> + case XEN_SYSCTL_LOGLVL_set: >> + if ( (op->host.lower_thresh >= 0 && op->host.upper_thresh >= 0 && >> + op->host.lower_thresh > op->host.upper_thresh) || >> + (op->guest.lower_thresh >= 0 && op->guest.upper_thresh >= 0 && >> + op->guest.lower_thresh > op->guest.upper_thresh) ) >> + return -EINVAL; >> + >> + do_loglvl_op(&op->host, &xenlog_lower_thresh, >> + &xenlog_upper_thresh, "standard"); > > > The keyboard and the sysctl both allow the user to go beyound the XENLOG_ > values we have. That is you could set the lower and upper threshold to be > at 9 (or more) say. It will have the same effect as XENLOG_DEBUG (which is > 4) > as printk_prefix_check seems to have a simple < check. > > But perhaps to be correct only accept only proper values? Not allow > the system admin to set the level to say 31415? Since there's no bad side effect from doing so I opted for not adding respective extra checks, keeping the code easier to read. Jan
On Mon, Mar 7, 2016 at 5:44 AM, Jan Beulich <JBeulich@suse.com> wrote: >>>> On 04.03.16 at 21:55, <konrad.wilk@oracle.com> wrote: >>> + case XEN_SYSCTL_LOGLVL_set: >>> + if ( (op->host.lower_thresh >= 0 && op->host.upper_thresh >= 0 && >>> + op->host.lower_thresh > op->host.upper_thresh) || >>> + (op->guest.lower_thresh >= 0 && op->guest.upper_thresh >= 0 && >>> + op->guest.lower_thresh > op->guest.upper_thresh) ) >>> + return -EINVAL; >>> + >>> + do_loglvl_op(&op->host, &xenlog_lower_thresh, >>> + &xenlog_upper_thresh, "standard"); >> >> >> The keyboard and the sysctl both allow the user to go beyound the XENLOG_ >> values we have. That is you could set the lower and upper threshold to be >> at 9 (or more) say. It will have the same effect as XENLOG_DEBUG (which is >> 4) >> as printk_prefix_check seems to have a simple < check. >> >> But perhaps to be correct only accept only proper values? Not allow >> the system admin to set the level to say 31415? > > Since there's no bad side effect from doing so I opted for not > adding respective extra checks, keeping the code easier to read. > Fair enough. Could you perhaps just add that in the commit description? Also I noticed that this patch is missing an XSM check in flask_sysctl - could that be added please? > Jan > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel
>>> On 07.03.16 at 15:41, <konrad@kernel.org> wrote: > On Mon, Mar 7, 2016 at 5:44 AM, Jan Beulich <JBeulich@suse.com> wrote: >>>>> On 04.03.16 at 21:55, <konrad.wilk@oracle.com> wrote: >>>> + case XEN_SYSCTL_LOGLVL_set: >>>> + if ( (op->host.lower_thresh >= 0 && op->host.upper_thresh >= 0 && >>>> + op->host.lower_thresh > op->host.upper_thresh) || >>>> + (op->guest.lower_thresh >= 0 && op->guest.upper_thresh >= 0 && >>>> + op->guest.lower_thresh > op->guest.upper_thresh) ) >>>> + return -EINVAL; >>>> + >>>> + do_loglvl_op(&op->host, &xenlog_lower_thresh, >>>> + &xenlog_upper_thresh, "standard"); >>> >>> >>> The keyboard and the sysctl both allow the user to go beyound the XENLOG_ >>> values we have. That is you could set the lower and upper threshold to be >>> at 9 (or more) say. It will have the same effect as XENLOG_DEBUG (which is >>> 4) >>> as printk_prefix_check seems to have a simple < check. >>> >>> But perhaps to be correct only accept only proper values? Not allow >>> the system admin to set the level to say 31415? >> >> Since there's no bad side effect from doing so I opted for not >> adding respective extra checks, keeping the code easier to read. >> > > Fair enough. Could you perhaps just add that in the commit description? Sure. > Also I noticed that this patch is missing an XSM check in flask_sysctl > - could that be added please? Of course; it's pretty ugly that one doesn't notice the lack thereof via a build failure. Jan
--- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -460,6 +460,10 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xe ret = tmem_control(&op->u.tmem_op); break; + case XEN_SYSCTL_loglvl_op: + ret = console_loglvl_op(&op->u.loglvl); + break; + default: ret = arch_do_sysctl(op, u_sysctl); copyback = 0; --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -168,7 +168,7 @@ static void __init parse_guest_loglvl(ch _parse_loglvl(s, &xenlog_guest_lower_thresh, &xenlog_guest_upper_thresh); } -static char * __init loglvl_str(int lvl) +static char *loglvl_str(int lvl) { switch ( lvl ) { @@ -181,6 +181,119 @@ static char * __init loglvl_str(int lvl) return "???"; } +static int *__read_mostly upper_thresh_adj = &xenlog_upper_thresh; +static int *__read_mostly lower_thresh_adj = &xenlog_lower_thresh; +static const char *__read_mostly thresh_adj = "standard"; + +static void do_toggle_guest(unsigned char key, struct cpu_user_regs *regs) +{ + if ( upper_thresh_adj == &xenlog_upper_thresh ) + { + upper_thresh_adj = &xenlog_guest_upper_thresh; + lower_thresh_adj = &xenlog_guest_lower_thresh; + thresh_adj = "guest"; + } + else + { + upper_thresh_adj = &xenlog_upper_thresh; + lower_thresh_adj = &xenlog_lower_thresh; + thresh_adj = "standard"; + } + printk("'%c' pressed -> %s log level adjustments enabled\n", + key, thresh_adj); +} + +static void do_adj_thresh(unsigned char key) +{ + if ( *upper_thresh_adj < *lower_thresh_adj ) + *upper_thresh_adj = *lower_thresh_adj; + printk("'%c' pressed -> %s log level: %s (rate limited %s)\n", + key, thresh_adj, loglvl_str(*lower_thresh_adj), + loglvl_str(*upper_thresh_adj)); +} + +static void do_inc_thresh(unsigned char key, struct cpu_user_regs *regs) +{ + ++*lower_thresh_adj; + do_adj_thresh(key); +} + +static void do_dec_thresh(unsigned char key, struct cpu_user_regs *regs) +{ + if ( *lower_thresh_adj ) + --*lower_thresh_adj; + do_adj_thresh(key); +} + +static void __putstr(const char *); +static void printk_start_of_line(const char *); + +static void do_loglvl_op(const struct xen_sysctl_loglvl_thresh *op, + int *lower, int *upper, const char *which) +{ + if ( op->lower_thresh < 0 && op->upper_thresh < 0 ) + return; + + if ( op->lower_thresh >= 0 ) + *lower = op->lower_thresh; + + if ( op->upper_thresh >= 0 ) + *upper = op->upper_thresh; + + if ( *upper < *lower ) + { + if ( op->upper_thresh < 0 ) + *upper = *lower; + else + *lower = *upper; + } + + if ( printk_ratelimit() ) + { + spin_lock_irq(&console_lock); + printk_start_of_line("(XEN) "); + __putstr(which); + __putstr(" log level: "); + __putstr(loglvl_str(*lower)); + __putstr(" (rate limited "); + __putstr(loglvl_str(*upper)); + __putstr(")\n"); + spin_unlock_irq(&console_lock); + } +} + +int console_loglvl_op(struct xen_sysctl_loglvl_op *op) +{ + switch ( op->cmd ) + { + default: + return -EOPNOTSUPP; + + case XEN_SYSCTL_LOGLVL_set: + if ( (op->host.lower_thresh >= 0 && op->host.upper_thresh >= 0 && + op->host.lower_thresh > op->host.upper_thresh) || + (op->guest.lower_thresh >= 0 && op->guest.upper_thresh >= 0 && + op->guest.lower_thresh > op->guest.upper_thresh) ) + return -EINVAL; + + do_loglvl_op(&op->host, &xenlog_lower_thresh, + &xenlog_upper_thresh, "standard"); + do_loglvl_op(&op->guest, &xenlog_guest_lower_thresh, + &xenlog_guest_upper_thresh, "guest"); + + /* fall through */ + case XEN_SYSCTL_LOGLVL_get: + op->host.lower_thresh = xenlog_lower_thresh; + op->host.upper_thresh = xenlog_upper_thresh; + + op->guest.lower_thresh = xenlog_guest_lower_thresh; + op->guest.upper_thresh = xenlog_guest_upper_thresh; + + break; + } + + return 0; +} /* * ******************************************************** * *************** ACCESS TO CONSOLE RING ***************** @@ -833,6 +946,12 @@ void __init console_endboot(void) register_keyhandler('w', dump_console_ring_key, "synchronously dump console ring buffer (dmesg)", 0); + register_irq_keyhandler('+', &do_inc_thresh, + "increase log level threshold", 0); + register_irq_keyhandler('-', &do_dec_thresh, + "decrease log level threshold", 0); + register_irq_keyhandler('G', &do_toggle_guest, + "toggle host/guest log level adjustment", 0); /* Serial input is directed to DOM0 by default. */ switch_serial_input(); --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -766,6 +766,17 @@ struct xen_sysctl_tmem_op { typedef struct xen_sysctl_tmem_op xen_sysctl_tmem_op_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tmem_op_t); +/* XEN_SYSCTL_loglvl_op */ +#define XEN_SYSCTL_LOGLVL_get 0 +#define XEN_SYSCTL_LOGLVL_set 1 +struct xen_sysctl_loglvl_op { + uint32_t cmd; /* XEN_SYSCTL_LOGLVL_* */ + struct xen_sysctl_loglvl_thresh { + /* Negative values mean "no adjustment". */ + int32_t lower_thresh, upper_thresh; + } host, guest; +}; + struct xen_sysctl { uint32_t cmd; #define XEN_SYSCTL_readconsole 1 @@ -791,6 +802,7 @@ struct xen_sysctl { #define XEN_SYSCTL_pcitopoinfo 22 #define XEN_SYSCTL_psr_cat_op 23 #define XEN_SYSCTL_tmem_op 24 +#define XEN_SYSCTL_loglvl_op 25 uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */ union { struct xen_sysctl_readconsole readconsole; @@ -816,6 +828,7 @@ struct xen_sysctl { struct xen_sysctl_psr_cmt_op psr_cmt_op; struct xen_sysctl_psr_cat_op psr_cat_op; struct xen_sysctl_tmem_op tmem_op; + struct xen_sysctl_loglvl_op loglvl; uint8_t pad[128]; } u; }; --- a/xen/include/xen/console.h +++ b/xen/include/xen/console.h @@ -12,6 +12,8 @@ struct xen_sysctl_readconsole; long read_console_ring(struct xen_sysctl_readconsole *op); +struct xen_sysctl_loglvl_op; +int console_loglvl_op(struct xen_sysctl_loglvl_op *); void console_init_preirq(void); void console_init_ring(void);