struct guest_paging_structures pg_structs;
struct mmio_access access;
bool is_write;
+ u32 val;
/* We don't enable dirty/accessed bit updated in EPTP, so only read
* of write flags can be set, not both. */
if (!vmx_get_guest_paging_structs(&pg_structs))
return false;
+
access = mmio_parse(cpu_data, vmcs_read64(GUEST_RIP),
&pg_structs, is_write);
if (!access.inst_len || access.size != 4)
return false;
+ if (is_write)
+ val = ((unsigned long *)guest_regs)[access.reg];
+
/* Filter out requests to PCI configuration space */
- if (pci_mmio_access_handler(guest_regs, cpu_data->cell,
- is_write, phys_addr, access.reg) == 1) {
+ if (pci_mmio_access_handler(cpu_data->cell, is_write,
+ phys_addr, &val) == 1) {
+ if (!is_write)
+ ((unsigned long *)guest_regs)[access.reg] = val;
vmx_skip_emulated_instruction(
vmcs_read64(VM_EXIT_INSTRUCTION_LEN));
return true;
bool pci_cfg_write_allowed(u32 type, u8 reg_num, unsigned int reg_bias,
unsigned int size);
-int pci_mmio_access_handler(struct registers *guest_regs,
- const struct cell *cell, bool is_write,
- u64 addr, u32 reg);
+int pci_mmio_access_handler(const struct cell *cell, bool is_write, u64 addr,
+ u32 *value);
#endif /* !_JAILHOUSE_PCI_H */
*/
#include <jailhouse/acpi.h>
+#include <jailhouse/mmio.h>
#include <jailhouse/pci.h>
#include <jailhouse/printk.h>
#include <jailhouse/utils.h>
* @cell: Request issuing cell
* @is_write: True if write access
* @addr: Address accessed
- * @value: Value to write (for write operations only)
+ * @value: Pointer to value for reading/writing
*
* Return: 1 if handled successfully, 0 if unhandled, -1 on access error
*/
-int pci_mmio_access_handler(struct registers *guest_regs,
- const struct cell *cell, bool is_write,
- u64 addr, u32 reg)
+int pci_mmio_access_handler(const struct cell *cell, bool is_write,
+ u64 addr, u32 *value)
{
const struct jailhouse_pci_device *device;
u32 mmcfg_offset;
if (pci_cfg_write_allowed(device->type,
(reg_num - reg_bias),
reg_bias, 4))
- *(volatile u32 *)(pci_space + mmcfg_offset) =
- ((u64 *)guest_regs)[reg];
+ mmio_write32(pci_space + mmcfg_offset, *value);
} else
if (device)
- ((u64 *)guest_regs)[reg] =
- *(volatile u32 *)(pci_space + mmcfg_offset);
+ *value = mmio_read32(pci_space + mmcfg_offset);
else
- ((u64 *)guest_regs)[reg] = BYTE_MASK(4);
+ *value = -1;
return 1;
}