[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/5] xen, gfx passthrough: add opregion mapping
From: |
Yang Zhang |
Subject: |
[Qemu-devel] [PATCH 5/5] xen, gfx passthrough: add opregion mapping |
Date: |
Fri, 21 Feb 2014 14:44:13 +0800 |
From: Yang Zhang <address@hidden>
The OpRegion shouldn't be mapped 1:1 because the address in the host
can't be used in the guest directly.
This patch traps read and write access to the opregion of the Intel
GPU config space (offset 0xfc).
The original patch is from Jean Guyader <address@hidden>
Signed-off-by: Yang Zhang <address@hidden>
Cc: Jean Guyader <address@hidden>
---
hw/xen/xen_pt.h | 4 ++-
hw/xen/xen_pt_config_init.c | 45 ++++++++++++++++++++++++++++++++++++++++++-
hw/xen/xen_pt_graphics.c | 45 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 92e4d51..9f7fd4e 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -63,7 +63,7 @@ typedef int (*xen_pt_conf_byte_read)
#define XEN_PT_BAR_UNMAPPED (-1)
#define PCI_CAP_MAX 48
-
+#define PCI_INTEL_OPREGION 0xfc
typedef enum {
XEN_PT_GRP_TYPE_HARDWIRED = 0, /* 0 Hardwired reg group */
@@ -307,5 +307,7 @@ int intel_pch_init(PCIBus *bus);
void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr,
uint32_t val, int len);
uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t config_addr, int len);
+uint32_t igd_read_opregion(XenPCIPassthroughState *s);
+void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val);
#endif /* !XEN_PT_H */
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 8ccc2e4..30135c1 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -575,6 +575,22 @@ static int
xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
return 0;
}
+static int xen_pt_intel_opregion_read(XenPCIPassthroughState *s,
+ XenPTReg *cfg_entry,
+ uint32_t *value, uint32_t valid_mask)
+{
+ *value = igd_read_opregion(s);
+ return 0;
+}
+
+static int xen_pt_intel_opregion_write(XenPCIPassthroughState *s,
+ XenPTReg *cfg_entry, uint32_t *value,
+ uint32_t dev_value, uint32_t valid_mask)
+{
+ igd_write_opregion(s, *value);
+ return 0;
+}
+
/* Header Type0 reg static information table */
static XenPTRegInfo xen_pt_emu_reg_header0[] = {
/* Vendor ID reg */
@@ -1438,6 +1454,20 @@ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
},
};
+static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
+ /* Intel IGFX OpRegion reg */
+ {
+ .offset = 0x0,
+ .size = 4,
+ .init_val = 0,
+ .no_wb = 1,
+ .u.dw.read = xen_pt_intel_opregion_read,
+ .u.dw.write = xen_pt_intel_opregion_write,
+ },
+ {
+ .size = 0,
+ },
+};
/****************************
* Capabilities
@@ -1675,6 +1705,14 @@ static const XenPTRegGroupInfo xen_pt_emu_reg_grps[] = {
.size_init = xen_pt_msix_size_init,
.emu_regs = xen_pt_emu_reg_msix,
},
+ /* Intel IGD Opregion group */
+ {
+ .grp_id = PCI_INTEL_OPREGION,
+ .grp_type = XEN_PT_GRP_TYPE_EMU,
+ .grp_size = 0x4,
+ .size_init = xen_pt_reg_grp_size_init,
+ .emu_regs = xen_pt_emu_reg_igd_opregion,
+ },
{
.grp_size = 0,
},
@@ -1804,7 +1842,8 @@ int xen_pt_config_init(XenPCIPassthroughState *s)
uint32_t reg_grp_offset = 0;
XenPTRegGroup *reg_grp_entry = NULL;
- if (xen_pt_emu_reg_grps[i].grp_id != 0xFF) {
+ if (xen_pt_emu_reg_grps[i].grp_id != 0xFF
+ && xen_pt_emu_reg_grps[i].grp_id != PCI_INTEL_OPREGION) {
if (xen_pt_hide_dev_cap(&s->real_device,
xen_pt_emu_reg_grps[i].grp_id)) {
continue;
@@ -1817,6 +1856,10 @@ int xen_pt_config_init(XenPCIPassthroughState *s)
}
}
+ if (xen_pt_emu_reg_grps[i].grp_id == PCI_INTEL_OPREGION) {
+ reg_grp_offset = PCI_INTEL_OPREGION;
+ }
+
reg_grp_entry = g_new0(XenPTRegGroup, 1);
QLIST_INIT(®_grp_entry->reg_tbl_list);
QLIST_INSERT_HEAD(&s->reg_grps, reg_grp_entry, entries);
diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c
index 2a01406..bebfcfd 100644
--- a/hw/xen/xen_pt_graphics.c
+++ b/hw/xen/xen_pt_graphics.c
@@ -6,6 +6,7 @@
#include "hw/xen/xen_backend.h"
int igd_passthru;
+static int igd_guest_opregion;
/*
* register VGA resources for the domain with assigned gfx
@@ -360,3 +361,47 @@ err_out:
return -1;
}
+uint32_t igd_read_opregion(XenPCIPassthroughState *s)
+{
+ uint32_t val = -1;
+
+ if (igd_guest_opregion == 0) {
+ return val;
+ }
+
+ val = igd_guest_opregion;
+
+ XEN_PT_LOG(&s->dev, "Read opregion val=%x\n", val);
+ return val;
+}
+
+void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val)
+{
+ uint32_t host_opregion = 0;
+ int ret;
+
+ if (igd_guest_opregion) {
+ XEN_PT_LOG(&s->dev, "opregion register already been set, ignoring
%x\n",
+ val);
+ return;
+ }
+
+ xen_host_pci_get_block(&s->real_device, PCI_INTEL_OPREGION,
+ (uint8_t *)&host_opregion, 4);
+ igd_guest_opregion = (val & ~0xfff) | (host_opregion & 0xfff);
+
+ ret = xc_domain_memory_mapping(xen_xc, xen_domid,
+ igd_guest_opregion >> XC_PAGE_SHIFT,
+ host_opregion >> XC_PAGE_SHIFT,
+ 2,
+ DPCI_ADD_MAPPING);
+
+ if (ret != 0) {
+ XEN_PT_ERR(&s->dev, "Error: Can't map opregion\n");
+ igd_guest_opregion = 0;
+ return;
+ }
+
+ XEN_PT_LOG(&s->dev, "Map OpRegion: %x -> %x\n", host_opregion,
+ igd_guest_opregion);
+}
--
1.7.1
- [Qemu-devel] [PATCH 0/5] xen: add Intel IGD passthrough support, Yang Zhang, 2014/02/21
- [Qemu-devel] [PATCH 1/5] xen, gfx passthrough: basic graphics passthrough support, Yang Zhang, 2014/02/21
- [Qemu-devel] [PATCH 2/5] xen, gfx passthrough: reserve 00:02.0 for INTEL IGD, Yang Zhang, 2014/02/21
- [Qemu-devel] [PATCH 5/5] xen, gfx passthrough: add opregion mapping,
Yang Zhang <=
- [Qemu-devel] [PATCH 3/5] xen, gfx passthrough: create intel isa bridge, Yang Zhang, 2014/02/21
- [Qemu-devel] [PATCH 4/5] xen, gfx passthrough: support Intel IGD passthrough with VT-D, Yang Zhang, 2014/02/21
- Re: [Qemu-devel] [PATCH 0/5] xen: add Intel IGD passthrough support, Zhang, Yang Z, 2014/02/27