Re: [Qemu-devel] [PATCH v2 0/2] hw/i386: Update FADT to Revision 3 (ACPI 2.0)

2017-03-11 Thread no-reply
Hi,

This series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Type: series
Subject: [Qemu-devel] [PATCH v2 0/2] hw/i386: Update FADT to Revision 3 (ACPI 
2.0)
Message-id: 1489298291-25154-1-git-send-email-p...@philjordan.eu

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=16
make docker-test-quick@centos6
make docker-test-mingw@fedora
make docker-test-build@min-glib
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
8ced515 hw/i386: Build-time assertion on pc/q35 reset register being identical.
61f42cf hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to improve guest OS 
support.

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out 'fa8bc7f928ac25f23532afc8beb2073efc8fb063'
  BUILD   centos6
make[1]: Entering directory `/var/tmp/patchew-tester-tmp-c8855z5b/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPYRUNNER
RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
gcc-4.4.7-17.el6.x86_64
git-1.7.1-4.el6_7.1.x86_64
glib2-devel-2.28.8-5.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=libfdt-devel ccache tar git make gcc g++ zlib-devel 
glib2-devel SDL-devel pixman-devel epel-release
HOSTNAME=3e9c368bf5ae
TERM=xterm
MAKEFLAGS= -j16
HISTSIZE=1000
J=16
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu 
--prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix/var/tmp/qemu-build/install
BIOS directory/var/tmp/qemu-build/install/share/qemu
binary directory  /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory  /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory  /var/tmp/qemu-build/install/etc
local state directory   /var/tmp/qemu-build/install/var
Manual directory  /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path   /tmp/qemu-test/src
C compilercc
Host C compiler   cc
C++ compiler  
Objective-C compiler cc
ARFLAGS   rv
CFLAGS-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS   -I/usr/include/pixman-1   -I$(SRC_PATH)/dtc/libfdt -pthread 
-I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -fPIE -DPIE -m64 -mcx16 
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes 
-Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes 
-fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels 
-Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security 
-Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration 
-Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS   -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make  make
install   install
pythonpython -B
smbd  /usr/sbin/smbd
module supportno
host CPU  x86_64
host big endian   no
target list   x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled no
sparse enabledno
strip binariesyes
profiler  no
static build  no
pixmansystem
SDL support   yes (1.2.14)
GTK support   no 
GTK GL supportno
VTE support   no 
TLS priority  NORMAL
GNUTLS supportno
GNUTLS rndno
libgcrypt no
libgcrypt kdf no
nettleno 
nettle kdfno
libtasn1  no
curses supportno
virgl support no
curl support  no
mingw32 support   no
Audio drivers oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS supportno
VNC support   yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support   no
brlapi supportno
bluez  supportno
Documentation no
PIE   yes
vde support   no
netmap supportno
Linux AIO support no
ATTR/XATTR support yes
Install blobs yes
KVM support   yes
HAX support   no
RDMA suppo

[Qemu-devel] [PATCH v2 2/2] hw/i386: Build-time assertion on pc/q35 reset register being identical.

2017-03-11 Thread Phil Dennis-Jordan
This adds a clarifying comment and build time assert to the FADT reset register 
field initialisation: the reset register is the same on both machine types.

Signed-off-by: Phil Dennis-Jordan 
---
 hw/i386/acpi-build.c | 3 +++
 hw/pci-host/piix.c   | 6 --
 include/hw/i386/pc.h | 6 ++
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 7997f06..1d8c645 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -310,6 +310,9 @@ static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, 
AcpiPmInfo *pm)
 fadt->reset_register.space_id = AML_SYSTEM_IO;
 fadt->reset_register.bit_width = 8;
 fadt->reset_register.address = cpu_to_le64(ICH9_RST_CNT_IOPORT);
+/* The above need not be conditional on machine type because the reset port
+ * happens to be the same on PIIX (pc) and ICH9 (q35). */
+QEMU_BUILD_BUG_ON(ICH9_RST_CNT_IOPORT != RCR_IOPORT);
 
 fadt->xpm1a_event_block.space_id = AML_SYSTEM_IO;
 fadt->xpm1a_event_block.bit_width = fadt->pm1_evt_len * 8;
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index f9218aa..bf4221d 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -58,12 +58,6 @@ typedef struct I440FXState {
 #define XEN_PIIX_NUM_PIRQS  128ULL
 #define PIIX_PIRQC  0x60
 
-/*
- * Reset Control Register: PCI-accessible ISA-Compatible Register at address
- * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
- */
-#define RCR_IOPORT 0xcf9
-
 typedef struct PIIX3State {
 PCIDevice dev;
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index ab303c7..10cb55f 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -303,6 +303,12 @@ typedef struct PCII440FXState PCII440FXState;
 
 #define TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE "igd-passthrough-i440FX"
 
+/*
+ * Reset Control Register: PCI-accessible ISA-Compatible Register at address
+ * 0xcf9, provided by the PCI/ISA bridge (PIIX3 PCI function 0, 8086:7000).
+ */
+#define RCR_IOPORT 0xcf9
+
 PCIBus *i440fx_init(const char *host_type, const char *pci_type,
 PCII440FXState **pi440fx_state, int *piix_devfn,
 ISABus **isa_bus, qemu_irq *pic,
-- 
2.3.2 (Apple Git-55)




[Qemu-devel] [PATCH v2 1/2] hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to improve guest OS support.

2017-03-11 Thread Phil Dennis-Jordan
This updates the FADT generated for x86/64 machine types from Revision 1 to 3. 
(Based on ACPI standard 2.0 instead of 1.0) The intention is to expose the 
reset register information to guest operating systems which require it, 
specifically OS X/macOS. Revision 1 FADTs do not contain the fields relating to 
the reset register.

The new layout and contents remains backwards-compatible with operating systems 
which only support ACPI 1.0, as the existing fields are not modified by this 
change, as the 64-bit and 32-bit variants are allowed to co-exist according to 
the ACPI 2.0 standard. No regressions became apparent in tests with a range of 
Windows (XP-10) and Linux versions.

Signed-off-by: Phil Dennis-Jordan 
---
 hw/i386/acpi-build.c| 32 +--
 include/hw/acpi/acpi-defs.h | 77 +
 tests/bios-tables-test.c|  4 +--
 3 files changed, 67 insertions(+), 46 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 2073108..7997f06 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -272,7 +272,7 @@ build_facs(GArray *table_data, BIOSLinker *linker)
 }
 
 /* Load chipset information in FADT */
-static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
+static void fadt_setup(AcpiFadtDescriptorRev3 *fadt, AcpiPmInfo *pm)
 {
 fadt->model = 1;
 fadt->reserved1 = 0;
@@ -304,6 +304,28 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, 
AcpiPmInfo *pm)
 fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
 }
 fadt->century = RTC_CENTURY;
+
+fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_RESET_REG_SUP);
+fadt->reset_value = 0xf;
+fadt->reset_register.space_id = AML_SYSTEM_IO;
+fadt->reset_register.bit_width = 8;
+fadt->reset_register.address = cpu_to_le64(ICH9_RST_CNT_IOPORT);
+
+fadt->xpm1a_event_block.space_id = AML_SYSTEM_IO;
+fadt->xpm1a_event_block.bit_width = fadt->pm1_evt_len * 8;
+fadt->xpm1a_event_block.address = cpu_to_le64(pm->io_base);
+
+fadt->xpm1a_control_block.space_id = AML_SYSTEM_IO;
+fadt->xpm1a_control_block.bit_width = fadt->pm1_cnt_len * 8;
+fadt->xpm1a_control_block.address = cpu_to_le64(pm->io_base + 0x4);
+
+fadt->xpm_timer_block.space_id = AML_SYSTEM_IO;
+fadt->xpm_timer_block.bit_width = fadt->pm_tmr_len * 8;
+fadt->xpm_timer_block.address = cpu_to_le64(pm->io_base + 0x8);
+
+fadt->xgpe0_block.space_id = AML_SYSTEM_IO;
+fadt->xgpe0_block.bit_width = pm->gpe0_blk_len * 8;
+fadt->xgpe0_block.address = cpu_to_le64(pm->gpe0_blk);
 }
 
 
@@ -313,9 +335,10 @@ build_fadt(GArray *table_data, BIOSLinker *linker, 
AcpiPmInfo *pm,
unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
const char *oem_id, const char *oem_table_id)
 {
-AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+AcpiFadtDescriptorRev3 *fadt = acpi_data_push(table_data, sizeof(*fadt));
 unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
 unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
+unsigned xdsdt_entry_offset = (char *)&fadt->Xdsdt - table_data->data;
 
 /* FACS address to be filled by Guest linker */
 bios_linker_loader_add_pointer(linker,
@@ -327,9 +350,12 @@ build_fadt(GArray *table_data, BIOSLinker *linker, 
AcpiPmInfo *pm,
 bios_linker_loader_add_pointer(linker,
 ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
 ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
+bios_linker_loader_add_pointer(linker,
+ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->Xdsdt),
+ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
 
 build_header(linker, table_data,
- (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
+ (void *)fadt, "FACP", sizeof(*fadt), 3, oem_id, oem_table_id);
 }
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 4cc3630..293ee45 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -131,17 +131,37 @@ typedef struct AcpiTableHeader AcpiTableHeader;
 uint8_t  duty_width;   /* Bit width of duty cycle field in p_cnt reg */ \
 uint8_t  day_alrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \
 uint8_t  mon_alrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \
-uint8_t  century;  /* Index to century in RTC CMOS RAM */
-
-struct AcpiFadtDescriptorRev1
-{
-ACPI_FADT_COMMON_DEF
-uint8_t  reserved4;  /* Reserved */
-uint8_t  reserved4a; /* Reserved */
-uint8_t  reserved4b; /* Reserved */
-uint32_t flags;
-} QEMU_PACKED;
-typedef struct AcpiFadtDescriptorRev1 AcpiFadtDescriptorRev1;
+uint8_t  century;  /* Index to century in RTC CMOS RAM */ \
+/* IA-PC Boot Architecture Flags (see below for individual fl

[Qemu-devel] [PATCH v2 0/2] hw/i386: Update FADT to Revision 3 (ACPI 2.0)

2017-03-11 Thread Phil Dennis-Jordan
This updates the FADT generated for x86/64 machine types from Revision 1 to 3. 
(Based on ACPI standard 2.0 instead of 1.0) As previously, the goal is to make 
running macOS/OS X guests smoother. With a Rev1 FADT, rebooting such a guest 
doesn't work, as the OS uses the reset register information from the FADT. 
Switching to a Rev3 (ACPI 2.0) FADT solves this problem.

The previous discussion of this raised a bunch of points, which I'll 
address/clarify here as well:

 1. No runtime option. The preference was expressed that we try to stay 
backwards-compatible with legacy guests as opposed to adding a runtime option 
for different APCI versions. ACPI 2.0/FADT Rev3 is the minimum version required 
for exposing the reset register, and it is also backwards-compatible with 
1.0/Rev1, so that seemed a good version to target.

 2. Legacy guest testing. I've tested this successfully (no apparent 
regressions) with:
   * Windows XP x86 (both "pc" and "q35" machine types, the latter using 
-device piix4-ide)
   * Windows 7, both 32-bit and 64-bit editions
   * Windows 10 x64
   * Fedora 7 x86 Live image
   * Fedora 25 x86_64 Live image
   * Ubuntu 10.04.4 AMD64 Live image
Any other specific OSes and versions I should check?


 3. 64-bit and 32-bit pointer fields.

Only very recent versions of the ACPI spec (6.1 and various errata of 5.1 and 
6.0) are clear about mutual exclusion of the FADT's 32-bit and 64-bit variants 
of pointers to tables and registers. The 2.0 version simply states "This is a 
required field" for both PM1a_EVT_BLK and X_PM1a_EVT_BLK, for example, although 
it does also state for the former that "This field is superseded in ACPI 2.0 by 
the X_PM1a_EVT_BLK field." No requirement is specified explicitly for the DSDT 
and X_DSDT fields.

In practice, I have found that Windows 10 will fail to boot with a Rev3 FADT 
unless BOTH the 32-bit and 64-bit variants are filled. The exception is 
X_FIRMWARE_CTRL, which is the first to be explicitly marked as mutually 
exclusive with FIRMWARE_CTRL in an ACPI spec - with a preference for 
FIRMWARE_CTRL if the pointer fits in a 32-bit field. Satisfying Windows 10 in 
this way does not contradict the 2.0 specification, and it also complies with 
the 1.0 standard for the fields which Rev1 of the FADT already has, so that's 
what I've gone with in the implementation.

The only problem is that upstream OVMF cannot deal with multiple pointers to 
the same table in the linker commands. This turns out to be a bug in 
OVMF/EDK2[1], and I am submitting a separate patch to EDK2 to fix that problem. 
The fix for a second issue where OVMF would rewrite the FADT so the DSDT is 
erroneously set to 0 has already been upstreamed.[2] I don't see a workaround 
to this other than fixing the OVMF code.

 4. i440FX vs Q35

Both machine types have the reset register, and it's at the same I/O port. To 
illustrate/document this, the second patch in the series adds a build-time 
assertion that this is indeed so.

Changelog
=

v1 -> v2:
 * v1 Thread was "[PATCH RFC] acpi: add reset register to fadt"
 * Instead of just adding the reset register, set up a fully standards 
compliant Rev3 FADT. (ACPI 2.0)
 * A compile-time assertion has been added for the PC/Q35 reset register 
equivalence.


[1]: https://bugzilla.tianocore.org/show_bug.cgi?id=368
[2]: EDK2 commit range e0e1cfcbbb24..198a46d768fb


Phil Dennis-Jordan (2):
  hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to improve guest OS
support.
  hw/i386: Build-time assertion on pc/q35 reset register being
identical.

 hw/i386/acpi-build.c| 35 +++--
 hw/pci-host/piix.c  |  6 
 include/hw/acpi/acpi-defs.h | 77 +
 include/hw/i386/pc.h|  6 
 tests/bios-tables-test.c|  4 +--
 5 files changed, 76 insertions(+), 52 deletions(-)

-- 
2.3.2 (Apple Git-55)




[Qemu-devel] [PATCH Risu v2 0/3] PPC64 Improvements

2017-03-11 Thread G 3


On Mar 9, 2017, at 3:08 PM, qemu-devel-requ...@nongnu.org wrote:



v2:
 - applied code review

This patchset include initial support to PPC64 (Big-Endian), that  
is pretty

much the same: only some fixes in configure and risugen.
Also, it adds a better random initialization of VSX registers.

Jose Ricardo Ziviani (3):
  risugen_ppc64: Load random 128-bit data to VSX registers
  configure: Add initial support to PPC64 (big endian)
  risugen,risugen_ppc64.pm: Add support ppc64 (big-endian)

 configure|  9 -
 risugen  |  6 +-
 risugen_ppc64.pm | 44 +---
 3 files changed, 42 insertions(+), 17 deletions(-)

--
2.7.4


Would this patch set work with the IBM PowerPC 970 (G5) CPU?



[Qemu-devel] Risu and the PowerPC 970

2017-03-11 Thread G 3
Does Risu support the PowerPC 970? I tried compiling it but I saw  
this error:


gcc  -Wall -D_GNU_SOURCE -DARCH=ppc64 -g  -o risu.o -c risu.c
In file included from risu.c:29:
risu.h:27:30: error: risu_reginfo_ppc64.h: No such file or directory
make: *** [Makefile:44: risu.o] Error 1

The PowerPC 970 is a 64-bit PowerPC CPU.

My configure line:
ARCH=ppc64 ./configure

I cloned Risu from here:
https://git.linaro.org/people/peter.maydell/risu.git





[Qemu-devel] [Bug 597362] Re: qemu-system-sparc singlestep not work in gdbstub

2017-03-11 Thread Launchpad Bug Tracker
[Expired for QEMU because there has been no activity for 60 days.]

** Changed in: qemu
   Status: Incomplete => Expired

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/597362

Title:
  qemu-system-sparc singlestep not work in gdbstub

Status in QEMU:
  Expired

Bug description:
  Debugging with gdb-stub does not work with qemu-system-sparc target

  Qemu compiled from current git tree.

  execution string: qemu-system-sparc.exe -s -S -m 256 -L Bios -hda
  sparc.img -boot c
  connect with telnet localhost 1234
  enter '$s#73' (without quotes, this is single step command to gdb stub)
  gdb stub reply '+' (without quotes, as it accept command)
  After this qemu continuously execute instructions in single step mode
  and does not exit to gdb stub after each executed instruction with
  interrupt signal
  ("T%02xthread:%02x;" /gdb_vm_state_change in gdbstub.c/ );

  If we look at target-sparc/translate.c, we can see that
  gen_helper_debug() is not called in single step mode:

  
  if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
  (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
  !s->singlestep)  {
  /* jump to same page: we can use a direct jump */
  tcg_gen_goto_tb(tb_num);
  tcg_gen_movi_tl(cpu_pc, pc);
  tcg_gen_movi_tl(cpu_npc, npc);
  tcg_gen_exit_tb((long)tb + tb_num);
  } else {
  /* jump to another page: currently not optimized */
  tcg_gen_movi_tl(cpu_pc, pc);
  tcg_gen_movi_tl(cpu_npc, npc);
  tcg_gen_exit_tb(0);
  }
  =

  
  /* if single step mode, we generate only one instruction and
 generate an exception */
  if (dc->singlestep) {
  break;
  }
  

  If we look similar code at target-sh4/translate.c we can see that is
  called in this cases:

  
  if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
!ctx->singlestep_enabled) {
/* Use a direct jump if in same page and singlestep not enabled */
  tcg_gen_goto_tb(n);
  tcg_gen_movi_i32(cpu_pc, dest);
  tcg_gen_exit_tb((long) tb + n);
  } else {
  tcg_gen_movi_i32(cpu_pc, dest);
  if (ctx->singlestep_enabled)
  gen_helper_debug();
  tcg_gen_exit_tb(0);
  }
  

  
  if (tb->cflags & CF_LAST_IO)
  gen_io_end();
  if (env->singlestep_enabled) {
  tcg_gen_movi_i32(cpu_pc, ctx.pc);
  gen_helper_debug();
  } else {
  ==

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/597362/+subscriptions



Re: [Qemu-devel] [PATCH v7 kernel 3/5] virtio-balloon: implementation of VIRTIO_BALLOON_F_CHUNK_TRANSFER

2017-03-11 Thread Michael S. Tsirkin
On Sun, Mar 12, 2017 at 01:59:54AM +, Wang, Wei W wrote:
> On 03/11/2017 10:10 PM, Matthew Wilcox wrote:
> > On Sat, Mar 11, 2017 at 07:59:31PM +0800, Wei Wang wrote:
> > > I'm thinking what if the guest needs to transfer these much physically
> > > continuous memory to host: 1GB+2MB+64KB+32KB+16KB+4KB.
> > > Is it going to use Six 64-bit chunks? Would it be simpler if we just
> > > use the 128-bit chunk format (we can drop the previous normal 64-bit
> > > format)?
> > 
> > Is that a likely thing for the guest to need to do though?  Freeing a 1GB 
> > page is
> > much more liikely, IMO.
> 
> Yes, I think it's very possible. The host can ask for any number of pages 
> (e.g. 1.5GB) that the guest can afford.  Also, the ballooned 1.5G memory is 
> not guaranteed to be continuous in any pattern like 1GB+512MB. That's why we 
> need to use a bitmap to draw the whole picture first, and then seek for 
> continuous bits to chunk.
> 
> Best,
> Wei

While I like the clever format that Matthew came up with, I'm also
inclined to say let's keep things simple.
the simplest thing seems to be to use the ext format all the time.
Except let's reserve the low 12 bits in both address and size,
since they are already 0, we might be able to use them for flags down the road.

-- 
MST



Re: [Qemu-devel] Incorrect memory region address with large 64-bit PCI BARs

2017-03-11 Thread Michael S. Tsirkin
On Sun, Mar 12, 2017 at 03:46:57AM +0200, Michael S. Tsirkin wrote:
> On Sat, Mar 11, 2017 at 10:37:09AM +, Mark Cave-Ayland wrote:
> > I've been looking at an issue with virtio BARs being mapped incorrectly
> > on qemu-system-sparc64, and as part of this investigation found that
> > some 64-bit PCI BAR memory regions don't appear correctly in "info mtree".
> > 
> > The easiest way to see this is to launch QEMU as below and then check
> > the output of "info mtree":
> > 
> > ./qemu-system-sparc64 -device virtio-net-pci
> > 
> > The interesting part is this:
> > 
> > > address-space: memory
> > >   - (prio 0, i/o): system
> > > -07ff (prio 0, ram): sun4u.ram
> > > 01fe-01fe (prio 0, i/o): apb-config
> > > 01fe0100-01fe01ff (prio 0, i/o): apb-pci-config
> > > 01fe0200-01fe0200 (prio 0, i/o): alias apb-pci ioport 
> > > @io -
> > > 01ff-01ff (prio 0, i/o): pci-mmio
> > >   01ff-01ff000f (prio 1, i/o): alias 
> > > pci_bridge_mem @pci_bridge_pci -000f
> > >   01ff-01ff000f (prio 1, i/o): alias 
> > > pci_bridge_pref_mem @pci_bridge_pci -000f
> > >   01ff-01ff000f (prio 1, i/o): alias 
> > > pci_bridge_mem @pci_bridge_pci -000f
> > >   01ff-01ff000f (prio 1, i/o): alias 
> > > pci_bridge_pref_mem @pci_bridge_pci -000f
> > >   01ff000a-01ff000a (prio 2, i/o): alias vga.chain4 
> > > @vga.vram -
> > >   01ff000a-01ff000b (prio 1, i/o): vga-lowmem
> > >   01ff0100-01ff01ff (prio 1, ram): vga.vram
> > >   01ff0200-01ff02000fff (prio 1, i/o): vga.mmio
> > > 01ff02000400-01ff0200041f (prio 0, i/o): vga ioports 
> > > remapped
> > > 01ff02000500-01ff02000515 (prio 0, i/o): bochs dispi 
> > > interface
> > > 01ff02000600-01ff02000607 (prio 0, i/o): qemu extended 
> > > regs
> > >   01ff0201-01ff0201 (prio 1, rom): vga.rom
> > >   01ff0300-01ff03ff (prio 1, i/o): alias bar0 @io 
> > > -00ff
> > >   01ff0400-01ff0403 (prio 1, rom): ne2000.rom
> > >   01ff0408-01ff040b (prio 1, rom): virtio-net-pci.rom
> > >   01fe0404-01fe04043fff (prio 1, i/o): virtio-pci
> > ^
> > 
> > Here virtio-pci is mapped to address 0x1fe0404 even though its
> > parent pci-mmio memory region is at 0x1ff.
> > 
> > > 01fe0404-01fe04040fff (prio 0, i/o): virtio-pci-common
> > > 01fe04041000-01fe04041fff (prio 0, i/o): virtio-pci-isr
> > > 01fe04042000-01fe04042fff (prio 0, i/o): virtio-pci-device
> > > 01fe04043000-01fe04043fff (prio 0, i/o): virtio-pci-notify
> > > 01fff000-01fff03f (prio 0, rom): sun4u.prom
> > 
> > The bug in the current OpenBIOS is that 64-bit BARs are incorrectly
> > identified, and so the BAR MSB register is set to 0x to detect
> > the size as per a standard 32-bit BAR. At this point OpenBIOS detects
> > something is wrong and aborts, leaving the 64-bit BAR set to 0x
> > 0x0404.
> > 
> > This is accurately reflected in the virtio-pci memory region itself, i.e.
> > 
> > > memory-region: virtio-pci
> > >   0404-04043fff (prio 1, i/o): virtio-pci
> > > 0404-04040fff (prio 0, i/o): virtio-pci-common
> > > 04041000-04041fff (prio 0, i/o): virtio-pci-isr
> > > 04042000-04042fff (prio 0, i/o): virtio-pci-device
> > > 04043000-04043fff (prio 0, i/o): virtio-pci-notify
> > 
> > But as you can see above the overall effect is that the virtio-pci
> > device ends up somehow being mapped outside (and indeed, before the
> > start of) its parent memory region.
> 
> And specifically we have:
> 
> 01ff + 0404 = 01fe04043000
> 
> which seems to be where this is coming from.
> 
> It does have to indicate some kind of modelling problem:
> since it looks like on sparc BAR is an offset within
> PCI MMIO region, I would expect an offset value bigger than 
> the region size not to be visible.
> 
> Specifically documentation states:
> 
> - all direct subregions of the root region are matched against the address, in
>   descending priority order
>   - if the address lies outside the region offset/size, the subregion is
> discarded
> 

After looking at it some more, I think the issue is merely with how info
mtree presents information, which confuses instead of helping when
overlap triggers. Sp

Re: [Qemu-devel] [PATCH v7 kernel 3/5] virtio-balloon: implementation of VIRTIO_BALLOON_F_CHUNK_TRANSFER

2017-03-11 Thread Wang, Wei W
On 03/11/2017 10:10 PM, Matthew Wilcox wrote:
> On Sat, Mar 11, 2017 at 07:59:31PM +0800, Wei Wang wrote:
> > I'm thinking what if the guest needs to transfer these much physically
> > continuous memory to host: 1GB+2MB+64KB+32KB+16KB+4KB.
> > Is it going to use Six 64-bit chunks? Would it be simpler if we just
> > use the 128-bit chunk format (we can drop the previous normal 64-bit
> > format)?
> 
> Is that a likely thing for the guest to need to do though?  Freeing a 1GB 
> page is
> much more liikely, IMO.

Yes, I think it's very possible. The host can ask for any number of pages (e.g. 
1.5GB) that the guest can afford.  Also, the ballooned 1.5G memory is not 
guaranteed to be continuous in any pattern like 1GB+512MB. That's why we need 
to use a bitmap to draw the whole picture first, and then seek for continuous 
bits to chunk.

Best,
Wei



Re: [Qemu-devel] Incorrect memory region address with large 64-bit PCI BARs

2017-03-11 Thread Michael S. Tsirkin
On Sat, Mar 11, 2017 at 10:37:09AM +, Mark Cave-Ayland wrote:
> I've been looking at an issue with virtio BARs being mapped incorrectly
> on qemu-system-sparc64, and as part of this investigation found that
> some 64-bit PCI BAR memory regions don't appear correctly in "info mtree".
> 
> The easiest way to see this is to launch QEMU as below and then check
> the output of "info mtree":
> 
> ./qemu-system-sparc64 -device virtio-net-pci
> 
> The interesting part is this:
> 
> > address-space: memory
> >   - (prio 0, i/o): system
> > -07ff (prio 0, ram): sun4u.ram
> > 01fe-01fe (prio 0, i/o): apb-config
> > 01fe0100-01fe01ff (prio 0, i/o): apb-pci-config
> > 01fe0200-01fe0200 (prio 0, i/o): alias apb-pci ioport 
> > @io -
> > 01ff-01ff (prio 0, i/o): pci-mmio
> >   01ff-01ff000f (prio 1, i/o): alias pci_bridge_mem 
> > @pci_bridge_pci -000f
> >   01ff-01ff000f (prio 1, i/o): alias 
> > pci_bridge_pref_mem @pci_bridge_pci -000f
> >   01ff-01ff000f (prio 1, i/o): alias pci_bridge_mem 
> > @pci_bridge_pci -000f
> >   01ff-01ff000f (prio 1, i/o): alias 
> > pci_bridge_pref_mem @pci_bridge_pci -000f
> >   01ff000a-01ff000a (prio 2, i/o): alias vga.chain4 
> > @vga.vram -
> >   01ff000a-01ff000b (prio 1, i/o): vga-lowmem
> >   01ff0100-01ff01ff (prio 1, ram): vga.vram
> >   01ff0200-01ff02000fff (prio 1, i/o): vga.mmio
> > 01ff02000400-01ff0200041f (prio 0, i/o): vga ioports 
> > remapped
> > 01ff02000500-01ff02000515 (prio 0, i/o): bochs dispi 
> > interface
> > 01ff02000600-01ff02000607 (prio 0, i/o): qemu extended regs
> >   01ff0201-01ff0201 (prio 1, rom): vga.rom
> >   01ff0300-01ff03ff (prio 1, i/o): alias bar0 @io 
> > -00ff
> >   01ff0400-01ff0403 (prio 1, rom): ne2000.rom
> >   01ff0408-01ff040b (prio 1, rom): virtio-net-pci.rom
> >   01fe0404-01fe04043fff (prio 1, i/o): virtio-pci
> ^
> 
> Here virtio-pci is mapped to address 0x1fe0404 even though its
> parent pci-mmio memory region is at 0x1ff.
> 
> > 01fe0404-01fe04040fff (prio 0, i/o): virtio-pci-common
> > 01fe04041000-01fe04041fff (prio 0, i/o): virtio-pci-isr
> > 01fe04042000-01fe04042fff (prio 0, i/o): virtio-pci-device
> > 01fe04043000-01fe04043fff (prio 0, i/o): virtio-pci-notify
> > 01fff000-01fff03f (prio 0, rom): sun4u.prom
> 
> The bug in the current OpenBIOS is that 64-bit BARs are incorrectly
> identified, and so the BAR MSB register is set to 0x to detect
> the size as per a standard 32-bit BAR. At this point OpenBIOS detects
> something is wrong and aborts, leaving the 64-bit BAR set to 0x
> 0x0404.
> 
> This is accurately reflected in the virtio-pci memory region itself, i.e.
> 
> > memory-region: virtio-pci
> >   0404-04043fff (prio 1, i/o): virtio-pci
> > 0404-04040fff (prio 0, i/o): virtio-pci-common
> > 04041000-04041fff (prio 0, i/o): virtio-pci-isr
> > 04042000-04042fff (prio 0, i/o): virtio-pci-device
> > 04043000-04043fff (prio 0, i/o): virtio-pci-notify
> 
> But as you can see above the overall effect is that the virtio-pci
> device ends up somehow being mapped outside (and indeed, before the
> start of) its parent memory region.

And specifically we have:

01ff + 0404 = 01fe04043000

which seems to be where this is coming from.

It does have to indicate some kind of modelling problem:
since it looks like on sparc BAR is an offset within
PCI MMIO region, I would expect an offset value bigger than 
the region size not to be visible.

Specifically documentation states:

- all direct subregions of the root region are matched against the address, in
  descending priority order
  - if the address lies outside the region offset/size, the subregion is
discarded



> Fixing the bug in OpenBIOS itself is fairly trivial, although it took
> much longer to diagnose due to the misleading output above. It does seem
> that something isn't quite right with the handling of the large 64-bit
> BARs in this case, so Michael suggested I email the list for further
> comment.
> 
> 
> ATB,
> 
> Mark.



Re: [Qemu-devel] [PATCH v7 kernel 3/5] virtio-balloon: implementation of VIRTIO_BALLOON_F_CHUNK_TRANSFER

2017-03-11 Thread Michael S. Tsirkin
On Sat, Mar 11, 2017 at 07:59:31PM +0800, Wei Wang wrote:
> On 03/11/2017 01:11 AM, Matthew Wilcox wrote:
> > On Fri, Mar 10, 2017 at 05:58:28PM +0200, Michael S. Tsirkin wrote:
> > > One of the issues of current balloon is the 4k page size
> > > assumption. For example if you free a huge page you
> > > have to split it up and pass 4k chunks to host.
> > > Quite often host can't free these 4k chunks at all (e.g.
> > > when it's using huge tlb fs).
> > > It's even sillier for architectures with base page size >4k.
> > I completely agree with you that we should be able to pass a hugepage
> > as a single chunk.  Also we shouldn't assume that host and guest have
> > the same page size.  I think we can come up with a scheme that actually
> > lets us encode that into a 64-bit word, something like this:
> > 
> > bit 0 clear => bits 1-11 encode a page count, bits 12-63 encode a PFN, page 
> > size 4k.
> > bit 0 set, bit 1 clear => bits 2-12 encode a page count, bits 13-63 encode 
> > a PFN, page size 8k
> > bits 0+1 set, bit 2 clear => bits 3-13 for page count, bits 14-63 for PFN, 
> > page size 16k.
> > bits 0-2 set, bit 3 clear => bits 4-14 for page count, bits 15-63 for PFN, 
> > page size 32k
> > bits 0-3 set, bit 4 clear => bits 5-15 for page count, bits 16-63 for PFN, 
> > page size 64k
> > 
> > That means we can always pass 2048 pages (of whatever page size) in a 
> > single chunk.  And
> > we support arbitrary power of two page sizes.  I suggest something like 
> > this:
> > 
> > u64 page_to_chunk(struct page *page)
> > {
> > u64 chunk = page_to_pfn(page) << PAGE_SHIFT;
> > chunk |= (1UL << compound_order(page)) - 1;
> > }
> > 
> > (note this is a single page of order N, so we leave the page count bits
> > set to 0, meaning one page).
> > 
> 
> I'm thinking what if the guest needs to transfer these much physically
> continuous
> memory to host: 1GB+2MB+64KB+32KB+16KB+4KB.
> Is it going to use Six 64-bit chunks? Would it be simpler if we just
> use the 128-bit chunk format (we can drop the previous normal 64-bit
> format)?
> 
> Best,
> Wei

I think I prefer that as a more straightforward approach, but
I can live with either approach.


-- 
MST



Re: [Qemu-devel] [PATCH v7 kernel 3/5] virtio-balloon: implementation of VIRTIO_BALLOON_F_CHUNK_TRANSFER

2017-03-11 Thread Michael S. Tsirkin
On Fri, Mar 10, 2017 at 01:25:41PM -0800, Matthew Wilcox wrote:
> On Fri, Mar 10, 2017 at 09:35:21PM +0200, Michael S. Tsirkin wrote:
> > > bit 0 clear => bits 1-11 encode a page count, bits 12-63 encode a PFN, 
> > > page size 4k.
> > > bit 0 set, bit 1 clear => bits 2-12 encode a page count, bits 13-63 
> > > encode a PFN, page size 8k
> > > bits 0+1 set, bit 2 clear => bits 3-13 for page count, bits 14-63 for 
> > > PFN, page size 16k.
> > > bits 0-2 set, bit 3 clear => bits 4-14 for page count, bits 15-63 for 
> > > PFN, page size 32k
> > > bits 0-3 set, bit 4 clear => bits 5-15 for page count, bits 16-63 for 
> > > PFN, page size 64k
> > > That means we can always pass 2048 pages (of whatever page size) in a 
> > > single chunk.  And
> > > we support arbitrary power of two page sizes.  I suggest something like 
> > > this:
> > > 
> > > u64 page_to_chunk(struct page *page)
> > > {
> > >   u64 chunk = page_to_pfn(page) << PAGE_SHIFT;
> > >   chunk |= (1UL << compound_order(page)) - 1;
> > > }
> > 
> > You need to fill in the size, do you not?
> 
> I think I did ... (1UL << compound_order(page)) - 1 sets the bottom
> N bits.  Bit N+1 will already be clear.  What am I missing?

This sets the order but not the number of pages.
For that you would do something like

chunk |= size << compound_order(page)

right?

> > > > - host should pass its base page size to guest
> > > >   this can be a separate patch and for now we can fall back on 12 bit 
> > > > if not there
> > > 
> > > With this encoding scheme, I don't think we need to do this?  As long as
> > > it's *at least* 12 bit, then we're fine.
> > 
> > I think we will still need something like this down the road.  The point
> > is that not all hosts are able to use 4k pages in a balloon.
> > So it's pointless for guest to pass 4k pages to such a host,
> > and we need host to tell guest the page size it needs.
> > 
> > However that's a separate feature that can wait until
> > another day.
> 
> Ah, the TRIM/DISCARD debate all over again ... should the guest batch
> up or should the host do that work ... probably easier to account it in
> the guest.  Might be better to frame it as 'balloon chunk size' rather than
> host page size as it might have nothing to do with the host page size.

Exactly.

> > > What per-chunk flags are you thinking would be useful?
> > 
> > Not entirely sure but I think would have been prudent to leave some free
> > if possible. Your encoding seems to use them all up, so be it.
> 
> We don't necessarily have to support 2048 pages in a single chunk.
> If it's worth reserving some bits, we can do that at the expense of
> reducing the maximum number of pages per chunk.

Well we can always change things with a feature bit ..
I'll leave this up to you and Wei.

-- 
MST



[Qemu-devel] [PATCH] target/xtensa: fix semihosting argc/argv implementation

2017-03-11 Thread Max Filippov
So far xtensa provides fixed dummy argc/argv for the corresponding
semihosting calls. Now that there are semihosting_get_argc and
semihosting_get_arg, use them to pass actual command line arguments
to guest.

Signed-off-by: Max Filippov 
---
 target/xtensa/xtensa-semi.c | 49 +
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c
index 370e365..a888a9d 100644
--- a/target/xtensa/xtensa-semi.c
+++ b/target/xtensa/xtensa-semi.c
@@ -28,6 +28,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/helper-proto.h"
+#include "exec/semihost.h"
 #include "qemu/log.h"
 
 enum {
@@ -261,28 +262,50 @@ void HELPER(simcall)(CPUXtensaState *env)
 break;
 
 case TARGET_SYS_argc:
-regs[2] = 1;
+regs[2] = semihosting_get_argc();
 regs[3] = 0;
 break;
 
 case TARGET_SYS_argv_sz:
-regs[2] = 128;
-regs[3] = 0;
+{
+int argc = semihosting_get_argc();
+int sz = (argc + 1) * sizeof(uint32_t);
+int i;
+
+for (i = 0; i < argc; ++i) {
+sz += 1 + strlen(semihosting_get_arg(i));
+}
+regs[2] = sz;
+regs[3] = 0;
+}
 break;
 
 case TARGET_SYS_argv:
 {
-struct Argv {
-uint32_t argptr[2];
-char text[120];
-} argv = {
-{0, 0},
-"test"
-};
-
-argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text));
+int argc = semihosting_get_argc();
+int str_offset = (argc + 1) * sizeof(uint32_t);
+int i;
+uint32_t argptr;
+
+for (i = 0; i < argc; ++i) {
+const char *str = semihosting_get_arg(i);
+int str_size = strlen(str) + 1;
+
+argptr = tswap32(regs[3] + str_offset);
+
+cpu_memory_rw_debug(cs,
+regs[3] + i * sizeof(uint32_t),
+(uint8_t *)&argptr, sizeof(argptr), 1);
+cpu_memory_rw_debug(cs,
+regs[3] + str_offset,
+(uint8_t *)str, str_size, 1);
+str_offset += str_size;
+}
+argptr = 0;
 cpu_memory_rw_debug(cs,
-regs[3], (uint8_t *)&argv, sizeof(argv), 1);
+regs[3] + i * sizeof(uint32_t),
+(uint8_t *)&argptr, sizeof(argptr), 1);
+regs[3] = 0;
 }
 break;
 
-- 
2.1.4




[Qemu-devel] [PATCH] target/xtensa: xtfpga: load DTB only when FDT support is enabled

2017-03-11 Thread Max Filippov
xtensa linux can use DTB but does not require it, so FDT support is not
a requirement for target/xtensa. Don't try to load DTB when FDT support
is not configured.

Signed-off-by: Max Filippov 
---
 hw/xtensa/xtfpga.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index dc6fdcc..11176e2 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -317,6 +317,7 @@ static void lx_init(const LxBoardDesc *board, MachineState 
*machine)
 cur_tagptr = put_tag(cur_tagptr, BP_TAG_COMMAND_LINE,
  strlen(kernel_cmdline) + 1, kernel_cmdline);
 }
+#ifdef CONFIG_FDT
 if (dtb_filename) {
 int fdt_size;
 void *fdt = load_device_tree(dtb_filename, &fdt_size);
@@ -332,6 +333,14 @@ static void lx_init(const LxBoardDesc *board, MachineState 
*machine)
  sizeof(dtb_addr), &dtb_addr);
 cur_lowmem = QEMU_ALIGN_UP(cur_lowmem + fdt_size, 4096);
 }
+#else
+if (dtb_filename) {
+error_report("could not load DTB '%s': "
+ "FDT support is not configured in QEMU",
+ dtb_filename);
+exit(EXIT_FAILURE);
+}
+#endif
 if (initrd_filename) {
 BpMemInfo initrd_location = { 0 };
 int initrd_size = load_ramdisk(initrd_filename, cur_lowmem,
-- 
2.1.4




Re: [Qemu-devel] [PATCH 1/3] linux-user: Restrict usage of sa_restorer

2017-03-11 Thread Richard Henderson

On 03/12/2017 07:02 AM, Richard Henderson wrote:

TARGET_ALPHA has KA_RESTORER, not sa_restorer.  The restorer value is passed to
sigaction in a 5th register argument.  Less than handy that qemu doesn't
distinguish the two structs...


I beg your pardon, we do -- they're just named confusingly.

target_old_sigaction/target_rt_sigaction vs target_sigaction.  The latter 
corresponds to the kernel's k_sigaction.



r~



Re: [Qemu-devel] [PATCH] linux-user: Fix TARGET_MAP* and TARGET_F_??LCK for hppa arch

2017-03-11 Thread Richard Henderson

On 03/12/2017 03:50 AM, Helge Deller wrote:

TARGET_MAP_TYPE needs to be 0x03 instead of 0x0f on the hppa
architecture, otherwise it conflicts with MAP_FIXED which is 0x04.

Add missing TARGET_MAP_STACK and TARGET_MAP_HUGETLB values.

Fix TARGET_F_RDLCK, TARGET_F_WRLCK and TARGET_F_UNLCK.

Signed-off-by: Helge Deller 


I applied the MAP_FIXED and TARGET_F_* parts separately in my tree.  I'd like 
to see what others think about the other MAP_* defines before including that.



r~



Re: [Qemu-devel] [PATCH] linux-user: Add TARGET_MAP_STACK and TARGET_MAP_HUGETLB for all remaining architectures

2017-03-11 Thread Richard Henderson

On 03/12/2017 04:30 AM, Helge Deller wrote:

Add the missing defines and for TARGET_MAP_STACK and TARGET_MAP_HUGETLB
for alpha, mips, ppc and x86, and fix the mmap_flags translation table
to translate those flags between host and target architecture.

Signed-off-by: Helge Deller 

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cec8428..03ed370 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5875,6 +5875,8 @@ static bitmask_transtbl mmap_flags_tbl[] = {
{ TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, MAP_NORESERVE,
   MAP_NORESERVE },
+   { TARGET_MAP_STACK, TARGET_MAP_STACK, MAP_STACK, MAP_STACK },
+   { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },


I don't see any point in this.  First, MAP_STACK is ignored by the kernel, and 
has been for some time.  Second, the size of huge pages varies widely between 
different targets, and we're not really able to map the sizes between guest and 
host.


I suppose we could pass it through and get lucky when the sizes do match.  But 
if they don't, is it better to succeed with small tlb entries or fail with -EINVAL?



r~



Re: [Qemu-devel] [PATCH 1/3] linux-user: Restrict usage of sa_restorer

2017-03-11 Thread Richard Henderson

On 03/12/2017 04:28 AM, Laurent Vivier wrote:

Le 11/03/2017 à 04:42, Richard Henderson a écrit :

Reading and writing to an sa_restorer member that isn't supposed to
exist corrupts user memory.  Introduce TARGET_ARCH_HAS_SA_RESTORER,
similar to the kernel's __ARCH_HAS_SA_RESTORER.

Reported-by: Helge Deller 
Signed-off-by: Richard Henderson 
---
 linux-user/signal.c   |  4 ++--
 linux-user/syscall_defs.h | 13 +
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index a67db04..c6b043b 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -777,7 +777,7 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 if (oact) {
 __put_user(k->_sa_handler, &oact->_sa_handler);
 __put_user(k->sa_flags, &oact->sa_flags);
-#if !defined(TARGET_MIPS)
+#ifdef TARGET_ARCH_HAS_SA_RESTORER
 __put_user(k->sa_restorer, &oact->sa_restorer);
 #endif
 /* Not swapped.  */
@@ -787,7 +787,7 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 /* FIXME: This is not threadsafe.  */
 __get_user(k->_sa_handler, &act->_sa_handler);
 __get_user(k->sa_flags, &act->sa_flags);
-#if !defined(TARGET_MIPS)
+#ifdef TARGET_ARCH_HAS_SA_RESTORER
 __get_user(k->sa_restorer, &act->sa_restorer);
 #endif
 /* To be swapped in target_to_host_sigset.  */
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 40c5027..8b1ad74 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -445,6 +445,7 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 #define TARGET_SA_RESTART  2u
 #define TARGET_SA_NODEFER  0x20u
 #define TARGET_SA_RESETHAND4u
+#define TARGET_ARCH_HAS_SA_RESTORER 1
 #elif defined(TARGET_MIPS)
 #define TARGET_SA_NOCLDSTOP0x0001
 #define TARGET_SA_NOCLDWAIT0x0001
@@ -483,6 +484,10 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 #define TARGET_SA_RESTORER 0x0400
 #endif

+#ifdef TARGET_SA_RESTORER
+#define TARGET_ARCH_HAS_SA_RESTORER 1
+#endif
+
 #if defined(TARGET_ALPHA)

 #define TARGET_SIGHUP1
@@ -718,19 +723,27 @@ struct target_sigaction {
abi_ulong   _sa_handler;
 #endif
target_sigset_t sa_mask;
+#ifdef TARGET_ARCH_HAS_SA_RESTORER
+/* ??? This is always present, but ignored unless O32.  */


If it is always present, why it is defined conditionally?

TARGET_ARCH_HAS_SA_RESTORER is defined only for O32.


I don't know.  It's a kernel inconsistency.


TARGET_ALPHA has a sa_restorer field, but TARGET_ARCH_HAS_SA_RESTORER is
not defined.


TARGET_ALPHA has KA_RESTORER, not sa_restorer.  The restorer value is passed to 
sigaction in a 5th register argument.  Less than handy that qemu doesn't 
distinguish the two structs...



r~



Re: [Qemu-devel] [PATCH V2] nios2: iic: Convert CPU prop to qom link

2017-03-11 Thread Marek Vasut
On 02/27/2017 08:38 PM, Marek Vasut wrote:
> Add a const qom link between the CPU and the IIC instead
> of passing the CPU link through a qom property.
> 
> Signed-off-by: Marek Vasut 
> Cc: Alexander Graf 
> Cc: Chris Wulff 
> Cc: Igor Mammedov 
> Cc: Jeff Da Silva 
> Cc: Ley Foon Tan 
> Cc: Markus Armbruster 
> Cc: Richard Henderson 
> Cc: Sandra Loosemore 
> Cc: Yves Vandervennet 

Why is this patch not applied yet ?

> ---
> V2: Retain dc->cannot_instantiate_with_device_add_yet = true
> in altera_iic_class_init() since the device is still not
> device_add() creatable.
> ---
>  hw/intc/nios2_iic.c   | 12 
>  hw/nios2/10m50_devboard.c |  3 ++-
>  2 files changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
> index 818ab1b315..fe15621202 100644
> --- a/hw/intc/nios2_iic.c
> +++ b/hw/intc/nios2_iic.c
> @@ -62,17 +62,15 @@ static void altera_iic_init(Object *obj)
>  sysbus_init_irq(SYS_BUS_DEVICE(obj), &pv->parent_irq);
>  }
>  
> -static Property altera_iic_properties[] = {
> -DEFINE_PROP_PTR("cpu", AlteraIIC, cpu),
> -DEFINE_PROP_END_OF_LIST(),
> -};
> -
>  static void altera_iic_realize(DeviceState *dev, Error **errp)
>  {
>  struct AlteraIIC *pv = ALTERA_IIC(dev);
> +Error *err = NULL;
>  
> +pv->cpu = object_property_get_link(OBJECT(dev), "cpu", &err);
>  if (!pv->cpu) {
> -error_setg(errp, "altera,iic: CPU not connected");
> +error_setg(errp, "altera,iic: CPU link not found: %s",
> +   error_get_pretty(err));
>  return;
>  }
>  }
> @@ -81,8 +79,6 @@ static void altera_iic_class_init(ObjectClass *klass, void 
> *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(klass);
>  
> -dc->props = altera_iic_properties;
> -/* Reason: pointer property "cpu" */
>  dc->cannot_instantiate_with_device_add_yet = true;
>  dc->realize = altera_iic_realize;
>  }
> diff --git a/hw/nios2/10m50_devboard.c b/hw/nios2/10m50_devboard.c
> index 0d8b9aa58f..c18e0b2a17 100644
> --- a/hw/nios2/10m50_devboard.c
> +++ b/hw/nios2/10m50_devboard.c
> @@ -83,7 +83,8 @@ static void nios2_10m50_ghrd_init(MachineState *machine)
>  
>  /* Register: Internal Interrupt Controller (IIC) */
>  dev = qdev_create(NULL, "altera,iic");
> -qdev_prop_set_ptr(dev, "cpu", cpu);
> +object_property_add_const_link(OBJECT(dev), "cpu", OBJECT(cpu),
> +   &error_abort);
>  qdev_init_nofail(dev);
>  sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
>  for (i = 0; i < 32; i++) {
> 


-- 
Best regards,
Marek Vasut



Re: [Qemu-devel] [PATCH 04/21] qobject: add quint type

2017-03-11 Thread Eric Blake
On 03/11/2017 07:22 AM, Marc-André Lureau wrote:
> The type is not used at all yet. Add some tests to exercice it.

s/exercice/exercise/

I wonder if we need this patch at all.

I've been thinking about a possible alternative representation, such
that a single QInt type can cover _both_ signed and unsigned types, by
having QInt track a sign bit bool in addition to a uint64_t value.

If the user passes in a value in the range [0, INT64_MAX], the number is
representable in both uint64_t and int64_t. So the internal sign bit
would be omitted, as in { value=v, sign=false }.  Input visitors can
visit this value with both the 'uint64' and the 'int64' visitors, and
output visitors will output the same value.

If the user passes in a value in the range [-INT64_MAX-1, -1], the
number is intended to be used as a negative signed number.  So the QInt
representation would be the 2s complement representation, { value=-v,
sign=true }.  On input, the uint64_t visitor would reject the value as
out of range, the int64_t visitor would return the appropriate negative
value, and the generic int visitor will return the uint64_t value.  On
output, the number would be given the negative signed value
representation in anything that stringizes the value.

If the user passes in a value in the range [INT64_MAX+1, UINT64_MAX},
the number is intended to be used as a large unsigned number. So the
QInt representation would be { value=v, sign=false }.  On input, the
uint64_t visitor would accept the value, the int64_t visitor would
reject it as out of range, and the generic int visitor will return the
uint64_t value.  On output, the number would be given the positive
unsigned value representation in the stringized form.

That way, you don't have to complicate the (already-awkward) type
promotion rules of QFloat vs QInt with yet another scalar type.  The
input parser becomes friendlier - you can either use generic 'int' when
you want to allow the user to pass in either signed or unsigned values
(important for back-compat, where callers like libvirt learned that only
signed values worked even when large unsigned values were wanted); or
the specific 'int64' and 'uint64' types to force proper ranges.

It's definitely an alternative implementation to the one you pursued in
your series, so maybe we should first figure out WHAT we want
represented, before implementing something that will be more baggage
than we want (you at least have the advantage of patches that are
written; my idea of adding a sign bool to QInt is still just in the
initial idea stage).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 12/21] test-qga: drop everything until guest-sync

2017-03-11 Thread Eric Blake
On 03/11/2017 07:22 AM, Marc-André Lureau wrote:
> In the following commits, qemu-ga will emit an event on connect that
> a real client should treat or ignore and test-qga can skip.
> 

By the way, I still have a patch pending to fix test-qga:
https://lists.gnu.org/archive/html/qemu-devel/2017-01/msg03664.html

that we may want to incorporate first

> Signed-off-by: Marc-André Lureau 
> ---
>  tests/test-qga.c | 27 ---
>  1 file changed, 20 insertions(+), 7 deletions(-)
> 

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH] linux-user: Add missing IP_TOS, IPV6_TCLASS and IPV6_RECVTCLASS sockopts

2017-03-11 Thread Helge Deller
When running the nslookup or dig command with IPv6, the following qemu
warnings will be shown:

Unsupported ancillary data: 0/1
Unsupported setsockopt level=41 optname=67
Unsupported setsockopt level=41 optname=66
Unsupported ancillary data: 41/67

This patch adds the missing code to quiet those warnings.

Signed-off-by: Helge Deller 

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 03ed370..e5f55e9 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -1713,6 +1713,18 @@ static inline abi_long target_to_host_cmsg(struct msghdr 
*msgh,
 __get_user(cred->pid, &target_cred->pid);
 __get_user(cred->uid, &target_cred->uid);
 __get_user(cred->gid, &target_cred->gid);
+} else if (cmsg->cmsg_level == SOL_IP
+   &&  cmsg->cmsg_type == IP_TOS) {
+char *s = (char *)data;
+char *t = (char *)target_data;
+
+__get_user(*s, t);
+} else if (cmsg->cmsg_level == SOL_IPV6
+   &&  cmsg->cmsg_type == IPV6_TCLASS) {
+int32_t *s = (int32_t *)data;
+int32_t *t = (int32_t *)target_data;
+
+__get_user(*s, t);
 } else {
 gemu_log("Unsupported ancillary data: %d/%d\n",
 cmsg->cmsg_level, cmsg->cmsg_type);
@@ -1848,6 +1860,7 @@ static inline abi_long host_to_target_cmsg(struct 
target_msghdr *target_msgh,
 
 case SOL_IP:
 switch (cmsg->cmsg_type) {
+case IP_TOS:
 case IP_TTL:
 {
 uint32_t *v = (uint32_t *)data;
@@ -2902,6 +2915,8 @@ static abi_long do_setsockopt(int sockfd, int level, int 
optname,
 case IPV6_RECVHOPLIMIT:
 case IPV6_2292HOPLIMIT:
 case IPV6_CHECKSUM:
+case IPV6_RECVTCLASS:
+case IPV6_TCLASS:
 val = 0;
 if (optlen < sizeof(uint32_t)) {
 return -TARGET_EINVAL;



Re: [Qemu-devel] [PATCH] linux-user: Add TARGET_MAP_STACK and TARGET_MAP_HUGETLB for all remaining architectures

2017-03-11 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Subject: [Qemu-devel] [PATCH] linux-user: Add TARGET_MAP_STACK and 
TARGET_MAP_HUGETLB for all remaining architectures
Message-id: 20170311183016.ga20...@ls3530.fritz.box

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 - [tag update]  patchew/20170311034232.14213-1-...@twiddle.net -> 
patchew/20170311034232.14213-1-...@twiddle.net
 * [new tag] patchew/20170311183016.ga20...@ls3530.fritz.box -> 
patchew/20170311183016.ga20...@ls3530.fritz.box
Switched to a new branch 'test'
8c465a2 linux-user: Add TARGET_MAP_STACK and TARGET_MAP_HUGETLB for all 
remaining architectures

=== OUTPUT BEGIN ===
Checking PATCH 1/1: linux-user: Add TARGET_MAP_STACK and TARGET_MAP_HUGETLB for 
all remaining architectures...
ERROR: code indent should never use tabs
#23: FILE: linux-user/syscall.c:5878:
+^I{ TARGET_MAP_STACK, TARGET_MAP_STACK, MAP_STACK, MAP_STACK },$

ERROR: code indent should never use tabs
#24: FILE: linux-user/syscall.c:5879:
+^I{ TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },$

ERROR: line over 90 characters
#36: FILE: linux-user/syscall_defs.h:1324:
+#define TARGET_MAP_STACK   0x4 /* give out an address that is 
best suited for process/thread stacks */

ERROR: code indent should never use tabs
#36: FILE: linux-user/syscall_defs.h:1324:
+#define TARGET_MAP_STACK^I0x4^I^I/* give out an address that is best 
suited for process/thread stacks */$

ERROR: code indent should never use tabs
#37: FILE: linux-user/syscall_defs.h:1325:
+#define TARGET_MAP_HUGETLB^I0x8^I^I/* create a huge page mapping */$

ERROR: line over 90 characters
#45: FILE: linux-user/syscall_defs.h:1336:
+#define TARGET_MAP_STACK   0x2 /* give out an address that is 
best suited for process/thread stacks */

ERROR: code indent should never use tabs
#45: FILE: linux-user/syscall_defs.h:1336:
+#define TARGET_MAP_STACK^I0x2^I^I/* give out an address that is best 
suited for process/thread stacks */$

ERROR: code indent should never use tabs
#46: FILE: linux-user/syscall_defs.h:1337:
+#define TARGET_MAP_HUGETLB^I0x4^I^I/* create a huge page mapping */$

ERROR: line over 90 characters
#54: FILE: linux-user/syscall_defs.h:1348:
+#define TARGET_MAP_STACK   0x8 /* give out an address that is 
best suited for process/thread stacks */

ERROR: code indent should never use tabs
#54: FILE: linux-user/syscall_defs.h:1348:
+#define TARGET_MAP_STACK^I0x8^I^I/* give out an address that is best 
suited for process/thread stacks */$

ERROR: code indent should never use tabs
#55: FILE: linux-user/syscall_defs.h:1349:
+#define TARGET_MAP_HUGETLB^I0x10^I/* create a huge page mapping */$

ERROR: line over 90 characters
#63: FILE: linux-user/syscall_defs.h:1370:
+#define TARGET_MAP_STACK   0x2 /* give out an address that is 
best suited for process/thread stacks */

ERROR: code indent should never use tabs
#63: FILE: linux-user/syscall_defs.h:1370:
+#define TARGET_MAP_STACK^I0x2^I^I/* give out an address that is best 
suited for process/thread stacks */$

ERROR: code indent should never use tabs
#64: FILE: linux-user/syscall_defs.h:1371:
+#define TARGET_MAP_HUGETLB^I0x4^I^I/* create a huge page mapping */$

total: 14 errors, 0 warnings, 40 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

[Qemu-devel] [PATCH] linux-user: Add TARGET_MAP_STACK and TARGET_MAP_HUGETLB for all remaining architectures

2017-03-11 Thread Helge Deller
Add the missing defines and for TARGET_MAP_STACK and TARGET_MAP_HUGETLB
for alpha, mips, ppc and x86, and fix the mmap_flags translation table
to translate those flags between host and target architecture.

Signed-off-by: Helge Deller 

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index cec8428..03ed370 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5875,6 +5875,8 @@ static bitmask_transtbl mmap_flags_tbl[] = {
{ TARGET_MAP_LOCKED, TARGET_MAP_LOCKED, MAP_LOCKED, MAP_LOCKED },
 { TARGET_MAP_NORESERVE, TARGET_MAP_NORESERVE, MAP_NORESERVE,
   MAP_NORESERVE },
+   { TARGET_MAP_STACK, TARGET_MAP_STACK, MAP_STACK, MAP_STACK },
+   { TARGET_MAP_HUGETLB, TARGET_MAP_HUGETLB, MAP_HUGETLB, MAP_HUGETLB },
{ 0, 0, 0, 0 }
 };
 
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index f356189..a516d77 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1346,6 +1346,8 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE   0x0400  /* don't check for reservations 
*/
 #define TARGET_MAP_POPULATE0x1 /* populate (prefault) 
pagetables */
 #define TARGET_MAP_NONBLOCK0x2 /* do not block on IO */
+#define TARGET_MAP_STACK   0x4 /* give out an address that is 
best suited for process/thread stacks */
+#define TARGET_MAP_HUGETLB 0x8 /* create a huge page mapping */
 #elif defined(TARGET_PPC)
 #define TARGET_MAP_FIXED   0x10/* Interpret addr exactly */
 #define TARGET_MAP_ANONYMOUS   0x20/* don't use a file */
@@ -1356,6 +1358,8 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE   0x0040  /* don't check for reservations 
*/
 #define TARGET_MAP_POPULATE0x8000  /* populate (prefault) 
pagetables */
 #define TARGET_MAP_NONBLOCK0x1 /* do not block on IO */
+#define TARGET_MAP_STACK   0x2 /* give out an address that is 
best suited for process/thread stacks */
+#define TARGET_MAP_HUGETLB 0x4 /* create a huge page mapping */
 #elif defined(TARGET_ALPHA)
 #define TARGET_MAP_ANONYMOUS   0x10/* don't use a file */
 #define TARGET_MAP_FIXED   0x100   /* Interpret addr exactly */
@@ -1366,6 +1370,8 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE   0x1 /* no check for reservations */
 #define TARGET_MAP_POPULATE0x2 /* pop (prefault) pagetables */
 #define TARGET_MAP_NONBLOCK0x4 /* do not block on IO */
+#define TARGET_MAP_STACK   0x8 /* give out an address that is 
best suited for process/thread stacks */
+#define TARGET_MAP_HUGETLB 0x10/* create a huge page mapping */
 #elif defined(TARGET_HPPA)
 #define TARGET_MAP_ANONYMOUS   0x10/* don't use a file */
 #define TARGET_MAP_FIXED   0x04/* Interpret addr exactly */
@@ -1388,6 +1394,8 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE   0x4000  /* don't check for reservations 
*/
 #define TARGET_MAP_POPULATE0x8000  /* populate (prefault) 
pagetables */
 #define TARGET_MAP_NONBLOCK0x1 /* do not block on IO */
+#define TARGET_MAP_STACK   0x2 /* give out an address that is 
best suited for process/thread stacks */
+#define TARGET_MAP_HUGETLB 0x4 /* create a huge page mapping */
 #define TARGET_MAP_UNINITIALIZED 0x400 /* for anonymous mmap, memory 
could be uninitialized */
 #endif
 



Re: [Qemu-devel] [PATCH 1/3] linux-user: Restrict usage of sa_restorer

2017-03-11 Thread Laurent Vivier
Le 11/03/2017 à 04:42, Richard Henderson a écrit :
> Reading and writing to an sa_restorer member that isn't supposed to
> exist corrupts user memory.  Introduce TARGET_ARCH_HAS_SA_RESTORER,
> similar to the kernel's __ARCH_HAS_SA_RESTORER.
> 
> Reported-by: Helge Deller 
> Signed-off-by: Richard Henderson 
> ---
>  linux-user/signal.c   |  4 ++--
>  linux-user/syscall_defs.h | 13 +
>  2 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/linux-user/signal.c b/linux-user/signal.c
> index a67db04..c6b043b 100644
> --- a/linux-user/signal.c
> +++ b/linux-user/signal.c
> @@ -777,7 +777,7 @@ int do_sigaction(int sig, const struct target_sigaction 
> *act,
>  if (oact) {
>  __put_user(k->_sa_handler, &oact->_sa_handler);
>  __put_user(k->sa_flags, &oact->sa_flags);
> -#if !defined(TARGET_MIPS)
> +#ifdef TARGET_ARCH_HAS_SA_RESTORER
>  __put_user(k->sa_restorer, &oact->sa_restorer);
>  #endif
>  /* Not swapped.  */
> @@ -787,7 +787,7 @@ int do_sigaction(int sig, const struct target_sigaction 
> *act,
>  /* FIXME: This is not threadsafe.  */
>  __get_user(k->_sa_handler, &act->_sa_handler);
>  __get_user(k->sa_flags, &act->sa_flags);
> -#if !defined(TARGET_MIPS)
> +#ifdef TARGET_ARCH_HAS_SA_RESTORER
>  __get_user(k->sa_restorer, &act->sa_restorer);
>  #endif
>  /* To be swapped in target_to_host_sigset.  */
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 40c5027..8b1ad74 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -445,6 +445,7 @@ int do_sigaction(int sig, const struct target_sigaction 
> *act,
>  #define TARGET_SA_RESTART  2u
>  #define TARGET_SA_NODEFER  0x20u
>  #define TARGET_SA_RESETHAND4u
> +#define TARGET_ARCH_HAS_SA_RESTORER 1
>  #elif defined(TARGET_MIPS)
>  #define TARGET_SA_NOCLDSTOP  0x0001
>  #define TARGET_SA_NOCLDWAIT  0x0001
> @@ -483,6 +484,10 @@ int do_sigaction(int sig, const struct target_sigaction 
> *act,
>  #define TARGET_SA_RESTORER   0x0400
>  #endif
>  
> +#ifdef TARGET_SA_RESTORER
> +#define TARGET_ARCH_HAS_SA_RESTORER 1
> +#endif
> +
>  #if defined(TARGET_ALPHA)
>  
>  #define TARGET_SIGHUP1
> @@ -718,19 +723,27 @@ struct target_sigaction {
>   abi_ulong   _sa_handler;
>  #endif
>   target_sigset_t sa_mask;
> +#ifdef TARGET_ARCH_HAS_SA_RESTORER
> +/* ??? This is always present, but ignored unless O32.  */

If it is always present, why it is defined conditionally?

TARGET_ARCH_HAS_SA_RESTORER is defined only for O32.

> +abi_ulong sa_restorer;
> +#endif
>  };
>  #else
>  struct target_old_sigaction {
>  abi_ulong _sa_handler;
>  abi_ulong sa_mask;
>  abi_ulong sa_flags;
> +#ifdef TARGET_ARCH_HAS_SA_RESTORER
>  abi_ulong sa_restorer;
> +#endif
>  };
>  
>  struct target_sigaction {
>  abi_ulong _sa_handler;
>  abi_ulong sa_flags;
> +#ifdef TARGET_ARCH_HAS_SA_RESTORER
>  abi_ulong sa_restorer;
> +#endif
>  target_sigset_t sa_mask;
>  };
>  #endif
> 

TARGET_ALPHA has a sa_restorer field, but TARGET_ARCH_HAS_SA_RESTORER is
not defined.

Laurent



[Qemu-devel] [PATCH] linux-user: Fix TARGET_MAP* and TARGET_F_??LCK for hppa arch

2017-03-11 Thread Helge Deller
TARGET_MAP_TYPE needs to be 0x03 instead of 0x0f on the hppa
architecture, otherwise it conflicts with MAP_FIXED which is 0x04.

Add missing TARGET_MAP_STACK and TARGET_MAP_HUGETLB values.

Fix TARGET_F_RDLCK, TARGET_F_WRLCK and TARGET_F_UNLCK.

Signed-off-by: Helge Deller 

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 2620b56..f356189 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1329,7 +1329,11 @@ struct target_winsize {
 /* Common */
 #define TARGET_MAP_SHARED  0x01/* Share changes */
 #define TARGET_MAP_PRIVATE 0x02/* Changes are private */
+#if defined(TARGET_HPPA)
+#define TARGET_MAP_TYPE0x03/* Mask for type of 
mapping */
+#else
 #define TARGET_MAP_TYPE0x0f/* Mask for type of 
mapping */
+#endif
 
 /* Target specific */
 #if defined(TARGET_MIPS)
@@ -1372,6 +1376,8 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE   0x04000 /* no check for reservations */
 #define TARGET_MAP_POPULATE0x1 /* pop (prefault) pagetables */
 #define TARGET_MAP_NONBLOCK0x2 /* do not block on IO */
+#define TARGET_MAP_STACK   0x4 /* give out an address that is 
best suited for process/thread stacks */
+#define TARGET_MAP_HUGETLB 0x8 /* create a huge page mapping */
 #else
 #define TARGET_MAP_FIXED   0x10/* Interpret addr exactly */
 #define TARGET_MAP_ANONYMOUS   0x20/* don't use a file */
@@ -2350,6 +2356,9 @@ struct target_statfs64 {
 #define TARGET_F_SETOWN24   /*  for sockets. */
 #define TARGET_F_GETOWN23   /*  for sockets. */
 #elif defined(TARGET_HPPA)
+#define TARGET_F_RDLCK 1
+#define TARGET_F_WRLCK 2
+#define TARGET_F_UNLCK 3
 #define TARGET_F_GETLK 5
 #define TARGET_F_SETLK 6
 #define TARGET_F_SETLKW7



[Qemu-devel] Qemu socket address

2017-03-11 Thread Ashish Gahlot
Sorry if I'm asking a silly question but why doesn't Qemu support *socket
address reuse *when we use remote debugging with gdb with options "-S -s"?

Is there a support in the upstream version? I am using Qemu version 2.7.0.

Thanks
Ashish

-- 
Ashish Kumar Gahlot
III year, UG
Govt. Engg. College, Ajmer, India


Re: [Qemu-devel] [PATCH v1 2/2] reduce qemu's heap Rss size from 12252kB to 2752KB

2017-03-11 Thread Paolo Bonzini

> > Subpages never have subregions, so the loop never runs.  The begin/commit
> > pair then becomes:
> > 
> > ++memory_region_transaction_depth;
> > --memory_region_transaction_depth;
> > if (!memory_region_transaction_depth) {
> > if (memory_region_update_pending) {
> > ...
> > } else if (ioeventfd_update_pending) {
> > ...
> > }
> > // memory_region_clear_pending()
> > memory_region_update_pending = false;
> > ioeventfd_update_pending = false;
> >}
> > 
> > If memory_region_transaction_depth is > 0 the begin/commit pair does
> > nothing.
> > 
> > But if memory_region_transaction_depth is == 0, there should be no update
> > pending because the loop has never run.  So I don't see what your patch can
> > change.
> 
> As I mentioned in PATCH1, this patch is used to fix an issue after we remove
> the global lock in RCU callback. After global lock is removed, other thread
> may set up update pending, so memory_region_transaction_commit
> may try to rebuild PhysPageMap even the loop doesn’t run, other thread may
> try to rebuild PhysPageMap at the same time, it is a race condition.
> subpage MemoryRegion is a specific MemoryRegion, it doesn't belong to any
> address space, it is only used to handle subpage. We may use a new structure
> other than MemoryRegion to handle subpage to make the logic more clearer. 
> After
> the change, RCU callback will not free any MemoryRegion.

This is not true.  Try hot-unplugging a device.

I'm all for reducing the scope of the global QEMU lock, but this needs a plan
and a careful analysis of the involved data structures across _all_ 
instance_finalize
implementations.

Paolo



Re: [Qemu-devel] [PATCH v1 1/2] reduce qemu's heap Rss size from 12252kB to 2752KB

2017-03-11 Thread Paolo Bonzini


- Original Message -
> From: "Anthony Xu" 
> To: "Paolo Bonzini" , "Yang Zhong" 
> , qemu-devel@nongnu.org
> Cc: "Chao P Peng" 
> Sent: Friday, March 10, 2017 8:30:06 PM
> Subject: RE: [PATCH v1 1/2] reduce qemu's heap Rss size from 12252kB to 2752KB
> 
> > > Ideally, freeing QOM object should not require a global lock.
> > > If you see any other QOM requiring a global lock, please let us know, we
> > are willing to fix it.
> > 
> > All of them.  When unplugging a device, the device object will be freed
> > from an RCU callback.
> > 
> 
> Thanks for your reply,
> Some objects may not need lock at all to be freed,
> Some objects may just need a small lock to be freed,
> 
> Should we let RCU callbacks to decide which lock they need instead of
> enforcing the global lock in RCU thread?

Splitting the global lock and deciding which object requires which lock
is very, very hard.

The problem is that everything calling object_unref potentially needs the
global lock, and that includes the following call chain: object_unref
-> memory_region_unref -> flatview_destroy -> flatview_unref ->
address_space_update_topology -> memory_region_transaction_commit.

Paolo

> As for the device object, can we get the global lock inside the object
> free/destroy function for now?
> 
> If we can remove the global lock inside RCU thread, we can save 9MB heap
> memory, that's a lot!
> 
> Please share with us if you have other idea to do this.
> 
> Thanks
> Anthony
> 
> 
> 
> 



Re: [Qemu-devel] Benchmarking linux-user performance

2017-03-11 Thread Peter Maydell
On 11 March 2017 at 03:25, Emilio G. Cota  wrote:
> On Fri, Mar 10, 2017 at 12:48:31 +0100, Peter Maydell wrote:
>> Given the scale on the LHS is from 1.74 to 1.88 my guess is that the
>> variation is in large part noise and the major thing is "our fp
>> performance is bounded by softfloat, which doesn't change and is
>> always very slow".
>
> It isn't "measurement noise" -- if you look at the PNGs the measurements
> are very stable (all points have error bars): http://imgur.com/a/nF7Ls
>
> It's true that performance here varies very little. This is just the
> result of Amdahl's law, as you point out. (upon re-reading your message,
> I see that perhaps what you meant by "noise" is exactly this.)

Yes, sorry, I wasn't really using the right terminology there.
I just meant that the release-to-release variation is not as
significant as it appears from the graph, because the LHS axis
scale is covering such a small range.

thanks
-- PMM



Re: [Qemu-devel] [PATCH 00/21] WIP: dump: add kaslr support (for after 2.9)

2017-03-11 Thread Dave Anderson


- Original Message -
> Hi,
> 
> Latest linux kernel enabled kaslr to randomize phys/virt memory
> addresses. There has been some effort to support kexec/kdump so that
> crash utility can still works in case crashed kernel has kaslr
> enabled.
> 
> This series aims to provide enough information in qemu dumps so that
> crash utility can work with kaslr kernel too, with x86_64 guests (it
> hasn't been tested on other archs, help welcome).
> 
> Two pieces of informations are necessary: the phys_base (the physical
> address where the kernel is loaded) and the kaslr offset. Other useful
> informations for debugging are provided in Linux vmcoreinfo too.
> 
> There has been discussions to provide those details in early boot,
> with ACPI, fw_cfg, virtio-pstore etc, but none has reached a consensus
> yet. A possiblity for now is to provide the information when qemu-ga
> starts. This has the advantage of working with older guests and may
> not be incompatible with future methods (in this case it could ignore
> qga info for example). The drawback is that qemu will have to parse
> the json stream. For now it stops processing it whem VMDUMP_INFO is
> received. It would be wise to introduce a QMP welcome message, so that
> qemu would stop immediately processing the stream if the agent doesn't
> have the event. Another option is to create a seperate channel...
> I welcome other ideas and discussion.
> 
> crash upstream doesn't yet parse NUMBER(phys_base). You may pass it to
> crash with --machdep phys_base=0x.. provided you snooped on qga.

FYI: a patch to utilize NUMBER(phys_base) has been checked in upstream:

  
https://github.com/crash-utility/crash/commit/ed60e97e319a1cfc9e2779aa1baac305677393d8

  Linux 4.10 commit 401721ecd1dcb0a428aa5d6832ee05ffbdbffbbe finally
  exports the x86_64 "phys_base" value in the VMCOREINFO note, so
  utilize it whenever it exists.
  (ander...@redhat.com)

Thanks,
  Dave


> kdump kaslr-dumps should now work with crash out of the box.
> 
> A large part of the series has to do with json and the qobject type
> system to deal with uint64 values, so that addresses can now be sent
> over json. The second halfs adds qga VMDUMP_INFO event, and ELF/kdump
> dumping. Depending on the feedback, I will probably split the series,
> but for those who would like to try it, help or suggest ideas, here is
> the whole thing.
> 
> cheers
> 
> Marc-André Lureau (21):
>   qapi: add info comment for generated types
>   pci-host: use more specific type names
>   object: fix potential leak in getters
>   qobject: add quint type
>   qapi: update the qobject visitor to use QUInt
>   json: learn to parse uint64 numbers
>   object: add uint property setter/getter
>   qdev: use int and uint properties
>   qdev: use appropriate type
>   Use uint property getter/setter where appropriate
>   qdict: learn to lookup quint
>   test-qga: drop everything until guest-sync
>   qga: report error on keyfile dump error
>   qga: add and populate VMDumpInfo
>   qga: register event emit function
>   qga: emit VMDUMP_INFO event
>   virtio-channel: parse qga stream for VMDUMP_INFO event
>   dump: use qga VMDUMP_INFO for ELF dump
>   kdump: write vmcoreinfo in header
>   scripts/dump-guest-memory.py: fix int128_get64 on recent gcc
>   scripts/dump-guest-memory.py: add VMCOREINFO
> 
>  qapi/introspect.json |   2 +-
>  scripts/qapi.py  |  39 ---
>  scripts/dump-guest-memory.py |  66 ++-
>  scripts/qapi-event.py|   4 +-
>  scripts/qapi-types.py|  17 +--
>  scripts/qapi-visit.py|   3 +-
>  include/hw/isa/isa.h |   2 +-
>  include/hw/qdev-core.h   |   5 +-
>  include/hw/qdev-properties.h |  59 ++
>  include/qapi/qmp/qdict.h |   2 +
>  include/qapi/qmp/quint.h |  25 +
>  include/qapi/qmp/types.h |   1 +
>  include/qom/object.h |  23 
>  include/sysemu/dump-info.h   |  15 +++
>  include/sysemu/dump.h|   2 +
>  qga/guest-agent-core.h   |   2 +
>  block/qapi.c |   5 +
>  dump.c   | 184
>  ++-
>  hw/acpi/memory_hotplug.c |  10 +-
>  hw/acpi/nvdimm.c |  10 +-
>  hw/acpi/pcihp.c  |   6 +-
>  hw/arm/aspeed.c  |   4 +-
>  hw/arm/bcm2835_peripherals.c |   9 +-
>  hw/arm/raspi.c   |   4 +-
>  hw/block/fdc.c   |  54 -
>  hw/char/virtio-console.c |  53 +
>  hw/core/platform-bus.c   |   2 +-
>  hw/core/qdev-properties.c|   8 +-
>  hw/core/qdev.c   |   8 +-
>  hw/i386/acpi-build.c |  70 ++--
>  hw

Re: [Qemu-devel] [PATCH 2/3] linux-user: Fix TARGET_SA_* defines for HPPA

2017-03-11 Thread Laurent Vivier
Le 11/03/2017 à 04:42, Richard Henderson a écrit :
> From: Helge Deller 
> 
> Reported-by: Helge Deller 
> Signed-off-by: Richard Henderson 

Reviewed-by: Laurent Vivier 

> ---
>  linux-user/syscall_defs.h | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 8b1ad74..2620b56 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -473,6 +473,14 @@ int do_sigaction(int sig, const struct target_sigaction 
> *act,
>  #define TARGET_SA_RESETHAND  0x0010
>  #define TARGET_SA_NOCLDWAIT  0x0020 /* not supported yet */
>  #define TARGET_SA_SIGINFO0x0040
> +#elif defined(TARGET_HPPA)
> +#define TARGET_SA_ONSTACK   0x0001
> +#define TARGET_SA_RESETHAND 0x0004
> +#define TARGET_SA_NOCLDSTOP 0x0008
> +#define TARGET_SA_SIGINFO   0x0010
> +#define TARGET_SA_NODEFER   0x0020
> +#define TARGET_SA_RESTART   0x0040
> +#define TARGET_SA_NOCLDWAIT 0x0080
>  #else
>  #define TARGET_SA_NOCLDSTOP  0x0001
>  #define TARGET_SA_NOCLDWAIT  0x0002 /* not supported yet */
> 




Re: [Qemu-devel] [PATCH v7 kernel 3/5] virtio-balloon: implementation of VIRTIO_BALLOON_F_CHUNK_TRANSFER

2017-03-11 Thread Matthew Wilcox
On Sat, Mar 11, 2017 at 07:59:31PM +0800, Wei Wang wrote:
> I'm thinking what if the guest needs to transfer these much physically
> continuous
> memory to host: 1GB+2MB+64KB+32KB+16KB+4KB.
> Is it going to use Six 64-bit chunks? Would it be simpler if we just
> use the 128-bit chunk format (we can drop the previous normal 64-bit
> format)?

Is that a likely thing for the guest to need to do though?  Freeing a
1GB page is much more liikely, IMO.



Re: [Qemu-devel] [PATCH] linux-user/hppa: Fix typo for TARGET_NR_epoll_wait

2017-03-11 Thread Laurent Vivier
Le 11/03/2017 à 11:05, Helge Deller a écrit :
> This fixes running a dynamically linked nslookup binary on hppa with
> LD_BIND_NOW=1.
> 
> Signed-off-by: Helge Deller 

Reviewed-by: Laurent Vivier 

> 
> diff --git a/linux-user/hppa/syscall_nr.h b/linux-user/hppa/syscall_nr.h
> index 0f396fa..55bdf71 100644
> --- a/linux-user/hppa/syscall_nr.h
> +++ b/linux-user/hppa/syscall_nr.h
> @@ -228,7 +228,7 @@
>  #define TARGET_NR_lookup_dcookie223
>  #define TARGET_NR_epoll_create  224
>  #define TARGET_NR_epoll_ctl 225
> -#define TARGET_NR_epill_wait226
> +#define TARGET_NR_epoll_wait226
>  #define TARGET_NR_remap_file_pages  227
>  #define TARGET_NR_semtimedop228
>  #define TARGET_NR_mq_open   229
> 




Re: [Qemu-devel] [PATCH 00/21] WIP: dump: add kaslr support (for after 2.9)

2017-03-11 Thread no-reply
Hi,

This series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Type: series
Subject: [Qemu-devel] [PATCH 00/21] WIP: dump: add kaslr support (for after 2.9)
Message-id: 20170311132256.22951-1-marcandre.lur...@redhat.com

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=16
make docker-test-quick@centos6
make docker-test-mingw@fedora
make docker-test-build@min-glib
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
c4258ed scripts/dump-guest-memory.py: add VMCOREINFO
12f2cd9 scripts/dump-guest-memory.py: fix int128_get64 on recent gcc
53ab76c kdump: write vmcoreinfo in header
f856c12 dump: use qga VMDUMP_INFO for ELF dump
2ef806a virtio-channel: parse qga stream for VMDUMP_INFO event
dcebb93 qga: emit VMDUMP_INFO event
c1774df qga: register event emit function
a0e47b1 qga: add and populate VMDumpInfo
86a1fa2 qga: report error on keyfile dump error
9137503 test-qga: drop everything until guest-sync
96cac9b qdict: learn to lookup quint
39f3ad6 Use uint property getter/setter where appropriate
98547af qdev: use appropriate type
be8b857 qdev: use int and uint properties
e7b693f object: add uint property setter/getter
ded1bba json: learn to parse uint64 numbers
222ed0a qapi: update the qobject visitor to use QUInt
f71f11e qobject: add quint type
0888419 object: fix potential leak in getters
47fff1e pci-host: use more specific type names
2de8460 qapi: add info comment for generated types

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out 'fa8bc7f928ac25f23532afc8beb2073efc8fb063'
  BUILD   centos6
make[1]: Entering directory `/var/tmp/patchew-tester-tmp-g_4q0obe/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPYRUNNER
RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
gcc-4.4.7-17.el6.x86_64
git-1.7.1-4.el6_7.1.x86_64
glib2-devel-2.28.8-5.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=libfdt-devel ccache tar git make gcc g++ zlib-devel 
glib2-devel SDL-devel pixman-devel epel-release
HOSTNAME=30eb98410084
TERM=xterm
MAKEFLAGS= -j16
HISTSIZE=1000
J=16
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu 
--prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix/var/tmp/qemu-build/install
BIOS directory/var/tmp/qemu-build/install/share/qemu
binary directory  /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory  /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory  /var/tmp/qemu-build/install/etc
local state directory   /var/tmp/qemu-build/install/var
Manual directory  /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path   /tmp/qemu-test/src
C compilercc
Host C compiler   cc
C++ compiler  
Objective-C compiler cc
ARFLAGS   rv
CFLAGS-O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS   -I/usr/include/pixman-1   -I$(SRC_PATH)/dtc/libfdt -pthread 
-I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -fPIE -DPIE -m64 -mcx16 
-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes 
-Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes 
-fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels 
-Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security 
-Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration 
-Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS   -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make  make
install   install
pythonpython -B
smbd  /usr/sbin/smbd
module supportno
host CPU  x86_64
host big endian   no
target list   x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled no
sparse enabledno
strip binariesyes
profiler  no
static build  no
pixm

[Qemu-devel] [PATCH 15/21] qga: register event emit function

2017-03-11 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 qga/main.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/qga/main.c b/qga/main.c
index 1c39895baa..8e852bd556 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -39,6 +39,7 @@
 #define CONFIG_FSFREEZE
 #endif
 #endif
+#include "qapi/qmp-event.h"
 
 #ifndef _WIN32
 #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
@@ -1488,6 +1489,12 @@ end:
 #endif
 }
 
+static void
+monitor_qapi_event_queue(qga_QAPIEvent event, QDict *qdict, Error **errp)
+{
+send_response(ga_state, QOBJECT(qdict));
+}
+
 int main(int argc, char **argv)
 {
 int ret = EXIT_SUCCESS;
@@ -1496,6 +1503,7 @@ int main(int argc, char **argv)
 int listen_fd;
 
 update_vmdump_info(s);
+qmp_event_set_func_emit(monitor_qapi_event_queue);
 
 config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
 
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 14/21] qga: add and populate VMDumpInfo

2017-03-11 Thread Marc-André Lureau
Get various addresses and informations that can be useful for qemu to
generate dumps, and provide enough details for KASLR kernels to be
exploitable by tools like crash.

phys-base: the physical address where the kernel is loaded
vmcoreinfo: can be used to read the guest vmcoreinfo ELF note
_text: can be used to compute the kaslr offset (not needed when vmcoreinfo)

Signed-off-by: Marc-André Lureau 
---
 qga/main.c | 134 +
 1 file changed, 134 insertions(+)

diff --git a/qga/main.c b/qga/main.c
index beff041340..1c39895baa 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -65,6 +65,14 @@ typedef struct GAPersistentState {
 int64_t fd_counter;
 } GAPersistentState;
 
+typedef struct VMDumpInfo {
+bool has_phys_base;
+uint64_t phys_base;
+bool has_text;
+uint64_t text;
+char *vmcoreinfo;
+} VMDumpInfo;
+
 struct GAState {
 JSONMessageParser parser;
 GMainLoop *main_loop;
@@ -90,6 +98,7 @@ struct GAState {
 #endif
 gchar *pstate_filepath;
 GAPersistentState pstate;
+VMDumpInfo vmdump;
 };
 
 struct GAState *ga_state;
@@ -1357,6 +1366,128 @@ static int run_agent(GAState *s, GAConfig *config)
 return EXIT_SUCCESS;
 }
 
+#define __START_KERNEL_map0x8000UL
+
+static void update_vmdump_info(GAState *s)
+{
+#ifndef _WIN32
+char *vmcoreinfo = NULL;
+char *iomem = NULL;
+char *kallsyms = NULL;
+gsize len;
+GError *err = NULL;
+#ifdef __x86_64__
+guint64 kernel_code_start, text_start, phys_base;
+char *tmp, *line, *eol;
+
+if (!g_file_get_contents("/proc/iomem", &iomem, &len, &err)) {
+g_critical("Failed to read /proc/iomem: %s", err->message);
+g_clear_error(&err);
+goto end;
+}
+if (!iomem[len] == '\0') {
+g_critical("iomem is not null-terminated");
+goto end;
+}
+
+for (line = iomem; line != NULL; line = eol ? eol + 1 : NULL) {
+eol = strstr(line, "\n");
+if (eol) {
+*eol = '\0';
+}
+tmp = strstr(line, " : Kernel code");
+if (!tmp || *(tmp + 14) != '\0') {
+continue;
+} else {
+break;
+}
+}
+
+if (line == NULL) {
+g_critical("failed to find kernel_code_start");
+goto end;
+} else {
+tmp = strstr(line, "-");
+if (!tmp) {
+g_critical("no -");
+goto end;
+}
+*tmp = '\0';
+kernel_code_start = g_ascii_strtoull(g_strstrip(line), &tmp, 16);
+if (*tmp != '\0') {
+g_critical("failed to parse hex value");
+goto end;
+}
+}
+
+if (!g_file_get_contents("/proc/kallsyms", &kallsyms, &len, &err)) {
+g_critical("Failed to read /proc/kallsyms: %s", err->message);
+g_clear_error(&err);
+goto end;
+}
+if (!kallsyms[len] == '\0') {
+g_critical("iomem is not null-terminated");
+goto end;
+}
+
+for (line = kallsyms; line != NULL; line = eol ? eol + 1 : NULL) {
+eol = strstr(line, "\n");
+if (eol) {
+*eol = '\0';
+}
+tmp = strstr(line, " T _text");
+if (!tmp || *(tmp + 8) != '\0') {
+continue;
+} else {
+*tmp = '\0';
+break;
+}
+}
+
+if (line == NULL) {
+g_critical("failed to find _text");
+goto end;
+} else {
+text_start = g_ascii_strtoull(g_strstrip(line), &tmp, 16);
+if (*tmp != '\0') {
+g_critical("failed to parse hex value");
+goto end;
+}
+}
+
+phys_base = kernel_code_start - (text_start - __START_KERNEL_map);
+g_debug("_text: %lx, kernel_code_start: %lx",
+text_start, kernel_code_start);
+g_debug("-> phys_base: %lx", phys_base);
+g_debug("vmcoreinfo: %s", vmcoreinfo);
+
+s->vmdump.has_phys_base = true;
+s->vmdump.phys_base = phys_base;
+s->vmdump.has_text = true;
+s->vmdump.text = text_start;
+#endif /* x86_64 */
+
+if (!g_file_get_contents("/sys/kernel/vmcoreinfo",
+ &vmcoreinfo, &len, &err)) {
+g_critical("Failed to read vmcoreinfo: %s", err->message);
+g_clear_error(&err);
+goto end;
+}
+if (!vmcoreinfo[len] == '\0') {
+g_critical("vmcoreinfo is not null-terminated");
+goto end;
+}
+
+s->vmdump.vmcoreinfo = vmcoreinfo;
+vmcoreinfo = NULL;
+
+end:
+g_free(vmcoreinfo);
+g_free(kallsyms);
+g_free(iomem);
+#endif
+}
+
 int main(int argc, char **argv)
 {
 int ret = EXIT_SUCCESS;
@@ -1364,6 +1495,8 @@ int main(int argc, char **argv)
 GAConfig *config = g_new0(GAConfig, 1);
 int listen_fd;
 
+update_vmdump_info(s);
+
 config->log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
 
 qga_qmp_init_marshal(&ga_commands);
@@ -1460,6 +1593,7 @@ end:
 if (s->main_loop) {
 g_main_loop_unref(s->main

[Qemu-devel] [PATCH 21/21] scripts/dump-guest-memory.py: add VMCOREINFO

2017-03-11 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 scripts/dump-guest-memory.py | 52 
 1 file changed, 52 insertions(+)

diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
index f7c6635f15..0ce32b2a3f 100644
--- a/scripts/dump-guest-memory.py
+++ b/scripts/dump-guest-memory.py
@@ -120,6 +120,33 @@ class ELF(object):
 self.segments[0].p_filesz += ctypes.sizeof(note)
 self.segments[0].p_memsz += ctypes.sizeof(note)
 
+
+def add_vmcoreinfo_note(self, vmcoreinfo, phys_base=None):
+"""Adds a vmcoreinfo note to the ELF."""
+chead = type(get_arch_note(self.endianness, 0, 0))
+header = chead.from_buffer_copy(vmcoreinfo[0:ctypes.sizeof(chead)])
+note = get_arch_note(self.endianness,
+ header.n_namesz - 1, header.n_descsz)
+ctypes.memmove(ctypes.pointer(note), vmcoreinfo, ctypes.sizeof(note))
+header_size = ctypes.sizeof(note) - header.n_descsz
+
+if phys_base:
+desc = bytearray(note.n_desc).decode().split()
+if not next((v for v in desc if 
v.startswith('NUMBER(phys_base)=')),
+False):
+desc.append('NUMBER(phys_base)=%ld' % phys_base)
+desc = "\n".join(desc) + '\n'
+descsz = (len(desc) + 3) // 4 * 4
+desc += '\0' * (descsz - len(desc))
+note = get_arch_note(self.endianness, header.n_namesz - 1, descsz)
+ctypes.memmove(ctypes.pointer(note), vmcoreinfo, header_size)
+note.n_descsz = descsz
+ctypes.memmove(note.n_desc, desc.encode(), descsz)
+
+self.notes.append(note)
+self.segments[0].p_filesz += ctypes.sizeof(note)
+self.segments[0].p_memsz += ctypes.sizeof(note)
+
 def add_segment(self, p_type, p_paddr, p_size):
 """Adds a segment to the elf."""
 
@@ -505,6 +532,30 @@ shape and this command should mostly work."""
 cur += chunk_size
 left -= chunk_size
 
+def get_vmcoreinfo(self):
+qemu_core = gdb.inferiors()[0]
+
+try:
+coreinfo = gdb.parse_and_eval("dump_info.vmcoreinfo")
+except gdb.error:
+return
+
+if coreinfo == 0:
+return
+
+phys_base = None
+has_phys_base = gdb.parse_and_eval("dump_info.has_phys_base")
+if has_phys_base:
+phys_base = int(gdb.parse_and_eval("dump_info.phys_base"))
+
+addr, size = [int(val, 16) for val in coreinfo.string().split()]
+for block in self.guest_phys_blocks:
+if block["target_start"] <= addr < block["target_end"]:
+haddr = block["host_addr"] + (addr - block["target_start"])
+vmcoreinfo = qemu_core.read_memory(haddr, size)
+self.elf.add_vmcoreinfo_note(vmcoreinfo.tobytes(), phys_base)
+return
+
 def invoke(self, args, from_tty):
 """Handles command invocation from gdb."""
 
@@ -518,6 +569,7 @@ shape and this command should mostly work."""
 
 self.elf = ELF(argv[1])
 self.guest_phys_blocks = get_guest_phys_blocks()
+self.get_vmcoreinfo()
 
 with open(argv[0], "wb") as vmcore:
 self.dump_init(vmcore)
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 18/21] dump: use qga VMDUMP_INFO for ELF dump

2017-03-11 Thread Marc-André Lureau
Add vmcoreinfo ELF note.

NUMBRE(phys_base) in vmcoreinfo has only been recently introduced in
Linux 4.10 ("kexec: export the value of phys_base instead of symbol
address"). To accomadate for older kernels, modify the vmcoreinfo to add
the new fields and help newer crash that will use it.

Signed-off-by: Marc-André Lureau 
---
 include/sysemu/dump.h |   2 +
 dump.c| 133 ++
 2 files changed, 135 insertions(+)

diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index ef931be469..ff0e9894b7 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -191,6 +191,8 @@ typedef struct DumpState {
   * this could be used to calculate
   * how much work we have
   * finished. */
+uint8_t *vmcoreinfo;
+size_t vmcoreinfo_size;
 } DumpState;
 
 uint16_t cpu_to_dump16(DumpState *s, uint16_t val);
diff --git a/dump.c b/dump.c
index 68b406459e..0ebfb5471a 100644
--- a/dump.c
+++ b/dump.c
@@ -27,6 +27,7 @@
 #include "qapi/qmp/qerror.h"
 #include "qmp-commands.h"
 #include "qapi-event.h"
+#include "qemu/error-report.h"
 
 #include 
 #ifdef CONFIG_LZO
@@ -82,6 +83,8 @@ static int dump_cleanup(DumpState *s)
 if (s->resume) {
 vm_start();
 }
+g_free(s->vmcoreinfo);
+s->vmcoreinfo = NULL;
 
 return 0;
 }
@@ -232,6 +235,19 @@ static inline int cpu_index(CPUState *cpu)
 return cpu->cpu_index + 1;
 }
 
+static void write_vmcoreinfo_note(WriteCoreDumpFunction f, DumpState *s,
+  Error **errp)
+{
+int ret;
+
+if (s->vmcoreinfo) {
+ret = f(s->vmcoreinfo, s->vmcoreinfo_size, s);
+if (ret < 0) {
+error_setg(errp, "dump: failed to write vmcoreinfo");
+}
+}
+}
+
 static void write_elf64_notes(WriteCoreDumpFunction f, DumpState *s,
   Error **errp)
 {
@@ -255,6 +271,8 @@ static void write_elf64_notes(WriteCoreDumpFunction f, 
DumpState *s,
 return;
 }
 }
+
+write_vmcoreinfo_note(f, s, errp);
 }
 
 static void write_elf32_note(DumpState *s, Error **errp)
@@ -300,6 +318,8 @@ static void write_elf32_notes(WriteCoreDumpFunction f, 
DumpState *s,
 return;
 }
 }
+
+write_vmcoreinfo_note(f, s, errp);
 }
 
 static void write_elf_section(DumpState *s, int type, Error **errp)
@@ -711,6 +731,50 @@ static int buf_write_note(const void *buf, size_t size, 
void *opaque)
 return 0;
 }
 
+static void get_note_sizes(DumpState *s, const void *note,
+   uint64_t *note_head_size,
+   uint64_t *name_size,
+   uint64_t *desc_size)
+{
+uint64_t note_head_sz;
+uint64_t name_sz;
+uint64_t desc_sz;
+
+if (s->dump_info.d_class == ELFCLASS64) {
+const Elf64_Nhdr *hdr = note;
+note_head_sz = sizeof(Elf64_Nhdr);
+name_sz = hdr->n_namesz;
+desc_sz = hdr->n_descsz;
+} else {
+const Elf32_Nhdr *hdr = note;
+note_head_sz = sizeof(Elf32_Nhdr);
+name_sz = hdr->n_namesz;
+desc_sz = hdr->n_descsz;
+}
+
+if (note_head_size) {
+*note_head_size = note_head_sz;
+}
+if (name_size) {
+*name_size = name_sz;
+}
+if (desc_size) {
+*desc_size = desc_sz;
+}
+}
+
+static void set_note_desc_size(DumpState *s, void *note,
+   uint64_t desc_size)
+{
+if (s->dump_info.d_class == ELFCLASS64) {
+Elf64_Nhdr *hdr = note;
+hdr->n_descsz = desc_size;
+} else {
+Elf32_Nhdr *hdr = note;
+hdr->n_descsz = desc_size;
+}
+}
+
 /* write common header, sub header and elf note to vmcore */
 static void create_header32(DumpState *s, Error **errp)
 {
@@ -1485,6 +1549,42 @@ static int64_t dump_calculate_size(DumpState *s)
 return total;
 }
 
+static void vmcoreinfo_add_phys_base(DumpState *s)
+{
+uint64_t size, note_head_size, name_size;
+char **lines, *physbase = NULL;
+uint8_t *newvmci, *vmci;
+size_t i;
+
+get_note_sizes(s, s->vmcoreinfo, ¬e_head_size, &name_size, &size);
+note_head_size = ((note_head_size + 3) / 4) * 4;
+name_size = ((name_size + 3) / 4) * 4;
+vmci = s->vmcoreinfo + note_head_size + name_size;
+*(vmci + size) = '\0';
+lines = g_strsplit((char *)vmci, "\n", -1);
+for (i = 0; lines[i]; i++) {
+if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
+goto end;
+}
+}
+
+physbase = g_strdup_printf("\nNUMBER(phys_base)=%ld",
+   s->dump_info.phys_base);
+s->vmcoreinfo_size =
+((note_head_size + name_size + size + strlen(physbase) + 3) / 4) * 4;
+
+newvmci = g_malloc(s->vmcoreinfo_size);
+memcpy(newvmci, s->vmcoreinfo, note_head_size + name_size + size - 1);
+memcpy(newvmci + note_head_size + name_size + size - 

[Qemu-devel] [PATCH 12/21] test-qga: drop everything until guest-sync

2017-03-11 Thread Marc-André Lureau
In the following commits, qemu-ga will emit an event on connect that
a real client should treat or ignore and test-qga can skip.

Signed-off-by: Marc-André Lureau 
---
 tests/test-qga.c | 27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/tests/test-qga.c b/tests/test-qga.c
index c780f0079a..e1f59b7370 100644
--- a/tests/test-qga.c
+++ b/tests/test-qga.c
@@ -13,6 +13,8 @@ typedef struct {
 GPid pid;
 } TestFixture;
 
+static void guest_sync_delimited(const TestFixture *fixture);
+
 static int connect_qga(char *path)
 {
 int s, ret, len, i = 0;
@@ -45,12 +47,13 @@ static void qga_watch(GPid pid, gint status, gpointer 
user_data)
 g_main_loop_quit(fixture->loop);
 }
 
+
 static void
 fixture_setup(TestFixture *fixture, gconstpointer data)
 {
 const gchar *extra_arg = data;
 GError *error = NULL;
-gchar *cwd, *path, *cmd, **argv = NULL;
+char *cwd, *path, *cmd, **argv = NULL;
 
 fixture->loop = g_main_loop_new(NULL, FALSE);
 
@@ -77,6 +80,8 @@ fixture_setup(TestFixture *fixture, gconstpointer data)
 fixture->fd = connect_qga(path);
 g_assert_cmpint(fixture->fd, !=, -1);
 
+guest_sync_delimited(fixture);
+
 g_strfreev(argv);
 g_free(cmd);
 g_free(cwd);
@@ -138,9 +143,8 @@ static void qmp_assertion_message_error(const char 
*domain,
 }   \
 } while (0)
 
-static void test_qga_sync_delimited(gconstpointer fix)
+static void guest_sync_delimited(const TestFixture *fixture)
 {
-const TestFixture *fixture = fix;
 guint32 v, r = g_random_int();
 unsigned char c;
 QDict *ret;
@@ -148,12 +152,13 @@ static void test_qga_sync_delimited(gconstpointer fix)
 
 cmd = g_strdup_printf("%c{'execute': 'guest-sync-delimited',"
   " 'arguments': {'id': %u } }", 0xff, r);
+
 qmp_fd_send(fixture->fd, cmd);
-g_free(cmd);
 
-v = read(fixture->fd, &c, 1);
-g_assert_cmpint(v, ==, 1);
-g_assert_cmpint(c, ==, 0xff);
+do {
+v = read(fixture->fd, &c, 1);
+g_assert_cmpint(v, ==, 1);
+} while (c != 0xff);
 
 ret = qmp_fd_receive(fixture->fd);
 g_assert_nonnull(ret);
@@ -163,6 +168,14 @@ static void test_qga_sync_delimited(gconstpointer fix)
 g_assert_cmpint(r, ==, v);
 
 QDECREF(ret);
+g_free(cmd);
+}
+
+static void test_qga_sync_delimited(gconstpointer fix)
+{
+const TestFixture *fixture = fix;
+
+guest_sync_delimited(fixture);
 }
 
 static void test_qga_sync(gconstpointer fix)
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 20/21] scripts/dump-guest-memory.py: fix int128_get64 on recent gcc

2017-03-11 Thread Marc-André Lureau
The Int128 is no longer a struct, reaching a python exception:
Python Exception  Attempt to extract a component of a value 
that is not a (null).:

Replace struct access with a cast to uint64 instead.

Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1427466

Signed-off-by: Marc-André Lureau 
---
 scripts/dump-guest-memory.py | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
index 9956fc036c..f7c6635f15 100644
--- a/scripts/dump-guest-memory.py
+++ b/scripts/dump-guest-memory.py
@@ -314,8 +314,18 @@ def get_arch_phdr(endianness, elfclass):
 def int128_get64(val):
 """Returns low 64bit part of Int128 struct."""
 
-assert val["hi"] == 0
-return val["lo"]
+try:
+assert val["hi"] == 0
+return val["lo"]
+except gdb.error:
+u64t = gdb.lookup_type('uint64_t').array(2)
+u64 = val.cast(u64t)
+if sys.byteorder == 'little':
+assert u64[1] == 0
+return u64[0]
+else:
+assert u64[0] == 0
+return u64[1]
 
 
 def qlist_foreach(head, field_str):
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 17/21] virtio-channel: parse qga stream for VMDUMP_INFO event

2017-03-11 Thread Marc-André Lureau
On virtio channel "org.qemu.guest_agent.0", parse the json stream until
the VMDUMP_INFO is received and retrieve the dump details.

Signed-off-by: Marc-André Lureau 
---
 include/sysemu/dump-info.h | 15 +
 dump.c |  3 +++
 hw/char/virtio-console.c   | 53 ++
 3 files changed, 71 insertions(+)
 create mode 100644 include/sysemu/dump-info.h

diff --git a/include/sysemu/dump-info.h b/include/sysemu/dump-info.h
new file mode 100644
index 00..fb1ddff9af
--- /dev/null
+++ b/include/sysemu/dump-info.h
@@ -0,0 +1,15 @@
+#ifndef DUMP_INFO_H
+#define DUMP_INFO_H
+
+typedef struct DumpInfo {
+bool received;
+bool has_phys_base;
+uint64_t phys_base;
+bool has_text;
+uint64_t text;
+char *vmcoreinfo;
+} DumpInfo;
+
+extern DumpInfo dump_info;
+
+#endif /* DUMP_INFO_H */
diff --git a/dump.c b/dump.c
index f7b80d856b..68b406459e 100644
--- a/dump.c
+++ b/dump.c
@@ -20,6 +20,7 @@
 #include "monitor/monitor.h"
 #include "sysemu/kvm.h"
 #include "sysemu/dump.h"
+#include "sysemu/dump-info.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/memory_mapping.h"
 #include "sysemu/cpus.h"
@@ -38,6 +39,8 @@
 #define ELF_MACHINE_UNAME "Unknown"
 #endif
 
+DumpInfo dump_info = { 0, };
+
 uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
 {
 if (s->dump_info.d_endian == ELFDATA2LSB) {
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 798d9b69fd..796b7c85aa 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -16,6 +16,9 @@
 #include "trace.h"
 #include "hw/virtio/virtio-serial.h"
 #include "qapi-event.h"
+#include "qapi/qmp/json-streamer.h"
+#include "qapi/qmp/json-parser.h"
+#include "sysemu/dump-info.h"
 
 #define TYPE_VIRTIO_CONSOLE_SERIAL_PORT "virtserialport"
 #define VIRTIO_CONSOLE(obj) \
@@ -26,6 +29,7 @@ typedef struct VirtConsole {
 
 CharBackend chr;
 guint watch;
+JSONMessageParser parser;
 } VirtConsole;
 
 /*
@@ -49,6 +53,11 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
 VirtConsole *vcon = VIRTIO_CONSOLE(port);
 ssize_t ret;
 
+if (vcon->parser.emit &&
+!dump_info.received) {
+json_message_parser_feed(&vcon->parser, (const char *)buf, len);
+}
+
 if (!qemu_chr_fe_get_driver(&vcon->chr)) {
 /* If there's no backend, we can just say we consumed all data. */
 return len;
@@ -108,6 +117,11 @@ static void set_guest_connected(VirtIOSerialPort *port, 
int guest_connected)
 DeviceState *dev = DEVICE(port);
 VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
 
+if (guest_connected && !port->guest_connected) {
+g_free(dump_info.vmcoreinfo);
+memset(&dump_info, 0, sizeof(dump_info));
+}
+
 if (!k->is_console) {
 qemu_chr_fe_set_open(&vcon->chr, guest_connected);
 }
@@ -163,6 +177,37 @@ static void chr_event(void *opaque, int event)
 }
 }
 
+
+static void qga_message(JSONMessageParser *parser, GQueue *tokens)
+{
+/* VirtConsole *vcon = container_of(parser, VirtConsole, parser); */
+QObject *obj;
+QDict *msg, *data;
+const char *event;
+
+obj = json_parser_parse(tokens, NULL);
+msg = qobject_to_qdict(obj);
+if (!msg) {
+error_report("JSON parsing failed");
+return;
+}
+
+event = qdict_get_try_str(msg, "event");
+data = qdict_get_qdict(msg, "data");
+if (event && g_str_equal(event, "VMDUMP_INFO") && data) {
+dump_info.received = true;
+if (qdict_haskey(data, "phys-base")) {
+dump_info.has_phys_base = true;
+dump_info.phys_base = qdict_get_try_uint(data, "phys-base", 0);
+}
+if (qdict_haskey(data, "text")) {
+dump_info.has_text = true;
+dump_info.text = qdict_get_try_uint(data, "text", 0);
+}
+dump_info.vmcoreinfo = g_strdup(qdict_get_try_str(data, "vmcoreinfo"));
+}
+}
+
 static void virtconsole_realize(DeviceState *dev, Error **errp)
 {
 VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
@@ -195,6 +240,10 @@ static void virtconsole_realize(DeviceState *dev, Error 
**errp)
  chr_event, vcon, NULL, false);
 }
 }
+
+if (port->name && g_str_equal(port->name, "org.qemu.guest_agent.0")) {
+json_message_parser_init(&vcon->parser, qga_message);
+}
 }
 
 static void virtconsole_unrealize(DeviceState *dev, Error **errp)
@@ -204,6 +253,10 @@ static void virtconsole_unrealize(DeviceState *dev, Error 
**errp)
 if (vcon->watch) {
 g_source_remove(vcon->watch);
 }
+
+if (vcon->parser.emit) {
+json_message_parser_destroy(&vcon->parser);
+}
 }
 
 static void virtconsole_class_init(ObjectClass *klass, void *data)
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 16/21] qga: emit VMDUMP_INFO event

2017-03-11 Thread Marc-André Lureau
When client connects, emit the VMDUMP_INFO.

Signed-off-by: Marc-André Lureau 
---
 qga/guest-agent-core.h |  2 ++
 qga/channel-posix.c| 11 +++
 qga/main.c | 13 +
 Makefile   |  7 ++-
 qga/Makefile.objs  |  1 +
 qga/qapi-schema.json   | 15 +++
 6 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/qga/guest-agent-core.h b/qga/guest-agent-core.h
index 3e8a4acff2..1880b0f0ac 100644
--- a/qga/guest-agent-core.h
+++ b/qga/guest-agent-core.h
@@ -46,3 +46,5 @@ int ga_parse_whence(GuestFileWhence *whence, Error **errp);
 #ifndef _WIN32
 void reopen_fd_to_null(int fd);
 #endif
+
+void ga_client_added(void);
diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 3f34465159..5999df0684 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -3,6 +3,7 @@
 #include "qapi/error.h"
 #include "qemu/sockets.h"
 #include "qga/channel.h"
+#include "qga/guest-agent-core.h"
 
 #ifdef CONFIG_SOLARIS
 #include 
@@ -98,6 +99,13 @@ static gboolean ga_channel_client_event(GIOChannel *channel,
 return true;
 }
 
+static gboolean client_added_idle_cb(gpointer user_data)
+{
+ga_client_added();
+
+return false;
+}
+
 static int ga_channel_client_add(GAChannel *c, int fd)
 {
 GIOChannel *client_channel;
@@ -115,6 +123,9 @@ static int ga_channel_client_add(GAChannel *c, int fd)
 g_io_add_watch(client_channel, G_IO_IN | G_IO_HUP,
ga_channel_client_event, c);
 c->client_channel = client_channel;
+
+g_idle_add(client_added_idle_cb, NULL);
+
 return 0;
 }
 
diff --git a/qga/main.c b/qga/main.c
index 8e852bd556..d2a874e67a 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -40,6 +40,7 @@
 #endif
 #endif
 #include "qapi/qmp-event.h"
+#include "qga-qapi-event.h"
 
 #ifndef _WIN32
 #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
@@ -691,6 +692,18 @@ static gboolean channel_event_cb(GIOCondition condition, 
gpointer data)
 return true;
 }
 
+void ga_client_added(void)
+{
+#ifndef _WIN32
+GAState *s = ga_state;
+
+qapi_event_send_vmdump_info(s->vmdump.has_phys_base, s->vmdump.phys_base,
+s->vmdump.has_text, s->vmdump.text,
+s->vmdump.vmcoreinfo != NULL,
+s->vmdump.vmcoreinfo, NULL);
+#endif
+}
+
 static gboolean channel_init(GAState *s, const gchar *method, const gchar 
*path,
  int listen_fd)
 {
diff --git a/Makefile b/Makefile
index 1c4c04f6f2..fc7e321041 100644
--- a/Makefile
+++ b/Makefile
@@ -404,6 +404,11 @@ $(SRC_PATH)/qga/qapi-schema.json 
$(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
$(gen-out-type) -o qga/qapi-generated -p "qga-" $<, \
"GEN","$@")
+qga/qapi-generated/qga-qapi-event.c qga/qapi-generated/qga-qapi-event.h :\
+$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py 
$(qapi-py)
+   $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
+   $(gen-out-type)  -o qga/qapi-generated -p "qga-" $<, \
+   "GEN","$@")
 
 qapi-modules = $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
@@ -437,7 +442,7 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py 
$(qapi-py)
$(gen-out-type) -o "." $<, \
"GEN","$@")
 
-QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h 
qga-qmp-commands.h)
+QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h 
qga-qmp-commands.h qga-qapi-event.h)
 $(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
 
 qemu-ga$(EXESUF): $(qga-obj-y) $(COMMON_LDADDS)
diff --git a/qga/Makefile.objs b/qga/Makefile.objs
index 1c5986c0bb..d22977f0e1 100644
--- a/qga/Makefile.objs
+++ b/qga/Makefile.objs
@@ -4,5 +4,6 @@ qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o 
service-win32.o
 qga-obj-$(CONFIG_WIN32) += vss-win32.o
 qga-obj-y += qapi-generated/qga-qapi-types.o qapi-generated/qga-qapi-visit.o
 qga-obj-y += qapi-generated/qga-qmp-marshal.o
+qga-obj-y += qapi-generated/qga-qapi-event.o
 
 qga-vss-dll-obj-$(CONFIG_QGA_VSS) += vss-win32/
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index d421609dcb..2a95af3399 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -48,6 +48,21 @@
   'returns': 'int' }
 
 ##
+# @VMDUMP_INFO:
+#
+# Provides VM dump information details to qemu.
+#
+# @phys-base: base address
+#
+# @text: "_text" location
+#
+# @vmcoreinfo: the content of /sys/kernel/vmcoreinfo on Linux
+#
+##
+{ 'event': 'VMDUMP_INFO',
+  'data': { '*phys-base': 'uint64', '*text': 'uint64', '*vmcoreinfo': 'str' } }
+
+##
 # @guest-sync:
 #
 # Echo back a unique integer value
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 09/21] qdev: use appropriate type

2017-03-11 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 hw/i386/acpi-build.c  | 15 ---
 hw/pci-host/gpex.c|  2 +-
 hw/pci-host/q35.c |  2 +-
 hw/pci-host/xilinx-pcie.c |  2 +-
 target/i386/cpu.c |  2 +-
 5 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 2073108577..76bff18e3f 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -58,6 +58,7 @@
 #include "hw/acpi/aml-build.h"
 
 #include "qapi/qmp/qint.h"
+#include "qapi/qmp/quint.h"
 #include "qom/qom-qobject.h"
 #include "hw/i386/amd_iommu.h"
 #include "hw/i386/intel_iommu.h"
@@ -150,21 +151,21 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
 /* Fill in optional s3/s4 related properties */
 o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
 if (o) {
-pm->s3_disabled = qint_get_int(qobject_to_qint(o));
+pm->s3_disabled = quint_get_uint(qobject_to_quint(o));
 } else {
 pm->s3_disabled = false;
 }
 qobject_decref(o);
 o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
 if (o) {
-pm->s4_disabled = qint_get_int(qobject_to_qint(o));
+pm->s4_disabled = quint_get_uint(qobject_to_quint(o));
 } else {
 pm->s4_disabled = false;
 }
 qobject_decref(o);
 o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
 if (o) {
-pm->s4_val = qint_get_int(qobject_to_qint(o));
+pm->s4_val = quint_get_uint(qobject_to_quint(o));
 } else {
 pm->s4_val = false;
 }
@@ -500,7 +501,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, 
PCIBus *bus,
 
 bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, 
NULL);
 if (bsel) {
-int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
+uint64_t bsel_val = quint_get_uint(qobject_to_quint(bsel));
 
 aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
 notify_method = aml_method("DVNT", 2, AML_NOTSERIALIZED);
@@ -610,7 +611,7 @@ static void build_append_pci_bus_devices(Aml *parent_scope, 
PCIBus *bus,
 
 /* If bus supports hotplug select it and notify about local events */
 if (bsel) {
-int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
+uint64_t bsel_val = quint_get_uint(qobject_to_quint(bsel));
 aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
 aml_append(method,
 aml_call2("DVNT", aml_name("PCIU"), aml_int(1) /* Device Check */)
@@ -2586,12 +2587,12 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
 if (!o) {
 return false;
 }
-mcfg->mcfg_base = qint_get_int(qobject_to_qint(o));
+mcfg->mcfg_base = quint_get_uint(qobject_to_quint(o));
 qobject_decref(o);
 
 o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
 assert(o);
-mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
+mcfg->mcfg_size = quint_get_uint(qobject_to_quint(o));
 qobject_decref(o);
 return true;
 }
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index 66055ee5cc..8d3a64008c 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -94,7 +94,7 @@ static void gpex_host_initfn(Object *obj)
 
 object_initialize(root, sizeof(*root), TYPE_GPEX_ROOT_DEVICE);
 object_property_add_child(obj, "gpex_root", OBJECT(root), NULL);
-qdev_prop_set_uint32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
+qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
 qdev_prop_set_bit(DEVICE(root), "multifunction", false);
 }
 
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 5438be8253..3cbe8cfcea 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -173,7 +173,7 @@ static void q35_host_initfn(Object *obj)
 
 object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
 object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
-qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
+qdev_prop_set_int32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
 qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
 
 object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index 8b71e2d950..461ed41151 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -150,7 +150,7 @@ static void xilinx_pcie_host_init(Object *obj)
 
 object_initialize(root, sizeof(*root), TYPE_XILINX_PCIE_ROOT);
 object_property_add_child(obj, "root", OBJECT(root), NULL);
-qdev_prop_set_uint32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
+qdev_prop_set_int32(DEVICE(root), "addr", PCI_DEVFN(0, 0));
 qdev_prop_set_bit(DEVICE(root), "multifunction", false);
 }
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index fba92125ab..54f859bc8d 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3176,7 +3176,7 @@ static void x86_cpu_apic_create(X86CPU *cpu

[Qemu-devel] [PATCH 19/21] kdump: write vmcoreinfo in header

2017-03-11 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 dump.c | 48 
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/dump.c b/dump.c
index 0ebfb5471a..bf88cb362b 100644
--- a/dump.c
+++ b/dump.c
@@ -785,8 +785,9 @@ static void create_header32(DumpState *s, Error **errp)
 uint32_t sub_hdr_size;
 uint32_t bitmap_blocks;
 uint32_t status = 0;
-uint64_t offset_note;
+uint64_t offset_note, offset_vmcoreinfo, size_vmcoreinfo = 0;
 Error *local_err = NULL;
+uint8_t *vmcoreinfo = NULL;
 
 /* write common header, the version of kdump-compressed format is 6th */
 size = sizeof(DiskDumpHeader32);
@@ -835,7 +836,18 @@ static void create_header32(DumpState *s, Error **errp)
 kh->phys_base = cpu_to_dump32(s, s->dump_info.phys_base);
 kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
 
-offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+offset_vmcoreinfo = DISKDUMP_HEADER_BLOCKS * block_size + size;
+if (s->vmcoreinfo) {
+uint64_t hsize, name_size;
+
+get_note_sizes(s, s->vmcoreinfo, &hsize, &name_size, &size_vmcoreinfo);
+vmcoreinfo =
+s->vmcoreinfo + ((hsize + 3) / 4 + (name_size + 3) / 4) * 4;
+kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
+kh->size_vmcoreinfo = cpu_to_dump32(s, size_vmcoreinfo);
+}
+
+offset_note = offset_vmcoreinfo + size_vmcoreinfo;
 kh->offset_note = cpu_to_dump64(s, offset_note);
 kh->note_size = cpu_to_dump32(s, s->note_size);
 
@@ -845,6 +857,14 @@ static void create_header32(DumpState *s, Error **errp)
 goto out;
 }
 
+if (vmcoreinfo) {
+if (write_buffer(s->fd, offset_vmcoreinfo, vmcoreinfo,
+ size_vmcoreinfo) < 0) {
+error_setg(errp, "dump: failed to vmcoreinfo");
+goto out;
+}
+}
+
 /* write note */
 s->note_buf = g_malloc0(s->note_size);
 s->note_buf_offset = 0;
@@ -885,8 +905,9 @@ static void create_header64(DumpState *s, Error **errp)
 uint32_t sub_hdr_size;
 uint32_t bitmap_blocks;
 uint32_t status = 0;
-uint64_t offset_note;
+uint64_t offset_note, offset_vmcoreinfo, size_vmcoreinfo = 0;
 Error *local_err = NULL;
+uint8_t *vmcoreinfo = NULL;
 
 /* write common header, the version of kdump-compressed format is 6th */
 size = sizeof(DiskDumpHeader64);
@@ -935,7 +956,18 @@ static void create_header64(DumpState *s, Error **errp)
 kh->phys_base = cpu_to_dump64(s, s->dump_info.phys_base);
 kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
 
-offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
+offset_vmcoreinfo = DISKDUMP_HEADER_BLOCKS * block_size + size;
+if (s->vmcoreinfo) {
+uint64_t hsize, name_size;
+
+get_note_sizes(s, s->vmcoreinfo, &hsize, &name_size, &size_vmcoreinfo);
+vmcoreinfo =
+s->vmcoreinfo + ((hsize + 3) / 4 + (name_size + 3) / 4) * 4;
+kh->offset_vmcoreinfo = cpu_to_dump64(s, offset_vmcoreinfo);
+kh->size_vmcoreinfo = cpu_to_dump64(s, size_vmcoreinfo);
+}
+
+offset_note = offset_vmcoreinfo + size_vmcoreinfo;
 kh->offset_note = cpu_to_dump64(s, offset_note);
 kh->note_size = cpu_to_dump64(s, s->note_size);
 
@@ -945,6 +977,14 @@ static void create_header64(DumpState *s, Error **errp)
 goto out;
 }
 
+if (vmcoreinfo) {
+if (write_buffer(s->fd, offset_vmcoreinfo, vmcoreinfo,
+ size_vmcoreinfo) < 0) {
+error_setg(errp, "dump: failed to vmcoreinfo");
+goto out;
+}
+}
+
 /* write note */
 s->note_buf = g_malloc0(s->note_size);
 s->note_buf_offset = 0;
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 11/21] qdict: learn to lookup quint

2017-03-11 Thread Marc-André Lureau
Since a number may be parsed as an integer if it fits, learn to deal
with this situtation and fallback on QInt if QUint failed. There is no
need for exact type getters in qemu yet.

Signed-off-by: Marc-André Lureau 
---
 include/qapi/qmp/qdict.h |  2 ++
 qobject/qdict.c  | 37 -
 tests/check-qdict.c  | 31 +++
 util/qemu-option.c   |  6 ++
 4 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h
index fe9a4c5c60..dae3149603 100644
--- a/include/qapi/qmp/qdict.h
+++ b/include/qapi/qmp/qdict.h
@@ -61,6 +61,8 @@ QDict *qdict_get_qdict(const QDict *qdict, const char *key);
 const char *qdict_get_str(const QDict *qdict, const char *key);
 int64_t qdict_get_try_int(const QDict *qdict, const char *key,
   int64_t def_value);
+uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
+Error **errp);
 bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value);
 const char *qdict_get_try_str(const QDict *qdict, const char *key);
 
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 291eef1a19..8d5c028181 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -12,6 +12,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/qmp/qint.h"
+#include "qapi/qmp/quint.h"
 #include "qapi/qmp/qfloat.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qbool.h"
@@ -181,7 +182,7 @@ size_t qdict_size(const QDict *qdict)
  * qdict_get_double(): Get an number mapped by 'key'
  *
  * This function assumes that 'key' exists and it stores a
- * QFloat or QInt object.
+ * QFloat, QInt or QUInt object.
  *
  * Return number mapped by 'key'.
  */
@@ -195,6 +196,8 @@ double qdict_get_double(const QDict *qdict, const char *key)
 return qfloat_get_double(qobject_to_qfloat(obj));
 case QTYPE_QINT:
 return qint_get_int(qobject_to_qint(obj));
+case QTYPE_QUINT:
+return quint_get_uint(qobject_to_quint(obj));
 default:
 abort();
 }
@@ -272,6 +275,38 @@ int64_t qdict_get_try_int(const QDict *qdict, const char 
*key,
 }
 
 /**
+ * qdict_get_try_uint(): Try to get unsigned mapped by 'key'
+ *
+ * Return integer mapped by 'key', if it is not present in
+ * the dictionary or with negative value, returns 0 and set error.
+ */
+uint64_t qdict_get_try_uint(const QDict *qdict, const char *key,
+Error **errp)
+{
+QUInt *quint = qobject_to_quint(qdict_get(qdict, key));
+QInt *qint;
+int val;
+
+if (quint) {
+return quint_get_uint(quint);
+}
+
+qint = qobject_to_qint(qdict_get(qdict, key));
+if (!qint) {
+error_setg(errp, "Missing key or type mismatch");
+return 0;
+}
+
+val = qint_get_int(qint);
+if (val < 0) {
+error_setg(errp, "Invalid value, unsigned int expected");
+return 0;
+}
+
+return val;
+}
+
+/**
  * qdict_get_try_bool(): Try to get a bool mapped by 'key'
  *
  * Return bool mapped by 'key', if it is not present in the
diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index 81162ee572..80a8aef689 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -12,6 +12,7 @@
 #include "qemu/osdep.h"
 
 #include "qapi/qmp/qint.h"
+#include "qapi/qmp/quint.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi/error.h"
@@ -121,6 +122,35 @@ static void qdict_get_try_int_test(void)
 QDECREF(tests_dict);
 }
 
+static void qdict_get_try_uint_test(void)
+{
+uint64_t ret;
+const int ivalue = 100;
+const uint64_t uvalue = G_MAXUINT64;
+const char *key = "uint";
+QDict *tests_dict = qdict_new();
+Error *err = NULL;
+
+qdict_put(tests_dict, key, qint_from_int(ivalue));
+/* try_uint will work with int types too */
+ret = qdict_get_try_uint(tests_dict, key, &err);
+g_assert_cmpint(ret, ==, ivalue);
+g_assert(!err);
+
+qdict_put(tests_dict, key, quint_from_uint(uvalue));
+ret = qdict_get_try_uint(tests_dict, key, &err);
+g_assert_cmpint(ret, ==, uvalue);
+g_assert(!err);
+
+qdict_put(tests_dict, key, qint_from_int(-1));
+/* try_uint will fail with negative values */
+ret = qdict_get_try_uint(tests_dict, key, &err);
+g_assert(err);
+error_free(err);
+
+QDECREF(tests_dict);
+}
+
 static void qdict_get_str_test(void)
 {
 const char *p;
@@ -854,6 +884,7 @@ int main(int argc, char **argv)
 g_test_add_func("/public/get", qdict_get_test);
 g_test_add_func("/public/get_int", qdict_get_int_test);
 g_test_add_func("/public/get_try_int", qdict_get_try_int_test);
+g_test_add_func("/public/get_try_uint", qdict_get_try_uint_test);
 g_test_add_func("/public/get_str", qdict_get_str_test);
 g_test_add_func("/public/get_try_str", qdict_get_try_str_test);
 g_test_add_func("/public/defaults", qdict_defaults_test);
diff --git a/util/qemu-option.c b/util/qemu-option.c
in

[Qemu-devel] [PATCH 10/21] Use uint property getter/setter where appropriate

2017-03-11 Thread Marc-André Lureau
All those property usages are associated with unsigned integers, so use
appropriate getter/setter.

Signed-off-by: Marc-André Lureau 
---
 include/hw/isa/isa.h |  2 +-
 hw/acpi/memory_hotplug.c | 10 
 hw/acpi/nvdimm.c | 10 
 hw/acpi/pcihp.c  |  6 ++---
 hw/arm/aspeed.c  |  4 ++--
 hw/arm/bcm2835_peripherals.c |  9 
 hw/arm/raspi.c   |  4 ++--
 hw/core/platform-bus.c   |  2 +-
 hw/i386/acpi-build.c | 55 ++--
 hw/i386/pc.c |  6 ++---
 hw/intc/arm_gicv3_common.c   |  2 +-
 hw/mem/pc-dimm.c |  5 ++--
 hw/misc/auxbus.c |  2 +-
 hw/misc/pvpanic.c|  2 +-
 hw/ppc/pnv_core.c|  2 +-
 hw/ppc/spapr.c   |  8 ---
 numa.c   |  6 ++---
 target/i386/cpu.c|  4 ++--
 ui/console.c |  4 ++--
 xen-hvm.c|  6 ++---
 20 files changed, 77 insertions(+), 72 deletions(-)

diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index c2fdd70cdc..95593408ef 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -29,7 +29,7 @@ static inline uint16_t applesmc_port(void)
 Object *obj = object_resolve_path_type("", TYPE_APPLE_SMC, NULL);
 
 if (obj) {
-return object_property_get_int(obj, APPLESMC_PROP_IO_BASE, NULL);
+return object_property_get_uint(obj, APPLESMC_PROP_IO_BASE, NULL);
 }
 return 0;
 }
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 210073d283..db3c89ceab 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -83,11 +83,12 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, 
hwaddr addr,
 o = OBJECT(mdev->dimm);
 switch (addr) {
 case 0x0: /* Lo part of phys address where DIMM is mapped */
-val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) : 0;
+val = o ? object_property_get_uint(o, PC_DIMM_ADDR_PROP, NULL) : 0;
 trace_mhp_acpi_read_addr_lo(mem_st->selector, val);
 break;
 case 0x4: /* Hi part of phys address where DIMM is mapped */
-val = o ? object_property_get_int(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 
0;
+val =
+o ? object_property_get_uint(o, PC_DIMM_ADDR_PROP, NULL) >> 32 : 0;
 trace_mhp_acpi_read_addr_hi(mem_st->selector, val);
 break;
 case 0x8: /* Lo part of DIMM size */
@@ -95,11 +96,12 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, 
hwaddr addr,
 trace_mhp_acpi_read_size_lo(mem_st->selector, val);
 break;
 case 0xc: /* Hi part of DIMM size */
-val = o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 
0;
+val =
+o ? object_property_get_int(o, PC_DIMM_SIZE_PROP, NULL) >> 32 : 0;
 trace_mhp_acpi_read_size_hi(mem_st->selector, val);
 break;
 case 0x10: /* node proximity for _PXM method */
-val = o ? object_property_get_int(o, PC_DIMM_NODE_PROP, NULL) : 0;
+val = o ? object_property_get_uint(o, PC_DIMM_NODE_PROP, NULL) : 0;
 trace_mhp_acpi_read_pxm(mem_st->selector, val);
 break;
 case 0x14: /* pack and return is_* fields */
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index 8e7d6ec034..e57027149d 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -236,14 +236,14 @@ static void
 nvdimm_build_structure_spa(GArray *structures, DeviceState *dev)
 {
 NvdimmNfitSpa *nfit_spa;
-uint64_t addr = object_property_get_int(OBJECT(dev), PC_DIMM_ADDR_PROP,
-NULL);
+uint64_t addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP,
+ NULL);
 uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP,
 NULL);
-uint32_t node = object_property_get_int(OBJECT(dev), PC_DIMM_NODE_PROP,
-NULL);
+uint32_t node = object_property_get_uint(OBJECT(dev), PC_DIMM_NODE_PROP,
+ NULL);
 int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
-NULL);
+   NULL);
 
 nfit_spa = acpi_data_push(structures, sizeof(*nfit_spa));
 
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 2b0f3e1bfb..d0e9c4770a 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -63,10 +63,10 @@ typedef struct AcpiPciHpFind {
 static int acpi_pcihp_get_bsel(PCIBus *bus)
 {
 Error *local_err = NULL;
-int64_t bsel = object_property_get_int(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
-   &local_err);
+uint64_t bsel = object_property_get_uint(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
+ &local_err);
 
-if (local_err || bsel < 0 || bsel >= ACPI_P

[Qemu-devel] [PATCH 05/21] qapi: update the qobject visitor to use QUInt

2017-03-11 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 scripts/qapi-visit.py   |  3 ++-
 qapi/qobject-input-visitor.c| 30 --
 qapi/qobject-output-visitor.c   |  3 +--
 tests/test-qobject-input-visitor.c  | 15 +++
 tests/test-qobject-output-visitor.c | 19 +++
 5 files changed, 57 insertions(+), 13 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 330b9f321b..532f929e18 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -165,7 +165,8 @@ def gen_visit_alternate(name, variants):
 promote_int = 'true'
 ret = ''
 for var in variants.variants:
-if var.type.alternate_qtype() == 'QTYPE_QINT':
+if var.type.alternate_qtype() == 'QTYPE_QINT' \
+or var.type.alternate_qtype() == 'QTYPE_QUINT':
 promote_int = 'false'
 
 ret += mcgen('''
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index 865e948ac0..41a825b06b 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -21,6 +21,7 @@
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/types.h"
 #include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
 #include "qemu/cutils.h"
 #include "qemu/option.h"
 
@@ -349,7 +350,8 @@ static void qobject_input_start_alternate(Visitor *v, const 
char *name,
 }
 *obj = g_malloc0(size);
 (*obj)->type = qobject_type(qobj);
-if (promote_int && (*obj)->type == QTYPE_QINT) {
+if (promote_int &&
+((*obj)->type == QTYPE_QINT || (*obj)->type == QTYPE_QUINT)) {
 (*obj)->type = QTYPE_QFLOAT;
 }
 }
@@ -395,22 +397,38 @@ static void qobject_input_type_int64_keyval(Visitor *v, 
const char *name,
 static void qobject_input_type_uint64(Visitor *v, const char *name,
   uint64_t *obj, Error **errp)
 {
-/* FIXME: qobject_to_qint mishandles values over INT64_MAX */
 QObjectInputVisitor *qiv = to_qiv(v);
 QObject *qobj = qobject_input_get_object(qiv, name, true, errp);
+QUInt *quint;
 QInt *qint;
+int64_t val;
 
 if (!qobj) {
 return;
 }
+
+quint = qobject_to_quint(qobj);
+if (quint) {
+*obj = quint_get_uint(quint);
+return;
+}
+
 qint = qobject_to_qint(qobj);
 if (!qint) {
-error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
-   full_name(qiv, name), "integer");
-return;
+goto error;
 }
 
-*obj = qint_get_int(qint);
+val = qint_get_int(qint);
+if (val < 0) {
+goto error;
+}
+
+*obj = val;
+return;
+
+error:
+error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
+   full_name(qiv, name), "unsigned integer");
 }
 
 static void qobject_input_type_uint64_keyval(Visitor *v, const char *name,
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
index 871127079d..7066b3b59b 100644
--- a/qapi/qobject-output-visitor.c
+++ b/qapi/qobject-output-visitor.c
@@ -150,9 +150,8 @@ static void qobject_output_type_int64(Visitor *v, const 
char *name,
 static void qobject_output_type_uint64(Visitor *v, const char *name,
uint64_t *obj, Error **errp)
 {
-/* FIXME values larger than INT64_MAX become negative */
 QObjectOutputVisitor *qov = to_qov(v);
-qobject_output_add(qov, name, qint_from_int(*obj));
+qobject_output_add(qov, name, quint_from_uint(*obj));
 }
 
 static void qobject_output_type_bool(Visitor *v, const char *name, bool *obj,
diff --git a/tests/test-qobject-input-visitor.c 
b/tests/test-qobject-input-visitor.c
index 6eb48fee7b..011366a65b 100644
--- a/tests/test-qobject-input-visitor.c
+++ b/tests/test-qobject-input-visitor.c
@@ -170,6 +170,19 @@ static void 
test_visitor_in_int_str_fail(TestInputVisitorData *data,
 error_free_or_abort(&err);
 }
 
+static void test_visitor_in_uint(TestInputVisitorData *data,
+const void *unused)
+{
+uint64_t res = 0;
+uint64_t value = G_MAXUINT64;
+Visitor *v;
+
+v = visitor_input_test_init(data, "%" PRIu64, value);
+
+visit_type_uint64(v, NULL, &res, &error_abort);
+g_assert_cmpint(res, ==, value);
+}
+
 static void test_visitor_in_bool(TestInputVisitorData *data,
  const void *unused)
 {
@@ -1233,6 +1246,8 @@ int main(int argc, char **argv)
NULL, test_visitor_in_int_str_keyval);
 input_visitor_test_add("/visitor/input/int_str_fail",
NULL, test_visitor_in_int_str_fail);
+input_visitor_test_add("/visitor/input/uint",
+   NULL, test_visitor_in_uint);
 input_visitor_test_add("/visitor/input/bool",
NULL, test_visitor_in_bool);
 input_visitor_test_add("/visitor/input/bool_keyval",
diff --git a/tests/test-qobject-output-visitor.c 
b/tests/test-qobject-output-visitor.c
index 500b452d98..047c6b5c6c 100644
--- a/tes

[Qemu-devel] [PATCH 07/21] object: add uint property setter/getter

2017-03-11 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
---
 include/qom/object.h | 23 +++
 qom/object.c | 32 
 2 files changed, 55 insertions(+)

diff --git a/include/qom/object.h b/include/qom/object.h
index cd0f412ce9..abaeb8cf4e 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1094,6 +1094,29 @@ int64_t object_property_get_int(Object *obj, const char 
*name,
 Error **errp);
 
 /**
+ * object_property_set_uint:
+ * @value: the value to be written to the property
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Writes an unsigned integer value to a property.
+ */
+void object_property_set_uint(Object *obj, uint64_t value,
+  const char *name, Error **errp);
+
+/**
+ * object_property_get_uint:
+ * @obj: the object
+ * @name: the name of the property
+ * @errp: returns an error if this function fails
+ *
+ * Returns: the value of the property, converted to an unsigned integer, or 0
+ * an error occurs (including when the property value is not an integer).
+ */
+uint64_t object_property_get_uint(Object *obj, const char *name,
+  Error **errp);
+
+/**
  * object_property_get_enum:
  * @obj: the object
  * @name: the name of the property
diff --git a/qom/object.c b/qom/object.c
index c7b8079df6..ca9d4137b3 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -28,6 +28,7 @@
 #include "qapi/qmp/qobject.h"
 #include "qapi/qmp/qbool.h"
 #include "qapi/qmp/qint.h"
+#include "qapi/qmp/quint.h"
 #include "qapi/qmp/qstring.h"
 
 #define MAX_INTERFACES 32
@@ -1218,6 +1219,37 @@ int64_t object_property_get_int(Object *obj, const char 
*name,
 return retval;
 }
 
+void object_property_set_uint(Object *obj, uint64_t value,
+ const char *name, Error **errp)
+{
+QUInt *quint = quint_from_uint(value);
+object_property_set_qobject(obj, QOBJECT(quint), name, errp);
+
+QDECREF(quint);
+}
+
+uint64_t object_property_get_uint(Object *obj, const char *name,
+  Error **errp)
+{
+QObject *ret = object_property_get_qobject(obj, name, errp);
+QUInt *quint;
+uint64_t retval;
+
+if (!ret) {
+return 0;
+}
+quint = qobject_to_quint(ret);
+if (!quint) {
+error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name, "uint");
+retval = 0;
+} else {
+retval = quint_get_uint(quint);
+}
+
+qobject_decref(ret);
+return retval;
+}
+
 typedef struct EnumProperty {
 const char * const *strings;
 int (*get)(Object *, Error **);
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 13/21] qga: report error on keyfile dump error

2017-03-11 Thread Marc-André Lureau
Signed-off-by: Marc-André Lureau 
Cc:qemu-triv...@nongnu.org
---
 qga/main.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/qga/main.c b/qga/main.c
index 92658bc0e2..beff041340 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -1082,7 +1082,12 @@ static void config_dump(GAConfig *config)
 g_free(tmp);
 
 tmp = g_key_file_to_data(keyfile, NULL, &error);
-printf("%s", tmp);
+if (tmp) {
+printf("%s", tmp);
+} else if (error) {
+g_critical("Failed to dump keyfile: %s", error->message);
+g_clear_error(&error);
+}
 
 g_free(tmp);
 g_key_file_free(keyfile);
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 04/21] qobject: add quint type

2017-03-11 Thread Marc-André Lureau
The type is not used at all yet. Add some tests to exercice it.

Signed-off-by: Marc-André Lureau 
---
 qapi/introspect.json |  2 +-
 scripts/qapi.py  | 28 ---
 include/qapi/qmp/quint.h | 25 ++
 include/qapi/qmp/types.h |  1 +
 block/qapi.c |  5 +++
 qobject/qobject.c|  1 +
 qobject/quint.c  | 58 +++
 tests/check-qint.c   | 59 
 qobject/Makefile.objs|  2 +-
 tests/qapi-schema/comments.out   |  2 +-
 tests/qapi-schema/empty.out  |  2 +-
 tests/qapi-schema/event-case.out |  2 +-
 tests/qapi-schema/ident-with-escape.out  |  2 +-
 tests/qapi-schema/include-relpath.out|  2 +-
 tests/qapi-schema/include-repetition.out |  2 +-
 tests/qapi-schema/include-simple.out |  2 +-
 tests/qapi-schema/indented-expr.out  |  2 +-
 tests/qapi-schema/qapi-schema-test.out   |  2 +-
 18 files changed, 175 insertions(+), 24 deletions(-)
 create mode 100644 include/qapi/qmp/quint.h
 create mode 100644 qobject/quint.c

diff --git a/qapi/introspect.json b/qapi/introspect.json
index f6adc439bb..512a961ab3 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -125,7 +125,7 @@
 # Since: 2.5
 ##
 { 'enum': 'JSONType',
-  'data': [ 'string', 'number', 'int', 'boolean', 'null',
+  'data': [ 'string', 'number', 'int', 'uint', 'boolean', 'null',
 'object', 'array', 'value' ] }
 
 ##
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 9504ebd8c7..80ecc821cb 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -28,11 +28,11 @@ builtin_types = {
 'int16':'QTYPE_QINT',
 'int32':'QTYPE_QINT',
 'int64':'QTYPE_QINT',
-'uint8':'QTYPE_QINT',
-'uint16':   'QTYPE_QINT',
-'uint32':   'QTYPE_QINT',
-'uint64':   'QTYPE_QINT',
-'size': 'QTYPE_QINT',
+'uint8':'QTYPE_QUINT',
+'uint16':   'QTYPE_QUINT',
+'uint32':   'QTYPE_QUINT',
+'uint64':   'QTYPE_QUINT',
+'size': 'QTYPE_QUINT',
 'any':  None,   # any QType possible, actually
 'QType':'QTYPE_QSTRING',
 }
@@ -1093,6 +1093,7 @@ class QAPISchemaType(QAPISchemaEntity):
 'string':  'QTYPE_QSTRING',
 'number':  'QTYPE_QFLOAT',
 'int': 'QTYPE_QINT',
+'uint':'QTYPE_QUINT',
 'boolean': 'QTYPE_QBOOL',
 'object':  'QTYPE_QDICT'
 }
@@ -1103,8 +1104,8 @@ class QAPISchemaBuiltinType(QAPISchemaType):
 def __init__(self, name, json_type, c_type):
 QAPISchemaType.__init__(self, name, None)
 assert not c_type or isinstance(c_type, str)
-assert json_type in ('string', 'number', 'int', 'boolean', 'null',
- 'value')
+assert json_type in ('string', 'number', 'int', 'uint',
+ 'boolean', 'null', 'value')
 self._json_type_name = json_type
 self._c_type_name = c_type
 
@@ -1519,18 +1520,19 @@ class QAPISchema(object):
   ('int16',  'int', 'int16_t'),
   ('int32',  'int', 'int32_t'),
   ('int64',  'int', 'int64_t'),
-  ('uint8',  'int', 'uint8_t'),
-  ('uint16', 'int', 'uint16_t'),
-  ('uint32', 'int', 'uint32_t'),
-  ('uint64', 'int', 'uint64_t'),
-  ('size',   'int', 'uint64_t'),
+  ('uint8',  'uint','uint8_t'),
+  ('uint16', 'uint','uint16_t'),
+  ('uint32', 'uint','uint32_t'),
+  ('uint64', 'uint','uint64_t'),
+  ('size',   'uint','uint64_t'),
   ('bool',   'boolean', 'bool'),
   ('any','value',   'QObject' + pointer_suffix)]:
 self._def_builtin_type(*t)
 self.the_empty_object_type = QAPISchemaObjectType('q_empty', None,
   None, [], None)
 self._def_entity(self.the_empty_object_type)
-qtype_values = self._make_enum_members(['none', 'qnull', 'qint',
+qtype_values = self._make_enum_members(['none', 'qnull',
+'qint', 'quint',
 'qstring', 'qdict', 'qlist',
 'qfloat', 'qbool'])
 self._def_entity(QAPISchemaEnumType('QType', None, qtype_values,
diff --git a/include/qapi/qmp/quint.h b/include/qapi/qmp/quint.h
new file mode 100644
index 00..5b920ece5d
--- /dev/null
+++ b/include/qapi/qmp/quint.h
@@ -0,0 +1,25 @@
+/*
+ * QUInt Module
+ *
+ * Copyright (C) 2017 Red Hat Inc.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See 

[Qemu-devel] [PATCH 06/21] json: learn to parse uint64 numbers

2017-03-11 Thread Marc-André Lureau
If the parsed number doesn't fit in a int64, try with a uint64 before
falling back to double.

Switch strtoll() usage to qemu_strtoi64() helper while at it.

Add a few tests for large numbers.

Signed-off-by: Marc-André Lureau 
---
 qobject/json-lexer.c  |  4 
 qobject/json-parser.c | 19 +--
 qobject/qjson.c   |  8 
 tests/check-qjson.c   | 28 
 4 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index af4a75e05b..a0beb0b106 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -227,15 +227,18 @@ static const uint8_t json_lexer[][256] =  {
 /* escape */
 [IN_ESCAPE_LL] = {
 ['d'] = JSON_ESCAPE,
+['u'] = JSON_ESCAPE,
 },
 
 [IN_ESCAPE_L] = {
 ['d'] = JSON_ESCAPE,
+['u'] = JSON_ESCAPE,
 ['l'] = IN_ESCAPE_LL,
 },
 
 [IN_ESCAPE_I64] = {
 ['d'] = JSON_ESCAPE,
+['u'] = JSON_ESCAPE,
 },
 
 [IN_ESCAPE_I6] = {
@@ -247,6 +250,7 @@ static const uint8_t json_lexer[][256] =  {
 },
 
 [IN_ESCAPE] = {
+['u'] = JSON_ESCAPE,
 ['d'] = JSON_ESCAPE,
 ['i'] = JSON_ESCAPE,
 ['p'] = JSON_ESCAPE,
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index c18e48ab94..b39cb4d8d6 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/cutils.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "qapi/qmp/types.h"
@@ -472,6 +473,13 @@ static QObject *parse_escape(JSONParserContext *ctxt, 
va_list *ap)
 } else if (!strcmp(token->str, "%lld") ||
!strcmp(token->str, "%I64d")) {
 return QOBJECT(qint_from_int(va_arg(*ap, long long)));
+} else if (!strcmp(token->str, "%u")) {
+return QOBJECT(quint_from_uint(va_arg(*ap, unsigned int)));
+} else if (!strcmp(token->str, "%lu")) {
+return QOBJECT(quint_from_uint(va_arg(*ap, unsigned long)));
+} else if (!strcmp(token->str, "%llu") ||
+   !strcmp(token->str, "%I64u")) {
+return QOBJECT(quint_from_uint(va_arg(*ap, unsigned long long)));
 } else if (!strcmp(token->str, "%s")) {
 return QOBJECT(qstring_from_str(va_arg(*ap, const char *)));
 } else if (!strcmp(token->str, "%f")) {
@@ -504,14 +512,21 @@ static QObject *parse_literal(JSONParserContext *ctxt)
  * strtoll() indicates these instances by setting errno to ERANGE
  */
 int64_t value;
+uint64_t uvalue;
 
-errno = 0; /* strtoll doesn't set errno on success */
-value = strtoll(token->str, NULL, 10);
+qemu_strtoi64(token->str, NULL, 10, &value);
 if (errno != ERANGE) {
 return QOBJECT(qint_from_int(value));
 }
+
+qemu_strtou64(token->str, NULL, 10, &uvalue);
+if (errno != ERANGE) {
+return QOBJECT(quint_from_uint(uvalue));
+}
+
 /* fall through to JSON_FLOAT */
 }
+
 case JSON_FLOAT:
 /* FIXME dependent on locale; a pervasive issue in QEMU */
 /* FIXME our lexer matches RFC 7159 in forbidding Inf or NaN,
diff --git a/qobject/qjson.c b/qobject/qjson.c
index b2f3bfec53..6356cff594 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -140,6 +140,14 @@ static void to_json(const QObject *obj, QString *str, int 
pretty, int indent)
 qstring_append(str, buffer);
 break;
 }
+case QTYPE_QUINT: {
+QUInt *val = qobject_to_quint(obj);
+char buffer[1024];
+
+snprintf(buffer, sizeof(buffer), "%" PRIu64, quint_get_uint(val));
+qstring_append(str, buffer);
+break;
+}
 case QTYPE_QSTRING: {
 QString *val = qobject_to_qstring(obj);
 const char *ptr;
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 963dd46f07..fd44cd6207 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -904,6 +904,33 @@ static void simple_number(void)
 }
 }
 
+static void large_number(void)
+{
+const char *maxu64 = "18446744073709551615"; /* 2^64-1 */
+const char *gtu64 = "18446744073709551616"; /* 2^64 */
+QUInt *quint;
+QFloat *qfloat;
+QString *str;
+
+quint = qobject_to_quint(qobject_from_json(maxu64, &error_abort));
+g_assert(quint);
+g_assert_cmpint(quint_get_uint(quint), ==, 18446744073709551615U);
+
+str = qobject_to_json(QOBJECT(quint));
+g_assert_cmpstr(qstring_get_str(str), ==, maxu64);
+QDECREF(str);
+QDECREF(quint);
+
+qfloat = qobject_to_qfloat(qobject_from_json(gtu64, &error_abort));
+g_assert(qfloat);
+g_assert_cmpfloat(qfloat_get_double(qfloat), ==, 18446744073709551616.0);
+
+str = qobject_to_json(QOBJECT(qfloat));
+g_assert_cmpstr(qstring_get_str(str), ==, gtu64);
+QDECREF(str);
+QDECREF(qfloat);
+}
+
 static void float_number(void)
 {
 int i;
@@ -1468,6 +1495,7 @@ int main(int argc, char **argv)
 g_tes

[Qemu-devel] [PATCH 03/21] object: fix potential leak in getters

2017-03-11 Thread Marc-André Lureau
If the property is not of the requested type, the getters will leak a
QObject.

Signed-off-by: Marc-André Lureau 
Cc: qemu-triv...@nongnu.org
---
 qom/object.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/qom/object.c b/qom/object.c
index eb4bc924ff..c7b8079df6 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1122,7 +1122,7 @@ char *object_property_get_str(Object *obj, const char 
*name,
 retval = g_strdup(qstring_get_str(qstring));
 }
 
-QDECREF(qstring);
+qobject_decref(ret);
 return retval;
 }
 
@@ -1183,7 +1183,7 @@ bool object_property_get_bool(Object *obj, const char 
*name,
 retval = qbool_get_bool(qbool);
 }
 
-QDECREF(qbool);
+qobject_decref(ret);
 return retval;
 }
 
@@ -1214,7 +1214,7 @@ int64_t object_property_get_int(Object *obj, const char 
*name,
 retval = qint_get_int(qint);
 }
 
-QDECREF(qint);
+qobject_decref(ret);
 return retval;
 }
 
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 08/21] qdev: use int and uint properties

2017-03-11 Thread Marc-André Lureau
So the correct QObject type is used.

Signed-off-by: Marc-André Lureau 
---
 include/hw/qdev-core.h   |  5 +++-
 include/hw/qdev-properties.h | 59 ++--
 hw/block/fdc.c   | 54 
 hw/core/qdev-properties.c|  8 +++---
 hw/core/qdev.c   |  8 +++---
 hw/net/e1000e.c  | 14 +--
 6 files changed, 82 insertions(+), 66 deletions(-)

diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index b44b476765..218f83b4a1 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -239,7 +239,10 @@ struct Property {
 ptrdiff_toffset;
 uint8_t  bitnr;
 QTypeqtype;
-int64_t  defval;
+union {
+int64_t  i;
+uint64_t u;
+} defval;
 int  arrayoffset;
 PropertyInfo *arrayinfo;
 int  arrayfieldsize;
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 7ac315331a..96584354a7 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -37,22 +37,33 @@ extern PropertyInfo qdev_prop_arraylen;
 .offset= offsetof(_state, _field)\
 + type_check(_type, typeof_field(_state, _field)),   \
 }
-#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
+
+#define DEFINE_PROP_INT(_name, _state, _field, _defval, _prop, _type) { \
 .name  = (_name),   \
 .info  = &(_prop),  \
 .offset= offsetof(_state, _field)   \
 + type_check(_type,typeof_field(_state, _field)),   \
 .qtype = QTYPE_QINT,\
-.defval= (_type)_defval,\
+.defval.i  = (_type)_defval,\
 }
-#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
-.name  = (_name),\
-.info  = &(qdev_prop_bit),   \
-.bitnr= (_bit),  \
-.offset= offsetof(_state, _field)\
-+ type_check(uint32_t,typeof_field(_state, _field)), \
-.qtype = QTYPE_QBOOL,\
-.defval= (bool)_defval,  \
+
+#define DEFINE_PROP_UINT(_name, _state, _field, _defval, _prop, _type) { \
+.name  = (_name),   \
+.info  = &(_prop),  \
+.offset= offsetof(_state, _field)   \
++ type_check(_type, typeof_field(_state, _field)),  \
+.qtype = QTYPE_QUINT,   \
+.defval.u  = (_type)_defval,\
+ }
+
+#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
+.name  = (_name),   \
+.info  = &(qdev_prop_bit),  \
+.bitnr= (_bit), \
+.offset= offsetof(_state, _field)   \
++ type_check(uint32_t, typeof_field(_state, _field)),   \
+.qtype = QTYPE_QBOOL,   \
+.defval.i  = (bool)_defval, \
 }
 #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {   \
 .name  = (_name),   \
@@ -61,7 +72,7 @@ extern PropertyInfo qdev_prop_arraylen;
 .offset= offsetof(_state, _field)   \
 + type_check(uint64_t, typeof_field(_state, _field)),   \
 .qtype = QTYPE_QBOOL,   \
-.defval= (bool)_defval, \
+.defval.i  = (bool)_defval ,\
 }
 
 #define DEFINE_PROP_BOOL(_name, _state, _field, _defval) {   \
@@ -70,7 +81,7 @@ extern PropertyInfo qdev_prop_arraylen;
 .offset= offsetof(_state, _field)\
 + type_check(bool, typeof_field(_state, _field)),\
 .qtype = QTYPE_QBOOL,\
-.defval= (bool)_defval,  \
+.defval.i  = (bool)_defval,  \
 }
 
 #define PROP_ARRAY_LEN_PREFIX "len-"
@@ -112,19 +123,19 @@ extern PropertyInfo qdev_prop_arraylen;
 }
 
 #define DEFINE_PROP_UINT8(_n, _s, _f, _d)   \
-DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qde

[Qemu-devel] [PATCH 00/21] WIP: dump: add kaslr support (for after 2.9)

2017-03-11 Thread Marc-André Lureau
Hi,

Latest linux kernel enabled kaslr to randomize phys/virt memory
addresses. There has been some effort to support kexec/kdump so that
crash utility can still works in case crashed kernel has kaslr
enabled.

This series aims to provide enough information in qemu dumps so that
crash utility can work with kaslr kernel too, with x86_64 guests (it
hasn't been tested on other archs, help welcome).

Two pieces of informations are necessary: the phys_base (the physical
address where the kernel is loaded) and the kaslr offset. Other useful
informations for debugging are provided in Linux vmcoreinfo too.

There has been discussions to provide those details in early boot,
with ACPI, fw_cfg, virtio-pstore etc, but none has reached a consensus
yet. A possiblity for now is to provide the information when qemu-ga
starts. This has the advantage of working with older guests and may
not be incompatible with future methods (in this case it could ignore
qga info for example). The drawback is that qemu will have to parse
the json stream. For now it stops processing it whem VMDUMP_INFO is
received. It would be wise to introduce a QMP welcome message, so that
qemu would stop immediately processing the stream if the agent doesn't
have the event. Another option is to create a seperate channel...
I welcome other ideas and discussion.

crash upstream doesn't yet parse NUMBER(phys_base). You may pass it to
crash with --machdep phys_base=0x.. provided you snooped on qga.

kdump kaslr-dumps should now work with crash out of the box.

A large part of the series has to do with json and the qobject type
system to deal with uint64 values, so that addresses can now be sent
over json. The second halfs adds qga VMDUMP_INFO event, and ELF/kdump
dumping. Depending on the feedback, I will probably split the series,
but for those who would like to try it, help or suggest ideas, here is
the whole thing.

cheers

Marc-André Lureau (21):
  qapi: add info comment for generated types
  pci-host: use more specific type names
  object: fix potential leak in getters
  qobject: add quint type
  qapi: update the qobject visitor to use QUInt
  json: learn to parse uint64 numbers
  object: add uint property setter/getter
  qdev: use int and uint properties
  qdev: use appropriate type
  Use uint property getter/setter where appropriate
  qdict: learn to lookup quint
  test-qga: drop everything until guest-sync
  qga: report error on keyfile dump error
  qga: add and populate VMDumpInfo
  qga: register event emit function
  qga: emit VMDUMP_INFO event
  virtio-channel: parse qga stream for VMDUMP_INFO event
  dump: use qga VMDUMP_INFO for ELF dump
  kdump: write vmcoreinfo in header
  scripts/dump-guest-memory.py: fix int128_get64 on recent gcc
  scripts/dump-guest-memory.py: add VMCOREINFO

 qapi/introspect.json |   2 +-
 scripts/qapi.py  |  39 ---
 scripts/dump-guest-memory.py |  66 ++-
 scripts/qapi-event.py|   4 +-
 scripts/qapi-types.py|  17 +--
 scripts/qapi-visit.py|   3 +-
 include/hw/isa/isa.h |   2 +-
 include/hw/qdev-core.h   |   5 +-
 include/hw/qdev-properties.h |  59 ++
 include/qapi/qmp/qdict.h |   2 +
 include/qapi/qmp/quint.h |  25 +
 include/qapi/qmp/types.h |   1 +
 include/qom/object.h |  23 
 include/sysemu/dump-info.h   |  15 +++
 include/sysemu/dump.h|   2 +
 qga/guest-agent-core.h   |   2 +
 block/qapi.c |   5 +
 dump.c   | 184 ++-
 hw/acpi/memory_hotplug.c |  10 +-
 hw/acpi/nvdimm.c |  10 +-
 hw/acpi/pcihp.c  |   6 +-
 hw/arm/aspeed.c  |   4 +-
 hw/arm/bcm2835_peripherals.c |   9 +-
 hw/arm/raspi.c   |   4 +-
 hw/block/fdc.c   |  54 -
 hw/char/virtio-console.c |  53 +
 hw/core/platform-bus.c   |   2 +-
 hw/core/qdev-properties.c|   8 +-
 hw/core/qdev.c   |   8 +-
 hw/i386/acpi-build.c |  70 ++--
 hw/i386/pc.c |   6 +-
 hw/intc/arm_gicv3_common.c   |   2 +-
 hw/mem/pc-dimm.c |   5 +-
 hw/misc/auxbus.c |   2 +-
 hw/misc/pvpanic.c|   2 +-
 hw/net/e1000e.c  |  14 +--
 hw/pci-host/gpex.c   |   2 +-
 hw/pci-host/piix.c   |   8 +-
 hw/pci-host/q35.c|  12 +-
 hw/pci-host/xilinx-pcie.c|   2 +-
 hw/ppc/pnv_core.c|   2 +-
 hw/ppc/spapr.c  

[Qemu-devel] [PATCH 02/21] pci-host: use more specific type names

2017-03-11 Thread Marc-André Lureau
Use the actual unsigned integer type name (this should't break since
property type aren't directly accessed from outside).

Signed-off-by: Marc-André Lureau 
---
 hw/pci-host/piix.c |  8 
 hw/pci-host/q35.c  | 10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index f9218aa952..9aed6225bf 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -279,19 +279,19 @@ static void i440fx_pcihost_initfn(Object *obj)
 memory_region_init_io(&s->data_mem, obj, &pci_host_data_le_ops, s,
   "pci-conf-data", 4);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
 i440fx_pcihost_get_pci_hole_start,
 NULL, NULL, NULL, NULL);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
 i440fx_pcihost_get_pci_hole_end,
 NULL, NULL, NULL, NULL);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
 i440fx_pcihost_get_pci_hole64_start,
 NULL, NULL, NULL, NULL);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
 i440fx_pcihost_get_pci_hole64_end,
 NULL, NULL, NULL, NULL);
 }
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 344f77b10c..5438be8253 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -176,23 +176,23 @@ static void q35_host_initfn(Object *obj)
 qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
 qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_START, "uint32",
 q35_host_get_pci_hole_start,
 NULL, NULL, NULL, NULL);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE_END, "uint32",
 q35_host_get_pci_hole_end,
 NULL, NULL, NULL, NULL);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_START, "uint64",
 q35_host_get_pci_hole64_start,
 NULL, NULL, NULL, NULL);
 
-object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "int",
+object_property_add(obj, PCI_HOST_PROP_PCI_HOLE64_END, "uint64",
 q35_host_get_pci_hole64_end,
 NULL, NULL, NULL, NULL);
 
-object_property_add(obj, PCIE_HOST_MCFG_SIZE, "int",
+object_property_add(obj, PCIE_HOST_MCFG_SIZE, "uint32",
 q35_host_get_mmcfg_size,
 NULL, NULL, NULL, NULL);
 
-- 
2.12.0.191.gc5d8de91d




[Qemu-devel] [PATCH 01/21] qapi: add info comment for generated types

2017-03-11 Thread Marc-André Lureau
This may help to find where the origin of the type was declared in the
json (when greping isn't easy enough).

Signed-off-by: Marc-André Lureau 
Cc: qemu-triv...@nongnu.org
---
 scripts/qapi.py   | 11 +--
 scripts/qapi-event.py |  4 +++-
 scripts/qapi-types.py | 17 +
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 53a44779d0..9504ebd8c7 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1874,15 +1874,22 @@ const char *const %(c_name)s_lookup[] = {
 return ret
 
 
-def gen_enum(name, values, prefix=None):
+def gen_info_comment(info):
+if info:
+return "/* %s:%d */" % (info['file'], info['line'])
+else:
+return ""
+
+def gen_enum(info, name, values, prefix=None):
 # append automatically generated _MAX value
 enum_values = values + ['_MAX']
 
 ret = mcgen('''
 
+%(info)s
 typedef enum %(c_name)s {
 ''',
-c_name=c_name(name))
+c_name=c_name(name), info=gen_info_comment(info))
 
 i = 0
 for value in enum_values:
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index f4eb7f85b1..ca90d6a5df 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -152,6 +152,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
 self.decl = None
 self.defn = None
 self._event_names = None
+self.info = None
 
 def visit_begin(self, schema):
 self.decl = ''
@@ -159,7 +160,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
 self._event_names = []
 
 def visit_end(self):
-self.decl += gen_enum(event_enum_name, self._event_names)
+self.decl += gen_enum(self.info, event_enum_name, self._event_names)
 self.defn += gen_enum_lookup(event_enum_name, self._event_names)
 self._event_names = None
 
@@ -167,6 +168,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaVisitor):
 self.decl += gen_event_send_decl(name, arg_type, boxed)
 self.defn += gen_event_send(name, arg_type, boxed)
 self._event_names.append(name)
+self.info = info
 
 
 (input_file, output_dir, do_c, do_h, prefix, dummy) = parse_command_line()
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index dabc42e047..896749bf61 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -19,12 +19,13 @@ from qapi import *
 objects_seen = set()
 
 
-def gen_fwd_object_or_array(name):
+def gen_fwd_object_or_array(info, name):
 return mcgen('''
 
+%(info)s
 typedef struct %(c_name)s %(c_name)s;
 ''',
- c_name=c_name(name))
+ c_name=c_name(name), info=gen_info_comment(info))
 
 
 def gen_array(name, element_type):
@@ -199,22 +200,22 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
 # Special case for our lone builtin enum type
 # TODO use something cleaner than existence of info
 if not info:
-self._btin += gen_enum(name, values, prefix)
+self._btin += gen_enum(info, name, values, prefix)
 if do_builtins:
 self.defn += gen_enum_lookup(name, values, prefix)
 else:
-self._fwdecl += gen_enum(name, values, prefix)
+self._fwdecl += gen_enum(info, name, values, prefix)
 self.defn += gen_enum_lookup(name, values, prefix)
 
 def visit_array_type(self, name, info, element_type):
 if isinstance(element_type, QAPISchemaBuiltinType):
-self._btin += gen_fwd_object_or_array(name)
+self._btin += gen_fwd_object_or_array(info, name)
 self._btin += gen_array(name, element_type)
 self._btin += gen_type_cleanup_decl(name)
 if do_builtins:
 self.defn += gen_type_cleanup(name)
 else:
-self._fwdecl += gen_fwd_object_or_array(name)
+self._fwdecl += gen_fwd_object_or_array(info, name)
 self.decl += gen_array(name, element_type)
 self._gen_type_cleanup(name)
 
@@ -222,7 +223,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
 # Nothing to do for the special empty builtin
 if name == 'q_empty':
 return
-self._fwdecl += gen_fwd_object_or_array(name)
+self._fwdecl += gen_fwd_object_or_array(info, name)
 self.decl += gen_object(name, base, members, variants)
 if base and not base.is_implicit():
 self.decl += gen_upcast(name, base)
@@ -233,7 +234,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
 self._gen_type_cleanup(name)
 
 def visit_alternate_type(self, name, info, variants):
-self._fwdecl += gen_fwd_object_or_array(name)
+self._fwdecl += gen_fwd_object_or_array(info, name)
 self.decl += gen_object(name, None, [variants.tag_member], variants)
 self._gen_type_cleanup(name)
 
-- 
2.12.0.191.gc5d8de91d




Re: [Qemu-devel] [PATCH v7 kernel 3/5] virtio-balloon: implementation of VIRTIO_BALLOON_F_CHUNK_TRANSFER

2017-03-11 Thread Wei Wang

On 03/11/2017 01:11 AM, Matthew Wilcox wrote:

On Fri, Mar 10, 2017 at 05:58:28PM +0200, Michael S. Tsirkin wrote:

One of the issues of current balloon is the 4k page size
assumption. For example if you free a huge page you
have to split it up and pass 4k chunks to host.
Quite often host can't free these 4k chunks at all (e.g.
when it's using huge tlb fs).
It's even sillier for architectures with base page size >4k.

I completely agree with you that we should be able to pass a hugepage
as a single chunk.  Also we shouldn't assume that host and guest have
the same page size.  I think we can come up with a scheme that actually
lets us encode that into a 64-bit word, something like this:

bit 0 clear => bits 1-11 encode a page count, bits 12-63 encode a PFN, page 
size 4k.
bit 0 set, bit 1 clear => bits 2-12 encode a page count, bits 13-63 encode a 
PFN, page size 8k
bits 0+1 set, bit 2 clear => bits 3-13 for page count, bits 14-63 for PFN, page 
size 16k.
bits 0-2 set, bit 3 clear => bits 4-14 for page count, bits 15-63 for PFN, page 
size 32k
bits 0-3 set, bit 4 clear => bits 5-15 for page count, bits 16-63 for PFN, page 
size 64k

That means we can always pass 2048 pages (of whatever page size) in a single 
chunk.  And
we support arbitrary power of two page sizes.  I suggest something like this:

u64 page_to_chunk(struct page *page)
{
u64 chunk = page_to_pfn(page) << PAGE_SHIFT;
chunk |= (1UL << compound_order(page)) - 1;
}

(note this is a single page of order N, so we leave the page count bits
set to 0, meaning one page).



I'm thinking what if the guest needs to transfer these much physically 
continuous

memory to host: 1GB+2MB+64KB+32KB+16KB+4KB.
Is it going to use Six 64-bit chunks? Would it be simpler if we just
use the 128-bit chunk format (we can drop the previous normal 64-bit 
format)?


Best,
Wei



[Qemu-devel] [PATCH 2/2] vmdk: Update metadata for multiple clusters

2017-03-11 Thread Ashijeet Acharya
Include a next pointer in VmdkMetaData struct to point to the previous
allocated L2 table. Modify vmdk_L2update to start updating metadata for
allocation of multiple clusters at once.

Signed-off-by: Ashijeet Acharya 
---
 block/vmdk.c | 131 ++-
 1 file changed, 102 insertions(+), 29 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 3dc178b..62ea46f 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -137,6 +137,8 @@ typedef struct VmdkMetaData {
 int valid;
 uint32_t *l2_cache_entry;
 uint32_t nb_clusters;
+uint32_t offset;
+struct VmdkMetaData *next;
 } VmdkMetaData;
 
 typedef struct VmdkGrainMarker {
@@ -1037,29 +1039,81 @@ static void vmdk_refresh_limits(BlockDriverState *bs, 
Error **errp)
 }
 }
 
-static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
- uint32_t offset)
+static int vmdk_alloc_cluster_link_l2(VmdkExtent *extent,
+  VmdkMetaData *m_data, bool zeroed)
 {
-offset = cpu_to_le32(offset);
+int i;
+uint32_t offset, temp_offset;
+
+if (zeroed) {
+temp_offset = VMDK_GTE_ZEROED;
+} else {
+temp_offset = m_data->offset;
+}
+
+temp_offset = cpu_to_le32(temp_offset);
+
 /* update L2 table */
-if (bdrv_pwrite_sync(extent->file,
+offset = temp_offset;
+for (i = 0; i < m_data->nb_clusters; i++) {
+if (bdrv_pwrite_sync(extent->file,
 ((int64_t)m_data->l2_offset * 512)
-+ (m_data->l2_index * sizeof(offset)),
-&offset, sizeof(offset)) < 0) {
-return VMDK_ERROR;
++ ((m_data->l2_index + i) * sizeof(offset)),
+&(offset), sizeof(offset)) < 0) {
+return VMDK_ERROR;
+}
+if (!zeroed) {
+offset += 128;
+}
 }
+
 /* update backup L2 table */
+offset = temp_offset;
 if (extent->l1_backup_table_offset != 0) {
 m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
-if (bdrv_pwrite_sync(extent->file,
-((int64_t)m_data->l2_offset * 512)
-+ (m_data->l2_index * sizeof(offset)),
-&offset, sizeof(offset)) < 0) {
-return VMDK_ERROR;
+for (i = 0; i < m_data->nb_clusters; i++) {
+if (bdrv_pwrite_sync(extent->file,
+((int64_t)m_data->l2_offset * 512)
++ ((m_data->l2_index + i) * sizeof(offset)),
+&(offset), sizeof(offset)) < 0) {
+return VMDK_ERROR;
+}
+if (!zeroed) {
+offset += 128;
+}
 }
 }
+
+offset = temp_offset;
 if (m_data->l2_cache_entry) {
-*m_data->l2_cache_entry = offset;
+for (i = 0; i < m_data->nb_clusters; i++) {
+*m_data->l2_cache_entry = offset;
+m_data->l2_cache_entry++;
+
+if (!zeroed) {
+offset += 128;
+}
+}
+}
+
+return VMDK_OK;
+}
+
+static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
+ bool zeroed)
+{
+int ret;
+
+while (m_data->next != NULL) {
+VmdkMetaData *next;
+
+ret = vmdk_alloc_cluster_link_l2(extent, m_data, zeroed);
+if (ret < 0) {
+return ret;
+}
+
+next = m_data->next;
+m_data = next;
 }
 
 return VMDK_OK;
@@ -1271,7 +1325,7 @@ exit:
  */
 static int handle_alloc(BlockDriverState *bs, VmdkExtent *extent,
 uint64_t offset, uint64_t *cluster_offset,
-int64_t *bytes, VmdkMetaData *m_data,
+int64_t *bytes, VmdkMetaData **m_data,
 bool allocate, uint32_t *total_alloc_clusters)
 {
 int l1_index, l2_offset, l2_index;
@@ -1280,6 +1334,7 @@ static int handle_alloc(BlockDriverState *bs, VmdkExtent 
*extent,
 uint32_t nb_clusters;
 bool zeroed = false;
 uint64_t skip_start_bytes, skip_end_bytes;
+VmdkMetaData *old_m_data;
 int ret;
 
 ret = get_cluster_table(extent, offset, &l1_index, &l2_offset,
@@ -1331,13 +1386,21 @@ static int handle_alloc(BlockDriverState *bs, 
VmdkExtent *extent,
 if (ret < 0) {
 return ret;
 }
-if (m_data) {
-m_data->valid = 1;
-m_data->l1_index = l1_index;
-m_data->l2_index = l2_index;
-m_data->l2_offset = l2_offset;
-m_data->l2_cache_entry = &l2_table[l2_index];
-m_data->nb_clusters = nb_clusters;
+
+if (*m_data) {
+old_m_data = *m_data;
+*m_data = g_malloc0(sizeof(**m_data));
+
+**m_data = (VmdkMetaData) {
+.valid=1,
+.l1_index =l1_index,
+.l2_index =l2_i

[Qemu-devel] [PATCH 0/2] Allocate mutiple clusters for VMDK I/O

2017-03-11 Thread Ashijeet Acharya
This series optimizes the I/O performance of VMDK driver.

Patch 1 makes the VMDK driver to allocate multiple clusters at once. Earlier
it used to allocate cluster by cluster which slowed down its performance to a
great extent.

Patch 2 changes the metadata update code to update the L2 tables for multiple
clusters at once.

Note: These changes pass all 41/41 tests suitable for VMDK driver.

Ashijeet Acharya (2):
  vmdk: Optimize I/O by allocating multiple clusters
  vmdk: Update metadata for multiple clusters

 block/vmdk.c | 596 ---
 1 file changed, 444 insertions(+), 152 deletions(-)

-- 
2.6.2




[Qemu-devel] [PATCH 1/2] vmdk: Optimize I/O by allocating multiple clusters

2017-03-11 Thread Ashijeet Acharya
The vmdk driver in block/vmdk.c used to allocate cluster by cluster
which slowed down its I/O performance.

Make vmdk driver allocate multiple clusters at once to reduce the
overhead costs of multiple separate cluster allocation calls. The number
of clusters allocated at once depends on the L2 table boundaries. Also
the first and the last clusters are allocated separately as we may need
to perform COW for them

Signed-off-by: Ashijeet Acharya 
---
 block/vmdk.c | 513 ++-
 1 file changed, 366 insertions(+), 147 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index a9bd22b..3dc178b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -136,6 +136,7 @@ typedef struct VmdkMetaData {
 unsigned int l2_offset;
 int valid;
 uint32_t *l2_cache_entry;
+uint32_t nb_clusters;
 } VmdkMetaData;
 
 typedef struct VmdkGrainMarker {
@@ -242,6 +243,26 @@ static void vmdk_free_last_extent(BlockDriverState *bs)
 s->extents = g_renew(VmdkExtent, s->extents, s->num_extents);
 }
 
+static inline uint64_t vmdk_find_offset_in_cluster(VmdkExtent *extent,
+   int64_t offset)
+{
+uint64_t extent_begin_offset, extent_relative_offset;
+uint64_t cluster_size = extent->cluster_sectors * BDRV_SECTOR_SIZE;
+
+extent_begin_offset =
+(extent->end_sector - extent->sectors) * BDRV_SECTOR_SIZE;
+extent_relative_offset = offset - extent_begin_offset;
+return extent_relative_offset % cluster_size;
+}
+
+static inline uint64_t size_to_clusters(VmdkExtent *extent, uint64_t size)
+{
+uint64_t cluster_size, round_off_size;
+cluster_size = extent->cluster_sectors * BDRV_SECTOR_SIZE;
+round_off_size = cluster_size - (size % cluster_size);
+return ((size + round_off_size) >> 16) - 1;
+}
+
 static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
 {
 char *desc;
@@ -1016,8 +1037,135 @@ static void vmdk_refresh_limits(BlockDriverState *bs, 
Error **errp)
 }
 }
 
-/**
- * get_whole_cluster
+static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
+ uint32_t offset)
+{
+offset = cpu_to_le32(offset);
+/* update L2 table */
+if (bdrv_pwrite_sync(extent->file,
+((int64_t)m_data->l2_offset * 512)
++ (m_data->l2_index * sizeof(offset)),
+&offset, sizeof(offset)) < 0) {
+return VMDK_ERROR;
+}
+/* update backup L2 table */
+if (extent->l1_backup_table_offset != 0) {
+m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
+if (bdrv_pwrite_sync(extent->file,
+((int64_t)m_data->l2_offset * 512)
++ (m_data->l2_index * sizeof(offset)),
+&offset, sizeof(offset)) < 0) {
+return VMDK_ERROR;
+}
+}
+if (m_data->l2_cache_entry) {
+*m_data->l2_cache_entry = offset;
+}
+
+return VMDK_OK;
+}
+
+/*
+ * vmdk_L2load
+ *
+ * Loads a new L2 table into memory. If the table is in the cache, the cache
+ * is used; otherwise the L2 table is loaded from the image file.
+ *
+ * Returns:
+ *   VMDK_OK:   on success
+ *   VMDK_ERROR:in error cases
+ */
+static int vmdk_L2load(VmdkExtent *extent, uint64_t offset, int l2_offset,
+   uint32_t **new_l2_table, int *new_l2_index)
+{
+int min_index, i, j;
+uint32_t *l2_table;
+uint32_t min_count;
+
+for (i = 0; i < L2_CACHE_SIZE; i++) {
+if (l2_offset == extent->l2_cache_offsets[i]) {
+/* increment the hit count */
+if (++extent->l2_cache_counts[i] == 0x) {
+for (j = 0; j < L2_CACHE_SIZE; j++) {
+extent->l2_cache_counts[j] >>= 1;
+}
+}
+l2_table = extent->l2_cache + (i * extent->l2_size);
+goto found;
+}
+}
+/* not found: load a new entry in the least used one */
+min_index = 0;
+min_count = 0x;
+for (i = 0; i < L2_CACHE_SIZE; i++) {
+if (extent->l2_cache_counts[i] < min_count) {
+min_count = extent->l2_cache_counts[i];
+min_index = i;
+}
+}
+l2_table = extent->l2_cache + (min_index * extent->l2_size);
+if (bdrv_pread(extent->file,
+(int64_t)l2_offset * 512,
+l2_table,
+extent->l2_size * sizeof(uint32_t)
+) != extent->l2_size * sizeof(uint32_t)) {
+return VMDK_ERROR;
+}
+
+extent->l2_cache_offsets[min_index] = l2_offset;
+extent->l2_cache_counts[min_index] = 1;
+found:
+*new_l2_index = ((offset >> 9) / extent->cluster_sectors) % 
extent->l2_size;
+*new_l2_table = l2_table;
+
+return VMDK_OK;
+}
+
+/*
+ * get_cluster_table
+ *
+ * for a given offset, load (and allocate if needed) the l2 table.
+ *
+ * Returns:
+ *   VMDK_OK:on success
+ *
+ *   VMDK_UNALLOC:   if cluste

[Qemu-devel] Incorrect memory region address with large 64-bit PCI BARs

2017-03-11 Thread Mark Cave-Ayland
I've been looking at an issue with virtio BARs being mapped incorrectly
on qemu-system-sparc64, and as part of this investigation found that
some 64-bit PCI BAR memory regions don't appear correctly in "info mtree".

The easiest way to see this is to launch QEMU as below and then check
the output of "info mtree":

./qemu-system-sparc64 -device virtio-net-pci

The interesting part is this:

> address-space: memory
>   - (prio 0, i/o): system
> -07ff (prio 0, ram): sun4u.ram
> 01fe-01fe (prio 0, i/o): apb-config
> 01fe0100-01fe01ff (prio 0, i/o): apb-pci-config
> 01fe0200-01fe0200 (prio 0, i/o): alias apb-pci ioport @io 
> -
> 01ff-01ff (prio 0, i/o): pci-mmio
>   01ff-01ff000f (prio 1, i/o): alias pci_bridge_mem 
> @pci_bridge_pci -000f
>   01ff-01ff000f (prio 1, i/o): alias 
> pci_bridge_pref_mem @pci_bridge_pci -000f
>   01ff-01ff000f (prio 1, i/o): alias pci_bridge_mem 
> @pci_bridge_pci -000f
>   01ff-01ff000f (prio 1, i/o): alias 
> pci_bridge_pref_mem @pci_bridge_pci -000f
>   01ff000a-01ff000a (prio 2, i/o): alias vga.chain4 
> @vga.vram -
>   01ff000a-01ff000b (prio 1, i/o): vga-lowmem
>   01ff0100-01ff01ff (prio 1, ram): vga.vram
>   01ff0200-01ff02000fff (prio 1, i/o): vga.mmio
> 01ff02000400-01ff0200041f (prio 0, i/o): vga ioports remapped
> 01ff02000500-01ff02000515 (prio 0, i/o): bochs dispi interface
> 01ff02000600-01ff02000607 (prio 0, i/o): qemu extended regs
>   01ff0201-01ff0201 (prio 1, rom): vga.rom
>   01ff0300-01ff03ff (prio 1, i/o): alias bar0 @io 
> -00ff
>   01ff0400-01ff0403 (prio 1, rom): ne2000.rom
>   01ff0408-01ff040b (prio 1, rom): virtio-net-pci.rom
>   01fe0404-01fe04043fff (prio 1, i/o): virtio-pci
^

Here virtio-pci is mapped to address 0x1fe0404 even though its
parent pci-mmio memory region is at 0x1ff.

> 01fe0404-01fe04040fff (prio 0, i/o): virtio-pci-common
> 01fe04041000-01fe04041fff (prio 0, i/o): virtio-pci-isr
> 01fe04042000-01fe04042fff (prio 0, i/o): virtio-pci-device
> 01fe04043000-01fe04043fff (prio 0, i/o): virtio-pci-notify
> 01fff000-01fff03f (prio 0, rom): sun4u.prom

The bug in the current OpenBIOS is that 64-bit BARs are incorrectly
identified, and so the BAR MSB register is set to 0x to detect
the size as per a standard 32-bit BAR. At this point OpenBIOS detects
something is wrong and aborts, leaving the 64-bit BAR set to 0x
0x0404.

This is accurately reflected in the virtio-pci memory region itself, i.e.

> memory-region: virtio-pci
>   0404-04043fff (prio 1, i/o): virtio-pci
> 0404-04040fff (prio 0, i/o): virtio-pci-common
> 04041000-04041fff (prio 0, i/o): virtio-pci-isr
> 04042000-04042fff (prio 0, i/o): virtio-pci-device
> 04043000-04043fff (prio 0, i/o): virtio-pci-notify

But as you can see above the overall effect is that the virtio-pci
device ends up somehow being mapped outside (and indeed, before the
start of) its parent memory region.

Fixing the bug in OpenBIOS itself is fairly trivial, although it took
much longer to diagnose due to the misleading output above. It does seem
that something isn't quite right with the handling of the large 64-bit
BARs in this case, so Michael suggested I email the list for further
comment.


ATB,

Mark.



[Qemu-devel] [PATCH] linux-user/hppa: Fix typo for TARGET_NR_epoll_wait

2017-03-11 Thread Helge Deller
This fixes running a dynamically linked nslookup binary on hppa with
LD_BIND_NOW=1.

Signed-off-by: Helge Deller 

diff --git a/linux-user/hppa/syscall_nr.h b/linux-user/hppa/syscall_nr.h
index 0f396fa..55bdf71 100644
--- a/linux-user/hppa/syscall_nr.h
+++ b/linux-user/hppa/syscall_nr.h
@@ -228,7 +228,7 @@
 #define TARGET_NR_lookup_dcookie223
 #define TARGET_NR_epoll_create  224
 #define TARGET_NR_epoll_ctl 225
-#define TARGET_NR_epill_wait226
+#define TARGET_NR_epoll_wait226
 #define TARGET_NR_remap_file_pages  227
 #define TARGET_NR_semtimedop228
 #define TARGET_NR_mq_open   229



Re: [Qemu-devel] [PATCH 2/3] linux-user: Fix TARGET_SA_* defines for HPPA

2017-03-11 Thread Helge Deller
On 11.03.2017 04:42, Richard Henderson wrote:
> From: Helge Deller 
> 
> Reported-by: Helge Deller 
> Signed-off-by: Richard Henderson 

Signed-off-by: Helge Deller 


> ---
>  linux-user/syscall_defs.h | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 8b1ad74..2620b56 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -473,6 +473,14 @@ int do_sigaction(int sig, const struct target_sigaction 
> *act,
>  #define TARGET_SA_RESETHAND  0x0010
>  #define TARGET_SA_NOCLDWAIT  0x0020 /* not supported yet */
>  #define TARGET_SA_SIGINFO0x0040
> +#elif defined(TARGET_HPPA)
> +#define TARGET_SA_ONSTACK   0x0001
> +#define TARGET_SA_RESETHAND 0x0004
> +#define TARGET_SA_NOCLDSTOP 0x0008
> +#define TARGET_SA_SIGINFO   0x0010
> +#define TARGET_SA_NODEFER   0x0020
> +#define TARGET_SA_RESTART   0x0040
> +#define TARGET_SA_NOCLDWAIT 0x0080
>  #else
>  #define TARGET_SA_NOCLDSTOP  0x0001
>  #define TARGET_SA_NOCLDWAIT  0x0002 /* not supported yet */
>