[Xen-devel] [PATCH v2] tools/hvmloader: Use base instead of pci_mem_start for find_next_rmrr()

2017-08-28 Thread Xiong Zhang
find_next_rmrr(base) is used to find the lowest RMRR ending above base
but below 4G. Current method couldn't cover the following situation:
a. two rmrr exist, small gap between them
b. pci_mem_start and mem_resource.base is below the first rmrr.base
c. find_next_rmrr(pci_mem_start) will find the first rmrr
d. After aligning mem_resource.base to bar size,
   first_rmrr.end < new_base < second_rmrr.base and
   new_base + bar_sz > second_rmrr.base.
   So the new bar will overlap with the second rmrr and doesn't overlap
with the first rmrr.
But the next_rmrr point to the first rmrr, then check_overlap() couldn't
find the overlap. Finally assign a wrong address to bar.

This patch using aligned new base to find the next rmrr, could fix the
above case and find all the overlapped rmrr with new base.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>

---
Changes since v1:
 - Reduce the scope of next_rmrr to just this if()
---
 tools/firmware/hvmloader/pci.c | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/tools/firmware/hvmloader/pci.c b/tools/firmware/hvmloader/pci.c
index f4288a3..1858d7f 100644
--- a/tools/firmware/hvmloader/pci.c
+++ b/tools/firmware/hvmloader/pci.c
@@ -84,7 +84,6 @@ void pci_setup(void)
 uint32_t vga_devfn = 256;
 uint16_t class, vendor_id, device_id;
 unsigned int bar, pin, link, isa_irq;
-int next_rmrr;
 
 /* Resources assignable to PCI devices via BARs. */
 struct resource {
@@ -405,8 +404,6 @@ void pci_setup(void)
 io_resource.base = 0xc000;
 io_resource.max = 0x1;
 
-next_rmrr = find_next_rmrr(pci_mem_start);
-
 /* Assign iomem and ioport resources in descending order of size. */
 for ( i = 0; i < nr_bars; i++ )
 {
@@ -464,15 +461,21 @@ void pci_setup(void)
 base = (resource->base  + bar_sz - 1) & ~(uint64_t)(bar_sz - 1);
 
 /* If we're using mem_resource, check for RMRR conflicts. */
-while ( resource == _resource &&
-next_rmrr >= 0 &&
-check_overlap(base, bar_sz,
-  memory_map.map[next_rmrr].addr,
-  memory_map.map[next_rmrr].size) )
+if ( resource == _resource)
 {
-base = memory_map.map[next_rmrr].addr + 
memory_map.map[next_rmrr].size;
-base = (base + bar_sz - 1) & ~(bar_sz - 1);
+int next_rmrr;
+
 next_rmrr = find_next_rmrr(base);
+while ( next_rmrr >= 0 &&
+check_overlap(base, bar_sz,
+  memory_map.map[next_rmrr].addr,
+  memory_map.map[next_rmrr].size) )
+{
+base = memory_map.map[next_rmrr].addr +
+   memory_map.map[next_rmrr].size;
+base = (base + bar_sz - 1) & ~(bar_sz - 1);
+next_rmrr = find_next_rmrr(base);
+}
 }
 
 bar_data |= (uint32_t)base;
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] tools/hvmloader: Use base instead of pci_mem_start for find_next_rmrr()

2017-08-21 Thread Xiong Zhang
find_next_rmrr(base) is used to find the lowest RMRR ending above base
but below 4G. Current method couldn't cover the following situation:
a. two rmrr exist, small gap between them
b. pci_mem_start and mem_resource.base is below the first rmrr.base
c. find_next_rmrr(pci_mem_start) will find the first rmrr
d. After aligning mem_resource.base to bar size,
   first_rmrr.end < new_base < second_rmrr.base and
   new_base + bar_sz > second_rmrr.base.
   So the new bar will overlap with the second rmrr and don't overlap with
the first rmrr.
But the next_rmrr point to the first rmrr, then check_overlap() couldn't
find the overlap. Finally assign a wrong bar address to bar.

This patch using aligned new base to find the next rmrr, could fix the
above case and find all the overlapped rmrr with new base.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
---
 tools/firmware/hvmloader/pci.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/tools/firmware/hvmloader/pci.c b/tools/firmware/hvmloader/pci.c
index f4288a3..16fccbf 100644
--- a/tools/firmware/hvmloader/pci.c
+++ b/tools/firmware/hvmloader/pci.c
@@ -405,8 +405,6 @@ void pci_setup(void)
 io_resource.base = 0xc000;
 io_resource.max = 0x1;
 
-next_rmrr = find_next_rmrr(pci_mem_start);
-
 /* Assign iomem and ioport resources in descending order of size. */
 for ( i = 0; i < nr_bars; i++ )
 {
@@ -464,15 +462,19 @@ void pci_setup(void)
 base = (resource->base  + bar_sz - 1) & ~(uint64_t)(bar_sz - 1);
 
 /* If we're using mem_resource, check for RMRR conflicts. */
-while ( resource == _resource &&
-next_rmrr >= 0 &&
-check_overlap(base, bar_sz,
-  memory_map.map[next_rmrr].addr,
-  memory_map.map[next_rmrr].size) )
+if ( resource == _resource)
 {
-base = memory_map.map[next_rmrr].addr + 
memory_map.map[next_rmrr].size;
-base = (base + bar_sz - 1) & ~(bar_sz - 1);
 next_rmrr = find_next_rmrr(base);
+while ( next_rmrr >= 0 &&
+check_overlap(base, bar_sz,
+  memory_map.map[next_rmrr].addr,
+  memory_map.map[next_rmrr].size) )
+{
+base = memory_map.map[next_rmrr].addr +
+   memory_map.map[next_rmrr].size;
+base = (base + bar_sz - 1) & ~(bar_sz - 1);
+next_rmrr = find_next_rmrr(base);
+}
 }
 
 bar_data |= (uint32_t)base;
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] tools/libxl: Fix a segment fault when mmio_hole is set in hvm.cfg

2017-07-12 Thread Xiong Zhang
When valid mmio_hole is set in hvm.cfg, segment fault happens at accessing
localents pointer.

Because the size of localents pointer isn't enough to store appended
mmio_hole_size parameter.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
---
 tools/libxl/libxl_create.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index bffbc45..1158303 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -451,7 +451,7 @@ int libxl__domain_build(libxl__gc *gc,
 vments[4] = "start_time";
 vments[5] = GCSPRINTF("%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/1);
 
-localents = libxl__calloc(gc, 9, sizeof(char *));
+localents = libxl__calloc(gc, 11, sizeof(char *));
 i = 0;
 localents[i++] = "platform/acpi";
 localents[i++] = libxl__acpi_defbool_val(info) ? "1" : "0";
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] hw/xen: Set emu_mask for igd_opregion register

2017-07-07 Thread Xiong Zhang
In igd passthrough environment, guest could only access opregion at the
first bootup time. Once guest shutdown, later guest couldn't access 
opregion anymore.
This is because qemu set emulated guest opregion base address to host
register. Later guest get a wrong host opregion base address, and couldn't
access it anymore.

This patch set emu_mask for igd_opregion register, so guest won't set
guest opregion base address to host.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
---
 hw/xen/xen_pt_config_init.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 6f18366..1f04ec5 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1535,6 +1535,7 @@ static XenPTRegInfo xen_pt_emu_reg_igd_opregion[] = {
 .offset = 0x0,
 .size   = 4,
 .init_val   = 0,
+.emu_mask   = 0x,
 .u.dw.read   = xen_pt_intel_opregion_read,
 .u.dw.write  = xen_pt_intel_opregion_write,
 },
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2 1/2] tools/libxl/libxl_pci.c: Extract sysfs_dev_get_class from libxl__grant_vga_iomem_permission

2017-07-02 Thread Xiong Zhang
No functional change. Just extract this function for next patch and avoid
code repetition.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
---
Changes in v2:
-Add No functional change in commit message
-Use 'goto out' style error handling
---
 tools/libxl/libxl_pci.c | 47 +--
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index b14df16..d109930 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -531,6 +531,34 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, 
libxl_device_pci *pcidev)
 return pci_device_device;
 }
 
+static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pcidev,
+   unsigned long *class)
+{
+char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
+ pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+int read_items, ret = 0;
+
+FILE *f = fopen(pci_device_class_path, "r");
+if (!f) {
+LOGE(ERROR,
+ "pci device "PCI_BDF" does not have class attribute",
+ pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+ret = ERROR_FAIL;
+goto out;
+}
+read_items = fscanf(f, "0x%lx\n", class);
+fclose(f);
+if (read_items != 1) {
+LOGE(ERROR,
+ "cannot read class of pci device "PCI_BDF,
+ pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+ret = ERROR_FAIL;
+}
+
+out:
+return ret;
+}
+
 typedef struct {
 uint16_t vendor;
 uint16_t device;
@@ -1652,27 +1680,10 @@ int libxl__grant_vga_iomem_permission(libxl__gc *gc, 
const uint32_t domid,
 uint64_t vga_iomem_start = 0xa >> XC_PAGE_SHIFT;
 uint32_t stubdom_domid;
 libxl_device_pci *pcidev = _config->pcidevs[i];
-char *pci_device_class_path =
-GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-  pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
-int read_items;
 unsigned long pci_device_class;
 
-FILE *f = fopen(pci_device_class_path, "r");
-if (!f) {
-LOGED(ERROR, domid,
-  "pci device "PCI_BDF" does not have class attribute",
-  pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+if (sysfs_dev_get_class(gc, pcidev, _device_class))
 continue;
-}
-read_items = fscanf(f, "0x%lx\n", _device_class);
-fclose(f);
-if (read_items != 1) {
-LOGED(ERROR, domid,
-  "cannot read class of pci device "PCI_BDF,
-  pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
-continue;
-}
 if (pci_device_class != 0x03) /* VGA class */
 continue;
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH v2 2/2] tools/libxl/libxl_pci.c: Judge igd through class code instead of device ID

2017-07-02 Thread Xiong Zhang
IGD passthrough couldn't work on Skylake and Kabylake, because their
Device ID aren't in fixup_ids[]. Currently we need to add every intel
graphic ID into fixup_ids[], it is hard to maintain.

This patch judge intel graphics through vendor id (0x8086) and class
code(0x03), this could support both the old and new intel graphics,
and reduce maintain work in future.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
Acked-by: Wei Liu <wei.l...@citrix.com>
---
Changes in v2:
-Add Acked-by: Wei Liu <wei.l...@citrix.com>
---
 tools/libxl/libxl_pci.c | 59 -
 1 file changed, 9 insertions(+), 50 deletions(-)

diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index d109930..65ad5e5 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -559,46 +559,6 @@ out:
 return ret;
 }
 
-typedef struct {
-uint16_t vendor;
-uint16_t device;
-} pci_info;
-
-static const pci_info fixup_ids[] = {
-/* Intel HSW Classic */
-{0x8086, 0x0402}, /* HSWGT1D, HSWD_w7 */
-{0x8086, 0x0406}, /* HSWGT1M, HSWM_w7 */
-{0x8086, 0x0412}, /* HSWGT2D, HSWD_w7 */
-{0x8086, 0x0416}, /* HSWGT2M, HSWM_w7 */
-{0x8086, 0x041E}, /* HSWGT15D, HSWD_w7 */
-/* Intel HSW ULT */
-{0x8086, 0x0A06}, /* HSWGT1UT, HSWM_w7 */
-{0x8086, 0x0A16}, /* HSWGT2UT, HSWM_w7 */
-{0x8086, 0x0A26}, /* HSWGT3UT, HSWM_w7 */
-{0x8086, 0x0A2E}, /* HSWGT3UT28W, HSWM_w7 */
-{0x8086, 0x0A1E}, /* HSWGT2UX, HSWM_w7 */
-{0x8086, 0x0A0E}, /* HSWGT1ULX, HSWM_w7 */
-/* Intel HSW CRW */
-{0x8086, 0x0D26}, /* HSWGT3CW, HSWM_w7 */
-{0x8086, 0x0D22}, /* HSWGT3CWDT, HSWD_w7 */
-/* Intel HSW Server */
-{0x8086, 0x041A}, /* HSWSVGT2, HSWD_w7 */
-/* Intel HSW SRVR */
-{0x8086, 0x040A}, /* HSWSVGT1, HSWD_w7 */
-/* Intel BSW */
-{0x8086, 0x1606}, /* BDWULTGT1, BDWM_w7 */
-{0x8086, 0x1616}, /* BDWULTGT2, BDWM_w7 */
-{0x8086, 0x1626}, /* BDWULTGT3, BDWM_w7 */
-{0x8086, 0x160E}, /* BDWULXGT1, BDWM_w7 */
-{0x8086, 0x161E}, /* BDWULXGT2, BDWM_w7 */
-{0x8086, 0x1602}, /* BDWHALOGT1, BDWM_w7 */
-{0x8086, 0x1612}, /* BDWHALOGT2, BDWM_w7 */
-{0x8086, 0x1622}, /* BDWHALOGT3, BDWM_w7 */
-{0x8086, 0x162B}, /* BDWHALO28W, BDWM_w7 */
-{0x8086, 0x162A}, /* BDWGT3WRKS, BDWM_w7 */
-{0x8086, 0x162D}, /* BDWGT3SRVR, BDWM_w7 */
-};
-
 /*
  * Some devices may need some ways to work well. Here like IGD,
  * we have to pass a specific option to qemu.
@@ -606,24 +566,23 @@ static const pci_info fixup_ids[] = {
 bool libxl__is_igd_vga_passthru(libxl__gc *gc,
 const libxl_domain_config *d_config)
 {
-unsigned int i, j, num = ARRAY_SIZE(fixup_ids);
-uint16_t vendor, device, pt_vendor, pt_device;
+unsigned int i;
+uint16_t pt_vendor, pt_device;
+unsigned long class;
 
 for (i = 0 ; i < d_config->num_pcidevs ; i++) {
 libxl_device_pci *pcidev = _config->pcidevs[i];
 pt_vendor = sysfs_dev_get_vendor(gc, pcidev);
 pt_device = sysfs_dev_get_device(gc, pcidev);
 
-if (pt_vendor == 0x || pt_device == 0x)
+if (pt_vendor == 0x || pt_device == 0x ||
+pt_vendor != 0x8086)
 continue;
 
-for (j = 0 ; j < num ; j++) {
-vendor = fixup_ids[j].vendor;
-device = fixup_ids[j].device;
-
-if (pt_vendor == vendor &&  pt_device == device)
-return true;
-}
+if (sysfs_dev_get_class(gc, pcidev, ))
+continue;
+if (class == 0x03)
+return true;
 }
 
 return false;
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 1/2] tools/libxl/libxl_pci.c: Extract sysfs_dev_get_class from libxl__grant_vga_iomem_permission

2017-06-30 Thread Xiong Zhang
Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
---
 tools/libxl/libxl_pci.c | 45 +++--
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index b14df16..cefd7d8 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -531,6 +531,32 @@ static uint16_t sysfs_dev_get_device(libxl__gc *gc, 
libxl_device_pci *pcidev)
 return pci_device_device;
 }
 
+static int sysfs_dev_get_class(libxl__gc *gc, libxl_device_pci *pcidev,
+   unsigned long *class)
+{
+char *pci_device_class_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
+ pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+int read_items;
+
+FILE *f = fopen(pci_device_class_path, "r");
+if (!f) {
+LOGE(ERROR,
+ "pci device "PCI_BDF" does not have class attribute",
+ pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+return ERROR_FAIL;
+}
+read_items = fscanf(f, "0x%lx\n", class);
+fclose(f);
+if (read_items != 1) {
+LOGE(ERROR,
+ "cannot read class of pci device "PCI_BDF,
+ pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+return ERROR_FAIL;
+}
+
+return 0;
+}
+
 typedef struct {
 uint16_t vendor;
 uint16_t device;
@@ -1652,27 +1678,10 @@ int libxl__grant_vga_iomem_permission(libxl__gc *gc, 
const uint32_t domid,
 uint64_t vga_iomem_start = 0xa >> XC_PAGE_SHIFT;
 uint32_t stubdom_domid;
 libxl_device_pci *pcidev = _config->pcidevs[i];
-char *pci_device_class_path =
-GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/class",
-  pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
-int read_items;
 unsigned long pci_device_class;
 
-FILE *f = fopen(pci_device_class_path, "r");
-if (!f) {
-LOGED(ERROR, domid,
-  "pci device "PCI_BDF" does not have class attribute",
-  pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
-continue;
-}
-read_items = fscanf(f, "0x%lx\n", _device_class);
-fclose(f);
-if (read_items != 1) {
-LOGED(ERROR, domid,
-  "cannot read class of pci device "PCI_BDF,
-  pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+if (sysfs_dev_get_class(gc, pcidev, _device_class))
 continue;
-}
 if (pci_device_class != 0x03) /* VGA class */
 continue;
 
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH 2/2] tools/libxl/libxl_pci.c: Judge igd through class code instead of device ID

2017-06-30 Thread Xiong Zhang
IGD passthrough couldn't work on Skylake and Kabylake, because their
Device ID aren't in fixup_ids[]. Currently we need to add every intel
graphic ID into fixup_ids[], it is hard to maintain.

This patch judge intel graphics through vendor id (0x8086) and class
code(0x03), this could support both the old and new intel graphics,
and reduce maintain work in future.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
---
 tools/libxl/libxl_pci.c | 59 -
 1 file changed, 9 insertions(+), 50 deletions(-)

diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index cefd7d8..7b43622 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -557,46 +557,6 @@ static int sysfs_dev_get_class(libxl__gc *gc, 
libxl_device_pci *pcidev,
 return 0;
 }
 
-typedef struct {
-uint16_t vendor;
-uint16_t device;
-} pci_info;
-
-static const pci_info fixup_ids[] = {
-/* Intel HSW Classic */
-{0x8086, 0x0402}, /* HSWGT1D, HSWD_w7 */
-{0x8086, 0x0406}, /* HSWGT1M, HSWM_w7 */
-{0x8086, 0x0412}, /* HSWGT2D, HSWD_w7 */
-{0x8086, 0x0416}, /* HSWGT2M, HSWM_w7 */
-{0x8086, 0x041E}, /* HSWGT15D, HSWD_w7 */
-/* Intel HSW ULT */
-{0x8086, 0x0A06}, /* HSWGT1UT, HSWM_w7 */
-{0x8086, 0x0A16}, /* HSWGT2UT, HSWM_w7 */
-{0x8086, 0x0A26}, /* HSWGT3UT, HSWM_w7 */
-{0x8086, 0x0A2E}, /* HSWGT3UT28W, HSWM_w7 */
-{0x8086, 0x0A1E}, /* HSWGT2UX, HSWM_w7 */
-{0x8086, 0x0A0E}, /* HSWGT1ULX, HSWM_w7 */
-/* Intel HSW CRW */
-{0x8086, 0x0D26}, /* HSWGT3CW, HSWM_w7 */
-{0x8086, 0x0D22}, /* HSWGT3CWDT, HSWD_w7 */
-/* Intel HSW Server */
-{0x8086, 0x041A}, /* HSWSVGT2, HSWD_w7 */
-/* Intel HSW SRVR */
-{0x8086, 0x040A}, /* HSWSVGT1, HSWD_w7 */
-/* Intel BSW */
-{0x8086, 0x1606}, /* BDWULTGT1, BDWM_w7 */
-{0x8086, 0x1616}, /* BDWULTGT2, BDWM_w7 */
-{0x8086, 0x1626}, /* BDWULTGT3, BDWM_w7 */
-{0x8086, 0x160E}, /* BDWULXGT1, BDWM_w7 */
-{0x8086, 0x161E}, /* BDWULXGT2, BDWM_w7 */
-{0x8086, 0x1602}, /* BDWHALOGT1, BDWM_w7 */
-{0x8086, 0x1612}, /* BDWHALOGT2, BDWM_w7 */
-{0x8086, 0x1622}, /* BDWHALOGT3, BDWM_w7 */
-{0x8086, 0x162B}, /* BDWHALO28W, BDWM_w7 */
-{0x8086, 0x162A}, /* BDWGT3WRKS, BDWM_w7 */
-{0x8086, 0x162D}, /* BDWGT3SRVR, BDWM_w7 */
-};
-
 /*
  * Some devices may need some ways to work well. Here like IGD,
  * we have to pass a specific option to qemu.
@@ -604,24 +564,23 @@ static const pci_info fixup_ids[] = {
 bool libxl__is_igd_vga_passthru(libxl__gc *gc,
 const libxl_domain_config *d_config)
 {
-unsigned int i, j, num = ARRAY_SIZE(fixup_ids);
-uint16_t vendor, device, pt_vendor, pt_device;
+unsigned int i;
+uint16_t pt_vendor, pt_device;
+unsigned long class;
 
 for (i = 0 ; i < d_config->num_pcidevs ; i++) {
 libxl_device_pci *pcidev = _config->pcidevs[i];
 pt_vendor = sysfs_dev_get_vendor(gc, pcidev);
 pt_device = sysfs_dev_get_device(gc, pcidev);
 
-if (pt_vendor == 0x || pt_device == 0x)
+if (pt_vendor == 0x || pt_device == 0x ||
+pt_vendor != 0x8086)
 continue;
 
-for (j = 0 ; j < num ; j++) {
-vendor = fixup_ids[j].vendor;
-device = fixup_ids[j].device;
-
-if (pt_vendor == vendor &&  pt_device == device)
-return true;
-}
+if (sysfs_dev_get_class(gc, pcidev, ))
+continue;
+if (class == 0x03)
+return true;
 }
 
 return false;
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH] hw/pt-graphics.c: Gave guest iomem permission for host opregion in qemu-xen-traditional

2017-06-27 Thread Xiong Zhang
Currently guest couldn't access host opregion when igd is passed through
to guest with qemu-xen-traditional. Because guest lack of
iomem permission to map guest allocated opregion pages to host opregion
pages.

So guest should get iomem permission for host opregion before mapping.

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
---
 hw/pt-graphics.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/pt-graphics.c b/hw/pt-graphics.c
index 7302b25..893bf12 100644
--- a/hw/pt-graphics.c
+++ b/hw/pt-graphics.c
@@ -78,10 +78,20 @@ void igd_write_opregion(struct pt_dev *real_dev, uint32_t 
val)
 igd_guest_opregion = (val & ~0xfff) | (host_opregion & 0xfff);
 PT_LOG("Map OpRegion: %x -> %x\n", host_opregion, igd_guest_opregion);
 
+ret = xc_domain_iomem_permission(xc_handle, domid,
+host_opregion >> XC_PAGE_SHIFT, 3, 1);
+if (ret)
+{
+PT_LOG("Error[%d]: Can't enable to access IGD host opregion: 0x%x\n",
+ret, host_opregion >> XC_PAGE_SHIFT);
+igd_guest_opregion = 0;
+return;
+}
+
 ret = xc_domain_memory_mapping(xc_handle, domid,
 igd_guest_opregion >> XC_PAGE_SHIFT,
 host_opregion >> XC_PAGE_SHIFT,
-2,
+3,
 DPCI_ADD_MAPPING);
 
 if ( ret != 0 )
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel


[Xen-devel] [PATCH V5] x86/ioreq_server: Make p2m_finish_type_change actually work

2017-05-12 Thread Xiong Zhang
Commit 6d774a951696 ("x86/ioreq server: synchronously reset outstanding
p2m_ioreq_server entries when an ioreq server unmaps") introduced
p2m_finish_type_change(), which was meant to synchronously finish a
previously initiated type change over a gpfn range.  It did this by
calling get_entry(), checking if it was the appropriate type, and then
calling set_entry().

Unfortunately, a previous commit (1679e0df3df6 "x86/ioreq server:
asynchronously reset outstanding p2m_ioreq_server entries") modified
get_entry() to always return the new type after the type change, meaning
that p2m_finish_type_change() never changed any entries.  Which means
when an ioreq server was detached and then re-attached (as happens in
XenGT on reboot) the re-attach failed.

Fix this by using the existing p2m-specific recalculation logic instead
of doing a read-check-write loop.

Fix: 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
  outstanding p2m_ioreq_server entries when an ioreq server unmaps")'

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
Signed-off-by: Yu Zhang <yu.c.zh...@linux.intel.com>
Reviewed-by: George Dunlap <george.dun...@ctrix.com>
Reviewed-by: Jan Beulich <jbeul...@suse.com>
---
v1: Add ioreq_pre_recalc query flag to get the old p2m_type.(Jan)
v2: Add p2m->recalc() hook to change gfn p2m_type. (George)
v3: Make commit message clearer. (George)
Keep the name of p2m-specific recal function unchanged. (Jan)
v4: Move version info below S-o-B and handle return value of
p2m->recalc. (Jan)
v5: Fix coding style. (Julien)

The target of this patch is Xen 4.9.
---
 xen/arch/x86/hvm/dm.c |  5 +++--
 xen/arch/x86/mm/p2m-ept.c |  1 +
 xen/arch/x86/mm/p2m-pt.c  |  1 +
 xen/arch/x86/mm/p2m.c | 35 +++
 xen/include/asm-x86/p2m.h |  9 +
 5 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index d72b7bd..99bf66a 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -412,8 +412,9 @@ static int dm_op(domid_t domid,
 first_gfn <= p2m->max_mapped_pfn )
 {
 /* Iterate p2m table for 256 gfns each time. */
-p2m_finish_type_change(d, _gfn(first_gfn), 256,
-   p2m_ioreq_server, p2m_ram_rw);
+rc = p2m_finish_type_change(d, _gfn(first_gfn), 256);
+if ( rc < 0 )
+break;
 
 first_gfn += 256;
 
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..09efba7 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -1238,6 +1238,7 @@ int ept_p2m_init(struct p2m_domain *p2m)
 
 p2m->set_entry = ept_set_entry;
 p2m->get_entry = ept_get_entry;
+p2m->recalc = resolve_misconfig;
 p2m->change_entry_type_global = ept_change_entry_type_global;
 p2m->change_entry_type_range = ept_change_entry_type_range;
 p2m->memory_type_changed = ept_memory_type_changed;
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..2eddeee 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -1153,6 +1153,7 @@ void p2m_pt_init(struct p2m_domain *p2m)
 {
 p2m->set_entry = p2m_pt_set_entry;
 p2m->get_entry = p2m_pt_get_entry;
+p2m->recalc = do_recalc;
 p2m->change_entry_type_global = p2m_pt_change_entry_type_global;
 p2m->change_entry_type_range = p2m_pt_change_entry_type_range;
 p2m->write_p2m_entry = paging_write_p2m_entry;
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 1d57e5c..1600422 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1011,33 +1011,44 @@ void p2m_change_type_range(struct domain *d,
 p2m_unlock(p2m);
 }
 
-/* Synchronously modify the p2m type for a range of gfns from ot to nt. */
-void p2m_finish_type_change(struct domain *d,
-gfn_t first_gfn, unsigned long max_nr,
-p2m_type_t ot, p2m_type_t nt)
+/*
+ * Finish p2m type change for gfns which are marked as need_recalc in a range.
+ * Returns: 0/1 for success, negative for failure
+ */
+int p2m_finish_type_change(struct domain *d,
+   gfn_t first_gfn, unsigned long max_nr)
 {
 struct p2m_domain *p2m = p2m_get_hostp2m(d);
-p2m_type_t t;
 unsigned long gfn = gfn_x(first_gfn);
 unsigned long last_gfn = gfn + max_nr - 1;
-
-ASSERT(ot != nt);
-ASSERT(p2m_is_changeable(ot) && p2m_is_changeable(nt));
+int rc = 0;
 
 p2m_lock(p2m);
 
 last_gfn = min(last_gfn, p2m->max_mapped_pfn);
 while ( gfn <= last_gfn )
 {
-get_gfn_query_unlocked(d, gfn, );
-
-if ( t == ot )
-p2m_change_type_one(d, gfn, t, nt);
+rc = p2m->recalc(p2m, gfn);
+/*
+ * ept->rec

[Xen-devel] [PATCH V4] x86/ioreq_server: Make p2m_finish_type_change actually work

2017-05-11 Thread Xiong Zhang
Commit 6d774a951696 ("x86/ioreq server: synchronously reset outstanding
p2m_ioreq_server entries when an ioreq server unmaps") introduced
p2m_finish_type_change(), which was meant to synchronously finish a
previously initiated type change over a gpfn range.  It did this by
calling get_entry(), checking if it was the appropriate type, and then
calling set_entry().

Unfortunately, a previous commit (1679e0df3df6 "x86/ioreq server:
asynchronously reset outstanding p2m_ioreq_server entries") modified
get_entry() to always return the new type after the type change, meaning
that p2m_finish_type_change() never changed any entries.  Which means
when an ioreq server was detached and then re-attached (as happens in
XenGT on reboot) the re-attach failed.

Fix this by using the existing p2m-specific recalculation logic instead
of doing a read-check-write loop.

Fix: 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
  outstanding p2m_ioreq_server entries when an ioreq server unmaps")'

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
Signed-off-by: Yu Zhang <yu.c.zh...@linux.intel.com>
Reviewed-by: George Dunlap <george.dun...@ctrix.com>
---
v1: Add ioreq_pre_recalc query flag to get the old p2m_type.(Jan)
v2: Add p2m->recalc() hook to change gfn p2m_type. (George)
v3: Make commit message clearer. (George)
Keep the name of p2m-specific recal function unchanged. (Jan)
v4: Move version info below S-o-B and handle return value of
p2m->recalc. (Jan)
---
 xen/arch/x86/hvm/dm.c |  5 +++--
 xen/arch/x86/mm/p2m-ept.c |  1 +
 xen/arch/x86/mm/p2m-pt.c  |  1 +
 xen/arch/x86/mm/p2m.c | 35 +++
 xen/include/asm-x86/p2m.h |  7 ---
 5 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index d72b7bd..99bf66a 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -412,8 +412,9 @@ static int dm_op(domid_t domid,
 first_gfn <= p2m->max_mapped_pfn )
 {
 /* Iterate p2m table for 256 gfns each time. */
-p2m_finish_type_change(d, _gfn(first_gfn), 256,
-   p2m_ioreq_server, p2m_ram_rw);
+rc = p2m_finish_type_change(d, _gfn(first_gfn), 256);
+if ( rc < 0 )
+break;
 
 first_gfn += 256;
 
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..09efba7 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -1238,6 +1238,7 @@ int ept_p2m_init(struct p2m_domain *p2m)
 
 p2m->set_entry = ept_set_entry;
 p2m->get_entry = ept_get_entry;
+p2m->recalc = resolve_misconfig;
 p2m->change_entry_type_global = ept_change_entry_type_global;
 p2m->change_entry_type_range = ept_change_entry_type_range;
 p2m->memory_type_changed = ept_memory_type_changed;
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..2eddeee 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -1153,6 +1153,7 @@ void p2m_pt_init(struct p2m_domain *p2m)
 {
 p2m->set_entry = p2m_pt_set_entry;
 p2m->get_entry = p2m_pt_get_entry;
+p2m->recalc = do_recalc;
 p2m->change_entry_type_global = p2m_pt_change_entry_type_global;
 p2m->change_entry_type_range = p2m_pt_change_entry_type_range;
 p2m->write_p2m_entry = paging_write_p2m_entry;
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 1d57e5c..668c5a6 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1011,33 +1011,44 @@ void p2m_change_type_range(struct domain *d,
 p2m_unlock(p2m);
 }
 
-/* Synchronously modify the p2m type for a range of gfns from ot to nt. */
-void p2m_finish_type_change(struct domain *d,
-gfn_t first_gfn, unsigned long max_nr,
-p2m_type_t ot, p2m_type_t nt)
+/*
+ * Finish p2m type change for gfns which are marked as need_recalc in a range.
+ * Returns: 0/1 for success, negative for failure
+ */
+int p2m_finish_type_change(struct domain *d,
+   gfn_t first_gfn, unsigned long max_nr)
 {
 struct p2m_domain *p2m = p2m_get_hostp2m(d);
-p2m_type_t t;
 unsigned long gfn = gfn_x(first_gfn);
 unsigned long last_gfn = gfn + max_nr - 1;
-
-ASSERT(ot != nt);
-ASSERT(p2m_is_changeable(ot) && p2m_is_changeable(nt));
+int rc = 0;
 
 p2m_lock(p2m);
 
 last_gfn = min(last_gfn, p2m->max_mapped_pfn);
 while ( gfn <= last_gfn )
 {
-get_gfn_query_unlocked(d, gfn, );
-
-if ( t == ot )
-p2m_change_type_one(d, gfn, t, nt);
+rc = p2m->recalc(p2m, gfn);
+/* 
+ * ept->recalc could return 0/1/-ENOMEM. pt->recalc could return
+ * 0/-ENOMEM/-ENOENT, -ENOENT isn't an error as we 

[Xen-devel] [PATCH V3] x86/ioreq_server: Make p2m_finish_type_change actually work

2017-05-10 Thread Xiong Zhang
Commit 6d774a951696 ("x86/ioreq server: synchronously reset outstanding
p2m_ioreq_server entries when an ioreq server unmaps") introduced
p2m_finish_type_change(), which was meant to synchronously finish a
previously initiated type change over a gpfn range.  It did this by
calling get_entry(), checking if it was the appropriate type, and then
calling set_entry().

Unfortunately, a previous commit (1679e0df3df6 "x86/ioreq server:
asynchronously reset outstanding p2m_ioreq_server entries") modified
get_entry() to always return the new type after the type change, meaning
that p2m_finish_type_change() never changed any entries.  Which means
when an ioreq server was detached and then re-attached (as happens in
XenGT on reboot) the re-attach failed.

Fix this by using the existing p2m-specific recalculation logic instead
of doing a read-check-write loop.

Fix: 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
  outstanding p2m_ioreq_server entries when an ioreq server unmaps")'

v1: Add ioreq_pre_recalc query flag to get the old p2m_type.(Jan)
v2: Add p2m->recalc() hook to change gfn p2m_type. (George)
v3: Make commit message clearer. (George)

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
Signed-off-by: Yu Zhang <yu.c.zh...@linux.intel.com>
---
 xen/arch/x86/hvm/dm.c |  3 +--
 xen/arch/x86/mm/p2m-ept.c |  1 +
 xen/arch/x86/mm/p2m-pt.c  |  1 +
 xen/arch/x86/mm/p2m.c | 12 ++--
 xen/include/asm-x86/p2m.h |  5 +++--
 5 files changed, 8 insertions(+), 14 deletions(-)

diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index d72b7bd..c1627ec 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -412,8 +412,7 @@ static int dm_op(domid_t domid,
 first_gfn <= p2m->max_mapped_pfn )
 {
 /* Iterate p2m table for 256 gfns each time. */
-p2m_finish_type_change(d, _gfn(first_gfn), 256,
-   p2m_ioreq_server, p2m_ram_rw);
+p2m_finish_type_change(d, _gfn(first_gfn), 256);
 
 first_gfn += 256;
 
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..09efba7 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -1238,6 +1238,7 @@ int ept_p2m_init(struct p2m_domain *p2m)
 
 p2m->set_entry = ept_set_entry;
 p2m->get_entry = ept_get_entry;
+p2m->recalc = resolve_misconfig;
 p2m->change_entry_type_global = ept_change_entry_type_global;
 p2m->change_entry_type_range = ept_change_entry_type_range;
 p2m->memory_type_changed = ept_memory_type_changed;
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..2eddeee 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -1153,6 +1153,7 @@ void p2m_pt_init(struct p2m_domain *p2m)
 {
 p2m->set_entry = p2m_pt_set_entry;
 p2m->get_entry = p2m_pt_get_entry;
+p2m->recalc = do_recalc;
 p2m->change_entry_type_global = p2m_pt_change_entry_type_global;
 p2m->change_entry_type_range = p2m_pt_change_entry_type_range;
 p2m->write_p2m_entry = paging_write_p2m_entry;
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 1d57e5c..2bad2e1 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1013,26 +1013,18 @@ void p2m_change_type_range(struct domain *d,
 
 /* Synchronously modify the p2m type for a range of gfns from ot to nt. */
 void p2m_finish_type_change(struct domain *d,
-gfn_t first_gfn, unsigned long max_nr,
-p2m_type_t ot, p2m_type_t nt)
+gfn_t first_gfn, unsigned long max_nr)
 {
 struct p2m_domain *p2m = p2m_get_hostp2m(d);
-p2m_type_t t;
 unsigned long gfn = gfn_x(first_gfn);
 unsigned long last_gfn = gfn + max_nr - 1;
 
-ASSERT(ot != nt);
-ASSERT(p2m_is_changeable(ot) && p2m_is_changeable(nt));
-
 p2m_lock(p2m);
 
 last_gfn = min(last_gfn, p2m->max_mapped_pfn);
 while ( gfn <= last_gfn )
 {
-get_gfn_query_unlocked(d, gfn, );
-
-if ( t == ot )
-p2m_change_type_one(d, gfn, t, nt);
+p2m->recalc(p2m, gfn);
 
 gfn++;
 }
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 7574a9b..081639c 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -246,6 +246,8 @@ struct p2m_domain {
 p2m_query_t q,
 unsigned int *page_order,
 bool_t *sve);
+int(*recalc)(struct p2m_domain *p2m,
+ unsigned long gfn);
 void   (*enable_hardware_log_dirty)(struct p2m_domain *p2m);
 void   (*disable_hardware_log_dirty)(struct p2m_domain *p2m);
 void   (*flush_hard

[Xen-devel] [PATCH V2] x86/ioreq server: Fix XenGT couldn't reboot when XenGT use p2m_ioreq_server p2m_type

2017-05-08 Thread Xiong Zhang
'commit 1679e0df3df6 ("x86/ioreq server: asynchronously reset
outstanding p2m_ioreq_server entries")' will call
p2m_change_entry_type_global() which set entry.recalc=1. Then
the following get_entry(p2m_ioreq_server) will return
p2m_ram_rw type.
But 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
outstanding p2m_ioreq_server entries when an ioreq server unmaps")'
assume get_entry(p2m_ioreq_server) will return p2m_ioreq_server
type, then reset p2m_ioreq_server entries. The fact is the assumption
isn't true, and sysnchronously reset function couldn't work. Then
ioreq.entry_count is larger than zero after an ioreq server unmaps.
During XenGT domU reboot, it will unmap, map and unmap ioreq
server with old domid, the map will fail as ioreq.entry_count > 0 and
reboot process is terminated.

This patch add p2m->recalc() hook which use the existing implementation
specific function as ept resolve_misconfig and pt do_recalc, so
p2m_finish_type_change() could call p2m->recalc() directly to
change gfn p2m_type which need recalc.

Fix: 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
  outstanding p2m_ioreq_server entries when an ioreq server unmaps")'

v1: Add ioreq_pre_recalc query flag to get the old p2m_type.(Jan)
v2: Add p2m->recalc() hook to change gfn p2m_type. (George)

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
Signed-off-by: Yu Zhang <yu.c.zh...@linux.intel.com>
---
 xen/arch/x86/hvm/dm.c |  3 +--
 xen/arch/x86/mm/p2m-ept.c |  7 ---
 xen/arch/x86/mm/p2m-pt.c  |  7 ---
 xen/arch/x86/mm/p2m.c | 12 ++--
 xen/include/asm-x86/p2m.h |  5 +++--
 5 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index d72b7bd..c1627ec 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -412,8 +412,7 @@ static int dm_op(domid_t domid,
 first_gfn <= p2m->max_mapped_pfn )
 {
 /* Iterate p2m table for 256 gfns each time. */
-p2m_finish_type_change(d, _gfn(first_gfn), 256,
-   p2m_ioreq_server, p2m_ram_rw);
+p2m_finish_type_change(d, _gfn(first_gfn), 256);
 
 first_gfn += 256;
 
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..f96bd3b 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -502,7 +502,7 @@ static int ept_invalidate_emt_range(struct p2m_domain *p2m,
  * - zero if no adjustment was done,
  * - a positive value if at least one adjustment was done.
  */
-static int resolve_misconfig(struct p2m_domain *p2m, unsigned long gfn)
+static int ept_resolve_misconfig(struct p2m_domain *p2m, unsigned long gfn)
 {
 struct ept_data *ept = >ept;
 unsigned int level = ept->wl;
@@ -659,7 +659,7 @@ bool_t ept_handle_misconfig(uint64_t gpa)
 p2m_lock(p2m);
 
 spurious = curr->arch.hvm_vmx.ept_spurious_misconfig;
-rc = resolve_misconfig(p2m, PFN_DOWN(gpa));
+rc = ept_resolve_misconfig(p2m, PFN_DOWN(gpa));
 curr->arch.hvm_vmx.ept_spurious_misconfig = 0;
 
 p2m_unlock(p2m);
@@ -707,7 +707,7 @@ ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, 
mfn_t mfn,
 return -EINVAL;
 
 /* Carry out any eventually pending earlier changes first. */
-ret = resolve_misconfig(p2m, gfn);
+ret = ept_resolve_misconfig(p2m, gfn);
 if ( ret < 0 )
 return ret;
 
@@ -1238,6 +1238,7 @@ int ept_p2m_init(struct p2m_domain *p2m)
 
 p2m->set_entry = ept_set_entry;
 p2m->get_entry = ept_get_entry;
+p2m->recalc = ept_resolve_misconfig;
 p2m->change_entry_type_global = ept_change_entry_type_global;
 p2m->change_entry_type_range = ept_change_entry_type_range;
 p2m->memory_type_changed = ept_memory_type_changed;
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..b0f6aa0 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -367,7 +367,7 @@ static int p2m_pt_set_recalc_range(struct p2m_domain *p2m,
  * GFN. Propagate the re-calculation flag down to the next page table level
  * for entries not involved in the translation of the given GFN.
  */
-static int do_recalc(struct p2m_domain *p2m, unsigned long gfn)
+static int p2m_pt_do_recalc(struct p2m_domain *p2m, unsigned long gfn)
 {
 void *table;
 unsigned long gfn_remainder = gfn;
@@ -493,7 +493,7 @@ int p2m_pt_handle_deferred_changes(uint64_t gpa)
 int rc;
 
 p2m_lock(p2m);
-rc = do_recalc(p2m, PFN_DOWN(gpa));
+rc = p2m_pt_do_recalc(p2m, PFN_DOWN(gpa));
 p2m_unlock(p2m);
 
 return rc;
@@ -555,7 +555,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, unsigned long gfn, 
mfn_t mfn,
 }
 
 /* Carry out any eventually pending earlier changes first. */
-rc = do_recalc(p2m, gfn);
+rc = p2m_pt_do_recalc(p2m, gfn);
 if ( rc < 0 )
 re

[Xen-devel] [PATCH] x86/ioreq server: Fix DomU couldn't reboot when using p2m_ioreq_server p2m_type

2017-05-04 Thread Xiong Zhang
'commit 1679e0df3df6 ("x86/ioreq server: asynchronously reset
outstanding p2m_ioreq_server entries")' will call
p2m_change_entry_type_global() which set entry.recalc=1. Then
the following get_entry(p2m_ioreq_server) will return
p2m_ram_rw type.
But 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
outstanding p2m_ioreq_server entries when an ioreq server unmaps")'
assume get_entry(p2m_ioreq_server) will return p2m_ioreq_server
type, then reset p2m_ioreq_server entries. The fact is the assumption
isn't true, and sysnchronously reset function couldn't work. Then
ioreq.entry_count is larger than zero after an ioreq server unmaps,
finally this results DomU couldn't reboot.

This patch add a P2M_PRE_RECALC flag to p2m_query_t, then
get_entry(P2M_PRE_RECALC) will return p2m_ioreq_server type
for p2m_ioreq_server pfn, and finally change mem type through set_entry.

Fix: 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
  outstanding p2m_ioreq_server entries when an ioreq server unmaps")'

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
Signed-off-by: Yu Zhang <yu.c.zh...@linux.intel.com>
---
 xen/arch/x86/mm/p2m-ept.c |  7 +--
 xen/arch/x86/mm/p2m-pt.c  | 19 ++-
 xen/arch/x86/mm/p2m.c |  8 +---
 xen/include/asm-x86/p2m.h |  1 +
 4 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..8f88d2b 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -991,8 +991,11 @@ static mfn_t ept_get_entry(struct p2m_domain *p2m,
 
 if ( is_epte_valid(ept_entry) )
 {
-*t = p2m_recalc_type(recalc || ept_entry->recalc,
- ept_entry->sa_p2mt, p2m, gfn);
+if ( !(q & P2M_PRE_RECALC) )
+*t = p2m_recalc_type(recalc || ept_entry->recalc,
+ ept_entry->sa_p2mt, p2m, gfn);
+else
+*t = ept_entry->sa_p2mt;
 *a = ept_entry->access;
 if ( sve )
 *sve = ept_entry->suppress_ve;
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..50e74f5 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -840,8 +840,11 @@ pod_retry_l3:
 mfn = _mfn(l3e_get_pfn(*l3e) +
l2_table_offset(addr) * L1_PAGETABLE_ENTRIES +
l1_table_offset(addr));
-*t = p2m_recalc_type(recalc || _needs_recalc(flags),
- p2m_flags_to_type(flags), p2m, gfn);
+if ( !(q & P2M_PRE_RECALC) )
+*t = p2m_recalc_type(recalc || _needs_recalc(flags),
+p2m_flags_to_type(flags), p2m, gfn);
+else
+*t = p2m_flags_to_type(flags);
 unmap_domain_page(l3e);
 
 ASSERT(mfn_valid(mfn) || !p2m_is_ram(*t));
@@ -879,8 +882,11 @@ pod_retry_l2:
 if ( flags & _PAGE_PSE )
 {
 mfn = _mfn(l2e_get_pfn(*l2e) + l1_table_offset(addr));
-*t = p2m_recalc_type(recalc || _needs_recalc(flags),
- p2m_flags_to_type(flags), p2m, gfn);
+if ( !(q & P2M_PRE_RECALC) )
+*t = p2m_recalc_type(recalc || _needs_recalc(flags),
+p2m_flags_to_type(flags), p2m, gfn);
+else
+*t = p2m_flags_to_type(flags);
 unmap_domain_page(l2e);
 
 ASSERT(mfn_valid(mfn) || !p2m_is_ram(*t));
@@ -916,7 +922,10 @@ pod_retry_l1:
 return INVALID_MFN;
 }
 mfn = _mfn(l1e_get_pfn(*l1e));
-*t = p2m_recalc_type(recalc || _needs_recalc(flags), l1t, p2m, gfn);
+if ( !(q & P2M_PRE_RECALC) )
+*t = p2m_recalc_type(recalc || _needs_recalc(flags), l1t, p2m, gfn);
+else
+*t = l1t;
 unmap_domain_page(l1e);
 
 ASSERT(mfn_valid(mfn) || !p2m_is_ram(*t) || p2m_is_paging(*t));
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 1d57e5c..1c3e22f 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1020,6 +1020,8 @@ void p2m_finish_type_change(struct domain *d,
 p2m_type_t t;
 unsigned long gfn = gfn_x(first_gfn);
 unsigned long last_gfn = gfn + max_nr - 1;
+mfn_t mfn;
+p2m_access_t a;
 
 ASSERT(ot != nt);
 ASSERT(p2m_is_changeable(ot) && p2m_is_changeable(nt));
@@ -1029,10 +1031,10 @@ void p2m_finish_type_change(struct domain *d,
 last_gfn = min(last_gfn, p2m->max_mapped_pfn);
 while ( gfn <= last_gfn )
 {
-get_gfn_query_unlocked(d, gfn, );
-
+mfn = p2m->get_entry(p2m, gfn, , , P2M_PRE_RECALC, NULL, NULL);
 if ( t == ot )
-p2m_change_type_one(d, gfn, t, nt);
+p2m_set_entry(p2m, gfn, mfn, PAGE_ORDER_4K, nt,
+  p2m->default_access);
 
 gfn++;
 }
diff --git a/xen/include/asm-x86/p2m.h b/xen/in

[Xen-devel] [PATCH] x86/ioreq server: Fix DomU reboot couldn't work when using p2m_ioreq_server p2m_type

2017-05-03 Thread Xiong Zhang
'commit 1679e0df3df6 ("x86/ioreq server: asynchronously reset
outstanding p2m_ioreq_server entries")' will call
p2m_change_entry_type_global() which set entry.recalc=1. Then
the following get_entry(p2m_ioreq_server) will return
p2m_ram_rw type.
But 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
outstanding p2m_ioreq_server entries when an ioreq server unmaps")'
assume get_entry(p2m_ioreq_server) will return p2m_ioreq_server
type, then reset p2m_ioreq_server entries. The fact is the assumption
isn't true, and sysnchronously reset function couldn't work. Then
ioreq.entry_count is larger than zero after an ioreq server unmaps,
finally this results DomU reboot couldn't work.

This patch will let get_entry(p2m_ioreq_server) return
p2m_ioreq_server type instead of p2m_ram_rw type when the type of
ioreq_server entries havn't been written. The actual type change
happens in recalc funciton.

Fix: 'commit 6d774a951696 ("x86/ioreq server: synchronously reset
  outstanding p2m_ioreq_server entries when an ioreq server unmaps")'

Signed-off-by: Xiong Zhang <xiong.y.zh...@intel.com>
Signed-off-by: Yu Zhang <yu.c.zh...@linux.intel.com>
---
 xen/arch/x86/mm/p2m-ept.c | 4 
 xen/arch/x86/mm/p2m-pt.c  | 3 +++
 xen/include/asm-x86/p2m.h | 2 +-
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f37a1f2..6178046 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -546,6 +546,10 @@ static int resolve_misconfig(struct p2m_domain *p2m, 
unsigned long gfn)
 e.ipat = ipat;
 
 nt = p2m_recalc_type(e.recalc, e.sa_p2mt, p2m, gfn + i);
+if ( e.sa_p2mt == p2m_ioreq_server &&
+p2m->ioreq.server == NULL )
+nt = p2m_ram_rw;
+
 if ( nt != e.sa_p2mt )
 {
 if ( e.sa_p2mt == p2m_ioreq_server )
diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c
index 5079b59..4de500c 100644
--- a/xen/arch/x86/mm/p2m-pt.c
+++ b/xen/arch/x86/mm/p2m-pt.c
@@ -445,6 +445,9 @@ static int do_recalc(struct p2m_domain *p2m, unsigned long 
gfn)
   p2m->domain->domain_id, gfn, level);
 ot = p2m_flags_to_type(l1e_get_flags(e));
 nt = p2m_recalc_type_range(true, ot, p2m, gfn & mask, gfn | ~mask);
+if ( ot == p2m_ioreq_server && p2m->ioreq.server == NULL )
+nt = p2m_ram_rw;
+
 if ( nt != ot )
 {
 unsigned long mfn = l1e_get_pfn(e);
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 7574a9b..dde516c 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -760,7 +760,7 @@ static inline p2m_type_t p2m_recalc_type_range(bool recalc, 
p2m_type_t t,
 if ( !recalc || !p2m_is_changeable(t) )
 return t;
 
-if ( t == p2m_ioreq_server && p2m->ioreq.server != NULL )
+if ( t == p2m_ioreq_server )
 return t;
 
 return p2m_is_logdirty_range(p2m, gfn_start, gfn_end) ? p2m_ram_logdirty
-- 
2.7.4


___
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel