From: "Christoph Egger" Subject: [PATCH][HVM] Fix guest hang producing "PIT: bad access" messages Date: Fri, 11 Jan 2008 12:08:01 +0100 Message-ID: <200801111208.02078.Christoph.Egger@amd.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary-00=_S40hHwFgudpzuQh" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: Keir Fraser List-Id: xen-devel@lists.xenproject.org --Boundary-00=_S40hHwFgudpzuQh Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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,=20 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 =3D> 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. Signed-off-by: Christoph Egger =2D-=20 AMD Saxony, Dresden, Germany Operating System Research Center Legal Information: AMD Saxony Limited Liability Company & Co. KG Sitz (Gesch=E4ftsanschrift): Wilschdorfer Landstr. 101, 01109 Dresden, Deutschland Registergericht Dresden: HRA 4896 vertretungsberechtigter Komplement=E4r: AMD Saxony LLC (Sitz Wilmington, Delaware, USA) Gesch=E4ftsf=FChrer der AMD Saxony LLC: Dr. Hans-R. Deppe, Thomas McCoy --Boundary-00=_S40hHwFgudpzuQh Content-Type: text/plain; charset=us-ascii; name=xen_pit.diff Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=xen_pit.diff diff -r 56b42d68518e xen/arch/x86/hvm/i8254.c --- a/xen/arch/x86/hvm/i8254.c Thu Jan 10 22:53:43 2008 +0000 +++ b/xen/arch/x86/hvm/i8254.c Fri Jan 11 14:00:29 2008 +0100 @@ -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; --Boundary-00=_S40hHwFgudpzuQh Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --Boundary-00=_S40hHwFgudpzuQh--