INTEL_GVT_PCI_BAR_MAX,
 };
 
+/* bitmap for writable bits (RW or RW1C bits, but cannot co-exist in one
+ * byte) byte by byte in standard pci configuration space. (not the full
+ * 256 bytes.)
+ */
+static const u8 pci_cfg_space_rw_bmp[PCI_INTERRUPT_LINE + 4] = {
+       [PCI_COMMAND]           = 0xff, 0x07,
+       [PCI_STATUS]            = 0x00, 0xf9, /* the only one RW1C byte */
+       [PCI_CACHE_LINE_SIZE]   = 0xff,
+       [PCI_BASE_ADDRESS_0 ... PCI_CARDBUS_CIS - 1] = 0xff,
+       [PCI_ROM_ADDRESS]       = 0x01, 0xf8, 0xff, 0xff,
+       [PCI_INTERRUPT_LINE]    = 0xff,
+};
+
+/**
+ * vgpu_pci_cfg_mem_write - write virtual cfg space memory
+ *
+ * Use this function to write virtual cfg space memory.
+ * For standard cfg space, only RW bits can be changed,
+ * and we emulates the RW1C behavior of PCI_STATUS register.
+ */
+static void vgpu_pci_cfg_mem_write(struct intel_vgpu *vgpu, unsigned int off,
+                                  u8 *src, unsigned int bytes)
+{
+       u8 *cfg_base = vgpu_cfg_space(vgpu);
+       u8 mask, new, old;
+       int i = 0;
+
+       for (; i < bytes && (off + i < sizeof(pci_cfg_space_rw_bmp)); i++) {
+               mask = pci_cfg_space_rw_bmp[off + i];
+               old = cfg_base[off + i];
+               new = src[i] & mask;
+
+               /**
+                * The PCI_STATUS high byte has RW1C bits, here
+                * emulates clear by writing 1 for these bits.
+                * Writing a 0b to RW1C bits has no effect.
+                */
+               if (off + i == PCI_STATUS + 1)
+                       new = (~new & old) & mask;
+
+               cfg_base[off + i] = (old & ~mask) | new;
+       }
+
+       /* For other configuration space directly copy as it is. */
+       if (i < bytes)
+               memcpy(cfg_base + off + i, src + i, bytes - i);
+}
+
 /**
  * intel_vgpu_emulate_cfg_read - emulate vGPU configuration space read
  *
        u8 changed = old ^ new;
        int ret;
 
-       memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
+       vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
        if (!(changed & PCI_COMMAND_MEMORY))
                return 0;
 
                if (ret)
                        return ret;
 
-               memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
+               vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
                break;
        default:
-               memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
+               vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
                break;
        }
        return 0;