[Qemu-devel] [PATCH] hw/audio/intel-hda: Fix MSI capability address

2014-07-27 Thread Jan Kiszka
From: Jan Kiszka 

According to ICH9 spec, the MSI capability is located at 0x60. This is
important for guest drivers that do not parse the capability chain and
use absolute addresses instead.

Signed-off-by: Jan Kiszka 
---
 hw/audio/intel-hda.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index aa49b47..09c4118 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -1141,7 +1141,7 @@ static int intel_hda_init(PCIDevice *pci)
   "intel-hda", 0x4000);
 pci_register_bar(&d->pci, 0, 0, &d->mmio);
 if (d->msi) {
-msi_init(&d->pci, 0x50, 1, true, false);
+msi_init(&d->pci, 0x60, 1, true, false);
 }

 hda_codec_bus_init(DEVICE(pci), &d->codecs, sizeof(d->codecs),
-- 
1.8.1.1.298.ge7eed54



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH] pci: Use bus master address space for delivering MSI/MSI-X messages

2014-07-27 Thread Jan Kiszka
From: Jan Kiszka 

The spec says (and real HW confirms this) that, if the bus master bit
is 0, the device will not generate any PCI accesses. MSI and MSI-X
messages fall among these, so we should use the corresponding address
space to deliver them. This will prevent delivery if bus master support
is disabled.

Signed-off-by: Jan Kiszka 
---
 hw/pci/msi.c  | 2 +-
 hw/pci/msix.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index a4a3040..52d2313 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -291,7 +291,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
"notify vector 0x%x"
" address: 0x%"PRIx64" data: 0x%"PRIx32"\n",
vector, msg.address, msg.data);
-stl_le_phys(&address_space_memory, msg.address, msg.data);
+stl_le_phys(&dev->bus_master_as, msg.address, msg.data);
 }
 
 /* Normally called by pci_default_write_config(). */
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 5c49bfc..20ae476 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -439,7 +439,7 @@ void msix_notify(PCIDevice *dev, unsigned vector)
 
 msg = msix_get_message(dev, vector);
 
-stl_le_phys(&address_space_memory, msg.address, msg.data);
+stl_le_phys(&dev->bus_master_as, msg.address, msg.data);
 }
 
 void msix_reset(PCIDevice *dev)
-- 
1.8.1.1.298.ge7eed54



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v2 0/3] intel-iommu: introduce Intel IOMMU (VT-d) emulation to q35 chipset

2014-07-27 Thread Le Tan
Hi,

These patches are intended to introduce Intel IOMMU (VT-d) emulation to q35
chipset. The major job in these patches is to add support for emulating Intel
IOMMU according to the VT-d specification, including basic responses to CSRs
accesses, the logic of DMAR (DMA remapping) and DMA memory address
translations.

Features implemented for now are:
1. Response to important CSRs accesses;
2. DMAR (DMA remapping) without PASID support;
3. Use register-based invalidation for IOTLB and context cache invalidation;
4. Add DMAR table to ACPI tables to expose VT-d to BIOS;
5. Add "-machine iommu=on|off" option to enable/disable VT-d;
6. Only one DMAR unit for all the devices of PCI Segment 0.

Testing:
1. L1 guest with Linux with intel_iommu=on can interact with VT-d and boot
smoothly, and I can see info about VT-d in log of kernel;
2. Run L1 with VT-d, L2 guest with Linux can boot smoothly withou PCI device
passthrough;
3. Run L1 with VT-d and "-soundhw ac97 (QEMU_AUDIO_DRV=none)", then assign the
sound card to L2; L2 can boot smoothly with legacy PCI assignment;
4. Jailhouse hypervisor seems to run smoothly for now (tested by Jan).
5. Run L1 with VT-d and e1000 network card, then assign e1000 to L2; L2 will be
STUCK when booting. This still remains unsolved now. As far as I know, I suppose
that the L2 crashes when doing e1000_probe(). The QEMU of L1 will dump
something with "KVM: entry failed, hardware error 0x0", and the KVM of host
will print "nested_vmx_exit_handled failed vm entry 7". Unlike assigning the
sound card, after being assigned to L2, there is no translation entry of e1000
through VT-d, which I think means that e1000 doesn't issue any DMA access during
the boot of L2. Sometimes the kernel of L2 will print "divide error" during
booting. Can someone help me with this? Any help is appreciated! :)
6. VFIO is tested and is the same as legacy pci assignment.

I have some questions want to consult here:
1. Now the struct IntelIOMMUState is a member of MCHPCIState. VT-d is registered
as TYPE_SYS_BUS_DEVICE but registers its configuration MemoryRegion as subregion
of mch->pci_address_space. Is this correct? Another thought comes to my mind is
using sysbus_mmio_map() to map the MemoryRegion of VT-d. But I am not sure. And
maybe there are more improper usage of the QOM.
2. For declaration of porinter of pointer, like VTDAddressSpace 
**address_spaces,
checkpatch.pl will warn that "ERROR: need consistent spacing around '*' 
(ctx:WxO)".
Is checkpatch.pl wrong?

TODO:
1. Fix the bug of legacy PCI assignment;
2. Clear up codes related to migration.
3. Queued Invalidation;
4. Basic fault reporting;
5. Caching propertities of IOTLB;

Changes since v1:
*address reviewing suggestions given by Michael, Paolo, Stefan and Jan
-split intel_iommu.h to include/hw/i386/intel_iommu.h and
 hw/i386/intel_iommu_internal.h
-change the copyright information
-change D() to VTD_DPRINTF()
-remove dead code
-rename constant definitions with consistent prefix VTD_
-rename some struct definitions according to QEMU standard
-rename some CSRs access functions
-use endian-save functions to access CSRs
-change machine option to "iommu=on|off"

Thanks very much!

Git trees:
https://github.com/tamlok/qemu

Le Tan (3):
  intel-iommu: introduce Intel IOMMU (VT-d) emulation
  intel-iommu: add DMAR table to ACPI tables
  intel-iommu: add Intel IOMMU emulation to q35 and add a machine option
"iommu" as a switch

 hw/core/machine.c  |  27 +-
 hw/i386/Makefile.objs  |   1 +
 hw/i386/acpi-build.c   |  41 ++
 hw/i386/acpi-defs.h|  70 
 hw/i386/intel_iommu.c  | 911 +
 hw/i386/intel_iommu_internal.h | 257 
 hw/pci-host/q35.c  |  72 +++-
 include/hw/boards.h|   1 +
 include/hw/i386/intel_iommu.h  |  75 
 include/hw/pci-host/q35.h  |   2 +
 qemu-options.hx|   5 +-
 vl.c   |   4 +
 12 files changed, 1457 insertions(+), 9 deletions(-)
 create mode 100644 hw/i386/intel_iommu.c
 create mode 100644 hw/i386/intel_iommu_internal.h
 create mode 100644 include/hw/i386/intel_iommu.h

-- 
1.9.1




[Qemu-devel] [PATCH v2 1/3] intel-iommu: introduce Intel IOMMU (VT-d) emulation

2014-07-27 Thread Le Tan
Add support for emulating Intel IOMMU according to the VT-d specification for
the q35 chipset machine. Implement the logic for DMAR (DMA remapping) without
PASID support. Use register-based invalidation for context-cache invalidation
and IOTLB invalidation.
Basic fault reporting and caching are not implemented yet.

Signed-off-by: Le Tan 
---
 hw/i386/Makefile.objs  |   1 +
 hw/i386/intel_iommu.c  | 911 +
 hw/i386/intel_iommu_internal.h | 257 
 include/hw/i386/intel_iommu.h  |  75 
 4 files changed, 1244 insertions(+)
 create mode 100644 hw/i386/intel_iommu.c
 create mode 100644 hw/i386/intel_iommu_internal.h
 create mode 100644 include/hw/i386/intel_iommu.h

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 48014ab..6936111 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -2,6 +2,7 @@ obj-$(CONFIG_KVM) += kvm/
 obj-y += multiboot.o smbios.o
 obj-y += pc.o pc_piix.o pc_q35.o
 obj-y += pc_sysfw.o
+obj-y += intel_iommu.o
 obj-$(CONFIG_XEN) += ../xenpv/ xen/
 
 obj-y += kvmvapic.o
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
new file mode 100644
index 000..718993a
--- /dev/null
+++ b/hw/i386/intel_iommu.c
@@ -0,0 +1,911 @@
+/*
+ * QEMU emulation of an Intel IOMMU (VT-d)
+ *   (DMA Remapping device)
+ *
+ * Copyright (C) 2013 Knut Omang, Oracle 
+ * Copyright (C) 2014 Le Tan, 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see .
+ */
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "intel_iommu_internal.h"
+
+
+/*#define DEBUG_INTEL_IOMMU*/
+#ifdef DEBUG_INTEL_IOMMU
+#define VTD_DPRINTF(fmt, ...) \
+do { fprintf(stderr, "(vtd)%s: " fmt "\n", __func__, \
+ ## __VA_ARGS__); } while (0)
+#else
+#define VTD_DPRINTF(fmt, ...) \
+do { } while (0)
+#endif
+
+static inline void define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val,
+   uint64_t wmask, uint64_t w1cmask)
+{
+stq_le_p(&s->csr[addr], val);
+stq_le_p(&s->wmask[addr], wmask);
+stq_le_p(&s->w1cmask[addr], w1cmask);
+}
+
+static inline void define_quad_wo(IntelIOMMUState *s, hwaddr addr,
+  uint64_t mask)
+{
+stq_le_p(&s->womask[addr], mask);
+}
+
+static inline void define_long(IntelIOMMUState *s, hwaddr addr, uint32_t val,
+   uint32_t wmask, uint32_t w1cmask)
+{
+stl_le_p(&s->csr[addr], val);
+stl_le_p(&s->wmask[addr], wmask);
+stl_le_p(&s->w1cmask[addr], w1cmask);
+}
+
+static inline void define_long_wo(IntelIOMMUState *s, hwaddr addr,
+  uint32_t mask)
+{
+stl_le_p(&s->womask[addr], mask);
+}
+
+/* "External" get/set operations */
+static inline void set_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val)
+{
+uint64_t oldval = ldq_le_p(&s->csr[addr]);
+uint64_t wmask = ldq_le_p(&s->wmask[addr]);
+uint64_t w1cmask = ldq_le_p(&s->w1cmask[addr]);
+stq_le_p(&s->csr[addr],
+ ((oldval & ~wmask) | (val & wmask)) & ~(w1cmask & val));
+}
+
+static inline void set_long(IntelIOMMUState *s, hwaddr addr, uint32_t val)
+{
+uint32_t oldval = ldl_le_p(&s->csr[addr]);
+uint32_t wmask = ldl_le_p(&s->wmask[addr]);
+uint32_t w1cmask = ldl_le_p(&s->w1cmask[addr]);
+stl_le_p(&s->csr[addr],
+ ((oldval & ~wmask) | (val & wmask)) & ~(w1cmask & val));
+}
+
+static inline uint64_t get_quad(IntelIOMMUState *s, hwaddr addr)
+{
+uint64_t val = ldq_le_p(&s->csr[addr]);
+uint64_t womask = ldq_le_p(&s->womask[addr]);
+return val & ~womask;
+}
+
+
+static inline uint32_t get_long(IntelIOMMUState *s, hwaddr addr)
+{
+uint32_t val = ldl_le_p(&s->csr[addr]);
+uint32_t womask = ldl_le_p(&s->womask[addr]);
+return val & ~womask;
+}
+
+/* "Internal" get/set operations */
+static inline uint64_t get_quad_raw(IntelIOMMUState *s, hwaddr addr)
+{
+return ldq_le_p(&s->csr[addr]);
+}
+
+static inline uint32_t get_long_raw(IntelIOMMUState *s, hwaddr addr)
+{
+return ldl_le_p(&s->csr[addr]);
+}
+
+static inline uint32_t set_clear_mask_long(IntelIOMMUState *s, hwaddr addr,
+   uint32_t clear, uint32_t mask)
+{
+uint32_t new_val = (ldl_le_p(&s->csr[addr]) & ~clear) | mask;
+stl_le_p(&s->csr[addr], new_val);
+return new_val;
+}
+
+static inline uint64_t set_

[Qemu-devel] [PATCH v2 2/3] intel-iommu: add DMAR table to ACPI tables

2014-07-27 Thread Le Tan
Expose Intel IOMMU to the BIOS. If object of TYPE_INTEL_IOMMU_DEVICE exists,
add DMAR table to ACPI RSDT table. For now the DMAR table indicates that there
is only one hardware unit without INTR_REMAP capability on the platform.

Signed-off-by: Le Tan 
---
 hw/i386/acpi-build.c | 41 ++
 hw/i386/acpi-defs.h  | 70 
 2 files changed, 111 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ebc5f03..8241621 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -45,6 +45,7 @@
 #include "hw/i386/ich9.h"
 #include "hw/pci/pci_bus.h"
 #include "hw/pci-host/q35.h"
+#include "hw/i386/intel_iommu.h"
 
 #include "hw/i386/q35-acpi-dsdt.hex"
 #include "hw/i386/acpi-dsdt.hex"
@@ -1316,6 +1317,31 @@ build_mcfg_q35(GArray *table_data, GArray *linker, 
AcpiMcfgInfo *info)
 }
 
 static void
+build_dmar_q35(GArray *table_data, GArray *linker)
+{
+int dmar_start = table_data->len;
+
+AcpiTableDmar *dmar;
+AcpiDmarHardwareUnit *drhd;
+
+dmar = acpi_data_push(table_data, sizeof(*dmar));
+dmar->host_address_width = 0x26;/* 0x26 + 1 = 39 */
+dmar->flags = 0;/* No intr_remap for now */
+
+/* DMAR Remapping Hardware Unit Definition structure */
+drhd = acpi_data_push(table_data, sizeof(*drhd));
+drhd->type = cpu_to_le16(ACPI_DMAR_TYPE_HARDWARE_UNIT);
+drhd->length = cpu_to_le16(sizeof(*drhd));   /* No device scope now */
+drhd->flags = ACPI_DMAR_INCLUDE_PCI_ALL;
+drhd->pci_segment = cpu_to_le16(0);
+drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);
+
+build_header(linker, table_data, (void *)(table_data->data + dmar_start),
+ "DMAR", table_data->len - dmar_start, 1);
+}
+
+
+static void
 build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
 {
 AcpiTableHeader *dsdt;
@@ -1436,6 +1462,17 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 return true;
 }
 
+static bool acpi_has_iommu(void)
+{
+bool ambiguous;
+Object *intel_iommu;
+
+intel_iommu = object_resolve_path_type("", TYPE_INTEL_IOMMU_DEVICE,
+   &ambiguous);
+return intel_iommu && !ambiguous;
+}
+
+
 static
 void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
 {
@@ -1497,6 +1534,10 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables 
*tables)
 acpi_add_table(table_offsets, tables->table_data);
 build_mcfg_q35(tables->table_data, tables->linker, &mcfg);
 }
+if (acpi_has_iommu()) {
+acpi_add_table(table_offsets, tables->table_data);
+build_dmar_q35(tables->table_data, tables->linker);
+}
 
 /* Add tables supplied by user (if any) */
 for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
index e93babb..9674825 100644
--- a/hw/i386/acpi-defs.h
+++ b/hw/i386/acpi-defs.h
@@ -314,4 +314,74 @@ struct AcpiTableMcfg {
 } QEMU_PACKED;
 typedef struct AcpiTableMcfg AcpiTableMcfg;
 
+/* DMAR - DMA Remapping table r2.2 */
+struct AcpiTableDmar {
+ACPI_TABLE_HEADER_DEF
+uint8_t host_address_width; /* Maximum DMA physical addressability */
+uint8_t flags;
+uint8_t reserved[10];
+} QEMU_PACKED;
+typedef struct AcpiTableDmar AcpiTableDmar;
+
+/* Masks for Flags field above */
+#define ACPI_DMAR_INTR_REMAP(1)
+#define ACPI_DMAR_X2APIC_OPT_OUT(2)
+
+/*
+ * DMAR sub-structures (Follow DMA Remapping table)
+ */
+#define ACPI_DMAR_SUB_HEADER_DEF /* Common ACPI DMAR sub-structure header */\
+uint16_t type;  \
+uint16_t length;
+
+/* Values for sub-structure type for DMAR */
+enum {
+ACPI_DMAR_TYPE_HARDWARE_UNIT = 0,   /* DRHD */
+ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, /* RMRR */
+ACPI_DMAR_TYPE_ATSR = 2,/* ATSR */
+ACPI_DMAR_TYPE_HARDWARE_AFFINITY = 3,   /* RHSR */
+ACPI_DMAR_TYPE_ANDD = 4,/* ANDD */
+ACPI_DMAR_TYPE_RESERVED = 5 /* Reserved for furture use */
+};
+
+/*
+ * Sub-structures for DMAR, correspond to Type in ACPI_DMAR_SUB_HEADER_DEF
+ */
+
+/* DMAR Device Scope structures */
+struct AcpiDmarDeviceScope {
+uint8_t type;
+uint8_t length;
+uint16_t reserved;
+uint8_t enumeration_id;
+uint8_t start_bus_number;
+uint8_t path[0];
+} QEMU_PACKED;
+typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope;
+
+/* Values for type in struct AcpiDmarDeviceScope */
+enum {
+ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,
+ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1,
+ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
+ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
+ACPI_DMAR_SCOPE_TYPE_HPET = 4,
+ACPI_DMAR_SCOPE_TYPE_ACPI = 5,
+ACPI_DMAR_SCOPE_TYPE_RESERVED = 6 /* Reserved for future use */
+};
+
+/* 0: Hardware Unit Definition */
+struct AcpiDmarHardwareUnit {
+ACPI_DMAR_SUB_HEADER_DEF
+uint8_t flags;
+uint8_t reserved;
+uint16_t pci_segment;   /* The PCI Segment associated with this unit */
+uint64_t address;   /* Base add

[Qemu-devel] [PATCH v2 3/3] intel-iommu: add Intel IOMMU emulation to q35 and add a machine option "iommu" as a switch

2014-07-27 Thread Le Tan
Add Intel IOMMU emulation to q35 chipset and expose it to the guest.
1. Add a machine option. Users can use "-machine iommu=on|off" in the command
line to enable/disable Intel IOMMU. The default is off.
2. Accroding to the machine option, q35 will initialize the Intel IOMMU and
use pci_setup_iommu() to setup q35_host_dma_iommu() as the IOMMU function for
the pci bus.
3. q35_host_dma_iommu() will return different address space according to the
bus_num and devfn of the device.

Signed-off-by: Le Tan 
---
 hw/core/machine.c | 27 --
 hw/pci-host/q35.c | 72 +++
 include/hw/boards.h   |  1 +
 include/hw/pci-host/q35.h |  2 ++
 qemu-options.hx   |  5 +++-
 vl.c  |  4 +++
 6 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index cbba679..9b166e5 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -235,6 +235,20 @@ static void machine_set_firmware(Object *obj, const char 
*value, Error **errp)
 ms->firmware = g_strdup(value);
 }
 
+static bool machine_get_iommu(Object *obj, Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+return ms->iommu;
+}
+
+static void machine_set_iommu(Object *obj, bool value, Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+ms->iommu = value;
+}
+
 static void machine_initfn(Object *obj)
 {
 object_property_add_str(obj, "accel",
@@ -270,10 +284,17 @@ static void machine_initfn(Object *obj)
  machine_set_dump_guest_core,
  NULL);
 object_property_add_bool(obj, "mem-merge",
- machine_get_mem_merge, machine_set_mem_merge, 
NULL);
-object_property_add_bool(obj, "usb", machine_get_usb, machine_set_usb, 
NULL);
+ machine_get_mem_merge,
+ machine_set_mem_merge, NULL);
+object_property_add_bool(obj, "usb",
+ machine_get_usb,
+ machine_set_usb, NULL);
 object_property_add_str(obj, "firmware",
-machine_get_firmware, machine_set_firmware, NULL);
+machine_get_firmware,
+machine_set_firmware, NULL);
+object_property_add_bool(obj, "iommu",
+ machine_get_iommu,
+ machine_set_iommu, NULL);
 }
 
 static void machine_finalize(Object *obj)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index a0a3068..4abd0ee 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -347,6 +347,61 @@ static void mch_reset(DeviceState *qdev)
 mch_update(mch);
 }
 
+static AddressSpace *q35_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
+{
+IntelIOMMUState *s = opaque;
+VTDAddressSpace **pvtd_as;
+VTDAddressSpace *vtd_as;
+int bus_num = pci_bus_num(bus);
+
+assert(devfn >= 0);
+
+pvtd_as = s->address_spaces[bus_num];
+if (!pvtd_as) {
+/* No corresponding free() */
+pvtd_as = g_malloc0(sizeof(VTDAddressSpace *) *
+VTD_PCI_SLOT_MAX * VTD_PCI_FUNC_MAX);
+s->address_spaces[bus_num] = pvtd_as;
+}
+
+vtd_as = *(pvtd_as + devfn);
+if (!vtd_as) {
+vtd_as = g_malloc0(sizeof(*vtd_as));
+*(pvtd_as + devfn) = vtd_as;
+
+vtd_as->bus_num = bus_num;
+vtd_as->devfn = devfn;
+vtd_as->iommu_state = s;
+memory_region_init_iommu(&vtd_as->iommu, OBJECT(s), &s->iommu_ops,
+ "intel_iommu", UINT64_MAX);
+address_space_init(&vtd_as->as, &vtd_as->iommu, "intel_iommu");
+}
+
+return &vtd_as->as;
+}
+
+static void mch_init_dmar(MCHPCIState *mch)
+{
+Error *error = NULL;
+PCIBus *pci_bus = PCI_BUS(qdev_get_parent_bus(DEVICE(mch)));
+
+mch->iommu = INTEL_IOMMU_DEVICE(object_new(TYPE_INTEL_IOMMU_DEVICE));
+qdev_set_parent_bus(DEVICE(mch->iommu), sysbus_get_default());
+object_property_set_bool(OBJECT(mch->iommu), true, "realized", &error);
+
+if (error) {
+fprintf(stderr, "%s\n", error_get_pretty(error));
+error_free(error);
+return;
+}
+
+memory_region_add_subregion(mch->pci_address_space,
+Q35_HOST_BRIDGE_IOMMU_ADDR,
+&mch->iommu->csrmem);
+pci_setup_iommu(pci_bus, q35_host_dma_iommu, mch->iommu);
+}
+
+
 static int mch_init(PCIDevice *d)
 {
 int i;
@@ -363,13 +418,20 @@ static int mch_init(PCIDevice *d)
 memory_region_add_subregion_overlap(mch->system_memory, 0xa,
 &mch->smram_region, 1);
 memory_region_set_enabled(&mch->smram_region, false);
-init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, 
mch->pci_address_space,
- &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);
+init_pam(DEVICE(mch), mch->ram_memory

Re: [Qemu-devel] [PATCH] [RFC] Add machine type pc-1.0-qemu-kvm for live migrate compatibility with qemu-kvm

2014-07-27 Thread Alex Bligh

On 22 Jul 2014, at 19:43, Alex Bligh  wrote:

> I have not (yet) brought forward the qxl rom size (and possibly
> video ram) changes in Cole's patches as I'd prefer an assessment
> of whether this is the right approach first.

Whilst vga=cirrus, and vga=none I appear to be able to get to work,
I suspect the QXL problem is unfixable.

The symptom on import is:
  Unknown ramblock ":00:02.0/virtio-net-pci.rom", cannot accept migration

A little debugging and this shows that the expected RAM blocks on load are
(just looking at the ones starting :00):
   :00:02.0/qxl.vram
   :00:02.0/qxl.rom
   :00:03.0/virtio-net-pci.rom
   :00:02.0/qxl.vrom

note the 03 in virtio-net-pci.rom, not an 02.

Looking at the migrated file (from qemu-kvm-1.0 with a pc-1.0 machine type)
with 'strings', I see:
   :00:02.0/virtio-net-pci.rom
   :00:00.0/I440FX
   :00:01.0/PIIX3
   :00:02.0/virtio-net
   :00:01.1/ide
   :00:01.2/uhci
   :00:01.3/piix4_pm
   :00:03.0/virtio-blk

A migrated file (from qemu 2.0 with a pc-1.0-qemu-kvm machine type) has
   :00:02.0/qxl.vram
   :00:03.0/virtio-net-pci.rom
   :00:02.0/qxl.rom
   :00:02.0/qxl.vrom
   :00:00.0/I440FX
   :00:01.0/PIIX3
   :00:02.0/qxl
   :00:03.0/virtio-net
   :00:01.1/ide
   :00:01.2/uhci
   :00:01.3/piix4_pm
   :00:04.0/virtio-blk

The symptom is the result of the assignment of device number 03 to
virtio-net, as (it would seem) qxl does not actually have a pci
device id in qemu-kvm-1.0 (or at least not one making it to migration);
I'm assuming the names are PCI BDF. Hence virtio-net is getting
device ID 02 not 03.

QXL does appear to migrate qemu-kvm-1.0 to qemu-kvm-1.0. I'm guessing
that once upon a time QXL was not a PCI device, but it is now.

For once I don't think Cole Robinson's patch is going to help here
as this seems to be handling QXL rom size mismatches between 8k
and 16k, and the QXL romsize (on both ubuntu 12.04 and 14.04 is
well over 32k) so that looks like not the issue.

I suspect QXL on qemu-kvm-1.0 is a bit niche anyway.

-- 
Alex Bligh







Re: [Qemu-devel] [PATCH] [RFC] Add machine type pc-1.0-qemu-kvm for live migrate compatibility with qemu-kvm

2014-07-27 Thread Andreas Färber
Hi Alex,

+ quintela, mst, libvirt

Am 22.07.2014 20:43, schrieb Alex Bligh:
> Add a machine type pc-1.0-qemu-kvm for live migrate compatibility
> with qemu-kvm version 1.0.
> 
> Signed-off-by: Alex Bligh 
> ---
>  hw/acpi/piix4.c  |   49 
> --
>  hw/i386/pc_piix.c|   31 +
>  hw/timer/i8254_common.c  |   41 ++
>  include/hw/acpi/piix4.h  |1 +
>  include/hw/timer/i8254.h |2 ++
>  5 files changed, 122 insertions(+), 2 deletions(-)
> 
> This RFC patch adds inbound migrate capability from qemu-kvm version
> 1.0. The main ideas are those set out in Cole Robinson's patch here:
> http://pkgs.fedoraproject.org/cgit/qemu.git/tree/0001-Fix-migration-from-qemu-kvm.patch?h=f20
> however, rather than patching statically (and breaking inbound
> migration on existing machine types), I have added a new machine
> type (pc-1.0-qemu-kvm) without affecting any other machine types.

This sounds like a really cool feature that SUSE would probably be
interested in extending back to 0.14 and 0.15, but I see a fundamental
flaw: libvirt on those old source systems does not know it should use a
different machine name on the destination side and would still use
pc-1.0, wouldn't it? After all, it needs to be able to migrate to other
old qemu-kvm machines, so it can't just be updated to use the new name.

Minor bikeshedding: I would ask to keep the package name in front of the
machine version, e.g. qemu-kvm-pc-1.0. Or just kvm-pc-1.0 since this is
a QEMU parameter anyway.

Haven't reviewed the code in detail yet.

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



Re: [Qemu-devel] [PATCH] [RFC] Add machine type pc-1.0-qemu-kvm for live migrate compatibility with qemu-kvm

2014-07-27 Thread Alex Bligh
Andreas,

On 27 Jul 2014, at 15:10, Andreas Färber  wrote:

> Hi Alex,
> 
> + quintela, mst, libvirt

Thanks for your comments!

> This sounds like a really cool feature that SUSE would probably be
> interested in extending back to 0.14 and 0.15, but I see a fundamental
> flaw: libvirt on those old source systems does not know it should use a
> different machine name on the destination side and would still use
> pc-1.0, wouldn't it? After all, it needs to be able to migrate to other
> old qemu-kvm machines, so it can't just be updated to use the new name.

Right. I'm not using libvirt but face a similar problem. The destination
libvirt (or equivalent) now has two 'pc-1.0' machine types. One (allegedly)
use by qemu-git 1.0, and one used by qemu-kvm 1.0. The name 'pc-1.0' needs
to refer to exactly one of these (obviously), and it currently refers
to qemu-git 1.0, so I've left it that way.

In a distribution environment where qemu-1.0 was never used, one might
want to make my new machine type called 'pc-1.0' and the existing qemu.git
pc-1.0 called 'pc-1.0-qemu-git' or similar.

Why don't I just change it? Well, imagine someone running Ubuntu 13.04 (say)
which shipped with an early post merge qemu made a machine with machine type
pc-1.0. Despite the fact that Ubuntu 12.04 was shipped with qemu-kvm (and
hence -m pc-1.0 there meant qemu-kvm's pc-1.0), on 13.04, this would mean
qemu-git's pc-1.0, and changing the name would break the migration of an
Ubuntu 13.04 pc-1.0 machine, whilst fixing migration of a 12.04 pc-1.0
machine. Let no one say this isn't a mess.

So, I'm expect whatever generates the qemu command line to know (from the
other end) whether to use the different version.

Perhaps a slightly nicer fix, if somewhat rococo, would be:
* Use pc-1.0-qemu-kvm as one machine name
* Use pc-1.0-qemu-git as another machine name
* Make pc-1.0 an alias of either one or the other, configurable at the
  command line, and subject to a build-time default.

This would let distributions / users simply decide which kind of pc-1.0
migration they'd like by working by default, and which they'd like
broken; the broken one is a second class citizen which can only
handle migration by changing the qemu command line appropriately.

This would perhaps make things more transparent by default.

BTW I would agree this is a significant issue, having spent quite a lot
of today playing with stuff that (mis)parses "qemu -version"

Also BTW, I did wonder whether I could autodetect this from the stream.
However, as it has to be read serially, by the time you know it's wrong,
you are too late AFAICT. Useful suggestion in case of future accidental
breakage: put the qemu version in a section right up top.

> Minor bikeshedding: I would ask to keep the package name in front of the
> machine version, e.g. qemu-kvm-pc-1.0. Or just kvm-pc-1.0 since this is
> a QEMU parameter anyway.

Obviously not a matter of great import, but per the list
below, the standard appears to be 'pc-(arch)?-version'
and I'd taken this as a subversion.

# qemu-system-x86_64 -machine '?'
Supported machines are:
pc-0.13  Standard PC (i440FX + PIIX, 1996)
pc-i440fx-2.0Standard PC (i440FX + PIIX, 1996)
pc-1.0   Standard PC (i440FX + PIIX, 1996)
pc-q35-1.7   Standard PC (Q35 + ICH9, 2009)
pc-1.1   Standard PC (i440FX + PIIX, 1996)
q35  Standard PC (Q35 + ICH9, 2009) (alias of pc-q35-2.0)
pc-q35-2.0   Standard PC (Q35 + ICH9, 2009)
pc-i440fx-1.4Standard PC (i440FX + PIIX, 1996)
pc-i440fx-1.5Standard PC (i440FX + PIIX, 1996)
pc-0.14  Standard PC (i440FX + PIIX, 1996)
pc-0.15  Standard PC (i440FX + PIIX, 1996)
xenfvXen Fully-virtualized PC
pc-q35-1.4   Standard PC (Q35 + ICH9, 2009)
isapcISA-only PC
pc-0.10  Standard PC (i440FX + PIIX, 1996)
pc   Ubuntu 14.04 PC (i440FX + PIIX, 1996) (alias of 
pc-i440fx-trusty)
pc-i440fx-trusty Ubuntu 14.04 PC (i440FX + PIIX, 1996) (default)
pc-1.2   Standard PC (i440FX + PIIX, 1996)
pc-0.11  Standard PC (i440FX + PIIX, 1996)
pc-i440fx-1.7Standard PC (i440FX + PIIX, 1996)
pc-i440fx-1.6Standard PC (i440FX + PIIX, 1996)
none empty machine
xenpvXen Para-virtualized PC
pc-q35-1.5   Standard PC (Q35 + ICH9, 2009)
pc-1.0-qemu-kvm  Standard PC (i440FX + PIIX, 1996)
pc-q35-1.6   Standard PC (Q35 + ICH9, 2009)
pc-0.12  Standard PC (i440FX + PIIX, 1996)
pc-1.3   Standard PC (i440FX + PIIX, 1996)

-- 
Alex Bligh







Re: [Qemu-devel] [PATCH] [RFC] Add machine type pc-1.0-qemu-kvm for live migrate compatibility with qemu-kvm

2014-07-27 Thread Alex Bligh

On 22 Jul 2014, at 19:43, Alex Bligh  wrote:

> Testing has been light to date (i.e.
> can I migrate it inbound with -S without anything complaining).

I've given this quite a bit more testing today.

It works fine qemu-kvm 1.0 -> qemu-2.0+patch (cirrus vga)
It works fine qemu-2.0+patch -> qemu-2.0+patch (cirrus vga)
It doesn't (yet) work qemu-2.0+patch -> qemu-kvm 1.0 (cirrus vga).

The reason for this is (at least) that I need to emulate the
broken versioning of the mc146818rtc timer section, as writing
it correctly confuses qemu-kvm 1.0. Therefore please don't bother
testing migration back to 1.0 yet.

-- 
Alex Bligh







Re: [Qemu-devel] [PATCH v3 1/7] bootindex: add modify_boot_device_path function

2014-07-27 Thread Gonglei (Arei)
> -Original Message-
> From: 陈梁 [mailto:chenliang0...@icloud.com]
> Sent: Sunday, July 27, 2014 11:51 AM
> Subject: Re: [Qemu-devel] [PATCH v3 1/7] bootindex: add
> modify_boot_device_path function
> 
> Hi
> > +if (bootindex >= 0) {
> > +node = g_malloc0(sizeof(FWBootEntry));
> > +node->bootindex = bootindex;
> > +if (suffix) {
> > +node->suffix = g_strdup(suffix);
> > +} else if (old_entry) {
> > +node->suffix = g_strdup(old_entry->suffix);
> > +} else {
> > +node->suffix = NULL;
> > +}
> > +node->dev = dev;
> > +
> > +/* add to the global boot list */
> > +QTAILQ_FOREACH(i, &fw_boot_order, link) {
> > +if (i->bootindex < bootindex) {
> > +continue;
> > +}
> > +QTAILQ_INSERT_BEFORE(i, node, link);
> > +goto out;
> > +}
> > +
> > +QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
> > +}
> 
> this code can be simply like this:
> 
> suffix = suffix ? suffix : old_entry->suffix ? old_entry->suffix : NULL;
> 
> add_boot_device_path(boot_index, dev, suffix)
> 
Nice, thanks.

Best regards,
-Gonglei



[Qemu-devel] [qemu-devel] Is sse2 implemented with host hardware support ?

2014-07-27 Thread 邓尧
Hello,

I need to optimize a Linux program running under qemu-system-i386. qemu is
compiled with KVM support. File /proc/cpuinfo in the guest shows that SSE2
is supported.
If SSE2 is backed with host hardware, using SSE2 may improve my program's
performance significantly. The host is x86_64 Linux.
My question is: whether sse2 is backed with host hardware ? If it is, how
much overhead does an SSE2 instruction have ? (comparing with an SSE2
instruction on the host)

Thanks
Yao


Re: [Qemu-devel] Possible null-ptr dereference

2014-07-27 Thread Gonglei (Arei)
Hi,

Should be easy to fix though. Does the following help?

(Cc'ing Stefan & Kevin)

-->
xen_disk:  fix possible null-ptr dereference

Signed-off-by: Gonglei 
---
hw/block/xen_disk.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index aed5b5b..a221d0b 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -589,6 +589,7 @@ static int blk_send_response_one(struct ioreq *ioreq)
 break;
 default:
 dst = NULL;
+return 0;
 }
 memcpy(dst, &resp, sizeof(resp));
 blkdev->rings.common.rsp_prod_pvt++;
--

Best regards,
-Gonglei

From: qemu-devel-bounces+arei.gonglei=huawei@nongnu.org 
[mailto:qemu-devel-bounces+arei.gonglei=huawei@nongnu.org] On Behalf Of 
mateusz.krzywi...@windowslive.com
Sent: Saturday, July 26, 2014 6:52 PM
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] Possible null-ptr dereference

Hey,

Found a little bug in latest qemu:

In function:
static int blk_send_response_one(struct ioreq *ioreq)

File:
qemu\hw\block\xen_disk.c

Code:

default:
dst = NULL;
}
memcpy(dst, &resp, sizeof(resp));


Just add simple check for dst and it will be all cool ;-)

Best regards,
Mateusz Krzywicki


Re: [Qemu-devel] [Qemu-ppc] [PATCH for-2.2] spapr: add host Linux version information to device tree

2014-07-27 Thread Alexey Kardashevskiy
On 07/24/2014 11:15 PM, Alexander Graf wrote:
> 
> On 18.07.14 06:31, cyril...@gmail.com wrote:
>> It may prove useful know which Linux distribution version the host machine
>> is running when an issue in the guest arises but a user cannot access
>> the host.
>>
>> Signed-off-by: Cyril Bur 
>> ---
>>   hw/ppc/spapr.c   |  8 +++
>>   target-ppc/kvm.c | 62
>> 
>>   target-ppc/kvm_ppc.h |  6 +
>>   3 files changed, 76 insertions(+)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index 6b48a26..391d47a 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -375,6 +375,14 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
>>   _FDT((fdt_property_string(fdt, "vm,uuid", buf)));
>>   g_free(buf);
>>   +/*
>> + * Add info to the guest FDT to tell it what linux the host is
>> + */
>> +if (kvmppc_get_linux_host(&buf)) {
>> +_FDT((fdt_property_string(fdt, "linux,host", buf)));
> 
> Is this even specified in sPAPR?


PAPR does not know about any "linux,xxx" properties.

> 
>> +g_free(buf);
>> +}
>> +
>>   _FDT((fdt_property_cell(fdt, "#address-cells", 0x2)));
>>   _FDT((fdt_property_cell(fdt, "#size-cells", 0x2)));
>>   diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
>> index 8c9e79c..95e0970 100644
>> --- a/target-ppc/kvm.c
>> +++ b/target-ppc/kvm.c
>> @@ -1415,6 +1415,68 @@ bool kvmppc_get_host_model(char **value)
>>   return g_file_get_contents("/proc/device-tree/model", value, NULL,
>> NULL);
>>   }
>>   +bool kvmppc_get_linux_host(char **value)
>> +{
>> +FILE *f;
>> +int i;
>> +char line[512];
>> +const char *names[] = {"NAME", "VERSION", "BUILD_ID"};
>> +bool names_found[ARRAY_SIZE(names)] = { 0 };
>> +GString *output = NULL;
>> +f = fopen("/etc/os-release", "r");
> 
> A few comments:
> 
>   1) Why would anyone care?


Useful debug info when the host is not reachable.


>   2) I'm not sure KVM is the right decision maker on whether we want this
> exposed or not.

Good point, there is no reason not to show this info in TCG.

> After all, the files you read here are available on an x86
> host just as well

Does qemu-x86 has any way to pass information like this to the guest?


>   3) Use glib functions to read files
> 
> 
> Alex
> 
> 


-- 
Alexey