}
/* update the corresponding virtual region address */
- r->addr = cfg_entry->data;
+ /*
+ * When guest code tries to get block size of mmio, it will write all "1"s
+ * into pci bar register. In this case, cfg_entry->data == writable_mask.
+ * Especially for devices with large mmio, the value of writable_mask
+ * is likely to be a guest physical address that has been mapped to ram
+ * rather than mmio. Remapping this value to mmio should be prevented.
+ */
+
+ if ( cfg_entry->data != writable_mask )
+ r->addr = cfg_entry->data;
exit:
/* create value for writing to I/O device register */
cfg_entry->data = PT_MERGE_VALUE(*value, cfg_entry->data, writable_mask);
/* update the corresponding virtual region address */
- r->addr = cfg_entry->data;
+ /*
+ * When guest code tries to get block size of mmio, it will write all "1"s
+ * into pci bar register. In this case, cfg_entry->data == writable_mask.
+ * Especially for devices with large mmio, the value of writable_mask
+ * is likely to be a guest physical address that has been mapped to ram
+ * rather than mmio. Remapping this value to mmio should be prevented.
+ */
+
+ if ( cfg_entry->data != writable_mask )
+ r->addr = cfg_entry->data;
/* create value for writing to I/O device register */
throughable_mask = ~bar_emu_mask & valid_mask;