[XEN] Add 'loglvl' and 'guest_loglvl' boot parameters.
authorkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Thu, 2 Nov 2006 22:24:20 +0000 (22:24 +0000)
committerkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Thu, 2 Nov 2006 22:24:20 +0000 (22:24 +0000)
 <lvl> := none|error|warning|info|debug|all

 loglvl=<lvl_print_always>[/<lvl_print_ratelimit>]
  <lvl_print_always>: log level which is always printed
  <lvl_print_rlimit>: log level which is rate-limit printed

 'loglvl' applies to non-guest-related messages.
 'guest_loglvl' applies to guest-related messages.

 Defaults: loglvl=warning ; guest_loglvl=none/warning

Also clean up hvm_print_line().

Signed-off-by: Keir Fraser <keir@xensource.com>
docs/src/user.tex
xen/arch/x86/domain.c
xen/arch/x86/hvm/hvm.c
xen/drivers/char/console.c
xen/include/asm-x86/hvm/domain.h
xen/include/xen/lib.h

index 768b22165abcd2abe742627a2d72b65bb2cc7c03..2528861a23e4add1f8c049aad4e23576ef17cfff 100644 (file)
@@ -3192,6 +3192,15 @@ editing \path{grub.conf}.
   input to DOM0 when it boots --- if it is `x' then auto-switching is
   disabled.  Any other value, or omitting the character, enables
   auto-switching.  [NB. Default switch-char is `a'.]
+\item [ loglvl=$<$level$>/<$level$>$ ]
+  Specify logging level. Messages of the specified severity level (and
+  higher) will be printed to the Xen console. Valid levels are `none',
+  `error', `warning', `info', `debug', and `all'. The second level
+  specifier is optional: it is used to specify message severities
+  which are to be rate limited. Default is `loglvl=warning'.
+\item [ guest\_loglvl=$<$level$>/<$level$>$ ] As for loglvl, but
+  applies to messages relating to guests. Default is
+  `guest\_loglvl=none/warning'. 
 \item [ nmi=xxx ]
   Specify what to do with an NMI parity or I/O error. \\
   `nmi=fatal':  Xen prints a diagnostic and then hangs. \\
index f763928010c85e71adf936a87fb45663b2c531d3..b484bcebb85804745c23f794200cdfb0627b2795 100644 (file)
@@ -243,6 +243,8 @@ int arch_domain_create(struct domain *d)
             goto fail;
         }
 
+        spin_lock_init(&d->arch.hvm_domain.pbuf_lock);
+
         rc = shadow_enable(d, SHM2_refcounts|SHM2_translate|SHM2_external);
         if ( rc != 0 )
             goto fail;
index cc052e823d8cb383e08408553c4945ebe7c69c6a..4c46a7ea8f9a41887bdda78d1e2d74b02553cebd 100644 (file)
@@ -325,22 +325,22 @@ int hvm_copy_from_guest_virt(void *buf, unsigned long vaddr, int size)
     return __hvm_copy(buf, shadow_gva_to_gpa(current, vaddr), size, 0);
 }
 
-/*
- * HVM specific printbuf. Mostly used for hvmloader chit-chat.
- */
+/* HVM specific printbuf. Mostly used for hvmloader chit-chat. */
 void hvm_print_line(struct vcpu *v, const char c)
 {
-    int *index = &v->domain->arch.hvm_domain.pbuf_index;
-    char *pbuf = v->domain->arch.hvm_domain.pbuf;
-
-    if (*index == HVM_PBUF_SIZE-2 || c == '\n') {
-        if (*index == HVM_PBUF_SIZE-2)
-            pbuf[(*index)++] = c;
-        pbuf[*index] = '\0';
-        printk("(GUEST: %u) %s\n", v->domain->domain_id, pbuf);
-        *index = 0;
-    } else
-        pbuf[(*index)++] = c;
+    struct hvm_domain *hd = &v->domain->arch.hvm_domain;
+
+    spin_lock(&hd->pbuf_lock);
+    hd->pbuf[hd->pbuf_idx++] = c;
+    if ( (hd->pbuf_idx == (sizeof(hd->pbuf) - 2)) || (c == '\n') )
+    {
+        if ( c != '\n' )
+            hd->pbuf[hd->pbuf_idx++] = '\n';
+        hd->pbuf[hd->pbuf_idx] = '\0';
+        printk(XENLOG_G_DEBUG "HVM%u: %s\n", v->domain->domain_id, hd->pbuf);
+        hd->pbuf_idx = 0;
+    }
+    spin_unlock(&hd->pbuf_lock);
 }
 
 typedef unsigned long hvm_hypercall_t(
index 5d609d15b0d872ac788b6f67a0dcdb4a0b185246..ddd367878ea9813d81d4eee3bf1ceef83ce7d686 100644 (file)
@@ -82,13 +82,76 @@ static DEFINE_SPINLOCK(console_lock);
 #define XENLOG_DEFAULT       1 /* XENLOG_WARNING */
 #define XENLOG_GUEST_DEFAULT 1 /* XENLOG_WARNING */
 
-int xenlog_upper_thresh = XENLOG_UPPER_THRESHOLD;
-int xenlog_lower_thresh = XENLOG_LOWER_THRESHOLD;
-int xenlog_guest_upper_thresh = XENLOG_GUEST_UPPER_THRESHOLD;
-int xenlog_guest_lower_thresh = XENLOG_GUEST_LOWER_THRESHOLD;
+static int xenlog_upper_thresh = XENLOG_UPPER_THRESHOLD;
+static int xenlog_lower_thresh = XENLOG_LOWER_THRESHOLD;
+static int xenlog_guest_upper_thresh = XENLOG_GUEST_UPPER_THRESHOLD;
+static int xenlog_guest_lower_thresh = XENLOG_GUEST_LOWER_THRESHOLD;
+
+static void parse_loglvl(char *s);
+static void parse_guest_loglvl(char *s);
+
+/*
+ * <lvl> := none|error|warning|info|debug|all
+ * loglvl=<lvl_print_always>[/<lvl_print_ratelimit>]
+ *  <lvl_print_always>: log level which is always printed
+ *  <lvl_print_rlimit>: log level which is rate-limit printed
+ * Similar definitions for guest_loglvl, but applies to guest tracing.
+ * Defaults: loglvl=warning ; guest_loglvl=none/warning
+ */
+custom_param("loglvl", parse_loglvl);
+custom_param("guest_loglvl", parse_guest_loglvl);
 
 static int xen_startup = 1;
 
+#define ___parse_loglvl(s, ps, lvlstr, lvlnum)          \
+    if ( !strncmp((s), (lvlstr), strlen(lvlstr)) ) {    \
+        *(ps) = (s) + strlen(lvlstr);                   \
+        return (lvlnum);                                \
+    }
+
+static int __parse_loglvl(char *s, char **ps)
+{
+    ___parse_loglvl(s, ps, "none",    0);
+    ___parse_loglvl(s, ps, "error",   1);
+    ___parse_loglvl(s, ps, "warning", 2);
+    ___parse_loglvl(s, ps, "info",    3);
+    ___parse_loglvl(s, ps, "debug",   4);
+    ___parse_loglvl(s, ps, "all",     4);
+    return 2; /* sane fallback */
+}
+
+static void _parse_loglvl(char *s, int *lower, int *upper)
+{
+    *lower = *upper = __parse_loglvl(s, &s);
+    if ( *s == '/' )
+        *upper = __parse_loglvl(s+1, &s);
+    if ( *upper < *lower )
+        *upper = *lower;
+}
+
+static void parse_loglvl(char *s)
+{
+    _parse_loglvl(s, &xenlog_lower_thresh, &xenlog_upper_thresh);
+}
+
+static void parse_guest_loglvl(char *s)
+{
+    _parse_loglvl(s, &xenlog_guest_lower_thresh, &xenlog_guest_upper_thresh);
+}
+
+static char *loglvl_str(int lvl)
+{
+    switch ( lvl )
+    {
+    case 0: return "Nothing";
+    case 1: return "Errors";
+    case 2: return "Errors and warnings";
+    case 3: return "Errors, warnings and info";
+    case 4: return "All";
+    }
+    return "???";
+}
+
 /*
  * ********************************************************
  * *************** ACCESS TO CONSOLE RING *****************
@@ -450,6 +513,14 @@ void console_endboot(void)
 {
     int i, j;
 
+    printk("Std. Loglevel: %s", loglvl_str(xenlog_lower_thresh));
+    if ( xenlog_upper_thresh != xenlog_lower_thresh )
+        printk(" (Rate-limited: %s)", loglvl_str(xenlog_upper_thresh));
+    printk("\nGuest Loglevel: %s", loglvl_str(xenlog_guest_lower_thresh));
+    if ( xenlog_guest_upper_thresh != xenlog_guest_lower_thresh )
+        printk(" (Rate-limited: %s)", loglvl_str(xenlog_guest_upper_thresh));
+    printk("\n");
+
     if ( opt_sync_console )
     {
         printk("**********************************************\n");
index 0ebec779c18593e3bfe4cd7a3f81cf89c47ab41d..ddcd2d12ee0ed5519cb90973b70f05e356649f08 100644 (file)
@@ -28,8 +28,6 @@
 #include <asm/hvm/vioapic.h>
 #include <public/hvm/params.h>
 
-#define HVM_PBUF_SIZE   80
-
 struct hvm_domain {
     unsigned long          shared_page_va;
     unsigned long          buffered_io_va;
@@ -45,8 +43,10 @@ struct hvm_domain {
     spinlock_t             round_robin_lock;
     int                    interrupt_request;
 
-    int                    pbuf_index;
-    char                   pbuf[HVM_PBUF_SIZE];
+    /* hvm_print_line() logging. */
+    char                   pbuf[80];
+    int                    pbuf_idx;
+    spinlock_t             pbuf_lock;
 
     uint64_t               params[HVM_NR_PARAMS];
 };
index 6327f3106ef3b1d39d796746b3b1a9e35fbf3a45..e05eac28a9ec872af254c0e069e0e9d561d236ad 100644 (file)
@@ -58,10 +58,6 @@ extern void panic(const char *format, ...)
 extern long vm_assist(struct domain *, unsigned int, unsigned int);
 extern int __printk_ratelimit(int ratelimit_ms, int ratelimit_burst);
 extern int printk_ratelimit(void);
-extern int xenlog_upper_thresh;
-extern int xenlog_lower_thresh;
-extern int xenlog_guest_upper_thresh;
-extern int xenlog_guest_lower_thresh;
 
 /* vsprintf.c */
 extern int sprintf(char * buf, const char * fmt, ...)