All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [HVM] Patches to make HVM capable of running OS/2.
@ 2007-03-16 12:07 Trolle Selander
  2007-03-16 12:21 ` Keir Fraser
  0 siblings, 1 reply; 10+ messages in thread
From: Trolle Selander @ 2007-03-16 12:07 UTC (permalink / raw)
  To: xen-devel; +Cc: Mats.Petersson, thomas.woller


[-- Attachment #1.1: Type: text/plain, Size: 2801 bytes --]

This is a set of patches that makes it possible to run OS/2 in a fully
virtualized guest. Because of the limited real-mode support on Intel VT,
this will currently only work on AMD-V  CPUs.
One of the patches (the smsw instruction emulation) is very "stop-gap" and
ugly as sin, but arguably even that is better than the current case which
blissfully does the wrong thing and then resumes execution from the wrong
EIP. :) The "right thing" is probably to add the lmsw/smsw instructions to
x86_emulate, and use that instead, unless something about how the control
register intercepts & emulation makes x86_emulate the wrong tool for the
job. Suggestions welcome, because I do want to make a proper general-case
fix for this, rather than the ugly special-case kludge provided here.

Patch descriptions:

Patch 1:
vpic-prio-fix.patch

This is plain bugfix - IRQ priority calculation is currently broken in the
virtual vpic. The priority shift should be a right-rotation, not a
left-rotation.

Patch 2:
mmio_ops.patch

Just two additional mmio ops that OS/2 needs emulated.

Patch 3:
qemu-dm_xchg.patch

Adds support for IOREQ_TYPE_XCHG in qemu-dm.

Patch 4:
ropmbios-e801-fix.patch

This is a "minimally intrusive" way to fix an issue that I think should
really be fixed in a different way.
Currently, the shared info, ioreq and buffered_io pages are mapped into the
guest's memory space as the three highest page frames. They are "protected"
from use by being marked as reserved in the e820 ram map. However, legacy
software won't know about the e820 call, and since the older e801 call
reports all ram, including the shared pages, the guest OS will end up using
them as regular ram with disastrous results.
This patch makes the older e801 bios call report one 64kb block less memory,
thus "protecting" the shared pages from older OS's in a similar manner to
the e820 call, at the expense of 52kb of wasted ram (the e801 call reports
memory in 64kb blocks, so no way around this).

However, while I think shared_info might be needed by PV-on-HVM drivers, I
don't see why the ioreq and buffered_iopage pages should be guest-accessible
at all. Rather they should be shared only between HV and Dom0, since their
use is strictly for the qemu-dm device model, which should happen entirely
"out of sight" of a fully virtualized guest.

Patch 5:

svm_smsw_modrm.patch

This is the abovementioned ugly patch.
The current SVM emulation of the smsw instruction makes the assumption that
the destination for the msw is always a register. While i think this is true
for the newer MOV from CRx, the legacy smsw can also copy to mem. Since I've
only encountered one specific usage of msw->mem this, which is msw->segment
base + offset, I've put in handling only of this special case. Consider this
one very temporary.

[-- Attachment #1.2: Type: text/html, Size: 3023 bytes --]

[-- Attachment #2: pic-prio-fix.patch --]
[-- Type: text/x-patch, Size: 562 bytes --]

diff -uNr xen-unstable.hg-pristine/xen/arch/x86/hvm/vpic.c xen-unstable.hg-patched/xen/arch/x86/hvm/vpic.c
--- xen-unstable.hg-pristine/xen/arch/x86/hvm/vpic.c	2007-02-07 18:55:16.000000000 +0100
+++ xen-unstable.hg-patched/xen/arch/x86/hvm/vpic.c	2007-03-14 13:28:43.000000000 +0100
@@ -55,7 +55,7 @@
         return VPIC_PRIO_NONE;
 
     /* prio = ffs(mask ROL vpic->priority_add); */
-    asm ( "rol %%cl,%b1 ; bsf %1,%0"
+    asm ( "ror %%cl,%b1 ; bsf %1,%0"
           : "=r" (prio) : "r" ((uint32_t)mask), "c" (vpic->priority_add) );
     return prio;
 }

[-- Attachment #3: mmio_ops.patch --]
[-- Type: text/x-patch, Size: 882 bytes --]

diff -uNr xen-unstable.hg-pristine/xen/arch/x86/hvm/platform.c xen-unstable.hg-p/xen/arch/x86/hvm/platform.c
--- xen-unstable.hg-pristine/xen/arch/x86/hvm/platform.c	2007-02-21 09:19:46.000000000 +0100
+++ xen-unstable.hg-p/xen/arch/x86/hvm/platform.c	2007-03-05 13:43:51.000000000 +0100
@@ -415,6 +415,17 @@
         GET_OP_SIZE_FOR_NONEBYTE(*op_size);
         return mem_reg(*op_size, opcode, mmio_op, rex);
 
+    case 0x08: /* or r8, m8 */	
+        mmio_op->instr = INSTR_OR;
+        *op_size = BYTE;
+        GET_OP_SIZE_FOR_BYTE(size_reg);
+        return reg_mem(size_reg, opcode, mmio_op, rex);
+
+    case 0x09: /* or r32/16, m32/16 */
+        mmio_op->instr = INSTR_OR;
+        GET_OP_SIZE_FOR_NONEBYTE(*op_size);
+        return reg_mem(*op_size, opcode, mmio_op, rex);
+
     case 0x0A: /* or m8, r8 */
         mmio_op->instr = INSTR_OR;
         *op_size = BYTE;

[-- Attachment #4: qemu-dm_xchg.patch --]
[-- Type: text/x-patch, Size: 1043 bytes --]

diff -uNr xen-unstable.hg-pristine/tools/ioemu/target-i386-dm/helper2.c xen-unstable.hg-p/tools/ioemu/target-i386-dm/helper2.c
--- xen-unstable.hg-pristine/tools/ioemu/target-i386-dm/helper2.c	2007-01-19 08:50:51.000000000 +0100
+++ xen-unstable.hg-p/tools/ioemu/target-i386-dm/helper2.c	2007-03-05 13:47:11.000000000 +0100
@@ -439,6 +439,18 @@
     req->data = tmp1;
 }
 
+void cpu_ioreq_xchg(CPUState *env, ioreq_t *req)
+{
+    unsigned long tmp1;
+
+    if (req->data_is_ptr != 0)
+        hw_error("expected scalar value");
+
+    read_physical(req->addr, req->size, &tmp1);
+    write_physical(req->addr, req->size, &req->data);
+    req->data = tmp1;
+}
+
 void __handle_ioreq(CPUState *env, ioreq_t *req)
 {
     if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
@@ -463,6 +475,9 @@
     case IOREQ_TYPE_XOR:
         cpu_ioreq_xor(env, req);
         break;
+    case IOREQ_TYPE_XCHG:
+        cpu_ioreq_xchg(env, req);
+        break;
     default:
         hw_error("Invalid ioreq type 0x%x\n", req->type);
     }

[-- Attachment #5: rombios_e801_fix.patch --]
[-- Type: text/x-patch, Size: 721 bytes --]

diff -uNr xen-unstable.hg-pristine/tools/firmware/rombios/rombios.c xen-unstable.hg/tools/firmware/rombios/rombios.c
--- xen-unstable.hg-pristine/tools/firmware/rombios/rombios.c	2007-03-13 02:17:37.000000000 +0100
+++ xen-unstable.hg/tools/firmware/rombios/rombios.c	2007-03-13 12:12:50.000000000 +0100
@@ -4360,6 +4360,11 @@
           regs.u.r8.dl = inb_cmos(0x34);
           regs.u.r8.dh = inb_cmos(0x35);
 
+#ifdef HVMASSIST
+          // Don't report highest 64kb block, or shared_page & friends will get exposed as regular RAM
+          regs.u.r16.dx -= 1;
+#endif
+
           // Set configured memory equal to extended memory
           regs.u.r16.ax = regs.u.r16.cx;
           regs.u.r16.bx = regs.u.r16.dx;

[-- Attachment #6: svm_smsw_modrm.patch --]
[-- Type: text/x-patch, Size: 3890 bytes --]

diff -uNr xen-unstable.hg-pristine/xen/arch/x86/hvm/svm/svm.c xen-unstable.hg/xen/arch/x86/hvm/svm/svm.c
--- xen-unstable.hg-pristine/xen/arch/x86/hvm/svm/svm.c	2007-03-13 02:17:37.000000000 +0100
+++ xen-unstable.hg/xen/arch/x86/hvm/svm/svm.c	2007-03-13 12:11:02.000000000 +0100
@@ -2156,11 +2156,13 @@
 {
     struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
     int inst_len = 0;
-    int index;
-    unsigned int gpreg;
-    unsigned long value;
+    int index,addr_size,i;
+    unsigned int gpreg,offset;
+    unsigned long value,addr;
     u8 buffer[MAX_INST_LEN];   
     u8 prefix = 0;
+    u8 modrm;
+    enum x86_segment seg;
     int result = 1;
     enum instruction_index list_a[] = {INSTR_MOV2CR, INSTR_CLTS, INSTR_LMSW};
     enum instruction_index list_b[] = {INSTR_MOVCR2, INSTR_SMSW};
@@ -2244,16 +2246,61 @@
         break;
 
     case INSTR_SMSW:
-        if (svm_dbg_on)
-            svm_dump_inst(svm_rip2pointer(v));
-        value = v->arch.hvm_svm.cpu_shadow_cr0;
-        gpreg = decode_src_reg(prefix, buffer[index+2]);
-        set_reg(gpreg, value, regs, vmcb);
+          if (svm_dbg_on)
+              svm_dump_inst(svm_rip2pointer(v));
+         value = v->arch.hvm_svm.cpu_shadow_cr0 & 0xFFFF;
+         modrm = buffer[index+2];
+         addr_size = svm_guest_x86_mode( v );
+         if ( likely( ( modrm & 0xC0 ) >> 6 == 3 ) )
+         {
+             gpreg = decode_src_reg(prefix, modrm);
+             set_reg(gpreg, value, regs, vmcb);
+             if ( svm_dbg_on )
+                  printk("CR0-SMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg, inst_len);
+         }
+         /* For now, only implement decode of the offset mode, since that's the only mode observed in a real-world OS.
+            This code is also making the assumption that we'll never hit this code in long mode... */
+         else if ( modrm == 0x26 || modrm == 0x25 )
+         {   
+             seg = x86_seg_ds;
+             i = index;
+             /* Segment or address size overrides? */
+             while ( i-- ) {
+                 switch ( buffer[i] )
+                 {
+                    case 0x26: seg = x86_seg_es;break;
+                    case 0x2e: seg = x86_seg_cs;break;
+                    case 0x36: seg = x86_seg_ss;break;
+                    case 0x64: seg = x86_seg_fs;break;
+                    case 0x65: seg = x86_seg_gs;break;
+                    case 0x67: addr_size ^= 6 ;break;
+                 }
+             }
+             /* Bail unless this really is a seg_base + offset case */
+             if ( ( modrm == 0x26 && addr_size == 4 ) || ( modrm == 0x25 && addr_size == 2 ) ) {
+                 printk("SMSW emulation at guest address: %lx failed due to unhandled addressing mode."
+                        "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
+                 domain_crash(v->domain);
+                 }
+             inst_len += addr_size;
+             offset = *(( unsigned int *) ( void *) &buffer[index + 3]);
+             offset = ( addr_size == 4 ) ? offset : ( offset & 0xFFFF );
+             addr = hvm_get_segment_base(v, seg);
+             if ( svm_dbg_on ) {
+                 printk("CR0-SMSW->mem value=%lx, base addr = %lx,"
+                        " offset = %i, inst_len=%d \n", value, addr, offset, inst_len);
+             }
+             addr += offset;
+             hvm_copy_to_guest_virt(addr,&value,2);
+         }
+         else
+         {
+            printk("SMSW emulation at guest address: %lx failed due to unhandled addressing mode!"
+                   "ModRM byte was: %x \n", svm_rip2pointer(v), modrm);
+            domain_crash(v->domain);
+         }
+          break;
 
-        if (svm_dbg_on)
-            printk("CR0-SMSW value=%lx, reg=%d, inst_len=%d\n", value, gpreg, 
-                   inst_len);
-        break;
 
     default:
         BUG();

[-- Attachment #7: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 10+ messages in thread
* Re: [PATCH] [HVM] Patches to make HVM capable of running OS/2.
@ 2007-03-21  9:12 ecs user
  2007-03-21 12:47 ` Trolle Selander
  0 siblings, 1 reply; 10+ messages in thread
From: ecs user @ 2007-03-21  9:12 UTC (permalink / raw)
  To: xen-devel


Thanks very much for the contribution. I am now
running Serenity System's eComStation. I will receive
a new AMD Athlon 64 X2 machine in a couple weeks. I
will try your patches then.

Do you have a copy of eComStation?



 
____________________________________________________________________________________
The fish are biting. 
Get more visitors on your site using Yahoo! Search Marketing.
http://searchmarketing.yahoo.com/arp/sponsoredsearch_v2.php

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-03-21 12:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-16 12:07 [PATCH] [HVM] Patches to make HVM capable of running OS/2 Trolle Selander
2007-03-16 12:21 ` Keir Fraser
2007-03-16 12:45   ` Trolle Selander
2007-03-16 14:10     ` Keir Fraser
2007-03-16 18:22       ` Trolle Selander
2007-03-16 19:07         ` Keir Fraser
2007-03-16 20:11           ` Trolle Selander
2007-03-16 20:28             ` Keir Fraser
  -- strict thread matches above, loose matches on Subject: below --
2007-03-21  9:12 ecs user
2007-03-21 12:47 ` Trolle Selander

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.