]> xenbits.xensource.com Git - qemu-xen-4.1-testing.git/commitdiff
passthough: add no_wb option for pci conf write
authorIan Jackson <ian.jackson@eu.citrix.com>
Fri, 6 Nov 2009 18:11:50 +0000 (18:11 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Fri, 6 Nov 2009 18:11:50 +0000 (18:11 +0000)
Current pt_pci_write_config always writes back to real pci conf
space. However, in the case of MSI address and data registers,
if guest changes the affinity of the interrupt, stale data will
be written to these registers. This is particularly a problem
if Xen uses per-CPU vector, where the interrupt in question fails
to work. This patch fixes this by adding an option to disable the
write back of certain controls.

Signed-off-by: Qing He <qing.he@intel.com>
hw/pass-through.c
hw/pass-through.h

index cdf0f31bc3b8ea426a4f11b71c4387633bcadb87..b125d7222e16cadd24fbc8b4db66ea594e1ed569 100644 (file)
@@ -628,6 +628,7 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .init_val   = 0x00000000,
         .ro_mask    = 0x00000003,
         .emu_mask   = 0xFFFFFFFF,
+        .no_wb      = 1,
         .init       = pt_common_reg_init,
         .u.dw.read  = pt_long_reg_read,
         .u.dw.write = pt_msgaddr32_reg_write,
@@ -640,6 +641,7 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .init_val   = 0x00000000,
         .ro_mask    = 0x00000000,
         .emu_mask   = 0xFFFFFFFF,
+        .no_wb      = 1,
         .init       = pt_msgaddr64_reg_init,
         .u.dw.read  = pt_long_reg_read,
         .u.dw.write = pt_msgaddr64_reg_write,
@@ -652,6 +654,7 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .init_val   = 0x0000,
         .ro_mask    = 0x0000,
         .emu_mask   = 0xFFFF,
+        .no_wb      = 1,
         .init       = pt_msgdata_reg_init,
         .u.w.read   = pt_word_reg_read,
         .u.w.write  = pt_msgdata_reg_write,
@@ -664,6 +667,7 @@ static struct pt_reg_info_tbl pt_emu_reg_msi_tbl[] = {
         .init_val   = 0x0000,
         .ro_mask    = 0x0000,
         .emu_mask   = 0xFFFF,
+        .no_wb      = 1,
         .init       = pt_msgdata_reg_init,
         .u.w.read   = pt_word_reg_read,
         .u.w.write  = pt_msgdata_reg_write,
@@ -1552,10 +1556,12 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val,
     val >>= ((address & 3) << 3);
 
 out:
-    ret = pci_write_block(pci_dev, address, (uint8_t *)&val, len);
+    if (!reg->no_wb) {
+        ret = pci_write_block(pci_dev, address, (uint8_t *)&val, len);
 
-    if (!ret)
-        PT_LOG("Error: pci_write_block failed. return value[%d].\n", ret);
+        if (!ret)
+            PT_LOG("Error: pci_write_block failed. return value[%d].\n", ret);
+    }
 
     if (pm_state != NULL && pm_state->flags & PT_FLAG_TRANSITING)
         /* set QEMUTimer */
index 324df5b9b44e567d2b65c7c462041ba43a2012a3..dc06a4f810e2f5d6874f75b6d503657ac11f63f0 100644 (file)
@@ -365,6 +365,8 @@ struct pt_reg_info_tbl {
     uint32_t ro_mask;
     /* reg emulate field mask (ON:emu, OFF:passthrough) */
     uint32_t emu_mask;
+    /* no write back allowed */
+    uint32_t no_wb;
     /* emul reg initialize method */
     conf_reg_init init;
     union {