All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26
@ 2015-01-26  9:24 Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 01/19] pc: fix KVM features in pc-1.3 and earlier machine types Paolo Bonzini
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit 699eae17b841e6784dc3864bf357e26bff1e9dfe:

  Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20150120' into staging (2015-01-20 16:19:58 +0000)

are available in the git repository at:


  git://github.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to 9fc2ecf4e8266dcb01961851c595d09485d26bc1:

  kvm_stat: Add RESET support for perf event ioctl (2015-01-26 10:03:09 +0100)

----------------------------------------------------------------
- Many fixes from the floor as usual
- New "edu" device
- Disabling HLE and RTM on Haswell & Broadwell
- kvm_stat updates
- Added --enable-modules to Travis, in preparation for switching
  the default

----------------------------------------------------------------
Christian Borntraeger (1):
      sparse: Fix build with sparse on .S files

Eduardo Habkost (1):
      target-i386: Disable HLE and RTM on Haswell & Broadwell

Jiri Slaby (1):
      hw: misc, add educational driver

Kevin Wolf (3):
      tests/multiboot: Update reference output
      multiboot: Fix offset of bootloader name
      tests/multiboot: Add test for modules

Paolo Bonzini (9):
      pc: fix KVM features in pc-1.3 and earlier machine types
      target-i386: use vmstate_offset_sub_array for AVX registers
      target-i386: make xmm_regs 512-bit wide
      qemu-timer: add timer_init and timer_init_ns/us/ms
      qemu-timer: introduce timer_deinit
      vmstate: accept QEMUTimer in VMSTATE_TIMER*, add VMSTATE_TIMER_PTR*
      apic: do not dereference pointer before it is checked for NULL
      .travis.yml: Add "--enable-modules"
      exec: fix madvise of NULL pointer

Wei Huang (4):
      kvm_stat: Add aarch64 support
      kvm_stat: Update exit reasons to the latest defintion
      kvm_stat: Print errno when syscall to perf_event_open() fails
      kvm_stat: Add RESET support for perf event ioctl

 .travis.yml                 |   3 +
 MAINTAINERS                 |   5 +
 configure                   |   1 +
 default-configs/pci.mak     |   1 +
 docs/specs/edu.txt          | 110 ++++++++++++
 exec.c                      |  13 +-
 hw/acpi/ich9.c              |   2 +-
 hw/acpi/piix4.c             |   2 +-
 hw/arm/stellaris.c          |   2 +-
 hw/block/fdc.c              |   2 +-
 hw/char/cadence_uart.c      |   2 +-
 hw/char/serial.c            |   4 +-
 hw/core/ptimer.c            |   2 +-
 hw/dma/pl330.c              |   2 +-
 hw/i386/multiboot.c         |  16 +-
 hw/i386/pc_piix.c           |   8 +-
 hw/i386/pc_q35.c            |   4 +
 hw/input/lm832x.c           |   2 +-
 hw/intc/apic_common.c       |   8 +-
 hw/intc/armv7m_nvic.c       |   2 +-
 hw/isa/vt82c686.c           |   2 +-
 hw/misc/Makefile.objs       |   1 +
 hw/misc/edu.c               | 408 ++++++++++++++++++++++++++++++++++++++++++++
 hw/misc/macio/cuda.c        |   2 +-
 hw/net/pcnet.c              |   2 +-
 hw/sd/sdhci.c               |   4 +-
 hw/timer/a9gtimer.c         |   2 +-
 hw/timer/arm_mptimer.c      |   2 +-
 hw/timer/hpet.c             |   2 +-
 hw/timer/mc146818rtc.c      |   4 +-
 hw/usb/hcd-ehci.c           |   2 +-
 hw/usb/hcd-ohci.c           |   2 +-
 hw/usb/hcd-uhci.c           |   2 +-
 hw/usb/hcd-xhci.c           |   2 +-
 hw/usb/redirect.c           |   2 +-
 hw/watchdog/wdt_i6300esb.c  |   2 +-
 hw/watchdog/wdt_ib700.c     |   2 +-
 include/migration/vmstate.h |  28 ++-
 include/qemu/timer.h        |  84 +++++++++
 qemu-timer.c                |  14 +-
 scripts/kvm/kvm_stat        |  24 ++-
 target-arm/machine.c        |   4 +-
 target-i386/cpu.c           |   9 +-
 target-i386/cpu.h           |  68 +-------
 target-i386/kvm.c           |  40 +++--
 target-i386/machine.c       |  73 ++++----
 tests/multiboot/Makefile    |   5 +-
 tests/multiboot/libc.c      |  12 ++
 tests/multiboot/libc.h      |   1 +
 tests/multiboot/mmap.out    |  37 ++--
 tests/multiboot/module.txt  |   1 +
 tests/multiboot/modules.c   |  55 ++++++
 tests/multiboot/modules.out |  38 +++++
 tests/multiboot/run_test.sh |   9 +-
 54 files changed, 944 insertions(+), 192 deletions(-)
 create mode 100644 docs/specs/edu.txt
 create mode 100644 hw/misc/edu.c
 create mode 100644 tests/multiboot/module.txt
 create mode 100644 tests/multiboot/modules.c
 create mode 100644 tests/multiboot/modules.out
-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 01/19] pc: fix KVM features in pc-1.3 and earlier machine types
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 02/19] tests/multiboot: Update reference output Paolo Bonzini
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

Due to a typo, instead of disabling KVM_FEATURE_PV_EOI (bit
6) these machine types are disabling bits 1 and 2, which are
KVM_FEATURE_NOP_IO_DELAY and KVM_FEATURE_MMU_OP.  Not a big deal
because they aren't very important and KVM_FEATURE_MMU_OP is
disabled anyway.  The worst part is actually that KVM_FEATURE_PV_EOI
is remaining enabled.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/pc_piix.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index f0a3201..97a754e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -406,7 +406,7 @@ static void pc_compat_1_3(MachineState *machine)
 static void pc_compat_1_2(MachineState *machine)
 {
     pc_compat_1_3(machine);
-    x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, KVM_FEATURE_PV_EOI);
+    x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 << KVM_FEATURE_PV_EOI);
 }
 
 static void pc_init_pci_2_2(MachineState *machine)
@@ -483,7 +483,7 @@ static void pc_init_isa(MachineState *machine)
     if (!machine->cpu_model) {
         machine->cpu_model = "486";
     }
-    x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, KVM_FEATURE_PV_EOI);
+    x86_cpu_compat_kvm_no_autoenable(FEAT_KVM, 1 << KVM_FEATURE_PV_EOI);
     enable_compat_apic_id_mode();
     pc_init1(machine, 0, 1);
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 02/19] tests/multiboot: Update reference output
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 01/19] pc: fix KVM features in pc-1.3 and earlier machine types Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 03/19] multiboot: Fix offset of bootloader name Paolo Bonzini
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf

From: Kevin Wolf <kwolf@redhat.com>

The changes look okay (larger PCI hole, some rounding differences), so
just update the reference output of the test case.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/multiboot/mmap.out | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/tests/multiboot/mmap.out b/tests/multiboot/mmap.out
index e70b6eb..003e109 100644
--- a/tests/multiboot/mmap.out
+++ b/tests/multiboot/mmap.out
@@ -4,14 +4,14 @@
 === Running test case: mmap.elf  ===
 
 Lower memory: 639k
-Upper memory: 130040k
+Upper memory: 129920k
 
 e820 memory map:
 0x0 - 0x9fc00: type 1 [entry size: 20]
 0x9fc00 - 0xa0000: type 2 [entry size: 20]
 0xf0000 - 0x100000: type 2 [entry size: 20]
-0x100000 - 0x7ffe000: type 1 [entry size: 20]
-0x7ffe000 - 0x8000000: type 2 [entry size: 20]
+0x100000 - 0x7fe0000: type 1 [entry size: 20]
+0x7fe0000 - 0x8000000: type 2 [entry size: 20]
 0xfffc0000 - 0x100000000: type 2 [entry size: 20]
 
 mmap start:       0x9000
@@ -22,32 +22,31 @@ real mmap end:    0x9090
 === Running test case: mmap.elf -m 1.1M ===
 
 Lower memory: 639k
-Upper memory: 96k
+Upper memory: 104k
 
 e820 memory map:
 0x0 - 0x9fc00: type 1 [entry size: 20]
 0x9fc00 - 0xa0000: type 2 [entry size: 20]
 0xf0000 - 0x100000: type 2 [entry size: 20]
-0x100000 - 0x118000: type 1 [entry size: 20]
-0x118000 - 0x11a000: type 2 [entry size: 20]
+0x100000 - 0x11a000: type 1 [entry size: 20]
 0xfffc0000 - 0x100000000: type 2 [entry size: 20]
 
 mmap start:       0x9000
-mmap end:         0x9090
-real mmap end:    0x9090
+mmap end:         0x9078
+real mmap end:    0x9078
 
 
 === Running test case: mmap.elf -m 2G ===
 
 Lower memory: 639k
-Upper memory: 2096120k
+Upper memory: 2096000k
 
 e820 memory map:
 0x0 - 0x9fc00: type 1 [entry size: 20]
 0x9fc00 - 0xa0000: type 2 [entry size: 20]
 0xf0000 - 0x100000: type 2 [entry size: 20]
-0x100000 - 0x7fffe000: type 1 [entry size: 20]
-0x7fffe000 - 0x80000000: type 2 [entry size: 20]
+0x100000 - 0x7ffe0000: type 1 [entry size: 20]
+0x7ffe0000 - 0x80000000: type 2 [entry size: 20]
 0xfffc0000 - 0x100000000: type 2 [entry size: 20]
 
 mmap start:       0x9000
@@ -58,16 +57,16 @@ real mmap end:    0x9090
 === Running test case: mmap.elf -m 4G ===
 
 Lower memory: 639k
-Upper memory: 3668984k
+Upper memory: 3144576k
 
 e820 memory map:
 0x0 - 0x9fc00: type 1 [entry size: 20]
 0x9fc00 - 0xa0000: type 2 [entry size: 20]
 0xf0000 - 0x100000: type 2 [entry size: 20]
-0x100000 - 0xdfffe000: type 1 [entry size: 20]
-0xdfffe000 - 0xe0000000: type 2 [entry size: 20]
+0x100000 - 0xbffe0000: type 1 [entry size: 20]
+0xbffe0000 - 0xc0000000: type 2 [entry size: 20]
 0xfffc0000 - 0x100000000: type 2 [entry size: 20]
-0x100000000 - 0x120000000: type 1 [entry size: 20]
+0x100000000 - 0x140000000: type 1 [entry size: 20]
 
 mmap start:       0x9000
 mmap end:         0x90a8
@@ -77,16 +76,16 @@ real mmap end:    0x90a8
 === Running test case: mmap.elf -m 8G ===
 
 Lower memory: 639k
-Upper memory: 3668984k
+Upper memory: 3144576k
 
 e820 memory map:
 0x0 - 0x9fc00: type 1 [entry size: 20]
 0x9fc00 - 0xa0000: type 2 [entry size: 20]
 0xf0000 - 0x100000: type 2 [entry size: 20]
-0x100000 - 0xdfffe000: type 1 [entry size: 20]
-0xdfffe000 - 0xe0000000: type 2 [entry size: 20]
+0x100000 - 0xbffe0000: type 1 [entry size: 20]
+0xbffe0000 - 0xc0000000: type 2 [entry size: 20]
 0xfffc0000 - 0x100000000: type 2 [entry size: 20]
-0x100000000 - 0x220000000: type 1 [entry size: 20]
+0x100000000 - 0x240000000: type 1 [entry size: 20]
 
 mmap start:       0x9000
 mmap end:         0x90a8
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 03/19] multiboot: Fix offset of bootloader name
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 01/19] pc: fix KVM features in pc-1.3 and earlier machine types Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 02/19] tests/multiboot: Update reference output Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 04/19] tests/multiboot: Add test for modules Paolo Bonzini
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf

From: Kevin Wolf <kwolf@redhat.com>

This fixes a bug introduced in commit 5eba5a66 ('Add bootloader name to
multiboot implementation').

The calculation of the bootloader name offset didn't consider space
occupied by module command lines, so some unlucky module got its command
line partially overwritten with a "qemu" string.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/multiboot.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index f86d351..1adbe9e 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -156,6 +156,7 @@ int load_multiboot(FWCfgState *fw_cfg,
     MultibootState mbs;
     uint8_t bootinfo[MBI_SIZE];
     uint8_t *mb_bootinfo_data;
+    uint32_t cmdline_len;
 
     /* Ok, let's see if it is a multiboot image.
        The header is 12x32bit long, so the latest entry may be 8192 - 48. */
@@ -258,27 +259,28 @@ int load_multiboot(FWCfgState *fw_cfg,
     mbs.offset_mbinfo = mbs.mb_buf_size;
 
     /* Calculate space for cmdlines, bootloader name, and mb_mods */
-    mbs.mb_buf_size += strlen(kernel_filename) + 1;
-    mbs.mb_buf_size += strlen(kernel_cmdline) + 1;
-    mbs.mb_buf_size += strlen(bootloader_name) + 1;
+    cmdline_len = strlen(kernel_filename) + 1;
+    cmdline_len += strlen(kernel_cmdline) + 1;
     if (initrd_filename) {
         const char *r = initrd_filename;
-        mbs.mb_buf_size += strlen(r) + 1;
+        cmdline_len += strlen(r) + 1;
         mbs.mb_mods_avail = 1;
         while (*(r = get_opt_value(NULL, 0, r))) {
            mbs.mb_mods_avail++;
            r++;
         }
-        mbs.mb_buf_size += MB_MOD_SIZE * mbs.mb_mods_avail;
     }
 
+    mbs.mb_buf_size += cmdline_len;
+    mbs.mb_buf_size += MB_MOD_SIZE * mbs.mb_mods_avail;
+    mbs.mb_buf_size += strlen(bootloader_name) + 1;
+
     mbs.mb_buf_size = TARGET_PAGE_ALIGN(mbs.mb_buf_size);
 
     /* enlarge mb_buf to hold cmdlines, bootloader, mb-info structs */
     mbs.mb_buf            = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
     mbs.offset_cmdlines   = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
-    mbs.offset_bootloader = mbs.offset_cmdlines + strlen(kernel_filename) + 1 
-                            + strlen(kernel_cmdline) + 1;
+    mbs.offset_bootloader = mbs.offset_cmdlines + cmdline_len;
 
     if (initrd_filename) {
         char *next_initrd, not_last;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 04/19] tests/multiboot: Add test for modules
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (2 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 03/19] multiboot: Fix offset of bootloader name Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 05/19] target-i386: use vmstate_offset_sub_array for AVX registers Paolo Bonzini
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf

From: Kevin Wolf <kwolf@redhat.com>

This test case is meant to detect corruptions of the Multiboot modules
as well as the multiboot modules list and the module command lines.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 tests/multiboot/Makefile    |  5 ++++-
 tests/multiboot/libc.c      | 12 ++++++++++
 tests/multiboot/libc.h      |  1 +
 tests/multiboot/module.txt  |  1 +
 tests/multiboot/modules.c   | 55 +++++++++++++++++++++++++++++++++++++++++++++
 tests/multiboot/modules.out | 38 +++++++++++++++++++++++++++++++
 tests/multiboot/run_test.sh |  9 +++++++-
 7 files changed, 119 insertions(+), 2 deletions(-)
 create mode 100644 tests/multiboot/module.txt
 create mode 100644 tests/multiboot/modules.c
 create mode 100644 tests/multiboot/modules.out

diff --git a/tests/multiboot/Makefile b/tests/multiboot/Makefile
index 34cdd81..36f01dc 100644
--- a/tests/multiboot/Makefile
+++ b/tests/multiboot/Makefile
@@ -6,11 +6,14 @@ LD=ld
 LDFLAGS=-melf_i386 -T link.ld
 LIBS=$(shell $(CC) $(CCFLAGS) -print-libgcc-file-name)
 
-all: mmap.elf
+all: mmap.elf modules.elf
 
 mmap.elf: start.o mmap.o libc.o
 	$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
 
+modules.elf: start.o modules.o libc.o
+	$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
+
 %.o: %.c
 	$(CC) $(CCFLAGS) -c -o $@ $^
 
diff --git a/tests/multiboot/libc.c b/tests/multiboot/libc.c
index 05abbd9..6df9bda 100644
--- a/tests/multiboot/libc.c
+++ b/tests/multiboot/libc.c
@@ -22,6 +22,18 @@
 
 #include "libc.h"
 
+void* memcpy(void *dest, const void *src, int n)
+{
+    char *d = dest;
+    const char *s = src;
+
+    while (n--) {
+        *d++ = *s++;
+    }
+
+    return dest;
+}
+
 static void print_char(char c)
 {
     outb(0xe9, c);
diff --git a/tests/multiboot/libc.h b/tests/multiboot/libc.h
index 80eec5b..04c9922 100644
--- a/tests/multiboot/libc.h
+++ b/tests/multiboot/libc.h
@@ -57,5 +57,6 @@ static inline void outb(uint16_t port, uint8_t data)
 /* Misc functions */
 
 void printf(const char *fmt, ...);
+void* memcpy(void *dest, const void *src, int n);
 
 #endif
diff --git a/tests/multiboot/module.txt b/tests/multiboot/module.txt
new file mode 100644
index 0000000..54c1d27
--- /dev/null
+++ b/tests/multiboot/module.txt
@@ -0,0 +1 @@
+This is a test file that is used as a multiboot module.
diff --git a/tests/multiboot/modules.c b/tests/multiboot/modules.c
new file mode 100644
index 0000000..531601f
--- /dev/null
+++ b/tests/multiboot/modules.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015 Kevin Wolf <kwolf@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "libc.h"
+#include "multiboot.h"
+
+int test_main(uint32_t magic, struct mb_info *mbi)
+{
+    struct mb_module *mod;
+    unsigned int i;
+
+    (void) magic;
+
+    printf("Module list with %d entries at %x\n",
+           mbi->mods_count, mbi->mods_addr);
+
+    for (i = 0, mod = (struct mb_module*) mbi->mods_addr;
+         i < mbi->mods_count;
+         i++, mod++)
+    {
+        char buf[1024];
+        unsigned int size = mod->mod_end - mod->mod_start;
+
+        printf("[%p] Module: %x - %x (%d bytes) '%s'\n",
+               mod, mod->mod_start, mod->mod_end, size, mod->string);
+
+        /* Print test file, but remove the newline at the end */
+        if (size < sizeof(buf)) {
+            memcpy(buf, (void*) mod->mod_start, size);
+            buf[size - 1] = '\0';
+            printf("         Content: '%s'\n", buf);
+        }
+    }
+
+    return 0;
+}
diff --git a/tests/multiboot/modules.out b/tests/multiboot/modules.out
new file mode 100644
index 0000000..1636708
--- /dev/null
+++ b/tests/multiboot/modules.out
@@ -0,0 +1,38 @@
+
+
+
+=== Running test case: modules.elf  ===
+
+Module list with 0 entries at 102000
+
+
+=== Running test case: modules.elf -initrd module.txt ===
+
+Module list with 1 entries at 102000
+[102000] Module: 103000 - 103038 (56 bytes) 'module.txt'
+         Content: 'This is a test file that is used as a multiboot module.'
+
+
+=== Running test case: modules.elf -initrd module.txt argument ===
+
+Module list with 1 entries at 102000
+[102000] Module: 103000 - 103038 (56 bytes) 'module.txt argument'
+         Content: 'This is a test file that is used as a multiboot module.'
+
+
+=== Running test case: modules.elf -initrd module.txt argument,,with,,commas ===
+
+Module list with 1 entries at 102000
+[102000] Module: 103000 - 103038 (56 bytes) 'module.txt argument,with,commas'
+         Content: 'This is a test file that is used as a multiboot module.'
+
+
+=== Running test case: modules.elf -initrd module.txt,module.txt argument,module.txt ===
+
+Module list with 3 entries at 102000
+[102000] Module: 103000 - 103038 (56 bytes) 'module.txt'
+         Content: 'This is a test file that is used as a multiboot module.'
+[102010] Module: 104000 - 104038 (56 bytes) 'module.txt argument'
+         Content: 'This is a test file that is used as a multiboot module.'
+[102020] Module: 105000 - 105038 (56 bytes) 'module.txt'
+         Content: 'This is a test file that is used as a multiboot module.'
diff --git a/tests/multiboot/run_test.sh b/tests/multiboot/run_test.sh
index 97a9a49..78d7edf 100755
--- a/tests/multiboot/run_test.sh
+++ b/tests/multiboot/run_test.sh
@@ -48,10 +48,17 @@ mmap() {
     run_qemu mmap.elf -m 8G
 }
 
+modules() {
+    run_qemu modules.elf
+    run_qemu modules.elf -initrd module.txt
+    run_qemu modules.elf -initrd "module.txt argument"
+    run_qemu modules.elf -initrd "module.txt argument,,with,,commas"
+    run_qemu modules.elf -initrd "module.txt,module.txt argument,module.txt"
+}
 
 make all
 
-for t in mmap; do
+for t in mmap modules; do
 
     echo > test.log
     $t
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 05/19] target-i386: use vmstate_offset_sub_array for AVX registers
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (3 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 04/19] tests/multiboot: Add test for modules Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 06/19] target-i386: make xmm_regs 512-bit wide Paolo Bonzini
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

After the next patch, each vmstate field will extract parts of a larger
(32x512-bit) array, so we cannot check the vmstate field against the
type of the array.

While changing this, change the macros to accept the index of the first
element (which will not be 0 for Hi16_ZMM_REGS) instead of the number
of elements (which is always CPU_NB_REGS).

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/migration/vmstate.h | 10 ++++++++++
 target-i386/machine.c       | 28 ++++++++++++++++------------
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index d712a65..6097b94 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -359,6 +359,16 @@ extern const VMStateInfo vmstate_info_bitmap;
     .offset     = vmstate_offset_array(_s, _f, _type*, _n),          \
 }
 
+#define VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, _num, _version, _vmsd, _type) { \
+    .name       = (stringify(_field)),                                     \
+    .version_id = (_version),                                              \
+    .num        = (_num),                                                  \
+    .vmsd       = &(_vmsd),                                                \
+    .size       = sizeof(_type),                                           \
+    .flags      = VMS_STRUCT|VMS_ARRAY,                                    \
+    .offset     = vmstate_offset_sub_array(_state, _field, _type, _start), \
+}
+
 #define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \
     .name         = (stringify(_field)),                             \
     .num          = (_num),                                          \
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 722d62e4..604a49a 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -42,8 +42,9 @@ static const VMStateDescription vmstate_xmm_reg = {
     }
 };
 
-#define VMSTATE_XMM_REGS(_field, _state, _n)                         \
-    VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_xmm_reg, XMMReg)
+#define VMSTATE_XMM_REGS(_field, _state, _start)                         \
+    VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0,     \
+                             vmstate_xmm_reg, XMMReg)
 
 /* YMMH format is the same as XMM */
 static const VMStateDescription vmstate_ymmh_reg = {
@@ -57,8 +58,9 @@ static const VMStateDescription vmstate_ymmh_reg = {
     }
 };
 
-#define VMSTATE_YMMH_REGS_VARS(_field, _state, _n, _v)                         \
-    VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_ymmh_reg, XMMReg)
+#define VMSTATE_YMMH_REGS_VARS(_field, _state, _start, _v)               \
+    VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, _v,    \
+                             vmstate_ymmh_reg, XMMReg)
 
 static const VMStateDescription vmstate_zmmh_reg = {
     .name = "zmmh_reg",
@@ -73,8 +75,9 @@ static const VMStateDescription vmstate_zmmh_reg = {
     }
 };
 
-#define VMSTATE_ZMMH_REGS_VARS(_field, _state, _n)                             \
-    VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_zmmh_reg, YMMReg)
+#define VMSTATE_ZMMH_REGS_VARS(_field, _state, _start)                   \
+    VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0,     \
+                             vmstate_zmmh_reg, YMMReg)
 
 #ifdef TARGET_X86_64
 static const VMStateDescription vmstate_hi16_zmm_reg = {
@@ -94,8 +97,9 @@ static const VMStateDescription vmstate_hi16_zmm_reg = {
     }
 };
 
-#define VMSTATE_Hi16_ZMM_REGS_VARS(_field, _state, _n)                         \
-    VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_hi16_zmm_reg, ZMMReg)
+#define VMSTATE_Hi16_ZMM_REGS_VARS(_field, _state, _start)               \
+    VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0,     \
+                             vmstate_hi16_zmm_reg, ZMMReg)
 #endif
 
 static const VMStateDescription vmstate_bnd_regs = {
@@ -679,9 +683,9 @@ static const VMStateDescription vmstate_avx512 = {
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT64_ARRAY(env.opmask_regs, X86CPU, NB_OPMASK_REGS),
-        VMSTATE_ZMMH_REGS_VARS(env.zmmh_regs, X86CPU, CPU_NB_REGS),
+        VMSTATE_ZMMH_REGS_VARS(env.zmmh_regs, X86CPU, 0),
 #ifdef TARGET_X86_64
-        VMSTATE_Hi16_ZMM_REGS_VARS(env.hi16_zmm_regs, X86CPU, CPU_NB_REGS),
+        VMSTATE_Hi16_ZMM_REGS_VARS(env.hi16_zmm_regs, X86CPU, 0),
 #endif
         VMSTATE_END_OF_LIST()
     }
@@ -750,7 +754,7 @@ VMStateDescription vmstate_x86_cpu = {
         VMSTATE_INT32(env.a20_mask, X86CPU),
         /* XMM */
         VMSTATE_UINT32(env.mxcsr, X86CPU),
-        VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, CPU_NB_REGS),
+        VMSTATE_XMM_REGS(env.xmm_regs, X86CPU, 0),
 
 #ifdef TARGET_X86_64
         VMSTATE_UINT64(env.efer, X86CPU),
@@ -803,7 +807,7 @@ VMStateDescription vmstate_x86_cpu = {
         /* XSAVE related fields */
         VMSTATE_UINT64_V(env.xcr0, X86CPU, 12),
         VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12),
-        VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, CPU_NB_REGS, 12),
+        VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, 0, 12),
         VMSTATE_END_OF_LIST()
         /* The above list is not sorted /wrt version numbers, watch out! */
     },
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 06/19] target-i386: make xmm_regs 512-bit wide
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (4 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 05/19] target-i386: use vmstate_offset_sub_array for AVX registers Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 07/19] qemu-timer: add timer_init and timer_init_ns/us/ms Paolo Bonzini
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

Right now, the AVX512 registers are split in many different fields:
xmm_regs for the low 128 bits of the first 16 registers, ymmh_regs
for the next 128 bits of the same first 16 registers, zmmh_regs
for the next 256 bits of the same first 16 registers, and finally
hi16_zmm_regs for the full 512 bits of the second 16 bit registers.

This makes it simple to move data in and out of the xsave region,
but would be a nightmare for a hypothetical TCG implementation and
leads to a proliferation of [XYZ]MM_[BWLSQD] macros.  Instead,
this patch marshals data manually from the xsave region to a single
32x512-bit array, simplifying the macro jungle and clarifying which
bits are in which vmstate subsection.

The migration format is unaffected.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target-i386/cpu.h     | 68 ++++++---------------------------------------------
 target-i386/kvm.c     | 40 ++++++++++++++++++------------
 target-i386/machine.c | 55 ++++++++++++++++++++---------------------
 3 files changed, 59 insertions(+), 104 deletions(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index da33587..478450c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -713,31 +713,13 @@ typedef struct SegmentCache {
 } SegmentCache;
 
 typedef union {
-    uint8_t _b[16];
-    uint16_t _w[8];
-    uint32_t _l[4];
-    uint64_t _q[2];
-    float32 _s[4];
-    float64 _d[2];
-} XMMReg;
-
-typedef union {
-    uint8_t _b[32];
-    uint16_t _w[16];
-    uint32_t _l[8];
-    uint64_t _q[4];
-    float32 _s[8];
-    float64 _d[4];
-} YMMReg;
-
-typedef union {
     uint8_t _b[64];
     uint16_t _w[32];
     uint32_t _l[16];
     uint64_t _q[8];
     float32 _s[16];
     float64 _d[8];
-} ZMMReg;
+} XMMReg; /* really zmm */
 
 typedef union {
     uint8_t _b[8];
@@ -758,46 +740,18 @@ typedef struct BNDCSReg {
 } BNDCSReg;
 
 #ifdef HOST_WORDS_BIGENDIAN
-#define ZMM_B(n) _b[63 - (n)]
-#define ZMM_W(n) _w[31 - (n)]
-#define ZMM_L(n) _l[15 - (n)]
-#define ZMM_S(n) _s[15 - (n)]
-#define ZMM_Q(n) _q[7 - (n)]
-#define ZMM_D(n) _d[7 - (n)]
-
-#define YMM_B(n) _b[31 - (n)]
-#define YMM_W(n) _w[15 - (n)]
-#define YMM_L(n) _l[7 - (n)]
-#define YMM_S(n) _s[7 - (n)]
-#define YMM_Q(n) _q[3 - (n)]
-#define YMM_D(n) _d[3 - (n)]
-
-#define XMM_B(n) _b[15 - (n)]
-#define XMM_W(n) _w[7 - (n)]
-#define XMM_L(n) _l[3 - (n)]
-#define XMM_S(n) _s[3 - (n)]
-#define XMM_Q(n) _q[1 - (n)]
-#define XMM_D(n) _d[1 - (n)]
+#define XMM_B(n) _b[63 - (n)]
+#define XMM_W(n) _w[31 - (n)]
+#define XMM_L(n) _l[15 - (n)]
+#define XMM_S(n) _s[15 - (n)]
+#define XMM_Q(n) _q[7 - (n)]
+#define XMM_D(n) _d[7 - (n)]
 
 #define MMX_B(n) _b[7 - (n)]
 #define MMX_W(n) _w[3 - (n)]
 #define MMX_L(n) _l[1 - (n)]
 #define MMX_S(n) _s[1 - (n)]
 #else
-#define ZMM_B(n) _b[n]
-#define ZMM_W(n) _w[n]
-#define ZMM_L(n) _l[n]
-#define ZMM_S(n) _s[n]
-#define ZMM_Q(n) _q[n]
-#define ZMM_D(n) _d[n]
-
-#define YMM_B(n) _b[n]
-#define YMM_W(n) _w[n]
-#define YMM_L(n) _l[n]
-#define YMM_S(n) _s[n]
-#define YMM_Q(n) _q[n]
-#define YMM_D(n) _d[n]
-
 #define XMM_B(n) _b[n]
 #define XMM_W(n) _w[n]
 #define XMM_L(n) _l[n]
@@ -896,17 +850,11 @@ typedef struct CPUX86State {
     float_status mmx_status; /* for 3DNow! float ops */
     float_status sse_status;
     uint32_t mxcsr;
-    XMMReg xmm_regs[CPU_NB_REGS];
+    XMMReg xmm_regs[CPU_NB_REGS == 8 ? 8 : 32];
     XMMReg xmm_t0;
     MMXReg mmx_t0;
 
-    XMMReg ymmh_regs[CPU_NB_REGS];
-
     uint64_t opmask_regs[NB_OPMASK_REGS];
-    YMMReg zmmh_regs[CPU_NB_REGS];
-#ifdef TARGET_X86_64
-    ZMMReg hi16_zmm_regs[CPU_NB_REGS];
-#endif
 
     /* sysenter registers */
     uint32_t sysenter_cs;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 36b1519..40d6a14 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1048,7 +1048,7 @@ static int kvm_put_xsave(X86CPU *cpu)
     CPUX86State *env = &cpu->env;
     struct kvm_xsave* xsave = env->kvm_xsave_buf;
     uint16_t cwd, swd, twd;
-    uint8_t *xmm;
+    uint8_t *xmm, *ymmh, *zmmh;
     int i, r;
 
     if (!kvm_has_xsave()) {
@@ -1071,26 +1071,30 @@ static int kvm_put_xsave(X86CPU *cpu)
             sizeof env->fpregs);
     xsave->region[XSAVE_MXCSR] = env->mxcsr;
     *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;
-    memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs,
-            sizeof env->ymmh_regs);
     memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs,
             sizeof env->bnd_regs);
     memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs,
             sizeof(env->bndcs_regs));
     memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs,
             sizeof env->opmask_regs);
-    memcpy(&xsave->region[XSAVE_ZMM_Hi256], env->zmmh_regs,
-            sizeof env->zmmh_regs);
 
     xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
-    for (i = 0; i < CPU_NB_REGS; i++, xmm += 16) {
+    ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
+    zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
+    for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
         stq_p(xmm,     env->xmm_regs[i].XMM_Q(0));
         stq_p(xmm+8,   env->xmm_regs[i].XMM_Q(1));
+        stq_p(ymmh,    env->xmm_regs[i].XMM_Q(2));
+        stq_p(ymmh+8,  env->xmm_regs[i].XMM_Q(3));
+        stq_p(zmmh,    env->xmm_regs[i].XMM_Q(4));
+        stq_p(zmmh+8,  env->xmm_regs[i].XMM_Q(5));
+        stq_p(zmmh+16, env->xmm_regs[i].XMM_Q(6));
+        stq_p(zmmh+24, env->xmm_regs[i].XMM_Q(7));
     }
 
 #ifdef TARGET_X86_64
-    memcpy(&xsave->region[XSAVE_Hi16_ZMM], env->hi16_zmm_regs,
-            sizeof env->hi16_zmm_regs);
+    memcpy(&xsave->region[XSAVE_Hi16_ZMM], &env->xmm_regs[16],
+            16 * sizeof env->xmm_regs[16]);
 #endif
     r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave);
     return r;
@@ -1407,7 +1411,7 @@ static int kvm_get_xsave(X86CPU *cpu)
     CPUX86State *env = &cpu->env;
     struct kvm_xsave* xsave = env->kvm_xsave_buf;
     int ret, i;
-    const uint8_t *xmm;
+    const uint8_t *xmm, *ymmh, *zmmh;
     uint16_t cwd, swd, twd;
 
     if (!kvm_has_xsave()) {
@@ -1435,26 +1439,30 @@ static int kvm_get_xsave(X86CPU *cpu)
     memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],
             sizeof env->fpregs);
     env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
-    memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE],
-            sizeof env->ymmh_regs);
     memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS],
             sizeof env->bnd_regs);
     memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR],
             sizeof(env->bndcs_regs));
     memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK],
             sizeof env->opmask_regs);
-    memcpy(env->zmmh_regs, &xsave->region[XSAVE_ZMM_Hi256],
-            sizeof env->zmmh_regs);
 
     xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE];
-    for (i = 0; i < CPU_NB_REGS; i++, xmm += 16) {
+    ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE];
+    zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256];
+    for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) {
         env->xmm_regs[i].XMM_Q(0) = ldq_p(xmm);
         env->xmm_regs[i].XMM_Q(1) = ldq_p(xmm+8);
+        env->xmm_regs[i].XMM_Q(2) = ldq_p(ymmh);
+        env->xmm_regs[i].XMM_Q(3) = ldq_p(ymmh+8);
+        env->xmm_regs[i].XMM_Q(4) = ldq_p(zmmh);
+        env->xmm_regs[i].XMM_Q(5) = ldq_p(zmmh+8);
+        env->xmm_regs[i].XMM_Q(6) = ldq_p(zmmh+16);
+        env->xmm_regs[i].XMM_Q(7) = ldq_p(zmmh+24);
     }
 
 #ifdef TARGET_X86_64
-    memcpy(env->hi16_zmm_regs, &xsave->region[XSAVE_Hi16_ZMM],
-            sizeof env->hi16_zmm_regs);
+    memcpy(&env->xmm_regs[16], &xsave->region[XSAVE_Hi16_ZMM],
+           16 * sizeof env->xmm_regs[16]);
 #endif
     return 0;
 }
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 604a49a..cd1ddd2 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -46,14 +46,14 @@ static const VMStateDescription vmstate_xmm_reg = {
     VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0,     \
                              vmstate_xmm_reg, XMMReg)
 
-/* YMMH format is the same as XMM */
+/* YMMH format is the same as XMM, but for bits 128-255 */
 static const VMStateDescription vmstate_ymmh_reg = {
     .name = "ymmh_reg",
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT64(XMM_Q(0), XMMReg),
-        VMSTATE_UINT64(XMM_Q(1), XMMReg),
+        VMSTATE_UINT64(XMM_Q(2), XMMReg),
+        VMSTATE_UINT64(XMM_Q(3), XMMReg),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -67,17 +67,17 @@ static const VMStateDescription vmstate_zmmh_reg = {
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT64(YMM_Q(0), YMMReg),
-        VMSTATE_UINT64(YMM_Q(1), YMMReg),
-        VMSTATE_UINT64(YMM_Q(2), YMMReg),
-        VMSTATE_UINT64(YMM_Q(3), YMMReg),
+        VMSTATE_UINT64(XMM_Q(4), XMMReg),
+        VMSTATE_UINT64(XMM_Q(5), XMMReg),
+        VMSTATE_UINT64(XMM_Q(6), XMMReg),
+        VMSTATE_UINT64(XMM_Q(7), XMMReg),
         VMSTATE_END_OF_LIST()
     }
 };
 
 #define VMSTATE_ZMMH_REGS_VARS(_field, _state, _start)                   \
     VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0,     \
-                             vmstate_zmmh_reg, YMMReg)
+                             vmstate_zmmh_reg, XMMReg)
 
 #ifdef TARGET_X86_64
 static const VMStateDescription vmstate_hi16_zmm_reg = {
@@ -85,21 +85,21 @@ static const VMStateDescription vmstate_hi16_zmm_reg = {
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT64(ZMM_Q(0), ZMMReg),
-        VMSTATE_UINT64(ZMM_Q(1), ZMMReg),
-        VMSTATE_UINT64(ZMM_Q(2), ZMMReg),
-        VMSTATE_UINT64(ZMM_Q(3), ZMMReg),
-        VMSTATE_UINT64(ZMM_Q(4), ZMMReg),
-        VMSTATE_UINT64(ZMM_Q(5), ZMMReg),
-        VMSTATE_UINT64(ZMM_Q(6), ZMMReg),
-        VMSTATE_UINT64(ZMM_Q(7), ZMMReg),
+        VMSTATE_UINT64(XMM_Q(0), XMMReg),
+        VMSTATE_UINT64(XMM_Q(1), XMMReg),
+        VMSTATE_UINT64(XMM_Q(2), XMMReg),
+        VMSTATE_UINT64(XMM_Q(3), XMMReg),
+        VMSTATE_UINT64(XMM_Q(4), XMMReg),
+        VMSTATE_UINT64(XMM_Q(5), XMMReg),
+        VMSTATE_UINT64(XMM_Q(6), XMMReg),
+        VMSTATE_UINT64(XMM_Q(7), XMMReg),
         VMSTATE_END_OF_LIST()
     }
 };
 
 #define VMSTATE_Hi16_ZMM_REGS_VARS(_field, _state, _start)               \
     VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, CPU_NB_REGS, 0,     \
-                             vmstate_hi16_zmm_reg, ZMMReg)
+                             vmstate_hi16_zmm_reg, XMMReg)
 #endif
 
 static const VMStateDescription vmstate_bnd_regs = {
@@ -658,17 +658,16 @@ static bool avx512_needed(void *opaque)
     }
 
     for (i = 0; i < CPU_NB_REGS; i++) {
-#define ENV_ZMMH(reg, field) (env->zmmh_regs[reg].YMM_Q(field))
-        if (ENV_ZMMH(i, 0) || ENV_ZMMH(i, 1) ||
-            ENV_ZMMH(i, 2) || ENV_ZMMH(i, 3)) {
+#define ENV_XMM(reg, field) (env->xmm_regs[reg].XMM_Q(field))
+        if (ENV_XMM(i, 4) || ENV_XMM(i, 6) ||
+            ENV_XMM(i, 5) || ENV_XMM(i, 7)) {
             return true;
         }
 #ifdef TARGET_X86_64
-#define ENV_Hi16_ZMM(reg, field) (env->hi16_zmm_regs[reg].ZMM_Q(field))
-        if (ENV_Hi16_ZMM(i, 0) || ENV_Hi16_ZMM(i, 1) ||
-            ENV_Hi16_ZMM(i, 2) || ENV_Hi16_ZMM(i, 3) ||
-            ENV_Hi16_ZMM(i, 4) || ENV_Hi16_ZMM(i, 5) ||
-            ENV_Hi16_ZMM(i, 6) || ENV_Hi16_ZMM(i, 7)) {
+        if (ENV_XMM(i+16, 0) || ENV_XMM(i+16, 1) ||
+            ENV_XMM(i+16, 2) || ENV_XMM(i+16, 3) ||
+            ENV_XMM(i+16, 4) || ENV_XMM(i+16, 5) ||
+            ENV_XMM(i+16, 6) || ENV_XMM(i+16, 7)) {
             return true;
         }
 #endif
@@ -683,9 +682,9 @@ static const VMStateDescription vmstate_avx512 = {
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT64_ARRAY(env.opmask_regs, X86CPU, NB_OPMASK_REGS),
-        VMSTATE_ZMMH_REGS_VARS(env.zmmh_regs, X86CPU, 0),
+        VMSTATE_ZMMH_REGS_VARS(env.xmm_regs, X86CPU, 0),
 #ifdef TARGET_X86_64
-        VMSTATE_Hi16_ZMM_REGS_VARS(env.hi16_zmm_regs, X86CPU, 0),
+        VMSTATE_Hi16_ZMM_REGS_VARS(env.xmm_regs, X86CPU, 16),
 #endif
         VMSTATE_END_OF_LIST()
     }
@@ -807,7 +806,7 @@ VMStateDescription vmstate_x86_cpu = {
         /* XSAVE related fields */
         VMSTATE_UINT64_V(env.xcr0, X86CPU, 12),
         VMSTATE_UINT64_V(env.xstate_bv, X86CPU, 12),
-        VMSTATE_YMMH_REGS_VARS(env.ymmh_regs, X86CPU, 0, 12),
+        VMSTATE_YMMH_REGS_VARS(env.xmm_regs, X86CPU, 0, 12),
         VMSTATE_END_OF_LIST()
         /* The above list is not sorted /wrt version numbers, watch out! */
     },
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 07/19] qemu-timer: add timer_init and timer_init_ns/us/ms
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (5 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 06/19] target-i386: make xmm_regs 512-bit wide Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 08/19] qemu-timer: introduce timer_deinit Paolo Bonzini
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

These functions for the main loop TimerListGroup will replace
timer_new and timer_new_ns/us/ms.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/timer.h | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 0666920..9a3504c 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -428,6 +428,79 @@ void timer_init_tl(QEMUTimer *ts,
                    QEMUTimerCB *cb, void *opaque);
 
 /**
+ * timer_init:
+ * @type: the clock to associate with the timer
+ * @scale: the scale value for the timer
+ * @cb: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Initialize a timer with the given scale on the default timer list
+ * associated with the clock.
+ *
+ * You need not call an explicit deinit call. Simply make
+ * sure it is not on a list with timer_del.
+ */
+static inline void timer_init(QEMUTimer *ts, QEMUClockType type, int scale,
+                              QEMUTimerCB *cb, void *opaque)
+{
+    timer_init_tl(ts, main_loop_tlg.tl[type], scale, cb, opaque);
+}
+
+/**
+ * timer_init_ns:
+ * @type: the clock to associate with the timer
+ * @cb: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Initialize a timer with nanosecond scale on the default timer list
+ * associated with the clock.
+ *
+ * You need not call an explicit deinit call. Simply make
+ * sure it is not on a list with timer_del.
+ */
+static inline void timer_init_ns(QEMUTimer *ts, QEMUClockType type,
+                                 QEMUTimerCB *cb, void *opaque)
+{
+    timer_init(ts, type, SCALE_NS, cb, opaque);
+}
+
+/**
+ * timer_init_us:
+ * @type: the clock to associate with the timer
+ * @cb: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Initialize a timer with microsecond scale on the default timer list
+ * associated with the clock.
+ *
+ * You need not call an explicit deinit call. Simply make
+ * sure it is not on a list with timer_del.
+ */
+static inline void timer_init_us(QEMUTimer *ts, QEMUClockType type,
+                                 QEMUTimerCB *cb, void *opaque)
+{
+    timer_init(ts, type, SCALE_US, cb, opaque);
+}
+
+/**
+ * timer_init_ms:
+ * @type: the clock to associate with the timer
+ * @cb: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Initialize a timer with millisecond scale on the default timer list
+ * associated with the clock.
+ *
+ * You need not call an explicit deinit call. Simply make
+ * sure it is not on a list with timer_del.
+ */
+static inline void timer_init_ms(QEMUTimer *ts, QEMUClockType type,
+                                 QEMUTimerCB *cb, void *opaque)
+{
+    timer_init(ts, type, SCALE_MS, cb, opaque);
+}
+
+/**
  * timer_new_tl:
  * @timer_list: the timer list to attach the timer to
  * @scale: the scale value for the timer
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 08/19] qemu-timer: introduce timer_deinit
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (6 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 07/19] qemu-timer: add timer_init and timer_init_ns/us/ms Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 09/19] vmstate: accept QEMUTimer in VMSTATE_TIMER*, add VMSTATE_TIMER_PTR* Paolo Bonzini
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

In some cases, a timer was set to NULL so that we could check if it is
initialized.  Use the timer_list field instead, and add a timer_deinit
function that NULLs it.

It then makes sense that timer_del be a no-op (instead of a crasher) on
such a de-initialized timer.  It avoids the need to poke at the timerlist
field to check if the timers are initialized.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/timer.h | 11 +++++++++++
 qemu-timer.c         | 14 +++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9a3504c..ca5befb 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -595,6 +595,17 @@ static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
 }
 
 /**
+ * timer_deinit:
+ * @ts: the timer to be de-initialised
+ *
+ * Deassociate the timer from any timerlist.  You should
+ * call timer_del before.  After this call, any further
+ * timer_del call cannot cause dangling pointer accesses
+ * even if the previously used timerlist is freed.
+ */
+void timer_deinit(QEMUTimer *ts);
+
+/**
  * timer_free:
  * @ts: the timer
  *
diff --git a/qemu-timer.c b/qemu-timer.c
index 98d9d1b..464396f 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -342,6 +342,12 @@ void timer_init_tl(QEMUTimer *ts,
     ts->expire_time = -1;
 }
 
+void timer_deinit(QEMUTimer *ts)
+{
+    assert(ts->expire_time == -1);
+    ts->timer_list = NULL;
+}
+
 void timer_free(QEMUTimer *ts)
 {
     g_free(ts);
@@ -398,9 +404,11 @@ void timer_del(QEMUTimer *ts)
 {
     QEMUTimerList *timer_list = ts->timer_list;
 
-    qemu_mutex_lock(&timer_list->active_timers_lock);
-    timer_del_locked(timer_list, ts);
-    qemu_mutex_unlock(&timer_list->active_timers_lock);
+    if (timer_list) {
+        qemu_mutex_lock(&timer_list->active_timers_lock);
+        timer_del_locked(timer_list, ts);
+        qemu_mutex_unlock(&timer_list->active_timers_lock);
+    }
 }
 
 /* modify the current timer so that it will be fired when current_time
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 09/19] vmstate: accept QEMUTimer in VMSTATE_TIMER*, add VMSTATE_TIMER_PTR*
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (7 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 08/19] qemu-timer: introduce timer_deinit Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 10/19] hw: misc, add educational driver Paolo Bonzini
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

Old users of VMSTATE_TIMER* are mechanically changed to VMSTATE_TIMER_PTR
variants.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/acpi/ich9.c              |  2 +-
 hw/acpi/piix4.c             |  2 +-
 hw/arm/stellaris.c          |  2 +-
 hw/block/fdc.c              |  2 +-
 hw/char/cadence_uart.c      |  2 +-
 hw/char/serial.c            |  4 ++--
 hw/core/ptimer.c            |  2 +-
 hw/dma/pl330.c              |  2 +-
 hw/input/lm832x.c           |  2 +-
 hw/intc/armv7m_nvic.c       |  2 +-
 hw/isa/vt82c686.c           |  2 +-
 hw/misc/macio/cuda.c        |  2 +-
 hw/net/pcnet.c              |  2 +-
 hw/sd/sdhci.c               |  4 ++--
 hw/timer/a9gtimer.c         |  2 +-
 hw/timer/arm_mptimer.c      |  2 +-
 hw/timer/hpet.c             |  2 +-
 hw/timer/mc146818rtc.c      |  4 ++--
 hw/usb/hcd-ehci.c           |  2 +-
 hw/usb/hcd-ohci.c           |  2 +-
 hw/usb/hcd-uhci.c           |  2 +-
 hw/usb/hcd-xhci.c           |  2 +-
 hw/usb/redirect.c           |  2 +-
 hw/watchdog/wdt_i6300esb.c  |  2 +-
 hw/watchdog/wdt_ib700.c     |  2 +-
 include/migration/vmstate.h | 18 +++++++++++++++---
 target-arm/machine.c        |  4 ++--
 27 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index ea991a3..43869d7 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -166,7 +166,7 @@ const VMStateDescription vmstate_ich9_pm = {
         VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs),
         VMSTATE_UINT16(acpi_regs.pm1.evt.en, ICH9LPCPMRegs),
         VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, ICH9LPCPMRegs),
-        VMSTATE_TIMER(acpi_regs.tmr.timer, ICH9LPCPMRegs),
+        VMSTATE_TIMER_PTR(acpi_regs.tmr.timer, ICH9LPCPMRegs),
         VMSTATE_INT64(acpi_regs.tmr.overflow_time, ICH9LPCPMRegs),
         VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, ICH9LPCPMRegs),
         VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 481a16c..184e7e4 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -285,7 +285,7 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
         VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
         VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
-        VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState),
+        VMSTATE_TIMER_PTR(ar.tmr.timer, PIIX4PMState),
         VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
         VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),
         VMSTATE_STRUCT_TEST(
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 64bd4b4..ccc3b18 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -306,7 +306,7 @@ static const VMStateDescription vmstate_stellaris_gptm = {
         VMSTATE_UINT32_ARRAY(match_prescale, gptm_state, 2),
         VMSTATE_UINT32(rtc, gptm_state),
         VMSTATE_INT64_ARRAY(tick, gptm_state, 2),
-        VMSTATE_TIMER_ARRAY(timer, gptm_state, 2),
+        VMSTATE_TIMER_PTR_ARRAY(timer, gptm_state, 2),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 739a03e..2bf87c9 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -791,7 +791,7 @@ static const VMStateDescription vmstate_fdc_result_timer = {
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_TIMER(result_timer, FDCtrl),
+        VMSTATE_TIMER_PTR(result_timer, FDCtrl),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index a5736cb..7044b35 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -520,7 +520,7 @@ static const VMStateDescription vmstate_cadence_uart = {
         VMSTATE_UINT32(rx_count, UartState),
         VMSTATE_UINT32(tx_count, UartState),
         VMSTATE_UINT32(rx_wpos, UartState),
-        VMSTATE_TIMER(fifo_trigger_handle, UartState),
+        VMSTATE_TIMER_PTR(fifo_trigger_handle, UartState),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 3aca874..bd25c03 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -730,7 +730,7 @@ const VMStateDescription vmstate_serial_fifo_timeout_timer = {
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_TIMER(fifo_timeout_timer, SerialState),
+        VMSTATE_TIMER_PTR(fifo_timeout_timer, SerialState),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -763,7 +763,7 @@ const VMStateDescription vmstate_serial_poll = {
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_INT32(poll_msl, SerialState),
-        VMSTATE_TIMER(modem_status_poll, SerialState),
+        VMSTATE_TIMER_PTR(modem_status_poll, SerialState),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
index 466e543..2abad1f 100644
--- a/hw/core/ptimer.c
+++ b/hw/core/ptimer.c
@@ -214,7 +214,7 @@ const VMStateDescription vmstate_ptimer = {
         VMSTATE_INT64(period, ptimer_state),
         VMSTATE_INT64(last_event, ptimer_state),
         VMSTATE_INT64(next_event, ptimer_state),
-        VMSTATE_TIMER(timer, ptimer_state),
+        VMSTATE_TIMER_PTR(timer, ptimer_state),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 6b6eaae..16cf77e 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -286,7 +286,7 @@ static const VMStateDescription vmstate_pl330 = {
                        PL330Queue),
         VMSTATE_STRUCT(write_queue, PL330State, 0, vmstate_pl330_queue,
                        PL330Queue),
-        VMSTATE_TIMER(timer, PL330State),
+        VMSTATE_TIMER_PTR(timer, PL330State),
         VMSTATE_UINT32(inten, PL330State),
         VMSTATE_UINT32(int_status, PL330State),
         VMSTATE_UINT32(ev_status, PL330State),
diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c
index 9eb68e8..530a6e0 100644
--- a/hw/input/lm832x.c
+++ b/hw/input/lm832x.c
@@ -455,7 +455,7 @@ static const VMStateDescription vmstate_lm_kbd = {
         VMSTATE_UINT16_ARRAY(pwm.file, LM823KbdState, 256),
         VMSTATE_UINT8(pwm.faddr, LM823KbdState),
         VMSTATE_BUFFER(pwm.addr, LM823KbdState),
-        VMSTATE_TIMER_ARRAY(pwm.tm, LM823KbdState, 3),
+        VMSTATE_TIMER_PTR_ARRAY(pwm.tm, LM823KbdState, 3),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index d0543d4..6ff6c7f 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -450,7 +450,7 @@ static const VMStateDescription vmstate_nvic = {
         VMSTATE_UINT32(systick.control, nvic_state),
         VMSTATE_UINT32(systick.reload, nvic_state),
         VMSTATE_INT64(systick.tick, nvic_state),
-        VMSTATE_TIMER(systick.timer, nvic_state),
+        VMSTATE_TIMER_PTR(systick.timer, nvic_state),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index 2f53bf8..17510ce 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -234,7 +234,7 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_UINT16(ar.pm1.evt.en, VT686PMState),
         VMSTATE_UINT16(ar.pm1.cnt.cnt, VT686PMState),
         VMSTATE_STRUCT(apm, VT686PMState, 0, vmstate_apm, APMState),
-        VMSTATE_TIMER(ar.tmr.timer, VT686PMState),
+        VMSTATE_TIMER_PTR(ar.tmr.timer, VT686PMState),
         VMSTATE_INT64(ar.tmr.overflow_time, VT686PMState),
         VMSTATE_END_OF_LIST()
     }
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index b4273aa..47d9771 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -631,7 +631,7 @@ static const VMStateDescription vmstate_cuda_timer = {
         VMSTATE_UINT16(counter_value, CUDATimer),
         VMSTATE_INT64(load_time, CUDATimer),
         VMSTATE_INT64(next_irq_time, CUDATimer),
-        VMSTATE_TIMER_TEST(timer, CUDATimer, cuda_timer_exist),
+        VMSTATE_TIMER_PTR_TEST(timer, CUDATimer, cuda_timer_exist),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 8a1c8f1..8486b80 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1719,7 +1719,7 @@ const VMStateDescription vmstate_pcnet = {
         VMSTATE_BUFFER(buffer, PCNetState),
         VMSTATE_UNUSED_TEST(is_version_2, 4),
         VMSTATE_INT32(tx_busy, PCNetState),
-        VMSTATE_TIMER(poll_timer, PCNetState),
+        VMSTATE_TIMER_PTR(poll_timer, PCNetState),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 15064d3..10e5355 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1205,8 +1205,8 @@ const VMStateDescription sdhci_vmstate = {
         VMSTATE_UINT64(admasysaddr, SDHCIState),
         VMSTATE_UINT8(stopped_state, SDHCIState),
         VMSTATE_VBUFFER_UINT32(fifo_buffer, SDHCIState, 1, NULL, 0, buf_maxsz),
-        VMSTATE_TIMER(insert_timer, SDHCIState),
-        VMSTATE_TIMER(transfer_timer, SDHCIState),
+        VMSTATE_TIMER_PTR(insert_timer, SDHCIState),
+        VMSTATE_TIMER_PTR(transfer_timer, SDHCIState),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index a0656d5..435142a 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -328,7 +328,7 @@ static const VMStateDescription vmstate_a9_gtimer = {
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_TIMER(timer, A9GTimerState),
+        VMSTATE_TIMER_PTR(timer, A9GTimerState),
         VMSTATE_UINT64(counter, A9GTimerState),
         VMSTATE_UINT64(ref_counter, A9GTimerState),
         VMSTATE_UINT64(cpu_ref_time, A9GTimerState),
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 35a0a23..8b93b3c 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -246,7 +246,7 @@ static const VMStateDescription vmstate_timerblock = {
         VMSTATE_UINT32(control, TimerBlock),
         VMSTATE_UINT32(status, TimerBlock),
         VMSTATE_INT64(tick, TimerBlock),
-        VMSTATE_TIMER(timer, TimerBlock),
+        VMSTATE_TIMER_PTR(timer, TimerBlock),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index d8bc231..78d86be 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -299,7 +299,7 @@ static const VMStateDescription vmstate_hpet_timer = {
         VMSTATE_UINT64(fsb, HPETTimer),
         VMSTATE_UINT64(period, HPETTimer),
         VMSTATE_UINT8(wrap_flag, HPETTimer),
-        VMSTATE_TIMER(qemu_timer, HPETTimer),
+        VMSTATE_TIMER_PTR(qemu_timer, HPETTimer),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index f18d128..5a107fa 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -758,7 +758,7 @@ static const VMStateDescription vmstate_rtc = {
         VMSTATE_BUFFER(cmos_data, RTCState),
         VMSTATE_UINT8(cmos_index, RTCState),
         VMSTATE_UNUSED(7*4),
-        VMSTATE_TIMER(periodic_timer, RTCState),
+        VMSTATE_TIMER_PTR(periodic_timer, RTCState),
         VMSTATE_INT64(next_periodic_time, RTCState),
         VMSTATE_UNUSED(3*8),
         VMSTATE_UINT32_V(irq_coalesced, RTCState, 2),
@@ -766,7 +766,7 @@ static const VMStateDescription vmstate_rtc = {
         VMSTATE_UINT64_V(base_rtc, RTCState, 3),
         VMSTATE_UINT64_V(last_update, RTCState, 3),
         VMSTATE_INT64_V(offset, RTCState, 3),
-        VMSTATE_TIMER_V(update_timer, RTCState, 3),
+        VMSTATE_TIMER_PTR_V(update_timer, RTCState, 3),
         VMSTATE_UINT64_V(next_alarm_time, RTCState, 3),
         VMSTATE_END_OF_LIST()
     },
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 1cc0fc1..ccf54b6 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2437,7 +2437,7 @@ const VMStateDescription vmstate_ehci = {
         VMSTATE_UINT32(portsc[4], EHCIState),
         VMSTATE_UINT32(portsc[5], EHCIState),
         /* frame timer */
-        VMSTATE_TIMER(frame_timer, EHCIState),
+        VMSTATE_TIMER_PTR(frame_timer, EHCIState),
         VMSTATE_UINT64(last_run_ns, EHCIState),
         VMSTATE_UINT32(async_stepdown, EHCIState),
         /* schedule state */
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 9a84eb6..a0d478e 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -2015,7 +2015,7 @@ static const VMStateDescription vmstate_ohci_eof_timer = {
     .minimum_version_id = 1,
     .pre_load = ohci_eof_timer_pre_load,
     .fields = (VMStateField[]) {
-        VMSTATE_TIMER(eof_timer, OHCIState),
+        VMSTATE_TIMER_PTR(eof_timer, OHCIState),
         VMSTATE_END_OF_LIST()
     },
 };
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 4a4215d..f903de7 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -419,7 +419,7 @@ static const VMStateDescription vmstate_uhci = {
         VMSTATE_UINT32(fl_base_addr, UHCIState),
         VMSTATE_UINT8(sof_timing, UHCIState),
         VMSTATE_UINT8(status2, UHCIState),
-        VMSTATE_TIMER(frame_timer, UHCIState),
+        VMSTATE_TIMER_PTR(frame_timer, UHCIState),
         VMSTATE_INT64_V(expire_time, UHCIState, 2),
         VMSTATE_UINT32_V(pending_int_mask, UHCIState, 3),
         VMSTATE_END_OF_LIST()
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 9a942cf..776699b 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3855,7 +3855,7 @@ static const VMStateDescription vmstate_xhci = {
 
         /* Runtime Registers & state */
         VMSTATE_INT64(mfindex_start,  XHCIState),
-        VMSTATE_TIMER(mfwrap_timer,   XHCIState),
+        VMSTATE_TIMER_PTR(mfwrap_timer,   XHCIState),
         VMSTATE_STRUCT(cmd_ring, XHCIState, 1, vmstate_xhci_ring, XHCIRing),
 
         VMSTATE_END_OF_LIST()
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 9fbd59e..962d3f5 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -2438,7 +2438,7 @@ static const VMStateDescription usbredir_vmstate = {
     .post_load = usbredir_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_USB_DEVICE(dev, USBRedirDevice),
-        VMSTATE_TIMER(attach_timer, USBRedirDevice),
+        VMSTATE_TIMER_PTR(attach_timer, USBRedirDevice),
         {
             .name         = "parser",
             .version_id   = 0,
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
index 687c8b1..33dd6d4 100644
--- a/hw/watchdog/wdt_i6300esb.c
+++ b/hw/watchdog/wdt_i6300esb.c
@@ -398,7 +398,7 @@ static const VMStateDescription vmstate_i6300esb = {
         VMSTATE_INT32(free_run, I6300State),
         VMSTATE_INT32(locked, I6300State),
         VMSTATE_INT32(enabled, I6300State),
-        VMSTATE_TIMER(timer, I6300State),
+        VMSTATE_TIMER_PTR(timer, I6300State),
         VMSTATE_UINT32(timer1_preload, I6300State),
         VMSTATE_UINT32(timer2_preload, I6300State),
         VMSTATE_INT32(stage, I6300State),
diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c
index 8cb9827..0917a71 100644
--- a/hw/watchdog/wdt_ib700.c
+++ b/hw/watchdog/wdt_ib700.c
@@ -93,7 +93,7 @@ static const VMStateDescription vmstate_ib700 = {
     .version_id = 0,
     .minimum_version_id = 0,
     .fields = (VMStateField[]) {
-        VMSTATE_TIMER(timer, IB700State),
+        VMSTATE_TIMER_PTR(timer, IB700State),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 6097b94..fa307a6 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -652,17 +652,29 @@ extern const VMStateInfo vmstate_info_bitmap;
 #define VMSTATE_FLOAT64(_f, _s)                                       \
     VMSTATE_FLOAT64_V(_f, _s, 0)
 
-#define VMSTATE_TIMER_TEST(_f, _s, _test)                             \
+#define VMSTATE_TIMER_PTR_TEST(_f, _s, _test)                             \
     VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *)
 
-#define VMSTATE_TIMER_V(_f, _s, _v)                                   \
+#define VMSTATE_TIMER_PTR_V(_f, _s, _v)                                   \
     VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *)
 
+#define VMSTATE_TIMER_PTR(_f, _s)                                         \
+    VMSTATE_TIMER_PTR_V(_f, _s, 0)
+
+#define VMSTATE_TIMER_PTR_ARRAY(_f, _s, _n)                              \
+    VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *)
+
+#define VMSTATE_TIMER_TEST(_f, _s, _test)                             \
+    VMSTATE_SINGLE_TEST(_f, _s, _test, 0, vmstate_info_timer, QEMUTimer)
+
+#define VMSTATE_TIMER_V(_f, _s, _v)                                   \
+    VMSTATE_SINGLE(_f, _s, _v, vmstate_info_timer, QEMUTimer)
+
 #define VMSTATE_TIMER(_f, _s)                                         \
     VMSTATE_TIMER_V(_f, _s, 0)
 
 #define VMSTATE_TIMER_ARRAY(_f, _s, _n)                              \
-    VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *)
+    VMSTATE_ARRAY(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer)
 
 #define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v)                         \
     VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool)
diff --git a/target-arm/machine.c b/target-arm/machine.c
index c29e7a2..9446e5a 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -277,8 +277,8 @@ const VMStateDescription vmstate_arm_cpu = {
         VMSTATE_UINT32(env.exception.syndrome, ARMCPU),
         VMSTATE_UINT32(env.exception.fsr, ARMCPU),
         VMSTATE_UINT64(env.exception.vaddress, ARMCPU),
-        VMSTATE_TIMER(gt_timer[GTIMER_PHYS], ARMCPU),
-        VMSTATE_TIMER(gt_timer[GTIMER_VIRT], ARMCPU),
+        VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU),
+        VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU),
         VMSTATE_BOOL(powered_off, ARMCPU),
         VMSTATE_END_OF_LIST()
     },
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 10/19] hw: misc, add educational driver
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (8 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 09/19] vmstate: accept QEMUTimer in VMSTATE_TIMER*, add VMSTATE_TIMER_PTR* Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 11/19] kvm_stat: Add aarch64 support Paolo Bonzini
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jiri Slaby

From: Jiri Slaby <jslaby@suse.cz>

I am using qemu for teaching the Linux kernel at our university. I
wrote a simple PCI device that can answer to writes/reads, generate
interrupts and perform DMA. As I am dragging it locally over 2 years,
I am sending it to you now.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 MAINTAINERS             |   5 +
 default-configs/pci.mak |   1 +
 docs/specs/edu.txt      | 110 +++++++++++++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/edu.c           | 408 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 525 insertions(+)
 create mode 100644 docs/specs/edu.txt
 create mode 100644 hw/misc/edu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 430688d..fd335a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -599,6 +599,11 @@ F: hw/net/opencores_eth.c
 
 Devices
 -------
+EDU
+M: Jiri Slaby <jslaby@suse.cz>
+S: Maintained
+F: hw/misc/edu.c
+
 IDE
 M: Kevin Wolf <kwolf@redhat.com>
 M: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index a186c39..030cdc7 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -32,3 +32,4 @@ CONFIG_PCI_TESTDEV=y
 CONFIG_NVME_PCI=y
 CONFIG_SD=y
 CONFIG_SDHCI=y
+CONFIG_EDU=y
diff --git a/docs/specs/edu.txt b/docs/specs/edu.txt
new file mode 100644
index 0000000..7f81467
--- /dev/null
+++ b/docs/specs/edu.txt
@@ -0,0 +1,110 @@
+
+EDU device
+==========
+
+Copyright (c) 2014-2015 Jiri Slaby
+
+This document is licensed under the GPLv2 (or later).
+
+This is an educational device for writing (kernel) drivers. Its original
+intention was to support the Linux kernel lectures taught at the Masaryk
+University. Students are given this virtual device and are expected to write a
+driver with I/Os, IRQs, DMAs and such.
+
+The devices behaves very similar to the PCI bridge present in the COMBO6 cards
+developed under the Liberouter wings. Both PCI device ID and PCI space is
+inherited from that device.
+
+Command line switches:
+    -device edu[,dma_mask=mask]
+
+    dma_mask makes the virtual device work with DMA addresses with the given
+    mask. For educational purposes, the device supports only 28 bits (256 MiB)
+    by default. Students shall set dma_mask for the device in the OS driver
+    properly.
+
+PCI specs
+---------
+
+PCI ID: 1234:11e8
+
+PCI Region 0:
+   I/O memory, 1 MB in size. Users are supposed to communicate with the card
+   through this memory.
+
+MMIO area spec
+--------------
+
+Only size == 4 accesses are allowed for addresses < 0x80. size == 4 or
+size == 8 for the rest.
+
+0x00 (RO) : identification (0xRRrr00edu)
+	    RR -- major version
+	    rr -- minor version
+
+0x04 (RW) : card liveness check
+	    It is a simple value inversion (~ C operator).
+
+0x08 (RW) : factorial computation
+	    The stored value is taken and factorial of it is put back here.
+	    This happens only after factorial bit in the status register (0x20
+	    below) is cleared.
+
+0x20 (RW) : status register, bitwise OR
+	    0x01 -- computing factorial (RO)
+	    0x80 -- raise interrupt 0x01 after finishing factorial computation
+
+0x24 (RO) : interrupt status register
+	    It contains values which raised the interrupt (see interrupt raise
+	    register below).
+
+0x60 (WO) : interrupt raise register
+	    Raise an interrupt. The value will be put to the interrupt status
+	    register (using bitwise OR).
+
+0x64 (WO) : interrupt acknowledge register
+	    Clear an interrupt. The value will be cleared from the interrupt
+	    status register. This needs to be done from the ISR to stop
+	    generating interrupts.
+
+0x80 (RW) : DMA source address
+	    Where to perform the DMA from.
+
+0x88 (RW) : DMA destination address
+	    Where to perform the DMA to.
+
+0x90 (RW) : DMA transfer count
+	    The size of the area to perform the DMA on.
+
+0x98 (RW) : DMA command register, bitwise OR
+	    0x01 -- start transfer
+	    0x02 -- direction (0: from RAM to EDU, 1: from EDU to RAM)
+	    0x04 -- raise interrupt 0x100 after finishing the DMA
+
+IRQ controller
+--------------
+An IRQ is generated when written to the interrupt raise register. The value
+appears in interrupt status register when the interrupt is raised and has to
+be written to the interrupt acknowledge register to lower it.
+
+DMA controller
+--------------
+One has to specify, source, destination, size, and start the transfer. One
+4096 bytes long buffer at offset 0x40000 is available in the EDU device. I.e.
+one can perform DMA to/from this space when programmed properly.
+
+Example of transferring a 100 byte block to and from the buffer using a given
+PCI address 'addr':
+addr     -> DMA source address
+0x40000  -> DMA destination address
+100      -> DMA transfer count
+1        -> DMA command register
+while (DMA command register & 1)
+	;
+
+0x40000  -> DMA source address
+addr+100 -> DMA destination address
+100      -> DMA transfer count
+3        -> DMA command register
+while (DMA command register & 1)
+	;
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index e47fea8..029a56f 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -40,3 +40,4 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o
 obj-$(CONFIG_ZYNQ) += zynq_slcr.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
+obj-$(CONFIG_EDU) += edu.o
diff --git a/hw/misc/edu.c b/hw/misc/edu.c
new file mode 100644
index 0000000..8b68d76
--- /dev/null
+++ b/hw/misc/edu.c
@@ -0,0 +1,408 @@
+/*
+ * QEMU educational PCI device
+ *
+ * Copyright (c) 2012-2015 Jiri Slaby
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "hw/pci/pci.h"
+#include "qemu/timer.h"
+#include "qemu/main-loop.h" /* iothread mutex */
+#include "qapi/visitor.h"
+
+#define EDU(obj)        OBJECT_CHECK(EduState, obj, "edu")
+
+#define FACT_IRQ        0x00000001
+#define DMA_IRQ         0x00000100
+
+#define DMA_START       0x40000
+#define DMA_SIZE        4096
+
+typedef struct {
+    PCIDevice pdev;
+    MemoryRegion mmio;
+
+    QemuThread thread;
+    QemuMutex thr_mutex;
+    QemuCond thr_cond;
+    bool stopping;
+
+    uint32_t addr4;
+    uint32_t fact;
+#define EDU_STATUS_COMPUTING    0x01
+#define EDU_STATUS_IRQFACT      0x80
+    uint32_t status;
+
+    uint32_t irq_status;
+
+#define EDU_DMA_RUN             0x1
+#define EDU_DMA_DIR(cmd)        (((cmd) & 0x2) >> 1)
+# define EDU_DMA_FROM_PCI       0
+# define EDU_DMA_TO_PCI         1
+#define EDU_DMA_IRQ             0x4
+    struct dma_state {
+        dma_addr_t src;
+        dma_addr_t dst;
+        dma_addr_t cnt;
+        dma_addr_t cmd;
+    } dma;
+    QEMUTimer dma_timer;
+    char dma_buf[DMA_SIZE];
+    uint64_t dma_mask;
+} EduState;
+
+static void edu_raise_irq(EduState *edu, uint32_t val)
+{
+    edu->irq_status |= val;
+    if (edu->irq_status) {
+        pci_set_irq(&edu->pdev, 1);
+    }
+}
+
+static void edu_lower_irq(EduState *edu, uint32_t val)
+{
+    edu->irq_status &= ~val;
+
+    if (!edu->irq_status) {
+        pci_set_irq(&edu->pdev, 0);
+    }
+}
+
+static bool within(uint32_t addr, uint32_t start, uint32_t end)
+{
+    return start <= addr && addr < end;
+}
+
+static void edu_check_range(uint32_t addr, uint32_t size1, uint32_t start,
+                uint32_t size2)
+{
+    uint32_t end1 = addr + size1;
+    uint32_t end2 = start + size2;
+
+    if (within(addr, start, end2) &&
+            end1 > addr && within(end1, start, end2)) {
+        return;
+    }
+
+    hw_error("EDU: DMA range 0x%.8x-0x%.8x out of bounds (0x%.8x-0x%.8x)!",
+            addr, end1 - 1, start, end2 - 1);
+}
+
+static dma_addr_t edu_clamp_addr(const EduState *edu, dma_addr_t addr)
+{
+    dma_addr_t res = addr & edu->dma_mask;
+
+    if (addr != res) {
+        printf("EDU: clamping DMA 0x%.16lx to 0x%.16lx!\n", addr, res);
+    }
+
+    return res;
+}
+
+static void edu_dma_timer(void *opaque)
+{
+    EduState *edu = opaque;
+    bool raise_irq = false;
+
+    if (!(edu->dma.cmd & EDU_DMA_RUN)) {
+        return;
+    }
+
+    if (EDU_DMA_DIR(edu->dma.cmd) == EDU_DMA_FROM_PCI) {
+        uint32_t dst = edu->dma.dst;
+        edu_check_range(dst, edu->dma.cnt, DMA_START, DMA_SIZE);
+        dst -= DMA_START;
+        pci_dma_read(&edu->pdev, edu_clamp_addr(edu, edu->dma.src),
+                edu->dma_buf + dst, edu->dma.cnt);
+    } else {
+        uint32_t src = edu->dma.src;
+        edu_check_range(src, edu->dma.cnt, DMA_START, DMA_SIZE);
+        src -= DMA_START;
+        pci_dma_write(&edu->pdev, edu_clamp_addr(edu, edu->dma.dst),
+                edu->dma_buf + src, edu->dma.cnt);
+    }
+
+    edu->dma.cmd &= ~EDU_DMA_RUN;
+    if (edu->dma.cmd & EDU_DMA_IRQ) {
+        raise_irq = true;
+    }
+
+    if (raise_irq) {
+        edu_raise_irq(edu, DMA_IRQ);
+    }
+}
+
+static void dma_rw(EduState *edu, bool write, dma_addr_t *val, dma_addr_t *dma,
+                bool timer)
+{
+    if (write && (edu->dma.cmd & EDU_DMA_RUN)) {
+        return;
+    }
+
+    if (write) {
+        *dma = *val;
+    } else {
+        *val = *dma;
+    }
+
+    if (timer) {
+        timer_mod(&edu->dma_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 100);
+    }
+}
+
+static uint64_t edu_mmio_read(void *opaque, hwaddr addr, unsigned size)
+{
+    EduState *edu = opaque;
+    uint64_t val = ~0ULL;
+
+    if (size != 4) {
+        return val;
+    }
+
+    switch (addr) {
+    case 0x00:
+        val = 0x010000edu;
+        break;
+    case 0x04:
+        val = edu->addr4;
+        break;
+    case 0x08:
+        qemu_mutex_lock(&edu->thr_mutex);
+        val = edu->fact;
+        qemu_mutex_unlock(&edu->thr_mutex);
+        break;
+    case 0x20:
+        val = atomic_read(&edu->status);
+        break;
+    case 0x24:
+        val = edu->irq_status;
+        break;
+    case 0x80:
+        dma_rw(edu, false, &val, &edu->dma.src, false);
+        break;
+    case 0x88:
+        dma_rw(edu, false, &val, &edu->dma.dst, false);
+        break;
+    case 0x90:
+        dma_rw(edu, false, &val, &edu->dma.cnt, false);
+        break;
+    case 0x98:
+        dma_rw(edu, false, &val, &edu->dma.cmd, false);
+        break;
+    }
+
+    return val;
+}
+
+static void edu_mmio_write(void *opaque, hwaddr addr, uint64_t val,
+                unsigned size)
+{
+    EduState *edu = opaque;
+
+    if (addr < 0x80 && size != 4) {
+        return;
+    }
+
+    if (addr >= 0x80 && size != 4 && size != 8) {
+        return;
+    }
+
+    switch (addr) {
+    case 0x04:
+        edu->addr4 = ~val;
+        break;
+    case 0x08:
+        if (atomic_read(&edu->status) & EDU_STATUS_COMPUTING) {
+            break;
+        }
+        /* EDU_STATUS_COMPUTING cannot go 0->1 concurrently, because it is only
+         * set in this function and it is under the iothread mutex.
+         */
+        qemu_mutex_lock(&edu->thr_mutex);
+        edu->fact = val;
+        atomic_or(&edu->status, EDU_STATUS_COMPUTING);
+        qemu_cond_signal(&edu->thr_cond);
+        qemu_mutex_unlock(&edu->thr_mutex);
+        break;
+    case 0x20:
+        if (val & EDU_STATUS_IRQFACT) {
+            atomic_or(&edu->status, EDU_STATUS_IRQFACT);
+        } else {
+            atomic_and(&edu->status, ~EDU_STATUS_IRQFACT);
+        }
+        break;
+    case 0x60:
+        edu_raise_irq(edu, val);
+        break;
+    case 0x64:
+        edu_lower_irq(edu, val);
+        break;
+    case 0x80:
+        dma_rw(edu, true, &val, &edu->dma.src, false);
+        break;
+    case 0x88:
+        dma_rw(edu, true, &val, &edu->dma.dst, false);
+        break;
+    case 0x90:
+        dma_rw(edu, true, &val, &edu->dma.cnt, false);
+        break;
+    case 0x98:
+        if (!(val & EDU_DMA_RUN)) {
+            break;
+        }
+        dma_rw(edu, true, &val, &edu->dma.cmd, true);
+        break;
+    }
+}
+
+static const MemoryRegionOps edu_mmio_ops = {
+    .read = edu_mmio_read,
+    .write = edu_mmio_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+/*
+ * We purposedly use a thread, so that users are forced to wait for the status
+ * register.
+ */
+static void *edu_fact_thread(void *opaque)
+{
+    EduState *edu = opaque;
+
+    while (1) {
+        uint32_t val, ret = 1;
+
+        qemu_mutex_lock(&edu->thr_mutex);
+        while ((atomic_read(&edu->status) & EDU_STATUS_COMPUTING) == 0 &&
+                        !edu->stopping) {
+            qemu_cond_wait(&edu->thr_cond, &edu->thr_mutex);
+        }
+
+        if (edu->stopping) {
+            qemu_mutex_unlock(&edu->thr_mutex);
+            break;
+        }
+
+        val = edu->fact;
+        qemu_mutex_unlock(&edu->thr_mutex);
+
+        while (val > 0) {
+            ret *= val--;
+        }
+
+        /*
+         * We should sleep for a random period here, so that students are
+         * forced to check the status properly.
+         */
+
+        qemu_mutex_lock(&edu->thr_mutex);
+        edu->fact = ret;
+        qemu_mutex_unlock(&edu->thr_mutex);
+        atomic_and(&edu->status, ~EDU_STATUS_COMPUTING);
+
+        if (atomic_read(&edu->status) & EDU_STATUS_IRQFACT) {
+            qemu_mutex_lock_iothread();
+            edu_raise_irq(edu, FACT_IRQ);
+            qemu_mutex_unlock_iothread();
+        }
+    }
+
+    return NULL;
+}
+
+static int pci_edu_init(PCIDevice *pdev)
+{
+    EduState *edu = DO_UPCAST(EduState, pdev, pdev);
+    uint8_t *pci_conf = pdev->config;
+
+    timer_init_ms(&edu->dma_timer, QEMU_CLOCK_VIRTUAL, edu_dma_timer, edu);
+
+    qemu_mutex_init(&edu->thr_mutex);
+    qemu_cond_init(&edu->thr_cond);
+    qemu_thread_create(&edu->thread, "edu", edu_fact_thread,
+                       edu, QEMU_THREAD_JOINABLE);
+
+    pci_config_set_interrupt_pin(pci_conf, 1);
+
+    memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,
+                    "edu-mmio", 1 << 20);
+    pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);
+
+    return 0;
+}
+
+static void pci_edu_uninit(PCIDevice *pdev)
+{
+    EduState *edu = DO_UPCAST(EduState, pdev, pdev);
+
+    qemu_mutex_lock(&edu->thr_mutex);
+    edu->stopping = true;
+    qemu_mutex_unlock(&edu->thr_mutex);
+    qemu_cond_signal(&edu->thr_cond);
+    qemu_thread_join(&edu->thread);
+
+    qemu_cond_destroy(&edu->thr_cond);
+    qemu_mutex_destroy(&edu->thr_mutex);
+
+    timer_del(&edu->dma_timer);
+}
+
+static void edu_obj_uint64(Object *obj, struct Visitor *v, void *opaque,
+                const char *name, Error **errp)
+{
+    uint64_t *val = opaque;
+
+    visit_type_uint64(v, val, name, errp);
+}
+
+static void edu_instance_init(Object *obj)
+{
+    EduState *edu = EDU(obj);
+
+    edu->dma_mask = (1UL << 28) - 1;
+    object_property_add(obj, "dma_mask", "uint64", edu_obj_uint64,
+                    edu_obj_uint64, NULL, &edu->dma_mask, NULL);
+}
+
+static void edu_class_init(ObjectClass *class, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(class);
+
+    k->init = pci_edu_init;
+    k->exit = pci_edu_uninit;
+    k->vendor_id = PCI_VENDOR_ID_QEMU;
+    k->device_id = 0x11e8;
+    k->revision = 0x10;
+    k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void pci_edu_register_types(void)
+{
+    static const TypeInfo edu_info = {
+        .name          = "edu",
+        .parent        = TYPE_PCI_DEVICE,
+        .instance_size = sizeof(EduState),
+        .instance_init = edu_instance_init,
+        .class_init    = edu_class_init,
+    };
+
+    type_register_static(&edu_info);
+}
+type_init(pci_edu_register_types)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 11/19] kvm_stat: Add aarch64 support
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (9 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 10/19] hw: misc, add educational driver Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 12/19] kvm_stat: Update exit reasons to the latest defintion Paolo Bonzini
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Wei Huang

From: Wei Huang <wei@redhat.com>

This patch enables aarch64 support for kvm_stat. The platform detection
is based on OS uname.

Signed-off-by: Wei Huang <wei@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 scripts/kvm/kvm_stat | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
index 7b1437c..470ca08 100755
--- a/scripts/kvm/kvm_stat
+++ b/scripts/kvm/kvm_stat
@@ -204,10 +204,18 @@ def ppc_init():
         }
     })
 
+def aarch64_init():
+    globals().update({
+        'sc_perf_evt_open' : 241
+    })
+
 def detect_platform():
     if os.uname()[4].startswith('ppc'):
         ppc_init()
         return
+    elif os.uname()[4].startswith('aarch64'):
+        aarch64_init()
+        return
 
     for line in file('/proc/cpuinfo').readlines():
         if line.startswith('flags'):
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 12/19] kvm_stat: Update exit reasons to the latest defintion
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (10 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 11/19] kvm_stat: Add aarch64 support Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 13/19] kvm_stat: Print errno when syscall to perf_event_open() fails Paolo Bonzini
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Wei Huang

From: Wei Huang <wei@redhat.com>

This patch updates the exit reasons for x86_vmx, x86_svm, and userspace
to the latest definition.

Signed-off-by: Wei Huang <wei@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 scripts/kvm/kvm_stat | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
index 470ca08..95c650b 100755
--- a/scripts/kvm/kvm_stat
+++ b/scripts/kvm/kvm_stat
@@ -65,6 +65,8 @@ vmx_exit_reasons = {
     49: 'EPT_MISCONFIG',
     54: 'WBINVD',
     55: 'XSETBV',
+    56: 'APIC_WRITE',
+    58: 'INVPCID',
 }
 
 svm_exit_reasons = {
@@ -138,6 +140,7 @@ svm_exit_reasons = {
     0x08a: 'MONITOR',
     0x08b: 'MWAIT',
     0x08c: 'MWAIT_COND',
+    0x08d: 'XSETBV',
     0x400: 'NPF',
 }
 
@@ -167,6 +170,7 @@ userspace_exit_reasons = {
     21: 'WATCHDOG',
     22: 'S390_TSCH',
     23: 'EPR',
+    24: 'SYSTEM_EVENT',
 }
 
 x86_exit_reasons = {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 13/19] kvm_stat: Print errno when syscall to perf_event_open() fails
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (11 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 12/19] kvm_stat: Update exit reasons to the latest defintion Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 14/19] apic: do not dereference pointer before it is checked for NULL Paolo Bonzini
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Wei Huang

From: Wei Huang <wei@redhat.com>

kvm_stat uses syscall() to call perf_event_open(). If this function
call fails, the returned value is -1, which doesn't tell the details
of such failure (i.e. ENOSYS or EINVAL). This patch retrieves errno
and prints it when syscall() fails. The error message will look like
"Exception: perf_event_open failed, errno = 38".

Signed-off-by: Wei Huang <wei@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 scripts/kvm/kvm_stat | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
index 95c650b..8f6f007 100755
--- a/scripts/kvm/kvm_stat
+++ b/scripts/kvm/kvm_stat
@@ -13,6 +13,7 @@
 
 import curses
 import sys, os, time, optparse, ctypes
+from ctypes import *
 
 class DebugfsProvider(object):
     def __init__(self):
@@ -247,6 +248,9 @@ import struct, array
 
 libc = ctypes.CDLL('libc.so.6')
 syscall = libc.syscall
+get_errno = libc.__errno_location
+get_errno.restype = POINTER(c_int)
+
 class perf_event_attr(ctypes.Structure):
     _fields_ = [('type', ctypes.c_uint32),
                 ('size', ctypes.c_uint32),
@@ -330,7 +334,8 @@ class Event(object):
             group_leader = group.events[0].fd
         fd = _perf_event_open(attr, -1, group.cpu, group_leader, 0)
         if fd == -1:
-            raise Exception('perf_event_open failed')
+            err = get_errno()[0]
+            raise Exception('perf_event_open failed, errno = ' + err.__str__())
         if filter:
             import fcntl
             fcntl.ioctl(fd, ioctl_numbers['SET_FILTER'], filter)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 14/19] apic: do not dereference pointer before it is checked for NULL
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (12 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 13/19] kvm_stat: Print errno when syscall to perf_event_open() fails Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 15/19] .travis.yml: Add "--enable-modules" Paolo Bonzini
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

Right now you only get to apic_init_reset if you have an APIC
(do_cpu_init is reached only if CPU_INTERRUPT_INIT is set and
that only happens in hw/intc/apic.c).  However, this is wrong
because for example a port 92 or keyboard controller reset is
really an INIT, and that can happen also with no APIC.  So
keep the check and fix the error that Coverity reported.

Reported-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/intc/apic_common.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index d9bb188..0858b45 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -177,13 +177,14 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time)
 
 void apic_init_reset(DeviceState *dev)
 {
-    APICCommonState *s = APIC_COMMON(dev);
-    APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
+    APICCommonState *s;
+    APICCommonClass *info;
     int i;
 
-    if (!s) {
+    if (!dev) {
         return;
     }
+    s = APIC_COMMON(dev);
     s->tpr = 0;
     s->spurious_vec = 0xff;
     s->log_dest = 0;
@@ -208,6 +209,7 @@ void apic_init_reset(DeviceState *dev)
     }
     s->timer_expiry = -1;
 
+    info = APIC_COMMON_GET_CLASS(s);
     if (info->reset) {
         info->reset(s);
     }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 15/19] .travis.yml: Add "--enable-modules"
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (13 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 14/19] apic: do not dereference pointer before it is checked for NULL Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 16/19] exec: fix madvise of NULL pointer Paolo Bonzini
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

We will change the default to "--enable-modules", let's cover it before
the switch.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 .travis.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index ad66e5b..0ac170b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -98,3 +98,6 @@ matrix:
           EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
           EXTRA_CONFIG="--enable-trace-backends=ust"
       compiler: gcc
+    - env: TARGETS=i386-softmmu,x86_64-softmmu
+           EXTRA_CONFIG="--enable-modules"
+      compiler: gcc
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 16/19] exec: fix madvise of NULL pointer
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (14 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 15/19] .travis.yml: Add "--enable-modules" Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 17/19] sparse: Fix build with sparse on .S files Paolo Bonzini
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel

Coverity flags this as "dereference after null check".  Not quite a
dereference, since it will just EFAULT, but still nice to fix.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/exec.c b/exec.c
index 410371d..6b79ad1 100644
--- a/exec.c
+++ b/exec.c
@@ -1386,12 +1386,13 @@ static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp)
     cpu_physical_memory_set_dirty_range(new_block->offset,
                                         new_block->used_length);
 
-    qemu_ram_setup_dump(new_block->host, new_block->max_length);
-    qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE);
-    qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK);
-
-    if (kvm_enabled()) {
-        kvm_setup_guest_memory(new_block->host, new_block->max_length);
+    if (new_block->host) {
+        qemu_ram_setup_dump(new_block->host, new_block->max_length);
+        qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_HUGEPAGE);
+        qemu_madvise(new_block->host, new_block->max_length, QEMU_MADV_DONTFORK);
+        if (kvm_enabled()) {
+            kvm_setup_guest_memory(new_block->host, new_block->max_length);
+        }
     }
 
     return new_block->offset;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 17/19] sparse: Fix build with sparse on .S files
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (15 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 16/19] exec: fix madvise of NULL pointer Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 18/19] target-i386: Disable HLE and RTM on Haswell & Broadwell Paolo Bonzini
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Christian Borntraeger

From: Christian Borntraeger <borntraeger@de.ibm.com>

rules.mak has a rule for .S files using CPP. This will result in
errors like
  CPP   s390-ccw/start.asm
 cc: error: unrecognized command line option '-Wbitwise'

Lets also redefine CPP in case of --enable-sparse.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 5ea1014..f185dd0 100755
--- a/configure
+++ b/configure
@@ -4938,6 +4938,7 @@ echo "QEMU_CFLAGS=$QEMU_CFLAGS" >> $config_host_mak
 echo "QEMU_INCLUDES=$QEMU_INCLUDES" >> $config_host_mak
 if test "$sparse" = "yes" ; then
   echo "CC           := REAL_CC=\"\$(CC)\" cgcc"       >> $config_host_mak
+  echo "CPP          := REAL_CC=\"\$(CPP)\" cgcc"      >> $config_host_mak
   echo "CXX          := REAL_CC=\"\$(CXX)\" cgcc"      >> $config_host_mak
   echo "HOST_CC      := REAL_CC=\"\$(HOST_CC)\" cgcc"  >> $config_host_mak
   echo "QEMU_CFLAGS  += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 18/19] target-i386: Disable HLE and RTM on Haswell & Broadwell
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (16 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 17/19] sparse: Fix build with sparse on .S files Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26  9:24 ` [Qemu-devel] [PULL 19/19] kvm_stat: Add RESET support for perf event ioctl Paolo Bonzini
  2015-01-26 10:30 ` [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Peter Maydell
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Eduardo Habkost

From: Eduardo Habkost <ehabkost@redhat.com>

All Haswell CPUs and some Broadwell CPUs were updated by Intel to have
the HLE and RTM features disabled. This will prevent
"-cpu Haswell,enforce" and "-cpu Broadwell,enforce" from running out of
the box on those CPUs.

Disable those features by default on Broadwell and Haswell CPU models,
starting on pc-*-2.3. Users who want to use those features can enable
them explicitly on the command-line.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/i386/pc_piix.c | 4 ++++
 hw/i386/pc_q35.c  | 4 ++++
 target-i386/cpu.c | 9 ++++-----
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 97a754e..38b42b0 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -328,6 +328,10 @@ static void pc_compat_2_2(MachineState *machine)
     x86_cpu_compat_set_features("Haswell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND);
     x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_F16C);
     x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND);
+    x86_cpu_compat_set_features("Haswell", FEAT_7_0_EBX,
+                                CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0);
+    x86_cpu_compat_set_features("Broadwell", FEAT_7_0_EBX,
+                                CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0);
 }
 
 static void pc_compat_2_1(MachineState *machine)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index a432944..63027ee 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -307,6 +307,10 @@ static void pc_compat_2_2(MachineState *machine)
     x86_cpu_compat_set_features("Haswell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND);
     x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_F16C);
     x86_cpu_compat_set_features("Broadwell", FEAT_1_ECX, 0, CPUID_EXT_RDRAND);
+    x86_cpu_compat_set_features("Haswell", FEAT_7_0_EBX,
+                                CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0);
+    x86_cpu_compat_set_features("Broadwell", FEAT_7_0_EBX,
+                                CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_RTM, 0);
 }
 
 static void pc_compat_2_1(MachineState *machine)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index b81ac5c..3a9b32e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1100,9 +1100,8 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT3_LAHF_LM,
         .features[FEAT_7_0_EBX] =
             CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
-            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
-            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
-            CPUID_7_0_EBX_RTM,
+            CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
+            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
         .xlevel = 0x8000000A,
@@ -1135,9 +1134,9 @@ static X86CPUDefinition builtin_x86_defs[] = {
             CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
         .features[FEAT_7_0_EBX] =
             CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
-            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
+            CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
             CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
-            CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+            CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
             CPUID_7_0_EBX_SMAP,
         .features[FEAT_XSAVE] =
             CPUID_XSAVE_XSAVEOPT,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [Qemu-devel] [PULL 19/19] kvm_stat: Add RESET support for perf event ioctl
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (17 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 18/19] target-i386: Disable HLE and RTM on Haswell & Broadwell Paolo Bonzini
@ 2015-01-26  9:24 ` Paolo Bonzini
  2015-01-26 10:30 ` [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Peter Maydell
  19 siblings, 0 replies; 21+ messages in thread
From: Paolo Bonzini @ 2015-01-26  9:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: Wei Huang

From: Wei Huang <wei@redhat.com>

While running kvm_stat using tracepoint on ARM64 hardware (e.g. "kvm_stat
-1 -t"), the initial values of some kvm_userspace_exit counters were found
to be very suspecious. For instance the tracing tool showed that S390_TSCH
was called many times on ARM64 machine, which apparently was wrong.

This patch adds RESET ioctl support for perf monitoring. Before calling
ioctl to enable a perf event, this patch resets the counter first. With
this patch, the init counter values become correct on ARM64 hardware.

Example:

==== before patch ====
kvm_userspace_exit(S390_SIEIC)      1426         0
kvm_userspace_exit(S390_TSCH)       339         0

==== after patch ====
kvm_userspace_exit(S390_SIEIC)         0         0
kvm_userspace_exit(S390_TSCH)         0         0

Signed-off-by: Wei Huang <wei@redhat.com>
---
 scripts/kvm/kvm_stat | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
index 8f6f007..c0c4ff0 100755
--- a/scripts/kvm/kvm_stat
+++ b/scripts/kvm/kvm_stat
@@ -186,6 +186,7 @@ ioctl_numbers = {
     'SET_FILTER' : 0x40082406,
     'ENABLE'     : 0x00002400,
     'DISABLE'    : 0x00002401,
+    'RESET'      : 0x00002403,
 }
 
 def x86_init(flag):
@@ -346,6 +347,9 @@ class Event(object):
     def disable(self):
         import fcntl
         fcntl.ioctl(self.fd, ioctl_numbers['DISABLE'], 0)
+    def reset(self):
+        import fcntl
+        fcntl.ioctl(self.fd, ioctl_numbers['RESET'], 0)
 
 class TracepointProvider(object):
     def __init__(self):
@@ -405,6 +409,7 @@ class TracepointProvider(object):
         for group in self.group_leaders:
             for event in group.events:
                 if event.name in fields:
+                    event.reset()
                     event.enable()
                 else:
                     event.disable()
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26
  2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
                   ` (18 preceding siblings ...)
  2015-01-26  9:24 ` [Qemu-devel] [PULL 19/19] kvm_stat: Add RESET support for perf event ioctl Paolo Bonzini
@ 2015-01-26 10:30 ` Peter Maydell
  19 siblings, 0 replies; 21+ messages in thread
From: Peter Maydell @ 2015-01-26 10:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 26 January 2015 at 09:24, Paolo Bonzini <pbonzini@redhat.com> wrote:
> The following changes since commit 699eae17b841e6784dc3864bf357e26bff1e9dfe:
>
>   Merge remote-tracking branch 'remotes/pmaydell/tags/pull-misc-20150120' into staging (2015-01-20 16:19:58 +0000)
>
> are available in the git repository at:
>
>
>   git://github.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 9fc2ecf4e8266dcb01961851c595d09485d26bc1:
>
>   kvm_stat: Add RESET support for perf event ioctl (2015-01-26 10:03:09 +0100)
>
> ----------------------------------------------------------------
> - Many fixes from the floor as usual
> - New "edu" device
> - Disabling HLE and RTM on Haswell & Broadwell
> - kvm_stat updates
> - Added --enable-modules to Travis, in preparation for switching
>   the default
>
> ----------------------------------------------------------------

Format string issues, I'm afraid (so build failure on 32 bit):

CC mips-softmmu/hw/misc/edu.o
/root/qemu/hw/misc/edu.c: In function 'edu_clamp_addr':
/root/qemu/hw/misc/edu.c:113:9: error: format '%lx' expects argument
of type 'long unsigned int', but argument 2 has type 'dma_addr_t'
[-Werror=format]
/root/qemu/hw/misc/edu.c:113:9: error: format '%lx' expects argument
of type 'long unsigned int', but argument 3 has type 'dma_addr_t'
[-Werror=format]
cc1: all warnings being treated as errors

thanks
-- PMM

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2015-01-26 10:31 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-26  9:24 [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 01/19] pc: fix KVM features in pc-1.3 and earlier machine types Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 02/19] tests/multiboot: Update reference output Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 03/19] multiboot: Fix offset of bootloader name Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 04/19] tests/multiboot: Add test for modules Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 05/19] target-i386: use vmstate_offset_sub_array for AVX registers Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 06/19] target-i386: make xmm_regs 512-bit wide Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 07/19] qemu-timer: add timer_init and timer_init_ns/us/ms Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 08/19] qemu-timer: introduce timer_deinit Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 09/19] vmstate: accept QEMUTimer in VMSTATE_TIMER*, add VMSTATE_TIMER_PTR* Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 10/19] hw: misc, add educational driver Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 11/19] kvm_stat: Add aarch64 support Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 12/19] kvm_stat: Update exit reasons to the latest defintion Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 13/19] kvm_stat: Print errno when syscall to perf_event_open() fails Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 14/19] apic: do not dereference pointer before it is checked for NULL Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 15/19] .travis.yml: Add "--enable-modules" Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 16/19] exec: fix madvise of NULL pointer Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 17/19] sparse: Fix build with sparse on .S files Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 18/19] target-i386: Disable HLE and RTM on Haswell & Broadwell Paolo Bonzini
2015-01-26  9:24 ` [Qemu-devel] [PULL 19/19] kvm_stat: Add RESET support for perf event ioctl Paolo Bonzini
2015-01-26 10:30 ` [Qemu-devel] [PULL 00/19] i386, KVM, misc changes for 2015-01-26 Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.