[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] Xen patch to fix management support on HP ProLiant systems


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: "Garrett, Michael (ISS Software)" <Michael.Garrett@xxxxxx>
  • Date: Mon, 26 Nov 2007 20:45:02 +0000
  • Accept-language: en-US
  • Acceptlanguage: en-US
  • Delivery-date: Tue, 27 Nov 2007 09:42:36 -0800
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: AcgwbTf5DmKNBwdtR4ynmyM/V8G76w==
  • Thread-topic: Xen patch to fix management support on HP ProLiant systems

# HG changeset patch
# User Mike Garrett <michael.garrett@xxxxxx>
# Date 1196108221 21600
# Node ID 32be7dd9fab00cf4fb9014ab235497a39593ffb4
# Parent  ba69fe2dce91cd7ef633b4b21706344f6be1a6de

Adds support to allow host-platform-specific handling of I/O port traps.
Specifically adds support to handle an HP ProLiant I/O port in a special way.

Signed-off-by: Mike Garrett <michael.garrett@xxxxxx>

diff -r ba69fe2dce91 -r 32be7dd9fab0 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile     Tue Nov 13 20:13:50 2007 +0000
+++ b/xen/arch/x86/Makefile     Mon Nov 26 14:17:01 2007 -0600
@@ -31,6 +31,7 @@ obj-y += nmi.o
 obj-y += nmi.o
 obj-y += numa.o
 obj-y += physdev.o
+obj-y += hp_proliant.o
 obj-y += rwlock.o
 obj-y += setup.o
 obj-y += shutdown.o
diff -r ba69fe2dce91 -r 32be7dd9fab0 xen/arch/x86/hp_proliant.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/hp_proliant.c        Mon Nov 26 14:17:01 2007 -0600
@@ -0,0 +1,87 @@
+/* HP ProLiant specific code */

+#include <xen/config.h>

+#include <xen/init.h>

+#include <xen/sched.h>

+#include <xen/lib.h>

+#include <xen/errno.h>

+#include <xen/mm.h>

+#include <xen/console.h>

+#include <xen/shutdown.h>

+#include <asm/regs.h>

+#include <xen/delay.h>

+#include <xen/event.h>

+#include <xen/spinlock.h>

+#include <xen/irq.h>

+#include <xen/perfc.h>

+#include <xen/softirq.h>

+#include <xen/domain_page.h>

+#include <xen/symbols.h>

+#include <xen/iocap.h>

+#include <xen/nmi.h>

+#include <xen/version.h>

+#include <xen/kexec.h>

+#include <asm/paging.h>

+#include <asm/system.h>

+#include <asm/io.h>

+#include <asm/atomic.h>

+#include <asm/desc.h>

+#include <asm/debugreg.h>

+#include <asm/smp.h>

+#include <asm/flushtlb.h>

+#include <asm/uaccess.h>

+#include <asm/i387.h>

+#include <asm/debugger.h>

+#include <asm/msr.h>

+#include <asm/shared.h>

+#include <asm/x86_emulate.h>

+#include <asm/hvm/vpt.h>

+#include <xen/dmi.h>
+

+

+/* Declare access to a function pointer used to handle platform specific I/O 
port emulation */

+extern u8 (*emulate_platform_specific_io_port)(u8 opcode, u16 port, u8 value, 
char* io_emul_stub, struct cpu_user_regs *regs);

+

+/* Do special handling of HP ProLiant port */

+static u8 emulate_proliant_specific_io_port(u8 opcode, u16 port, u8 value, 
char* io_emul_stub, struct cpu_user_regs *regs)

+{

+       /* if opcode = I/O write, and port = 0CD4 and we are writing the high 
bit to 1 */

+       if (opcode == 0xee && port == 0x0cd4 && (value & 0x80))

+       {

+           void (*io_emul)(struct cpu_user_regs *) 
__attribute__((__regparm__(1)));

+

+           /* Handy function-typed pointer to the stub. */

+           io_emul = (void *) io_emul_stub;

+

+               /*

+                * important offsets (from original code)

+                * +0 -> +4/+11:        call host_to_guest_gpr_switch (32 bit 
and 64 bit)

+                * ret is rigged to return to guest_to_host_gpr_switch via a 
stack stunt

+                */

+

+               io_emul_stub[12] = 0x66;        //

+               io_emul_stub[13] = 0x9c;        // pushf

+               io_emul_stub[14] = 0xfa;        // cli

+               io_emul_stub[15] = 0xee;        // out  dx, al

+               // loop:

+               io_emul_stub[16] = 0xec;        // in al, dx

+               io_emul_stub[17] = 0xa8;        //

+               io_emul_stub[18] = 0x80;        // test al, 80h

+               io_emul_stub[19] = 0x75;        // jnz short loop

+               io_emul_stub[20] = 0xfb;        //

+               io_emul_stub[21] = 0x66;        //

+               io_emul_stub[22] = 0x9d;        // popf

+               io_emul_stub[23] = 0xc3;        // ret

+

+               io_emul(regs);

+

+               return 1;                                       // we handled 
it, no need for generic handling

+       }

+       return 0;                                               // we didn't 
handle it, do generic handling

+}

+

+int __init set_proliant_io_emul(struct dmi_system_id *d)

+{

+       /* emulate_platform_specific_io_port should be NULL on entry */

+       emulate_platform_specific_io_port = emulate_proliant_specific_io_port;

+    return 0;
+}

diff -r ba69fe2dce91 -r 32be7dd9fab0 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Tue Nov 13 20:13:50 2007 +0000
+++ b/xen/arch/x86/setup.c      Mon Nov 26 14:17:01 2007 -0600
@@ -49,6 +49,7 @@

 extern void generic_apic_probe(void);
 extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn);
+extern int __init io_emul_init(void);

 extern u16 boot_edid_caps;
 extern u8 boot_edid_info[128];
@@ -868,6 +869,8 @@ void __init __start_xen(unsigned long mb

     acpi_boot_init();

+       io_emul_init();
+
     init_cpu_to_node();

     if ( smp_found_config )
diff -r ba69fe2dce91 -r 32be7dd9fab0 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Nov 13 20:13:50 2007 +0000
+++ b/xen/arch/x86/traps.c      Mon Nov 26 14:17:01 2007 -0600
@@ -62,6 +62,7 @@
 #include <asm/shared.h>
 #include <asm/x86_emulate.h>
 #include <asm/hvm/vpt.h>
+#include <xen/dmi.h>

 /*
  * opt_nmi: one of 'ignore', 'dom0', or 'fatal'.
@@ -110,6 +111,7 @@ DECLARE_TRAP_HANDLER(spurious_interrupt_

 long do_set_debugreg(int reg, unsigned long value);
 unsigned long do_get_debugreg(int reg);
+u8 (*emulate_platform_specific_io_port)(u8 opcode, u16 port, u8 value, char* 
io_emul_stub, struct cpu_user_regs *regs) = NULL;

 static int debug_stack_lines = 20;
 integer_param("debug_stack_lines", debug_stack_lines);
@@ -1331,7 +1333,7 @@ static int emulate_privileged_op(struct
                            ? (*(u32 *)&regs->reg = (val)) \
                            : (*(u16 *)&regs->reg = (val)))
     unsigned long code_base, code_limit;
-    char io_emul_stub[16];
+    char io_emul_stub[32];     /* size increased from 16 to 32 bytes to handle 
platform-specific port emulation */
     void (*io_emul)(struct cpu_user_regs *) __attribute__((__regparm__(1)));
     u32 l, h, eax, edx;

@@ -1642,7 +1644,11 @@ static int emulate_privileged_op(struct
         switch ( op_bytes )
         {
         case 1:
-            if ( guest_outb_okay(port, v, regs) )
+                       /* check and emulate platform-specific I/O ports */
+                       if (emulate_platform_specific_io_port != NULL &&
+                               emulate_platform_specific_io_port(opcode, port, 
(u8) regs->eax, io_emul_stub, regs))
+                               ; /* no more work to do, if true, the platform 
specific handler emulated it fully */
+            else if ( guest_outb_okay(port, v, regs) )
             {
                 io_emul(regs);
                 if ( pv_post_outb_hook )
@@ -2850,6 +2856,67 @@ unsigned long do_get_debugreg(int reg)
     return current->arch.guest_context.debugreg[reg];
 }

+/*     This table is the set of system specific I/O emulation hooks */
+extern int __init set_proliant_io_emul(struct dmi_system_id *d);
+static struct dmi_system_id __initdata io_emul_init_tbl[] = {
+    {    /* Handle I/O emulation hook for certain HP ProLiant servers */
+        .callback = set_proliant_io_emul,
+        .ident = "HP ProLiant DL3xx",
+        .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL3"),
+        },
+    },
+    {    /* Handle I/O emulation hook for certain HP ProLiant servers */
+        .callback = set_proliant_io_emul,
+        .ident = "HP ProLiant DL5xx",
+        .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL5"),
+        },
+    },
+    {    /* Handle I/O emulation hook for certain HP ProLiant servers */
+        .callback = set_proliant_io_emul,
+        .ident = "HP ProLiant ML3xx",
+        .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant ML3"),
+        },
+    },
+    {    /* Handle I/O emulation hook for certain HP ProLiant servers */
+        .callback = set_proliant_io_emul,
+        .ident = "HP ProLiant ML5xx",
+        .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant ML5"),
+        },
+    },
+    {    /* Handle I/O emulation hook for certain HP ProLiant servers */
+        .callback = set_proliant_io_emul,
+        .ident = "HP ProLiant BL4xx",
+        .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL4"),
+        },
+    },
+    {    /* Handle I/O emulation hook for certain HP ProLiant servers */
+        .callback = set_proliant_io_emul,
+        .ident = "HP ProLiant BL6xx",
+        .matches = {
+                       DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
+            DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL6"),
+        },
+    },
+    { }
+};
+
+/* Called during setup, allows us to hook system-specific I/O emulation hooks 
*/
+int __init io_emul_init(void)
+{
+       dmi_check_system(io_emul_init_tbl);
+       return 0;
+}
+
 /*
  * Local variables:
  * mode: C

Attachment: hp_proliant_support.txt
Description: hp_proliant_support.txt

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.