Skip to contentSkip to conversation

Fix guest hang producing "PIT: bad access" messages

PATCH In review Christoph Egger 2 participants 4 messages Jan 11, 2008 – Jan 14, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix guest hang producing "PIT: bad access" messages

Hi

When the HVM guest atomically reads two bytes from the PIT via "rep insb" and the two bytes crosses pages, then in xen/arch/x86/hvm/i8254.c, handle_pit_io(), p->data_is_ptr is 1 which leads to an unhandled read.

Since reading the first byte does not change the guest rip, an endless loop of VMEXIT_IOIO happens. This leads to an endless stream of "PIT: bad access" xen messages => Guest hangs.

This has been accurately reproduced on NetBSD/amd64 as HVM guest and this also been seen on 64bit Windows guests.

The attached patch handles the page-crossing access in the PIT emulation.

Signature · 12 lines
AMD Saxony, Dresden, Germany
Operating System Research Center

Legal Information:
AMD Saxony Limited Liability Company & Co. KG
Sitz (Geschäftsanschrift):
   Wilschdorfer Landstr. 101, 01109 Dresden, Deutschland
Registergericht Dresden: HRA 4896
vertretungsberechtigter Komplementär:
   AMD Saxony LLC (Sitz Wilmington, Delaware, USA)
Geschäftsführer der AMD Saxony LLC:
   Dr. Hans-R. Deppe, Thomas McCoy
xen/arch/x86/hvm/i8254.c +31 -9
diff -r 56b42d68518e xen/arch/x86/hvm/i8254.c
@@ -527,24 +527,46 @@ void pit_deinit(struct domain *d)
 /* the intercept action for PIT DM retval:0--not handled; 1--handled */  
 static int handle_pit_io(ioreq_t *p)
 {
+    uint32_t value;
     struct PITState *vpit = vcpu_vpit(current);
 
-    if ( (p->size != 1) || p->data_is_ptr || (p->type != IOREQ_TYPE_PIO) )
+    if ( (p->size != 1) || (p->type != IOREQ_TYPE_PIO) || (p->count > 4) )
     {
         gdprintk(XENLOG_WARNING, "PIT bad access\n");
         return 1;
     }
 
-    if ( p->dir == IOREQ_WRITE )
-    {
-        pit_ioport_write(vpit, p->addr, p->data);
-    }
-    else
-    {
-        if ( (p->addr & 3) != 3 )
-            p->data = pit_ioport_read(vpit, p->addr);
+    switch (p->dir) {
+    case IOREQ_WRITE:
+
+        if ( p->data_is_ptr )
+           hvm_copy_from_guest_phys(&value, p->data, p->size * p->count);
         else
+           value = p->data;
+
+        pit_ioport_write(vpit, p->addr, value);
+        break;
+    
+    case IOREQ_READ:
+
+        if ( !((p->addr & 3) != 3) ) {
             gdprintk(XENLOG_WARNING, "PIT: read A1:A0=3!\n");
+            return 1;
+        }
+
+        value = pit_ioport_read(vpit, p->addr);
+
+        if ( p->data_is_ptr ) {
+           hvm_copy_to_guest_phys(p->data, &value, p->size * p->count);
+        } else
+           p->data = value;
+
+        break;
+
+    default:
+        /* Unknown/Invalid operation */
+        gdprintk(XENLOG_ERR, "PIT access: p->dir: %d\n", p->dir);
+        BUG();
     }
 
     return 1;

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

#1 lore raw

Re: [PATCH][HVM] Fix guest hang producing "PIT: bad access"messages

Okay, but the patch is buggy (accesses count*size bytes of memory, but actually only one byte-sized port will be accessed) and actually this is indicative of a wider issue in other Xen-emulated devices. We need a more cooked interface to PIO handlers. I'll take a look.

-- Keir

Quoted 18 lines · Christoph Egger

Hi

When the HVM guest atomically reads two bytes from the PIT via "rep insb" and the two bytes crosses pages, then in xen/arch/x86/hvm/i8254.c, handle_pit_io(), p->data_is_ptr is 1 which leads to an unhandled read.

Since reading the first byte does not change the guest rip, an endless loop of VMEXIT_IOIO happens. This leads to an endless stream of "PIT: bad access" xen messages => Guest hangs.

This has been accurately reproduced on NetBSD/amd64 as HVM guest and this also been seen on 64bit Windows guests.

The attached patch handles the page-crossing access in the PIT emulation.

#2 lore raw

Re: [PATCH][HVM] Fix guest hang producing "PIT: bad access"messages

In reply to Christoph Egger

Fixed by c/s 16709. I tested with the ISO you sent me and NetBSD boots much further, to a reasonable point (failure to init a console).

-- Keir

Quoted 18 lines · Christoph Egger

Hi

When the HVM guest atomically reads two bytes from the PIT via "rep insb" and the two bytes crosses pages, then in xen/arch/x86/hvm/i8254.c, handle_pit_io(), p->data_is_ptr is 1 which leads to an unhandled read.

Since reading the first byte does not change the guest rip, an endless loop of VMEXIT_IOIO happens. This leads to an endless stream of "PIT: bad access" xen messages => Guest hangs.

This has been accurately reproduced on NetBSD/amd64 as HVM guest and this also been seen on 64bit Windows guests.

The attached patch handles the page-crossing access in the PIT emulation.

#3 lore raw

Re: [PATCH][HVM] Fix guest hang producing "PIT: bad access"messages

Quoted 2 lines · On Saturday 12 January 2008 12:10:58 Keir Fraser wrote:

Fixed by c/s 16709. I tested with the ISO you sent me and NetBSD boots much further,

I can confirm that. I tested with c/s 16712. Thanks for fixing this.

Quoted 1 line

to a reasonable point (failure to init a console).

It launches "sysinst", the install application. Press CTRL+Z get back on console.

Christoph

Quoted 20 lines

-- Keir

Quoted 16 lines · Christoph Egger

Hi

When the HVM guest atomically reads two bytes from the PIT via "rep insb" and the two bytes crosses pages, then in xen/arch/x86/hvm/i8254.c, handle_pit_io(), p->data_is_ptr is 1 which leads to an unhandled read.

Since reading the first byte does not change the guest rip, an endless loop of VMEXIT_IOIO happens. This leads to an endless stream of "PIT: bad access" xen messages => Guest hangs.

This has been accurately reproduced on NetBSD/amd64 as HVM guest and this also been seen on 64bit Windows guests.

The attached patch handles the page-crossing access in the PIT emulation.

Signature · 12 lines
AMD Saxony, Dresden, Germany
Operating System Research Center

Legal Information:
AMD Saxony Limited Liability Company & Co. KG
Sitz (Geschäftsanschrift):
   Wilschdorfer Landstr. 101, 01109 Dresden, Deutschland
Registergericht Dresden: HRA 4896
vertretungsberechtigter Komplementär:
   AMD Saxony LLC (Sitz Wilmington, Delaware, USA)
Geschäftsführer der AMD Saxony LLC:
   Dr. Hans-R. Deppe, Thomas McCoy