]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
core: Only perform PCI config space writes on PCI_ACCESS_PERFORM
authorJan Kiszka <jan.kiszka@siemens.com>
Tue, 29 Jul 2014 18:45:23 +0000 (20:45 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Sun, 3 Aug 2014 19:22:55 +0000 (21:22 +0200)
If we emulate a config space write, we may be able to skip the physical
access completely. To model this, rename PCI_ACCESS_EMULATE to
PCI_ACCESS_DONE which signals to the caller of the moderation functions
that no physical access should be performed.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/pci.c
hypervisor/include/jailhouse/pci.h
hypervisor/pci.c

index fa4887ce3ebbea4dce799ffb3fa655bb55e6d1c7..738d3ff3175532d77241a357d16d777e6d132a7c 100644 (file)
@@ -144,13 +144,13 @@ data_port_out_handler(struct registers *guest_regs, const struct cell *cell,
                      u16 address, unsigned int size)
 {
        u32 reg_data = get_rax_reg(guest_regs, size);
+       enum pci_access access;
 
-       if (pci_cfg_write_moderate(cell, device, address,
-                                  size, reg_data) == PCI_ACCESS_REJECT)
+       access = pci_cfg_write_moderate(cell, device, address, size, reg_data);
+       if (access == PCI_ACCESS_REJECT)
                return -1;
-
-       arch_pci_write_config(device->bdf, address, reg_data, size);
-
+       if (access == PCI_ACCESS_PERFORM)
+               arch_pci_write_config(device->bdf, address, reg_data, size);
        return 1;
 }
 
index 1b3e7736f003777b67557b79f227c7d960755507..2d96e5ee74338ca5226f8327f065c9dd11f63859 100644 (file)
@@ -20,7 +20,7 @@
 #define PCI_DEVFN(bdf)         ((bdf) & 0xff)
 #define PCI_BDF_PARAMS(bdf)    (bdf) >> 8, ((bdf) >> 3) & 0x1f, (bdf) & 7
 
-enum pci_access { PCI_ACCESS_REJECT, PCI_ACCESS_PERFORM, PCI_ACCESS_EMULATE };
+enum pci_access { PCI_ACCESS_REJECT, PCI_ACCESS_PERFORM, PCI_ACCESS_DONE };
 
 int pci_init(void);
 
index 3d5553dbb31e280c3834992087b75fdc57ca7587..57b451c71b28829da378fa34554d4cbd05c620d8 100644 (file)
@@ -160,9 +160,9 @@ pci_find_capability(const struct cell *cell,
  * @address:   Config space address
  * @size:      Access size (1, 2 or 4 bytes)
  * @value:     Pointer to buffer to receive the emulated value if
- *             PCI_ACCESS_EMULATE is returned
+ *             PCI_ACCESS_DONE is returned
  *
- * Return: PCI_ACCESS_PERFORM or PCI_ACCESS_EMULATE.
+ * Return: PCI_ACCESS_PERFORM or PCI_ACCESS_DONE.
  */
 enum pci_access
 pci_cfg_read_moderate(const struct cell *cell,
@@ -173,7 +173,7 @@ pci_cfg_read_moderate(const struct cell *cell,
 
        if (!device) {
                *value = -1;
-               return PCI_ACCESS_EMULATE;
+               return PCI_ACCESS_DONE;
        }
 
        if (address < PCI_CONFIG_HEADER_SIZE)
@@ -196,7 +196,7 @@ pci_cfg_read_moderate(const struct cell *cell,
  * @size:      Access size (1, 2 or 4 bytes)
  * @value:     Value to be written
  *
- * Return: PCI_ACCESS_REJECT, PCI_ACCESS_PERFORM or PCI_ACCESS_EMULATE.
+ * Return: PCI_ACCESS_REJECT, PCI_ACCESS_PERFORM or PCI_ACCESS_DONE.
  */
 enum pci_access
 pci_cfg_write_moderate(const struct cell *cell,
@@ -301,7 +301,8 @@ int pci_mmio_access_handler(const struct cell *cell, bool is_write,
                                                *value);
                if (access == PCI_ACCESS_REJECT)
                        goto invalid_access;
-               mmio_write32(pci_space + mmcfg_offset, *value);
+               if (access == PCI_ACCESS_PERFORM)
+                       mmio_write32(pci_space + mmcfg_offset, *value);
        } else {
                access = pci_cfg_read_moderate(cell, device, reg_addr, 4,
                                               value);