Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term

2015-01-29 Thread Shannon Zhao
On 2015/1/22 22:50, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov 
> ---
>  hw/acpi/acpi-build-utils.c | 47 
> ++
>  hw/i386/acpi-build.c   |  1 -
>  include/hw/acpi/acpi-build-utils.h |  8 +++
>  3 files changed, 55 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> index b19d370..58f88cd 100644
> --- a/hw/acpi/acpi-build-utils.c
> +++ b/hw/acpi/acpi-build-utils.c
> @@ -26,6 +26,7 @@
>  #include 
>  #include "hw/acpi/acpi-build-utils.h"
>  #include "qemu/bswap.h"
> +#include "hw/acpi/bios-linker-loader.h"
>  
>  GArray *build_alloc_array(void)
>  {
> @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
>  build_prepend_int(child.buf, child.buf->len);
>  build_package(child.buf, child.op);
>  break;
> +case DEF_BLOCK: {
> +uint8_t *start = (uint8_t *)parent_ctx->buf->data +
> + parent_ctx->buf->len;
> +uint32_t le32_len = cpu_to_le32(child.buf->len);
> +
> +/* create linker entry for the DefinitionBlock */
> +bios_linker_loader_add_checksum(parent_ctx->linker,
> +ACPI_BUILD_TABLE_FILE,
> +parent_ctx->buf->data,
> +start, child.buf->len, start + 9 /* checksum offset */);
> +
> +/* set DefinitionBlock length at TableLength offset*/
> +memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
> +break;
> +}
>  default:
>  break;
>  }
> @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed 
> min_fixed,
>dec, addr_gran, addr_min, addr_max,
>addr_trans, len, flags);
>  }
> +
> +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
> +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> +   const char *oem_id, const char *oem_table_id,
> +   uint32_t oem_revision)
> +{
> +int len;
> +AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
> +
> +assert(strlen(signature) == 4);
> +g_array_append_vals(var.buf, signature, 4);
> +build_append_value(var.buf, 0, 4); /* Length place holder */
> +build_append_byte(var.buf, revision);
> +build_append_byte(var.buf, 0); /* place holder for Checksum */
> +
> +len = strlen(oem_id);
> +assert(len <= 6);
> +g_array_append_vals(var.buf, oem_id, len);
> +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
> +
> +len = strlen(oem_table_id);
> +assert(len <= 8);
> +g_array_append_vals(var.buf, oem_table_id, len);
> +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
> +
> +build_append_value(var.buf, oem_revision, 4);
> +g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id 
> */
> +build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
> +
> +return var;
> +}

This function is similar with build_header() in hw/i386/acpi-build.c
But the format of omt_id, oem_table_id, asl_compiler_id are not exactly same.
Maybe we should make it consistent.


> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 4572c21..9ff8d72 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -270,7 +270,6 @@ static void acpi_get_pci_info(PcPciInfo *info)
>  #define ACPI_BUILD_APPNAME6 "BOCHS "
>  #define ACPI_BUILD_APPNAME4 "BXPC"
>  
> -#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
>  #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
>  #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
>  
> diff --git a/include/hw/acpi/acpi-build-utils.h 
> b/include/hw/acpi/acpi-build-utils.h
> index 5e8db3d..868d439 100644
> --- a/include/hw/acpi/acpi-build-utils.h
> +++ b/include/hw/acpi/acpi-build-utils.h
> @@ -11,12 +11,17 @@ typedef enum {
>  EXT_PACKAGE,
>  BUFFER,
>  RES_TEMPLATE,
> +DEF_BLOCK,
>  } AcpiBlockFlags;
>  
> +#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
> +#define ACPI_BUILD_APPNAME4 "BXPC"
> +
>  typedef struct AcpiAml {
>  GArray *buf;
>  uint8_t op;
>  AcpiBlockFlags block_flags;
> +GArray *linker;
>  } AcpiAml;
>  
>  typedef enum {
> @@ -146,6 +151,9 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed 
> min_fixed,
>uint64_t len);
>  
>  /* Block ASL object primitives */
> +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> +   const char *oem_id, const char *oem_table_id,
> +   uint32_t oem_revision);
>  AcpiAml acpi_if(AcpiAml predicate);
>  AcpiAml acpi_method(const char *name, int arg_count);
>  AcpiAml GCC_FMT_ATTR(1, 2) acpi_scope(const char *name_format, ...);
> 





Re: [Qemu-devel] [PATCH] block-migration: fix pending() return value

2015-01-29 Thread Vladimir Sementsov-Ogievskiy
v2 is already pushed 
http://git.qemu.org/?p=qemu.git;a=commit;h=04636dc410b163c2243e66c3813dd4900a50a4ed


Best regards,
Vladimir

On 29.01.2015 10:58, Markus Armbruster wrote:

Vladimir Sementsov-Ogievskiy  writes:


Hi there.. Can someone review my bug fix? I'll surely fix typos in
description after it.

The file you patch has since moved.  Suggest a quick rebase.  Make sure
to cc: your v2 to migration maintainers.

$ scripts/get_maintainer.pl -f migration/block.c
Kevin Wolf  (supporter:Block)
Stefan Hajnoczi  (supporter:Block)
Juan Quintela  (maintainer:Migration)
Amit Shah  (maintainer:Migration)






[Qemu-devel] [RFC PATCH v2 09/11] hw/arm/virt-acpi-build: Generate XSDT table

2015-01-29 Thread Shannon Zhao
XDST points to other tables except FACS & DSDT.

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c|   32 +++-
 include/hw/acpi/acpi-defs.h |9 +
 2 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index ac0a864..2a2b2ab 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -176,6 +176,32 @@ static void acpi_dsdt_add_virtio(AcpiAml *scope, const 
hwaddr *mmio_addrs,
 }
 }
 
+
+/* XSDT */
+static void
+build_xsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
+{
+AcpiXsdtDescriptor *xsdt;
+size_t xsdt_len;
+int i;
+
+xsdt_len = sizeof(*xsdt) + sizeof(uint64_t) * table_offsets->len;
+xsdt = acpi_data_push(table_data, xsdt_len);
+memcpy(xsdt->table_offset_entry, table_offsets->data,
+   sizeof(uint64_t) * table_offsets->len);
+for (i = 0; i < table_offsets->len; ++i) {
+/* xsdt->table_offset_entry to be filled by Guest linker */
+bios_linker_loader_add_pointer(linker,
+   ACPI_BUILD_TABLE_FILE,
+   ACPI_BUILD_TABLE_FILE,
+   table_data, 
&xsdt->table_offset_entry[i],
+   sizeof(uint64_t));
+}
+build_header(linker, table_data, (void *)xsdt, "XSDT",
+ ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4,
+ xsdt_len, 1);
+}
+
 /* GTDT */
 static void
 build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
@@ -311,7 +337,7 @@ static
 void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
 {
 GArray *table_offsets;
-unsigned dsdt;
+unsigned dsdt, xsdt;
 VirtAcpiCpuInfo cpuinfo;
 
 virt_acpi_get_cpu_info(&cpuinfo);
@@ -346,6 +372,10 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables->table_data.buf);
 build_gtdt(tables->table_data.buf, tables->linker, guest_info);
 
+/* XSDT is pointed to by RSDP */
+xsdt = tables->table_data.buf->len;
+build_xsdt(tables->table_data.buf, tables->linker, table_offsets);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index ee40a5e..47c8c41 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -88,6 +88,15 @@ struct AcpiTableHeader /* ACPI common table header */
 typedef struct AcpiTableHeader AcpiTableHeader;
 
 /*
+ * Extended System Description Table (XSDT)
+ */
+struct AcpiXsdtDescriptor {
+ACPI_TABLE_HEADER_DEF
+uint64_t table_offset_entry[1]; /* Array of pointers to ACPI tables */
+} QEMU_PACKED;
+typedef struct AcpiXsdtDescriptor AcpiXsdtDescriptor;
+
+/*
  * ACPI Fixed ACPI Description Table (FADT)
  */
 #define ACPI_FADT_COMMON_DEF /* FADT common definition */ \
-- 
1.7.1





[Qemu-devel] [RFC PATCH v2 03/11] hw/arm/virt-acpi-build: Basic framework for building ACPI tables on ARM

2015-01-29 Thread Shannon Zhao
Introduce a preliminary framework in virt-acpi-build.c with the main
ACPI build functions. It exposes the generated ACPI contents to
guest over fw_cfg.

The required ACPI v5.1 tables for ARM are:
- RSDP: Initial table that points to XSDT
- XSDT: Points to all other tables (except FACS & DSDT)
- FADT: Generic information about the machine
- GTDT: Generic timer description table
- MADT: Multiple APIC description table
- DSDT: Holds all information about system devices/peripherals, pointed by FADT

Signed-off-by: Shannon Zhao 
---
 hw/arm/Makefile.objs |1 +
 hw/arm/virt-acpi-build.c |  204 ++
 include/hw/arm/virt-acpi-build.h |   69 +
 3 files changed, 274 insertions(+), 0 deletions(-)
 create mode 100644 hw/arm/virt-acpi-build.c
 create mode 100644 include/hw/arm/virt-acpi-build.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 6088e53..8daf825 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
+obj-$(CONFIG_ACPI) += virt-acpi-build.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-$(CONFIG_DIGIC) += digic.o
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
new file mode 100644
index 000..2f72b1e
--- /dev/null
+++ b/hw/arm/virt-acpi-build.c
@@ -0,0 +1,204 @@
+/* Support for generating ACPI tables and passing them to Guests
+ *
+ * ARM virt ACPI generation
+ *
+ * Copyright (C) 2008-2010  Kevin O'Connor 
+ * Copyright (C) 2006 Fabrice Bellard
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Author: Michael S. Tsirkin 
+ *
+ * Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * Author: Shannon Zhao 
+ *
+ * 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/arm/virt-acpi-build.h"
+#include 
+#include 
+#include "qemu-common.h"
+#include "qemu/bitmap.h"
+#include "qemu/osdep.h"
+#include "qemu/range.h"
+#include "qemu/error-report.h"
+#include "qom/cpu.h"
+#include "target-arm/cpu.h"
+#include "hw/acpi/acpi-defs.h"
+#include "hw/acpi/acpi.h"
+#include "hw/nvram/fw_cfg.h"
+#include "hw/acpi/bios-linker-loader.h"
+#include "hw/loader.h"
+#include "hw/hw.h"
+
+#include "hw/acpi/acpi-build-utils.h"
+
+#include "qapi/qmp/qint.h"
+#include "qom/qom-qobject.h"
+#include "exec/ram_addr.h"
+
+/* #define DEBUG_ACPI_BUILD */
+#ifdef DEBUG_ACPI_BUILD
+#define ACPI_BUILD_DPRINTF(fmt, ...)\
+do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define ACPI_BUILD_DPRINTF(fmt, ...)
+#endif
+
+typedef
+struct AcpiBuildState {
+/* Copy of table in RAM (for patching). */
+ram_addr_t table_ram;
+uint32_t table_size;
+ram_addr_t linker_ram;
+uint32_t linker_size;
+ram_addr_t rsdp_ram;
+uint32_t rsdp_size;
+/* Is table patched? */
+uint8_t patched;
+VirtGuestInfo *guest_info;
+} AcpiBuildState;
+
+static
+void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
+{
+GArray *table_offsets;
+
+table_offsets = g_array_new(false, true /* clear */,
+sizeof(uint64_t));
+
+bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
+ 64, false /* high memory */);
+
+/*
+ * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
+ * RSDP
+ * XSDT
+ * FADT
+ * GTDT
+ * MADT
+ * DSDT
+ */
+
+/* Cleanup memory that's no longer used. */
+g_array_free(table_offsets, true);
+}
+
+static void virt_acpi_build_update(void *build_opaque, uint32_t offset)
+{
+AcpiBuildState *build_state = build_opaque;
+AcpiBuildTables tables;
+
+/* No state to update or already patched? Nothing to do. */
+if (!build_state || build_state->patched) {
+return;
+}
+build_state->patched = 1;
+
+acpi_build_tables_init(&tables);
+
+virt_acpi_build(build_state->guest_info, &tables);
+
+assert(acpi_data_len(tables.table_data.buf) == build_state->table_size);
+
+/* Make sure RAM size is correct - in case it got changed by migration */
+qemu_ram_resize(build_state->table_ram, build_state->table_size,
+&error_a

[Qemu-devel] [RFC PATCH v2 05/11] hw/arm/virt-acpi-build: Generation of DSDT table for virt devices

2015-01-29 Thread Shannon Zhao
DSDT consists of the usual common table header plus a definition
block in AML encoding which describes all devices in the platform.

After initializing DSDT with header information the namespace is
created which is followed by the device encodings. The devices are
described using the Resource Template for the 32-Bit Fixed Memory
Range and the Extended Interrupt Descriptors.

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c |  131 ++
 1 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 2f72b1e..8560dae 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -57,6 +57,132 @@
 #define ACPI_BUILD_DPRINTF(fmt, ...)
 #endif
 
+static void acpi_dsdt_add_cpus(AcpiAml *scope, int max_cpus)
+{
+AcpiAml dev, crs;
+int i;
+char name[5];
+for (i = 0; i < max_cpus; i++) {
+snprintf(name, 5, "CPU%u", i);
+dev = acpi_device("%s", name);
+aml_append(&dev, acpi_name_decl("_HID", acpi_string("ACPI007")));
+aml_append(&dev, acpi_name_decl("_UID", acpi_int(i)));
+crs = acpi_resource_template();
+aml_append(&dev, acpi_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+}
+
+static void acpi_dsdt_add_uart(AcpiAml *scope, const hwaddr *uart_addr,
+   const int *uart_irq)
+{
+AcpiAml dev, crs;
+
+dev = acpi_device("COM0");
+aml_append(&dev, acpi_name_decl("_HID", acpi_string("ARMH0011")));
+aml_append(&dev, acpi_name_decl("_UID", acpi_int(0)));
+
+crs = acpi_resource_template();
+aml_append(&crs,
+   acpi_memory32_fixed(uart_addr[0], uart_addr[1], 0x01));
+aml_append(&crs,
+   acpi_interrupt(0x01, *uart_irq + 32));
+aml_append(&dev, acpi_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
+static void acpi_dsdt_add_rtc(AcpiAml *scope, const hwaddr *rtc_addr,
+  const int *rtc_irq)
+{
+AcpiAml dev, crs;
+
+dev = acpi_device("RTC0");
+aml_append(&dev, acpi_name_decl("_HID", acpi_string("LNRO0013")));
+aml_append(&dev, acpi_name_decl("_UID", acpi_int(0)));
+
+crs = acpi_resource_template();
+aml_append(&crs,
+   acpi_memory32_fixed(rtc_addr[0], rtc_addr[1], 0x01));
+aml_append(&crs,
+   acpi_interrupt(0x01, *rtc_irq + 32));
+aml_append(&dev, acpi_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
+static void acpi_dsdt_add_flash(AcpiAml *scope, const hwaddr *flash_addr)
+{
+AcpiAml dev, crs;
+hwaddr base = flash_addr[0];
+hwaddr size = flash_addr[1];
+
+dev = acpi_device("FLS0");
+aml_append(&dev, acpi_name_decl("_HID", acpi_string("LNRO0015")));
+aml_append(&dev, acpi_name_decl("_UID", acpi_int(0)));
+
+crs = acpi_resource_template();
+aml_append(&crs,
+   acpi_memory32_fixed(base, size, 0x01));
+aml_append(&dev, acpi_name_decl("_CRS", crs));
+aml_append(scope, dev);
+
+dev = acpi_device("FLS1");
+aml_append(&dev, acpi_name_decl("_HID", acpi_string("LNRO0015")));
+aml_append(&dev, acpi_name_decl("_UID", acpi_int(1)));
+crs = acpi_resource_template();
+aml_append(&crs,
+   acpi_memory32_fixed(base + size, size, 0x01));
+aml_append(&dev, acpi_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
+static void acpi_dsdt_add_virtio(AcpiAml *scope, const hwaddr *mmio_addrs,
+ const int *mmio_irq, int num)
+{
+AcpiAml dev, crs;
+hwaddr base = mmio_addrs[0];
+hwaddr size = mmio_addrs[1];
+int irq = *mmio_irq + 32;
+int i;
+char name[5];
+
+for (i = 0; i < num; i++) {
+snprintf(name, 5, "VR%02u", i);
+dev = acpi_device("%s", name);
+aml_append(&dev, acpi_name_decl("_HID", acpi_string("LNRO0005")));
+aml_append(&dev, acpi_name_decl("_UID", acpi_int(i)));
+
+crs = acpi_resource_template();
+aml_append(&crs,
+   acpi_memory32_fixed(base, size, 0x01));
+aml_append(&crs,
+   acpi_interrupt(0x01, irq + i));
+aml_append(&dev, acpi_name_decl("_CRS", crs));
+aml_append(scope, dev);
+base += size;
+}
+}
+
+/* DSDT */
+static void
+build_dsdt(AcpiAml *table_aml, GArray *linker, VirtGuestInfo *guest_info)
+{
+AcpiAml scope, dsdt;
+const struct acpi_dsdt_info *info = guest_info->dsdt_info;
+
+dsdt = acpi_def_block("DSDT", 1, ACPI_BUILD_APPNAME6,
+   ACPI_BUILD_APPNAME4, 1, ACPI_BUILD_APPNAME4);
+scope = acpi_scope("\\_SB");
+acpi_dsdt_add_cpus(&scope, guest_info->max_cpus);
+acpi_dsdt_add_uart(&scope, info->uart_addr, info->uart_irq);
+acpi_dsdt_add_rtc(&scope, info->rtc_addr, info->rtc_irq);
+acpi_dsdt_add_flash(&scope, info->flash_addr);
+acpi_dsdt_add_virtio(&scope, info->virtio_mmio_add

[Qemu-devel] [RFC PATCH v2 02/11] hw/i386/acpi-build: move generic acpi building helpers into dedictated file

2015-01-29 Thread Shannon Zhao
Move generic acpi building helpers into dedictated file and this
can be shared with other machines.

Signed-off-by: Shannon Zhao 
---
 hw/acpi/acpi-build-utils.c |   63 -
 hw/i386/acpi-build.c   |  111 
 hw/i386/acpi-build.h   |3 +
 include/hw/acpi/acpi-build-utils.h |   26 -
 4 files changed, 111 insertions(+), 92 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 59873e3..aa32fe4 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -881,7 +881,7 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed 
min_fixed,
 /* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
 AcpiAml acpi_def_block(const char *signature, uint8_t revision,
const char *oem_id, const char *oem_table_id,
-   uint32_t oem_revision)
+   uint32_t oem_revision, const char *asl_compiler_id)
 {
 int len;
 AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
@@ -903,8 +903,67 @@ AcpiAml acpi_def_block(const char *signature, uint8_t 
revision,
 g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
 
 build_append_value(var.buf, oem_revision, 4);
-g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* asl_compiler_id */
+g_array_append_vals(var.buf, asl_compiler_id, 4); /* asl_compiler_id */
 build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
 
 return var;
 }
+
+void
+build_header(GArray *linker, GArray *table_data, AcpiTableHeader *h,
+ const char *sig, const char *ome_id, const char *asl_id,
+ int len, uint8_t rev)
+{
+memcpy(&h->signature, sig, 4);
+h->length = cpu_to_le32(len);
+h->revision = rev;
+memcpy(h->oem_id, ome_id, 6);
+memcpy(h->oem_table_id, asl_id, 4);
+memcpy(h->oem_table_id + 4, sig, 4);
+h->oem_revision = cpu_to_le32(1);
+memcpy(h->asl_compiler_id, asl_id, 4);
+h->asl_compiler_revision = cpu_to_le32(1);
+h->checksum = 0;
+/* Checksum to be filled in by Guest linker */
+bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
+table_data->data, h, len, &h->checksum);
+}
+
+void *acpi_data_push(GArray *table_data, uint64_t size)
+{
+uint64_t off = table_data->len;
+g_array_set_size(table_data, off + size);
+return table_data->data + off;
+}
+
+uint64_t acpi_data_len(GArray *table)
+{
+#if GLIB_CHECK_VERSION(2, 22, 0)
+assert(g_array_get_element_size(table) == 1);
+#endif
+return table->len;
+}
+
+void acpi_add_table(GArray *table_offsets, GArray *table_data)
+{
+uint64_t offset = cpu_to_le64(table_data->len);
+g_array_append_val(table_offsets, offset);
+}
+
+void acpi_build_tables_init(AcpiBuildTables *tables)
+{
+tables->rsdp = g_array_new(false, true /* clear */, 1);
+tables->table_data.buf = g_array_new(false, true /* clear */, 1);
+tables->tcpalog = g_array_new(false, true /* clear */, 1);
+tables->linker = bios_linker_loader_init();
+tables->table_data.linker = tables->linker;
+}
+
+void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
+{
+void *linker_data = bios_linker_loader_cleanup(tables->linker);
+g_free(linker_data);
+g_array_free(tables->rsdp, mfre);
+g_array_free(tables->table_data.buf, true);
+g_array_free(tables->tcpalog, mfre);
+}
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f22f6d6..2015760 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -70,9 +70,6 @@
 
 #define ACPI_BUILD_TABLE_SIZE 0x2
 
-/* Reserve RAM space for tables: add another order of magnitude. */
-#define ACPI_BUILD_TABLE_MAX_SIZE 0x20
-
 /* #define DEBUG_ACPI_BUILD */
 #ifdef DEBUG_ACPI_BUILD
 #define ACPI_BUILD_DPRINTF(fmt, ...)\
@@ -261,49 +258,9 @@ static void acpi_get_pci_info(PcPciInfo *info)
 NULL);
 }
 
-#define ACPI_BUILD_APPNAME  "Bochs"
-#define ACPI_BUILD_APPNAME6 "BOCHS "
-
-#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
-#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
-
-static void
-build_header(GArray *linker, GArray *table_data,
- AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
-{
-memcpy(&h->signature, sig, 4);
-h->length = cpu_to_le32(len);
-h->revision = rev;
-memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
-memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
-memcpy(h->oem_table_id + 4, sig, 4);
-h->oem_revision = cpu_to_le32(1);
-memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
-h->asl_compiler_revision = cpu_to_le32(1);
-h->checksum = 0;
-/* Checksum to be filled in by Guest linker */
-bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
-table_data->data, h, len, &h->checksum);
-}
-
 /* End here */
 #define ACPI_PORT_SMI_CMD   0x00b2 

[Qemu-devel] [RFC PATCH v2 00/11] Generate ACPI v5.1 tables and expose it to guest over fw_cfg on ARM

2015-01-29 Thread Shannon Zhao
This patch series generate seven ACPI v5.1 tables for machine virt on ARM.
The set of generated tables are:
- RSDP
- XSDT
- MADT
- GTDT
- FADT
- DSDT

These tables are created dynamically using the function of acpi-build-utils.c,
taking into account the needed information passed from the virt machine model.
When the generation is finalized, it use fw_cfg to expose the tables to guest.

This patchset is based on Igor Mammedov's branch which can be found at below
git tree:
 https://github.com/imammedo/qemu/commits/ASL_API_v2

And this patchset refers to Alexander Spyridakis's patches which are sent to
qemu-devel mailing list before.
 http://lists.gnu.org/archive/html/qemu-devel/2014-10/msg03987.html

Thanks to Laszlo's work on UEFI (ArmVirtualizationQemu) supporting downloading
ACPI tables over fw_cfg, we now can use ACPI in VM. I have done following vm
startup test:

xp, windows2008, sles11 on X86
Linux on ARM64

Laszlo's patch
http://thread.gmane.org/gmane.comp.bios.tianocore.devel/12158

Todo:
1) add GPIO controller in virt and expose it through ACPI
2) add cpu hotplug support

Any comments are welcome.

changes since v1:
  * fix bug found by Laszlo
  * move common helpers into dedictated file and change generating
table order according to Igor's comments
  * fix copyright and function name according to Michael's comments

Shannon Zhao (11):
  hw/i386: Move ACPI header definitions in an arch-independent location
  hw/i386/acpi-build: move generic acpi building helpers into
dedictated file
  hw/arm/virt-acpi-build: Basic framework for building ACPI tables on
ARM
  hw/acpi/acpi-build-utils: Add acpi_memory32_fixed() and
acpi_interrupt()
  hw/arm/virt-acpi-build: Generation of DSDT table for virt devices
  hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers
  hw/arm/virt-acpi-build: Generate MADT table
  hw/arm/virt-acpi-build: Generate GTDT table
  hw/arm/virt-acpi-build: Generate XSDT table
  hw/arm/virt-acpi-build: Generate RSDP table
  hw/arm/virt: Enable dynamic generation of ACPI v5.1 tables

 default-configs/arm-softmmu.mak  |1 +
 default-configs/i386-softmmu.mak |3 +
 default-configs/mips-softmmu.mak |3 +
 default-configs/mips64-softmmu.mak   |3 +
 default-configs/mips64el-softmmu.mak |3 +
 default-configs/mipsel-softmmu.mak   |3 +
 default-configs/x86_64-softmmu.mak   |3 +
 hw/acpi/Makefile.objs|5 +-
 hw/acpi/acpi-build-utils.c   |  103 +++-
 hw/arm/Makefile.objs |1 +
 hw/arm/virt-acpi-build.c |  519 ++
 hw/arm/virt.c|   59 -
 hw/i2c/Makefile.objs |2 +-
 hw/i386/acpi-build.c |  113 ++--
 hw/i386/acpi-build.h |3 +
 hw/i386/acpi-defs.h  |  368 
 include/hw/acpi/acpi-build-utils.h   |   28 ++-
 include/hw/acpi/acpi-defs.h  |  488 
 include/hw/arm/virt-acpi-build.h |   71 +
 tests/bios-tables-test.c |2 +-
 20 files changed, 1312 insertions(+), 469 deletions(-)
 create mode 100644 hw/arm/virt-acpi-build.c
 delete mode 100644 hw/i386/acpi-defs.h
 create mode 100644 include/hw/acpi/acpi-defs.h
 create mode 100644 include/hw/arm/virt-acpi-build.h





[Qemu-devel] [RFC PATCH v2 04/11] hw/acpi/acpi-build-utils: Add acpi_memory32_fixed() and acpi_interrupt()

2015-01-29 Thread Shannon Zhao
Add acpi_memory32_fixed() for describing device mmio region in resource 
template.
Add acpi_interrupt() for describing device interrupt in resource template.
These can be used to generating DSDT table for ACPI on ARM.

Signed-off-by: Shannon Zhao 
---
 hw/acpi/acpi-build-utils.c |   40 
 include/hw/acpi/acpi-build-utils.h |2 +
 2 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index aa32fe4..60cce5d 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -493,6 +493,46 @@ AcpiAml acpi_call4(const char *method, AcpiAml arg1, 
AcpiAml arg2,
 }
 
 /*
+ * ACPI 1.0: 6.4.3.4 Memory32Fixed (Memory Resource Descriptor Macro)
+ */
+AcpiAml acpi_memory32_fixed(uint64_t addr, uint64_t size, uint8_t rw_flag)
+{
+AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+build_append_byte(var.buf, 0x86); /* Memory32Fixed Resource Descriptor */
+build_append_byte(var.buf, 9); /* Length, bits[7:0] value = 9 */
+build_append_byte(var.buf, 0); /* Length, bits[15:8] value = 0 */
+build_append_byte(var.buf, rw_flag); /* Write status, 1 rw 0 ro */
+build_append_byte(var.buf, addr & 0xff); /* Range base address bits[7:0] */
+build_append_byte(var.buf, (addr >> 8) & 0xff); /* Range base address 
bits[15:8] */
+build_append_byte(var.buf, (addr >> 16) & 0xff); /* Range base address 
bits[23:16] */
+build_append_byte(var.buf, (addr >> 24) & 0xff); /* Range base address 
bits[31:24] */
+
+build_append_byte(var.buf, size & 0xff); /* Range length bits[7:0] */
+build_append_byte(var.buf, (size >> 8) & 0xff); /* Range length bits[15:8] 
*/
+build_append_byte(var.buf, (size >> 16) & 0xff); /* Range length 
bits[23:16] */
+build_append_byte(var.buf, (size >> 24) & 0xff); /* Range length 
bits[31:24] */
+return var;
+}
+
+/*
+ * ACPI 1.0: 6.4.3.6 Interrupt (Interrupt Resource Descriptor Macro)
+ */
+AcpiAml acpi_interrupt(uint8_t irq_flags, int irq)
+{
+AcpiAml var = aml_allocate_internal(0, NON_BLOCK);
+build_append_byte(var.buf, 0x89); /* Extended irq descriptor */
+build_append_byte(var.buf, 6); /* Length, bits[7:0] minimum value = 6 */
+build_append_byte(var.buf, 0); /* Length, bits[15:8] minimum value = 0 */
+build_append_byte(var.buf, irq_flags); /* Interrupt Vector Information. */
+build_append_byte(var.buf, 0x01); /* Interrupt table length = 1 */
+build_append_byte(var.buf, irq & 0xff); /* Interrupt Number bits[7:0] */
+build_append_byte(var.buf, (irq >> 8) & 0xff); /* Interrupt Number 
bits[15:8] */
+build_append_byte(var.buf, (irq >> 16) & 0xff); /* Interrupt Number 
bits[23:16] */
+build_append_byte(var.buf, (irq >> 24) & 0xff); /* Interrupt Number 
bits[31:24] */
+return var;
+}
+
+/*
  * ACPI 5.0: 19.5.62 IO (IO Resource Descriptor Macro)
  *   6.4.2 Small Resource Data Type
 */
diff --git a/include/hw/acpi/acpi-build-utils.h 
b/include/hw/acpi/acpi-build-utils.h
index b504c3a..0b0ced7 100644
--- a/include/hw/acpi/acpi-build-utils.h
+++ b/include/hw/acpi/acpi-build-utils.h
@@ -127,6 +127,8 @@ AcpiAml acpi_call3(const char *method, AcpiAml arg1, 
AcpiAml arg2,
AcpiAml arg3);
 AcpiAml acpi_call4(const char *method, AcpiAml arg1, AcpiAml arg2,
AcpiAml arg3, AcpiAml arg4);
+AcpiAml acpi_memory32_fixed(uint64_t addr, uint64_t size, uint8_t rw_flag);
+AcpiAml acpi_interrupt(uint8_t irq_flags, int irq);
 AcpiAml acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
 uint8_t aln, uint8_t len);
 AcpiAml acpi_iqr_no_flags(uint8_t irq);
-- 
1.7.1





[Qemu-devel] [RFC PATCH v2 01/11] hw/i386: Move ACPI header definitions in an arch-independent location

2015-01-29 Thread Shannon Zhao
The ACPI related header file acpi-defs.h, includes definitions that
apply on other architectures as well. Move it in `include/hw/acpi/`
to sanely include it from other architectures.

Signed-off-by: Alvise Rigo 
Signed-off-by: Shannon Zhao 
---
 hw/i386/acpi-build.c|2 +-
 hw/i386/acpi-defs.h |  368 ---
 include/hw/acpi/acpi-defs.h |  368 +++
 tests/bios-tables-test.c|2 +-
 4 files changed, 370 insertions(+), 370 deletions(-)
 delete mode 100644 hw/i386/acpi-defs.h
 create mode 100644 include/hw/acpi/acpi-defs.h

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index f66da5d..f22f6d6 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -33,7 +33,7 @@
 #include "hw/i386/pc.h"
 #include "target-i386/cpu.h"
 #include "hw/timer/hpet.h"
-#include "hw/i386/acpi-defs.h"
+#include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
deleted file mode 100644
index c4468f8..000
--- a/hw/i386/acpi-defs.h
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * 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 .
- */
-#ifndef QEMU_ACPI_DEFS_H
-#define QEMU_ACPI_DEFS_H
-
-enum {
-ACPI_FADT_F_WBINVD,
-ACPI_FADT_F_WBINVD_FLUSH,
-ACPI_FADT_F_PROC_C1,
-ACPI_FADT_F_P_LVL2_UP,
-ACPI_FADT_F_PWR_BUTTON,
-ACPI_FADT_F_SLP_BUTTON,
-ACPI_FADT_F_FIX_RTC,
-ACPI_FADT_F_RTC_S4,
-ACPI_FADT_F_TMR_VAL_EXT,
-ACPI_FADT_F_DCK_CAP,
-ACPI_FADT_F_RESET_REG_SUP,
-ACPI_FADT_F_SEALED_CASE,
-ACPI_FADT_F_HEADLESS,
-ACPI_FADT_F_CPU_SW_SLP,
-ACPI_FADT_F_PCI_EXP_WAK,
-ACPI_FADT_F_USE_PLATFORM_CLOCK,
-ACPI_FADT_F_S4_RTC_STS_VALID,
-ACPI_FADT_F_REMOTE_POWER_ON_CAPABLE,
-ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL,
-ACPI_FADT_F_FORCE_APIC_PHYSICAL_DESTINATION_MODE,
-ACPI_FADT_F_HW_REDUCED_ACPI,
-ACPI_FADT_F_LOW_POWER_S0_IDLE_CAPABLE,
-};
-
-/*
- * ACPI 2.0 Generic Address Space definition.
- */
-struct Acpi20GenericAddress {
-uint8_t  address_space_id;
-uint8_t  register_bit_width;
-uint8_t  register_bit_offset;
-uint8_t  reserved;
-uint64_t address;
-} QEMU_PACKED;
-typedef struct Acpi20GenericAddress Acpi20GenericAddress;
-
-struct AcpiRsdpDescriptor {/* Root System Descriptor Pointer */
-uint64_t signature;  /* ACPI signature, contains "RSD PTR " */
-uint8_t  checksum;   /* To make sum of struct == 0 */
-uint8_t  oem_id [6]; /* OEM identification */
-uint8_t  revision;   /* Must be 0 for 1.0, 2 for 2.0 */
-uint32_t rsdt_physical_address;  /* 32-bit physical address of RSDT */
-uint32_t length; /* XSDT Length in bytes including hdr */
-uint64_t xsdt_physical_address;  /* 64-bit physical address of XSDT */
-uint8_t  extended_checksum;  /* Checksum of entire table */
-uint8_t  reserved [3];   /* Reserved field must be 0 */
-} QEMU_PACKED;
-typedef struct AcpiRsdpDescriptor AcpiRsdpDescriptor;
-
-/* Table structure from Linux kernel (the ACPI tables are under the
-   BSD license) */
-
-
-#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
-uint32_t signature;  /* ACPI signature (4 ASCII characters) */ \
-uint32_t length; /* Length of table, in bytes, including 
header */ \
-uint8_t  revision;   /* ACPI Specification minor version # */ \
-uint8_t  checksum;   /* To make sum of entire table == 0 */ \
-uint8_t  oem_id [6]; /* OEM identification */ \
-uint8_t  oem_table_id [8];   /* OEM table identification */ \
-uint32_t oem_revision;   /* OEM revision number */ \
-uint8_t  asl_compiler_id [4];/* ASL compiler vendor ID */ \
-uint32_t asl_compiler_revision;  /* ASL compiler revision number */
-
-
-struct AcpiTableHeader /* ACPI common table header */
-{
-ACPI_TABLE_HEADER_DEF
-} QEMU_PACKED;
-typedef struct AcpiTableHeader AcpiTableHeader;
-
-/*
- * ACPI 1.0 Fixed ACPI Description Table (FADT)
- */
-struct AcpiFadtDescriptorRev1
-{
-ACPI_TABLE_HEADER_DEF /* ACPI common table header */
-uint32_t firmware_ctrl;  /* Physical address of FACS */
-uint32_t dsdt; 

[Qemu-devel] [RFC PATCH v2 11/11] hw/arm/virt: Enable dynamic generation of ACPI v5.1 tables

2015-01-29 Thread Shannon Zhao
Expose the needed device information to the table generation
insfrastructure and register a machine_init_done notify to
call virt_acpi_build().

Add CONFIG_ACPI to arm-softmmu.mak, but there is compile error.
Don't include unnecessary file for ARM. Maybe this way is not
right, fix me please.

Signed-off-by: Shannon Zhao 
---
 default-configs/arm-softmmu.mak  |1 +
 default-configs/i386-softmmu.mak |3 ++
 default-configs/mips-softmmu.mak |3 ++
 default-configs/mips64-softmmu.mak   |3 ++
 default-configs/mips64el-softmmu.mak |3 ++
 default-configs/mipsel-softmmu.mak   |3 ++
 default-configs/x86_64-softmmu.mak   |3 ++
 hw/acpi/Makefile.objs|5 ++-
 hw/arm/virt.c|   59 +++--
 hw/i2c/Makefile.objs |2 +-
 10 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index f3513fa..3c89f53 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -88,3 +88,4 @@ CONFIG_INTEGRATOR_DEBUG=y
 CONFIG_ALLWINNER_A10_PIT=y
 CONFIG_ALLWINNER_A10_PIC=y
 CONFIG_ALLWINNER_A10=y
+CONFIG_ACPI=y
diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 8e08841..3a5fe74 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -17,6 +17,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_IDE_ISA=y
diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index 2a80b04..d37ada7 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -17,6 +17,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/mips64-softmmu.mak 
b/default-configs/mips64-softmmu.mak
index f1f933b..b15d6c0 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -17,6 +17,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/mips64el-softmmu.mak 
b/default-configs/mips64el-softmmu.mak
index 317b151..494a7e7 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -17,6 +17,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/mipsel-softmmu.mak 
b/default-configs/mipsel-softmmu.mak
index 7708185..0d2173b 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -17,6 +17,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_PIIX4=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index 66557ac..79eb980 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -17,6 +17,9 @@ CONFIG_PCSPK=y
 CONFIG_PCKBD=y
 CONFIG_FDC=y
 CONFIG_ACPI=y
+CONFIG_ACPI_CORE=y
+CONFIG_ACPI_MEMORY_HOTPLUG=y
+CONFIG_ACPI_CPU_HOTPLUG=y
 CONFIG_APM=y
 CONFIG_I8257=y
 CONFIG_IDE_ISA=y
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index cad0355..30361e4 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -1,5 +1,6 @@
-common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
-common-obj-$(CONFIG_ACPI) += memory_hotplug.o
+common-obj-$(CONFIG_ACPI_CORE) += core.o piix4.o ich9.o pcihp.o
+common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
+common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
 common-obj-$(CONFIG_ACPI) += acpi_interface.o
 common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
 common-obj-$(CONFIG_ACPI) += acpi-build-utils.o
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 2353440..8a00574 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -42,6 +42,7 @@
 #include "exec/address-spaces.h"
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
+#include "hw/arm/virt-acpi-build.h"
 
 #define NUM_VIRTIO_TRANSPORTS 32
 
@@ -59,6 +60,11 @@
 #define GIC_FDT_IRQ_PPI_CPU_START 8
 #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
 
+#define ARCH_TIMER_VIRT_IRQ   11
+#define ARCH_TIMER_S_EL1_IRQ  13
+#define ARCH_TIMER_NS_EL1_IRQ 14
+#define ARCH_TIMER_NS_EL2_IRQ 10
+
 enum {
 VIRT_FLASH,
 VIRT_MEM,
@@ -139,6 +145,29 @@ static const int a15irqmap[] = {
 [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
 };
 
+static const struct acpi_madt_info madt_info = {
+&a15memmap[VIRT_GIC_CPU].base,
+

[Qemu-devel] [RFC PATCH v2 10/11] hw/arm/virt-acpi-build: Generate RSDP table

2015-01-29 Thread Shannon Zhao
RSDP points to XSDT which in turn points to other tables.

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c |   31 +++
 1 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 2a2b2ab..c838285 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -176,6 +176,34 @@ static void acpi_dsdt_add_virtio(AcpiAml *scope, const 
hwaddr *mmio_addrs,
 }
 }
 
+/* RSDP */
+static GArray *
+build_rsdp(GArray *rsdp_table, GArray *linker, uint64_t xsdt)
+{
+AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
+
+bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
+ true /* fseg memory */);
+
+memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
+memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id));
+rsdp->length = cpu_to_le32(sizeof(*rsdp));
+rsdp->revision = 0x02;
+
+/* Point to XSDT */
+rsdp->xsdt_physical_address = cpu_to_le64(xsdt);
+/* Address to be filled by Guest linker */
+bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
+   ACPI_BUILD_TABLE_FILE,
+   rsdp_table, &rsdp->xsdt_physical_address,
+   sizeof rsdp->xsdt_physical_address);
+rsdp->checksum = 0;
+/* Checksum to be filled by Guest linker */
+bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
+rsdp, rsdp, sizeof *rsdp, &rsdp->checksum);
+
+return rsdp_table;
+}
 
 /* XSDT */
 static void
@@ -376,6 +404,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 xsdt = tables->table_data.buf->len;
 build_xsdt(tables->table_data.buf, tables->linker, table_offsets);
 
+/* RSDP is in FSEG memory, so allocate it separately */
+build_rsdp(tables->rsdp, tables->linker, xsdt);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
-- 
1.7.1





[Qemu-devel] [RFC PATCH v2 07/11] hw/arm/virt-acpi-build: Generate MADT table

2015-01-29 Thread Shannon Zhao
MADT describes GIC enabled ARM platforms. The GICC and GICD
subtables are used to define the GIC regions.

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c |   62 ++
 include/hw/acpi/acpi-defs.h  |   36 +-
 include/hw/arm/virt-acpi-build.h |2 +
 3 files changed, 99 insertions(+), 1 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index e12c20f..64a3022 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -57,6 +57,20 @@
 #define ACPI_BUILD_DPRINTF(fmt, ...)
 #endif
 
+typedef struct VirtAcpiCpuInfo {
+DECLARE_BITMAP(found_cpus, VIRT_ACPI_CPU_ID_LIMIT);
+} VirtAcpiCpuInfo;
+
+static void virt_acpi_get_cpu_info(VirtAcpiCpuInfo *cpuinfo)
+{
+CPUState *cpu;
+
+memset(cpuinfo->found_cpus, 0, sizeof cpuinfo->found_cpus);
+CPU_FOREACH(cpu) {
+set_bit(cpu->cpu_index, cpuinfo->found_cpus);
+}
+}
+
 static void acpi_dsdt_add_cpus(AcpiAml *scope, int max_cpus)
 {
 AcpiAml dev, crs;
@@ -162,6 +176,48 @@ static void acpi_dsdt_add_virtio(AcpiAml *scope, const 
hwaddr *mmio_addrs,
 }
 }
 
+/* MADT */
+static void
+build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
+   VirtAcpiCpuInfo *cpuinfo)
+{
+int madt_start = table_data->len;
+const struct acpi_madt_info *info = guest_info->madt_info;
+AcpiMultipleApicTable *madt;
+AcpiMadtGenericDistributor *gicd;
+int i;
+
+madt = acpi_data_push(table_data, sizeof *madt);
+madt->local_apic_address = *info->gic_cpu_base_addr;
+madt->flags = cpu_to_le32(1);
+
+for (i = 0; i < guest_info->max_cpus; i++) {
+AcpiMadtGenericInterrupt *gicc = acpi_data_push(table_data,
+ sizeof *gicc);
+gicc->type = ACPI_APIC_GENERIC_INTERRUPT;
+gicc->length = sizeof(*gicc);
+gicc->base_address = *info->gic_cpu_base_addr;
+gicc->cpu_interface_number = i;
+gicc->arm_mpidr = i;
+gicc->uid = i;
+if (test_bit(i, cpuinfo->found_cpus)) {
+gicc->flags = cpu_to_le32(1);
+} else {
+gicc->flags = cpu_to_le32(0);
+}
+}
+
+gicd = acpi_data_push(table_data, sizeof *gicd);
+gicd->type = ACPI_APIC_GENERIC_DISTRIBUTOR;
+gicd->length = sizeof(*gicd);
+gicd->base_address = *info->gic_dist_base_addr;
+
+build_header(linker, table_data,
+ (void *)(table_data->data + madt_start), "APIC",
+ ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4,
+ table_data->len - madt_start, 1);
+}
+
 /* FADT */
 static void
 build_fadt(GArray *table_data, GArray *linker, uint64_t dsdt)
@@ -228,6 +284,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 {
 GArray *table_offsets;
 unsigned dsdt;
+VirtAcpiCpuInfo cpuinfo;
+
+virt_acpi_get_cpu_info(&cpuinfo);
 
 table_offsets = g_array_new(false, true /* clear */,
 sizeof(uint64_t));
@@ -253,6 +312,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables->table_data.buf);
 build_fadt(tables->table_data.buf, tables->linker, dsdt);
 
+acpi_add_table(table_offsets, tables->table_data.buf);
+build_madt(tables->table_data.buf, tables->linker, guest_info, &cpuinfo);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index e588df5..e343728 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -235,7 +235,13 @@ typedef struct AcpiMultipleApicTable AcpiMultipleApicTable;
 #define ACPI_APIC_IO_SAPIC   6
 #define ACPI_APIC_LOCAL_SAPIC7
 #define ACPI_APIC_XRUPT_SOURCE   8
-#define ACPI_APIC_RESERVED   9   /* 9 and greater are reserved 
*/
+#define ACPI_APIC_LOCAL_X2APIC   9
+#define ACPI_APIC_LOCAL_X2APIC_NMI  10
+#define ACPI_APIC_GENERIC_INTERRUPT 11
+#define ACPI_APIC_GENERIC_DISTRIBUTOR   12
+#define ACPI_APIC_GENERIC_MSI_FRAME 13
+#define ACPI_APIC_GENERIC_REDISTRIBUTOR 14
+#define ACPI_APIC_RESERVED  15   /* 15 and greater are reserved */
 
 /*
  * MADT sub-structures (Follow MULTIPLE_APIC_DESCRIPTION_TABLE)
@@ -283,6 +289,34 @@ struct AcpiMadtLocalNmi {
 } QEMU_PACKED;
 typedef struct AcpiMadtLocalNmi AcpiMadtLocalNmi;
 
+struct AcpiMadtGenericInterrupt {
+ACPI_SUB_HEADER_DEF
+uint16_t reserved;
+uint32_t cpu_interface_number;
+uint32_t uid;
+uint32_t flags;
+uint32_t parking_version;
+uint32_t performance_interrupt;
+uint64_t parked_address;
+uint64_t base_address;
+uint64_t gicv_base_address;
+uint64_t gich_base_address;
+uint32_t vgic_interrupt;
+uint64_t gicr_base_address;
+uint64_t arm_mpidr;
+} QEMU_PACKED;
+typedef struct AcpiMadtGenericIn

[Qemu-devel] [RFC PATCH v2 06/11] hw/arm/virt-acpi-build: Generate FADT table and update ACPI headers

2015-01-29 Thread Shannon Zhao
In the case of mach virt, it is used to set the Hardware Reduced bit
and enable PSCI SMP booting through HVC. So ignore FACS and FADT
points to DSDT.

Update the header definitions for FADT taking into account the new
additions of ACPI v5.1 in `include/hw/acpi/acpi-defs.h`

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c|   30 +++
 include/hw/acpi/acpi-defs.h |  114 +--
 2 files changed, 107 insertions(+), 37 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8560dae..e12c20f 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -162,6 +162,32 @@ static void acpi_dsdt_add_virtio(AcpiAml *scope, const 
hwaddr *mmio_addrs,
 }
 }
 
+/* FADT */
+static void
+build_fadt(GArray *table_data, GArray *linker, uint64_t dsdt)
+{
+AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+
+/* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
+fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
+fadt->arm_boot_flags = cpu_to_le16((1 << ACPI_FADT_ARM_USE_PSCI_G_0_2) |
+   (1 << ACPI_FADT_ARM_PSCI_USE_HVC));
+
+/* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
+fadt->minor_revision = 0x1;
+
+fadt->Xdsdt = cpu_to_le64(dsdt);
+/* DSDT address to be filled by Guest linker */
+bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
+   ACPI_BUILD_TABLE_FILE,
+   table_data, &fadt->Xdsdt,
+   sizeof fadt->Xdsdt);
+
+build_header(linker, table_data, (void *)fadt, "FACP",
+ ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4,
+ sizeof(*fadt), 5);
+}
+
 /* DSDT */
 static void
 build_dsdt(AcpiAml *table_aml, GArray *linker, VirtGuestInfo *guest_info)
@@ -223,6 +249,10 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 dsdt = tables->table_data.buf->len;
 build_dsdt(&tables->table_data, tables->linker, guest_info);
 
+/* FADT MADT GTDT pointed to by XSDT */
+acpi_add_table(table_offsets, tables->table_data.buf);
+build_fadt(tables->table_data.buf, tables->linker, dsdt);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index c4468f8..e588df5 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -88,46 +88,49 @@ struct AcpiTableHeader /* ACPI common table header 
*/
 typedef struct AcpiTableHeader AcpiTableHeader;
 
 /*
- * ACPI 1.0 Fixed ACPI Description Table (FADT)
+ * ACPI Fixed ACPI Description Table (FADT)
  */
+#define ACPI_FADT_COMMON_DEF /* FADT common definition */ \
+ACPI_TABLE_HEADER_DEF/* ACPI common table header */ \
+uint32_t firmware_ctrl;  /* Physical address of FACS */ \
+uint32_t dsdt;   /* Physical address of DSDT */ \
+uint8_t  model;  /* System Interrupt Model */ \
+uint8_t  reserved1;  /* Reserved */ \
+uint16_t sci_int;/* System vector of SCI interrupt */ \
+uint32_t smi_cmd;/* Port address of SMI command port */ \
+uint8_t  acpi_enable;/* Value to write to smi_cmd to enable 
ACPI */ \
+uint8_t  acpi_disable;   /* Value to write to smi_cmd to disable 
ACPI */ \
+uint8_t  S4bios_req; /* Value to write to SMI CMD to enter 
S4BIOS state */ \
+uint8_t  reserved2;  /* Reserved - must be zero */ \
+uint32_t pm1a_evt_blk;   /* Port address of Power Mgt 1a 
acpi_event Reg Blk */ \
+uint32_t pm1b_evt_blk;   /* Port address of Power Mgt 1b 
acpi_event Reg Blk */ \
+uint32_t pm1a_cnt_blk;   /* Port address of Power Mgt 1a Control 
Reg Blk */ \
+uint32_t pm1b_cnt_blk;   /* Port address of Power Mgt 1b Control 
Reg Blk */ \
+uint32_t pm2_cnt_blk;/* Port address of Power Mgt 2 Control 
Reg Blk */ \
+uint32_t pm_tmr_blk; /* Port address of Power Mgt Timer Ctrl 
Reg Blk */ \
+uint32_t gpe0_blk;   /* Port addr of General Purpose 
acpi_event 0 Reg Blk */ \
+uint32_t gpe1_blk;   /* Port addr of General Purpose 
acpi_event 1 Reg Blk */ \
+uint8_t  pm1_evt_len;/* Byte length of ports at pm1_x_evt_blk 
*/ \
+uint8_t  pm1_cnt_len;/* Byte length of ports at pm1_x_cnt_blk 
*/ \
+uint8_t  pm2_cnt_len;/* Byte Length of ports at pm2_cnt_blk */ 
\
+uint8_t  pm_tmr_len; /* Byte Length of ports at pm_tm_blk */ \
+uint8_t  gpe0_blk_len;   /* Byte Length of ports at gpe0_blk */ \
+uint8_t  gpe1_blk_len;   /* Byte Length of ports at gpe1_blk */ \
+uint8_t  gpe1_base;  /* Offset in gpe model where gpe1 

Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term

2015-01-29 Thread Igor Mammedov
On Thu, 29 Jan 2015 16:02:47 +0800
Shannon Zhao  wrote:

> On 2015/1/22 22:50, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov 
> > ---
> >  hw/acpi/acpi-build-utils.c | 47 
> > ++
> >  hw/i386/acpi-build.c   |  1 -
> >  include/hw/acpi/acpi-build-utils.h |  8 +++
> >  3 files changed, 55 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> > index b19d370..58f88cd 100644
> > --- a/hw/acpi/acpi-build-utils.c
> > +++ b/hw/acpi/acpi-build-utils.c
> > @@ -26,6 +26,7 @@
> >  #include 
> >  #include "hw/acpi/acpi-build-utils.h"
> >  #include "qemu/bswap.h"
> > +#include "hw/acpi/bios-linker-loader.h"
> >  
> >  GArray *build_alloc_array(void)
> >  {
> > @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
> >  build_prepend_int(child.buf, child.buf->len);
> >  build_package(child.buf, child.op);
> >  break;
> > +case DEF_BLOCK: {
> > +uint8_t *start = (uint8_t *)parent_ctx->buf->data +
> > + parent_ctx->buf->len;
> > +uint32_t le32_len = cpu_to_le32(child.buf->len);
> > +
> > +/* create linker entry for the DefinitionBlock */
> > +bios_linker_loader_add_checksum(parent_ctx->linker,
> > +ACPI_BUILD_TABLE_FILE,
> > +parent_ctx->buf->data,
> > +start, child.buf->len, start + 9 /* checksum offset */);
> > +
> > +/* set DefinitionBlock length at TableLength offset*/
> > +memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
> > +break;
> > +}
> >  default:
> >  break;
> >  }
> > @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed 
> > min_fixed,
> >dec, addr_gran, addr_min, addr_max,
> >addr_trans, len, flags);
> >  }
> > +
> > +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
> > +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> > +   const char *oem_id, const char *oem_table_id,
> > +   uint32_t oem_revision)
> > +{
> > +int len;
> > +AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
> > +
> > +assert(strlen(signature) == 4);
> > +g_array_append_vals(var.buf, signature, 4);
> > +build_append_value(var.buf, 0, 4); /* Length place holder */
> > +build_append_byte(var.buf, revision);
> > +build_append_byte(var.buf, 0); /* place holder for Checksum */
> > +
> > +len = strlen(oem_id);
> > +assert(len <= 6);
> > +g_array_append_vals(var.buf, oem_id, len);
> > +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
> > +
> > +len = strlen(oem_table_id);
> > +assert(len <= 8);
> > +g_array_append_vals(var.buf, oem_table_id, len);
> > +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
> > +
> > +build_append_value(var.buf, oem_revision, 4);
> > +g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* 
> > asl_compiler_id */
> > +build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
> > +
> > +return var;
> > +}
> 
> This function is similar with build_header() in hw/i386/acpi-build.c
> But the format of omt_id, oem_table_id, asl_compiler_id are not exactly same.
> Maybe we should make it consistent.
I've tried to follow APCI spec for definition block here,
which should be identical to build_header().
What exactly is not the same?

> 
> 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 4572c21..9ff8d72 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -270,7 +270,6 @@ static void acpi_get_pci_info(PcPciInfo *info)
> >  #define ACPI_BUILD_APPNAME6 "BOCHS "
> >  #define ACPI_BUILD_APPNAME4 "BXPC"
> >  
> > -#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
> >  #define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
> >  #define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
> >  
> > diff --git a/include/hw/acpi/acpi-build-utils.h 
> > b/include/hw/acpi/acpi-build-utils.h
> > index 5e8db3d..868d439 100644
> > --- a/include/hw/acpi/acpi-build-utils.h
> > +++ b/include/hw/acpi/acpi-build-utils.h
> > @@ -11,12 +11,17 @@ typedef enum {
> >  EXT_PACKAGE,
> >  BUFFER,
> >  RES_TEMPLATE,
> > +DEF_BLOCK,
> >  } AcpiBlockFlags;
> >  
> > +#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
> > +#define ACPI_BUILD_APPNAME4 "BXPC"
> > +
> >  typedef struct AcpiAml {
> >  GArray *buf;
> >  uint8_t op;
> >  AcpiBlockFlags block_flags;
> > +GArray *linker;
> >  } AcpiAml;
> >  
> >  typedef enum {
> > @@ -146,6 +151,9 @@ AcpiAml acpi_qword_memory(acpiDecode dec, acpiMinFixed 
> > min_fixed,
> >uint64_t len);
> >  
> >  /* Block ASL object primitives */
> > +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
> > +   const char *oem_id, const char *oem_table_id,
> > +

[Qemu-devel] [RFC PATCH v2 08/11] hw/arm/virt-acpi-build: Generate GTDT table

2015-01-29 Thread Shannon Zhao
ACPI v5.1 defines GTDT for ARM devices as a place to describe timer
related information in the system. The Arch Timer interrupts must
be provided for GTDT.

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c|   31 +++
 include/hw/acpi/acpi-defs.h |   37 +
 2 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 64a3022..ac0a864 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -176,6 +176,34 @@ static void acpi_dsdt_add_virtio(AcpiAml *scope, const 
hwaddr *mmio_addrs,
 }
 }
 
+/* GTDT */
+static void
+build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+{
+int gtdt_start = table_data->len;
+const struct acpi_gtdt_info *info = guest_info->gtdt_info;
+AcpiGenericTimerTable *gtdt;
+
+gtdt = acpi_data_push(table_data, sizeof *gtdt);
+/* The interrupt values are the same with the device tree when adding 16 */
+gtdt->secure_el1_interrupt = info->timer_s_el1;
+gtdt->secure_el1_flags = ACPI_EDGE_SENSITIVE;
+
+gtdt->non_secure_el1_interrupt = info->timer_ns_el1;
+gtdt->non_secure_el1_flags = ACPI_EDGE_SENSITIVE;
+
+gtdt->virtual_timer_interrupt = info->timer_virt;
+gtdt->virtual_timer_flags = ACPI_EDGE_SENSITIVE;
+
+gtdt->non_secure_el2_interrupt = info->timer_ns_el2;
+gtdt->non_secure_el2_flags = ACPI_EDGE_SENSITIVE;
+
+build_header(linker, table_data,
+ (void *)(table_data->data + gtdt_start), "GTDT",
+ ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4,
+ table_data->len - gtdt_start, 1);
+}
+
 /* MADT */
 static void
 build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
@@ -315,6 +343,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, 
AcpiBuildTables *tables)
 acpi_add_table(table_offsets, tables->table_data.buf);
 build_madt(tables->table_data.buf, tables->linker, guest_info, &cpuinfo);
 
+acpi_add_table(table_offsets, tables->table_data.buf);
+build_gtdt(tables->table_data.buf, tables->linker, guest_info);
+
 /* Cleanup memory that's no longer used. */
 g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index e343728..ee40a5e 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -318,6 +318,43 @@ struct AcpiMadtGenericDistributor {
 typedef struct AcpiMadtGenericDistributor AcpiMadtGenericDistributor;
 
 /*
+ * Generic Timer Description Table (GTDT)
+ */
+
+#define ACPI_GTDT_INTERRUPT_MODE(1)
+#define ACPI_GTDT_INTERRUPT_POLARITY(1<<1)
+#define ACPI_GTDT_ALWAYS_ON (1<<2)
+
+/* Triggering */
+
+#define ACPI_LEVEL_SENSITIVE(uint8_t) 0x00
+#define ACPI_EDGE_SENSITIVE (uint8_t) 0x01
+
+/* Polarity */
+
+#define ACPI_ACTIVE_HIGH(uint8_t) 0x00
+#define ACPI_ACTIVE_LOW (uint8_t) 0x01
+#define ACPI_ACTIVE_BOTH(uint8_t) 0x02
+
+struct AcpiGenericTimerTable {
+ACPI_TABLE_HEADER_DEF
+uint64_t counter_block_addresss;
+uint32_t reserved;
+uint32_t secure_el1_interrupt;
+uint32_t secure_el1_flags;
+uint32_t non_secure_el1_interrupt;
+uint32_t non_secure_el1_flags;
+uint32_t virtual_timer_interrupt;
+uint32_t virtual_timer_flags;
+uint32_t non_secure_el2_interrupt;
+uint32_t non_secure_el2_flags;
+uint64_t counter_read_block_address;
+uint32_t platform_timer_count;
+uint32_t platform_timer_offset;
+} QEMU_PACKED;
+typedef struct AcpiGenericTimerTable AcpiGenericTimerTable;
+
+/*
  * HPET Description Table
  */
 struct Acpi20Hpet {
-- 
1.7.1





Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()

2015-01-29 Thread Igor Mammedov
On Thu, 29 Jan 2015 15:46:32 +0800
Shannon Zhao  wrote:

> On 2015/1/28 18:00, Igor Mammedov wrote:
> > On Wed, 28 Jan 2015 09:56:26 +0200
> > "Michael S. Tsirkin"  wrote:
> > 
> >>> I've tried redo series with passing alloc list as first argument,
> >>> looks ugly as hell
> >>
> >> I tried too. Not too bad at all. See below:
> >>
> >> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> >> index f66da5d..820504a 100644
> >> --- a/hw/i386/acpi-build.c
> >> +++ b/hw/i386/acpi-build.c
> >> @@ -491,14 +491,14 @@ static void acpi_set_pci_info(void)
> >>  }
> >>  }
> >>  
> >> -static void build_append_pcihp_notify_entry(AcpiAml *method, int slot)
> >> +static void build_append_pcihp_notify_entry(AmlPool *p, AcpiAml *method, 
> >> int slot)
> >>  {
> >> -AcpiAml if_ctx;
> >> +AcpiAml *if_ctx;
> >>  int32_t devfn = PCI_DEVFN(slot, 0);
> >>  
> >> -if_ctx = acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> >> -aml_append(&if_ctx, acpi_notify(acpi_name("S%.02X", devfn), 
> >> acpi_arg1()));
> >> -aml_append(method, if_ctx);
> >> +if_ctx = acpi_if(p, acpi_and(p, acpi_arg0(), acpi_int(p, 0x1U << 
> >> slot)));
> >> +aml_append(p, if_ctx, acpi_notify(p, acpi_name(p, "S%.02X", devfn), 
> >> acpi_arg1(p)));
> >> +aml_append(p, method, if_ctx);
> >>  }
> >>  
> >>  static void build_append_pci_bus_devices(AcpiAml *parent_scope, PCIBus 
> >> *bus,
> >>
> >> What exactly is the problem?  A tiny bit more verbose but the lifetime
> >> of all objects is now explicit.
> > every usage of aml_foo()/build_append_pcihp_notify_entry() tags along
> > extra pointer which is not really necessary for user to know. If possible
> > user shouldn't care about it and concentrate on composing AML instead.
> > 
> > Whole point of passing AmlPool and record every allocation is to avoid
> > mistakes like:
> > 
> > acpi_if(acpi_and(acpi_arg0(), acpi_int(0x1U << slot)));
> > 
> > and forgetting to assign object returned by call anywhere,
> > it's basically the same as calling malloc() without
> > using result anywhere, however neither libc nor glib
> > force user to pass allocator (in our case garbage collector)
> > in every call that allocates memory. Let's just follow common
> > convention here (#4) where an object is allocated by API call
> > (i.e like object_new(FOO), gtk_widget_foo()).
> > 
> > Hence is suggesting at least to hide AmlPool internally in API
> > without exposing it to user. We can provide for user
> > init/free API to manage internal AmlPool manually, allowing
> > him to select when to do initialization and cleanup.
> > 
> > Claudio, Marcel, Shannon,
> > As the first API users, could you give your feedback on the topic.
> > 
> 
> In my opinion, it's good to make users focused on ACPI table construction 
> through
> auto memory management. And it makes the code clear.
> 
> PS:
> We're talking about use-after-free, like below example. But this example 
> really exist?
> During generating ACPI tables for virt machine, I don't encounter this case.
> 
> For example:
>   aml_append(&a, b);
>   aml_append(&a, b);
Thanks for your reply,

yesterday we've came to a compromise, where API will stay as it is externally
only it will take all AML arguments by pointer. And we would introduce
allocation list internally inside API, User only would need to initialize it
before using API and free it after using API.

> 
> Thanks,
> Shannon
> 
> 




Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term

2015-01-29 Thread Shannon Zhao
On 2015/1/29 16:45, Igor Mammedov wrote:
> On Thu, 29 Jan 2015 16:02:47 +0800
> Shannon Zhao  wrote:
> 
>> > On 2015/1/22 22:50, Igor Mammedov wrote:
>>> > > Signed-off-by: Igor Mammedov 
>>> > > ---
>>> > >  hw/acpi/acpi-build-utils.c | 47 
>>> > > ++
>>> > >  hw/i386/acpi-build.c   |  1 -
>>> > >  include/hw/acpi/acpi-build-utils.h |  8 +++
>>> > >  3 files changed, 55 insertions(+), 1 deletion(-)
>>> > > 
>>> > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
>>> > > index b19d370..58f88cd 100644
>>> > > --- a/hw/acpi/acpi-build-utils.c
>>> > > +++ b/hw/acpi/acpi-build-utils.c
>>> > > @@ -26,6 +26,7 @@
>>> > >  #include 
>>> > >  #include "hw/acpi/acpi-build-utils.h"
>>> > >  #include "qemu/bswap.h"
>>> > > +#include "hw/acpi/bios-linker-loader.h"
>>> > >  
>>> > >  GArray *build_alloc_array(void)
>>> > >  {
>>> > > @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml child)
>>> > >  build_prepend_int(child.buf, child.buf->len);
>>> > >  build_package(child.buf, child.op);
>>> > >  break;
>>> > > +case DEF_BLOCK: {
>>> > > +uint8_t *start = (uint8_t *)parent_ctx->buf->data +
>>> > > + parent_ctx->buf->len;
>>> > > +uint32_t le32_len = cpu_to_le32(child.buf->len);
>>> > > +
>>> > > +/* create linker entry for the DefinitionBlock */
>>> > > +bios_linker_loader_add_checksum(parent_ctx->linker,
>>> > > +ACPI_BUILD_TABLE_FILE,
>>> > > +parent_ctx->buf->data,
>>> > > +start, child.buf->len, start + 9 /* checksum offset */);
>>> > > +
>>> > > +/* set DefinitionBlock length at TableLength offset*/
>>> > > +memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
>>> > > +break;
>>> > > +}
>>> > >  default:
>>> > >  break;
>>> > >  }
>>> > > @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, 
>>> > > acpiMinFixed min_fixed,
>>> > >dec, addr_gran, addr_min, addr_max,
>>> > >addr_trans, len, flags);
>>> > >  }
>>> > > +
>>> > > +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
>>> > > +AcpiAml acpi_def_block(const char *signature, uint8_t revision,
>>> > > +   const char *oem_id, const char *oem_table_id,
>>> > > +   uint32_t oem_revision)
>>> > > +{
>>> > > +int len;
>>> > > +AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
>>> > > +
>>> > > +assert(strlen(signature) == 4);
>>> > > +g_array_append_vals(var.buf, signature, 4);
>>> > > +build_append_value(var.buf, 0, 4); /* Length place holder */
>>> > > +build_append_byte(var.buf, revision);
>>> > > +build_append_byte(var.buf, 0); /* place holder for Checksum */
>>> > > +
>>> > > +len = strlen(oem_id);
>>> > > +assert(len <= 6);
>>> > > +g_array_append_vals(var.buf, oem_id, len);
>>> > > +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
>>> > > +
>>> > > +len = strlen(oem_table_id);
>>> > > +assert(len <= 8);
>>> > > +g_array_append_vals(var.buf, oem_table_id, len);
>>> > > +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
>>> > > +
>>> > > +build_append_value(var.buf, oem_revision, 4);
>>> > > +g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* 
>>> > > asl_compiler_id */
>>> > > +build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
>>> > > +
>>> > > +return var;
>>> > > +}
>> > 
>> > This function is similar with build_header() in hw/i386/acpi-build.c
>> > But the format of omt_id, oem_table_id, asl_compiler_id are not exactly 
>> > same.
>> > Maybe we should make it consistent.
> I've tried to follow APCI spec for definition block here,
> which should be identical to build_header().
> What exactly is not the same?
> 

Sorry, I don make myself clear.
I mean that the values of omt_id, oem_table_id, asl_compiler_id are different 
between
using build_header and acpi_def_block.
E.g. using acpi_def_block the asl_compiler_id would be "BXPC" while 
build_header is blank.

I think we should make the omt_id, oem_table_id, asl_compiler_id as parameters 
of the
functions, then users assign the value.

Thanks,
Shannon




Re: [Qemu-devel] [PATCH v2 42/47] acpi: add acpi_def_block() term

2015-01-29 Thread Igor Mammedov
On Thu, 29 Jan 2015 17:01:02 +0800
Shannon Zhao  wrote:

> On 2015/1/29 16:45, Igor Mammedov wrote:
> > On Thu, 29 Jan 2015 16:02:47 +0800
> > Shannon Zhao  wrote:
> > 
> >> > On 2015/1/22 22:50, Igor Mammedov wrote:
> >>> > > Signed-off-by: Igor Mammedov 
> >>> > > ---
> >>> > >  hw/acpi/acpi-build-utils.c | 47 
> >>> > > ++
> >>> > >  hw/i386/acpi-build.c   |  1 -
> >>> > >  include/hw/acpi/acpi-build-utils.h |  8 +++
> >>> > >  3 files changed, 55 insertions(+), 1 deletion(-)
> >>> > > 
> >>> > > diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
> >>> > > index b19d370..58f88cd 100644
> >>> > > --- a/hw/acpi/acpi-build-utils.c
> >>> > > +++ b/hw/acpi/acpi-build-utils.c
> >>> > > @@ -26,6 +26,7 @@
> >>> > >  #include 
> >>> > >  #include "hw/acpi/acpi-build-utils.h"
> >>> > >  #include "qemu/bswap.h"
> >>> > > +#include "hw/acpi/bios-linker-loader.h"
> >>> > >  
> >>> > >  GArray *build_alloc_array(void)
> >>> > >  {
> >>> > > @@ -312,6 +313,21 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml 
> >>> > > child)
> >>> > >  build_prepend_int(child.buf, child.buf->len);
> >>> > >  build_package(child.buf, child.op);
> >>> > >  break;
> >>> > > +case DEF_BLOCK: {
> >>> > > +uint8_t *start = (uint8_t *)parent_ctx->buf->data +
> >>> > > + parent_ctx->buf->len;
> >>> > > +uint32_t le32_len = cpu_to_le32(child.buf->len);
> >>> > > +
> >>> > > +/* create linker entry for the DefinitionBlock */
> >>> > > +bios_linker_loader_add_checksum(parent_ctx->linker,
> >>> > > +ACPI_BUILD_TABLE_FILE,
> >>> > > +parent_ctx->buf->data,
> >>> > > +start, child.buf->len, start + 9 /* checksum offset */);
> >>> > > +
> >>> > > +/* set DefinitionBlock length at TableLength offset*/
> >>> > > +memcpy(child.buf->data + 4, &le32_len, sizeof le32_len);
> >>> > > +break;
> >>> > > +}
> >>> > >  default:
> >>> > >  break;
> >>> > >  }
> >>> > > @@ -843,3 +859,34 @@ AcpiAml acpi_qword_memory(acpiDecode dec, 
> >>> > > acpiMinFixed min_fixed,
> >>> > >dec, addr_gran, addr_min, addr_max,
> >>> > >addr_trans, len, flags);
> >>> > >  }
> >>> > > +
> >>> > > +/* ACPI 5.0: 20.2.1 Table and Table Header Encoding */
> >>> > > +AcpiAml ()(const char *signature, uint8_t revision,
> >>> > > +   const char *oem_id, const char *oem_table_id,
> >>> > > +   uint32_t oem_revision)
> >>> > > +{
> >>> > > +int len;
> >>> > > +AcpiAml var = aml_allocate_internal(0, DEF_BLOCK);
> >>> > > +
> >>> > > +assert(strlen(signature) == 4);
> >>> > > +g_array_append_vals(var.buf, signature, 4);
> >>> > > +build_append_value(var.buf, 0, 4); /* Length place holder */
> >>> > > +build_append_byte(var.buf, revision);
> >>> > > +build_append_byte(var.buf, 0); /* place holder for Checksum */
> >>> > > +
> >>> > > +len = strlen(oem_id);
> >>> > > +assert(len <= 6);
> >>> > > +g_array_append_vals(var.buf, oem_id, len);
> >>> > > +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 6 - len);
> >>> > > +
> >>> > > +len = strlen(oem_table_id);
> >>> > > +assert(len <= 8);
> >>> > > +g_array_append_vals(var.buf, oem_table_id, len);
> >>> > > +g_array_append_vals(var.buf, "\0\0\0\0\0\0\0\0", 8 - len);
> >>> > > +
> >>> > > +build_append_value(var.buf, oem_revision, 4);
> >>> > > +g_array_append_vals(var.buf, ACPI_BUILD_APPNAME4, 4); /* 
> >>> > > asl_compiler_id */
> >>> > > +build_append_value(var.buf, 1, 4); /* asl_compiler_revision */
> >>> > > +
> >>> > > +return var;
> >>> > > +}
> >> > 
> >> > This function is similar with build_header() in hw/i386/acpi-build.c
> >> > But the format of omt_id, oem_table_id, asl_compiler_id are not exactly 
> >> > same.
> >> > Maybe we should make it consistent.
> > I've tried to follow APCI spec for definition block here,
> > which should be identical to build_header().
> > What exactly is not the same?
> > 
> 
> Sorry, I don make myself clear.
> I mean that the values of omt_id, oem_table_id, asl_compiler_id are different 
> between
> using build_header and acpi_def_block.
> E.g. using acpi_def_block the asl_compiler_id would be "BXPC" while 
> build_header is blank.
That's no true, build_header() sets asl_compiler_id to ACPI_BUILD_APPNAME4
the same way as does acpi_def_block().

> 
> I think we should make the omt_id, oem_table_id, asl_compiler_id as 
> parameters of the
> functions, then users assign the value.
The only thing not exposed to API user is asl_compiler_id and
asl_compiler_revision, I'll add them as arguments of acpi_def_block()
on the next respin to be closer to ACPI spec.

> 
> Thanks,
> Shannon
> 




Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits

2015-01-29 Thread Thomas Huth

 Hi,

On Thu, 29 Jan 2015 11:11:32 +1100
David Gibson  wrote:

> On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > On Thu, 22 Jan 2015 12:43:43 +1100
> > David Gibson  wrote:
> > 
> > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > host and guest features to 64, which should suffice for a while.
> > > > 
> > > > vhost and migration have been ignored for now.
> > > 
> > > [snip]
> > > 
> > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > index f6c0379..08141c7 100644
> > > > --- a/include/hw/virtio/virtio.h
> > > > +++ b/include/hw/virtio/virtio.h
> > > > @@ -55,6 +55,12 @@
> > > >  /* A guest should never accept this.  It implies negotiation is 
> > > > broken. */
> > > >  #define VIRTIO_F_BAD_FEATURE   30
> > > >  
> > > > +/* v1.0 compliant. */
> > > > +#define VIRTIO_F_VERSION_1  32
> > > 
> > > This is already in the kernel header, isn't it?
> 
> > 
> > Yes. But nearly all files include this header but not the kernel
> > header.
> 
> Can't you change that?  Or this file include the kernel header?
 
AFAIK non-KVM code should never try to include one of the Linux headers
to avoid breaking on non-Linux platforms (for example  is
not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
So it's a little bit ugly to define these things twice, but it seems
the only way to stay portable.

 Thomas


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v2 2/9] qmp hmp: Improve error messages when SPICE is not in use

2015-01-29 Thread Markus Armbruster
Commit 7572150 adopted QERR_DEVICE_NOT_ACTIVE for the purpose,
probably because adding another error seemed cumbersome overkill.
Produces "No spice device has been activated", which is awkward.

We've since abandoned our quest for "rich" error objects.  Time to
undo the damage to this error message.  Replace it by "SPICE is not in
use".

Keep the stupid DeviceNotActive ErrorClass for compatibility, even
though Libvirt doesn't use it.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Gerd Hoffmann 
---
 include/ui/qemu-spice.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index db7926d..762e063 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -91,8 +91,8 @@ static inline int qemu_spice_display_add_client(int csock, 
int skipauth,
 static inline bool qemu_using_spice(Error **errp)
 {
 if (!using_spice) {
-/* correct one? spice isn't a device ,,, */
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "spice");
+error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
+  "SPICE is not in use");
 return false;
 }
 return true;
-- 
1.9.3




[Qemu-devel] [PATCH v2 5/9] qmp: Simplify recognition of capability negotiation command

2015-01-29 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 monitor.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/monitor.c b/monitor.c
index 8323de3..2ac40c9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4783,9 +4783,9 @@ static int monitor_can_read(void *opaque)
 return (mon->suspend_cnt == 0) ? 1 : 0;
 }
 
-static int invalid_qmp_mode(const Monitor *mon, const char *cmd_name)
+static int invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd)
 {
-int is_cap = compare_cmd(cmd_name, "qmp_capabilities");
+int is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
 return (qmp_cmd_mode(mon) ? is_cap : !is_cap);
 }
 
@@ -5079,13 +5079,8 @@ static void handle_qmp_command(JSONMessageParser 
*parser, QList *tokens)
 
 cmd_name = qdict_get_str(input, "execute");
 trace_handle_qmp_command(mon, cmd_name);
-if (invalid_qmp_mode(mon, cmd_name)) {
-qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
-goto err_out;
-}
-
 cmd = qmp_find_cmd(cmd_name);
-if (!cmd) {
+if (!cmd || invalid_qmp_mode(mon, cmd)) {
 qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
 goto err_out;
 }
-- 
1.9.3




[Qemu-devel] [PATCH v2 3/9] hmp: Compile hmp_info_spice() only with CONFIG_SPICE

2015-01-29 Thread Markus Armbruster
It's dead code when CONFIG_SPICE is off.  If it wasn't, it would crash
dereferencing the null pointer returned by the qmp_query_spice()
dummy in qmp.c.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Gerd Hoffmann 
---
 hmp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hmp.c b/hmp.c
index 481be80..a42c5c0 100644
--- a/hmp.c
+++ b/hmp.c
@@ -535,6 +535,7 @@ out:
 qapi_free_VncInfo(info);
 }
 
+#ifdef CONFIG_SPICE
 void hmp_info_spice(Monitor *mon, const QDict *qdict)
 {
 SpiceChannelList *chan;
@@ -581,6 +582,7 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict)
 out:
 qapi_free_SpiceInfo(info);
 }
+#endif
 
 void hmp_info_balloon(Monitor *mon, const QDict *qdict)
 {
-- 
1.9.3




[Qemu-devel] [PATCH v2 7/9] balloon: Inline qemu_balloon(), qemu_balloon_status()

2015-01-29 Thread Markus Armbruster
... and simplify a bit.  Permits factoring out common error checks in
the next commit.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 balloon.c | 42 +-
 1 file changed, 13 insertions(+), 29 deletions(-)

diff --git a/balloon.c b/balloon.c
index b70da4f..2884c2d 100644
--- a/balloon.c
+++ b/balloon.c
@@ -62,25 +62,6 @@ void qemu_remove_balloon_handler(void *opaque)
 balloon_opaque = NULL;
 }
 
-static int qemu_balloon(ram_addr_t target)
-{
-if (!balloon_event_fn) {
-return 0;
-}
-trace_balloon_event(balloon_opaque, target);
-balloon_event_fn(balloon_opaque, target);
-return 1;
-}
-
-static int qemu_balloon_status(BalloonInfo *info)
-{
-if (!balloon_stat_fn) {
-return 0;
-}
-balloon_stat_fn(balloon_opaque, info);
-return 1;
-}
-
 BalloonInfo *qmp_query_balloon(Error **errp)
 {
 BalloonInfo *info;
@@ -90,30 +71,33 @@ BalloonInfo *qmp_query_balloon(Error **errp)
 return NULL;
 }
 
+if (!balloon_stat_fn) {
+error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
+return NULL;
+}
+
 info = g_malloc0(sizeof(*info));
-
-if (qemu_balloon_status(info) == 0) {
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
-qapi_free_BalloonInfo(info);
-return NULL;
-}
-
+balloon_stat_fn(balloon_opaque, info);
 return info;
 }
 
-void qmp_balloon(int64_t value, Error **errp)
+void qmp_balloon(int64_t target, Error **errp)
 {
 if (kvm_enabled() && !kvm_has_sync_mmu()) {
 error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
 return;
 }
 
-if (value <= 0) {
+if (target <= 0) {
 error_set(errp, QERR_INVALID_PARAMETER_VALUE, "target", "a size");
 return;
 }
 
-if (qemu_balloon(value) == 0) {
+if (!balloon_event_fn) {
 error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
+return;
 }
+
+trace_balloon_event(balloon_opaque, target);
+balloon_event_fn(balloon_opaque, target);
 }
-- 
1.9.3




[Qemu-devel] [PATCH v2 9/9] balloon: Eliminate silly QERR_ macros

2015-01-29 Thread Markus Armbruster
The QERR_ macros are leftovers from the days of "rich" error objects.
They're used with error_set() and qerror_report(), and expand into the
first *two* arguments.  This trickiness has become pointless.  Clean
up the balloon ones.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Signed-off-by: Markus Armbruster 
---
 balloon.c | 6 --
 include/qapi/qmp/qerror.h | 6 --
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/balloon.c b/balloon.c
index 728bb70..dea19a4 100644
--- a/balloon.c
+++ b/balloon.c
@@ -39,11 +39,13 @@ static void *balloon_opaque;
 static bool have_ballon(Error **errp)
 {
 if (kvm_enabled() && !kvm_has_sync_mmu()) {
-error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
+error_set(errp, ERROR_CLASS_KVM_MISSING_CAP,
+  "Using KVM without synchronous MMU, balloon unavailable");
 return false;
 }
 if (!balloon_event_fn) {
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
+error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
+  "No balloon device has been activated");
 return false;
 }
 return true;
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 28f980e..eeaf0cb 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -70,9 +70,6 @@ void qerror_report_err(Error *err);
 #define QERR_DEVICE_NO_HOTPLUG \
 ERROR_CLASS_GENERIC_ERROR, "Device '%s' does not support hotplugging"
 
-#define QERR_DEVICE_NOT_ACTIVE \
-ERROR_CLASS_DEVICE_NOT_ACTIVE, "No %s device has been activated"
-
 #define QERR_DEVICE_NOT_ENCRYPTED \
 ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted"
 
@@ -109,9 +106,6 @@ void qerror_report_err(Error *err);
 #define QERR_JSON_PARSING \
 ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
 
-#define QERR_KVM_MISSING_CAP \
-ERROR_CLASS_KVM_MISSING_CAP, "Using KVM without %s, %s unavailable"
-
 #define QERR_MIGRATION_ACTIVE \
 ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
 
-- 
1.9.3




[Qemu-devel] [PATCH v2 8/9] balloon: Factor out common "is balloon active" test

2015-01-29 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 balloon.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/balloon.c b/balloon.c
index 2884c2d..728bb70 100644
--- a/balloon.c
+++ b/balloon.c
@@ -36,6 +36,19 @@ static QEMUBalloonEvent *balloon_event_fn;
 static QEMUBalloonStatus *balloon_stat_fn;
 static void *balloon_opaque;
 
+static bool have_ballon(Error **errp)
+{
+if (kvm_enabled() && !kvm_has_sync_mmu()) {
+error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
+return false;
+}
+if (!balloon_event_fn) {
+error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
+return false;
+}
+return true;
+}
+
 int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
  QEMUBalloonStatus *stat_func, void *opaque)
 {
@@ -66,13 +79,7 @@ BalloonInfo *qmp_query_balloon(Error **errp)
 {
 BalloonInfo *info;
 
-if (kvm_enabled() && !kvm_has_sync_mmu()) {
-error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
-return NULL;
-}
-
-if (!balloon_stat_fn) {
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
+if (!have_ballon(errp)) {
 return NULL;
 }
 
@@ -83,8 +90,7 @@ BalloonInfo *qmp_query_balloon(Error **errp)
 
 void qmp_balloon(int64_t target, Error **errp)
 {
-if (kvm_enabled() && !kvm_has_sync_mmu()) {
-error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
+if (!have_ballon(errp)) {
 return;
 }
 
@@ -92,11 +98,6 @@ void qmp_balloon(int64_t target, Error **errp)
 error_set(errp, QERR_INVALID_PARAMETER_VALUE, "target", "a size");
 return;
 }
-
-if (!balloon_event_fn) {
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
-return;
-}
 
 trace_balloon_event(balloon_opaque, target);
 balloon_event_fn(balloon_opaque, target);
-- 
1.9.3




[Qemu-devel] [PATCH v4 05/18] spapr_pci: Make find_phb()/find_dev() public

2015-01-29 Thread Alexey Kardashevskiy
This makes find_phb()/find_dev() public and changed its names
to spapr_pci_find_phb()/spapr_pci_find_dev() as they are going to
be used from other parts of QEMU such as VFIO DDW (dynamic DMA window)
or VFIO PCI error injection or VFIO EEH handling - in all these
cases there are RTAS calls which are addressed to BUID+config_addr
in IEEE1275 format.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: David Gibson 
---
 hw/ppc/spapr_pci.c  | 22 +++---
 include/hw/pci-host/spapr.h |  4 
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 64c7702..3665f8a 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -47,7 +47,7 @@
 #define RTAS_TYPE_MSI   1
 #define RTAS_TYPE_MSIX  2
 
-static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, uint64_t buid)
+sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid)
 {
 sPAPRPHBState *sphb;
 
@@ -61,10 +61,10 @@ static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, 
uint64_t buid)
 return NULL;
 }
 
-static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid,
-   uint32_t config_addr)
+PCIDevice *spapr_pci_find_dev(sPAPREnvironment *spapr, uint64_t buid,
+  uint32_t config_addr)
 {
-sPAPRPHBState *sphb = find_phb(spapr, buid);
+sPAPRPHBState *sphb = spapr_pci_find_phb(spapr, buid);
 PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
 int bus_num = (config_addr >> 16) & 0xFF;
 int devfn = (config_addr >> 8) & 0xFF;
@@ -95,7 +95,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, 
uint64_t buid,
 return;
 }
 
-pci_dev = find_dev(spapr, buid, addr);
+pci_dev = spapr_pci_find_dev(spapr, buid, addr);
 addr = rtas_pci_cfgaddr(addr);
 
 if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
@@ -162,7 +162,7 @@ static void finish_write_pci_config(sPAPREnvironment 
*spapr, uint64_t buid,
 return;
 }
 
-pci_dev = find_dev(spapr, buid, addr);
+pci_dev = spapr_pci_find_dev(spapr, buid, addr);
 addr = rtas_pci_cfgaddr(addr);
 
 if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
@@ -280,9 +280,9 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
 }
 
 /* Fins sPAPRPHBState */
-phb = find_phb(spapr, buid);
+phb = spapr_pci_find_phb(spapr, buid);
 if (phb) {
-pdev = find_dev(spapr, buid, config_addr);
+pdev = spapr_pci_find_dev(spapr, buid, config_addr);
 }
 if (!phb || !pdev) {
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -381,9 +381,9 @@ static void 
rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
 spapr_pci_msi *msi;
 
 /* Find sPAPRPHBState */
-phb = find_phb(spapr, buid);
+phb = spapr_pci_find_phb(spapr, buid);
 if (phb) {
-pdev = find_dev(spapr, buid, config_addr);
+pdev = spapr_pci_find_dev(spapr, buid, config_addr);
 }
 if (!phb || !pdev) {
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -530,7 +530,7 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
-if (find_phb(spapr, sphb->buid)) {
+if (spapr_pci_find_phb(spapr, sphb->buid)) {
 error_setg(errp, "PCI host bridges must have unique BUIDs");
 return;
 }
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 92695b6..5c91387 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -123,4 +123,8 @@ void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr 
addr);
 
 void spapr_pci_rtas_init(void);
 
+sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid);
+PCIDevice *spapr_pci_find_dev(sPAPREnvironment *spapr, uint64_t buid,
+  uint32_t config_addr);
+
 #endif /* __HW_SPAPR_PCI_H__ */
-- 
2.0.0




[Qemu-devel] [PATCH v4 11/18] spapr_pci/spapr_pci_vfio: Support Dynamic DMA Windows (DDW)

2015-01-29 Thread Alexey Kardashevskiy
This implements DDW for emulated and VFIO PHB.

This removes all DMA windows on reset and creates the default window,
same is done on the "ibm,reset-pe-dma-window" call.
This converts sPAPRPHBClass::finish_realize to sPAPRPHBClass::ddw_reset
and others.

The "ddw" property is enabled by default on a PHB but for compatibility
pseries-2.1 machine disables it.

Signed-off-by: Alexey Kardashevskiy 
---
Changes:
v4:
* reset handler is back in generalized form

v3:
* removed reset
* windows_num is now 1 or bigger rather than 0-based value and it is only
changed in PHB code, not in RTAS
* added page mask check in create()
* added SPAPR_PCI_DDW_MAX_WINDOWS to track how many windows are already
created

v2:
* tested on hacked emulated E1000
* implemented DDW reset on the PHB reset
* spapr_pci_ddw_remove/spapr_pci_ddw_reset are public for reuse by VFIO

spapr_pci_vfio: Enable DDW

This implements DDW for VFIO. Host kernel support is required for this.

After this patch DDW will be enabled on all machines but pseries-2.1.

Signed-off-by: Alexey Kardashevskiy 
---
Changes:
v2:
* remove()/reset() callbacks use spapr_pci's ones
---
 hw/ppc/spapr_pci.c  | 160 +++-
 hw/ppc/spapr_pci_vfio.c |  98 +--
 include/hw/pci-host/spapr.h |  15 -
 3 files changed, 203 insertions(+), 70 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 6bd00e8..3ec03be 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -469,6 +469,126 @@ static const MemoryRegionOps spapr_msi_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN
 };
 
+static int spapr_phb_get_win_num_cb(Object *child, void *opaque)
+{
+if (object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE)) {
+++*(unsigned *)opaque;
+}
+return 0;
+}
+
+unsigned spapr_phb_get_win_num(sPAPRPHBState *sphb)
+{
+unsigned ret = 0;
+
+object_child_foreach(OBJECT(sphb), spapr_phb_get_win_num_cb, &ret);
+
+return ret;
+}
+
+/*
+ * Dynamic DMA windows
+ */
+static int spapr_pci_ddw_query(sPAPRPHBState *sphb,
+   uint32_t *windows_supported,
+   uint32_t *page_size_mask,
+   uint32_t *dma32_window_size,
+   uint64_t *dma64_window_size)
+{
+*windows_supported = SPAPR_PCI_DDW_MAX_WINDOWS;
+*page_size_mask = DDW_PGSIZE_64K | DDW_PGSIZE_16M;
+*dma32_window_size = SPAPR_PCI_TCE32_WIN_SIZE;
+*dma64_window_size = ram_size;
+
+return 0;
+}
+
+static int spapr_pci_ddw_create(sPAPRPHBState *sphb, uint32_t liobn,
+uint32_t page_shift, uint32_t window_shift,
+sPAPRTCETable **ptcet)
+{
+uint64_t bus_offset = spapr_phb_get_win_num(sphb) ?
+  SPAPR_PCI_TCE64_START : 0;
+
+if (((page_shift != 16) && (page_shift != 24) && (page_shift != 12))) {
+return -1;
+}
+
+*ptcet = spapr_tce_new_table(DEVICE(sphb), liobn,
+ bus_offset,
+ page_shift,
+ 1ULL << (window_shift - page_shift),
+ false);
+if (!*ptcet) {
+return -1;
+}
+memory_region_add_subregion(&sphb->iommu_root, (*ptcet)->bus_offset,
+spapr_tce_get_iommu(*ptcet));
+
+return 0;
+}
+
+int spapr_pci_ddw_remove(sPAPRPHBState *sphb, sPAPRTCETable *tcet)
+{
+memory_region_del_subregion(&sphb->iommu_root,
+spapr_tce_get_iommu(tcet));
+spapr_tce_free_table(tcet);
+
+return 0;
+}
+
+static int spapr_pci_remove_ddw_cb(Object *child, void *opaque)
+{
+sPAPRTCETable *tcet;
+
+tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
+
+if (tcet) {
+sPAPRPHBState *sphb = opaque;
+sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+
+spc->ddw_remove(sphb, tcet);
+}
+
+return 0;
+}
+
+int spapr_pci_ddw_reset(sPAPRPHBState *sphb)
+{
+int ret;
+sPAPRPHBClass *spc;
+sPAPRTCETable *tcet;
+uint32_t windows_supported = 0, page_size_mask = 0, dma32_window_size = 0;
+uint64_t dma64_window_size = 0;
+
+/* Remove all windows */
+object_child_foreach(OBJECT(sphb), spapr_pci_remove_ddw_cb, sphb);
+
+/* Create default 32bit window */
+spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+if (!spc->ddw_create || !spc->ddw_query) {
+return -1;
+}
+
+ret = spc->ddw_query(sphb, &windows_supported, &page_size_mask,
+ &dma32_window_size, &dma64_window_size);
+if (ret) {
+return ret;
+}
+
+sphb->ddw_enabled = (windows_supported > 1);
+
+ret = spc->ddw_create(sphb, SPAPR_PCI_LIOBN(sphb->index, 0),
+  SPAPR_TCE_PAGE_SHIFT, ctzl(dma32_window_size), 
&tcet);
+if (ret) {
+return ret;
+}
+
+object_unref(OBJECT(tc

[Qemu-devel] [PATCH v4 09/18] spapr_rtas: Reserve DDW RTAS token numbers

2015-01-29 Thread Alexey Kardashevskiy
Will be squashed later.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: David Gibson 
---
 include/hw/ppc/spapr.h | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index b442e41..5f4e137 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -382,8 +382,12 @@ int spapr_allocate_irq_block(int num, bool lsi, bool msi);
 #define RTAS_GET_SENSOR_STATE   (RTAS_TOKEN_BASE + 0x1D)
 #define RTAS_IBM_CONFIGURE_CONNECTOR(RTAS_TOKEN_BASE + 0x1E)
 #define RTAS_IBM_OS_TERM(RTAS_TOKEN_BASE + 0x1F)
+#define RTAS_IBM_QUERY_PE_DMA_WINDOW(RTAS_TOKEN_BASE + 0x20)
+#define RTAS_IBM_CREATE_PE_DMA_WINDOW   (RTAS_TOKEN_BASE + 0x21)
+#define RTAS_IBM_REMOVE_PE_DMA_WINDOW   (RTAS_TOKEN_BASE + 0x22)
+#define RTAS_IBM_RESET_PE_DMA_WINDOW(RTAS_TOKEN_BASE + 0x23)
 
-#define RTAS_TOKEN_MAX  (RTAS_TOKEN_BASE + 0x20)
+#define RTAS_TOKEN_MAX  (RTAS_TOKEN_BASE + 0x24)
 
 /* RTAS ibm,get-system-parameter token values */
 #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS  20
-- 
2.0.0




[Qemu-devel] [PATCH v2 0/9] qmp hmp balloon: Cleanups around error reporting

2015-01-29 Thread Markus Armbruster
I'm including balloon patches in the hope that they too can go through
Luiz's tree.

v2:
* PATCH 1+8: Use bool [Eric]
* PATCH 9: Clarify commit message [Eric]
* R-bys retrained since changes are trivial

Markus Armbruster (9):
  qmp hmp: Factor out common "using spice" test
  qmp hmp: Improve error messages when SPICE is not in use
  hmp: Compile hmp_info_spice() only with CONFIG_SPICE
  qmp: Clean up qmp_query_spice() #ifndef !CONFIG_SPICE dummy
  qmp: Simplify recognition of capability negotiation command
  qmp: Eliminate silly QERR_COMMAND_NOT_FOUND macro
  balloon: Inline qemu_balloon(), qemu_balloon_status()
  balloon: Factor out common "is balloon active" test
  balloon: Eliminate silly QERR_ macros

 balloon.c | 59 ++-
 hmp.c |  2 ++
 include/qapi/qmp/qerror.h |  9 
 include/ui/qemu-spice.h   | 10 
 monitor.c | 19 +++
 qapi/qmp-dispatch.c   |  3 ++-
 qmp.c | 27 +++---
 7 files changed, 58 insertions(+), 71 deletions(-)

-- 
1.9.3




[Qemu-devel] [PATCH v4 17/18] target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64

2015-01-29 Thread Alexey Kardashevskiy
Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_iommu.c |  7 ---
 target-ppc/kvm.c | 48 +---
 target-ppc/kvm_ppc.h | 10 +++---
 3 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 1adf568..258f837 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -129,11 +129,12 @@ static MemoryRegionIOMMUOps spapr_iommu_ops = {
 static int spapr_tce_table_realize(DeviceState *dev)
 {
 sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
-uint64_t window_size = (uint64_t)tcet->nb_table << tcet->page_shift;
 
-if (kvm_enabled() && !(window_size >> 32)) {
+if (kvm_enabled()) {
 tcet->table = kvmppc_create_spapr_tce(tcet->liobn,
-  window_size,
+  tcet->nb_table,
+  tcet->bus_offset,
+  tcet->page_shift,
   &tcet->fd,
   tcet->vfio_accel);
 }
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 1edf2b5..5e0e2e8 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -63,6 +63,7 @@ static int cap_booke_sregs;
 static int cap_ppc_smt;
 static int cap_ppc_rma;
 static int cap_spapr_tce;
+static int cap_spapr_tce_64;
 static int cap_spapr_multitce;
 static int cap_spapr_vfio;
 static int cap_hior;
@@ -104,6 +105,7 @@ int kvm_arch_init(KVMState *s)
 cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
 cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
 cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
+cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
 cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE);
 cap_spapr_vfio = false;
 cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
@@ -1994,13 +1996,10 @@ bool kvmppc_spapr_use_multitce(void)
 return cap_spapr_multitce;
 }
 
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
-  bool vfio_accel)
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_shift,
+  uint64_t bus_offset, uint32_t page_shift,
+  int *pfd, bool vfio_accel)
 {
-struct kvm_create_spapr_tce args = {
-.liobn = liobn,
-.window_size = window_size,
-};
 long len;
 int fd;
 void *table;
@@ -2013,14 +2012,41 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t 
window_size, int *pfd,
 return NULL;
 }
 
-fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
-if (fd < 0) {
-fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
-liobn);
+if (cap_spapr_tce_64) {
+struct kvm_create_spapr_tce_64 args = {
+.liobn = liobn,
+.page_shift = page_shift,
+.offset = bus_offset >> page_shift,
+.size = window_shift,
+.flags = 0
+};
+fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE_64, &args);
+if (fd < 0) {
+fprintf(stderr,
+"KVM: Failed to create TCE64 table for liobn 0x%x\n",
+liobn);
+return NULL;
+}
+} else if (cap_spapr_tce) {
+uint64_t window_size = (uint64_t) window_shift << page_shift;
+struct kvm_create_spapr_tce args = {
+.liobn = liobn,
+.window_size = window_size,
+};
+if ((window_size != args.window_size) || bus_offset) {
+return NULL;
+}
+fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
+if (fd < 0) {
+fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
+liobn);
+return NULL;
+}
+} else {
 return NULL;
 }
 
-len = (window_size / SPAPR_TCE_PAGE_SIZE) * sizeof(uint64_t);
+len = window_shift * sizeof(uint64_t);
 /* FIXME: round this up to page size */
 
 table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 2e0224c..ec36777 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -35,8 +35,9 @@ int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
 #ifndef CONFIG_USER_ONLY
 off_t kvmppc_alloc_rma(void **rma);
 bool kvmppc_spapr_use_multitce(void);
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
-  bool vfio_accel);
+void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_shift,
+  uint64_t bus_offset, uint32_t page_shift,
+  int *pfd, bool vfio_accel);
 int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
 int kvmppc_reset_

[Qemu-devel] [PATCH v4 18/18] vfio: Enable in-kernel acceleration via VFIO KVM device

2015-01-29 Thread Alexey Kardashevskiy
TCE hypercalls (H_PUT_TCE, H_PUT_TCE_INDIRECT, H_STUFF_TCE) use a logical bus
number (LIOBN) to identify which TCE table the request is addressed to.
However VFIO kernel driver operates with IOMMU group IDs and has no idea
about which LIOBN corresponds to which group. If the host kernel supports
in-kernel acceleration for TCE calls, we have to provide the LIOBN to IOMMU
mapping information.

This makes use of a VFIO KVM device's
KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE_LIOBN attribute to set the link
between LIOBN and IOMMU group.

The vfio_container_spapr_set_liobn() helper is implemented completely
in vfio.c because kvm_vfio_spapr_tce_liobn needs a group fd and
we do not want to share resources likes that outside vfio.c.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_iommu.c|  1 +
 hw/ppc/spapr_pci_vfio.c | 11 +++
 hw/vfio/common.c| 33 +
 include/hw/vfio/vfio.h  |  4 
 4 files changed, 49 insertions(+)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 258f837..3de95d7 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -142,6 +142,7 @@ static int spapr_tce_table_realize(DeviceState *dev)
 if (!tcet->table) {
 size_t table_size = tcet->nb_table * sizeof(uint64_t);
 tcet->table = g_malloc0(table_size);
+tcet->vfio_accel = false;
 }
 
 trace_spapr_iommu_new_table(tcet->liobn, tcet, tcet->table, tcet->fd);
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 257181d..2078187 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -21,6 +21,7 @@
 #include "hw/pci-host/spapr.h"
 #include "linux/vfio.h"
 #include "hw/vfio/vfio.h"
+#include "qemu/error-report.h"
 
 static Property spapr_phb_vfio_properties[] = {
 DEFINE_PROP_INT32("iommu", sPAPRPHBVFIOState, iommugroupid, -1),
@@ -80,6 +81,16 @@ static int spapr_pci_vfio_ddw_create(sPAPRPHBState *sphb, 
uint32_t liobn,
 memory_region_add_subregion(&sphb->iommu_root, (*ptcet)->bus_offset,
 spapr_tce_get_iommu(*ptcet));
 
+if (!(*ptcet)->vfio_accel) {
+return 0;
+}
+ret = vfio_container_spapr_set_liobn(&sphb->iommu_as,
+ liobn, (*ptcet)->bus_offset);
+if (ret) {
+error_report("spapr-vfio: failed to create link to IOMMU");
+ret = 0;
+}
+
 return ret;
 }
 
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index a26cbae..ec778d0 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1053,3 +1053,36 @@ int vfio_container_ioctl(AddressSpace *as,
 
 return vfio_container_do_ioctl(as, req, param);
 }
+
+int vfio_container_spapr_set_liobn(AddressSpace *as,
+   uint64_t liobn,
+   uint64_t start_addr)
+{
+#ifdef CONFIG_KVM
+int ret;
+struct kvm_vfio_spapr_tce_liobn param = {
+.argsz = sizeof(param),
+.liobn = liobn,
+.start_addr = start_addr
+};
+struct kvm_device_attr attr = {
+.group = KVM_DEV_VFIO_GROUP,
+.attr = KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE_LIOBN,
+.addr = (uint64_t)(unsigned long)¶m,
+};
+
+if (vfio_kvm_device_fd < 0) {
+return 0;
+}
+
+ret = ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr);
+if (ret) {
+error_report("vfio: failed to setup liobn for a group: %s",
+ strerror(errno));
+}
+
+return ret;
+#else
+return 0;
+#endif
+}
diff --git a/include/hw/vfio/vfio.h b/include/hw/vfio/vfio.h
index 76b5744..8457933 100644
--- a/include/hw/vfio/vfio.h
+++ b/include/hw/vfio/vfio.h
@@ -6,4 +6,8 @@
 extern int vfio_container_ioctl(AddressSpace *as,
 int req, void *param);
 
+extern int vfio_container_spapr_set_liobn(AddressSpace *as,
+  uint64_t liobn,
+  uint64_t start_addr);
+
 #endif
-- 
2.0.0




[Qemu-devel] [PATCH v4 02/18] spapr_iommu: Make H_PUT_TCE_INDIRECT endian-safe

2015-01-29 Thread Alexey Kardashevskiy
PAPR is defined as big endian so TCEs need an adjustment so
does this patch.

This changes code to have ldq_be_phys() in one place.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_iommu.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 8de0482..a19dc5e 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -250,7 +250,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
 target_ulong ioba1 = ioba;
 target_ulong tce_list = args[2];
 target_ulong npages = args[3];
-target_ulong ret = H_PARAMETER;
+target_ulong ret = H_PARAMETER, tce = 0;
 sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
 CPUState *cs = CPU(cpu);
 hwaddr page_mask, page_size;
@@ -270,7 +270,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
 for (i = 0; i < npages; ++i, ioba += page_size) {
 target_ulong off = (tce_list & ~SPAPR_TCE_RW) +
 i * sizeof(target_ulong);
-target_ulong tce = ldq_phys(cs->as, off);
+tce = ldq_be_phys(cs->as, off);
 
 ret = put_tce_emu(tcet, ioba, tce);
 if (ret) {
@@ -281,8 +281,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu,
 /* Trace last successful or the first problematic entry */
 i = i ? (i - 1) : 0;
 trace_spapr_iommu_indirect(liobn, ioba1, tce_list, i,
-   ldq_phys(cs->as,
-   tce_list + i * sizeof(target_ulong)),
+   tce,
ret);
 
 return ret;
-- 
2.0.0




[Qemu-devel] [PATCH v4 04/18] spapr_vio: Introduce a liobn number generating macros

2015-01-29 Thread Alexey Kardashevskiy
This introduces a macro which makes up a LIOBN from fixed prefix and
VIO device address (@reg property).

This is to keep LIOBN macros rendering consistent - the same macro for
PCI has been added by the previous patch.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: David Gibson 
---
 hw/ppc/spapr_vio.c | 2 +-
 include/hw/ppc/spapr.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 367345c..4f1eb79 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -469,7 +469,7 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
 }
 
 if (pc->rtce_window_size) {
-uint32_t liobn = SPAPR_VIO_BASE_LIOBN | dev->reg;
+uint32_t liobn = SPAPR_VIO_LIOBN(dev->reg);
 
 memory_region_init(&dev->mrroot, OBJECT(dev), "iommu-spapr-root",
ram_size);
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index a2c4bac..7e0b69c 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -441,7 +441,7 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr 
rtas_addr,
 #define SPAPR_TCE_PAGE_SIZE(1ULL << SPAPR_TCE_PAGE_SHIFT)
 #define SPAPR_TCE_PAGE_MASK(SPAPR_TCE_PAGE_SIZE - 1)
 
-#define SPAPR_VIO_BASE_LIOBN0x
+#define SPAPR_VIO_LIOBN(reg)(0x | (reg))
 #define SPAPR_PCI_LIOBN(i, n)   (0x8000 | ((i) << 8) | (n))
 #define SPAPR_PCI_DMA_WINDOW_NUM(liobn) ((liobn) & 0xff)
 
-- 
2.0.0




[Qemu-devel] [PATCH v2 4/9] qmp: Clean up qmp_query_spice() #ifndef !CONFIG_SPICE dummy

2015-01-29 Thread Markus Armbruster
QMP command query-spice exists only #ifdef CONFIG_SPICE.  Due to QAPI
limitations, we need a dummy function anyway, but it's unreachable.

Our current dummy function goes out of its way to produce the exact
same error as the QMP core does for unknown commands.  Cute, but both
unclean and unnecessary.  Replace by straight abort().

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Gerd Hoffmann 
---
 qmp.c | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/qmp.c b/qmp.c
index ef155ff..7f2d25a 100644
--- a/qmp.c
+++ b/qmp.c
@@ -137,14 +137,18 @@ VncInfo *qmp_query_vnc(Error **errp)
 #endif
 
 #ifndef CONFIG_SPICE
-/* If SPICE support is enabled, the "true" query-spice command is
-   defined in the SPICE subsystem. Also note that we use a small
-   trick to maintain query-spice's original behavior, which is not
-   to be available in the namespace if SPICE is not compiled in */
+/*
+ * qmp-commands.hx ensures that QMP command query-spice exists only
+ * #ifdef CONFIG_SPICE.  Necessary for an accurate query-commands
+ * result.  However, the QAPI schema is blissfully unaware of that,
+ * and the QAPI code generator happily generates a dead
+ * qmp_marshal_input_query_spice() that calls qmp_query_spice().
+ * Provide it one, or else linking fails.
+ * FIXME Educate the QAPI schema on CONFIG_SPICE.
+ */
 SpiceInfo *qmp_query_spice(Error **errp)
 {
-error_set(errp, QERR_COMMAND_NOT_FOUND, "query-spice");
-return NULL;
+abort();
 };
 #endif
 
-- 
1.9.3




[Qemu-devel] [PATCH v4 08/18] vfio: Add DMA memory registering

2015-01-29 Thread Alexey Kardashevskiy
This makes use of the new "memory registering" feature. The idea is
to provide the guest ability to notify the host kernel about pages which
are going to be used for DMA. Having this information, the host kernel
can pin them all, do locked pages accounting and not spent time on
doing that in real time with possible failures which cannot be handled
nicely in some cases.

This adds a memory listener which notifies a VFIO container about memory
which needs to be pinned/unpinned. VFIO MMIO regions are skipped.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/vfio/common.c  | 99 ++-
 include/hw/vfio/vfio-common.h |  3 +-
 2 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index cf483ff..c08f9ab 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -485,6 +485,99 @@ void vfio_listener_release(VFIOContainer *container)
 memory_listener_unregister(&container->iommu_data.type1.listener);
 }
 
+static int vfio_mem_register(VFIOContainer *container,
+ void *vaddr, ram_addr_t size)
+{
+struct vfio_iommu_type1_register_memory reg = {
+.argsz = sizeof(reg),
+.vaddr = (__u64)(uintptr_t)vaddr,
+.size = size,
+};
+long ret = ioctl(container->fd, VFIO_IOMMU_REGISTER_MEMORY, ®);
+
+DPRINTF("(%u) %s %u: va=%lx size=%lx, ret=%ld\n", getpid(),
+__func__, __LINE__, reg.vaddr, reg.size, ret);
+
+return ret;
+}
+
+static int vfio_mem_unregister(VFIOContainer *container,
+   void *vaddr, ram_addr_t size)
+{
+struct vfio_iommu_type1_unregister_memory reg = {
+.argsz = sizeof(reg),
+.vaddr = (__u64)(uintptr_t)vaddr,
+.size = size,
+};
+long ret = ioctl(container->fd, VFIO_IOMMU_UNREGISTER_MEMORY, ®);
+
+DPRINTF("(%u) %s %u: va=%lx size=%lx, ret=%ld\n", getpid(),
+__func__, __LINE__, reg.vaddr, reg.size, ret);
+
+return ret;
+}
+
+static void vfio_ram_region_add(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+VFIOContainer *container = container_of(listener, VFIOContainer,
+iommu_data.type1.ramlistener);
+hwaddr end;
+Int128 llend;
+void *vaddr;
+
+if (!memory_region_is_ram(section->mr) ||
+memory_region_is_skip_dump(section->mr)) {
+return;
+}
+
+llend = int128_make64(section->offset_within_address_space);
+llend = int128_add(llend, section->size);
+llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));
+
+memory_region_ref(section->mr);
+
+end = int128_get64(llend);
+vaddr = memory_region_get_ram_ptr(section->mr) +
+section->offset_within_region;
+vfio_mem_register(container, vaddr, end);
+}
+
+static void vfio_ram_region_del(MemoryListener *listener,
+MemoryRegionSection *section)
+{
+VFIOContainer *container = container_of(listener, VFIOContainer,
+iommu_data.type1.ramlistener);
+hwaddr iova, end;
+void *vaddr;
+
+if (!memory_region_is_ram(section->mr) ||
+memory_region_is_skip_dump(section->mr)) {
+return;
+}
+
+
+iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);
+end = (section->offset_within_address_space + int128_get64(section->size)) 
&
+TARGET_PAGE_MASK;
+vaddr = memory_region_get_ram_ptr(section->mr) +
+section->offset_within_region +
+(iova - section->offset_within_address_space);
+
+vfio_mem_unregister(container, vaddr, end - iova);
+}
+
+const MemoryListener vfio_ram_listener = {
+.region_add = vfio_ram_region_add,
+.region_del = vfio_ram_region_del,
+};
+
+static void vfio_spapr_listener_release(VFIOContainer *container)
+{
+memory_listener_unregister(&container->iommu_data.type1.listener);
+memory_listener_unregister(&container->iommu_data.type1.ramlistener);
+}
+
 int vfio_mmap_region(Object *obj, VFIORegion *region,
  MemoryRegion *mem, MemoryRegion *submem,
  void **map, size_t size, off_t offset,
@@ -705,6 +798,10 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as)
 goto free_container_exit;
 }
 
+container->iommu_data.type1.ramlistener = vfio_ram_listener;
+memory_listener_register(&container->iommu_data.type1.ramlistener,
+ &address_space_memory);
+
 /*
  * The host kernel code implementing VFIO_IOMMU_DISABLE is called
  * when container fd is closed so we do not call it explicitly
@@ -718,7 +815,7 @@ static int vfio_connect_container(VFIOGroup *group, 
AddressSpace *as)
 }
 
 container->iommu_data.type1.listener = vfio_memory_listener;
-container->iommu_data.release = vfio_listener_release;
+container->iommu_data.rel

[Qemu-devel] [PATCH v2 6/9] qmp: Eliminate silly QERR_COMMAND_NOT_FOUND macro

2015-01-29 Thread Markus Armbruster
The QERR_ macros are leftovers from the days of "rich" error objects.
They're used with error_set() and qerror_report(), and expand into the
first *two* arguments.  This trickiness has become pointless.  Clean
this one up.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 include/qapi/qmp/qerror.h | 3 ---
 monitor.c | 3 ++-
 qapi/qmp-dispatch.c   | 3 ++-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 0ca6cbd..28f980e 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -52,9 +52,6 @@ void qerror_report_err(Error *err);
 #define QERR_BUS_NOT_FOUND \
 ERROR_CLASS_GENERIC_ERROR, "Bus '%s' not found"
 
-#define QERR_COMMAND_NOT_FOUND \
-ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found"
-
 #define QERR_DEVICE_ENCRYPTED \
 ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted"
 
diff --git a/monitor.c b/monitor.c
index 2ac40c9..2e2b0e5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -5081,7 +5081,8 @@ static void handle_qmp_command(JSONMessageParser *parser, 
QList *tokens)
 trace_handle_qmp_command(mon, cmd_name);
 cmd = qmp_find_cmd(cmd_name);
 if (!cmd || invalid_qmp_mode(mon, cmd)) {
-qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
+qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
+  "The command %s has not been found", cmd_name);
 goto err_out;
 }
 
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 168b083..2227420 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -76,7 +76,8 @@ static QObject *do_qmp_dispatch(QObject *request, Error 
**errp)
 command = qdict_get_str(dict, "execute");
 cmd = qmp_find_command(command);
 if (cmd == NULL) {
-error_set(errp, QERR_COMMAND_NOT_FOUND, command);
+error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
+  "The command %s has not been found", command);
 return NULL;
 }
 if (!cmd->enabled) {
-- 
1.9.3




[Qemu-devel] [PATCH v4 15/18] spapr_pci_vfio: Enable multiple groups per container

2015-01-29 Thread Alexey Kardashevskiy
This enables multiple IOMMU groups in one VFIO container which means
that multiple devices from different groups can share the same IOMMU table
and locked pages counting can be done once as there is no need to have
several containers for two or more groups.

This removes a group id from vfio_container_ioctl(). The kernel support
is required for this.

This adds a check that there is just one VFIO container per PHB address
space.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_pci_vfio.c |  9 +++--
 hw/vfio/common.c| 33 +++--
 include/hw/vfio/vfio.h  |  2 +-
 3 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index b20ac90..257181d 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -33,11 +33,10 @@ static int spapr_pci_vfio_ddw_query(sPAPRPHBState *sphb,
 uint32_t *dma32_window_size,
 uint64_t *dma64_window_size)
 {
-sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
 struct vfio_iommu_spapr_tce_info info = { .argsz = sizeof(info) };
 int ret;
 
-ret = vfio_container_ioctl(&sphb->iommu_as, svphb->iommugroupid,
+ret = vfio_container_ioctl(&sphb->iommu_as,
VFIO_IOMMU_SPAPR_TCE_GET_INFO, &info);
 if (ret) {
 return ret;
@@ -55,7 +54,6 @@ static int spapr_pci_vfio_ddw_create(sPAPRPHBState *sphb, 
uint32_t liobn,
  uint32_t page_shift, uint32_t 
window_shift,
  sPAPRTCETable **ptcet)
 {
-sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
 struct vfio_iommu_spapr_tce_create create = {
 .argsz = sizeof(create),
 .page_shift = page_shift,
@@ -65,7 +63,7 @@ static int spapr_pci_vfio_ddw_create(sPAPRPHBState *sphb, 
uint32_t liobn,
 };
 int ret;
 
-ret = vfio_container_ioctl(&sphb->iommu_as, svphb->iommugroupid,
+ret = vfio_container_ioctl(&sphb->iommu_as,
VFIO_IOMMU_SPAPR_TCE_CREATE, &create);
 if (ret) {
 return ret;
@@ -87,7 +85,6 @@ static int spapr_pci_vfio_ddw_create(sPAPRPHBState *sphb, 
uint32_t liobn,
 
 static int spapr_pci_vfio_ddw_remove(sPAPRPHBState *sphb, sPAPRTCETable *tcet)
 {
-sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
 struct vfio_iommu_spapr_tce_remove remove = {
 .argsz = sizeof(remove),
 .start_addr = tcet->bus_offset
@@ -95,7 +92,7 @@ static int spapr_pci_vfio_ddw_remove(sPAPRPHBState *sphb, 
sPAPRTCETable *tcet)
 int ret;
 
 spapr_pci_ddw_remove(sphb, tcet);
-ret = vfio_container_ioctl(&sphb->iommu_as, svphb->iommugroupid,
+ret = vfio_container_ioctl(&sphb->iommu_as,
VFIO_IOMMU_SPAPR_TCE_REMOVE, &remove);
 
 return ret;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 1cafcf8..a26cbae 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1011,34 +1011,31 @@ void vfio_put_base_device(VFIODevice *vbasedev)
 close(vbasedev->fd);
 }
 
-static int vfio_container_do_ioctl(AddressSpace *as, int32_t groupid,
+static int vfio_container_do_ioctl(AddressSpace *as,
int req, void *param)
 {
-VFIOGroup *group;
 VFIOContainer *container;
-int ret = -1;
+int ret;
+VFIOAddressSpace *space;
 
-group = vfio_get_group(groupid, as);
-if (!group) {
-error_report("vfio: group %d not registered", groupid);
-return ret;
-}
+space = vfio_get_address_space(as);
+container = QLIST_FIRST(&space->containers);
 
-container = group->container;
-if (group->container) {
-ret = ioctl(container->fd, req, param);
-if (ret < 0) {
-error_report("vfio: failed to ioctl container: ret=%d, %s",
- ret, strerror(errno));
-}
+if (!container || QLIST_NEXT(container, next)) {
+error_report("vfio: multiple containers per PHB are not supported");
+return -1;
 }
 
-vfio_put_group(group);
+ret = ioctl(container->fd, req, param);
+if (ret < 0) {
+error_report("vfio: failed to ioctl container: ret=%d, %s",
+ ret, strerror(errno));
+}
 
 return ret;
 }
 
-int vfio_container_ioctl(AddressSpace *as, int32_t groupid,
+int vfio_container_ioctl(AddressSpace *as,
  int req, void *param)
 {
 /* We allow only certain ioctls to the container */
@@ -1054,5 +1051,5 @@ int vfio_container_ioctl(AddressSpace *as, int32_t 
groupid,
 return -1;
 }
 
-return vfio_container_do_ioctl(as, groupid, req, param);
+return vfio_container_do_ioctl(as, req, param);
 }
diff --git a/include/hw/vfio/vfio.h b/include/hw/vfio/vfio.h
index 0b26cd8..76b5744 100644
--- a/include/hw/vfio/vfio.h
+++ b/include/hw/vfio/vfio.h
@@ -3,7 +3,7 @@
 
 #include "qemu/typedefs.h"

[Qemu-devel] [PATCH v2 1/9] qmp hmp: Factor out common "using spice" test

2015-01-29 Thread Markus Armbruster
Into qemu_using_spice().  For want of a better place, put it next the
existing monitor command handler dummies in qemu-spice.h.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Gerd Hoffmann 
---
 include/ui/qemu-spice.h | 10 ++
 monitor.c   |  5 +++--
 qmp.c   | 11 +++
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index a93b4b2..db7926d 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -88,4 +88,14 @@ static inline int qemu_spice_display_add_client(int csock, 
int skipauth,
 
 #endif /* CONFIG_SPICE */
 
+static inline bool qemu_using_spice(Error **errp)
+{
+if (!using_spice) {
+/* correct one? spice isn't a device ,,, */
+error_set(errp, QERR_DEVICE_NOT_ACTIVE, "spice");
+return false;
+}
+return true;
+}
+
 #endif /* QEMU_SPICE_H */
diff --git a/monitor.c b/monitor.c
index 7e4f605..8323de3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1095,11 +1095,12 @@ static int client_migrate_info(Monitor *mon, const 
QDict *qdict,
 const char *subject  = qdict_get_try_str(qdict, "cert-subject");
 int port = qdict_get_try_int(qdict, "port", -1);
 int tls_port = qdict_get_try_int(qdict, "tls-port", -1);
+Error *err;
 int ret;
 
 if (strcmp(protocol, "spice") == 0) {
-if (!using_spice) {
-qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
+if (!qemu_using_spice(&err)) {
+qerror_report_err(err);
 return -1;
 }
 
diff --git a/qmp.c b/qmp.c
index 963305c..ef155ff 100644
--- a/qmp.c
+++ b/qmp.c
@@ -287,9 +287,7 @@ void qmp_set_password(const char *protocol, const char 
*password,
 }
 
 if (strcmp(protocol, "spice") == 0) {
-if (!using_spice) {
-/* correct one? spice isn't a device ,,, */
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "spice");
+if (!qemu_using_spice(errp)) {
 return;
 }
 rc = qemu_spice_set_passwd(password, fail_if_connected,
@@ -335,9 +333,7 @@ void qmp_expire_password(const char *protocol, const char 
*whenstr,
 }
 
 if (strcmp(protocol, "spice") == 0) {
-if (!using_spice) {
-/* correct one? spice isn't a device ,,, */
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "spice");
+if (!qemu_using_spice(errp)) {
 return;
 }
 rc = qemu_spice_set_pw_expire(when);
@@ -575,8 +571,7 @@ void qmp_add_client(const char *protocol, const char 
*fdname,
 }
 
 if (strcmp(protocol, "spice") == 0) {
-if (!using_spice) {
-error_set(errp, QERR_DEVICE_NOT_ACTIVE, "spice");
+if (!qemu_using_spice(errp)) {
 close(fd);
 return;
 }
-- 
1.9.3




[Qemu-devel] [PATCH v4 01/18] spapr_iommu: Disable in-kernel IOMMU tables for >4GB windows

2015-01-29 Thread Alexey Kardashevskiy
The existing KVM_CREATE_SPAPR_TCE ioctl only support 4G windows max as
the window size parameter to the kernel ioctl() is 32-bit so
there's no way of expressing a TCE window > 4GB.

We are going to add huge DMA windows support so this will create small
window and unexpectedly fail later.

This disables KVM_CREATE_SPAPR_TCE for windows bigger that 4GB.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: David Gibson 
---
Changes:
v3:
* fixed commit log
* added cast to uint64_t
---
 hw/ppc/spapr_iommu.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 51d49c8..8de0482 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -129,11 +129,11 @@ static MemoryRegionIOMMUOps spapr_iommu_ops = {
 static int spapr_tce_table_realize(DeviceState *dev)
 {
 sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
+uint64_t window_size = (uint64_t)tcet->nb_table << tcet->page_shift;
 
-if (kvm_enabled()) {
+if (kvm_enabled() && !(window_size >> 32)) {
 tcet->table = kvmppc_create_spapr_tce(tcet->liobn,
-  tcet->nb_table <<
-  tcet->page_shift,
+  window_size,
   &tcet->fd,
   tcet->vfio_accel);
 }
-- 
2.0.0




[Qemu-devel] [PATCH v4 00/18] spapr: vfio: Enable Dynamic DMA windows (DDW)

2015-01-29 Thread Alexey Kardashevskiy

At the moment sPAPR PHB supports only a single 32bit window
which is normally 1..2GB which is not enough for high performance devices.

PAPR spec enables creating an additional window(s) to support 64bit
DMA and bigger page sizes.

This patchset adds DDW support for pseries. The host kernel changes are
required, posted earlier today as:
[PATCH v3 00/24] powerpc/iommu/vfio: Enable Dynamic DMA windows

This was tested on POWER8 system which allows one additional DMA window
which is mapped at 0x800... and supports 16MB pages.
Existing guests check for DDW capabilities in PHB's device tree and if it
is present, they request for an additional window and map entire guest RAM
using H_PUT_TCE/... hypercalls once at boot time and switch to direct DMA
operations.

TCE tables still may be big enough for guests backed with 64K pages but they
are reasonably small for guests backed by 16MB pages.


This does not contain PCI 64bit BAR support and VIO-TCE-bypass rework, these
are required for this to work but they have been posted separately today.


Please comment. Thanks!

Changes:
v4:
* (!) reimplemented the whole thing
* machine reset and ddw-reset RTAS call both remove all TCE tables and
create the default one
* IOMMU group id is not needed to use VFIO PHB anymore, multiple groups
are supported on the same VFIO container and virtual PHB

v3:
* removed "reset" from API now
* reworked machine versions
* applied multiple comments
* includes David's machine QOM rework as this patchset adds a new machine type

v2:
* tested on emulated PHB
* removed "ddw" machine property, now it is PHB property
* disabled by default
* defined "pseries-2.2" machine which enables DDW by default
* fixed reset() and reference counting




Alexey Kardashevskiy (18):
  spapr_iommu: Disable in-kernel IOMMU tables for >4GB windows
  spapr_iommu: Make H_PUT_TCE_INDIRECT endian-safe
  spapr_pci: Introduce a liobn number generating macros
  spapr_vio: Introduce a liobn number generating macros
  spapr_pci: Make find_phb()/find_dev() public
  spapr_iommu: Make spapr_tce_find_by_liobn() public
  spapr_iommu: Implement free_table() helper
  vfio: Add DMA memory registering
  spapr_rtas: Reserve DDW RTAS token numbers
  spapr_pci: Define DDW callbacks
  spapr_pci/spapr_pci_vfio: Support Dynamic DMA Windows (DDW)
  spapr_rtas: Add Dynamic DMA windows (DDW) RTAS handlers
  spapr_pci: Advertise dynamic DMA windows to guest
  vfio: Enable DDW ioctls to VFIO IOMMU driver
  spapr_pci_vfio: Enable multiple groups per container
  spapr_rtas_ddw: Workaround broken LE guests
  target-ppc: kvm: make use of KVM_CREATE_SPAPR_TCE_64
  vfio: Enable in-kernel acceleration via VFIO KVM device

 hw/ppc/Makefile.objs  |   3 +
 hw/ppc/spapr.c|   5 +
 hw/ppc/spapr_iommu.c  |  23 ++-
 hw/ppc/spapr_pci.c| 209 --
 hw/ppc/spapr_pci_vfio.c   | 108 +-
 hw/ppc/spapr_rtas.c   |  29 
 hw/ppc/spapr_rtas_ddw.c   | 337 ++
 hw/ppc/spapr_vio.c|   2 +-
 hw/vfio/common.c  | 167 ++---
 include/hw/pci-host/spapr.h   |  38 -
 include/hw/ppc/spapr.h|  15 +-
 include/hw/vfio/vfio-common.h |   3 +-
 include/hw/vfio/vfio.h|   6 +-
 target-ppc/kvm.c  |  48 --
 target-ppc/kvm_ppc.h  |  10 +-
 trace-events  |   4 +
 16 files changed, 881 insertions(+), 126 deletions(-)
 create mode 100644 hw/ppc/spapr_rtas_ddw.c

-- 
2.0.0




[Qemu-devel] [PATCH v4 12/18] spapr_rtas: Add Dynamic DMA windows (DDW) RTAS handlers

2015-01-29 Thread Alexey Kardashevskiy
This adds support for Dynamic DMA Windows (DDW) option defined by
the SPAPR specification which allows to have additional DMA window(s)
which can support page sizes other than 4K.

The existing implementation of DDW in the guest tries to create one huge
DMA window with 64K or 16MB pages and map the entire guest RAM to. If it
succeeds, the guest switches to dma_direct_ops and never calls
TCE hypercalls (H_PUT_TCE,...) again. This enables VFIO devices to use
the entire RAM and not waste time on map/unmap later.

This adds 4 RTAS handlers:
* ibm,query-pe-dma-window
* ibm,create-pe-dma-window
* ibm,remove-pe-dma-window
* ibm,reset-pe-dma-window
These are registered from type_init() callback.

These RTAS handlers are implemented in a separate file to avoid polluting
spapr_iommu.c with PHB.

Signed-off-by: Alexey Kardashevskiy 
---
Changes:
v3:
* added ibm,reset-pe-dma-window

v2:
* double loop squashed to spapr_iommu_fixmask() helper
* added @ddw_num counter to PHB, it is used to generate LIOBN for new
window; it is reset on ddw-reset event
* added ULL to constants used in shift operations
* rtas_ibm_reset_pe_dma_window() and rtas_ibm_remove_pe_dma_window()
do not remove windows anymore, the PHB callback has to as it will reuse
the same code in case of guest reboot as well
---
 hw/ppc/Makefile.objs|   3 +
 hw/ppc/spapr_rtas_ddw.c | 297 
 trace-events|   4 +
 3 files changed, 304 insertions(+)
 create mode 100644 hw/ppc/spapr_rtas_ddw.c

diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 19d9920..d7fe4fb 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -7,6 +7,9 @@ obj-$(CONFIG_PSERIES) += spapr_pci.o
 ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
 obj-y += spapr_pci_vfio.o
 endif
+ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES), yy)
+obj-y += spapr_rtas_ddw.o
+endif
 # PowerPC 4xx boards
 obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o
 obj-y += ppc4xx_pci.o
diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c
new file mode 100644
index 000..af70601
--- /dev/null
+++ b/hw/ppc/spapr_rtas_ddw.c
@@ -0,0 +1,297 @@
+/*
+ * QEMU sPAPR Dynamic DMA windows support
+ *
+ * Copyright (c) 2014 Alexey Kardashevskiy, IBM Corporation.
+ *
+ *  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/ppc/spapr.h"
+#include "hw/pci-host/spapr.h"
+#include "trace.h"
+
+static uint32_t spapr_iommu_fixmask(struct ppc_one_seg_page_size *sps,
+uint32_t query_mask)
+{
+int i, j;
+uint32_t mask = 0;
+const struct { int shift; uint32_t mask; } masks[] = {
+{ 12, DDW_PGSIZE_4K },
+{ 16, DDW_PGSIZE_64K },
+{ 24, DDW_PGSIZE_16M },
+{ 25, DDW_PGSIZE_32M },
+{ 26, DDW_PGSIZE_64M },
+{ 27, DDW_PGSIZE_128M },
+{ 28, DDW_PGSIZE_256M },
+{ 34, DDW_PGSIZE_16G },
+};
+
+for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
+for (j = 0; j < ARRAY_SIZE(masks); ++j) {
+if ((sps[i].page_shift == masks[j].shift) &&
+(query_mask & masks[j].mask)) {
+mask |= masks[j].mask;
+}
+}
+}
+
+return mask;
+}
+
+static void rtas_ibm_query_pe_dma_window(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args,
+ uint32_t nret, target_ulong rets)
+{
+CPUPPCState *env = &cpu->env;
+sPAPRPHBState *sphb;
+sPAPRPHBClass *spc;
+uint64_t buid;
+uint32_t avail, addr, pgmask = 0;
+uint32_t windows_supported = 0, page_size_mask = 0, dma32_window_size = 0;
+uint64_t dma64_window_size = 0;
+unsigned current;
+long ret;
+
+if ((nargs != 3) || (nret != 5)) {
+goto param_error_exit;
+}
+
+buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
+addr = rtas_ld(args, 0);
+sphb = spapr_pci_find_phb(spapr, buid);
+if (!sphb || !sphb->ddw_enabled) {
+goto param_error_exit;
+}
+
+spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+if (!spc->ddw_query) {
+goto hw_error_exit;
+}
+
+ret = spc->ddw_query(sphb, &windows_supported, &page_size_mask,
+   

[Qemu-devel] [PATCH v4 06/18] spapr_iommu: Make spapr_tce_find_by_liobn() public

2015-01-29 Thread Alexey Kardashevskiy
At the moment spapr_tce_find_by_liobn() is used by H_PUT_TCE/...
handlers to find an IOMMU by LIOBN.

We are going to implement Dynamic DMA windows (DDW), new code
will go to a new file and we will use spapr_tce_find_by_liobn()
there too so let's make it public.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: David Gibson 
---
 hw/ppc/spapr_iommu.c   | 2 +-
 include/hw/ppc/spapr.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index a19dc5e..309c6cf 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -41,7 +41,7 @@ enum sPAPRTCEAccess {
 
 static QLIST_HEAD(spapr_tce_tables, sPAPRTCETable) spapr_tce_tables;
 
-static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn)
+sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn)
 {
 sPAPRTCETable *tcet;
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 7e0b69c..696b786 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -468,6 +468,7 @@ struct sPAPRTCETable {
 QLIST_ENTRY(sPAPRTCETable) list;
 };
 
+sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn);
 void spapr_events_init(sPAPREnvironment *spapr);
 void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
 int spapr_h_cas_compose_response(target_ulong addr, target_ulong size);
-- 
2.0.0




[Qemu-devel] [PATCH v2 3/4] block: New bdrv_add_key(), convert monitor to use it

2015-01-29 Thread Markus Armbruster
Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 block.c   | 29 +
 blockdev.c| 24 ++--
 include/block/block.h |  1 +
 monitor.c | 16 +++-
 qmp.c |  8 
 5 files changed, 47 insertions(+), 31 deletions(-)

diff --git a/block.c b/block.c
index d45e4dd..aa12160 100644
--- a/block.c
+++ b/block.c
@@ -3719,6 +3719,35 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
 return ret;
 }
 
+/*
+ * Provide an encryption key for @bs.
+ * If @key is non-null:
+ * If @bs is not encrypted, fail.
+ * Else if the key is invalid, fail.
+ * Else set @bs's key to @key, replacing the existing key, if any.
+ * If @key is null:
+ * If @bs is encrypted and still lacks a key, fail.
+ * Else do nothing.
+ * On failure, store an error object through @errp if non-null.
+ */
+void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp)
+{
+if (key) {
+if (!bdrv_is_encrypted(bs)) {
+error_set(errp, QERR_DEVICE_NOT_ENCRYPTED,
+  bdrv_get_device_name(bs));
+} else if (bdrv_set_key(bs, key) < 0) {
+error_set(errp, QERR_INVALID_PASSWORD);
+}
+} else {
+if (bdrv_key_required(bs)) {
+error_set(errp, QERR_DEVICE_ENCRYPTED,
+  bdrv_get_device_name(bs),
+  bdrv_get_encrypted_filename(bs));
+}
+}
+}
+
 const char *bdrv_get_format_name(BlockDriverState *bs)
 {
 return bs->drv ? bs->drv->format_name : NULL;
diff --git a/blockdev.c b/blockdev.c
index 287d7af..7d34960 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1793,7 +1793,6 @@ void qmp_block_passwd(bool has_device, const char *device,
 Error *local_err = NULL;
 BlockDriverState *bs;
 AioContext *aio_context;
-int err;
 
 bs = bdrv_lookup_bs(has_device ? device : NULL,
 has_node_name ? node_name : NULL,
@@ -1806,16 +1805,8 @@ void qmp_block_passwd(bool has_device, const char 
*device,
 aio_context = bdrv_get_aio_context(bs);
 aio_context_acquire(aio_context);
 
-err = bdrv_set_key(bs, password);
-if (err == -EINVAL) {
-error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
-goto out;
-} else if (err < 0) {
-error_set(errp, QERR_INVALID_PASSWORD);
-goto out;
-}
+bdrv_add_key(bs, password, errp);
 
-out:
 aio_context_release(aio_context);
 }
 
@@ -1833,18 +1824,7 @@ static void qmp_bdrv_open_encrypted(BlockDriverState 
*bs, const char *filename,
 return;
 }
 
-if (bdrv_key_required(bs)) {
-if (password) {
-if (bdrv_set_key(bs, password) < 0) {
-error_set(errp, QERR_INVALID_PASSWORD);
-}
-} else {
-error_set(errp, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs),
-  bdrv_get_encrypted_filename(bs));
-}
-} else if (password) {
-error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
-}
+bdrv_add_key(bs, password, errp);
 }
 
 void qmp_change_blockdev(const char *device, const char *filename,
diff --git a/include/block/block.h b/include/block/block.h
index 3082d2b..623c390 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -378,6 +378,7 @@ BlockDriverState *bdrv_next(BlockDriverState *bs);
 int bdrv_is_encrypted(BlockDriverState *bs);
 int bdrv_key_required(BlockDriverState *bs);
 int bdrv_set_key(BlockDriverState *bs, const char *key);
+void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp);
 int bdrv_query_missing_keys(void);
 void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
  void *opaque);
diff --git a/monitor.c b/monitor.c
index 7e4f605..50dceac 100644
--- a/monitor.c
+++ b/monitor.c
@@ -5366,9 +5366,12 @@ static void bdrv_password_cb(void *opaque, const char 
*password,
 Monitor *mon = opaque;
 BlockDriverState *bs = readline_opaque;
 int ret = 0;
+Error *local_err = NULL;
 
-if (bdrv_set_key(bs, password) != 0) {
-monitor_printf(mon, "invalid password\n");
+bdrv_add_key(bs, password, &local_err);
+if (local_err) {
+monitor_printf(mon, "%s\n", error_get_pretty(local_err));
+error_free(local_err);
 ret = -EPERM;
 }
 if (mon->password_completion_cb)
@@ -5386,17 +5389,20 @@ int monitor_read_bdrv_key_start(Monitor *mon, 
BlockDriverState *bs,
 BlockCompletionFunc *completion_cb,
 void *opaque)
 {
+Error *local_err = NULL;
 int err;
 
-if (!bdrv_key_required(bs)) {
+bdrv_add_key(bs, NULL, &local_err);
+if (!local_err) {
 if (completion_cb)
 completion_cb(opaque, 0);
 return 0;
 }
 
+/* Need a key for @bs */
+
 if (monitor_ctrl_mode(mon)) {
-qerror

[Qemu-devel] [PATCH v4 07/18] spapr_iommu: Implement free_table() helper

2015-01-29 Thread Alexey Kardashevskiy
Every sPAPRTCETable object holds an IOMMU memory region which holds
a referenced to the sPAPRTCETable instance. So if we want to free
an sPAPRTCETable instance, calling object_unref() will not be enough
as embedded memory region will hold the reference and we need to break
the loop.

This adds a spapr_tce_free_table() helper which destroys the embedded
memory region and then calls object_unref() on the sPAPRTCETable instance
which will succeed now. The helper adds a new child under unique name
derived from LIOBN.

As we are here, fix spapr_tce_new_table() callers.
At the moment spapr_tce_new_table() references sPAPRTCETable twice -
once in object_new() and second time in object_property_add_child().
The callers of spapr_tce_new_table() should take care of correct
referencing.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_iommu.c| 10 +-
 hw/ppc/spapr_pci.c  |  2 ++
 hw/ppc/spapr_pci_vfio.c |  2 ++
 include/hw/ppc/spapr.h  |  1 +
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 309c6cf..1adf568 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -164,6 +164,7 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, 
uint32_t liobn,
bool vfio_accel)
 {
 sPAPRTCETable *tcet;
+char buf[32];
 
 if (spapr_tce_find_by_liobn(liobn)) {
 fprintf(stderr, "Attempted to create TCE table with duplicate"
@@ -182,13 +183,20 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, 
uint32_t liobn,
 tcet->nb_table = nb_table;
 tcet->vfio_accel = vfio_accel;
 
-object_property_add_child(OBJECT(owner), "tce-table", OBJECT(tcet), NULL);
+snprintf(buf, sizeof(buf) - 1, "tce-table-%08X", tcet->liobn);
+object_property_add_child(OBJECT(owner), buf, OBJECT(tcet), NULL);
 
 object_property_set_bool(OBJECT(tcet), true, "realized", NULL);
 
 return tcet;
 }
 
+void spapr_tce_free_table(sPAPRTCETable *tcet)
+{
+object_unparent(OBJECT(&tcet->iommu));
+object_unparent(OBJECT(tcet));
+}
+
 static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
 {
 sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 3665f8a..6bd00e8 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -649,6 +649,8 @@ static void spapr_phb_finish_realize(sPAPRPHBState *sphb, 
Error **errp)
 /* Register default 32bit DMA window */
 memory_region_add_subregion(&sphb->iommu_root, 0,
 spapr_tce_get_iommu(tcet));
+
+object_unref(OBJECT(tcet));
 }
 
 static int spapr_phb_children_reset(Object *child, void *opaque)
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 144912b..aabf0ae 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -69,6 +69,8 @@ static void spapr_phb_vfio_finish_realize(sPAPRPHBState 
*sphb, Error **errp)
 /* Register default 32bit DMA window */
 memory_region_add_subregion(&sphb->iommu_root, tcet->bus_offset,
 spapr_tce_get_iommu(tcet));
+
+object_unref(OBJECT(tcet));
 }
 
 static void spapr_phb_vfio_reset(DeviceState *qdev)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 696b786..b442e41 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -477,6 +477,7 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, 
uint32_t liobn,
uint32_t page_shift,
uint32_t nb_table,
bool vfio_accel);
+void spapr_tce_free_table(sPAPRTCETable *tcet);
 MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet);
 int spapr_dma_dt(void *fdt, int node_off, const char *propname,
  uint32_t liobn, uint64_t window, uint32_t size);
-- 
2.0.0




[Qemu-devel] [PATCH v4 13/18] spapr_pci: Advertise dynamic DMA windows to guest

2015-01-29 Thread Alexey Kardashevskiy
Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr.c |  5 +
 hw/ppc/spapr_pci.c | 25 +
 2 files changed, 30 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b560459..f9882c1 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1760,6 +1760,11 @@ static void spapr_machine_2_1_class_init(ObjectClass 
*oc, void *data)
 MachineClass *mc = MACHINE_CLASS(oc);
 static GlobalProperty compat_props[] = {
 HW_COMPAT_2_1,
+{
+.driver   = TYPE_SPAPR_PCI_HOST_BRIDGE,
+.property = "ddw",
+.value= stringify(off),
+},
 { /* end of list */ }
 };
 
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 3ec03be..a94bba1 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -775,6 +775,7 @@ static Property spapr_phb_properties[] = {
 DEFINE_PROP_UINT64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
 DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
SPAPR_PCI_IO_WIN_SIZE),
+DEFINE_PROP_BOOL("ddw", sPAPRPHBState, ddw_enabled, true),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -993,6 +994,12 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
 uint32_t interrupt_map_mask[] = {
 cpu_to_be32(b_d(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)};
 uint32_t interrupt_map[PCI_SLOT_MAX * PCI_NUM_PINS][7];
+uint32_t ddw_applicable[] = {
+cpu_to_be32(RTAS_IBM_QUERY_PE_DMA_WINDOW),
+cpu_to_be32(RTAS_IBM_CREATE_PE_DMA_WINDOW),
+cpu_to_be32(RTAS_IBM_REMOVE_PE_DMA_WINDOW)
+};
+sPAPRPHBClass *spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(phb);
 
 /* Start populating the FDT */
 sprintf(nodename, "pci@%" PRIx64, phb->buid);
@@ -1022,6 +1029,24 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
 _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1));
 _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS));
 
+/* Dynamic DMA window */
+if (phb->ddw_enabled &&
+spc->ddw_query && spc->ddw_create && spc->ddw_remove) {
+_FDT(fdt_setprop(fdt, bus_off, "ibm,ddw-applicable", &ddw_applicable,
+ sizeof(ddw_applicable)));
+
+if (spc->ddw_reset) {
+uint32_t ddw_extensions[] = {
+cpu_to_be32(1),
+cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW)
+};
+
+/* When enabled, the guest will remove the default 32bit window */
+_FDT(fdt_setprop(fdt, bus_off, "ibm,ddw-extensions",
+ &ddw_extensions, sizeof(ddw_extensions)));
+}
+}
+
 /* Build the interrupt-map, this must matches what is done
  * in pci_spapr_map_irq
  */
-- 
2.0.0




[Qemu-devel] [PATCH v4 16/18] spapr_rtas_ddw: Workaround broken LE guests

2015-01-29 Thread Alexey Kardashevskiy
Recent kernels do parse results of what DDW RTAS calls return incorrectly
if compiled with LITTLE_ENDIAN=yes.

This adds special handling for such guests.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_rtas.c | 29 +
 hw/ppc/spapr_rtas_ddw.c | 40 
 include/hw/ppc/spapr.h  |  2 ++
 3 files changed, 71 insertions(+)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 2ec2a8e..c3dee94 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -293,12 +293,15 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu,
 static struct rtas_call {
 const char *name;
 spapr_rtas_fn fn;
+spapr_rtas_fn fn_wa; /* workaround helper */
 } rtas_table[RTAS_TOKEN_MAX - RTAS_TOKEN_BASE];
 
 target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
  uint32_t token, uint32_t nargs, target_ulong args,
  uint32_t nret, target_ulong rets)
 {
+uint32_t tokensw = bswap32(token);
+
 if ((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX)) {
 struct rtas_call *call = rtas_table + (token - RTAS_TOKEN_BASE);
 
@@ -308,6 +311,16 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
 }
 }
 
+/* Workaround for LE guests */
+if ((tokensw >= RTAS_TOKEN_BASE) && (tokensw < RTAS_TOKEN_MAX)) {
+struct rtas_call *call = rtas_table + (tokensw - RTAS_TOKEN_BASE);
+
+if (call->fn_wa) {
+call->fn_wa(cpu, spapr, tokensw, nargs, args, nret, rets);
+return H_SUCCESS;
+}
+}
+
 /* HACK: Some Linux early debug code uses RTAS display-character,
  * but assumes the token value is 0xa (which it is on some real
  * machines) without looking it up in the device tree.  This
@@ -340,6 +353,22 @@ void spapr_rtas_register(int token, const char *name, 
spapr_rtas_fn fn)
 rtas_table[token].fn = fn;
 }
 
+void spapr_rtas_register_wrong_endian(int token, spapr_rtas_fn fn)
+{
+if (!((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX))) {
+fprintf(stderr, "RTAS invalid token 0x%x\n", token);
+exit(1);
+}
+
+token -= RTAS_TOKEN_BASE;
+if (!rtas_table[token].fn) {
+fprintf(stderr, "RTAS token %x must be initialized to allow 
workaround\n",
+token);
+exit(1);
+}
+rtas_table[token].fn_wa = fn;
+}
+
 int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
  hwaddr rtas_size)
 {
diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c
index af70601..56eae9f 100644
--- a/hw/ppc/spapr_rtas_ddw.c
+++ b/hw/ppc/spapr_rtas_ddw.c
@@ -278,6 +278,41 @@ param_error_exit:
 rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
 }
 
+#define SPAPR_RTAS_DDW_SWAP(n) rtas_st(rets, (n), bswap32(rtas_ld(rets, (n
+
+static void rtas_ibm_query_pe_dma_window_wrong_endian(PowerPCCPU *cpu,
+  sPAPREnvironment *spapr,
+  uint32_t token,
+  uint32_t nargs,
+  target_ulong args,
+  uint32_t nret,
+  target_ulong rets)
+{
+rtas_ibm_query_pe_dma_window(cpu, spapr, token, nargs, args, nret, rets);
+
+SPAPR_RTAS_DDW_SWAP(0);
+SPAPR_RTAS_DDW_SWAP(1);
+SPAPR_RTAS_DDW_SWAP(2);
+SPAPR_RTAS_DDW_SWAP(3);
+SPAPR_RTAS_DDW_SWAP(4);
+}
+
+static void rtas_ibm_create_pe_dma_window_wrong_endian(PowerPCCPU *cpu,
+   sPAPREnvironment *spapr,
+   uint32_t token,
+   uint32_t nargs,
+   target_ulong args,
+   uint32_t nret,
+   target_ulong rets)
+{
+rtas_ibm_create_pe_dma_window(cpu, spapr, token, nargs, args, nret, rets);
+
+SPAPR_RTAS_DDW_SWAP(0);
+SPAPR_RTAS_DDW_SWAP(1);
+SPAPR_RTAS_DDW_SWAP(2);
+SPAPR_RTAS_DDW_SWAP(3);
+}
+
 static void spapr_rtas_ddw_init(void)
 {
 spapr_rtas_register(RTAS_IBM_QUERY_PE_DMA_WINDOW,
@@ -292,6 +327,11 @@ static void spapr_rtas_ddw_init(void)
 spapr_rtas_register(RTAS_IBM_RESET_PE_DMA_WINDOW,
 "ibm,reset-pe-dma-window",
 rtas_ibm_reset_pe_dma_window);
+
+spapr_rtas_register_wrong_endian(RTAS_IBM_QUERY_PE_DMA_WINDOW,
+ 
rtas_ibm_query_pe_dma_window_wrong_endian);
+spapr_rtas_register_wrong_endian(RTAS_IBM_CREATE_PE_DMA_WINDOW,
+ 
rtas_ibm_create_pe_dma_window_wrong_endian);
 }
 
 type_init(spapr_rt

[Qemu-devel] [PATCH] vnc: fix qemu crash when not configure vnc option

2015-01-29 Thread arei.gonglei
From: Gonglei 

Reproducer:
$ x86_64-softmmu/qemu-system-x86_64
qemu-system-x86_64: Invalid parameter 'to'
Segmentation fault (core dumped)

Signed-off-by: Gonglei 
---
 ui/vnc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/ui/vnc.c b/ui/vnc.c
index a742c90..acff482 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3276,6 +3276,9 @@ static QemuOptsList qemu_vnc_opts = {
 .name = "connections",
 .type = QEMU_OPT_NUMBER,
 },{
+.name = "to",
+.type = QEMU_OPT_NUMBER,
+},{
 .name = "password",
 .type = QEMU_OPT_BOOL,
 },{
-- 
1.7.12.4





[Qemu-devel] [PATCH v4 10/18] spapr_pci: Define DDW callbacks

2015-01-29 Thread Alexey Kardashevskiy
This adds callbacks definitions which PHB needs to implement in order to
support dynamic DMA windows (DDW).

Will be squashed later.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: David Gibson 
---
 include/hw/pci-host/spapr.h | 21 +
 1 file changed, 21 insertions(+)

diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 5c91387..eec95f3 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -49,6 +49,27 @@ struct sPAPRPHBClass {
 PCIHostBridgeClass parent_class;
 
 void (*finish_realize)(sPAPRPHBState *sphb, Error **errp);
+
+/* sPAPR spec defined pagesize mask values */
+#define DDW_PGSIZE_4K   0x01
+#define DDW_PGSIZE_64K  0x02
+#define DDW_PGSIZE_16M  0x04
+#define DDW_PGSIZE_32M  0x08
+#define DDW_PGSIZE_64M  0x10
+#define DDW_PGSIZE_128M 0x20
+#define DDW_PGSIZE_256M 0x40
+#define DDW_PGSIZE_16G  0x80
+#define DDW_PGSIZE_MASK 0xFF
+
+int (*ddw_query)(sPAPRPHBState *sphb, uint32_t *windows_supported,
+ uint32_t *page_size_mask,
+ uint32_t *dma32_window_size,
+ uint64_t *dma64_window_size);
+int (*ddw_create)(sPAPRPHBState *sphb, uint32_t liobn,
+  uint32_t page_shift, uint32_t window_shift,
+  sPAPRTCETable **ptcet);
+int (*ddw_remove)(sPAPRPHBState *sphb, sPAPRTCETable *tcet);
+int (*ddw_reset)(sPAPRPHBState *sphb);
 };
 
 typedef struct spapr_pci_msi {
-- 
2.0.0




[Qemu-devel] [PATCH v4 14/18] vfio: Enable DDW ioctls to VFIO IOMMU driver

2015-01-29 Thread Alexey Kardashevskiy
This enables DDW RTAS-related ioctls in VFIO.

Signed-off-by: Alexey Kardashevskiy 
---
 hw/vfio/common.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index c08f9ab..1cafcf8 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -1045,6 +1045,8 @@ int vfio_container_ioctl(AddressSpace *as, int32_t 
groupid,
 switch (req) {
 case VFIO_CHECK_EXTENSION:
 case VFIO_IOMMU_SPAPR_TCE_GET_INFO:
+case VFIO_IOMMU_SPAPR_TCE_CREATE:
+case VFIO_IOMMU_SPAPR_TCE_REMOVE:
 break;
 default:
 /* Return an error on unknown requests */
-- 
2.0.0




[Qemu-devel] [PATCH v4 03/18] spapr_pci: Introduce a liobn number generating macros

2015-01-29 Thread Alexey Kardashevskiy
We are going to have multiple DMA windows per PHB and we want them to
migrate so we need a predictable way of assigning LIOBNs.

This introduces a macro which makes up a LIOBN from fixed prefix,
PHB index (unique PHB id) and window number.

This introduces a SPAPR_PCI_DMA_WINDOW_NUM() to know the window number
from LIOBN. It is used to distinguish the default 32bit windows from
dynamic windows and avoid picking default DMA window properties from
a wrong TCE table.

Signed-off-by: Alexey Kardashevskiy 
Reviewed-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 4 ++--
 include/hw/ppc/spapr.h | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 4500849..64c7702 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -502,7 +502,7 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
 }
 
 sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
-sphb->dma_liobn = SPAPR_PCI_BASE_LIOBN + sphb->index;
+sphb->dma_liobn = SPAPR_PCI_LIOBN(sphb->index, 0);
 
 windows_base = SPAPR_PCI_WINDOW_BASE
 + sphb->index * SPAPR_PCI_WINDOW_SPACING;
@@ -843,7 +843,7 @@ static int spapr_phb_children_dt(Object *child, void 
*opaque)
 sPAPRTCETable *tcet;
 
 tcet = (sPAPRTCETable *) object_dynamic_cast(child, TYPE_SPAPR_TCE_TABLE);
-if (!tcet) {
+if (!tcet || SPAPR_PCI_DMA_WINDOW_NUM(tcet->liobn)) {
 return 0;
 }
 
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 642cdc3..a2c4bac 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -442,7 +442,8 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr 
rtas_addr,
 #define SPAPR_TCE_PAGE_MASK(SPAPR_TCE_PAGE_SIZE - 1)
 
 #define SPAPR_VIO_BASE_LIOBN0x
-#define SPAPR_PCI_BASE_LIOBN0x8000
+#define SPAPR_PCI_LIOBN(i, n)   (0x8000 | ((i) << 8) | (n))
+#define SPAPR_PCI_DMA_WINDOW_NUM(liobn) ((liobn) & 0xff)
 
 #define RTAS_ERROR_LOG_MAX  2048
 
-- 
2.0.0




[Qemu-devel] [PATCH v2 4/4] block: Eliminate silly QERR_ macros used for encryption keys

2015-01-29 Thread Markus Armbruster
The QERR_ macros are leftovers from the days of "rich" error objects.
They're used with error_set() and qerror_report(), and expand into the
first *two* arguments.  This trickiness has become pointless.  Clean
up QERR_DEVICE_ENCRYPTED and QERR_DEVICE_NOT_ENCRYPTED.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 block.c   | 5 +++--
 include/qapi/qmp/qerror.h | 6 --
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/block.c b/block.c
index aa12160..ad6fcef 100644
--- a/block.c
+++ b/block.c
@@ -3734,14 +3734,15 @@ void bdrv_add_key(BlockDriverState *bs, const char 
*key, Error **errp)
 {
 if (key) {
 if (!bdrv_is_encrypted(bs)) {
-error_set(errp, QERR_DEVICE_NOT_ENCRYPTED,
+error_setg(errp, "Device '%s' is not encrypted",
   bdrv_get_device_name(bs));
 } else if (bdrv_set_key(bs, key) < 0) {
 error_set(errp, QERR_INVALID_PASSWORD);
 }
 } else {
 if (bdrv_key_required(bs)) {
-error_set(errp, QERR_DEVICE_ENCRYPTED,
+error_set(errp, ERROR_CLASS_DEVICE_ENCRYPTED,
+  "'%s' (%s) is encrypted",
   bdrv_get_device_name(bs),
   bdrv_get_encrypted_filename(bs));
 }
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index becdca6..423d8a3 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -52,9 +52,6 @@ void qerror_report_err(Error *err);
 #define QERR_COMMAND_NOT_FOUND \
 ERROR_CLASS_COMMAND_NOT_FOUND, "The command %s has not been found"
 
-#define QERR_DEVICE_ENCRYPTED \
-ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted"
-
 #define QERR_DEVICE_HAS_NO_MEDIUM \
 ERROR_CLASS_GENERIC_ERROR, "Device '%s' has no medium"
 
@@ -73,9 +70,6 @@ void qerror_report_err(Error *err);
 #define QERR_DEVICE_NOT_ACTIVE \
 ERROR_CLASS_DEVICE_NOT_ACTIVE, "No %s device has been activated"
 
-#define QERR_DEVICE_NOT_ENCRYPTED \
-ERROR_CLASS_GENERIC_ERROR, "Device '%s' is not encrypted"
-
 #define QERR_DEVICE_NOT_FOUND \
 ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found"
 
-- 
1.9.3




[Qemu-devel] [PATCH v2 1/4] blockdev: Give find_block_job() an Error ** parameter

2015-01-29 Thread Markus Armbruster
When find_block_job() fails, all its callers build the same Error
object.  Build it in find_block_job() instead.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 blockdev.c | 19 ---
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index d59efd3..8d6ca35 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2653,7 +2653,8 @@ out:
 }
 
 /* Get the block job for a given device name and acquire its AioContext */
-static BlockJob *find_block_job(const char *device, AioContext **aio_context)
+static BlockJob *find_block_job(const char *device, AioContext **aio_context,
+Error **errp)
 {
 BlockDriverState *bs;
 
@@ -2673,6 +2674,7 @@ static BlockJob *find_block_job(const char *device, 
AioContext **aio_context)
 return bs->job;
 
 notfound:
+error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
 *aio_context = NULL;
 return NULL;
 }
@@ -2680,10 +2682,9 @@ notfound:
 void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
 {
 AioContext *aio_context;
-BlockJob *job = find_block_job(device, &aio_context);
+BlockJob *job = find_block_job(device, &aio_context, errp);
 
 if (!job) {
-error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
 return;
 }
 
@@ -2695,10 +2696,9 @@ void qmp_block_job_cancel(const char *device,
   bool has_force, bool force, Error **errp)
 {
 AioContext *aio_context;
-BlockJob *job = find_block_job(device, &aio_context);
+BlockJob *job = find_block_job(device, &aio_context, errp);
 
 if (!job) {
-error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
 return;
 }
 
@@ -2721,10 +2721,9 @@ out:
 void qmp_block_job_pause(const char *device, Error **errp)
 {
 AioContext *aio_context;
-BlockJob *job = find_block_job(device, &aio_context);
+BlockJob *job = find_block_job(device, &aio_context, errp);
 
 if (!job) {
-error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
 return;
 }
 
@@ -2736,10 +2735,9 @@ void qmp_block_job_pause(const char *device, Error 
**errp)
 void qmp_block_job_resume(const char *device, Error **errp)
 {
 AioContext *aio_context;
-BlockJob *job = find_block_job(device, &aio_context);
+BlockJob *job = find_block_job(device, &aio_context, errp);
 
 if (!job) {
-error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
 return;
 }
 
@@ -2751,10 +2749,9 @@ void qmp_block_job_resume(const char *device, Error 
**errp)
 void qmp_block_job_complete(const char *device, Error **errp)
 {
 AioContext *aio_context;
-BlockJob *job = find_block_job(device, &aio_context);
+BlockJob *job = find_block_job(device, &aio_context, errp);
 
 if (!job) {
-error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
 return;
 }
 
-- 
1.9.3




[Qemu-devel] [PATCH v2 2/4] blockdev: Eliminate silly QERR_BLOCK_JOB_NOT_ACTIVE macro

2015-01-29 Thread Markus Armbruster
From: Markus Armbruster 

The QERR_ macros are leftovers from the days of "rich" error objects.
They're used with error_set() and qerror_report(), and expand into the
first *two* arguments.  This trickiness has become pointless.  Clean
this one up.

Signed-off-by: Markus Armbruster 
Reviewed-by: Eric Blake 
---
 blockdev.c| 3 ++-
 include/qapi/qmp/qerror.h | 3 ---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 8d6ca35..287d7af 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2674,7 +2674,8 @@ static BlockJob *find_block_job(const char *device, 
AioContext **aio_context,
 return bs->job;
 
 notfound:
-error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
+error_set(errp, ERROR_CLASS_DEVICE_NOT_ACTIVE,
+  "No active block job on device '%s'", device);
 *aio_context = NULL;
 return NULL;
 }
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 0ca6cbd..becdca6 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -37,9 +37,6 @@ void qerror_report_err(Error *err);
 #define QERR_BASE_NOT_FOUND \
 ERROR_CLASS_GENERIC_ERROR, "Base '%s' not found"
 
-#define QERR_BLOCK_JOB_NOT_ACTIVE \
-ERROR_CLASS_DEVICE_NOT_ACTIVE, "No active block job on device '%s'"
-
 #define QERR_BLOCK_JOB_NOT_READY \
 ERROR_CLASS_GENERIC_ERROR, "The active block job for device '%s' cannot be 
completed"
 
-- 
1.9.3




[Qemu-devel] [PATCH v2 0/4] block: Cleanups around error reporting

2015-01-29 Thread Markus Armbruster
v2:
* PATCH 4: Use error_setg() [Kevin]
* R-bys retained

Markus Armbruster (4):
  blockdev: Give find_block_job() an Error ** parameter
  blockdev: Eliminate silly QERR_BLOCK_JOB_NOT_ACTIVE macro
  block: New bdrv_add_key(), convert monitor to use it
  block: Eliminate silly QERR_ macros used for encryption keys

 block.c   | 30 ++
 blockdev.c| 44 +++-
 include/block/block.h |  1 +
 include/qapi/qmp/qerror.h |  9 -
 monitor.c | 16 +++-
 qmp.c |  8 
 6 files changed, 57 insertions(+), 51 deletions(-)

-- 
1.9.3




Re: [Qemu-devel] [PATCH] target-mips: use CP0EnLo_XI instead of magic number

2015-01-29 Thread Leon Alrae
On 28/01/2015 23:11, Maciej W. Rozycki wrote:
>> @@ -4947,7 +4947,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int 
>> reg, int sel)
>>  #if defined(TARGET_MIPS64)
>>  if (ctx->rxi) {
>>  TCGv tmp = tcg_temp_new();
>> -tcg_gen_andi_tl(tmp, arg, (3ull << 62));
>> +tcg_gen_andi_tl(tmp, arg, (3ull << CP0EnLo_XI));
>>  tcg_gen_shri_tl(tmp, tmp, 32);
> 
> ... don't we need to do:
> 
> tcg_gen_andi_tl(arg, arg, ~(3ull << CP0EnLo_XI));
> 
> here and for EntryLo1 as well (for LPA-enabled processors)?

Yes, this would be required if we supported LPA - good spot.

> 
>>  tcg_gen_or_tl(arg, arg, tmp);
>>  tcg_temp_free(tmp);
> 
>  And do we want to have CP0C3_LPA set in the few templates that do in the 
> first place?  AFAICT we don't really implement LPA so this bit will 
> confuse software.  Of course implementing it would be another option, not 
> very complicated AFAICS, and if we can track the requirement to update 
> MFC0 at that time, then the clean-up I mentioned above can be deferred 
> until then.

In general I don't think it's a good idea to indicate presence of a
feature in a CPU config if it isn't implemented at all in QEMU -- as you
said, it will confuse software. As far as LPA goes I've got already an
implementation of it (and XPA as well) which I haven't submitted
upstream yet. I'll make sure it contains the change you suggested.

Thanks,
Leon




Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits

2015-01-29 Thread David Gibson
On Thu, Jan 29, 2015 at 10:24:00AM +0100, Thomas Huth wrote:
> 
>  Hi,
> 
> On Thu, 29 Jan 2015 11:11:32 +1100
> David Gibson  wrote:
> 
> > On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > > On Thu, 22 Jan 2015 12:43:43 +1100
> > > David Gibson  wrote:
> > > 
> > > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > > With virtio-1, we support more than 32 feature bits. Let's extend both
> > > > > host and guest features to 64, which should suffice for a while.
> > > > > 
> > > > > vhost and migration have been ignored for now.
> > > > 
> > > > [snip]
> > > > 
> > > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > > index f6c0379..08141c7 100644
> > > > > --- a/include/hw/virtio/virtio.h
> > > > > +++ b/include/hw/virtio/virtio.h
> > > > > @@ -55,6 +55,12 @@
> > > > >  /* A guest should never accept this.  It implies negotiation is 
> > > > > broken. */
> > > > >  #define VIRTIO_F_BAD_FEATURE 30
> > > > >  
> > > > > +/* v1.0 compliant. */
> > > > > +#define VIRTIO_F_VERSION_1  32
> > > > 
> > > > This is already in the kernel header, isn't it?
> > 
> > > 
> > > Yes. But nearly all files include this header but not the kernel
> > > header.
> > 
> > Can't you change that?  Or this file include the kernel header?
>  
> AFAIK non-KVM code should never try to include one of the Linux headers
> to avoid breaking on non-Linux platforms (for example  is
> not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
> So it's a little bit ugly to define these things twice, but it seems
> the only way to stay portable.

Ah, yeah, good point.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


pgp062bZnQwA1.pgp
Description: PGP signature


Re: [Qemu-devel] [PATCH v3 0/4] target-arm: ARM64: Adding EL1 AARCH32 guest support

2015-01-29 Thread Christoffer Dall
On Tue, Jan 27, 2015 at 05:58:33PM -0600, Greg Bellows wrote:
> Added support for running an AArch32 guest on a AArch64 KVM host.  Support has
> only been added to the QEMU machvirt machine.  The addition of CPU properties
> specifiable from the command line were added to allow disablement of AArch64
> execution state hereby forcing EL1 to be AArch32.  The new CPU command line
> property is "aarch64=on/off" that is specified as follows:
> 
> aarch64-softmmu/qemu-system-aarch64 -M virt -cpu cortex-a57,aarch64=off 
> ...
> 
Tested-by: Christoffer Dall 



Re: [Qemu-devel] [PATCH] net: synchronize net_host_device_remove with host_net_remove_completion

2015-01-29 Thread Jason Wang

On 12/24/2014 12:53 AM, Paolo Bonzini wrote:
> Using net_host_check_device is unnecessary.  qemu_del_net_client asserts
> for the non-peer case that it can only process NIC type NetClientStates,
> and that assertion is valid for the peered case as well, so move it and
> use the same check in net_host_device_remove.  host_net_remove_completion
> is already checking the type.
>
> Signed-off-by: Paolo Bonzini 
> ---
>  net/net.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/net/net.c b/net/net.c
> index 7acc162..1da612f 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -324,6 +324,8 @@ void qemu_del_net_client(NetClientState *nc)
>  NetClientState *ncs[MAX_QUEUE_NUM];
>  int queues, i;
>  
> +assert(nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC);
> +
>  /* If the NetClientState belongs to a multiqueue backend, we will change 
> all
>   * other NetClientStates also.
>   */
> @@ -355,8 +357,6 @@ void qemu_del_net_client(NetClientState *nc)
>  return;
>  }
>  
> -assert(nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC);
> -
>  for (i = 0; i < queues; i++) {
>  qemu_cleanup_net_client(ncs[i]);
>  qemu_free_net_client(ncs[i]);
> @@ -992,7 +992,7 @@ void net_host_device_remove(Monitor *mon, const QDict 
> *qdict)
>   device, vlan_id);
>  return;
>  }
> -if (!net_host_check_device(nc->model)) {
> +if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
>  error_report("invalid host network device '%s'", device);
>  return;
>  }

Reviewed-by: Jason Wang 



Re: [Qemu-devel] [RFC PATCH v8 02/21] replay: global variables and function stubs

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:51, Pavel Dovgalyuk wrote:
> This patch adds global variables, defines, functions declarations,
> and function stubs for deterministic VM replay used by external modules.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  Makefile.target  |1 +
>  qapi-schema.json |   18 ++
>  replay/Makefile.objs |1 +
>  replay/replay.c  |   14 ++
>  replay/replay.h  |   19 +++
>  stubs/Makefile.objs  |1 +
>  stubs/replay.c   |3 +++
>  7 files changed, 57 insertions(+), 0 deletions(-)
>  create mode 100755 replay/Makefile.objs
>  create mode 100755 replay/replay.c
>  create mode 100755 replay/replay.h
>  create mode 100755 stubs/replay.c
> 
> diff --git a/Makefile.target b/Makefile.target
> index e9ff1ee..a45378f 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -83,6 +83,7 @@ all: $(PROGS) stap
>  #
>  # cpu emulator library
>  obj-y = exec.o translate-all.o cpu-exec.o
> +obj-y += replay/
>  obj-y += tcg/tcg.o tcg/optimize.o
>  obj-$(CONFIG_TCG_INTERPRETER) += tci.o
>  obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
> diff --git a/qapi-schema.json b/qapi-schema.json
> index fbfc52f..7e3177f 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3523,3 +3523,21 @@
>  # Since: 2.1
>  ##
>  { 'command': 'rtc-reset-reinjection' }
> +
> +##
> +# ReplayMode:
> +#
> +# Mode of the replay subsystem.
> +#
> +# @none: normal execution mode. Replay or record are not enabled.
> +#
> +# @record: record mode. All non-deterministic data is written into the
> +#  replay log.
> +#
> +# @play: replay mode. Non-deterministic data required for system execution
> +#is read from the log.
> +#
> +# Since: 2.3
> +##
> +{ 'enum': 'ReplayMode',
> +  'data': [ 'none', 'record', 'play' ] }
> diff --git a/replay/Makefile.objs b/replay/Makefile.objs
> new file mode 100755
> index 000..7ea860f
> --- /dev/null
> +++ b/replay/Makefile.objs
> @@ -0,0 +1 @@
> +obj-y += replay.o
> diff --git a/replay/replay.c b/replay/replay.c
> new file mode 100755
> index 000..5ce066f
> --- /dev/null
> +++ b/replay/replay.c
> @@ -0,0 +1,14 @@
> +/*
> + * replay.c
> + *
> + * Copyright (c) 2010-2015 Institute for System Programming
> + * of the Russian Academy of Sciences.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "replay.h"
> +
> +ReplayMode replay_mode = REPLAY_MODE_NONE;
> diff --git a/replay/replay.h b/replay/replay.h
> new file mode 100755
> index 000..d6b73c3
> --- /dev/null
> +++ b/replay/replay.h
> @@ -0,0 +1,19 @@
> +#ifndef REPLAY_H
> +#define REPLAY_H
> +
> +/*
> + * replay.h
> + *
> + * Copyright (c) 2010-2015 Institute for System Programming
> + * of the Russian Academy of Sciences.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "qapi-types.h"
> +
> +extern ReplayMode replay_mode;
> +
> +#endif
> diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
> index 5e347d0..45a6c71 100644
> --- a/stubs/Makefile.objs
> +++ b/stubs/Makefile.objs
> @@ -27,6 +27,7 @@ stub-obj-y += notify-event.o
>  stub-obj-y += pci-drive-hot-add.o
>  stub-obj-$(CONFIG_SPICE) += qemu-chr-open-spice.o
>  stub-obj-y += qtest.o
> +stub-obj-y += replay.o
>  stub-obj-y += reset.o
>  stub-obj-y += runstate-check.o
>  stub-obj-y += set-fd-handler.o
> diff --git a/stubs/replay.c b/stubs/replay.c
> new file mode 100755
> index 000..563c777
> --- /dev/null
> +++ b/stubs/replay.c
> @@ -0,0 +1,3 @@
> +#include "replay/replay.h"
> +
> +ReplayMode replay_mode;
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [RFC PATCH v8 04/21] replay: internal functions for replay log

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:51, Pavel Dovgalyuk wrote:
> This patch adds functions to perform read and write operations
> with replay log.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  replay/Makefile.objs |1 
>  replay/replay-internal.c |  141 
> ++
>  replay/replay-internal.h |   50 
>  3 files changed, 192 insertions(+), 0 deletions(-)
>  create mode 100755 replay/replay-internal.c
>  create mode 100755 replay/replay-internal.h
> 
> diff --git a/replay/Makefile.objs b/replay/Makefile.objs
> index 7ea860f..1148f45 100755
> --- a/replay/Makefile.objs
> +++ b/replay/Makefile.objs
> @@ -1 +1,2 @@
>  obj-y += replay.o
> +obj-y += replay-internal.o
> diff --git a/replay/replay-internal.c b/replay/replay-internal.c
> new file mode 100755
> index 000..3865fa5
> --- /dev/null
> +++ b/replay/replay-internal.c
> @@ -0,0 +1,141 @@
> +/*
> + * replay-internal.c
> + *
> + * Copyright (c) 2010-2015 Institute for System Programming
> + * of the Russian Academy of Sciences.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "qemu-common.h"
> +#include "replay-internal.h"
> +
> +unsigned int replay_data_kind = -1;
> +unsigned int replay_has_unread_data;
> +
> +/* File for replay writing */
> +FILE *replay_file;
> +
> +void replay_put_byte(uint8_t byte)
> +{
> +if (replay_file) {
> +fwrite(&byte, sizeof(byte), 1, replay_file);

putc(byte, replay_file);

> +}
> +}
> +
> +void replay_put_event(uint8_t event)
> +{
> +replay_put_byte(event);
> +}
> +
> +
> +void replay_put_word(uint16_t word)
> +{
> +if (replay_file) {
> +fwrite(&word, sizeof(word), 1, replay_file);

Let's make this use a guaranteed endianness.  QEMU usually uses big
endian.  So either use putc, or use cpu_to_be16 and fwrite.

> +}
> +}
> +
> +void replay_put_dword(uint32_t dword)
> +{
> +if (replay_file) {
> +fwrite(&dword, sizeof(dword), 1, replay_file);

Same here.

> +}
> +}
> +
> +void replay_put_qword(int64_t qword)
> +{
> +if (replay_file) {
> +fwrite(&qword, sizeof(qword), 1, replay_file);

And same here.

> +}
> +}
> +
> +void replay_put_array(const uint8_t *buf, size_t size)
> +{
> +if (replay_file) {
> +fwrite(&size, sizeof(size), 1, replay_file);

replay_put_dword (a limit of 2^32 elements should not be a problem :)).

> +fwrite(buf, 1, size, replay_file);
> +}
> +}
> +
> +uint8_t replay_get_byte(void)
> +{
> +uint8_t byte;
> +if (replay_file) {
> +fread(&byte, sizeof(byte), 1, replay_file);

byte = getc(replay_file)

> +}
> +return byte;
> +}
> +
> +uint16_t replay_get_word(void)
> +{
> +uint16_t word;
> +if (replay_file) {
> +fread(&word, sizeof(word), 1, replay_file);

Same comment about endianness.

> +}
> +
> +return word;
> +}
> +
> +uint32_t replay_get_dword(void)
> +{
> +uint32_t dword;
> +if (replay_file) {
> +fread(&dword, sizeof(dword), 1, replay_file);
> +}
> +
> +return dword;
> +}
> +
> +int64_t replay_get_qword(void)
> +{
> +int64_t qword;
> +if (replay_file) {
> +fread(&qword, sizeof(qword), 1, replay_file);
> +}
> +
> +return qword;
> +}
> +
> +void replay_get_array(uint8_t *buf, size_t *size)
> +{
> +if (replay_file) {
> +fread(size, sizeof(*size), 1, replay_file);
> +fread(buf, 1, *size, replay_file);
> +}
> +}
> +
> +void replay_get_array_alloc(uint8_t **buf, size_t *size)
> +{
> +if (replay_file) {
> +fread(size, sizeof(*size), 1, replay_file);
> +*buf = g_malloc(*size);
> +fread(*buf, 1, *size, replay_file);
> +}
> +}
> +
> +void replay_check_error(void)

Could this be static? (I haven't checked).

> +{
> +if (replay_file) {
> +if (feof(replay_file)) {
> +fprintf(stderr, "replay file is over\n");
> +exit(1);

Perhaps qemu_system_vmstop_request_prepare +
qemu_system_vmstop_request(RUN_STATE_PAUSED) instead of exit?  Those two
functions are thread-safe.


> +} else if (ferror(replay_file)) {
> +fprintf(stderr, "replay file is over or something goes wrong\n");

Same here (RUN_STATE_INTERNAL_ERROR?).

> +exit(1);
> +}
> +}
> +}
> +
> +void replay_fetch_data_kind(void)
> +{
> +if (replay_file) {
> +if (!replay_has_unread_data) {
> +replay_data_kind = replay_get_byte();
> +replay_check_error();
> +replay_has_unread_data = 1;
> +}
> +}
> +}
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> new file mode 100755
> index 000..dad5bc8
> --- /dev/null
> +++ b/replay/replay-internal.h
> @@ -0,0 +1,50 @@
> +#ifndef REPLAY_INTERNAL_H
> +#define REPLAY_INTERNAL_H
> +
> +/*
> + * replay-internal.h
> + *
> + * Copyright (c) 2010-2015 Institut

Re: [Qemu-devel] [RFC PATCH v8 08/21] cpu: replay instructions sequence

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:52, Pavel Dovgalyuk wrote:
> This patch adds calls to replay functions into the icount setup block.
> In record mode number of executed instructions is written to the log.
> In replay mode number of istructions to execute is taken from the replay log.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  cpu-exec.c  |1 +
>  cpus.c  |   28 ++--
>  replay/replay.c |   24 
>  replay/replay.h |4 
>  4 files changed, 47 insertions(+), 10 deletions(-)
> 
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 49f01f5..99a0993 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -531,6 +531,7 @@ int cpu_exec(CPUArchState *env)
>  }
>  cpu->exception_index = EXCP_INTERRUPT;
>  next_tb = 0;
> +qemu_notify_event();

Why is this needed?

>  cpu_loop_exit(cpu);
>  }
>  break;
> diff --git a/cpus.c b/cpus.c
> index c513275..8787277 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -41,6 +41,7 @@
>  #include "qemu/seqlock.h"
>  #include "qapi-event.h"
>  #include "hw/nmi.h"
> +#include "replay/replay.h"
>  
>  #ifndef _WIN32
>  #include "qemu/compatfd.h"
> @@ -1342,18 +1343,22 @@ static int tcg_cpu_exec(CPUArchState *env)
>  + cpu->icount_extra);
>  cpu->icount_decr.u16.low = 0;
>  cpu->icount_extra = 0;
> -deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
> +if (replay_mode != REPLAY_MODE_PLAY) {
> +deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
>  
> -/* Maintain prior (possibly buggy) behaviour where if no deadline
> - * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more 
> than
> - * INT32_MAX nanoseconds ahead, we still use INT32_MAX
> - * nanoseconds.
> - */
> -if ((deadline < 0) || (deadline > INT32_MAX)) {
> -deadline = INT32_MAX;
> -}
> +/* Maintain prior (possibly buggy) behaviour where if no deadline
> + * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is 
> more than
> + * INT32_MAX nanoseconds ahead, we still use INT32_MAX
> + * nanoseconds.
> + */
> +if ((deadline < 0) || (deadline > INT32_MAX)) {
> +deadline = INT32_MAX;
> +}
>  
> -count = qemu_icount_round(deadline);
> +count = qemu_icount_round(deadline);
> +} else {
> +count = replay_get_instructions();
> +}

Please extract the "if" to a separate function tcg_get_icount_limit().

>  timers_state.qemu_icount += count;
>  decr = (count > 0x) ? 0x : count;
>  count -= decr;
> @@ -1371,6 +1376,9 @@ static int tcg_cpu_exec(CPUArchState *env)
>  + cpu->icount_extra);
>  cpu->icount_decr.u32 = 0;
>  cpu->icount_extra = 0;
> +if (replay_mode == REPLAY_MODE_PLAY) {
> +replay_exec_instructions();

replay_account_executed_instructions()

> +}
>  }
>  return ret;
>  }
> diff --git a/replay/replay.c b/replay/replay.c
> index a43bbbc..d6f5c4b 100755
> --- a/replay/replay.c
> +++ b/replay/replay.c
> @@ -58,3 +58,27 @@ uint64_t replay_get_current_step(void)
>  {
>  return cpu_get_icount_raw();
>  }
> +
> +int replay_get_instructions(void)
> +{
> +int res = 0;
> +replay_mutex_lock();
> +if (skip_async_events(EVENT_INSTRUCTION)) {
> +res = replay_state.instructions_count;
> +}
> +replay_mutex_unlock();
> +return res;
> +}
> +
> +void replay_exec_instructions(void)
> +{
> +if (replay_state.instructions_count > 0) {
> +int count = (int)(replay_get_current_step()
> +  - replay_state.current_step);
> +replay_state.instructions_count -= count;
> +replay_state.current_step += count;
> +if (replay_state.instructions_count == 0 && count != 0) {

If replay_state.instructions_count is now zero, count must be nonzero
(because replay_state.instructions_count was > 0) before.

> +replay_has_unread_data = 0;
> +}

Can replay_state.instructions_count be < count at all?  If not, and if
replay_state.instructions_count is zero, then count must also be zero.

If so, I suggest rewriting as

int count = (int)(replay_get_current_step()
  - replay_state.current_step);
assert(replay_state.instructions_count >= count);
replay_state.instructions_count -= count;
replay_state.current_step += count;
if (replay_state.instructions_count == 0) {
replay_has_unread_data = 0;
}

Paolo

> +}
> +}
> diff --git a/replay/replay.h b/replay/replay.h
> index a03c748..e425dea 100755
> --- a/replay/replay.h
> +++ b/replay/repla

Re: [Qemu-devel] [RFC PATCH v8 03/21] sysemu: system functions for replay

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:51, Pavel Dovgalyuk wrote:
> This patch removes "static" specifier from several qemu function to make
> them visible to the replay module. It also invents several system functions
> that will be used by replay.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  cpus.c  |4 ++--
>  include/exec/exec-all.h |1 +
>  include/qom/cpu.h   |   10 ++
>  include/sysemu/cpus.h   |1 +
>  translate-all.c |8 
>  5 files changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/cpus.c b/cpus.c
> index 3a5323b..c513275 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -88,7 +88,7 @@ static bool cpu_thread_is_idle(CPUState *cpu)
>  return true;
>  }
>  
> -static bool all_cpu_threads_idle(void)
> +bool all_cpu_threads_idle(void)
>  {
>  CPUState *cpu;
>  
> @@ -1121,7 +1121,7 @@ bool qemu_cpu_is_self(CPUState *cpu)
>  return qemu_thread_is_self(cpu->thread);
>  }
>  
> -static bool qemu_in_vcpu_thread(void)
> +bool qemu_in_vcpu_thread(void)
>  {
>  return current_cpu && qemu_cpu_is_self(current_cpu);
>  }
> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
> index 4a6237f..63fb1a3 100644
> --- a/include/exec/exec-all.h
> +++ b/include/exec/exec-all.h
> @@ -214,6 +214,7 @@ static inline unsigned int 
> tb_phys_hash_func(tb_page_addr_t pc)
>  
>  void tb_free(TranslationBlock *tb);
>  void tb_flush(CPUArchState *env);
> +void tb_flush_all(void);
>  void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
>  
>  #if defined(USE_DIRECT_JUMP)
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 2098f1c..5afb44c 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -480,6 +480,16 @@ static inline bool cpu_has_work(CPUState *cpu)
>  bool qemu_cpu_is_self(CPUState *cpu);
>  
>  /**
> + * qemu_in_vcpu_thread:
> + *
> + * Checks whether the caller is executing on the vCPU thread
> + * of the current vCPU.
> + *
> + * Returns: %true if called from vCPU's thread, %false otherwise.
> + */
> +bool qemu_in_vcpu_thread(void);
> +
> +/**
>   * qemu_cpu_kick:
>   * @cpu: The vCPU to kick.
>   *
> diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
> index 3f162a9..86ae556 100644
> --- a/include/sysemu/cpus.h
> +++ b/include/sysemu/cpus.h
> @@ -6,6 +6,7 @@ void qemu_init_cpu_loop(void);
>  void resume_all_vcpus(void);
>  void pause_all_vcpus(void);
>  void cpu_stop_current(void);
> +bool all_cpu_threads_idle(void);
>  
>  void cpu_synchronize_all_states(void);
>  void cpu_synchronize_all_post_reset(void);
> diff --git a/translate-all.c b/translate-all.c
> index 4a1b64f..c0cba7d 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -812,6 +812,14 @@ void tb_flush(CPUArchState *env1)
>  tcg_ctx.tb_ctx.tb_flush_count++;
>  }
>  
> +void tb_flush_all(void)
> +{
> +CPUState *cpu;
> +for (cpu = first_cpu ; cpu != NULL ; cpu = CPU_NEXT(cpu)) {
> +tb_flush(cpu->env_ptr);
> +}
> +}
> +
>  #ifdef DEBUG_TB_CHECK
>  
>  static void tb_invalidate_check(target_ulong address)
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [RFC PATCH v8 05/21] replay: introduce mutex to protect the replay log

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:51, Pavel Dovgalyuk wrote:
> This mutex will protect read/write operations for replay log.
> Using mutex is necessary because most of the events consist of
> several fields stored in the log. The mutex will help to avoid races.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  replay/replay-internal.c |   25 +
>  replay/replay-internal.h |7 +++
>  2 files changed, 32 insertions(+), 0 deletions(-)
> 
> diff --git a/replay/replay-internal.c b/replay/replay-internal.c
> index 3865fa5..f552dad 100755
> --- a/replay/replay-internal.c
> +++ b/replay/replay-internal.c
> @@ -15,6 +15,11 @@
>  unsigned int replay_data_kind = -1;
>  unsigned int replay_has_unread_data;
>  
> +/* Mutex to protect reading and writing events to the log.
> +   replay_data_kind and replay_has_unread_data are also protected
> +   by this mutex. */
> +static QemuMutex lock;
> +
>  /* File for replay writing */
>  FILE *replay_file;
>  
> @@ -139,3 +144,23 @@ void replay_fetch_data_kind(void)
>  }
>  }
>  }
> +
> +void replay_mutex_init(void)
> +{
> +qemu_mutex_init(&lock);
> +}
> +
> +void replay_mutex_destroy(void)
> +{
> +qemu_mutex_destroy(&lock);
> +}

Destroy is probably not necessary.

> +void replay_mutex_lock(void)
> +{
> +qemu_mutex_lock(&lock);
> +}
> +
> +void replay_mutex_unlock(void)
> +{
> +qemu_mutex_unlock(&lock);
> +}
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index dad5bc8..50ce29b 100755
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -34,6 +34,13 @@ int64_t replay_get_qword(void);
>  void replay_get_array(uint8_t *buf, size_t *size);
>  void replay_get_array_alloc(uint8_t **buf, size_t *size);
>  
> +/* Mutex functions for protecting replay log file */
> +
> +void replay_mutex_init(void);
> +void replay_mutex_destroy(void);
> +void replay_mutex_lock(void);
> +void replay_mutex_unlock(void);
> +
>  /*! Checks error status of the file. */
>  void replay_check_error(void);
>  
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [RFC PATCH v8 09/21] replay: interrupts and exceptions

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:52, Pavel Dovgalyuk wrote:
> +if (replay_mode == REPLAY_MODE_RECORD) {
> +replay_save_instructions();
> +replay_put_event(EVENT_EXCEPTION);
> +return true;

Missing mutex lock/unlock.

> +} else if (replay_mode == REPLAY_MODE_PLAY) {
> +bool res = false;
> +replay_exec_instructions();
> +replay_mutex_lock();
> +if (skip_async_events(EVENT_EXCEPTION)) {
> +replay_has_unread_data = 0;
> +res = true;
> +}
> +replay_mutex_unlock();
> +return res;
> +}

bool res;
replay_exec_instructions();
res = replay_has_exception();
if (res) {
replay_has_unread_data = 0;
}
return res;

Same for replay_interrupt().

Perhaps worth factoring out two functions replay_cpu_event and
replay_has_cpu_event?  You choose.

> 
> @@ -1294,6 +1295,9 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int 
> interrupt_request)
>  if (interrupt_request & CPU_INTERRUPT_POLL) {
>  cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
>  apic_poll_irq(cpu->apic_state);
> +if (replay_mode != REPLAY_MODE_NONE) {
> +return true;
> +}
>  }
>  #endif

Can you explain this?  It probably needs a comment.

Paolo



Re: [Qemu-devel] [RFC PATCH v8 11/21] replay: recording and replaying clock ticks

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:52, Pavel Dovgalyuk wrote:
> Clock ticks are considered as the sources of non-deterministic data for
> virtual machine. This patch implements saving the clock values when they
> are acquired (virtual, host clock, rdtsc, and some other timers).
> When replaying the execution corresponding values are read from log and
> transfered to the module, which wants to read the values.
> Such a design required the clock polling to be synchronized. Sometimes
> it is not true - e.g. when timeouts for timer lists are checked. In this case
> we use a cached value of the clock, passing it to the client code.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  cpus.c   |3 +-
>  include/qemu/timer.h |   10 +
>  qemu-timer.c |7 ++--
>  replay/Makefile.objs |1 +
>  replay/replay-internal.h |   13 +++
>  replay/replay-time.c |   84 
> ++
>  replay/replay.h  |   25 ++
>  stubs/replay.c   |9 +
>  8 files changed, 147 insertions(+), 5 deletions(-)
>  create mode 100755 replay/replay-time.c
> 
> diff --git a/cpus.c b/cpus.c
> index 8787277..01d89aa 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -353,7 +353,8 @@ static void icount_warp_rt(void *opaque)
>  
>  seqlock_write_lock(&timers_state.vm_clock_seqlock);
>  if (runstate_is_running()) {
> -int64_t clock = cpu_get_clock_locked();
> +int64_t clock = REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT,
> + cpu_get_clock_locked());
>  int64_t warp_delta;
>  
>  warp_delta = clock - vm_clock_warp_start;
> diff --git a/include/qemu/timer.h b/include/qemu/timer.h
> index 0666920..0c2472c 100644
> --- a/include/qemu/timer.h
> +++ b/include/qemu/timer.h
> @@ -4,6 +4,7 @@
>  #include "qemu/typedefs.h"
>  #include "qemu-common.h"
>  #include "qemu/notify.h"
> +#include "replay/replay.h"
>  
>  /* timers */
>  
> @@ -760,6 +761,8 @@ int64_t cpu_icount_to_ns(int64_t icount);
>  /***/
>  /* host CPU ticks (if available) */
>  
> +#define cpu_get_real_ticks cpu_get_real_ticks_impl
> +
>  #if defined(_ARCH_PPC)
>  
>  static inline int64_t cpu_get_real_ticks(void)
> @@ -913,6 +916,13 @@ static inline int64_t cpu_get_real_ticks (void)
>  }
>  #endif
>  
> +#undef cpu_get_real_ticks
> +
> +static inline int64_t cpu_get_real_ticks(void)

cpu_get_real_ticks should never be used.  Please instead wrap
cpu_get_ticks() with REPLAY_CLOCK.

> +{
> +return REPLAY_CLOCK(REPLAY_CLOCK_REAL_TICKS, cpu_get_real_ticks_impl());
> +}
> +
>  #ifdef CONFIG_PROFILER
>  static inline int64_t profile_getclock(void)
>  {
> diff --git a/qemu-timer.c b/qemu-timer.c
> index 98d9d1b..bc981a2 100644
> --- a/qemu-timer.c
> +++ b/qemu-timer.c
> @@ -25,6 +25,7 @@
>  #include "sysemu/sysemu.h"
>  #include "monitor/monitor.h"
>  #include "ui/console.h"
> +#include "replay/replay.h"
>  
>  #include "hw/hw.h"
>  
> @@ -566,15 +567,15 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
>  return cpu_get_clock();
>  }
>  case QEMU_CLOCK_HOST:
> -now = get_clock_realtime();
> +now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime());
>  last = clock->last;
>  clock->last = now;
> -if (now < last) {
> +if (now < last && replay_mode == REPLAY_MODE_NONE) {
>  notifier_list_notify(&clock->reset_notifiers, &now);
>  }
>  return now;
>  case QEMU_CLOCK_VIRTUAL_RT:
> -return cpu_get_clock();
> +return REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock());
>  }
>  }
>  
> diff --git a/replay/Makefile.objs b/replay/Makefile.objs
> index 56da09c..257c320 100755
> --- a/replay/Makefile.objs
> +++ b/replay/Makefile.objs
> @@ -1,3 +1,4 @@
>  obj-y += replay.o
>  obj-y += replay-internal.o
>  obj-y += replay-events.o
> +obj-y += replay-time.o
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index 1666d6e..e906ec3 100755
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -22,7 +22,10 @@ enum ReplayEvents {
>  /* for emulated exceptions */
>  EVENT_EXCEPTION,
>  /* for async events */
> -EVENT_ASYNC
> +EVENT_ASYNC,
> +/* for clock read/writes */
> +/* some of grteater codes are reserved for clocks */
> +EVENT_CLOCK
>  };
>  
>  /* Asynchronous events IDs */
> @@ -34,6 +37,8 @@ enum ReplayAsyncEventKind {
>  typedef enum ReplayAsyncEventKind ReplayAsyncEventKind;
>  
>  typedef struct ReplayState {
> +/*! Cached clock values. */
> +int64_t cached_clock[REPLAY_CLOCK_COUNT];
>  /*! Current step - number of processed instructions and timer events. */
>  uint64_t current_step;
>  /*! Number of instructions to be executed before other events happen. */
> @@ -88,6 +93,12 @@ bool skip_async_events(int stop_event);
>  reports an error and stops the execution. */
>  void skip_async_events_unt

Re: [Qemu-devel] [RFC PATCH v8 10/21] replay: asynchronous events infrastructure

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:52, Pavel Dovgalyuk wrote:
> This patch adds module for saving and replaying asynchronous events.
> These events include network packets, keyboard and mouse input,
> USB packets, thread pool and bottom halves callbacks.
> All events are stored in the queue to be processed at synchronization points
> such as beginning of TB execution, or checkpoint in the iothread.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  replay/Makefile.objs |1 
>  replay/replay-events.c   |  228 
> ++
>  replay/replay-internal.h |   33 ++-
>  replay/replay.h  |4 +
>  4 files changed, 265 insertions(+), 1 deletions(-)
>  create mode 100755 replay/replay-events.c
> 
> diff --git a/replay/Makefile.objs b/replay/Makefile.objs
> index 1148f45..56da09c 100755
> --- a/replay/Makefile.objs
> +++ b/replay/Makefile.objs
> @@ -1,2 +1,3 @@
>  obj-y += replay.o
>  obj-y += replay-internal.o
> +obj-y += replay-events.o
> diff --git a/replay/replay-events.c b/replay/replay-events.c
> new file mode 100755
> index 000..dfd5efd
> --- /dev/null
> +++ b/replay/replay-events.c
> @@ -0,0 +1,228 @@
> +/*
> + * replay-events.c
> + *
> + * Copyright (c) 2010-2015 Institute for System Programming
> + * of the Russian Academy of Sciences.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include "qemu-common.h"
> +#include "replay.h"
> +#include "replay-internal.h"
> +
> +typedef struct Event {
> +ReplayAsyncEventKind event_kind;
> +void *opaque;
> +void *opaque2;
> +uint64_t id;
> +
> +QTAILQ_ENTRY(Event) events;
> +} Event;
> +
> +static QTAILQ_HEAD(, Event) events_list = 
> QTAILQ_HEAD_INITIALIZER(events_list);
> +/* Mutex to protect events_list modifications */
> +static QemuMutex lock;

Can you just reuse the replay_lock?  Otherwise you have to document the
lock hierarchy.  But if a single coarser lock is enough, that would be nice.

> +static unsigned int read_event_kind = -1;
> +static uint64_t read_id = -1;
> +static int read_opt = -1;

Please document what "opt" means.

> +
> +static bool replay_events_enabled = false;
> +
> +/* Functions */
> +
> +static void replay_run_event(Event *event)
> +{
> +switch (event->event_kind) {
> +default:
> +fprintf(stderr, "Replay: invalid async event ID (%d) in the queue\n",
> +event->event_kind);
> +exit(1);

Please treat this the same as ferror().  fprintf(stderr) should be
replaced by error_report(), which btw takes a string that is not
terminated by \n.

> +break;
> +}
> +}
> +
> +void replay_enable_events(void)
> +{
> +replay_events_enabled = true;
> +}
> +
> +bool replay_has_events(void)
> +{
> +return !QTAILQ_EMPTY(&events_list);
> +}
> +
> +void replay_flush_events(void)
> +{
> +qemu_mutex_lock(&lock);
> +while (!QTAILQ_EMPTY(&events_list)) {
> +Event *event = QTAILQ_FIRST(&events_list);
> +qemu_mutex_unlock(&lock);
> +replay_run_event(event);
> +qemu_mutex_lock(&lock);
> +QTAILQ_REMOVE(&events_list, event, events);
> +g_free(event);
> +}
> +qemu_mutex_unlock(&lock);
> +}
> +
> +void replay_disable_events(void)
> +{
> +replay_events_enabled = false;
> +/* Flush events queue before waiting of completion */
> +replay_flush_events();
> +}
> +
> +void replay_clear_events(void)
> +{
> +qemu_mutex_lock(&lock);
> +while (!QTAILQ_EMPTY(&events_list)) {
> +Event *event = QTAILQ_FIRST(&events_list);
> +QTAILQ_REMOVE(&events_list, event, events);
> +
> +g_free(event);
> +}
> +qemu_mutex_unlock(&lock);
> +}
> +
> +static void replay_add_event_internal(ReplayAsyncEventKind event_kind,
> +  void *opaque,
> +  void *opaque2, uint64_t id)
> +{
> +if (event_kind >= REPLAY_ASYNC_COUNT) {
> +fprintf(stderr, "Replay: invalid async event ID (%d)\n", event_kind);
> +exit(1);
> +}
> +if (!replay_file || replay_mode == REPLAY_MODE_NONE
> +|| !replay_events_enabled) {
> +Event e;
> +e.event_kind = event_kind;
> +e.opaque = opaque;
> +e.opaque2 = opaque2;
> +e.id = id;
> +replay_run_event(&e);
> +return;
> +}
> +
> +Event *event = g_malloc0(sizeof(Event));
> +event->event_kind = event_kind;
> +event->opaque = opaque;
> +event->opaque2 = opaque2;
> +event->id = id;
> +
> +qemu_mutex_lock(&lock);
> +QTAILQ_INSERT_TAIL(&events_list, event, events);
> +qemu_mutex_unlock(&lock);
> +}
> +
> +void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque)
> +{
> +replay_add_event_internal(event_kind, opaque, NULL, 0);
> +}
> +
> +/* Called with replay mutex locked */
> +void replay_save_events(int opt)
> +{
> +qemu_m

Re: [Qemu-devel] [RFC PATCH v8 06/21] replay: introduce icount event

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:52, Pavel Dovgalyuk wrote:
> This patch adds icount event to the replay subsystem. This event corresponds
> to execution of several instructions and used to synchronize input events
> in the replay phase.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  replay/replay-internal.c |   16 
>  replay/replay-internal.h |   20 
>  replay/replay.c  |   46 
> ++
>  replay/replay.h  |7 +++
>  4 files changed, 89 insertions(+), 0 deletions(-)
> 
> diff --git a/replay/replay-internal.c b/replay/replay-internal.c
> index f552dad..49b37a6 100755
> --- a/replay/replay-internal.c
> +++ b/replay/replay-internal.c
> @@ -10,6 +10,7 @@
>   */
>  
>  #include "qemu-common.h"
> +#include "replay.h"
>  #include "replay-internal.h"
>  
>  unsigned int replay_data_kind = -1;
> @@ -164,3 +165,18 @@ void replay_mutex_unlock(void)
>  {
>  qemu_mutex_unlock(&lock);
>  }
> +
> +/*! Saves cached instructions. */
> +void replay_save_instructions(void)
> +{
> +if (replay_file && replay_mode == REPLAY_MODE_RECORD) {
> +int diff = (int)(replay_get_current_step() - 
> replay_state.current_step);
> +if (first_cpu != NULL && diff > 0) {
> +replay_mutex_lock();
> +replay_put_event(EVENT_INSTRUCTION);
> +replay_put_dword(diff);
> +replay_state.current_step += diff;
> +replay_mutex_unlock();
> +}
> +}
> +}
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index 50ce29b..4d661a1 100755
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -14,6 +14,19 @@
>  
>  #include 
>  
> +enum ReplayEvents {
> +/* for instruction event */
> +EVENT_INSTRUCTION
> +};
> +
> +typedef struct ReplayState {
> +/*! Current step - number of processed instructions and timer events. */
> +uint64_t current_step;
> +/*! Number of instructions to be executed before other events happen. */
> +int instructions_count;
> +} ReplayState;
> +extern ReplayState replay_state;
> +
>  extern unsigned int replay_data_kind;
>  extern unsigned int replay_has_unread_data;
>  
> @@ -54,4 +67,11 @@ void replay_save_instructions(void);
>  Terminates the program in case of error. */
>  void validate_data_kind(int kind);
>  
> +/*! Skips async events until some sync event will be found. */
> +bool skip_async_events(int stop_event);
> +/*! Skips async events invocations from the input,
> +until required data kind is found. If the requested data is not found
> +reports an error and stops the execution. */
> +void skip_async_events_until(unsigned int kind);
> +
>  #endif
> diff --git a/replay/replay.c b/replay/replay.c
> index 5ce066f..a43bbbc 100755
> --- a/replay/replay.c
> +++ b/replay/replay.c
> @@ -9,6 +9,52 @@
>   *
>   */
>  
> +#include "qemu-common.h"
>  #include "replay.h"
> +#include "replay-internal.h"
> +#include "qemu/timer.h"
>  
>  ReplayMode replay_mode = REPLAY_MODE_NONE;
> +
> +ReplayState replay_state;
> +
> +bool skip_async_events(int stop_event)
> +{
> +bool res = false;
> +
> +/* nothing to skip - not all instructions used */
> +if (replay_state.instructions_count != 0
> +&& replay_has_unread_data) {
> +return stop_event == EVENT_INSTRUCTION;
> +}
> +
> +while (true) {
> +replay_fetch_data_kind();
> +if (stop_event == replay_data_kind) {
> +res = true;
> +}
> +switch (replay_data_kind) {
> +case EVENT_INSTRUCTION:
> +replay_state.instructions_count = replay_get_dword();
> +return res;
> +default:
> +/* clock, time_t, checkpoint and other events */
> +return res;
> +}
> +}
> +return res;
> +}
> +
> +void skip_async_events_until(unsigned int kind)
> +{
> +if (!skip_async_events(kind)) {
> +fprintf(stderr, "%"PRId64": Read data kind %d instead of expected 
> %d\n",
> +replay_get_current_step(), replay_data_kind, kind);
> +exit(1);
> +}
> +}
> +
> +uint64_t replay_get_current_step(void)
> +{
> +return cpu_get_icount_raw();
> +}
> diff --git a/replay/replay.h b/replay/replay.h
> index d6b73c3..a03c748 100755
> --- a/replay/replay.h
> +++ b/replay/replay.h
> @@ -12,8 +12,15 @@
>   *
>   */
>  
> +#include 
> +#include 
>  #include "qapi-types.h"
>  
>  extern ReplayMode replay_mode;
>  
> +/* Processing the instructions */
> +
> +/*! Returns number of executed instructions. */
> +uint64_t replay_get_current_step(void);
> +
>  #endif
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [RFC PATCH v8 13/21] replay: shutdown event

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:52, Pavel Dovgalyuk wrote:
> This patch records and replays simulator shutdown event.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  replay/replay-internal.h |2 ++
>  replay/replay.c  |   12 
>  replay/replay.h  |5 +
>  vl.c |1 +
>  4 files changed, 20 insertions(+), 0 deletions(-)
> 
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index be71e6f..68b2d45 100755
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -27,6 +27,8 @@ enum ReplayEvents {
>  EVENT_TIME_T,
>  /* for tm event */
>  EVENT_TM,
> +/* for shutdown request */
> +EVENT_SHUTDOWN,
>  /* for clock read/writes */
>  /* some of grteater codes are reserved for clocks */
>  EVENT_CLOCK
> diff --git a/replay/replay.c b/replay/replay.c
> index 307ac4b..cfa69fa 100755
> --- a/replay/replay.c
> +++ b/replay/replay.c
> @@ -13,6 +13,7 @@
>  #include "replay.h"
>  #include "replay-internal.h"
>  #include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
>  
>  ReplayMode replay_mode = REPLAY_MODE_NONE;
>  
> @@ -34,6 +35,10 @@ bool skip_async_events(int stop_event)
>  res = true;
>  }
>  switch (replay_data_kind) {
> +case EVENT_SHUTDOWN:
> +replay_has_unread_data = 0;
> +qemu_system_shutdown_request();
> +break;
>  case EVENT_INSTRUCTION:
>  replay_state.instructions_count = replay_get_dword();
>  return res;
> @@ -151,3 +156,10 @@ bool replay_has_interrupt(void)
>  }
>  return res;
>  }
> +
> +void replay_shutdown_request(void)
> +{
> +if (replay_mode == REPLAY_MODE_RECORD) {
> +replay_put_event(EVENT_SHUTDOWN);
> +}
> +}
> diff --git a/replay/replay.h b/replay/replay.h
> index 2f1402c..e1c5fcf 100755
> --- a/replay/replay.h
> +++ b/replay/replay.h
> @@ -76,6 +76,11 @@ time_t replay_time(void);
>  In replay mode it just read from the log. */
>  void replay_get_timedate(struct tm *tm);
>  
> +/* Events */
> +
> +/*! Called when qemu shutdown is requested. */
> +void replay_shutdown_request(void);
> +
>  /* Asynchronous events queue */
>  
>  /*! Disables storing events in the queue */
> diff --git a/vl.c b/vl.c
> index baff3b5..905ea8a 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1720,6 +1720,7 @@ void qemu_system_killed(int signal, pid_t pid)
>  void qemu_system_shutdown_request(void)
>  {
>  trace_qemu_system_shutdown_request();
> +replay_shutdown_request();
>  shutdown_requested = 1;
>  qemu_notify_event();
>  }
> 
> 
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [RFC PATCH v8 12/21] replay: recording and replaying different timers

2015-01-29 Thread Paolo Bonzini


On 22/01/2015 09:52, Pavel Dovgalyuk wrote:
> This patch introduces functions for recording and replaying realtime sources,
> that do not use qemu-clock interface. These include return value of time()
> function in time_t and struct tm forms. Patch also adds warning to
> get_timedate function to prevent its usage in recording mode, because it may
> lead to non-determinism.
> 
> Signed-off-by: Pavel Dovgalyuk 
> ---
>  hw/timer/mc146818rtc.c   |3 +
>  hw/timer/pl031.c |3 +
>  include/qemu-common.h|1 
>  replay/replay-internal.h |4 +
>  replay/replay-time.c |  132 
> ++
>  replay/replay.h  |8 +++
>  vl.c |   17 +-
>  7 files changed, 163 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
> index f18d128..92295fb 100644
> --- a/hw/timer/mc146818rtc.c
> +++ b/hw/timer/mc146818rtc.c
> @@ -28,6 +28,7 @@
>  #include "qapi/visitor.h"
>  #include "qapi-event.h"
>  #include "qmp-commands.h"
> +#include "replay/replay.h"
>  
>  #ifdef TARGET_I386
>  #include "hw/i386/apic.h"
> @@ -703,7 +704,7 @@ static void rtc_set_date_from_host(ISADevice *dev)
>  RTCState *s = MC146818_RTC(dev);
>  struct tm tm;
>  
> -qemu_get_timedate(&tm, 0);

What about just making qemu_get_timedate use
qemu_clock_get_ns(QEMU_CLOCK_HOST) instead of time()?  This would just
work using the infrastructure of the previous patch.

Paolo

> +replay_get_timedate(&tm);
>  
>  s->base_rtc = mktimegm(&tm);
>  s->last_update = qemu_clock_get_ns(rtc_clock);
> diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
> index 34d9b44..b02d288 100644
> --- a/hw/timer/pl031.c
> +++ b/hw/timer/pl031.c
> @@ -14,6 +14,7 @@
>  #include "hw/sysbus.h"
>  #include "qemu/timer.h"
>  #include "sysemu/sysemu.h"
> +#include "replay/replay.h"
>  
>  //#define DEBUG_PL031
>  
> @@ -200,7 +201,7 @@ static int pl031_init(SysBusDevice *dev)
>  sysbus_init_mmio(dev, &s->iomem);
>  
>  sysbus_init_irq(dev, &s->irq);
> -qemu_get_timedate(&tm, 0);
> +replay_get_timedate(&tm);
>  s->tick_offset = mktimegm(&tm) -
>  qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
>  
> diff --git a/include/qemu-common.h b/include/qemu-common.h
> index 644b46d..8c9957e 100644
> --- a/include/qemu-common.h
> +++ b/include/qemu-common.h
> @@ -129,6 +129,7 @@ void dump_drift_info(FILE *f, fprintf_function 
> cpu_fprintf);
>  int qemu_main(int argc, char **argv, char **envp);
>  #endif
>  
> +void qemu_get_timedate_no_warning(struct tm *tm, int offset);
>  void qemu_get_timedate(struct tm *tm, int offset);
>  int qemu_timedate_diff(struct tm *tm);
>  
> diff --git a/replay/replay-internal.h b/replay/replay-internal.h
> index e906ec3..be71e6f 100755
> --- a/replay/replay-internal.h
> +++ b/replay/replay-internal.h
> @@ -23,6 +23,10 @@ enum ReplayEvents {
>  EVENT_EXCEPTION,
>  /* for async events */
>  EVENT_ASYNC,
> +/* for time_t event */
> +EVENT_TIME_T,
> +/* for tm event */
> +EVENT_TM,
>  /* for clock read/writes */
>  /* some of grteater codes are reserved for clocks */
>  EVENT_CLOCK
> diff --git a/replay/replay-time.c b/replay/replay-time.c
> index 5f5bc6a..282d00e 100755
> --- a/replay/replay-time.c
> +++ b/replay/replay-time.c
> @@ -82,3 +82,135 @@ int64_t replay_read_clock(ReplayClockKind kind)
>  fprintf(stderr, "REPLAY INTERNAL ERROR %d\n", __LINE__);
>  exit(1);
>  }
> +
> +/*! Saves time_t value to the log */
> +static void replay_save_time_t(time_t tm)
> +{
> +replay_save_instructions();
> +
> +if (replay_file) {
> +replay_mutex_lock();
> +replay_put_event(EVENT_TIME_T);
> +if (sizeof(tm) == 4) {
> +replay_put_dword(tm);
> +} else if (sizeof(tm) == 8) {
> +replay_put_qword(tm);
> +} else {
> +fprintf(stderr, "invalid time_t sizeof: %u\n",
> +(unsigned)sizeof(tm));
> +exit(1);
> +}
> +replay_mutex_unlock();
> +}
> +}
> +
> +/*! Reads time_t value from the log. Stops execution in case of error */
> +static time_t replay_read_time_t(void)
> +{
> +replay_exec_instructions();
> +
> +if (replay_file) {
> +time_t tm;
> +
> +replay_mutex_lock();
> +skip_async_events_until(EVENT_TIME_T);
> +
> +if (sizeof(tm) == 4) {
> +tm = replay_get_dword();
> +} else if (sizeof(tm) == 8) {
> +tm = replay_get_qword();
> +} else {
> +fprintf(stderr, "invalid time_t sizeof: %u\n",
> +(unsigned)sizeof(tm));
> +exit(1);
> +}
> +
> +replay_check_error();
> +
> +replay_has_unread_data = 0;
> +replay_mutex_unlock();
> +
> +return tm;
> +}
> +
> +fprintf(stderr, "REPLAY INTERNAL ERROR %d\n", __LINE__);
> +exit(1);
> +}
> +
> +static void replay_save_tm(struct tm

Re: [Qemu-devel] [RFC PATCH v8 00/21] Deterministic replay core

2015-01-29 Thread Paolo Bonzini


On 28/01/2015 12:45, Pavel Dovgaluk wrote:
> Ping?

Reviewed 13 patches out of 21.  Made some comments, but overall I'm
really pleased.  Thanks for persisting!

Will continue tomorrow.

Paolo

> Pavel Dovgalyuk
> 
>> -Original Message-
>> From: Pavel Dovgalyuk [mailto:pavel.dovga...@ispras.ru]
>> Sent: Thursday, January 22, 2015 11:52 AM
>> To: qemu-devel@nongnu.org
>> Cc: peter.mayd...@linaro.org; peter.crosthwa...@xilinx.com; 
>> ebl...@redhat.com;
>> mark.bur...@greensocs.com; r...@ispras.ru; batuz...@ispras.ru; 
>> maria.klimushenk...@ispras.ru;
>> pavel.dovga...@ispras.ru; pbonz...@redhat.com; alex.ben...@linaro.org; 
>> afaer...@suse.de;
>> fred.kon...@greensocs.com
>> Subject: [RFC PATCH v8 00/21] Deterministic replay core
>>
>> This set of patches is related to the reverse execution and deterministic
>> replay of qemu execution  This implementation of deterministic replay can
>> be used for deterministic debugging of guest code through gdb remote
>> interface.
>>
>> These patches include only core function of the replay,
>> excluding the support for replaying serial, audio, network, and USB devices'
>> operations. Reverse debugging and monitor commands were also excluded to
>> be submitted later as separate patches.
>>
>> Execution recording writes non-deterministic events log, which can be later
>> used for replaying the execution anywhere and for unlimited number of times.
>> It also supports checkpointing for faster rewinding during reverse debugging.
>> Execution replaying reads the log and replays all non-deterministic events
>> including external input, hardware clocks, and interrupts.
>>
>> Deterministic replay has the following features:
>>  * Deterministically replays whole system execution and all contents of the 
>> memory,
>>state of the hadrware devices, clocks, and screen of the VM.
>>  * Writes execution log into the file for latter replaying for multiple times
>>on different machines.
>>  * Supports i386, x86_64, and ARM hardware platforms.
>>  * Performs deterministic replay of all operations with keyboard and mouse
>>input devices.
>>  * Supports auto-checkpointing for convenient reverse debugging.
>>
>> Usage of the record/replay:
>>  * First, record the execution, by adding the following string to the 
>> command line:
>>'-record fname=replay.bin -icount 7 -net none'. Block devices' images are 
>> not
>>actually changed in the recording mode, because all of the changes are
>>written to the temporary overlay file.
>>  * Then you can replay it for the multiple times by using another command
>>line option: '-replay fname=replay.bin -icount 7 -net none'
>>  * '-net none' option should also be specified if network replay patches
>>are not applied.
>>
>> Paper with short description of deterministic replay implementation:
>> http://www.computer.org/csdl/proceedings/csmr/2012/4666/00/4666a553-abs.html
>>
>> Modifications of qemu include:
>>  * wrappers for clock and time functions to save their return values in the 
>> log
>>  * saving different asynchronous events (e.g. system shutdown) into the log
>>  * synchronization of the bottom halves execution
>>  * synchronization of the threads from thread pool
>>  * recording/replaying user input (mouse and keyboard)
>>  * adding internal events for cpu and io synchronization
>>
>> v8 changes:
>>  * Simplified processing of the shutdown event (as suggested by Paolo 
>> Bonzini)
>>  * Replaced stack of bottom halves in AIO context with QSIMPLEQ (as 
>> suggested by Paolo
>> Bonzini)
>>  * Moved replay_submode out of the series (as suggested by Paolo Bonzini)
>>  * Moved suffix option out of the series
>>  * Converted some of the defines into enums (as suggested by Paolo Bonzini)
>>  * Encapsulated save_tm/read_tm calls into the single function (as suggested 
>> by Paolo Bonzini)
>>  * Moved record/replay options to icount group (as suggested by Paolo 
>> Bonzini)
>>  * Updated mutex protection for the events queue (as suggested by Paolo 
>> Bonzini)
>>  * Added mutex to protect replay log file (as suggested by Paolo Bonzini)
>>  * Minor cleanups
>>
>> v7 changes:
>>  * Removed patches that were applied to upstream.
>>
>> v6 changes:
>>  * Fixed replay stub return value (as suggested by Eric Blake)
>>  * Fixed icount warping.
>>  * Virtual rt clock now uses cpu_get_clock() (as suggested by Paolo Bonzini)
>>  * Replated get_clock_realtime and get_clock calls with qemu clock requests 
>> (as suggested by
>> Paolo Bonzini)
>>  * Modified can_do_io logic to allow requesting icount from cpu_exec 
>> function (as suggested by
>> Paolo Bonzini)
>>  * Removed applied patches.
>>
>> v5 changes:
>>  * Minor changes.
>>  * Used fixed-width integer types for read/write functions (as suggested by 
>> Alex Bennee)
>>  * Moved savevm-related code out of the core.
>>  * Added new traced clock for deterministic virtual clock warping (as 
>> suggested by Paolo
>> Bonzini)
>>  * Fixed exception_index reset for user mode

[Qemu-devel] [PATCH v2 0/1] block: enforce minimal 4096 alignment in qemu_blockalign

2015-01-29 Thread Denis V. Lunev
The following sequence
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
for (i = 0; i < 10; i++)
write(fd, buf, 4096);
performs 5% better if buf is aligned to 4096 bytes rather then to
512 bytes on HDD with 512/4096 logical/physical sector size.

The difference is quite reliable.

I have used the following program to test
#define _GNU_SOURCE

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
void *buf;
int i = 0;

do {
buf = memalign(512, 4096); <--- replace 512 with 4096
if ((unsigned long)buf & 4095)
break;
i++;
} while (1);
printf("%d\n", i);

memset(buf, 0x11, 4096);

for (i = 0; i < 10; i++)
write(fd, buf, 4096);

close(fd);
return 0;
}
time for in in `seq 1 30` ; do a.out aa ; done

The file was placed into 8 GB partition on HDD below to avoid speed
change due to different offset on disk. Results are reliable:
- 189 vs 180 seconds on Linux 3.16

Changes from v1:
- enforces 4096 alignment in qemu_(try_)blockalign, avoid touching of
  bdrv_qiov_is_aligned path not to enforce additional bounce buffering
  as suggested by Paolo
- reduces 10% to 5% in patch description to better fit 180 vs 189
  difference

Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Kevin Wolf 
CC: Stefan Hajnoczi 

hades ~/src/qemu # hdparm -I /dev/sdg

/dev/sdg:

ATA device, with non-removable media
Model Number:   WDC WD20EZRX-07D8PB0
Serial Number:  WD-WCC4M5LVSAEP
Firmware Revision:  80.00A80
Transport:  Serial, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, 
SATA Rev 2.6, SATA Rev 3.0
Standards:
Supported: 9 8 7 6 5
Likely used: 9
Configuration:
Logical max current
cylinders   16383   16383
heads   16  16
sectors/track   63  63
--
CHS current addressable sectors:   16514064
LBAuser addressable sectors:  268435455
LBA48  user addressable sectors: 3907029168
Logical  Sector size:   512 bytes
Physical Sector size:  4096 bytes
device size with M = 1024*1024: 1907729 MBytes
device size with M = 1000*1000: 2000398 MBytes (2000 GB)
cache/buffer size  = unknown
Nominal Media Rotation Rate: 5400
Capabilities:
LBA, IORDY(can be disabled)
Queue depth: 32
Standby timer values: spec'd by Standard, with device specific minimum
R/W multiple sector transfer: Max = 16  Current = 16
DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6
 Cycle time: min=120ns recommended=120ns
PIO: pio0 pio1 pio2 pio3 pio4
 Cycle time: no flow control=120ns  IORDY flow control=120ns
Commands/features:
Enabled Supported:
   *SMART feature set
Security Mode feature set
   *Power Management feature set
   *Write cache
   *Look-ahead
   *Host Protected Area feature set
   *WRITE_BUFFER command
   *READ_BUFFER command
   *NOP cmd
   *DOWNLOAD_MICROCODE
Power-Up In Standby feature set
   *SET_FEATURES required to spinup after power up
SET_MAX security extension
   *48-bit Address feature set
   *Device Configuration Overlay feature set
   *Mandatory FLUSH_CACHE
   *FLUSH_CACHE_EXT
   *SMART error logging
   *SMART self-test
   *General Purpose Logging feature set
   *64-bit World wide name
   *WRITE_UNCORRECTABLE_EXT command
   *{READ,WRITE}_DMA_EXT_GPL commands
   *Segmented DOWNLOAD_MICROCODE
   *Gen1 signaling speed (1.5Gb/s)
   *Gen2 signaling speed (3.0Gb/s)
   *Gen3 signaling speed (6.0Gb/s)
   *Native Command Queueing (NCQ)
   *Host-initiated interface power management
   *Phy event counters
   *NCQ priority information
   *READ_LOG_DMA_EXT equivalent to READ_LOG_EXT
   *DMA Setup Auto-Activate optimization
Device-initiated interface power management
   *Software settings preservation
   *SMART Command Transport (SCT) feature set
   *SCT Write Same (AC2)
   *SCT Features Control (AC4)
   *SCT Data Tables (AC5)
unknown 206[12] (vendor specific)
unknown 206[13] (vendor specific)
unknown 206[14] (vendor specific)
Security:
Master password revision code = 65534
supported
not enabled
not locked
frozen
not expired: security count
supported: enhanced erase
276min for SECURITY ERASE UNIT. 276min for ENHANCED SECURITY ERASE UNIT.
Logical Unit WWN Device Identifier: 50014ee2b5da838c
NAA : 5
IEEE OUI: 0014ee
Unique ID   : 2b5da838c
Checksum: correct
hades ~/src/qemu #



[Qemu-devel] [PATCH 1/1] block: enforce minimal 4096 alignment in qemu_blockalign

2015-01-29 Thread Denis V. Lunev
The following sequence
int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
for (i = 0; i < 10; i++)
write(fd, buf, 4096);
performs 5% better if buf is aligned to 4096 bytes rather then to
512 bytes on HDD with 512/4096 logical/physical sector size.

The difference is quite reliable.

On the other hand we do not want at the moment to enforce bounce
buffering if guest request is aligned to 512 bytes. This patch
forces page alignment when we really forced to perform memory
allocation.

Signed-off-by: Denis V. Lunev 
CC: Paolo Bonzini 
CC: Kevin Wolf 
CC: Stefan Hajnoczi 
---
 block.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index d45e4dd..38cf73f 100644
--- a/block.c
+++ b/block.c
@@ -5293,7 +5293,11 @@ void bdrv_set_guest_block_size(BlockDriverState *bs, int 
align)
 
 void *qemu_blockalign(BlockDriverState *bs, size_t size)
 {
-return qemu_memalign(bdrv_opt_mem_align(bs), size);
+size_t align = bdrv_opt_mem_align(bs);
+if (align < 4096) {
+align = 4096;
+}
+return qemu_memalign(align, size);
 }
 
 void *qemu_blockalign0(BlockDriverState *bs, size_t size)
@@ -5307,6 +5311,9 @@ void *qemu_try_blockalign(BlockDriverState *bs, size_t 
size)
 
 /* Ensure that NULL is never returned on success */
 assert(align > 0);
+if (align < 4096) {
+align = 4096;
+}
 if (size == 0) {
 size = align;
 }
-- 
1.9.1




Re: [Qemu-devel] [RFC][PATCH 1/1] libxl: add one machine property to support IGD GFX passthrough

2015-01-29 Thread Wei Liu
On Thu, Jan 29, 2015 at 08:41:24AM +0800, Chen, Tiejun wrote:
> On 2015/1/28 19:12, Wei Liu wrote:
> >On Wed, Jan 28, 2015 at 08:42:56AM +0800, Chen, Tiejun wrote:
> >>On 2015/1/27 22:40, Ian Jackson wrote:
> >>>Chen, Tiejun writes ("Re: [Qemu-devel] [RFC][PATCH 1/1] libxl: add one 
> >>>machine property to support IGD GFX passthrough"):
> On 2015/1/23 8:43, Chen, Tiejun wrote:
> >On 2015/1/22 8:51, Chen, Tiejun wrote:
> >>At this point I just concern here if we still use 'gfx_passthrou', at
> >>least it may look like a backward compatibility with older versions of
> >>qemu in Xen side, qemu-xen-traditional. But I'd like to follow your
> >>final option.
> >>>...
> >Any feedback to this option I should follow here?
> 
> Ping...
> >>>
> >>>I think this is a question that qemu upstream should answer.
> >>>
> >>
> >>Actually this is just commented by Gerd in qemu upstream. So now looks in
> >>Xen side you guys don't have any objection to use 'igd-passthru' as well. If
> >>yes, I'm fine to adopt this.
> >>
> >
> >Yes, we would like to stay in line with upstream.
> 
> Wei,
> 
> Thanks for your response.
> 
> >
> >Just remember to handle old option in libxl if your old option is already
> >released by some older version of QEMUs.
> 
> I just drop that old option, -gfx_passthru, if we're under qemu upstream
> circumstance, like this,
> 

The question is, is there any version of qemu upstream that has
been released that has the old option (-gfx-passthru)?

This gives us a situation that we need to support both the old
(-gfx-passthru) and new (-igd-passthru) options. Presumably we (libxl)
would need to fork a qemu process to determine which option it has and
pass the right one.

Or you can try to keep both old and new option at the same time but
deprecate the old one. Then in a few qemu release cycles later (or
probably one year or two?) you can finally remove the old one. The point
is that to give downstream (in this case, Xen) time to cope with the
change.

> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -318,7 +318,10 @@ static char **
> libxl__build_device_model_args_old(libxl__gc *gc,
>  flexarray_vappend(dm_args, "-net", "none", NULL);
>  }
>  if (libxl_defbool_val(b_info->u.hvm.gfx_passthru)) {
> -flexarray_append(dm_args, "-gfx_passthru");
> +if (b_info->device_model_version !=
> +LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
> +flexarray_append(dm_args, "-gfx_passthru");
> +}

I don't think this is right if upstream qemu also supports gfx-passthru.

However, you're modifying libxl__build_device_model_args_old, it
strongly suggests that it only affects qemu-trad. That means you don't
even need this patch...

Wei.

>  }
>  } else {
>  if (!sdl && !vnc)
> @@ -702,7 +705,10 @@ static char **
> libxl__build_device_model_args_new(libxl__gc *gc,
>  flexarray_append(dm_args, "none");
>  }
>  if (libxl_defbool_val(b_info->u.hvm.gfx_passthru)) {
> -flexarray_append(dm_args, "-gfx_passthru");
> +if (b_info->device_model_version !=
> +LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN) {
> +flexarray_append(dm_args, "-gfx_passthru");
> +}
>  }
>  } else {
>  if (!sdl && !vnc) {
> 
> Is this good enough?
> 
> Thanks
> Tiejun



Re: [Qemu-devel] [PATCH v1] vhost-user: fix not send all hugepage files to vhost-user

2015-01-29 Thread Michael S. Tsirkin
On Thu, Jan 29, 2015 at 11:58:08AM +0800, Linhaifeng wrote:
> Hi,Michael S.Tsirkin
> 
> The vhost-user device will not work if there are two numa nodes in VM.
> 
> Should we fix this bug or ignore it ?

I suggest we fix this bug.
I saw that you responded to self so I assume you will
send v2 with the modification you listed.
Did I get it right?

Also, pls Cc qemu-stable on bugfixes.

Thanks!

> On 2014/12/18 13:06, Linhaifeng wrote:
> > 
> > 
> > On 2014/12/17 14:02, haifeng@huawei.com wrote:
> >> From: linhaifeng 
> >>
> >> If we create VM with two or more numa nodes qemu will create two
> >> or more hugepage files but qemu only send one hugepage file fd
> >> to vhost-user when VM's memory size is 2G and with two numa nodes.
> >>
> >> Signed-off-by: linhaifeng 
> >> ---
> >>  hw/virtio/vhost-user.c  | 78 
> >> ++---
> >>  hw/virtio/vhost.c   | 13 
> >>  linux-headers/linux/vhost.h |  7 
> >>  3 files changed, 73 insertions(+), 25 deletions(-)
> >>
> >> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> >> index aefe0bb..439cbba 100644
> >> --- a/hw/virtio/vhost-user.c
> >> +++ b/hw/virtio/vhost-user.c
> >> @@ -24,6 +24,10 @@
> >>  #include 
> >>  
> >>  #define VHOST_MEMORY_MAX_NREGIONS8
> >> +/* FIXME: same as the max number of numa node?*/
> >> +#define HUGEPAGE_MAX_FILES   8
> >> +
> >> +#define RAM_SHARED (1 << 1)
> >>  
> >>  typedef enum VhostUserRequest {
> >>  VHOST_USER_NONE = 0,
> >> @@ -41,14 +45,15 @@ typedef enum VhostUserRequest {
> >>  VHOST_USER_SET_VRING_KICK = 12,
> >>  VHOST_USER_SET_VRING_CALL = 13,
> >>  VHOST_USER_SET_VRING_ERR = 14,
> >> -VHOST_USER_MAX
> >> +VHOST_USER_MMAP_HUGEPAGE_FILE = 15,
> >> +VHOST_USER_UNMAP_HUGEPAGE_FILE = 16,
> >> +VHOST_USER_MAX,
> >>  } VhostUserRequest;
> >>  
> >>  typedef struct VhostUserMemoryRegion {
> >>  uint64_t guest_phys_addr;
> >>  uint64_t memory_size;
> >>  uint64_t userspace_addr;
> >> -uint64_t mmap_offset;
> >>  } VhostUserMemoryRegion;
> >>  
> >>  typedef struct VhostUserMemory {
> >> @@ -57,6 +62,16 @@ typedef struct VhostUserMemory {
> >>  VhostUserMemoryRegion regions[VHOST_MEMORY_MAX_NREGIONS];
> >>  } VhostUserMemory;
> >>  
> >> +typedef struct HugepageMemoryInfo {
> >> +uint64_t base_addr;
> >> +uint64_t size;
> >> +}HugeMemInfo;
> >> +
> >> +typedef struct HugepageInfo {
> >> +uint32_t num;
> >> +HugeMemInfo files[HUGEPAGE_MAX_FILES];
> >> +}HugepageInfo;
> >> +
> >>  typedef struct VhostUserMsg {
> >>  VhostUserRequest request;
> >>  
> >> @@ -71,6 +86,7 @@ typedef struct VhostUserMsg {
> >>  struct vhost_vring_state state;
> >>  struct vhost_vring_addr addr;
> >>  VhostUserMemory memory;
> >> +HugepageInfo huge_info;
> >>  };
> >>  } QEMU_PACKED VhostUserMsg;
> >>  
> >> @@ -104,7 +120,9 @@ static unsigned long int 
> >> ioctl_to_vhost_user_request[VHOST_USER_MAX] = {
> >>  VHOST_GET_VRING_BASE,   /* VHOST_USER_GET_VRING_BASE */
> >>  VHOST_SET_VRING_KICK,   /* VHOST_USER_SET_VRING_KICK */
> >>  VHOST_SET_VRING_CALL,   /* VHOST_USER_SET_VRING_CALL */
> >> -VHOST_SET_VRING_ERR /* VHOST_USER_SET_VRING_ERR */
> >> +VHOST_SET_VRING_ERR,/* VHOST_USER_SET_VRING_ERR */
> >> +VHOST_MMAP_HUGEPAGE_FILE,  /* VHOST_USER_MMAP_HUGEPAGE_FILE */
> >> +VHOST_UNMAP_HUGEPAGE_FILE, /* VHOST_USER_UNMAP_HUGEPAGE_FILE */
> >>  };
> >>  
> >>  static VhostUserRequest vhost_user_request_translate(unsigned long int 
> >> request)
> >> @@ -190,6 +208,7 @@ static int vhost_user_call(struct vhost_dev *dev, 
> >> unsigned long int request,
> >>  int fds[VHOST_MEMORY_MAX_NREGIONS];
> >>  int i, fd;
> >>  size_t fd_num = 0;
> >> +RAMBlock *block;
> >>  
> >>  assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
> >>  
> >> @@ -213,37 +232,46 @@ static int vhost_user_call(struct vhost_dev *dev, 
> >> unsigned long int request,
> >>  case VHOST_RESET_OWNER:
> >>  break;
> >>  
> >> -case VHOST_SET_MEM_TABLE:
> >> -for (i = 0; i < dev->mem->nregions; ++i) {
> >> -struct vhost_memory_region *reg = dev->mem->regions + i;
> >> -ram_addr_t ram_addr;
> >> +case VHOST_MMAP_HUGEPAGE_FILE:
> >> +qemu_mutex_lock_ramlist();
> >>  
> >> -assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
> >> -qemu_ram_addr_from_host((void 
> >> *)(uintptr_t)reg->userspace_addr, &ram_addr);
> >> -fd = qemu_get_ram_fd(ram_addr);
> >> -if (fd > 0) {
> >> -msg.memory.regions[fd_num].userspace_addr = 
> >> reg->userspace_addr;
> >> -msg.memory.regions[fd_num].memory_size  = 
> >> reg->memory_size;
> >> -msg.memory.regions[fd_num].guest_phys_addr = 
> >> reg->guest_phys_addr;
> >> -msg.memory.regions[fd_num].mmap_offset = 
> >> reg->userspace_add

Re: [Qemu-devel] [PATCH 2/2] bootdevice: update boot_order in MachineState

2015-01-29 Thread Alexander Graf


On 29.01.15 08:48, Markus Armbruster wrote:
> Dinar Valeev  writes:
> 
>> On 01/28/2015 02:48 AM, Gonglei wrote:
>>> On 2015/1/27 18:49, Dinar Valeev wrote:
>>>
 On 01/27/2015 10:18 AM, Gonglei wrote:
> On 2015/1/27 16:57, Dinar Valeev wrote:
>
>> On 01/27/2015 03:51 AM, Gonglei wrote:
>>> On 2015/1/27 7:52, dval...@suse.de wrote:
>>>
 From: Dinar Valeev 

 on sPAPR we need to update boot_order in MachineState in case it
 got changed on reset.

 Signed-off-by: Dinar Valeev 
 ---
  bootdevice.c | 3 +++
  1 file changed, 3 insertions(+)

 diff --git a/bootdevice.c b/bootdevice.c
 index 5914417..4f11a06 100644
 --- a/bootdevice.c
 +++ b/bootdevice.c
 @@ -26,6 +26,7 @@
  #include "qapi/visitor.h"
  #include "qemu/error-report.h"
  #include "hw/hw.h"
 +#include "hw/boards.h"
  
  typedef struct FWBootEntry FWBootEntry;
  
 @@ -50,6 +51,8 @@ void qemu_register_boot_set(QEMUBootSetHandler 
 *func, void *opaque)
  void qemu_boot_set(const char *boot_order, Error **errp)
  {
  Error *local_err = NULL;
 +MachineState *machine = MACHINE(qdev_get_machine());
 +machine->boot_order = boot_order;
  
  if (!boot_set_handler) {
  error_setg(errp, "no function defined to set boot device list 
 for"
>>>
>>> Have you registered boot set handler on ppc/sPAPR platform by calling
>>> qemu_register_boot_set()? Otherwise qemu_boot_set function
>>>  will return error.
>> No, I set boot_order on each machine reset. My tests are showing
>> it works without an error.
>
> That's interesting. Does this function be called?
 Yes, then simply returns.
> Would you debug it by setting a breakpoint ?
 I added a trace event.
  if (!boot_set_handler) {
 +trace_qemu_boot_set(boot_order);
  error_setg(errp, "no function defined to set boot device list for"
   " this architecture");
  return;

 And I see this now in qemu's monitor. Still I don't see error message.
>>>
>>> That's because NULL is passed to this function in restore_boot_order()
>>> the error is ignored (commit f183993). I have seen the previous conversation
>>> about your patch serials. And I think this is the reason which
>>> you moved machine->boot_order = boot_order before
>>> checking boot_set_handler variable based on Alexander's
>>> suggestion, right? But I think this is not a good idea.
>> Yes
>>
>> Any proposal how this can be done differently?
>>
>> It seems I'm almost alone who wants -boot once=X option to get fixed
>> for sPAPR. We use it in test automation, and we need to be sure that
>> we boot from hard disk once installation is done.
> 
> The crash is a bug, and bugs need fixing.
> 
> You first patch looked okay to me.  

I'd rather not modify the "base fdt" ;). Today we have a pretty simple
layout that does

base fdt -> init
runtime changes -> reset

I'd prefer to keep it that way, so over the lifetime of a VM, the base
fdt shouldn't change.

> I suggested dropping the null check
> in spapr_create_fdt_skel(), because I feel it's papering over the bug
> you fix.
> 
> This isn't a review of your second attempt, it's encouragement.  I
> haven't looked at this version, nor have I thought through Alex's idea
> to patch machine->boot_order in qemu_boot_set().

If people are against it (though I can't see why), we can also move the
logic to spapr.c and change the machine->boot_order in a local callback
to set_boot_handler().


Alex



Re: [Qemu-devel] [PATCH 2/2] bootdevice: update boot_order in MachineState

2015-01-29 Thread Alexander Graf


On 28.01.15 02:48, Gonglei wrote:
> On 2015/1/27 18:49, Dinar Valeev wrote:
> 
>> On 01/27/2015 10:18 AM, Gonglei wrote:
>>> On 2015/1/27 16:57, Dinar Valeev wrote:
>>>
 On 01/27/2015 03:51 AM, Gonglei wrote:
> On 2015/1/27 7:52, dval...@suse.de wrote:
>
>> From: Dinar Valeev 
>>
>> on sPAPR we need to update boot_order in MachineState in case it
>> got changed on reset.
>>
>> Signed-off-by: Dinar Valeev 
>> ---
>>  bootdevice.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/bootdevice.c b/bootdevice.c
>> index 5914417..4f11a06 100644
>> --- a/bootdevice.c
>> +++ b/bootdevice.c
>> @@ -26,6 +26,7 @@
>>  #include "qapi/visitor.h"
>>  #include "qemu/error-report.h"
>>  #include "hw/hw.h"
>> +#include "hw/boards.h"
>>  
>>  typedef struct FWBootEntry FWBootEntry;
>>  
>> @@ -50,6 +51,8 @@ void qemu_register_boot_set(QEMUBootSetHandler *func, 
>> void *opaque)
>>  void qemu_boot_set(const char *boot_order, Error **errp)
>>  {
>>  Error *local_err = NULL;
>> +MachineState *machine = MACHINE(qdev_get_machine());
>> +machine->boot_order = boot_order;
>>  
>>  if (!boot_set_handler) {
>>  error_setg(errp, "no function defined to set boot device list 
>> for"
>
> Have you registered boot set handler on ppc/sPAPR platform by calling
> qemu_register_boot_set()? Otherwise qemu_boot_set function
>  will return error.
 No, I set boot_order on each machine reset. My tests are showing it works 
 without an error.
>>>
>>> That's interesting. Does this function be called?
>> Yes, then simply returns.
>>> Would you debug it by setting a breakpoint ?
>> I added a trace event.
>>  if (!boot_set_handler) {
>> +trace_qemu_boot_set(boot_order);
>>  error_setg(errp, "no function defined to set boot device list for"
>>   " this architecture");
>>  return;
>>
>> And I see this now in qemu's monitor. Still I don't see error message.
> 
> That's because NULL is passed to this function in restore_boot_order()
> the error is ignored (commit f183993). I have seen the previous conversation
> about your patch serials. And I think this is the reason which
> you moved machine->boot_order = boot_order before
> checking boot_set_handler variable based on Alexander's
> suggestion, right? But I think this is not a good idea.

Why is it not a good idea? The check is only checking whether there are
callbacks. The boot order changes nevertheless.


Alex



Re: [Qemu-devel] [PATCH RFC v6 05/20] virtio: support more feature bits

2015-01-29 Thread Michael S. Tsirkin
On Thu, Jan 29, 2015 at 09:01:45PM +1100, David Gibson wrote:
> On Thu, Jan 29, 2015 at 10:24:00AM +0100, Thomas Huth wrote:
> > 
> >  Hi,
> > 
> > On Thu, 29 Jan 2015 11:11:32 +1100
> > David Gibson  wrote:
> > 
> > > On Wed, Jan 28, 2015 at 04:59:45PM +0100, Cornelia Huck wrote:
> > > > On Thu, 22 Jan 2015 12:43:43 +1100
> > > > David Gibson  wrote:
> > > > 
> > > > > On Thu, Dec 11, 2014 at 02:25:07PM +0100, Cornelia Huck wrote:
> > > > > > With virtio-1, we support more than 32 feature bits. Let's extend 
> > > > > > both
> > > > > > host and guest features to 64, which should suffice for a while.
> > > > > > 
> > > > > > vhost and migration have been ignored for now.
> > > > > 
> > > > > [snip]
> > > > > 
> > > > > > diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> > > > > > index f6c0379..08141c7 100644
> > > > > > --- a/include/hw/virtio/virtio.h
> > > > > > +++ b/include/hw/virtio/virtio.h
> > > > > > @@ -55,6 +55,12 @@
> > > > > >  /* A guest should never accept this.  It implies negotiation is 
> > > > > > broken. */
> > > > > >  #define VIRTIO_F_BAD_FEATURE   30
> > > > > >  
> > > > > > +/* v1.0 compliant. */
> > > > > > +#define VIRTIO_F_VERSION_1  32
> > > > > 
> > > > > This is already in the kernel header, isn't it?
> > > 
> > > > 
> > > > Yes. But nearly all files include this header but not the kernel
> > > > header.
> > > 
> > > Can't you change that?  Or this file include the kernel header?
> >  
> > AFAIK non-KVM code should never try to include one of the Linux headers
> > to avoid breaking on non-Linux platforms (for example  is
> > not available on OS X, see http://patchwork.ozlabs.org/patch/424655/ ).
> > So it's a little bit ugly to define these things twice, but it seems
> > the only way to stay portable.
> 
> Ah, yeah, good point.

I do intend to write a script to import more headers from linux,
changing them on the fly to drop dependency on linux/types.h
etc.

If someone wants to beat me to it, so much the better.

> -- 
> David Gibson  | I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au| minimalist, thank you.  NOT _the_ 
> _other_
>   | _way_ _around_!
> http://www.ozlabs.org/~dgibson





Re: [Qemu-devel] [PATCH 1/1] block: enforce minimal 4096 alignment in qemu_blockalign

2015-01-29 Thread Paolo Bonzini


On 29/01/2015 11:50, Denis V. Lunev wrote:
> The following sequence
> int fd = open(argv[1], O_RDWR | O_CREAT | O_DIRECT, 0644);
> for (i = 0; i < 10; i++)
> write(fd, buf, 4096);
> performs 5% better if buf is aligned to 4096 bytes rather then to
> 512 bytes on HDD with 512/4096 logical/physical sector size.
> 
> The difference is quite reliable.
> 
> On the other hand we do not want at the moment to enforce bounce
> buffering if guest request is aligned to 512 bytes. This patch
> forces page alignment when we really forced to perform memory
> allocation.
> 
> Signed-off-by: Denis V. Lunev 
> CC: Paolo Bonzini 
> CC: Kevin Wolf 
> CC: Stefan Hajnoczi 
> ---
>  block.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/block.c b/block.c
> index d45e4dd..38cf73f 100644
> --- a/block.c
> +++ b/block.c
> @@ -5293,7 +5293,11 @@ void bdrv_set_guest_block_size(BlockDriverState *bs, 
> int align)
>  
>  void *qemu_blockalign(BlockDriverState *bs, size_t size)
>  {
> -return qemu_memalign(bdrv_opt_mem_align(bs), size);
> +size_t align = bdrv_opt_mem_align(bs);
> +if (align < 4096) {
> +align = 4096;
> +}
> +return qemu_memalign(align, size);
>  }
>  
>  void *qemu_blockalign0(BlockDriverState *bs, size_t size)
> @@ -5307,6 +5311,9 @@ void *qemu_try_blockalign(BlockDriverState *bs, size_t 
> size)
>  
>  /* Ensure that NULL is never returned on success */
>  assert(align > 0);
> +if (align < 4096) {
> +align = 4096;
> +}
>  if (size == 0) {
>  size = align;
>  }
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [PATCH 04/21] block: Add bdrv_close_all() handlers

2015-01-29 Thread Paolo Bonzini


On 28/01/2015 23:56, Max Reitz wrote:
> Somehow I lost track of that final detail (I blame Christmas and New
> Year), so that's indeed what we decided upon. I will implement it in v2
> (an eject notifier for BBs, which is then used by NBD).

Yeah, I was thinking again about it and an eject notifier really sounds
like the best plan.

Paolo



Re: [Qemu-devel] [PATCH] target-mips: use CP0EnLo_XI instead of magic number

2015-01-29 Thread Maciej W. Rozycki
On Thu, 29 Jan 2015, Leon Alrae wrote:

> >  And do we want to have CP0C3_LPA set in the few templates that do in the 
> > first place?  AFAICT we don't really implement LPA so this bit will 
> > confuse software.  Of course implementing it would be another option, not 
> > very complicated AFAICS, and if we can track the requirement to update 
> > MFC0 at that time, then the clean-up I mentioned above can be deferred 
> > until then.
> 
> In general I don't think it's a good idea to indicate presence of a
> feature in a CPU config if it isn't implemented at all in QEMU -- as you
> said, it will confuse software. As far as LPA goes I've got already an
> implementation of it (and XPA as well) which I haven't submitted
> upstream yet. I'll make sure it contains the change you suggested.

 Great, I'll leave it to you to sort out then.  Thanks!

  Maciej



Re: [Qemu-devel] [PATCH 2/2] bootdevice: update boot_order in MachineState

2015-01-29 Thread Gonglei
On 2015/1/29 18:55, Alexander Graf wrote:

> 
> 
> On 28.01.15 02:48, Gonglei wrote:
>> On 2015/1/27 18:49, Dinar Valeev wrote:
>>
>>> On 01/27/2015 10:18 AM, Gonglei wrote:
 On 2015/1/27 16:57, Dinar Valeev wrote:

> On 01/27/2015 03:51 AM, Gonglei wrote:
>> On 2015/1/27 7:52, dval...@suse.de wrote:
>>
>>> From: Dinar Valeev 
>>>
>>> on sPAPR we need to update boot_order in MachineState in case it
>>> got changed on reset.
>>>
>>> Signed-off-by: Dinar Valeev 
>>> ---
>>>  bootdevice.c | 3 +++
>>>  1 file changed, 3 insertions(+)
>>>
>>> diff --git a/bootdevice.c b/bootdevice.c
>>> index 5914417..4f11a06 100644
>>> --- a/bootdevice.c
>>> +++ b/bootdevice.c
>>> @@ -26,6 +26,7 @@
>>>  #include "qapi/visitor.h"
>>>  #include "qemu/error-report.h"
>>>  #include "hw/hw.h"
>>> +#include "hw/boards.h"
>>>  
>>>  typedef struct FWBootEntry FWBootEntry;
>>>  
>>> @@ -50,6 +51,8 @@ void qemu_register_boot_set(QEMUBootSetHandler *func, 
>>> void *opaque)
>>>  void qemu_boot_set(const char *boot_order, Error **errp)
>>>  {
>>>  Error *local_err = NULL;
>>> +MachineState *machine = MACHINE(qdev_get_machine());
>>> +machine->boot_order = boot_order;
>>>  
>>>  if (!boot_set_handler) {
>>>  error_setg(errp, "no function defined to set boot device list 
>>> for"
>>
>> Have you registered boot set handler on ppc/sPAPR platform by calling
>> qemu_register_boot_set()? Otherwise qemu_boot_set function
>>  will return error.
> No, I set boot_order on each machine reset. My tests are showing it works 
> without an error.

 That's interesting. Does this function be called?
>>> Yes, then simply returns.
 Would you debug it by setting a breakpoint ?
>>> I added a trace event.
>>>  if (!boot_set_handler) {
>>> +trace_qemu_boot_set(boot_order);
>>>  error_setg(errp, "no function defined to set boot device list for"
>>>   " this architecture");
>>>  return;
>>>
>>> And I see this now in qemu's monitor. Still I don't see error message.
>>
>> That's because NULL is passed to this function in restore_boot_order()
>> the error is ignored (commit f183993). I have seen the previous conversation
>> about your patch serials. And I think this is the reason which
>> you moved machine->boot_order = boot_order before
>> checking boot_set_handler variable based on Alexander's
>> suggestion, right? But I think this is not a good idea.
> 
> Why is it not a good idea? The check is only checking whether there are
> callbacks. The boot order changes nevertheless.
> 

I mean we can't simply ignore this error. If you don't use boot_set_handler
but machine->boot_order then the check should not report error.

Something like this:

diff --git a/bootdevice.c b/bootdevice.c
index c3a010c..98ed2d2 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -51,19 +51,15 @@ void qemu_boot_set(const char *boot_order, Error **errp)
 {
 Error *local_err = NULL;

-if (!boot_set_handler) {
-error_setg(errp, "no function defined to set boot device list for"
- " this architecture");
-return;
-}
-
 validate_bootdevices(boot_order, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
 return;
 }

-boot_set_handler(boot_set_opaque, boot_order, errp);
+if (boot_set_handler) {
+boot_set_handler(boot_set_opaque, boot_order, errp);
+}
 }

 void validate_bootdevices(const char *devices, Error **errp)

Regards,
-Gonglei





Re: [Qemu-devel] [PATCH 2/2] bootdevice: update boot_order in MachineState

2015-01-29 Thread Alexander Graf


On 29.01.15 12:08, Gonglei wrote:
> On 2015/1/29 18:55, Alexander Graf wrote:
> 
>>
>>
>> On 28.01.15 02:48, Gonglei wrote:
>>> On 2015/1/27 18:49, Dinar Valeev wrote:
>>>
 On 01/27/2015 10:18 AM, Gonglei wrote:
> On 2015/1/27 16:57, Dinar Valeev wrote:
>
>> On 01/27/2015 03:51 AM, Gonglei wrote:
>>> On 2015/1/27 7:52, dval...@suse.de wrote:
>>>
 From: Dinar Valeev 

 on sPAPR we need to update boot_order in MachineState in case it
 got changed on reset.

 Signed-off-by: Dinar Valeev 
 ---
  bootdevice.c | 3 +++
  1 file changed, 3 insertions(+)

 diff --git a/bootdevice.c b/bootdevice.c
 index 5914417..4f11a06 100644
 --- a/bootdevice.c
 +++ b/bootdevice.c
 @@ -26,6 +26,7 @@
  #include "qapi/visitor.h"
  #include "qemu/error-report.h"
  #include "hw/hw.h"
 +#include "hw/boards.h"
  
  typedef struct FWBootEntry FWBootEntry;
  
 @@ -50,6 +51,8 @@ void qemu_register_boot_set(QEMUBootSetHandler 
 *func, void *opaque)
  void qemu_boot_set(const char *boot_order, Error **errp)
  {
  Error *local_err = NULL;
 +MachineState *machine = MACHINE(qdev_get_machine());
 +machine->boot_order = boot_order;
  
  if (!boot_set_handler) {
  error_setg(errp, "no function defined to set boot device list 
 for"
>>>
>>> Have you registered boot set handler on ppc/sPAPR platform by calling
>>> qemu_register_boot_set()? Otherwise qemu_boot_set function
>>>  will return error.
>> No, I set boot_order on each machine reset. My tests are showing it 
>> works without an error.
>
> That's interesting. Does this function be called?
 Yes, then simply returns.
> Would you debug it by setting a breakpoint ?
 I added a trace event.
  if (!boot_set_handler) {
 +trace_qemu_boot_set(boot_order);
  error_setg(errp, "no function defined to set boot device list for"
   " this architecture");
  return;

 And I see this now in qemu's monitor. Still I don't see error message.
>>>
>>> That's because NULL is passed to this function in restore_boot_order()
>>> the error is ignored (commit f183993). I have seen the previous conversation
>>> about your patch serials. And I think this is the reason which
>>> you moved machine->boot_order = boot_order before
>>> checking boot_set_handler variable based on Alexander's
>>> suggestion, right? But I think this is not a good idea.
>>
>> Why is it not a good idea? The check is only checking whether there are
>> callbacks. The boot order changes nevertheless.
>>
> 
> I mean we can't simply ignore this error. If you don't use boot_set_handler
> but machine->boot_order then the check should not report error.
> 
> Something like this:

Oh, I see. Yes, I agree there :).


Alex



Re: [Qemu-devel] [PATCH 2/2] acpi-build: skip hotplugged bridges

2015-01-29 Thread Igor Mammedov
On Wed, 28 Jan 2015 18:30:38 +0200
"Michael S. Tsirkin"  wrote:

> hotplugged bridges don't get bsel allocated so acpi hotplug doesn't work
> for them anyway.  OTOH adding them in ACPI creates a host of problems,
> e.g. they can't be hot-unplugged themselves which is surprising to
> users.
> 
> So let's just skip these.

While reviewing this patch I've found out that in current master
hotplug bridge + reboot creates shrunk SSDT  which leads to
RSDT offset shift -> static RSDP no longer points at it.

Sequence of events are following:
 
  1: on reboot create subtree with hotplugged bridge device but without slots 
since
   1: hotplugged bridge doesn't have BSEL -> can_eject = false for every 
slot
   2: every slot marked as non present since no device plugged in it
 that leads to skipping creation of slot devices inside bridge
  2. condition
   if (bus_hotplug_support || child->notify_table->len || !bus->parent_dev)
 also completely skips creation of notify_table and device_table,
 hence parent bus never adds bridge subtree to its context.
  3. since for the slot where bridge was hotplugged
   bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en;
   if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) {
set_bit(slot, slot_device_system); 
 its parent bus, completely skips creation of slot device relying
 on it being provided by child->device_table but due to #2
 it doesn't happen.
As result of all above PCI0 tree description shrinks on 56 bytes,
size of skipped original hotplug slot.


> 
> Signed-off-by: Michael S. Tsirkin 
> ---
>  hw/i386/acpi-build.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 74586f3..ff42de5 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -857,8 +857,10 @@ static void build_pci_bus_end(PCIBus *bus, void 
> *bus_state)
>  /*
>   * Skip bridge subtree creation if bridge hotplug is disabled
>   * to make acpi tables compatible with legacy machine types.
> + * Skip creation for hotplugged bridges as well.
>   */
> -if (!child->pcihp_bridge_en && bus->parent_dev) {
> +if (bus->parent_dev && (!child->pcihp_bridge_en ||
> +DEVICE(bus->parent_dev)->hotplugged)) {
according to above findings this doesn't change anything,
since device_table won't be populated in the end anyway.
It just makes outcome clearer.

but following hunk makes a difference.

>  build_free_array(bus_table);
>  build_pci_bus_state_cleanup(child);
>  g_free(child);
> @@ -915,8 +917,10 @@ static void build_pci_bus_end(PCIBus *bus, void 
> *bus_state)
>  /* When hotplug for bridges is enabled, bridges are
>   * described in ACPI separately (see build_pci_bus_end).
>   * In this case they aren't themselves hot-pluggable.
> + * Hotplugged bridges *are* hot-pluggable.
>   */
> -bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en;
> +bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en &&
> + !DEVICE(pdev)->hotplugged;
with this, current bus tree keeps hotplugged slot description for slot
where bridge was hotplugged and keeps SSDT size exactly the same across
reboot. But it has side effect that it would be possible to invoke
hot-unplug on it -> I don't know what side effects it will cause at the end.

However it doesn't fix immutable RSDP pointing to fixed RSDT offset,
i.e. it's fixing symptoms until the next time we hit shifted RSDT problem.
Proper fix would be make RSDP updated on reboot along with currently
updated ACPI tables blob.

That also rises a question: do we need to rebuild ACPI tables on
reboot at all? If yes, Why?

>  
>  if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) {
>  set_bit(slot, slot_device_system);




Re: [Qemu-devel] [PATCH v5 2/2] Xen: Use the ioreq-server API when available

2015-01-29 Thread Paul Durrant
> -Original Message-
> From: Don Slutz [mailto:dsl...@verizon.com]
> Sent: 29 January 2015 00:58
> To: Don Slutz; Paul Durrant; qemu-devel@nongnu.org; Stefano Stabellini
> Cc: Peter Maydell; Olaf Hering; Alexey Kardashevskiy; Stefan Weil; Michael
> Tokarev; Alexander Graf; Gerd Hoffmann; Stefan Hajnoczi; Paolo Bonzini
> Subject: Re: [Qemu-devel] [PATCH v5 2/2] Xen: Use the ioreq-server API
> when available
> 
> 
> 
> On 01/28/15 19:05, Don Slutz wrote:
> > On 01/28/15 14:32, Don Slutz wrote:
> >> On 12/05/14 05:50, Paul Durrant wrote:
> >>> The ioreq-server API added to Xen 4.5 offers better security than
> >>> the existing Xen/QEMU interface because the shared pages that are
> >>> used to pass emulation request/results back and forth are removed
> >>> from the guest's memory space before any requests are serviced.
> >>> This prevents the guest from mapping these pages (they are in a
> >>> well known location) and attempting to attack QEMU by synthesizing
> >>> its own request structures. Hence, this patch modifies configure
> >>> to detect whether the API is available, and adds the necessary
> >>> code to use the API if it is.
> >>
> >> This patch (which is now on xenbits qemu staging) is causing me
> >> issues.
> >>
> >
> > I have found the key.
> >
> > The following will reproduce my issue:
> >
> > 1) xl create -p 
> > 2) read one of HVM_PARAM_IOREQ_PFN, HVM_PARAM_BUFIOREQ_PFN,
> or
> >HVM_PARAM_BUFIOREQ_EVTCHN
> > 3) xl unpause new guest
> >
> > The guest will hang in hvmloader.
> >
> > More in thread:
> >
> >
> > Subject: Re: [Xen-devel] [PATCH] ioreq-server: handle
> > IOREQ_TYPE_PCI_CONFIG in assist function
> > References: <1422385589-17316-1-git-send-email-wei.l...@citrix.com>
> >
> >
> 
> Opps, That thread does not make sense to include what I have found.
> 
> Here is the info I was going to send there:
> 
> 
> Using QEMU upstream master (or xenbits qemu staging), you do not have a
> default ioreq server.  And so hvm_select_ioreq_server() returns NULL for
> hvmloader's iorequest to:
> 
> CPU4  0 (+   0)  HANDLE_PIO [ port = 0x0cfe size = 2 dir = 1 ]
> 
> (I added this xentrace to figure out what is happening, and I have
> a lot of data about it, if any one wants it.)
> 
> To get a guest hang instead of calling hvm_complete_assist_req()
> for some of hvmloader's pci_read() calls, you can do the following:
> 
> 
> 1) xl create -p 
> 2) read one of HVM_PARAM_IOREQ_PFN, HVM_PARAM_BUFIOREQ_PFN,
> or
>HVM_PARAM_BUFIOREQ_EVTCHN
> 3) xl unpause new guest
> 
> The guest will hang in hvmloader.
> 
> The read of HVM_PARAM_IOREQ_PFN will cause a default ioreq server to
> be created and directed to the QEMU upsteam that is not a default
> ioreq server.  This read also creates the extra event channels that
> I see.
> 
> I see that hvmop_create_ioreq_server() prevents you from creating
> an is_default ioreq_server, so QEMU is not able to do.
> 
> Not sure where we go from here.
> 

Given that IIRC you are using a new dedicated IOREQ type, I think there needs 
to be something that allows an emulator to register for this IOREQ type. How 
about adding a new type to those defined for HVMOP_map_io_range_to_ioreq_server 
for your case? (In your case the start and end values in the hypercall would be 
meaningless but it could be used to steer hvm_select_ioreq_server() into 
sending all emulation requests or your new type to QEMU.
Actually such a mechanism could be used to steer IOREQ_TYPE_TIMEOFFSET requests 
as, with the new QEMU patches, they are going nowhere. Upstream QEMU (as 
default) used to ignore them anyway, which is why I didn't bother with such a 
patch to Xen before but since you now need one maybe you could add that too?

  Paul

>-Don Slutz
> 
> 
> > -Don Slutz
> >
> >
> >> So far I have tracked it back to hvm_select_ioreq_server()
> >> which selects the "default_ioreq_server".  Since I have one 1
> >> QEMU, it is both the "default_ioreq_server" and an enabled
> >> 2nd ioreq_server.  I am continuing to understand why my changes
> >> are causing this.  More below.
> >>
> >> This patch causes QEMU to only call xc_evtchn_bind_interdomain()
> >> for the enabled 2nd ioreq_server.  So when (if)
> >> hvm_select_ioreq_server() selects the "default_ioreq_server", the
> >> guest hangs on an I/O.
> >>
> >> Using the debug key 'e':
> >>
> >> (XEN) [2015-01-28 18:57:07] 'e' pressed -> dumping event-channel info
> >> (XEN) [2015-01-28 18:57:07] Event channel information for domain 0:
> >> (XEN) [2015-01-28 18:57:07] Polling vCPUs: {}
> >> (XEN) [2015-01-28 18:57:07] port [p/m/s]
> >> (XEN) [2015-01-28 18:57:07]1 [0/0/0]: s=5 n=0 x=0 v=0
> >> (XEN) [2015-01-28 18:57:07]2 [0/0/0]: s=6 n=0 x=0
> >> (XEN) [2015-01-28 18:57:07]3 [0/0/0]: s=6 n=0 x=0
> >> (XEN) [2015-01-28 18:57:07]4 [0/0/0]: s=5 n=0 x=0 v=1
> >> (XEN) [2015-01-28 18:57:07]5 [0/0/0]: s=6 n=0 x=0
> >> (XEN) [2015-01-28 18:57:07]6 [0/0/0]: s=6 n=0 x=0
> >> (XEN) [2015-01-28 18:57

Re: [Qemu-devel] [RESEND PATCH v1 01/13] acpi, mem-hotplug: Use PC_DIMM_SLOT_PROP in acpi_memory_plug_cb().

2015-01-29 Thread Igor Mammedov
On Thu, 8 Jan 2015 09:06:08 +0800
Tang Chen  wrote:

> Replace string "slot" in acpi_memory_plug_cb() with MACRO PC_DIMM_SLOT_PROP.
> 
> Signed-off-by: Tang Chen 
Reviewed-by: Igor Mammedov 

> ---
>  hw/acpi/memory_hotplug.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index ed39241..c6580da 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -168,7 +168,8 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, 
> MemHotplugState *mem_st,
>  {
>  MemStatus *mdev;
>  Error *local_err = NULL;
> -int slot = object_property_get_int(OBJECT(dev), "slot", &local_err);
> +int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
> +   &local_err);
>  
>  if (local_err) {
>  error_propagate(errp, local_err);




[Qemu-devel] [PATCH v10 3/5] stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG

2015-01-29 Thread Alistair Francis
This patch adds the stm32f2xx System Configuration
Controller. This is used to configure what memory is mapped
at address 0 (although that is not supported) as well
as configure how the EXTI interrupts work (also not
supported at the moment).

This device is not required for basic examples, but more
complex systems will require it (as well as the EXTI device)

Signed-off-by: Alistair Francis 
Reviewed-by: Peter Crosthwaite 
---
V6:
 - Rename to STM32F2XX
 - Remove all casts from debug printing

 default-configs/arm-softmmu.mak|   1 +
 hw/misc/Makefile.objs  |   1 +
 hw/misc/stm32f2xx_syscfg.c | 160 +
 include/hw/misc/stm32f2xx_syscfg.h |  61 ++
 4 files changed, 223 insertions(+)
 create mode 100644 hw/misc/stm32f2xx_syscfg.c
 create mode 100644 include/hw/misc/stm32f2xx_syscfg.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 1348104..a5aab7f 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -80,6 +80,7 @@ CONFIG_ZAURUS=y
 CONFIG_ZYNQ=y
 CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
+CONFIG_STM32F2XX_SYSCFG=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 029a56f..049c1a0 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -38,6 +38,7 @@ obj-$(CONFIG_OMAP) += omap_sdrc.o
 obj-$(CONFIG_OMAP) += omap_tap.o
 obj-$(CONFIG_SLAVIO) += slavio_misc.o
 obj-$(CONFIG_ZYNQ) += zynq_slcr.o
+obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
diff --git a/hw/misc/stm32f2xx_syscfg.c b/hw/misc/stm32f2xx_syscfg.c
new file mode 100644
index 000..4ae4042
--- /dev/null
+++ b/hw/misc/stm32f2xx_syscfg.c
@@ -0,0 +1,160 @@
+/*
+ * STM32F2XX SYSCFG
+ *
+ * Copyright (c) 2014 Alistair Francis 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/misc/stm32f2xx_syscfg.h"
+
+#ifndef STM_SYSCFG_ERR_DEBUG
+#define STM_SYSCFG_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_syscfg_reset(DeviceState *dev)
+{
+STM32F2XXSyscfgState *s = STM32F2XX_SYSCFG(dev);
+
+s->syscfg_memrmp = 0x;
+s->syscfg_pmc = 0x;
+s->syscfg_exticr1 = 0x;
+s->syscfg_exticr2 = 0x;
+s->syscfg_exticr3 = 0x;
+s->syscfg_exticr4 = 0x;
+s->syscfg_cmpcr = 0x;
+}
+
+static uint64_t stm32f2xx_syscfg_read(void *opaque, hwaddr addr,
+ unsigned int size)
+{
+STM32F2XXSyscfgState *s = opaque;
+
+DB_PRINT("0x%"HWADDR_PRIx"\n", addr);
+
+switch (addr) {
+case SYSCFG_MEMRMP:
+return s->syscfg_memrmp;
+case SYSCFG_PMC:
+return s->syscfg_pmc;
+case SYSCFG_EXTICR1:
+return s->syscfg_exticr1;
+case SYSCFG_EXTICR2:
+return s->syscfg_exticr2;
+case SYSCFG_EXTICR3:
+return s->syscfg_exticr3;
+case SYSCFG_EXTICR4:
+return s->syscfg_exticr4;
+case SYSCFG_CMPCR:
+return s->syscfg_cmpcr;
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+return 0;
+}
+
+return 0;
+}
+
+static void stm32f2xx_syscfg_write(void *opaque, hwaddr addr,
+   uint64_t val64, unsigned int size)
+{
+STM32F2XXSyscfgState *s = opaque;
+uint32_t value = val64;
+
+DB_PRINT("0x%x, 0x%"HWADDR_PRIx"\n", value, addr);
+
+switch (addr) {
+case SYSCFG_MEMRMP:
+qemu_log_mask(LOG_UNIMP,
+  "%s: Changeing the memory mapping isn't supported " \
+  "in QEMU\n", __func__);
+

[Qemu-devel] [PATCH v10 0/5] Netduino 2 Machine Model

2015-01-29 Thread Alistair Francis
This patch series adds the Netduino 2 Machine to QEMU

Information on the board is avalible at:
http://www.netduino.com/netduino2/specs.htm

The git tree can be found at:
https://github.com/alistair23/qemu/tree/netduino2.9

This patch series makes some changes to the armv7m_init function
that allows the code to be reused with the Netduino 2 and the
Stellaris machines.

Some example code that runs on QEMU is avaliable at:
at: https://github.com/alistair23/CSSE3010-QEMU-Examples

There are more devices in the works, I figured I would just start
with these three

V9/V10:
 - Correct timer device based on Peter C's comments
V8:
 - Update the timer device based on Peter C's comments
 - Update the USART device based on Peter C's comments
V7:
 - Rebase to QEMU 2.2
V6:
 - Rename the three devices to STM32FXX*
 - Correct the timer to use ns
 - Correct the number of devices that are inited
 - Rename memory regions


Alistair Francis (5):
  stm32f2xx_timer: Add the stm32f2xx Timer
  stm32f2xx_USART: Add the stm32f2xx USART Controller
  stm32f2xx_SYSCFG: Add the stm32f2xx SYSCFG
  stm32f205: Add the stm32f205 SoC
  netduino2: Add the Netduino 2 Machine

 default-configs/arm-softmmu.mak|   4 +
 hw/arm/Makefile.objs   |   2 +
 hw/arm/netduino2.c |  54 +++
 hw/arm/stm32f205_soc.c | 157 ++
 hw/char/Makefile.objs  |   1 +
 hw/char/stm32f2xx_usart.c  | 229 ++
 hw/misc/Makefile.objs  |   1 +
 hw/misc/stm32f2xx_syscfg.c | 160 ++
 hw/timer/Makefile.objs |   2 +
 hw/timer/stm32f2xx_timer.c | 324 +
 include/hw/arm/stm32f205_soc.h |  69 
 include/hw/char/stm32f2xx_usart.h  |  69 
 include/hw/misc/stm32f2xx_syscfg.h |  61 +++
 include/hw/timer/stm32f2xx_timer.h | 101 
 14 files changed, 1234 insertions(+)
 create mode 100644 hw/arm/netduino2.c
 create mode 100644 hw/arm/stm32f205_soc.c
 create mode 100644 hw/char/stm32f2xx_usart.c
 create mode 100644 hw/misc/stm32f2xx_syscfg.c
 create mode 100644 hw/timer/stm32f2xx_timer.c
 create mode 100644 include/hw/arm/stm32f205_soc.h
 create mode 100644 include/hw/char/stm32f2xx_usart.h
 create mode 100644 include/hw/misc/stm32f2xx_syscfg.h
 create mode 100644 include/hw/timer/stm32f2xx_timer.h

-- 
2.1.0




[Qemu-devel] [PATCH v10 1/5] stm32f2xx_timer: Add the stm32f2xx Timer

2015-01-29 Thread Alistair Francis
This patch adds the stm32f2xx timers: TIM2, TIM3, TIM4 and TIM5
to QEMU.

Signed-off-by: Alistair Francis 
Signed-off-by: Peter Crosthwaite 
---
V10:
 - Correct the units based on a patch by Peter C
V9:
 - Convert tick_offset to now be updated on more events
- This is similar to what I did with the ARM PCCNT regiseter
V8:
 - Fix tick_offset to allow now to wrap around
 - Remove the calls to get_ticks_per_sec()
 - Pre-scale the guest visable time
V6:
 - Rename to STM32F2XX
 - Change the timer calculations to use ns
 - Update the value to timer_mod to ensure it is in ns
 - Account for reloadable/resetable timer
- Thanks to Peter C for pointing this out

 default-configs/arm-softmmu.mak|   1 +
 hw/timer/Makefile.objs |   2 +
 hw/timer/stm32f2xx_timer.c | 324 +
 include/hw/timer/stm32f2xx_timer.h | 101 
 4 files changed, 428 insertions(+)
 create mode 100644 hw/timer/stm32f2xx_timer.c
 create mode 100644 include/hw/timer/stm32f2xx_timer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index f3513fa..faea100 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -78,6 +78,7 @@ CONFIG_NSERIES=y
 CONFIG_REALVIEW=y
 CONFIG_ZAURUS=y
 CONFIG_ZYNQ=y
+CONFIG_STM32F2XX_TIMER=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 2c86c3d..133bd0d 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -31,3 +31,5 @@ obj-$(CONFIG_DIGIC) += digic-timer.o
 obj-$(CONFIG_MC146818RTC) += mc146818rtc.o
 
 obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o
+
+common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o
diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
new file mode 100644
index 000..72de746
--- /dev/null
+++ b/hw/timer/stm32f2xx_timer.c
@@ -0,0 +1,324 @@
+/*
+ * STM32F2XX Timer
+ *
+ * Copyright (c) 2014 Alistair Francis 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/timer/stm32f2xx_timer.h"
+
+#ifndef STM_TIMER_ERR_DEBUG
+#define STM_TIMER_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (STM_TIMER_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f2xx_timer_set_alarm(STM32F2XXTimerState *s, int64_t now);
+
+static void stm32f2xx_timer_interrupt(void *opaque)
+{
+STM32F2XXTimerState *s = opaque;
+
+DB_PRINT("Interrupt\n");
+
+if (s->tim_dier & TIM_DIER_UIE && s->tim_cr1 & TIM_CR1_CEN) {
+s->tim_sr |= 1;
+qemu_irq_pulse(s->irq);
+stm32f2xx_timer_set_alarm(s, s->hit_time);
+}
+}
+
+static inline int64_t stm32f2xx_ns_to_ticks(STM32F2XXTimerState *s, int64_t t)
+{
+return muldiv64(t, s->freq_hz, 10ULL) / (s->tim_psc + 1);
+}
+
+static void stm32f2xx_timer_set_alarm(STM32F2XXTimerState *s, int64_t now)
+{
+uint64_t ticks;
+int64_t now_ticks;
+
+if (s->tim_arr == 0) {
+return;
+}
+
+DB_PRINT("Alarm set at: 0x%x\n", s->tim_cr1);
+
+now_ticks = stm32f2xx_ns_to_ticks(s, now);
+ticks = s->tim_arr - (now_ticks - s->tick_offset);
+
+DB_PRINT("Alarm set in %d ticks\n", (int) ticks);
+
+s->hit_time = muldiv64((ticks + (uint64_t) now_ticks) * (s->tim_psc + 1),
+   10ULL, s->freq_hz);
+
+timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->hit_time);
+DB_PRINT("Wait Time: %" PRId64 " ticks\n", s->hit_time);
+}
+
+static void stm32f2xx_timer_reset(DeviceState *dev)
+{
+STM32F2XXTimerState *s = STM32F2XXTIMER(dev);
+int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+
+s->tim_cr1 = 0;
+s->tim_cr2 = 0;
+s->tim_smcr = 0;
+s->tim_dier = 0;
+s->tim_sr = 0;
+s->tim_egr = 0;
+s->tim_ccmr1 = 0;
+s->tim_cc

Re: [Qemu-devel] [RESEND PATCH v1 02/13] acpi, mem-hotplug: Add acpi_memory_get_slot_status_descriptor() to get MemStatus.

2015-01-29 Thread Igor Mammedov
On Thu, 8 Jan 2015 09:06:09 +0800
Tang Chen  wrote:

> Add a new API named acpi_memory_get_slot_status_descriptor() to obtain
> a single memory slot status. Doing this is because this procedure will
> be used by other functions in the next coming patches.
> 
> Signed-off-by: Tang Chen 
> ---
>  hw/acpi/memory_hotplug.c | 27 +++
>  1 file changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index c6580da..ef56bf6 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -163,29 +163,40 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object 
> *owner,
>  memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io);
>  }
>  
> -void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
> - DeviceState *dev, Error **errp)
> +static MemStatus *
> +acpi_memory_get_slot_status_descriptor(MemHotplugState *mem_st,
> +   DeviceState *dev, Error **errp)
how about
  s/acpi_memory_get_slot_status_descriptor/acpi_memory_slot_status/


>  {
> -MemStatus *mdev;
>  Error *local_err = NULL;
>  int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
> &local_err);
>  
>  if (local_err) {
>  error_propagate(errp, local_err);
> -return;
> +return NULL;
>  }
>  
>  if (slot >= mem_st->dev_count) {
>  char *dev_path = object_get_canonical_path(OBJECT(dev));
> -error_setg(errp, "acpi_memory_plug_cb: "
> +error_setg(errp, "acpi_memory_get_slot_status_descriptor: "
> "device [%s] returned invalid memory slot[%d]",
> -dev_path, slot);
> +   dev_path, slot);
>  g_free(dev_path);
> -return;
> +return NULL;
>  }
>  
> -mdev = &mem_st->devs[slot];
> +return &mem_st->devs[slot];
> +}
> +
> +void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
> + DeviceState *dev, Error **errp)
> +{
> +MemStatus *mdev;
> +
> +mdev = acpi_memory_get_slot_status_descriptor(mem_st, dev, errp);
> +if (!mdev)
> +return;
> +
>  mdev->dimm = dev;
>  mdev->is_enabled = true;
>  mdev->is_inserting = true;




[Qemu-devel] [PATCH v10 2/5] stm32f2xx_USART: Add the stm32f2xx USART Controller

2015-01-29 Thread Alistair Francis
This patch adds the stm32f2xx USART controller
(UART also uses the same controller).

Signed-off-by: Alistair Francis 
---
V8:
 - Clear IRQ on reset
 - Lower IRQ on data read/status clear
 - Set IRQ if enabled while data is avaliable
V6:
 - Rename to STM32F2XX
 - Fix up unimplemented printing
 - Add a qemu_chr_accept()

 default-configs/arm-softmmu.mak   |   1 +
 hw/char/Makefile.objs |   1 +
 hw/char/stm32f2xx_usart.c | 229 ++
 include/hw/char/stm32f2xx_usart.h |  69 
 4 files changed, 300 insertions(+)
 create mode 100644 hw/char/stm32f2xx_usart.c
 create mode 100644 include/hw/char/stm32f2xx_usart.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index faea100..1348104 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -79,6 +79,7 @@ CONFIG_REALVIEW=y
 CONFIG_ZAURUS=y
 CONFIG_ZYNQ=y
 CONFIG_STM32F2XX_TIMER=y
+CONFIG_STM32F2XX_USART=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 317385d..5931cc8 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -15,6 +15,7 @@ obj-$(CONFIG_OMAP) += omap_uart.o
 obj-$(CONFIG_SH4) += sh_serial.o
 obj-$(CONFIG_PSERIES) += spapr_vty.o
 obj-$(CONFIG_DIGIC) += digic-uart.o
+obj-$(CONFIG_STM32F2XX_USART) += stm32f2xx_usart.o
 
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
new file mode 100644
index 000..260b053
--- /dev/null
+++ b/hw/char/stm32f2xx_usart.c
@@ -0,0 +1,229 @@
+/*
+ * STM32F2XX USART
+ *
+ * Copyright (c) 2014 Alistair Francis 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/char/stm32f2xx_usart.h"
+
+#ifndef STM_USART_ERR_DEBUG
+#define STM_USART_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+if (STM_USART_ERR_DEBUG >= lvl) { \
+qemu_log("%s: " fmt, __func__, ## args); \
+} \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static int stm32f2xx_usart_can_receive(void *opaque)
+{
+STM32F2XXUsartState *s = opaque;
+
+if (!(s->usart_sr & USART_SR_RXNE)) {
+return 1;
+}
+
+return 0;
+}
+
+static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
+{
+STM32F2XXUsartState *s = opaque;
+
+s->usart_dr = *buf;
+
+if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) {
+/* USART not enabled - drop the chars */
+DB_PRINT("Dropping the chars\n");
+return;
+}
+
+s->usart_sr |= USART_SR_RXNE;
+
+if (s->usart_cr1 & USART_CR1_RXNEIE) {
+qemu_set_irq(s->irq, 1);
+}
+
+DB_PRINT("Receiving: %c\n", s->usart_dr);
+}
+
+static void stm32f2xx_usart_reset(DeviceState *dev)
+{
+STM32F2XXUsartState *s = STM32F2XX_USART(dev);
+
+s->usart_sr = USART_SR_RESET;
+s->usart_dr = 0x;
+s->usart_brr = 0x;
+s->usart_cr1 = 0x;
+s->usart_cr2 = 0x;
+s->usart_cr3 = 0x;
+s->usart_gtpr = 0x;
+
+qemu_set_irq(s->irq, 0);
+}
+
+static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
+   unsigned int size)
+{
+STM32F2XXUsartState *s = opaque;
+uint64_t retvalue;
+
+DB_PRINT("Read 0x%"HWADDR_PRIx"\n", addr);
+
+switch (addr) {
+case USART_SR:
+retvalue = s->usart_sr;
+s->usart_sr &= ~USART_SR_TC;
+if (s->chr) {
+qemu_chr_accept_input(s->chr);
+}
+return retvalue;
+case USART_DR:
+DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) 
s->usart_dr);
+s->usart_sr |= USART_SR_TXE;
+s->usart_sr &= ~USART_SR_RXNE;
+if (s->chr) {
+qemu_chr_accept_input(s->chr);
+}
+qemu_set_irq(s->irq, 0)

[Qemu-devel] [PATCH v10 4/5] stm32f205: Add the stm32f205 SoC

2015-01-29 Thread Alistair Francis
This patch adds the stm32f205 SoC. This will be used by the
Netduino 2 to create a machine.

Signed-off-by: Alistair Francis 
---
V6:
 - Correct the number of USART/UART devices
 - Use macros to define how many devices are inited
 - Update the memory regions name from netduino.* to
   STM32F205.*

 default-configs/arm-softmmu.mak |   1 +
 hw/arm/Makefile.objs|   1 +
 hw/arm/stm32f205_soc.c  | 157 
 include/hw/arm/stm32f205_soc.h  |  69 ++
 4 files changed, 228 insertions(+)
 create mode 100644 hw/arm/stm32f205_soc.c
 create mode 100644 include/hw/arm/stm32f205_soc.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a5aab7f..9ac755e 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -81,6 +81,7 @@ CONFIG_ZYNQ=y
 CONFIG_STM32F2XX_TIMER=y
 CONFIG_STM32F2XX_USART=y
 CONFIG_STM32F2XX_SYSCFG=y
+CONFIG_STM32F205_SOC=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 6088e53..9769317 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -8,3 +8,4 @@ obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o 
pxa2xx_pic.o
 obj-$(CONFIG_DIGIC) += digic.o
 obj-y += omap1.o omap2.o strongarm.o
 obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
+obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
new file mode 100644
index 000..186e15d
--- /dev/null
+++ b/hw/arm/stm32f205_soc.c
@@ -0,0 +1,157 @@
+/*
+ * STM32F205 SoC
+ *
+ * Copyright (c) 2014 Alistair Francis 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/arm/stm32f205_soc.h"
+
+/* At the moment only Timer 2 to 5 are modelled */
+static const uint32_t timer_addr[STM_NUM_TIMERS] = { 0x4000, 0x4400,
+0x4800, 0x4C00 };
+static const uint32_t usart_addr[STM_NUM_USARTS] = { 0x40011000, 0x40004400,
+0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
+
+static const int timer_irq[STM_NUM_TIMERS] = {28, 29, 30, 50};
+static const int usart_irq[STM_NUM_USARTS] = {37, 38, 39, 52, 53, 71};
+
+static void stm32f205_soc_initfn(Object *obj)
+{
+STM32F205State *s = STM32F205_SOC(obj);
+int i;
+
+object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F2XX_SYSCFG);
+qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
+
+for (i = 0; i < STM_NUM_USARTS; i++) {
+object_initialize(&s->usart[i], sizeof(s->usart[i]),
+  TYPE_STM32F2XX_USART);
+qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
+}
+
+for (i = 0; i < STM_NUM_TIMERS; i++) {
+object_initialize(&s->timer[i], sizeof(s->timer[i]),
+  TYPE_STM32F2XX_TIMER);
+qdev_set_parent_bus(DEVICE(&s->timer[i]), sysbus_get_default());
+}
+}
+
+static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+STM32F205State *s = STM32F205_SOC(dev_soc);
+DeviceState *syscfgdev, *usartdev, *timerdev;
+SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
+qemu_irq *pic;
+Error *err = NULL;
+int i;
+
+MemoryRegion *system_memory = get_system_memory();
+MemoryRegion *sram = g_new(MemoryRegion, 1);
+MemoryRegion *flash = g_new(MemoryRegion, 1);
+MemoryRegion *flash_alias = g_new(MemoryRegion, 1);
+
+memory_region_init_ram(flash, NULL, "STM32F205.flash", FLASH_SIZE,
+   &error_abort);
+memory_region_init_alias(flash_alias, NULL, "STM32F205.flash.alias",
+ flash, 0, FLASH_SIZE);
+
+vmstate_register_ram_global(flash);
+
+memory_region_set_readonly(flash, true);
+memory_region_set_readonly(flash_alias, true);
+
+memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);
+memory_region_add_subregion(system_memory, 0, flash_al

[Qemu-devel] [PATCH v10 5/5] netduino2: Add the Netduino 2 Machine

2015-01-29 Thread Alistair Francis
This patch adds the Netduino 2 Machine.

This is a Cortex-M3 based machine. Information can be found at:
http://www.netduino.com/netduino2/specs.htm

Signed-off-by: Alistair Francis 
---

 hw/arm/Makefile.objs |  1 +
 hw/arm/netduino2.c   | 54 
 2 files changed, 55 insertions(+)
 create mode 100644 hw/arm/netduino2.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9769317..2577f68 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
+obj-y += netduino2.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-$(CONFIG_DIGIC) += digic.o
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
new file mode 100644
index 000..305983f
--- /dev/null
+++ b/hw/arm/netduino2.c
@@ -0,0 +1,54 @@
+/*
+ * Netduino 2 Machine Model
+ *
+ * Copyright (c) 2014 Alistair Francis 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/arm/stm32f205_soc.h"
+
+static void netduino2_init(MachineState *machine)
+{
+DeviceState *dev;
+Error *err = NULL;
+
+dev = qdev_create(NULL, TYPE_STM32F205_SOC);
+if (machine->kernel_filename) {
+qdev_prop_set_string(dev, "kernel-filename", machine->kernel_filename);
+}
+object_property_set_bool(OBJECT(dev), true, "realized", &err);
+if (err != NULL) {
+error_report("%s", error_get_pretty(err));
+exit(1);
+}
+}
+
+static QEMUMachine netduino2_machine = {
+.name = "netduino2",
+.desc = "Netduino 2 Machine",
+.init = netduino2_init,
+};
+
+static void netduino2_machine_init(void)
+{
+qemu_register_machine(&netduino2_machine);
+}
+
+machine_init(netduino2_machine_init);
-- 
2.1.0




Re: [Qemu-devel] [RESEND PATCH v1 03/13] acpi, mem-hotplug: Add acpi_memory_hotplug_sci() to rise sci for memory hotplug.

2015-01-29 Thread Igor Mammedov
On Thu, 8 Jan 2015 09:06:10 +0800
Tang Chen  wrote:

> Add a new API named acpi_memory_hotplug_sci() to send memory hotplug SCI.
> Doing this is because this procedure will be used by other functions in the
> next coming patches.
> 
> Signed-off-by: Tang Chen 
> ---
>  hw/acpi/memory_hotplug.c | 12 
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index ef56bf6..9839963 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -188,6 +188,12 @@ acpi_memory_get_slot_status_descriptor(MemHotplugState 
> *mem_st,
>  return &mem_st->devs[slot];
>  }
>  
> +static void acpi_memory_hotplug_sci(ACPIREGS *ar, qemu_irq irq)
> +{
> +ar->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
> +acpi_update_sci(ar, irq);
> +}
I'd suggest do a generic:

acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS)

which could be reused by CPU and PCI hotplug as well

>  void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
>   DeviceState *dev, Error **errp)
>  {
> @@ -201,10 +207,8 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, 
> MemHotplugState *mem_st,
>  mdev->is_enabled = true;
>  mdev->is_inserting = true;
>  
> -/* do ACPI magic */
> -ar->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
> -acpi_update_sci(ar, irq);
> -return;
> +/* Do ACPI magic */
> +acpi_memory_hotplug_sci(ar, irq);
>  }
>  
>  static const VMStateDescription vmstate_memhp_sts = {




Re: [Qemu-devel] [RESEND PATCH v1 07/13] pc-dimm: Add memory hot unplug request support for pc-dimm.

2015-01-29 Thread Igor Mammedov
On Thu, 8 Jan 2015 09:06:14 +0800
Tang Chen  wrote:

> Implement memory unplug request cb for pc-dimm, and call it in
> pc_machine_device_unplug_request_cb().
> ---
>  hw/i386/pc.c | 28 ++--
>  1 file changed, 26 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 0f3b1e0..f501f1f 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1671,6 +1671,26 @@ out:
>  error_propagate(errp, local_err);
>  }
>  
> +static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev,
> +   DeviceState *dev, Error **errp)
> +{
> +HotplugHandlerClass *hhc;
> +Error *local_err = NULL;
> +PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> +
> +if (!pcms->acpi_dev) {
> +error_setg(&local_err,
> +   "memory hotplug is not enabled: missing acpi device");
> + goto out;
wrong indent

> +}
> +
> +hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
> +hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
> +
> +out:
> +error_propagate(errp, local_err);
> +}
> +
>  static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>  DeviceState *dev, Error **errp)
>  {
> @@ -1713,8 +1733,12 @@ static void pc_machine_device_plug_cb(HotplugHandler 
> *hotplug_dev,
>  static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
>  DeviceState *dev, Error 
> **errp)
>  {
> -error_setg(errp, "acpi: device unplug request for not supported device"
> -   " type: %s", object_get_typename(OBJECT(dev)));
> +if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> +pc_dimm_unplug_request(hotplug_dev, dev, errp);
> +} else {
> +error_setg(errp, "acpi: device unplug request for not supported 
> device"
> +   " type: %s", object_get_typename(OBJECT(dev)));
> +}
>  }
>  
>  static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev,




[Qemu-devel] [PATCH 3/3] vnc: using bool type instead of int for QEMU_OPT_BOOL

2015-01-29 Thread arei.gonglei
From: Gonglei 

Signed-off-by: Gonglei 
---
 ui/vnc.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 23f413e..4bae970 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3322,8 +3322,8 @@ void vnc_display_open(const char *id, Error **errp)
 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
 const char *share, *device_id;
 QemuConsole *con;
-int password = 0;
-int reverse = 0;
+bool password = false;
+bool reverse = false;
 const char *vnc;
 const char *has_to;
 char *display, *to = NULL;
@@ -,11 +,11 @@ void vnc_display_open(const char *id, Error **errp)
 const char *websocket;
 #endif
 #ifdef CONFIG_VNC_TLS
-int tls = 0, x509 = 0;
+bool tls = false, x509 = false;
 const char *path;
 #endif
 #ifdef CONFIG_VNC_SASL
-int sasl = 0;
+bool sasl = false;
 int saslErr;
 #endif
 #if defined(CONFIG_VNC_TLS) || defined(CONFIG_VNC_SASL)
@@ -3389,7 +3389,7 @@ void vnc_display_open(const char *id, Error **errp)
 tls  = qemu_opt_get_bool(opts, "tls", false);
 path = qemu_opt_get(opts, "x509");
 if (path) {
-x509 = 1;
+x509 = true;
 vs->tls.x509verify = qemu_opt_get_bool(opts, "x509verify", false);
 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
 error_setg(errp, "Failed to find x509 certificates/keys in %s",
-- 
1.7.12.4





[Qemu-devel] [PATCH 2/3] vnc: correct missing property about vnc_display

2015-01-29 Thread arei.gonglei
From: Gonglei 

Missing three property for vnc socket connection,
revalue display variable with correct way.

Signed-off-by: Gonglei 
---
 ui/vnc.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 08b8b24..23f413e 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3320,10 +3320,15 @@ void vnc_display_open(const char *id, Error **errp)
 {
 VncDisplay *vs = vnc_display_find(id);
 QemuOpts *opts = qemu_opts_find(&qemu_vnc_opts, id);
-const char *display, *share, *device_id;
+const char *share, *device_id;
 QemuConsole *con;
 int password = 0;
 int reverse = 0;
+const char *vnc;
+const char *has_to;
+char *display, *to = NULL;
+bool has_ipv4 = false;
+bool has_ipv6 = false;
 #ifdef CONFIG_VNC_WS
 const char *websocket;
 #endif
@@ -3349,10 +3354,21 @@ void vnc_display_open(const char *id, Error **errp)
 if (!opts) {
 return;
 }
-display = qemu_opt_get(opts, "vnc");
-if (!display || strcmp(display, "none") == 0) {
+vnc = qemu_opt_get(opts, "vnc");
+if (!vnc || strcmp(vnc, "none") == 0) {
 return;
 }
+
+has_to = qemu_opt_get(opts, "to");
+if (has_to) {
+to = g_strdup_printf(",to=%s", has_to);
+}
+has_ipv4 = qemu_opt_get_bool(opts, "ipv4", false);
+has_ipv6 = qemu_opt_get_bool(opts, "ipv6", false);
+display = g_strdup_printf("%s%s%s%s", vnc,
+  has_to ? to : "",
+  has_ipv4 ? ",ipv4" : "",
+  has_ipv6 ? ",ipv6" : "");
 vs->display = g_strdup(display);
 
 password = qemu_opt_get_bool(opts, "password", false);
@@ -3632,6 +3648,8 @@ void vnc_display_open(const char *id, Error **errp)
 }
 #endif /* CONFIG_VNC_WS */
 }
+g_free(to);
+g_free(display);
 g_free(vs->display);
 vs->display = dpy;
 qemu_set_fd_handler2(vs->lsock, NULL,
@@ -3646,6 +3664,8 @@ void vnc_display_open(const char *id, Error **errp)
 return;
 
 fail:
+g_free(to);
+g_free(display);
 g_free(vs->display);
 vs->display = NULL;
 #ifdef CONFIG_VNC_WS
-- 
1.7.12.4





[Qemu-devel] [PATCH 0/3] fix qemu crash about vnc

2015-01-29 Thread arei.gonglei
From: Gonglei 

Reproducer:
$ x86_64-softmmu/qemu-system-x86_64
qemu-system-x86_64: Invalid parameter 'to'
Segmentation fault (core dumped)

Patch 1~2 is bugfix, patch 3 is trivial.

Gonglei (3):
  vnc: fix qemu crash when not configure vnc option
  vnc: correct missing property about vnc_display
  vnc: using bool type instead of int for QEMU_OPT_BOOL

 ui/vnc.c | 45 +
 1 file changed, 37 insertions(+), 8 deletions(-)

-- 
1.7.12.4





[Qemu-devel] [PATCH 1/3] vnc: fix qemu crash when not configure vnc option

2015-01-29 Thread arei.gonglei
From: Gonglei 

Reproducer:
$ x86_64-softmmu/qemu-system-x86_64
qemu-system-x86_64: Invalid parameter 'to'
Segmentation fault (core dumped)

Signed-off-by: Gonglei 
---
 ui/vnc.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/ui/vnc.c b/ui/vnc.c
index a742c90..08b8b24 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3276,6 +3276,15 @@ static QemuOptsList qemu_vnc_opts = {
 .name = "connections",
 .type = QEMU_OPT_NUMBER,
 },{
+.name = "to",
+.type = QEMU_OPT_NUMBER,
+},{
+.name = "ipv4",
+.type = QEMU_OPT_BOOL,
+},{
+.name = "ipv6",
+.type = QEMU_OPT_BOOL,
+},{
 .name = "password",
 .type = QEMU_OPT_BOOL,
 },{
-- 
1.7.12.4





Re: [Qemu-devel] [RESEND PATCH v1 09/13] acpi, piix4: Add memory hot unplug support for piix4.

2015-01-29 Thread Igor Mammedov
On Thu, 8 Jan 2015 09:06:16 +0800
Tang Chen  wrote:

> Call memory unplug cb in piix4_device_unplug_cb().
> ---
>  hw/acpi/piix4.c | 12 ++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> index f809c3a..4ae4867 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -377,8 +377,16 @@ static void 
> piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
>  static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
> DeviceState *dev, Error **errp)
>  {
> -error_setg(errp, "acpi: device unplug for not supported device"
> -   " type: %s", object_get_typename(OBJECT(dev)));
> +PIIX4PMState *s = PIIX4_PM(hotplug_dev);
> +
> +if (s->acpi_memory_hotplug.is_enabled &&
is above check really necessary? If yes, do it inside common 
acpi_memory_unplug_cb()

> +object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> +acpi_memory_unplug_cb(&s->ar, s->irq, &s->acpi_memory_hotplug,
> +  dev, errp);
> +} else {
> +error_setg(errp, "acpi: device unplug for not supported device"
> +   " type: %s", object_get_typename(OBJECT(dev)));
> +}
>  }
>  
>  static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque)




Re: [Qemu-devel] [PATCH 2/2] hw/ppc/spapr Add qemu_register_boot_set for SPAPR

2015-01-29 Thread Alexander Graf


On 29.01.15 04:46, Gonglei wrote:
> On 2015/1/29 8:42, Alexander Graf wrote:
> 
>>
>>
>> On 29.01.15 01:40, Gonglei wrote:
>>> On 2015/1/26 17:35, Alexander Graf wrote:
>>>
 On 01/26/2015 11:49 AM, Dinar Valeev wrote:
> On 01/24/2015 12:04 AM, Alexander Graf wrote:
>>
>>
>> On 23.01.15 23:51, dval...@suse.de wrote:
>>> From: Dinar Valeev 
>>>
>>> In order to have -boot once=d functioning, it is required to have
>>> qemu_register_boot_set
>>>
>>> qemu-system-ppc64 -enable-kvm -boot once=d
>>>
>>> Ready!
>>> 0 > dev /chosen   ok
>>> 0 > .properties
>>> ...
>>> qemu,boot-device d
>>> ...
>>> 0 > reset-all
>>>
>>> Ready!
>>> 0 > dev /chosen   ok
>>> 0 > .properties
>>> ...
>>> qemu,boot-device cdn
>>> ...
>>>
>>> Signed-off-by: Dinar Valeev 
>>> ---
>>>   hw/ppc/spapr.c | 12 
>>>   1 file changed, 12 insertions(+)
>>>
>>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>>> index 3d2cfa3..38b03fc 100644
>>> --- a/hw/ppc/spapr.c
>>> +++ b/hw/ppc/spapr.c
>>> @@ -314,6 +314,16 @@ static void add_str(GString *s, const gchar *s1)
>>>   g_string_append_len(s, s1, strlen(s1) + 1);
>>>   }
>>>
>>> +static void spapr_boot_set(void *opaque, const char *boot_device,
>>> +   Error **errp)
>>> +{
>>> +int offset;
>>> +offset = fdt_path_offset(opaque, "/chosen");
>>> +fdt_setprop_string(opaque, offset, "qemu,boot-device", 
>>> boot_device);
>>> +
>>> +}
>>> +
>>> +
>>>   static void *spapr_create_fdt_skel(hwaddr initrd_base,
>>>  hwaddr initrd_size,
>>>  hwaddr kernel_size,
>>> @@ -414,6 +424,8 @@ static void *spapr_create_fdt_skel(hwaddr 
>>> initrd_base,
>>>   if (boot_device) {
>>>   _FDT((fdt_property_string(fdt, "qemu,boot-device", 
>>> boot_device)));
>>>   }
>>> +qemu_register_boot_set(spapr_boot_set, fdt);
>>
>> If you simply move the code above (the _FDT() one) from create_fdt_skel
>> to spapr_finalize_fdt() you should have the same net effect and much
>> cleaner code :).
> I've tried your proposal, on reset boot-device property stays "d"

 Ugh, the machine field doesn't change on reset. I think it'd be a lot more 
 intuitive if it did. Can you try with the patch below applied as well?

>>>
>>> This approach is not good because boot_set_handler is NULL and return error 
>>> directly.
>>> Please using qemu_register_boot_set for this purpose.
>>
>> I'd personally prefer if we get rid of qemu_register_boot_set
>> completely. It duplicates the reset logic as well as information holder
>> locality (machine struct vs parameter).
>>
> 
> Maybe yes. But lots of other machines do not  register
> reset callback. So those machines using qemu_register_boot_set()
> register a handler callback achieve this purpose.

I think we're better off just registering reset handlers then.


Alex



  1   2   3   >