NetBSD-Bugs archive

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

Re: port-xen/47057: Xen NetBSD DomU file system trash under Linux Dom0



On Sat, Oct 20, 2012 at 08:34:16PM +0200, Roger Pau Monné wrote:
> I'm sorry to say that the patch didn't seem to help, here is another
> output with your patch applied. It seems like prod and cons gets
> overwritten with random data.

OK, here's another patch, which also checks that the mapping doesn't
change. But I wonder is the corruption occurs on the NetBSD side.
Could you also add some debugging code on the other side ?

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: xenbus_comms.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xenbus/xenbus_comms.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 xenbus_comms.c
--- xenbus_comms.c      20 Sep 2011 00:12:24 -0000      1.14
+++ xenbus_comms.c      21 Oct 2012 11:26:23 -0000
@@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: xenbus_comms
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
+#include <uvm/uvm_extern.h>
 
 #include <xen/xen.h>   /* for xendomain_is_dom0() */
 #include <xen/hypervisor.h>
@@ -121,7 +122,10 @@ xb_write(const void *data, unsigned len)
        while (len != 0) {
                void *dst;
                unsigned int avail;
+               paddr_t pa;
 
+               KASSERT(pmap_extract_ma(pmap_kernel(), (vaddr_t)intf, &pa));
+               KASSERT(pa == (xen_start_info.store_mfn << PAGE_SHIFT));
                while ((intf->req_prod - intf->req_cons) == XENSTORE_RING_SIZE) 
{
                        XENPRINTF(("xb_write tsleep\n"));
                        tsleep(&xenstore_interface, PRIBIO, "wrst", 0);
@@ -142,6 +146,10 @@ xb_write(const void *data, unsigned len)
                        continue;
                if (avail > len)
                        avail = len;
+               pmap_kenter_ma((vaddr_t)intf,
+                   xen_start_info.store_mfn << PAGE_SHIFT,
+                   VM_PROT_READ | VM_PROT_WRITE, 0);
+               pmap_update(pmap_kernel());
 
                memcpy(dst, data, avail);
                data = (const char *)data + avail;
@@ -151,6 +159,10 @@ xb_write(const void *data, unsigned len)
                xen_rmb();
                intf->req_prod += avail;
                xen_rmb();
+               pmap_protect(pmap_kernel(), (vaddr_t)intf,
+                   (vaddr_t)intf + PAGE_SIZE,
+                   VM_PROT_READ);
+               pmap_update(pmap_kernel());
 
                hypervisor_notify_via_evtchn(xen_start_info.store_evtchn);
        }
@@ -170,6 +182,10 @@ xb_read(void *data, unsigned len)
        while (len != 0) {
                unsigned int avail;
                const char *src;
+               paddr_t pa;
+
+               KASSERT(pmap_extract_ma(pmap_kernel(), (vaddr_t)intf, &pa));
+               KASSERT(pa == (xen_start_info.store_mfn << PAGE_SHIFT));
 
                while (intf->rsp_cons == intf->rsp_prod)
                        tsleep(&xenstore_interface, PRIBIO, "rdst", 0);
@@ -198,9 +214,17 @@ xb_read(void *data, unsigned len)
                len -= avail;
 
                /* Other side must not see free space until we've copied out */
+               pmap_kenter_ma((vaddr_t)intf,
+                   xen_start_info.store_mfn << PAGE_SHIFT,
+                   VM_PROT_READ | VM_PROT_WRITE, 0);
+               pmap_update(pmap_kernel());
                xen_rmb();
                intf->rsp_cons += avail;
                xen_rmb();
+               pmap_protect(pmap_kernel(), (vaddr_t)intf,
+                   (vaddr_t)intf + PAGE_SIZE,
+                   VM_PROT_READ);
+               pmap_update(pmap_kernel());
 
                XENPRINTF(("Finished read of %i bytes (%i to go)\n",
                    avail, len));


Home | Main Index | Thread Index | Old Index