]> xenbits.xensource.com Git - xen.git/commitdiff
hvm: Clean up buf_ioreq handling.
authorKeir Fraser <keir@xensource.com>
Thu, 8 Nov 2007 14:50:01 +0000 (14:50 +0000)
committerKeir Fraser <keir@xensource.com>
Thu, 8 Nov 2007 14:50:01 +0000 (14:50 +0000)
Also, disable stdvga caching on hvm save/restore, as the shadow vga
state is not preserved.
Signed-off-by: Keir Fraser <keir@xensource.com>
tools/ioemu/target-i386-dm/helper2.c
xen/arch/ia64/vmx/mmio.c
xen/arch/ia64/vmx/save.c
xen/arch/x86/hvm/intercept.c
xen/arch/x86/hvm/save.c
xen/arch/x86/hvm/stdvga.c
xen/common/hvm/save.c
xen/include/public/hvm/ioreq.h
xen/include/xen/hvm/save.h

index 56e1dc5ab19f73ea77996391a72aa1b2e31b3824..c139f1263246797980e86101dfaefc3ab75bdf8a 100644 (file)
@@ -541,27 +541,28 @@ void __handle_buffered_iopage(CPUState *env)
 {
     buf_ioreq_t *buf_req = NULL;
     ioreq_t req;
-    int qw = 0;
+    int qw;
 
     if (!buffered_io_page)
         return;
 
     while (buffered_io_page->read_pointer !=
            buffered_io_page->write_pointer) {
-        memset(&req, 0, sizeof(req));
-        buf_req = &buffered_io_page->buf_ioreq[buffered_io_page->read_pointer %
-                                      IOREQ_BUFFER_SLOT_NUM];
+        buf_req = &buffered_io_page->buf_ioreq[
+            buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
         req.size = 1UL << buf_req->size;
         req.count = 1;
         req.addr = buf_req->addr;
         req.data = buf_req->data;
         req.state = STATE_IOREQ_READY;
-        req.dir  = buf_req->dir;
+        req.dir = buf_req->dir;
+        req.df = buf_req->df;
         req.type = buf_req->type;
-        qw = req.size == 8;
+        req.data_is_ptr = 0;
+        qw = (req.size == 8);
         if (qw) {
-            buf_req = &buffered_io_page->buf_ioreq[(buffered_io_page->read_pointer+1) %
-                                               IOREQ_BUFFER_SLOT_NUM];
+            buf_req = &buffered_io_page->buf_ioreq[
+                (buffered_io_page->read_pointer+1) % IOREQ_BUFFER_SLOT_NUM];
             req.data |= ((uint64_t)buf_req->data) << 32;
         }
 
index 2c247b740380d6afabc3cde37056815951b8587c..c72969a9b6db606a3ea865e4a5afafa13532eeab 100644 (file)
@@ -65,7 +65,7 @@ static int hvm_buffered_io_intercept(ioreq_t *p)
 
     /* ignore READ ioreq_t and anything buffered io can't deal with */
     if (p->dir == IOREQ_READ || p->addr > 0xFFFFFUL ||
-        p->data_is_ptr || p->df || p->count != 1)
+        p->data_is_ptr || p->count != 1)
         return 0;
 
     for (i = 0; i < HVM_BUFFERED_IO_RANGE_NR; i++) {
@@ -80,6 +80,7 @@ static int hvm_buffered_io_intercept(ioreq_t *p)
 
     bp.type = p->type;
     bp.dir = p->dir;
+    bp.df = p->df;
     switch (p->size) {
     case 1:
         bp.size = 0;
index 3d4eddd44fc5be484126aed01d738e2980054c72..f0e9145f91964346ad1fe2f97a19fa641495c6be 100644 (file)
@@ -23,8 +23,7 @@
 #include <xen/types.h>
 #include <xen/hvm/save.h>
 
-void
-arch_hvm_save(struct hvm_save_header *hdr)
+void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr)
 {
     unsigned int i;
     
@@ -32,8 +31,7 @@ arch_hvm_save(struct hvm_save_header *hdr)
         hdr->cpuid[i] = ia64_get_cpuid(i);
 }
 
-int
-arch_hvm_load(struct hvm_save_header *hdr)
+int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
 {
     unsigned int i;
     if (hdr->magic != HVM_FILE_MAGIC) {
index dc2b1ffbba4fd89ffd8190732c292b023554fd29..be58c05d0cc756394f114bed7dc8538fd3dd5fcf 100644 (file)
@@ -163,18 +163,20 @@ int hvm_buffered_io_send(ioreq_t *p)
     /* Ensure buffered_iopage fits in a page */
     BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE);
 
-    /* Return 0 for the cases we can't deal with. */
-    if ( (p->addr > 0xffffful) || p->data_is_ptr || p->df || (p->count != 1) )
-    {
-        gdprintk(XENLOG_DEBUG, "slow ioreq. type:%d size:%"PRIu64" addr:0x%"
-                 PRIx64" dir:%d ptr:%d df:%d count:%"PRIu64"\n",
-                 p->type, p->size, p->addr, !!p->dir,
-                 !!p->data_is_ptr, !!p->df, p->count);
+    /*
+     * Return 0 for the cases we can't deal with:
+     *  - 'addr' is only a 20-bit field, so we cannot address beyond 1MB
+     *  - we cannot buffer accesses to guest memory buffers, as the guest
+     *    may expect the memory buffer to be synchronously accessed
+     *  - the count field is usually used with data_is_ptr and since we don't
+     *    support data_is_ptr we do not waste space for the count field either
+     */
+    if ( (p->addr > 0xffffful) || p->data_is_ptr || (p->count != 1) )
         return 0;
-    }
 
     bp.type = p->type;
     bp.dir  = p->dir;
+    bp.df   = p->df;
     switch ( p->size )
     {
     case 1:
index 1f75b63682070c712e771b1c732a48713642b7d4..6d93340c8b55f498e4337318d0aaaebed2d0be4f 100644 (file)
@@ -24,8 +24,7 @@
 #include <asm/hvm/support.h>
 #include <public/hvm/save.h>
 
-void
-arch_hvm_save(struct hvm_save_header *hdr)
+void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr)
 {
     uint32_t eax, ebx, ecx, edx;
 
@@ -36,10 +35,10 @@ arch_hvm_save(struct hvm_save_header *hdr)
     hdr->pad0 = 0;
 }
 
-int
-arch_hvm_load(struct hvm_save_header *hdr)
+int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
 {
     uint32_t eax, ebx, ecx, edx;
+
     if ( hdr->magic != HVM_FILE_MAGIC )
     {
         gdprintk(XENLOG_ERR, 
@@ -55,11 +54,14 @@ arch_hvm_load(struct hvm_save_header *hdr)
     }
 
     cpuid(1, &eax, &ebx, &ecx, &edx);
-    /*TODO: need to define how big a difference is acceptable */
+    /* TODO: need to define how big a difference is acceptable? */
     if ( hdr->cpuid != eax )
         gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") "
                "does not match host (%#"PRIx32").\n", hdr->cpuid, eax);
 
+    /* VGA state is not saved/restored, so we nobble the cache. */
+    d->arch.hvm_domain.stdvga.cache = 0;
+
     return 0;
 }
 
index 7d2599ca692f8e539ac299cf9b265498c7d92cfb..e068c31a0c77b5a526e2a239cdffbff75330e6ef 100644 (file)
@@ -220,7 +220,9 @@ static void stdvga_outb(uint64_t addr, uint8_t val)
         gdprintk(XENLOG_INFO, "entering stdvga and caching modes\n");
     }
     else if ( prev_stdvga && !s->stdvga )
+    {
         gdprintk(XENLOG_INFO, "leaving stdvga\n");
+    }
 }
 
 static void stdvga_outv(uint64_t addr, uint64_t data, uint32_t size)
@@ -636,7 +638,7 @@ int stdvga_intercept_mmio(ioreq_t *p)
             buf = mmio_op(s, p);
             break;
         default:
-            gdprintk(XENLOG_ERR, "unsupported mmio request type:%d "
+            gdprintk(XENLOG_WARNING, "unsupported mmio request type:%d "
                      "addr:0x%04x data:0x%04x size:%d count:%d state:%d "
                      "isptr:%d dir:%d df:%d\n",
                      p->type, (int)p->addr, (int)p->data, (int)p->size,
index 26ba8ad813c0eb20d7e8b7b03f6a0238ff4d81a9..3079363676a96494e3d08358030b22e93602ef02 100644 (file)
@@ -94,7 +94,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h)
     else 
         hdr.changeset = -1ULL; /* Unknown */
 
-    arch_hvm_save(&hdr);
+    arch_hvm_save(d, &hdr);
 
     if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
     {
@@ -144,7 +144,7 @@ int hvm_load(struct domain *d, hvm_domain_context_t *h)
     if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) 
         return -1;
 
-    if ( arch_hvm_load(&hdr) )
+    if ( arch_hvm_load(d, &hdr) )
         return -1;
 
     c = strrchr(xen_changeset(), ':');
index 18922c44401ebf4af436dea496472b535c274de2..456d059d9271469f05aa1902116344e3954ff81f 100644 (file)
@@ -78,11 +78,12 @@ struct shared_iopage {
 typedef struct shared_iopage shared_iopage_t;
 
 struct buf_ioreq {
-    uint8_t  type;   /*  I/O type                    */
-    uint8_t  dir:1;  /*  1=read, 0=write             */
-    uint8_t  size:2; /*  0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */
-    uint32_t addr:20;/*  physical address            */
-    uint32_t data;   /*  data                        */
+    uint8_t  type;   /* I/O type                    */
+    uint8_t  df:1;   /* EFLAGS.DF                   */
+    uint8_t  dir:1;  /* 1=read, 0=write             */
+    uint8_t  size:2; /* 0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */
+    uint32_t addr:20;/* physical address            */
+    uint32_t data;   /* data                        */
 };
 typedef struct buf_ioreq buf_ioreq_t;
 
index 09298c333404eb84637353a70d1d4af9f95b4b6e..2842cf08395baf945067dd4a9705687c233029b0 100644 (file)
@@ -155,7 +155,7 @@ int hvm_load(struct domain *d, hvm_domain_context_t *h);
 
 /* Arch-specific definitions. */
 struct hvm_save_header;
-void arch_hvm_save(struct hvm_save_header *hdr);
-int arch_hvm_load(struct hvm_save_header *hdr);
+void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr);
+int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr);
 
 #endif /* __XEN_HVM_SAVE_H__ */