Merge branch 'bugfix' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Nov 2009 18:58:07 +0000 (10:58 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Nov 2009 18:58:07 +0000 (10:58 -0800)
* 'bugfix' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen:
  xen: mask extended topology info in cpuid
  xen/hvc: make sure console output is always emitted, with explicit polling

arch/x86/xen/enlighten.c
drivers/char/hvc_xen.c

index 23a4d80fb39e80a496bcd847e5de6d0886255fc3..dfbf70e65860dc768c255e07ac5d2c2b63e3a159 100644 (file)
@@ -178,6 +178,7 @@ static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0;
 static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                      unsigned int *cx, unsigned int *dx)
 {
+       unsigned maskebx = ~0;
        unsigned maskecx = ~0;
        unsigned maskedx = ~0;
 
@@ -185,9 +186,16 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
         * Mask out inconvenient features, to try and disable as many
         * unsupported kernel subsystems as possible.
         */
-       if (*ax == 1) {
+       switch (*ax) {
+       case 1:
                maskecx = cpuid_leaf1_ecx_mask;
                maskedx = cpuid_leaf1_edx_mask;
+               break;
+
+       case 0xb:
+               /* Suppress extended topology stuff */
+               maskebx = 0;
+               break;
        }
 
        asm(XEN_EMULATE_PREFIX "cpuid"
@@ -197,6 +205,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
                  "=d" (*dx)
                : "0" (*ax), "2" (*cx));
 
+       *bx &= maskebx;
        *cx &= maskecx;
        *dx &= maskedx;
 }
index eba999f8598d07a8a29fe03bac5bb4de18d39f62..a6ee32b599a880c13f3595fa43aaa9717b7fb1f0 100644 (file)
@@ -55,7 +55,7 @@ static inline void notify_daemon(void)
        notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
 }
 
-static int write_console(uint32_t vtermno, const char *data, int len)
+static int __write_console(const char *data, int len)
 {
        struct xencons_interface *intf = xencons_interface();
        XENCONS_RING_IDX cons, prod;
@@ -76,6 +76,29 @@ static int write_console(uint32_t vtermno, const char *data, int len)
        return sent;
 }
 
+static int write_console(uint32_t vtermno, const char *data, int len)
+{
+       int ret = len;
+
+       /*
+        * Make sure the whole buffer is emitted, polling if
+        * necessary.  We don't ever want to rely on the hvc daemon
+        * because the most interesting console output is when the
+        * kernel is crippled.
+        */
+       while (len) {
+               int sent = __write_console(data, len);
+               
+               data += sent;
+               len -= sent;
+
+               if (unlikely(len))
+                       HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
+       }
+
+       return ret;
+}
+
 static int read_console(uint32_t vtermno, char *buf, int len)
 {
        struct xencons_interface *intf = xencons_interface();