All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
@ 2016-05-27 10:06 Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 01/31] Add optionrom compatible with fw_cfg DMA version Paolo Bonzini
                   ` (31 more replies)
  0 siblings, 32 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

The following changes since commit b75536c9fa742f887304769d0608557bb8e3a27f:

  blockjob: Remove BlockJob.bs (2016-05-25 19:04:21 +0200)

are available in the git repository at:

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

for you to fetch changes up to 7052033834d4c2d7ade147cf5b045be6eaf07113:

  exec: hide mr->ram_addr from qemu_get_ram_ptr users (2016-05-27 11:55:23 +0200)

----------------------------------------------------------------
* docs/atomics fixes and atomic_rcu_* optimization (Emilio)
* NBD bugfix (Eric)
* Memory fixes and cleanups (Paolo, Paul)
* scsi-block support for SCSI status, including persistent
  reservations (Paolo)
* linuxboot support for fw_cfg DMA (Marc, Richard Jones)
* kvm_stat moves to the Linux repository
* SCSI bug fixes (Peter, Prasad)
* Killing qemu_char_get_next_serial, non-ARM parts (Xiaoqiang)

----------------------------------------------------------------
Emilio G. Cota (3):
      docs/atomics: update atomic_read/set comparison with Linux
      atomics: emit an smp_read_barrier_depends() barrier only for Alpha and Thread Sanitizer
      atomics: do not emit consume barrier for atomic_rcu_read

Eric Blake (1):
      nbd: Don't trim unrequested bytes

Fam Zheng (1):
      scsi-generic: Merge block max xfer len in INQUIRY response

Marc Marí (1):
      Add optionrom compatible with fw_cfg DMA version

Paolo Bonzini (13):
      Revert "memory: Drop FlatRange.romd_mode"
      kvm_stat: Remove
      bt: rewrite csrhci_write to avoid out-of-bounds writes
      docs/atomics: update comparison with Linux
      scsi-disk: introduce a common base class
      scsi-disk: introduce dma_readv and dma_writev
      scsi-disk: add need_fua_emulation to SCSIDiskClass
      scsi-disk: introduce scsi_disk_req_check_error
      scsi-block: always use SG_IO
      memory: remove qemu_get_ram_fd, qemu_set_ram_fd, qemu_ram_block_host_ptr
      exec: remove ram_addr argument from qemu_ram_block_from_host
      memory: split memory_region_from_host from qemu_ram_addr_from_host
      exec: hide mr->ram_addr from qemu_get_ram_ptr users

Paul Durrant (1):
      xen-hvm: ignore background I/O sections

Peter Lieven (1):
      block/iscsi: avoid potential overflow of acb->task->cdb

Prasad J Pandit (5):
      scsi: pvscsi: check command descriptor ring buffer size (CVE-2016-4952)
      scsi: mptsas: infinite loop while fetching requests
      scsi: megasas: use appropriate property buffer size
      scsi: megasas: initialise local configuration data buffer
      scsi: megasas: check 'read_queue_head' index value

xiaoqiang zhao (5):
      hw/char: QOM'ify escc.c
      hw/char: QOM'ify etraxfs_ser.c
      hw/char: QOM'ify lm32_juart.c
      hw/char: QOM'ify lm32_uart.c
      hw/char: QOM'ify milkymist-uart.c

 .gitignore                        |   4 +
 Makefile                          |  11 +-
 block/iscsi.c                     |   7 +
 configure                         |  20 +
 cputlb.c                          |   3 +-
 docs/atomics.txt                  |  38 +-
 exec.c                            | 110 ++---
 hw/bt/hci-csr.c                   |  67 +++-
 hw/char/escc.c                    |  30 +-
 hw/char/etraxfs_ser.c             |  27 +-
 hw/char/lm32_juart.c              |  17 +-
 hw/char/lm32_uart.c               |  28 +-
 hw/char/milkymist-uart.c          |  10 +-
 hw/cris/axis_dev88.c              |   4 +-
 hw/i386/pc.c                      |  10 +-
 hw/lm32/lm32.h                    |  19 +-
 hw/lm32/lm32_boards.c             |   9 +-
 hw/lm32/milkymist-hw.h            |   4 +-
 hw/lm32/milkymist.c               |   4 +-
 hw/misc/ivshmem.c                 |   5 +-
 hw/nvram/fw_cfg.c                 |   2 +-
 hw/scsi/megasas.c                 |   6 +-
 hw/scsi/mptsas.c                  |   9 +-
 hw/scsi/scsi-disk.c               | 412 +++++++++++++------
 hw/scsi/scsi-generic.c            |  12 +
 hw/scsi/vmw_pvscsi.c              |  24 +-
 hw/virtio/vhost-user.c            |  25 +-
 include/exec/cpu-common.h         |   4 +-
 include/exec/memory.h             |  36 +-
 include/exec/ram_addr.h           |   3 -
 include/hw/cris/etraxfs.h         |  16 +
 include/hw/nvram/fw_cfg.h         |   1 +
 include/qemu/atomic.h             |  25 +-
 memory.c                          |  43 +-
 migration/postcopy-ram.c          |   3 +-
 nbd/server.c                      |  20 +-
 pc-bios/optionrom/Makefile        |  19 +-
 pc-bios/optionrom/code16gcc.h     |   3 +
 pc-bios/optionrom/linuxboot_dma.c | 291 ++++++++++++++
 scripts/dump-guest-memory.py      |  19 +-
 scripts/kvm/kvm_stat              | 825 --------------------------------------
 scripts/kvm/kvm_stat.texi         |  55 ---
 target-i386/kvm.c                 |   6 +-
 xen-hvm.c                         |  14 +-
 44 files changed, 1055 insertions(+), 1245 deletions(-)
 create mode 100644 pc-bios/optionrom/code16gcc.h
 create mode 100644 pc-bios/optionrom/linuxboot_dma.c
 delete mode 100755 scripts/kvm/kvm_stat
 delete mode 100644 scripts/kvm/kvm_stat.texi
-- 
2.5.5

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

* [Qemu-devel] [PULL 01/31] Add optionrom compatible with fw_cfg DMA version
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 02/31] Revert "memory: Drop FlatRange.romd_mode" Paolo Bonzini
                   ` (30 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Richard W.M. Jones

From: Marc Marí <markmb@redhat.com>

This optionrom is based on linuxboot.S.

Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Message-Id: <1464027093-24073-2-git-send-email-rjones@redhat.com>
[Add -fno-toplevel-reorder. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 .gitignore                        |   4 +
 Makefile                          |   2 +-
 configure                         |  20 +++
 hw/i386/pc.c                      |  10 +-
 hw/nvram/fw_cfg.c                 |   2 +-
 include/hw/nvram/fw_cfg.h         |   1 +
 pc-bios/optionrom/Makefile        |  19 ++-
 pc-bios/optionrom/code16gcc.h     |   3 +
 pc-bios/optionrom/linuxboot_dma.c | 291 ++++++++++++++++++++++++++++++++++++++
 9 files changed, 346 insertions(+), 6 deletions(-)
 create mode 100644 pc-bios/optionrom/code16gcc.h
 create mode 100644 pc-bios/optionrom/linuxboot_dma.c

diff --git a/.gitignore b/.gitignore
index 88a80ff..101d1e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -94,6 +94,10 @@
 /pc-bios/optionrom/linuxboot.bin
 /pc-bios/optionrom/linuxboot.raw
 /pc-bios/optionrom/linuxboot.img
+/pc-bios/optionrom/linuxboot_dma.asm
+/pc-bios/optionrom/linuxboot_dma.bin
+/pc-bios/optionrom/linuxboot_dma.raw
+/pc-bios/optionrom/linuxboot_dma.img
 /pc-bios/optionrom/multiboot.asm
 /pc-bios/optionrom/multiboot.bin
 /pc-bios/optionrom/multiboot.raw
diff --git a/Makefile b/Makefile
index a5d7e62..3a9782e 100644
--- a/Makefile
+++ b/Makefile
@@ -400,7 +400,7 @@ efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
 efi-pcnet.rom efi-rtl8139.rom efi-virtio.rom \
 qemu-icon.bmp qemu_logo_no_text.svg \
 bamboo.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
-multiboot.bin linuxboot.bin kvmvapic.bin \
+multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin \
 s390-ccw.img \
 spapr-rtas.bin slof.bin \
 palcode-clipper \
diff --git a/configure b/configure
index b5aab72..6d4cbbd 100755
--- a/configure
+++ b/configure
@@ -237,6 +237,7 @@ fortify_source=""
 strip_opt="yes"
 tcg_interpreter="no"
 bigendian="no"
+compiler_m16="no"
 mingw32="no"
 gcov="no"
 gcov_tool="gcov"
@@ -1524,6 +1525,21 @@ if test "$static" = "yes" ; then
   fi
 fi
 
+# Check if the compiler supports -m16 to generate i8086 binaries.
+#
+# GCC < 4.9 didn't, so we have to work around that when building the
+# linuxboot_dma option ROM.  When GCC < 4.9 is considered sufficiently
+# old that we no longer care about it, we can remove this section and
+# CONFIG_COMPILER_M16 which will simplify the build.
+if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+  cat > $TMPC << EOF
+int main(void) { return 0; }
+EOF
+  if compile_prog "-m16" "" ; then
+    compiler_m16=yes
+  fi
+fi
+
 # Unconditional check for compiler __thread support
   cat > $TMPC << EOF
 static __thread int tls_var;
@@ -4780,6 +4796,7 @@ fi
 echo "module support    $modules"
 echo "host CPU          $cpu"
 echo "host big endian   $bigendian"
+echo "compiler has -m16 $compiler_m16"
 echo "target list       $target_list"
 echo "tcg debug enabled $debug_tcg"
 echo "gprof enabled     $gprof"
@@ -4928,6 +4945,9 @@ fi
 if test "$bigendian" = "yes" ; then
   echo "HOST_WORDS_BIGENDIAN=y" >> $config_host_mak
 fi
+if test "$compiler_m16" = "yes" ; then
+  echo "CONFIG_COMPILER_M16=y" >> $config_host_mak
+fi
 if test "$mingw32" = "yes" ; then
   echo "CONFIG_WIN32=y" >> $config_host_mak
   rc_version=`cat $source_path/VERSION`
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e29ccc8..2ab7b42 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1000,8 +1000,13 @@ static void load_linux(PCMachineState *pcms,
     fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size);
     fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size);
 
-    option_rom[nb_option_roms].name = "linuxboot.bin";
-    option_rom[nb_option_roms].bootindex = 0;
+    if (fw_cfg_dma_enabled(fw_cfg)) {
+        option_rom[nb_option_roms].name = "linuxboot_dma.bin";
+        option_rom[nb_option_roms].bootindex = 0;
+    } else {
+        option_rom[nb_option_roms].name = "linuxboot.bin";
+        option_rom[nb_option_roms].bootindex = 0;
+    }
     nb_option_roms++;
 }
 
@@ -1264,6 +1269,7 @@ void xen_load_linux(PCMachineState *pcms)
     load_linux(pcms, fw_cfg);
     for (i = 0; i < nb_option_roms; i++) {
         assert(!strcmp(option_rom[i].name, "linuxboot.bin") ||
+               !strcmp(option_rom[i].name, "linuxboot_dma.bin") ||
                !strcmp(option_rom[i].name, "multiboot.bin"));
         rom_add_option(option_rom[i].name, option_rom[i].bootindex);
     }
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index cdbdfb5..6ac486e 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -552,7 +552,7 @@ static bool is_version_1(void *opaque, int version_id)
     return version_id == 1;
 }
 
-static bool fw_cfg_dma_enabled(void *opaque)
+bool fw_cfg_dma_enabled(void *opaque)
 {
     FWCfgState *s = opaque;
 
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index d008112..5c27a1f 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -182,5 +182,6 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
                                  hwaddr dma_addr, AddressSpace *dma_as);
 
 FWCfgState *fw_cfg_find(void);
+bool fw_cfg_dma_enabled(void *opaque);
 
 #endif
diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index ce4852a..2b11cd3 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -13,15 +13,30 @@ CFLAGS := -Wall -Wstrict-prototypes -Werror -fomit-frame-pointer -fno-builtin
 CFLAGS += -I$(SRC_PATH)
 CFLAGS += $(call cc-option, $(CFLAGS), -fno-stack-protector)
 CFLAGS += $(CFLAGS_NOPIE)
+ifdef CONFIG_COMPILER_M16
+CFLAGS += -m16
+else
+# Attempt to work around the lack of support for -m16 in gcc < 4.9.
+CFLAGS += -m32 -fno-toplevel-reorder
+linuxboot_dma.o-cflags += -include code16gcc.h
+endif
 QEMU_CFLAGS = $(CFLAGS)
 
-build-all: multiboot.bin linuxboot.bin kvmvapic.bin
+ASFLAGS += -32
+
+build-all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin
 
 # suppress auto-removal of intermediate files
 .SECONDARY:
 
+ifdef CONFIG_WIN32
+LD_EMULATION = i386pe
+else
+LD_EMULATION = elf_i386
+endif
+
 %.img: %.o
-	$(call quiet-command,$(LD) $(LDFLAGS_NOPIE) -Ttext 0 -e _start -s -o $@ $<,"  Building $(TARGET_DIR)$@")
+	$(call quiet-command,$(LD) $(LDFLAGS_NOPIE) -m $(LD_EMULATION) -Ttext 0 -e _start -s -o $@ $<,"  Building $(TARGET_DIR)$@")
 
 %.raw: %.img
 	$(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,"  Building $(TARGET_DIR)$@")
diff --git a/pc-bios/optionrom/code16gcc.h b/pc-bios/optionrom/code16gcc.h
new file mode 100644
index 0000000..9c8d25d
--- /dev/null
+++ b/pc-bios/optionrom/code16gcc.h
@@ -0,0 +1,3 @@
+asm(
+".code16gcc\n"
+);
diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c
new file mode 100644
index 0000000..7057ead
--- /dev/null
+++ b/pc-bios/optionrom/linuxboot_dma.c
@@ -0,0 +1,291 @@
+/*
+ * Linux Boot Option ROM for fw_cfg DMA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Copyright (c) 2015-2016 Red Hat Inc.
+ *   Authors:
+ *     Marc Marí <marc.mari.barcelo@gmail.com>
+ *     Richard W.M. Jones <rjones@redhat.com>
+ */
+
+asm(
+".text\n"
+".global _start\n"
+"_start:\n"
+"   .short 0xaa55\n"
+"   .byte 0\n" /* size in 512 units, filled in by signrom.py */
+"   .byte 0xcb\n" /* far return without prefix */
+"   .org 0x18\n"
+"   .short 0\n"
+"   .short _pnph\n"
+"_pnph:\n"
+"   .ascii \"$PnP\"\n"
+"   .byte 0x01\n"
+"   .byte (_pnph_len / 16)\n"
+"   .short 0x0000\n"
+"   .byte 0x00\n"
+"   .byte 0x00\n"
+"   .long 0x00000000\n"
+"   .short _manufacturer\n"
+"   .short _product\n"
+"   .long 0x00000000\n"
+"   .short 0x0000\n"
+"   .short 0x0000\n"
+"   .short _bev\n"
+"   .short 0x0000\n"
+"   .short 0x0000\n"
+"   .equ _pnph_len, . - _pnph\n"
+"_manufacturer:\n"
+"   .asciz \"QEMU\"\n"
+"_product:\n"
+"   .asciz \"Linux loader DMA\"\n"
+"   .align 4, 0\n"
+"_bev:\n"
+"   cli\n"
+"   cld\n"
+"   jmp load_kernel\n"
+);
+
+#include "../../include/hw/nvram/fw_cfg_keys.h"
+
+/* QEMU_CFG_DMA_CONTROL bits */
+#define BIOS_CFG_DMA_CTL_ERROR   0x01
+#define BIOS_CFG_DMA_CTL_READ    0x02
+#define BIOS_CFG_DMA_CTL_SKIP    0x04
+#define BIOS_CFG_DMA_CTL_SELECT  0x08
+
+#define BIOS_CFG_DMA_ADDR_HIGH 0x514
+#define BIOS_CFG_DMA_ADDR_LOW  0x518
+
+#define uint64_t unsigned long long
+#define uint32_t unsigned int
+#define uint16_t unsigned short
+
+#define barrier() asm("" : : : "memory")
+
+typedef struct FWCfgDmaAccess {
+    uint32_t control;
+    uint32_t length;
+    uint64_t address;
+} __attribute__((packed)) FWCfgDmaAccess;
+
+static inline void outl(uint32_t value, uint16_t port)
+{
+    asm("outl %0, %w1" : : "a"(value), "Nd"(port));
+}
+
+static inline void set_es(void *addr)
+{
+    uint32_t seg = (uint32_t)addr >> 4;
+    asm("movl %0, %%es" : : "r"(seg));
+}
+
+#ifdef __clang__
+#define ADDR32
+#else
+#define ADDR32 "addr32 "
+#endif
+
+static inline uint16_t readw_es(uint16_t offset)
+{
+    uint16_t val;
+    asm(ADDR32 "movw %%es:(%1), %0" : "=r"(val) : "r"((uint32_t)offset));
+    barrier();
+    return val;
+}
+
+static inline uint32_t readl_es(uint16_t offset)
+{
+    uint32_t val;
+    asm(ADDR32 "movl %%es:(%1), %0" : "=r"(val) : "r"((uint32_t)offset));
+    barrier();
+    return val;
+}
+
+static inline void writel_es(uint16_t offset, uint32_t val)
+{
+    barrier();
+    asm(ADDR32 "movl %0, %%es:(%1)" : : "r"(val), "r"((uint32_t)offset));
+}
+
+static inline uint32_t bswap32(uint32_t x)
+{
+    return
+        ((x & 0x000000ffU) << 24) |
+        ((x & 0x0000ff00U) <<  8) |
+        ((x & 0x00ff0000U) >>  8) |
+        ((x & 0xff000000U) >> 24);
+}
+
+static inline uint64_t bswap64(uint64_t x)
+{
+    return
+        ((x & 0x00000000000000ffULL) << 56) |
+        ((x & 0x000000000000ff00ULL) << 40) |
+        ((x & 0x0000000000ff0000ULL) << 24) |
+        ((x & 0x00000000ff000000ULL) <<  8) |
+        ((x & 0x000000ff00000000ULL) >>  8) |
+        ((x & 0x0000ff0000000000ULL) >> 24) |
+        ((x & 0x00ff000000000000ULL) >> 40) |
+        ((x & 0xff00000000000000ULL) >> 56);
+}
+
+static inline uint64_t cpu_to_be64(uint64_t x)
+{
+    return bswap64(x);
+}
+
+static inline uint32_t cpu_to_be32(uint32_t x)
+{
+    return bswap32(x);
+}
+
+static inline uint32_t be32_to_cpu(uint32_t x)
+{
+    return bswap32(x);
+}
+
+static void bios_cfg_read_entry(void *buf, uint16_t entry, uint32_t len)
+{
+    FWCfgDmaAccess access;
+    uint32_t control = (entry << 16) | BIOS_CFG_DMA_CTL_SELECT
+                        | BIOS_CFG_DMA_CTL_READ;
+
+    access.address = cpu_to_be64((uint64_t)(uint32_t)buf);
+    access.length = cpu_to_be32(len);
+    access.control = cpu_to_be32(control);
+
+    barrier();
+
+    outl(cpu_to_be32((uint32_t)&access), BIOS_CFG_DMA_ADDR_LOW);
+
+    while (be32_to_cpu(access.control) & ~BIOS_CFG_DMA_CTL_ERROR) {
+        barrier();
+    }
+}
+
+/* Return top of memory using BIOS function E801. */
+static uint32_t get_e801_addr(void)
+{
+    uint16_t ax, bx, cx, dx;
+    uint32_t ret;
+
+    asm("int $0x15\n"
+        : "=a"(ax), "=b"(bx), "=c"(cx), "=d"(dx)
+        : "a"(0xe801), "b"(0), "c"(0), "d"(0));
+
+    /* Not SeaBIOS, but in theory a BIOS could return CX=DX=0 in which
+     * case we need to use the result from AX & BX instead.
+     */
+    if (cx == 0 && dx == 0) {
+        cx = ax;
+        dx = bx;
+    }
+
+    if (dx) {
+        /* DX = extended memory above 16M, in 64K units.
+         * Convert it to bytes and return.
+         */
+        ret = ((uint32_t)dx + 256 /* 16M in 64K units */) << 16;
+    } else {
+        /* This is a fallback path for machines with <= 16MB of RAM,
+         * which probably would never be the case, but deal with it
+         * anyway.
+         *
+         * CX = extended memory between 1M and 16M, in kilobytes
+         * Convert it to bytes and return.
+         */
+        ret = ((uint32_t)cx + 1024 /* 1M in K */) << 10;
+    }
+
+    return ret;
+}
+
+void load_kernel(void)
+{
+    void *setup_addr;
+    void *initrd_addr;
+    void *kernel_addr;
+    void *cmdline_addr;
+    uint32_t setup_size;
+    uint32_t initrd_size;
+    uint32_t kernel_size;
+    uint32_t cmdline_size;
+    uint32_t initrd_end_page, max_allowed_page;
+    uint32_t segment_addr, stack_addr;
+
+    bios_cfg_read_entry(&setup_addr, FW_CFG_SETUP_ADDR, 4);
+    bios_cfg_read_entry(&setup_size, FW_CFG_SETUP_SIZE, 4);
+    bios_cfg_read_entry(setup_addr, FW_CFG_SETUP_DATA, setup_size);
+
+    set_es(setup_addr);
+
+    /* For protocol < 0x203 we don't have initrd_max ... */
+    if (readw_es(0x206) < 0x203) {
+        /* ... so we assume initrd_max = 0x37ffffff. */
+        writel_es(0x22c, 0x37ffffff);
+    }
+
+    bios_cfg_read_entry(&initrd_addr, FW_CFG_INITRD_ADDR, 4);
+    bios_cfg_read_entry(&initrd_size, FW_CFG_INITRD_SIZE, 4);
+
+    initrd_end_page = ((uint32_t)(initrd_addr + initrd_size) & -4096);
+    max_allowed_page = (readl_es(0x22c) & -4096);
+
+    if (initrd_end_page != 0 && max_allowed_page != 0 &&
+        initrd_end_page != max_allowed_page) {
+        /* Initrd at the end of memory. Compute better initrd address
+         * based on e801 data
+         */
+        initrd_addr = (void *)((get_e801_addr() - initrd_size) & -4096);
+        writel_es(0x218, (uint32_t)initrd_addr);
+
+    }
+
+    bios_cfg_read_entry(initrd_addr, FW_CFG_INITRD_DATA, initrd_size);
+
+    bios_cfg_read_entry(&kernel_addr, FW_CFG_KERNEL_ADDR, 4);
+    bios_cfg_read_entry(&kernel_size, FW_CFG_KERNEL_SIZE, 4);
+    bios_cfg_read_entry(kernel_addr, FW_CFG_KERNEL_DATA, kernel_size);
+
+    bios_cfg_read_entry(&cmdline_addr, FW_CFG_CMDLINE_ADDR, 4);
+    bios_cfg_read_entry(&cmdline_size, FW_CFG_CMDLINE_SIZE, 4);
+    bios_cfg_read_entry(cmdline_addr, FW_CFG_CMDLINE_DATA, cmdline_size);
+
+    /* Boot linux */
+    segment_addr = ((uint32_t)setup_addr >> 4);
+    stack_addr = (uint32_t)(cmdline_addr - setup_addr - 16);
+
+    /* As we are changing critical registers, we cannot leave freedom to the
+     * compiler.
+     */
+    asm("movw %%ax, %%ds\n"
+        "movw %%ax, %%es\n"
+        "movw %%ax, %%fs\n"
+        "movw %%ax, %%gs\n"
+        "movw %%ax, %%ss\n"
+        "movl %%ebx, %%esp\n"
+        "addw $0x20, %%ax\n"
+        "pushw %%ax\n" /* CS */
+        "pushw $0\n" /* IP */
+        /* Clear registers and jump to Linux */
+        "xor %%ebx, %%ebx\n"
+        "xor %%ecx, %%ecx\n"
+        "xor %%edx, %%edx\n"
+        "xor %%edi, %%edi\n"
+        "xor %%ebp, %%ebp\n"
+        "lretw\n"
+        : : "a"(segment_addr), "b"(stack_addr));
+}
-- 
2.5.5

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

* [Qemu-devel] [PULL 02/31] Revert "memory: Drop FlatRange.romd_mode"
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 01/31] Add optionrom compatible with fw_cfg DMA version Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:51   ` Laszlo Ersek
  2016-05-27 10:06 ` [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c Paolo Bonzini
                   ` (29 subsequent siblings)
  31 siblings, 1 reply; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

This reverts commit 5b5660adf1fdb61db14ec681b10463b8cba633f1,
as it breaks the UEFI guest firmware (known as ArmVirtPkg or AAVMF)
running in the "virt" machine type of "qemu-system-aarch64":

Contrary to the commit message, (a->mr == b->mr) does *not* imply
that (a->romd_mode == b->romd_mode): the pflash device model calls
memory_region_rom_device_set_romd() -- for switching between the above
modes --, and that function changes mr->romd_mode but the current
AddressSpaceDispatch's FlatRange keeps the old value.  Therefore
region_del/region_add are not called on the KVM MemoryListener.

Reported-by: Drew Jones <drjones@redhat.com>
Tested-by: Drew Jones <drjones@redhat.com>
Analyzed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 memory.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/memory.c b/memory.c
index 4e3cda8..0f52522 100644
--- a/memory.c
+++ b/memory.c
@@ -227,6 +227,7 @@ struct FlatRange {
     hwaddr offset_in_region;
     AddrRange addr;
     uint8_t dirty_log_mask;
+    bool romd_mode;
     bool readonly;
 };
 
@@ -251,6 +252,7 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
     return a->mr == b->mr
         && addrrange_equal(a->addr, b->addr)
         && a->offset_in_region == b->offset_in_region
+        && a->romd_mode == b->romd_mode
         && a->readonly == b->readonly;
 }
 
@@ -310,6 +312,7 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
                                 r1->addr.size),
                      int128_make64(r2->offset_in_region))
         && r1->dirty_log_mask == r2->dirty_log_mask
+        && r1->romd_mode == r2->romd_mode
         && r1->readonly == r2->readonly;
 }
 
@@ -663,6 +666,7 @@ static void render_memory_region(FlatView *view,
 
     fr.mr = mr;
     fr.dirty_log_mask = memory_region_get_dirty_log_mask(mr);
+    fr.romd_mode = mr->romd_mode;
     fr.readonly = readonly;
 
     /* Render the region itself into any gaps left by the current view. */
-- 
2.5.5

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

* [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 01/31] Add optionrom compatible with fw_cfg DMA version Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 02/31] Revert "memory: Drop FlatRange.romd_mode" Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-31 22:13   ` Mark Cave-Ayland
  2016-05-27 10:06 ` [Qemu-devel] [PULL 04/31] hw/char: QOM'ify etraxfs_ser.c Paolo Bonzini
                   ` (28 subsequent siblings)
  31 siblings, 1 reply; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: xiaoqiang zhao

From: xiaoqiang zhao <zxq_yx_007@163.com>

* Drop the old SysBus init function and use instance_init
* Call qemu_chr_add_handlers in the realize callback

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Message-Id: <1464158344-12266-2-git-send-email-zxq_yx_007@163.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/char/escc.c | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/hw/char/escc.c b/hw/char/escc.c
index 7bf09a0..8e6a7df 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -983,9 +983,10 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
     sysbus_mmio_map(s, 0, base);
 }
 
-static int escc_init1(SysBusDevice *dev)
+static void escc_init1(Object *obj)
 {
-    ESCCState *s = ESCC(dev);
+    ESCCState *s = ESCC(obj);
+    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
     unsigned int i;
 
     s->chn[0].disabled = s->disabled;
@@ -994,17 +995,26 @@ static int escc_init1(SysBusDevice *dev)
         sysbus_init_irq(dev, &s->chn[i].irq);
         s->chn[i].chn = 1 - i;
         s->chn[i].clock = s->frequency / 2;
-        if (s->chn[i].chr) {
-            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
-                                  serial_receive1, serial_event, &s->chn[i]);
-        }
     }
     s->chn[0].otherchn = &s->chn[1];
     s->chn[1].otherchn = &s->chn[0];
 
-    memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
+    memory_region_init_io(&s->mmio, obj, &escc_mem_ops, s, "escc",
                           ESCC_SIZE << s->it_shift);
     sysbus_init_mmio(dev, &s->mmio);
+}
+
+static void escc_realize(DeviceState *dev, Error **errp)
+{
+    ESCCState *s = ESCC(dev);
+    unsigned int i;
+
+    for (i = 0; i < 2; i++) {
+        if (s->chn[i].chr) {
+            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
+                                  serial_receive1, serial_event, &s->chn[i]);
+        }
+    }
 
     if (s->chn[0].type == mouse) {
         qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
@@ -1014,8 +1024,6 @@ static int escc_init1(SysBusDevice *dev)
         s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
                                                    &sunkbd_handler);
     }
-
-    return 0;
 }
 
 static Property escc_properties[] = {
@@ -1032,10 +1040,9 @@ static Property escc_properties[] = {
 static void escc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = escc_init1;
     dc->reset = escc_reset;
+    dc->realize = escc_realize;
     dc->vmsd = &vmstate_escc;
     dc->props = escc_properties;
     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
@@ -1045,6 +1052,7 @@ static const TypeInfo escc_info = {
     .name          = TYPE_ESCC,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(ESCCState),
+    .instance_init = escc_init1,
     .class_init    = escc_class_init,
 };
 
-- 
2.5.5

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

* [Qemu-devel] [PULL 04/31] hw/char: QOM'ify etraxfs_ser.c
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (2 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 05/31] hw/char: QOM'ify lm32_juart.c Paolo Bonzini
                   ` (27 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: xiaoqiang zhao

From: xiaoqiang zhao <zxq_yx_007@163.com>

* Drop the old SysBus init function and use instance_init
* Call qemu_chr_add_handlers in the realize callback
* Use qdev chardev prop instead of qemu_char_get_next_serial
* Add etraxfs_ser_create function to create etraxfs serial device

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Message-Id: <1464158344-12266-3-git-send-email-zxq_yx_007@163.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/char/etraxfs_ser.c     | 27 +++++++++++++++++----------
 hw/cris/axis_dev88.c      |  4 ++--
 include/hw/cris/etraxfs.h | 16 ++++++++++++++++
 3 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index 146b387..04ca04f 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -159,6 +159,11 @@ static const MemoryRegionOps ser_ops = {
     }
 };
 
+static Property etraxfs_ser_properties[] = {
+    DEFINE_PROP_CHR("chardev", ETRAXSerial, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void serial_receive(void *opaque, const uint8_t *buf, int size)
 {
     ETRAXSerial *s = opaque;
@@ -209,40 +214,42 @@ static void etraxfs_ser_reset(DeviceState *d)
 
 }
 
-static int etraxfs_ser_init(SysBusDevice *dev)
+static void etraxfs_ser_init(Object *obj)
 {
-    ETRAXSerial *s = ETRAX_SERIAL(dev);
+    ETRAXSerial *s = ETRAX_SERIAL(obj);
+    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
 
     sysbus_init_irq(dev, &s->irq);
-    memory_region_init_io(&s->mmio, OBJECT(s), &ser_ops, s,
+    memory_region_init_io(&s->mmio, obj, &ser_ops, s,
                           "etraxfs-serial", R_MAX * 4);
     sysbus_init_mmio(dev, &s->mmio);
+}
+
+static void etraxfs_ser_realize(DeviceState *dev, Error **errp)
+{
+    ETRAXSerial *s = ETRAX_SERIAL(dev);
 
-    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
-    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr,
                               serial_can_receive, serial_receive,
                               serial_event, s);
     }
-    return 0;
 }
 
 static void etraxfs_ser_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = etraxfs_ser_init;
     dc->reset = etraxfs_ser_reset;
-    /* Reason: init() method uses qemu_char_get_next_serial() */
-    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->props = etraxfs_ser_properties;
+    dc->realize = etraxfs_ser_realize;
 }
 
 static const TypeInfo etraxfs_ser_info = {
     .name          = TYPE_ETRAX_FS_SERIAL,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(ETRAXSerial),
+    .instance_init = etraxfs_ser_init,
     .class_init    = etraxfs_ser_class_init,
 };
 
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 9f58658..60df887 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -37,6 +37,7 @@
 #include "sysemu/block-backend.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
+#include "sysemu/sysemu.h"
 
 #define D(x)
 #define DNAND(x)
@@ -341,8 +342,7 @@ void axisdev88_init(MachineState *machine)
     sysbus_create_varargs("etraxfs,timer", 0x3005e000, irq[0x1b], nmi[1], NULL);
 
     for (i = 0; i < 4; i++) {
-        sysbus_create_simple("etraxfs,serial", 0x30026000 + i * 0x2000,
-                             irq[0x14 + i]);
+        etraxfs_ser_create(0x30026000 + i * 0x2000, irq[0x14 + i], serial_hds[i]);
     }
 
     if (kernel_filename) {
diff --git a/include/hw/cris/etraxfs.h b/include/hw/cris/etraxfs.h
index 73a6134..eb66418 100644
--- a/include/hw/cris/etraxfs.h
+++ b/include/hw/cris/etraxfs.h
@@ -46,4 +46,20 @@ etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr,
     return dev;
 }
 
+static inline DeviceState *etraxfs_ser_create(hwaddr addr,
+                                              qemu_irq irq,
+                                              CharDriverState *chr)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_create(NULL, "etraxfs,serial");
+    s = SYS_BUS_DEVICE(dev);
+    qdev_prop_set_chr(dev, "chardev", chr);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(s, 0, addr);
+    sysbus_connect_irq(s, 0, irq);
+    return dev;
+}
+
 #endif
-- 
2.5.5

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

* [Qemu-devel] [PULL 05/31] hw/char: QOM'ify lm32_juart.c
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (3 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 04/31] hw/char: QOM'ify etraxfs_ser.c Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 06/31] hw/char: QOM'ify lm32_uart.c Paolo Bonzini
                   ` (26 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: xiaoqiang zhao

From: xiaoqiang zhao <zxq_yx_007@163.com>

* Drop the old SysBus init function
* Call qemu_chr_add_handlers in the realize callback
* Use qdev chardev prop instead of qemu_char_get_next_serial

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Message-Id: <1464158344-12266-4-git-send-email-zxq_yx_007@163.com>
Tested-by: Michael Walle <michael@walle.cc>
Acked-by: Michael Walle <michael@walle.cc>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/char/lm32_juart.c  | 17 ++++++++---------
 hw/lm32/lm32.h        |  3 ++-
 hw/lm32/lm32_boards.c |  5 +++--
 hw/lm32/milkymist.c   |  2 +-
 4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
index 5bf8acf..28c2cf7 100644
--- a/hw/char/lm32_juart.c
+++ b/hw/char/lm32_juart.c
@@ -114,17 +114,13 @@ static void juart_reset(DeviceState *d)
     s->jrx = 0;
 }
 
-static int lm32_juart_init(SysBusDevice *dev)
+static void lm32_juart_realize(DeviceState *dev, Error **errp)
 {
     LM32JuartState *s = LM32_JUART(dev);
 
-    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
-    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, juart_can_rx, juart_rx, juart_event, s);
     }
-
-    return 0;
 }
 
 static const VMStateDescription vmstate_lm32_juart = {
@@ -138,16 +134,19 @@ static const VMStateDescription vmstate_lm32_juart = {
     }
 };
 
+static Property lm32_juart_properties[] = {
+    DEFINE_PROP_CHR("chardev", LM32JuartState, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void lm32_juart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = lm32_juart_init;
     dc->reset = juart_reset;
     dc->vmsd = &vmstate_lm32_juart;
-    /* Reason: init() method uses qemu_char_get_next_serial() */
-    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->props = lm32_juart_properties;
+    dc->realize = lm32_juart_realize;
 }
 
 static const TypeInfo lm32_juart_info = {
diff --git a/hw/lm32/lm32.h b/hw/lm32/lm32.h
index 18aa6fd..a993f00 100644
--- a/hw/lm32/lm32.h
+++ b/hw/lm32/lm32.h
@@ -16,11 +16,12 @@ static inline DeviceState *lm32_pic_init(qemu_irq cpu_irq)
     return dev;
 }
 
-static inline DeviceState *lm32_juart_init(void)
+static inline DeviceState *lm32_juart_init(CharDriverState *chr)
 {
     DeviceState *dev;
 
     dev = qdev_create(NULL, TYPE_LM32_JUART);
+    qdev_prop_set_chr(dev, "chardev", chr);
     qdev_init_nofail(dev);
 
     return dev;
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index c029056..2ae6555 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -31,6 +31,7 @@
 #include "lm32_hwsetup.h"
 #include "lm32.h"
 #include "exec/address-spaces.h"
+#include "sysemu/sysemu.h"
 
 typedef struct {
     LM32CPU *cpu;
@@ -136,7 +137,7 @@ static void lm32_evr_init(MachineState *machine)
     sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
 
     /* make sure juart isn't the first chardev */
-    env->juart_state = lm32_juart_init();
+    env->juart_state = lm32_juart_init(serial_hds[1]);
 
     reset_info->bootstrap_pc = flash_base;
 
@@ -238,7 +239,7 @@ static void lm32_uclinux_init(MachineState *machine)
     sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]);
 
     /* make sure juart isn't the first chardev */
-    env->juart_state = lm32_juart_init();
+    env->juart_state = lm32_juart_init(serial_hds[1]);
 
     reset_info->bootstrap_pc = flash_base;
 
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 1abdf6e..ebd8a3c 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -175,7 +175,7 @@ milkymist_init(MachineState *machine)
             0x20000000, 0x1000, 0x20020000, 0x2000);
 
     /* make sure juart isn't the first chardev */
-    env->juart_state = lm32_juart_init();
+    env->juart_state = lm32_juart_init(serial_hds[1]);
 
     if (kernel_filename) {
         uint64_t entry;
-- 
2.5.5

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

* [Qemu-devel] [PULL 06/31] hw/char: QOM'ify lm32_uart.c
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (4 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 05/31] hw/char: QOM'ify lm32_juart.c Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 07/31] hw/char: QOM'ify milkymist-uart.c Paolo Bonzini
                   ` (25 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: xiaoqiang zhao

From: xiaoqiang zhao <zxq_yx_007@163.com>

* Drop the old SysBus init function and use instance_init
* Call qemu_chr_add_handlers in the realize callback
* Use qdev chardev prop instead of qemu_char_get_next_serial
* Add lm32_uart_create function to create lm32 uart device

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Message-Id: <1464158344-12266-5-git-send-email-zxq_yx_007@163.com>
Tested-by: Michael Walle <michael@walle.cc>
Acked-by: Michael Walle <michael@walle.cc>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/char/lm32_uart.c   | 28 +++++++++++++++++-----------
 hw/lm32/lm32.h        | 16 ++++++++++++++++
 hw/lm32/lm32_boards.c |  4 ++--
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index 036813d..b5c760d 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -249,23 +249,25 @@ static void uart_reset(DeviceState *d)
     s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
 }
 
-static int lm32_uart_init(SysBusDevice *dev)
+static void lm32_uart_init(Object *obj)
 {
-    LM32UartState *s = LM32_UART(dev);
+    LM32UartState *s = LM32_UART(obj);
+    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
 
     sysbus_init_irq(dev, &s->irq);
 
-    memory_region_init_io(&s->iomem, OBJECT(s), &uart_ops, s,
+    memory_region_init_io(&s->iomem, obj, &uart_ops, s,
                           "uart", R_MAX * 4);
     sysbus_init_mmio(dev, &s->iomem);
+}
+
+static void lm32_uart_realize(DeviceState *dev, Error **errp)
+{
+    LM32UartState *s = LM32_UART(dev);
 
-    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
-    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
-
-    return 0;
 }
 
 static const VMStateDescription vmstate_lm32_uart = {
@@ -278,22 +280,26 @@ static const VMStateDescription vmstate_lm32_uart = {
     }
 };
 
+static Property lm32_uart_properties[] = {
+    DEFINE_PROP_CHR("chardev", LM32UartState, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void lm32_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 
-    k->init = lm32_uart_init;
     dc->reset = uart_reset;
     dc->vmsd = &vmstate_lm32_uart;
-    /* Reason: init() method uses qemu_char_get_next_serial() */
-    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->props = lm32_uart_properties;
+    dc->realize = lm32_uart_realize;
 }
 
 static const TypeInfo lm32_uart_info = {
     .name          = TYPE_LM32_UART,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(LM32UartState),
+    .instance_init = lm32_uart_init,
     .class_init    = lm32_uart_class_init,
 };
 
diff --git a/hw/lm32/lm32.h b/hw/lm32/lm32.h
index a993f00..e338bfe 100644
--- a/hw/lm32/lm32.h
+++ b/hw/lm32/lm32.h
@@ -27,4 +27,20 @@ static inline DeviceState *lm32_juart_init(CharDriverState *chr)
     return dev;
 }
 
+static inline DeviceState *lm32_uart_create(hwaddr addr,
+                                            qemu_irq irq,
+                                            CharDriverState *chr)
+{
+    DeviceState *dev;
+    SysBusDevice *s;
+
+    dev = qdev_create(NULL, "lm32-uart");
+    s = SYS_BUS_DEVICE(dev);
+    qdev_prop_set_chr(dev, "chardev", chr);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(s, 0, addr);
+    sysbus_connect_irq(s, 0, irq);
+    return dev;
+}
+
 #endif
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 2ae6555..8f0c307 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -132,7 +132,7 @@ static void lm32_evr_init(MachineState *machine)
         irq[i] = qdev_get_gpio_in(env->pic_state, i);
     }
 
-    sysbus_create_simple("lm32-uart", uart0_base, irq[uart0_irq]);
+    lm32_uart_create(uart0_base, irq[uart0_irq], serial_hds[0]);
     sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
     sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
 
@@ -233,7 +233,7 @@ static void lm32_uclinux_init(MachineState *machine)
         irq[i] = qdev_get_gpio_in(env->pic_state, i);
     }
 
-    sysbus_create_simple("lm32-uart", uart0_base, irq[uart0_irq]);
+    lm32_uart_create(uart0_base, irq[uart0_irq], serial_hds[0]);
     sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
     sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
     sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]);
-- 
2.5.5

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

* [Qemu-devel] [PULL 07/31] hw/char: QOM'ify milkymist-uart.c
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (5 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 06/31] hw/char: QOM'ify lm32_uart.c Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 08/31] nbd: Don't trim unrequested bytes Paolo Bonzini
                   ` (24 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: xiaoqiang zhao

From: xiaoqiang zhao <zxq_yx_007@163.com>

drop the qemu_char_get_next_serial and use chardev prop instead

Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
Message-Id: <1464158344-12266-6-git-send-email-zxq_yx_007@163.com>
Tested-by: Michael Walle <michael@walle.cc>
Acked-by: Michael Walle <michael@walle.cc>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/char/milkymist-uart.c | 10 ++++++----
 hw/lm32/milkymist-hw.h   |  4 +++-
 hw/lm32/milkymist.c      |  2 +-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index 03b36b2..72f8484 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -200,8 +200,6 @@ static void milkymist_uart_realize(DeviceState *dev, Error **errp)
 {
     MilkymistUartState *s = MILKYMIST_UART(dev);
 
-    /* FIXME use a qdev chardev prop instead of qemu_char_get_next_serial() */
-    s->chr = qemu_char_get_next_serial();
     if (s->chr) {
         qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
     }
@@ -229,6 +227,11 @@ static const VMStateDescription vmstate_milkymist_uart = {
     }
 };
 
+static Property milkymist_uart_properties[] = {
+    DEFINE_PROP_CHR("chardev", MilkymistUartState, chr),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void milkymist_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -236,8 +239,7 @@ static void milkymist_uart_class_init(ObjectClass *klass, void *data)
     dc->realize = milkymist_uart_realize;
     dc->reset = milkymist_uart_reset;
     dc->vmsd = &vmstate_milkymist_uart;
-    /* Reason: realize() method uses qemu_char_get_next_serial() */
-    dc->cannot_instantiate_with_device_add_yet = true;
+    dc->props = milkymist_uart_properties;
 }
 
 static const TypeInfo milkymist_uart_info = {
diff --git a/hw/lm32/milkymist-hw.h b/hw/lm32/milkymist-hw.h
index f857d28..eb6a3a2 100644
--- a/hw/lm32/milkymist-hw.h
+++ b/hw/lm32/milkymist-hw.h
@@ -5,11 +5,13 @@
 #include "net/net.h"
 
 static inline DeviceState *milkymist_uart_create(hwaddr base,
-        qemu_irq irq)
+                                                 qemu_irq irq,
+                                                 CharDriverState *chr)
 {
     DeviceState *dev;
 
     dev = qdev_create(NULL, "milkymist-uart");
+    qdev_prop_set_chr(dev, "chardev", chr);
     qdev_init_nofail(dev);
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index ebd8a3c..5cae0f1 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -159,7 +159,7 @@ milkymist_init(MachineState *machine)
     }
     g_free(bios_filename);
 
-    milkymist_uart_create(0x60000000, irq[0]);
+    milkymist_uart_create(0x60000000, irq[0], serial_hds[0]);
     milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3],
             80000000, 0x10014d31, 0x0000041f, 0x00000001);
     milkymist_hpdmc_create(0x60002000);
-- 
2.5.5

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

* [Qemu-devel] [PULL 08/31] nbd: Don't trim unrequested bytes
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (6 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 07/31] hw/char: QOM'ify milkymist-uart.c Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 09/31] kvm_stat: Remove Paolo Bonzini
                   ` (23 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Eric Blake, qemu-stable

From: Eric Blake <eblake@redhat.com>

Similar to commit df7b97ff, we are mishandling clients that
give an unaligned NBD_CMD_TRIM request, and potentially
trimming bytes that occur before their request; which in turn
can cause potential unintended data loss (unlikely in
practice, since most clients are sane and issue aligned trim
requests).  However, while we fixed read and write by switching
to the byte interfaces of blk_, we don't yet have a byte
interface for discard.  On the other hand, trim is advisory, so
rounding the user's request to simply ignore the first and last
unaligned sectors (or the entire request, if it is sub-sector
in length) is just fine.

CC: qemu-stable@nongnu.org
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1464173965-9694-1-git-send-email-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 nbd/server.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/nbd/server.c b/nbd/server.c
index fa862cd..b2cfeb9 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1153,12 +1153,20 @@ static void nbd_trip(void *opaque)
         break;
     case NBD_CMD_TRIM:
         TRACE("Request type is TRIM");
-        ret = blk_co_discard(exp->blk, (request.from + exp->dev_offset)
-                                       / BDRV_SECTOR_SIZE,
-                             request.len / BDRV_SECTOR_SIZE);
-        if (ret < 0) {
-            LOG("discard failed");
-            reply.error = -ret;
+        /* Ignore unaligned head or tail, until block layer adds byte
+         * interface */
+        if (request.len >= BDRV_SECTOR_SIZE) {
+            request.len -= (request.from + request.len) % BDRV_SECTOR_SIZE;
+            ret = blk_co_discard(exp->blk,
+                                 DIV_ROUND_UP(request.from + exp->dev_offset,
+                                              BDRV_SECTOR_SIZE),
+                                 request.len / BDRV_SECTOR_SIZE);
+            if (ret < 0) {
+                LOG("discard failed");
+                reply.error = -ret;
+            }
+        } else {
+            TRACE("trim request too small, ignoring");
         }
         if (nbd_co_send_reply(req, &reply, 0) < 0) {
             goto out;
-- 
2.5.5

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

* [Qemu-devel] [PULL 09/31] kvm_stat: Remove
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (7 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 08/31] nbd: Don't trim unrequested bytes Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 10/31] scsi: pvscsi: check command descriptor ring buffer size (CVE-2016-4952) Paolo Bonzini
                   ` (22 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

The source has moved to the Linux kernel tree.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 Makefile                  |   9 -
 scripts/kvm/kvm_stat      | 825 ----------------------------------------------
 scripts/kvm/kvm_stat.texi |  55 ----
 3 files changed, 889 deletions(-)
 delete mode 100755 scripts/kvm/kvm_stat
 delete mode 100644 scripts/kvm/kvm_stat.texi

diff --git a/Makefile b/Makefile
index 3a9782e..51403f1 100644
--- a/Makefile
+++ b/Makefile
@@ -92,9 +92,6 @@ HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF)
 ifdef BUILD_DOCS
 DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
 DOCS+=qmp-commands.txt
-ifdef CONFIG_LINUX
-DOCS+=kvm_stat.1
-endif
 ifdef CONFIG_VIRTFS
 DOCS+=fsdev/virtfs-proxy-helper.1
 endif
@@ -571,12 +568,6 @@ qemu-ga.8: qemu-ga.texi
 	  $(POD2MAN) --section=8 --center=" " --release=" " qemu-ga.pod > $@, \
 	  "  GEN   $@")
 
-kvm_stat.1: scripts/kvm/kvm_stat.texi
-	$(call quiet-command, \
-	  perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< kvm_stat.pod && \
-	  $(POD2MAN) --section=1 --center=" " --release=" " kvm_stat.pod > $@, \
-	  "  GEN   $@")
-
 dvi: qemu-doc.dvi qemu-tech.dvi
 html: qemu-doc.html qemu-tech.html
 info: qemu-doc.info qemu-tech.info
diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat
deleted file mode 100755
index 769d884..0000000
--- a/scripts/kvm/kvm_stat
+++ /dev/null
@@ -1,825 +0,0 @@
-#!/usr/bin/python
-#
-# top-like utility for displaying kvm statistics
-#
-# Copyright 2006-2008 Qumranet Technologies
-# Copyright 2008-2011 Red Hat, Inc.
-#
-# Authors:
-#  Avi Kivity <avi@redhat.com>
-#
-# This work is licensed under the terms of the GNU GPL, version 2.  See
-# the COPYING file in the top-level directory.
-
-import curses
-import sys
-import os
-import time
-import optparse
-import ctypes
-import fcntl
-import resource
-import struct
-import re
-from collections import defaultdict
-from time import sleep
-
-VMX_EXIT_REASONS = {
-    'EXCEPTION_NMI':        0,
-    'EXTERNAL_INTERRUPT':   1,
-    'TRIPLE_FAULT':         2,
-    'PENDING_INTERRUPT':    7,
-    'NMI_WINDOW':           8,
-    'TASK_SWITCH':          9,
-    'CPUID':                10,
-    'HLT':                  12,
-    'INVLPG':               14,
-    'RDPMC':                15,
-    'RDTSC':                16,
-    'VMCALL':               18,
-    'VMCLEAR':              19,
-    'VMLAUNCH':             20,
-    'VMPTRLD':              21,
-    'VMPTRST':              22,
-    'VMREAD':               23,
-    'VMRESUME':             24,
-    'VMWRITE':              25,
-    'VMOFF':                26,
-    'VMON':                 27,
-    'CR_ACCESS':            28,
-    'DR_ACCESS':            29,
-    'IO_INSTRUCTION':       30,
-    'MSR_READ':             31,
-    'MSR_WRITE':            32,
-    'INVALID_STATE':        33,
-    'MWAIT_INSTRUCTION':    36,
-    'MONITOR_INSTRUCTION':  39,
-    'PAUSE_INSTRUCTION':    40,
-    'MCE_DURING_VMENTRY':   41,
-    'TPR_BELOW_THRESHOLD':  43,
-    'APIC_ACCESS':          44,
-    'EPT_VIOLATION':        48,
-    'EPT_MISCONFIG':        49,
-    'WBINVD':               54,
-    'XSETBV':               55,
-    'APIC_WRITE':           56,
-    'INVPCID':              58,
-}
-
-SVM_EXIT_REASONS = {
-    'READ_CR0':       0x000,
-    'READ_CR3':       0x003,
-    'READ_CR4':       0x004,
-    'READ_CR8':       0x008,
-    'WRITE_CR0':      0x010,
-    'WRITE_CR3':      0x013,
-    'WRITE_CR4':      0x014,
-    'WRITE_CR8':      0x018,
-    'READ_DR0':       0x020,
-    'READ_DR1':       0x021,
-    'READ_DR2':       0x022,
-    'READ_DR3':       0x023,
-    'READ_DR4':       0x024,
-    'READ_DR5':       0x025,
-    'READ_DR6':       0x026,
-    'READ_DR7':       0x027,
-    'WRITE_DR0':      0x030,
-    'WRITE_DR1':      0x031,
-    'WRITE_DR2':      0x032,
-    'WRITE_DR3':      0x033,
-    'WRITE_DR4':      0x034,
-    'WRITE_DR5':      0x035,
-    'WRITE_DR6':      0x036,
-    'WRITE_DR7':      0x037,
-    'EXCP_BASE':      0x040,
-    'INTR':           0x060,
-    'NMI':            0x061,
-    'SMI':            0x062,
-    'INIT':           0x063,
-    'VINTR':          0x064,
-    'CR0_SEL_WRITE':  0x065,
-    'IDTR_READ':      0x066,
-    'GDTR_READ':      0x067,
-    'LDTR_READ':      0x068,
-    'TR_READ':        0x069,
-    'IDTR_WRITE':     0x06a,
-    'GDTR_WRITE':     0x06b,
-    'LDTR_WRITE':     0x06c,
-    'TR_WRITE':       0x06d,
-    'RDTSC':          0x06e,
-    'RDPMC':          0x06f,
-    'PUSHF':          0x070,
-    'POPF':           0x071,
-    'CPUID':          0x072,
-    'RSM':            0x073,
-    'IRET':           0x074,
-    'SWINT':          0x075,
-    'INVD':           0x076,
-    'PAUSE':          0x077,
-    'HLT':            0x078,
-    'INVLPG':         0x079,
-    'INVLPGA':        0x07a,
-    'IOIO':           0x07b,
-    'MSR':            0x07c,
-    'TASK_SWITCH':    0x07d,
-    'FERR_FREEZE':    0x07e,
-    'SHUTDOWN':       0x07f,
-    'VMRUN':          0x080,
-    'VMMCALL':        0x081,
-    'VMLOAD':         0x082,
-    'VMSAVE':         0x083,
-    'STGI':           0x084,
-    'CLGI':           0x085,
-    'SKINIT':         0x086,
-    'RDTSCP':         0x087,
-    'ICEBP':          0x088,
-    'WBINVD':         0x089,
-    'MONITOR':        0x08a,
-    'MWAIT':          0x08b,
-    'MWAIT_COND':     0x08c,
-    'XSETBV':         0x08d,
-    'NPF':            0x400,
-}
-
-# EC definition of HSR (from arch/arm64/include/asm/kvm_arm.h)
-AARCH64_EXIT_REASONS = {
-    'UNKNOWN':      0x00,
-    'WFI':          0x01,
-    'CP15_32':      0x03,
-    'CP15_64':      0x04,
-    'CP14_MR':      0x05,
-    'CP14_LS':      0x06,
-    'FP_ASIMD':     0x07,
-    'CP10_ID':      0x08,
-    'CP14_64':      0x0C,
-    'ILL_ISS':      0x0E,
-    'SVC32':        0x11,
-    'HVC32':        0x12,
-    'SMC32':        0x13,
-    'SVC64':        0x15,
-    'HVC64':        0x16,
-    'SMC64':        0x17,
-    'SYS64':        0x18,
-    'IABT':         0x20,
-    'IABT_HYP':     0x21,
-    'PC_ALIGN':     0x22,
-    'DABT':         0x24,
-    'DABT_HYP':     0x25,
-    'SP_ALIGN':     0x26,
-    'FP_EXC32':     0x28,
-    'FP_EXC64':     0x2C,
-    'SERROR':       0x2F,
-    'BREAKPT':      0x30,
-    'BREAKPT_HYP':  0x31,
-    'SOFTSTP':      0x32,
-    'SOFTSTP_HYP':  0x33,
-    'WATCHPT':      0x34,
-    'WATCHPT_HYP':  0x35,
-    'BKPT32':       0x38,
-    'VECTOR32':     0x3A,
-    'BRK64':        0x3C,
-}
-
-# From include/uapi/linux/kvm.h, KVM_EXIT_xxx
-USERSPACE_EXIT_REASONS = {
-    'UNKNOWN':          0,
-    'EXCEPTION':        1,
-    'IO':               2,
-    'HYPERCALL':        3,
-    'DEBUG':            4,
-    'HLT':              5,
-    'MMIO':             6,
-    'IRQ_WINDOW_OPEN':  7,
-    'SHUTDOWN':         8,
-    'FAIL_ENTRY':       9,
-    'INTR':             10,
-    'SET_TPR':          11,
-    'TPR_ACCESS':       12,
-    'S390_SIEIC':       13,
-    'S390_RESET':       14,
-    'DCR':              15,
-    'NMI':              16,
-    'INTERNAL_ERROR':   17,
-    'OSI':              18,
-    'PAPR_HCALL':       19,
-    'S390_UCONTROL':    20,
-    'WATCHDOG':         21,
-    'S390_TSCH':        22,
-    'EPR':              23,
-    'SYSTEM_EVENT':     24,
-}
-
-IOCTL_NUMBERS = {
-    'SET_FILTER':  0x40082406,
-    'ENABLE':      0x00002400,
-    'DISABLE':     0x00002401,
-    'RESET':       0x00002403,
-}
-
-class Arch(object):
-    """Class that encapsulates global architecture specific data like
-    syscall and ioctl numbers.
-
-    """
-    @staticmethod
-    def get_arch():
-        machine = os.uname()[4]
-
-        if machine.startswith('ppc'):
-            return ArchPPC()
-        elif machine.startswith('aarch64'):
-            return ArchA64()
-        elif machine.startswith('s390'):
-            return ArchS390()
-        else:
-            # X86_64
-            for line in open('/proc/cpuinfo'):
-                if not line.startswith('flags'):
-                    continue
-
-                flags = line.split()
-                if 'vmx' in flags:
-                    return ArchX86(VMX_EXIT_REASONS)
-                if 'svm' in flags:
-                    return ArchX86(SVM_EXIT_REASONS)
-                return
-
-class ArchX86(Arch):
-    def __init__(self, exit_reasons):
-        self.sc_perf_evt_open = 298
-        self.ioctl_numbers = IOCTL_NUMBERS
-        self.exit_reasons = exit_reasons
-
-class ArchPPC(Arch):
-    def __init__(self):
-        self.sc_perf_evt_open = 319
-        self.ioctl_numbers = IOCTL_NUMBERS
-        self.ioctl_numbers['ENABLE'] = 0x20002400
-        self.ioctl_numbers['DISABLE'] = 0x20002401
-
-        # PPC comes in 32 and 64 bit and some generated ioctl
-        # numbers depend on the wordsize.
-        char_ptr_size = ctypes.sizeof(ctypes.c_char_p)
-        self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16
-
-class ArchA64(Arch):
-    def __init__(self):
-        self.sc_perf_evt_open = 241
-        self.ioctl_numbers = IOCTL_NUMBERS
-        self.exit_reasons = AARCH64_EXIT_REASONS
-
-class ArchS390(Arch):
-    def __init__(self):
-        self.sc_perf_evt_open = 331
-        self.ioctl_numbers = IOCTL_NUMBERS
-        self.exit_reasons = None
-
-ARCH = Arch.get_arch()
-
-
-def walkdir(path):
-    """Returns os.walk() data for specified directory.
-
-    As it is only a wrapper it returns the same 3-tuple of (dirpath,
-    dirnames, filenames).
-    """
-    return next(os.walk(path))
-
-
-def parse_int_list(list_string):
-    """Returns an int list from a string of comma separated integers and
-    integer ranges."""
-    integers = []
-    members = list_string.split(',')
-
-    for member in members:
-        if '-' not in member:
-            integers.append(int(member))
-        else:
-            int_range = member.split('-')
-            integers.extend(range(int(int_range[0]),
-                                  int(int_range[1]) + 1))
-
-    return integers
-
-
-def get_online_cpus():
-    with open('/sys/devices/system/cpu/online') as cpu_list:
-        cpu_string = cpu_list.readline()
-        return parse_int_list(cpu_string)
-
-
-def get_filters():
-    filters = {}
-    filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS)
-    if ARCH.exit_reasons:
-        filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons)
-    return filters
-
-libc = ctypes.CDLL('libc.so.6', use_errno=True)
-syscall = libc.syscall
-
-class perf_event_attr(ctypes.Structure):
-    _fields_ = [('type', ctypes.c_uint32),
-                ('size', ctypes.c_uint32),
-                ('config', ctypes.c_uint64),
-                ('sample_freq', ctypes.c_uint64),
-                ('sample_type', ctypes.c_uint64),
-                ('read_format', ctypes.c_uint64),
-                ('flags', ctypes.c_uint64),
-                ('wakeup_events', ctypes.c_uint32),
-                ('bp_type', ctypes.c_uint32),
-                ('bp_addr', ctypes.c_uint64),
-                ('bp_len', ctypes.c_uint64),
-                ]
-
-    def __init__(self):
-        super(self.__class__, self).__init__()
-        self.type = PERF_TYPE_TRACEPOINT
-        self.size = ctypes.sizeof(self)
-        self.read_format = PERF_FORMAT_GROUP
-
-def perf_event_open(attr, pid, cpu, group_fd, flags):
-    return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr),
-                   ctypes.c_int(pid), ctypes.c_int(cpu),
-                   ctypes.c_int(group_fd), ctypes.c_long(flags))
-
-PERF_TYPE_TRACEPOINT = 2
-PERF_FORMAT_GROUP = 1 << 3
-
-PATH_DEBUGFS_TRACING = '/sys/kernel/debug/tracing'
-PATH_DEBUGFS_KVM = '/sys/kernel/debug/kvm'
-
-class Group(object):
-    def __init__(self):
-        self.events = []
-
-    def add_event(self, event):
-        self.events.append(event)
-
-    def read(self):
-        length = 8 * (1 + len(self.events))
-        read_format = 'xxxxxxxx' + 'Q' * len(self.events)
-        return dict(zip([event.name for event in self.events],
-                        struct.unpack(read_format,
-                                      os.read(self.events[0].fd, length))))
-
-class Event(object):
-    def __init__(self, name, group, trace_cpu, trace_point, trace_filter,
-                 trace_set='kvm'):
-        self.name = name
-        self.fd = None
-        self.setup_event(group, trace_cpu, trace_point, trace_filter,
-                         trace_set)
-
-    def setup_event_attribute(self, trace_set, trace_point):
-        id_path = os.path.join(PATH_DEBUGFS_TRACING, 'events', trace_set,
-                               trace_point, 'id')
-
-        event_attr = perf_event_attr()
-        event_attr.config = int(open(id_path).read())
-        return event_attr
-
-    def setup_event(self, group, trace_cpu, trace_point, trace_filter,
-                    trace_set):
-        event_attr = self.setup_event_attribute(trace_set, trace_point)
-
-        group_leader = -1
-        if group.events:
-            group_leader = group.events[0].fd
-
-        fd = perf_event_open(event_attr, -1, trace_cpu,
-                             group_leader, 0)
-        if fd == -1:
-            err = ctypes.get_errno()
-            raise OSError(err, os.strerror(err),
-                          'while calling sys_perf_event_open().')
-
-        if trace_filter:
-            fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'],
-                        trace_filter)
-
-        self.fd = fd
-
-    def enable(self):
-        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0)
-
-    def disable(self):
-        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0)
-
-    def reset(self):
-        fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0)
-
-class TracepointProvider(object):
-    def __init__(self):
-        self.group_leaders = []
-        self.filters = get_filters()
-        self._fields = self.get_available_fields()
-        self.setup_traces()
-        self.fields = self._fields
-
-    def get_available_fields(self):
-        path = os.path.join(PATH_DEBUGFS_TRACING, 'events', 'kvm')
-        fields = walkdir(path)[1]
-        extra = []
-        for field in fields:
-            if field in self.filters:
-                filter_name_, filter_dicts = self.filters[field]
-                for name in filter_dicts:
-                    extra.append(field + '(' + name + ')')
-        fields += extra
-        return fields
-
-    def setup_traces(self):
-        cpus = get_online_cpus()
-
-        # The constant is needed as a buffer for python libs, std
-        # streams and other files that the script opens.
-        newlim = len(cpus) * len(self._fields) + 50
-        try:
-            softlim_, hardlim = resource.getrlimit(resource.RLIMIT_NOFILE)
-
-            if hardlim < newlim:
-                # Now we need CAP_SYS_RESOURCE, to increase the hard limit.
-                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, newlim))
-            else:
-                # Raising the soft limit is sufficient.
-                resource.setrlimit(resource.RLIMIT_NOFILE, (newlim, hardlim))
-
-        except ValueError:
-            sys.exit("NOFILE rlimit could not be raised to {0}".format(newlim))
-
-        for cpu in cpus:
-            group = Group()
-            for name in self._fields:
-                tracepoint = name
-                tracefilter = None
-                match = re.match(r'(.*)\((.*)\)', name)
-                if match:
-                    tracepoint, sub = match.groups()
-                    tracefilter = ('%s==%d\0' %
-                                   (self.filters[tracepoint][0],
-                                    self.filters[tracepoint][1][sub]))
-
-                group.add_event(Event(name=name,
-                                      group=group,
-                                      trace_cpu=cpu,
-                                      trace_point=tracepoint,
-                                      trace_filter=tracefilter))
-            self.group_leaders.append(group)
-
-    def available_fields(self):
-        return self.get_available_fields()
-
-    @property
-    def fields(self):
-        return self._fields
-
-    @fields.setter
-    def fields(self, fields):
-        self._fields = fields
-        for group in self.group_leaders:
-            for index, event in enumerate(group.events):
-                if event.name in fields:
-                    event.reset()
-                    event.enable()
-                else:
-                    # Do not disable the group leader.
-                    # It would disable all of its events.
-                    if index != 0:
-                        event.disable()
-
-    def read(self):
-        ret = defaultdict(int)
-        for group in self.group_leaders:
-            for name, val in group.read().iteritems():
-                if name in self._fields:
-                    ret[name] += val
-        return ret
-
-class DebugfsProvider(object):
-    def __init__(self):
-        self._fields = self.get_available_fields()
-
-    def get_available_fields(self):
-        return walkdir(PATH_DEBUGFS_KVM)[2]
-
-    @property
-    def fields(self):
-        return self._fields
-
-    @fields.setter
-    def fields(self, fields):
-        self._fields = fields
-
-    def read(self):
-        def val(key):
-            return int(file(PATH_DEBUGFS_KVM + '/' + key).read())
-        return dict([(key, val(key)) for key in self._fields])
-
-class Stats(object):
-    def __init__(self, providers, fields=None):
-        self.providers = providers
-        self._fields_filter = fields
-        self.values = {}
-        self.update_provider_filters()
-
-    def update_provider_filters(self):
-        def wanted(key):
-            if not self._fields_filter:
-                return True
-            return re.match(self._fields_filter, key) is not None
-
-        # As we reset the counters when updating the fields we can
-        # also clear the cache of old values.
-        self.values = {}
-        for provider in self.providers:
-            provider_fields = [key for key in provider.get_available_fields()
-                               if wanted(key)]
-            provider.fields = provider_fields
-
-    @property
-    def fields_filter(self):
-        return self._fields_filter
-
-    @fields_filter.setter
-    def fields_filter(self, fields_filter):
-        self._fields_filter = fields_filter
-        self.update_provider_filters()
-
-    def get(self):
-        for provider in self.providers:
-            new = provider.read()
-            for key in provider.fields:
-                oldval = self.values.get(key, (0, 0))
-                newval = new.get(key, 0)
-                newdelta = None
-                if oldval is not None:
-                    newdelta = newval - oldval[0]
-                self.values[key] = (newval, newdelta)
-        return self.values
-
-LABEL_WIDTH = 40
-NUMBER_WIDTH = 10
-
-class Tui(object):
-    def __init__(self, stats):
-        self.stats = stats
-        self.screen = None
-        self.drilldown = False
-        self.update_drilldown()
-
-    def __enter__(self):
-        """Initialises curses for later use.  Based on curses.wrapper
-           implementation from the Python standard library."""
-        self.screen = curses.initscr()
-        curses.noecho()
-        curses.cbreak()
-
-        # The try/catch works around a minor bit of
-        # over-conscientiousness in the curses module, the error
-        # return from C start_color() is ignorable.
-        try:
-            curses.start_color()
-        except:
-            pass
-
-        curses.use_default_colors()
-        return self
-
-    def __exit__(self, *exception):
-        """Resets the terminal to its normal state.  Based on curses.wrappre
-           implementation from the Python standard library."""
-        if self.screen:
-            self.screen.keypad(0)
-            curses.echo()
-            curses.nocbreak()
-            curses.endwin()
-
-    def update_drilldown(self):
-        if not self.stats.fields_filter:
-            self.stats.fields_filter = r'^[^\(]*$'
-
-        elif self.stats.fields_filter == r'^[^\(]*$':
-            self.stats.fields_filter = None
-
-    def refresh(self, sleeptime):
-        self.screen.erase()
-        self.screen.addstr(0, 0, 'kvm statistics - summary', curses.A_BOLD)
-        self.screen.addstr(2, 1, 'Event')
-        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH -
-                           len('Total'), 'Total')
-        self.screen.addstr(2, 1 + LABEL_WIDTH + NUMBER_WIDTH + 8 -
-                           len('Current'), 'Current')
-        row = 3
-        stats = self.stats.get()
-        def sortkey(x):
-            if stats[x][1]:
-                return (-stats[x][1], -stats[x][0])
-            else:
-                return (0, -stats[x][0])
-        for key in sorted(stats.keys(), key=sortkey):
-
-            if row >= self.screen.getmaxyx()[0]:
-                break
-            values = stats[key]
-            if not values[0] and not values[1]:
-                break
-            col = 1
-            self.screen.addstr(row, col, key)
-            col += LABEL_WIDTH
-            self.screen.addstr(row, col, '%10d' % (values[0],))
-            col += NUMBER_WIDTH
-            if values[1] is not None:
-                self.screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
-            row += 1
-        self.screen.refresh()
-
-    def show_filter_selection(self):
-        while True:
-            self.screen.erase()
-            self.screen.addstr(0, 0,
-                               "Show statistics for events matching a regex.",
-                               curses.A_BOLD)
-            self.screen.addstr(2, 0,
-                               "Current regex: {0}"
-                               .format(self.stats.fields_filter))
-            self.screen.addstr(3, 0, "New regex: ")
-            curses.echo()
-            regex = self.screen.getstr()
-            curses.noecho()
-            if len(regex) == 0:
-                return
-            try:
-                re.compile(regex)
-                self.stats.fields_filter = regex
-                return
-            except re.error:
-                continue
-
-    def show_stats(self):
-        sleeptime = 0.25
-        while True:
-            self.refresh(sleeptime)
-            curses.halfdelay(int(sleeptime * 10))
-            sleeptime = 3
-            try:
-                char = self.screen.getkey()
-                if char == 'x':
-                    self.drilldown = not self.drilldown
-                    self.update_drilldown()
-                if char == 'q':
-                    break
-                if char == 'f':
-                    self.show_filter_selection()
-            except KeyboardInterrupt:
-                break
-            except curses.error:
-                continue
-
-def batch(stats):
-    s = stats.get()
-    time.sleep(1)
-    s = stats.get()
-    for key in sorted(s.keys()):
-        values = s[key]
-        print '%-42s%10d%10d' % (key, values[0], values[1])
-
-def log(stats):
-    keys = sorted(stats.get().iterkeys())
-    def banner():
-        for k in keys:
-            print '%s' % k,
-        print
-    def statline():
-        s = stats.get()
-        for k in keys:
-            print ' %9d' % s[k][1],
-        print
-    line = 0
-    banner_repeat = 20
-    while True:
-        time.sleep(1)
-        if line % banner_repeat == 0:
-            banner()
-        statline()
-        line += 1
-
-def get_options():
-    description_text = """
-This script displays various statistics about VMs running under KVM.
-The statistics are gathered from the KVM debugfs entries and / or the
-currently available perf traces.
-
-The monitoring takes additional cpu cycles and might affect the VM's
-performance.
-
-Requirements:
-- Access to:
-    /sys/kernel/debug/kvm
-    /sys/kernel/debug/trace/events/*
-    /proc/pid/task
-- /proc/sys/kernel/perf_event_paranoid < 1 if user has no
-  CAP_SYS_ADMIN and perf events are used.
-- CAP_SYS_RESOURCE if the hard limit is not high enough to allow
-  the large number of files that are possibly opened.
-"""
-
-    class PlainHelpFormatter(optparse.IndentedHelpFormatter):
-        def format_description(self, description):
-            if description:
-                return description + "\n"
-            else:
-                return ""
-
-    optparser = optparse.OptionParser(description=description_text,
-                                      formatter=PlainHelpFormatter())
-    optparser.add_option('-1', '--once', '--batch',
-                         action='store_true',
-                         default=False,
-                         dest='once',
-                         help='run in batch mode for one second',
-                         )
-    optparser.add_option('-l', '--log',
-                         action='store_true',
-                         default=False,
-                         dest='log',
-                         help='run in logging mode (like vmstat)',
-                         )
-    optparser.add_option('-t', '--tracepoints',
-                         action='store_true',
-                         default=False,
-                         dest='tracepoints',
-                         help='retrieve statistics from tracepoints',
-                         )
-    optparser.add_option('-d', '--debugfs',
-                         action='store_true',
-                         default=False,
-                         dest='debugfs',
-                         help='retrieve statistics from debugfs',
-                         )
-    optparser.add_option('-f', '--fields',
-                         action='store',
-                         default=None,
-                         dest='fields',
-                         help='fields to display (regex)',
-                         )
-    (options, _) = optparser.parse_args(sys.argv)
-    return options
-
-def get_providers(options):
-    providers = []
-
-    if options.tracepoints:
-        providers.append(TracepointProvider())
-    if options.debugfs:
-        providers.append(DebugfsProvider())
-    if len(providers) == 0:
-        providers.append(TracepointProvider())
-
-    return providers
-
-def check_access(options):
-    if not os.path.exists('/sys/kernel/debug'):
-        sys.stderr.write('Please enable CONFIG_DEBUG_FS in your kernel.')
-        sys.exit(1)
-
-    if not os.path.exists(PATH_DEBUGFS_KVM):
-        sys.stderr.write("Please make sure, that debugfs is mounted and "
-                         "readable by the current user:\n"
-                         "('mount -t debugfs debugfs /sys/kernel/debug')\n"
-                         "Also ensure, that the kvm modules are loaded.\n")
-        sys.exit(1)
-
-    if not os.path.exists(PATH_DEBUGFS_TRACING) and (options.tracepoints
-                                                     or not options.debugfs):
-        sys.stderr.write("Please enable CONFIG_TRACING in your kernel "
-                         "when using the option -t (default).\n"
-                         "If it is enabled, make {0} readable by the "
-                         "current user.\n"
-                         .format(PATH_DEBUGFS_TRACING))
-        if options.tracepoints:
-            sys.exit(1)
-
-        sys.stderr.write("Falling back to debugfs statistics!\n")
-        options.debugfs = True
-        sleep(5)
-
-    return options
-
-def main():
-    options = get_options()
-    options = check_access(options)
-    providers = get_providers(options)
-    stats = Stats(providers, fields=options.fields)
-
-    if options.log:
-        log(stats)
-    elif not options.once:
-        with Tui(stats) as tui:
-            tui.show_stats()
-    else:
-        batch(stats)
-
-if __name__ == "__main__":
-    main()
diff --git a/scripts/kvm/kvm_stat.texi b/scripts/kvm/kvm_stat.texi
deleted file mode 100644
index 6ce00d8..0000000
--- a/scripts/kvm/kvm_stat.texi
+++ /dev/null
@@ -1,55 +0,0 @@
-@example
-@c man begin SYNOPSIS
-usage: kvm_stat [OPTION]...
-@c man end
-@end example
-
-@c man begin DESCRIPTION
-
-kvm_stat prints counts of KVM kernel module trace events.  These events signify
-state transitions such as guest mode entry and exit.
-
-This tool is useful for observing guest behavior from the host perspective.
-Often conclusions about performance or buggy behavior can be drawn from the
-output.
-
-The set of KVM kernel module trace events may be specific to the kernel version
-or architecture.  It is best to check the KVM kernel module source code for the
-meaning of events.
-
-Note that trace events are counted globally across all running guests.
-
-@c man end
-
-@c man begin OPTIONS
-@table @option
-@item -1, --once, --batch
-  run in batch mode for one second
-@item -l, --log
-  run in logging mode (like vmstat)
-@item -t, --tracepoints
-  retrieve statistics from tracepoints
-@item -d, --debugfs
-  retrieve statistics from debugfs
-@item -f, --fields=@var{fields}
-  fields to display (regex)
-@item -h, --help
-  show help message
-@end table
-
-@c man end
-
-@ignore
-
-@setfilename kvm_stat
-@settitle Report KVM kernel module event counters.
-
-@c man begin AUTHOR
-Stefan Hajnoczi <stefanha@redhat.com>
-@c man end
-
-@c man begin SEEALSO
-perf(1), trace-cmd(1)
-@c man end
-
-@end ignore
-- 
2.5.5

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

* [Qemu-devel] [PULL 10/31] scsi: pvscsi: check command descriptor ring buffer size (CVE-2016-4952)
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (8 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 09/31] kvm_stat: Remove Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 11/31] scsi: mptsas: infinite loop while fetching requests Paolo Bonzini
                   ` (21 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Prasad J Pandit, qemu-stable

From: Prasad J Pandit <pjp@fedoraproject.org>

Vmware Paravirtual SCSI emulation uses command descriptors to
process SCSI commands. These descriptors come with their ring
buffers. A guest could set the ring buffer size to an arbitrary
value leading to OOB access issue. Add check to avoid it.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Message-Id: <1464000485-27041-1-git-send-email-ppandit@redhat.com>
Reviewed-by: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/vmw_pvscsi.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index f67b5bf..2d7528d 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -153,7 +153,7 @@ pvscsi_log2(uint32_t input)
     return log;
 }
 
-static void
+static int
 pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
 {
     int i;
@@ -161,6 +161,10 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
     uint32_t req_ring_size, cmp_ring_size;
     m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT;
 
+    if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)
+        || (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) {
+        return -1;
+    }
     req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
     cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
     txr_len_log2 = pvscsi_log2(req_ring_size - 1);
@@ -192,15 +196,20 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
 
     /* Flush ring state page changes */
     smp_wmb();
+
+    return 0;
 }
 
-static void
+static int
 pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
 {
     int i;
     uint32_t len_log2;
     uint32_t ring_size;
 
+    if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
+        return -1;
+    }
     ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
     len_log2 = pvscsi_log2(ring_size - 1);
 
@@ -220,6 +229,8 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
 
     /* Flush ring state page changes */
     smp_wmb();
+
+    return 0;
 }
 
 static void
@@ -770,7 +781,10 @@ pvscsi_on_cmd_setup_rings(PVSCSIState *s)
     trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS");
 
     pvscsi_dbg_dump_tx_rings_config(rc);
-    pvscsi_ring_init_data(&s->rings, rc);
+    if (pvscsi_ring_init_data(&s->rings, rc) < 0) {
+        return PVSCSI_COMMAND_PROCESSING_FAILED;
+    }
+
     s->rings_info_valid = TRUE;
     return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
 }
@@ -850,7 +864,9 @@ pvscsi_on_cmd_setup_msg_ring(PVSCSIState *s)
     }
 
     if (s->rings_info_valid) {
-        pvscsi_ring_init_msg(&s->rings, rc);
+        if (pvscsi_ring_init_msg(&s->rings, rc) < 0) {
+            return PVSCSI_COMMAND_PROCESSING_FAILED;
+        }
         s->msg_ring_info_valid = TRUE;
     }
     return sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(uint32_t);
-- 
2.5.5

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

* [Qemu-devel] [PULL 11/31] scsi: mptsas: infinite loop while fetching requests
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (9 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 10/31] scsi: pvscsi: check command descriptor ring buffer size (CVE-2016-4952) Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 12/31] scsi: megasas: use appropriate property buffer size Paolo Bonzini
                   ` (20 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Prasad J Pandit, qemu-stable

From: Prasad J Pandit <pjp@fedoraproject.org>

The LSI SAS1068 Host Bus Adapter emulator in Qemu, periodically
looks for requests and fetches them. A loop doing that in
mptsas_fetch_requests() could run infinitely if 's->state' was
not operational. Move check to avoid such a loop.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Message-Id: <1464077264-25473-1-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/mptsas.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index 499c146..be88e16 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -754,11 +754,6 @@ static void mptsas_fetch_request(MPTSASState *s)
     hwaddr addr;
     int size;
 
-    if (s->state != MPI_IOC_STATE_OPERATIONAL) {
-        mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_STATE);
-        return;
-    }
-
     /* Read the message header from the guest first. */
     addr = s->host_mfa_high_addr | MPTSAS_FIFO_GET(s, request_post);
     pci_dma_read(pci, addr, req, sizeof(hdr));
@@ -789,6 +784,10 @@ static void mptsas_fetch_requests(void *opaque)
 {
     MPTSASState *s = opaque;
 
+    if (s->state != MPI_IOC_STATE_OPERATIONAL) {
+        mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_STATE);
+        return;
+    }
     while (!MPTSAS_FIFO_EMPTY(s, request_post)) {
         mptsas_fetch_request(s);
     }
-- 
2.5.5

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

* [Qemu-devel] [PULL 12/31] scsi: megasas: use appropriate property buffer size
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (10 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 11/31] scsi: mptsas: infinite loop while fetching requests Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 13/31] scsi: megasas: initialise local configuration data buffer Paolo Bonzini
                   ` (19 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Prasad J Pandit

From: Prasad J Pandit <pjp@fedoraproject.org>

When setting MegaRAID SAS controller properties via MegaRAID
Firmware Interface(MFI) commands, a user supplied size parameter
is used to set property value. Use appropriate size value to avoid
OOB access issues.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1464172291-2856-2-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/megasas.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index a63a581..dcbd3e1 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1446,7 +1446,7 @@ static int megasas_dcmd_set_properties(MegasasState *s, MegasasCmd *cmd)
                                             dcmd_size);
         return MFI_STAT_INVALID_PARAMETER;
     }
-    dma_buf_write((uint8_t *)&info, cmd->iov_size, &cmd->qsg);
+    dma_buf_write((uint8_t *)&info, dcmd_size, &cmd->qsg);
     trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size);
     return MFI_STAT_OK;
 }
-- 
2.5.5

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

* [Qemu-devel] [PULL 13/31] scsi: megasas: initialise local configuration data buffer
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (11 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 12/31] scsi: megasas: use appropriate property buffer size Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 14/31] scsi: megasas: check 'read_queue_head' index value Paolo Bonzini
                   ` (18 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Prasad J Pandit

From: Prasad J Pandit <pjp@fedoraproject.org>

When reading MegaRAID SAS controller configuration via MegaRAID
Firmware Interface(MFI) commands, routine megasas_dcmd_cfg_read
uses an uninitialised local data buffer. Initialise this buffer
to avoid stack information leakage.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1464178304-12831-1-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/megasas.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index dcbd3e1..bf642d4 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1293,7 +1293,7 @@ static int megasas_dcmd_ld_get_info(MegasasState *s, MegasasCmd *cmd)
 
 static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
 {
-    uint8_t data[4096];
+    uint8_t data[4096] = { 0 };
     struct mfi_config_data *info;
     int num_pd_disks = 0, array_offset, ld_offset;
     BusChild *kid;
-- 
2.5.5

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

* [Qemu-devel] [PULL 14/31] scsi: megasas: check 'read_queue_head' index value
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (12 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 13/31] scsi: megasas: initialise local configuration data buffer Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 15/31] block/iscsi: avoid potential overflow of acb->task->cdb Paolo Bonzini
                   ` (17 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Prasad J Pandit

From: Prasad J Pandit <pjp@fedoraproject.org>

While doing MegaRAID SAS controller command frame lookup, routine
'megasas_lookup_frame' uses 'read_queue_head' value as an index
into 'frames[MEGASAS_MAX_FRAMES=2048]' array. Limit its value
within array bounds to avoid any OOB access.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1464179110-18593-1-git-send-email-ppandit@redhat.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/megasas.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index bf642d4..cc66d36 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -650,7 +650,9 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
     pa_hi = le32_to_cpu(initq->pi_addr_hi);
     s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo;
     s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa);
+    s->reply_queue_head %= MEGASAS_MAX_FRAMES;
     s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa);
+    s->reply_queue_tail %= MEGASAS_MAX_FRAMES;
     flags = le32_to_cpu(initq->flags);
     if (flags & MFI_QUEUE_FLAG_CONTEXT64) {
         s->flags |= MEGASAS_MASK_USE_QUEUE64;
-- 
2.5.5

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

* [Qemu-devel] [PULL 15/31] block/iscsi: avoid potential overflow of acb->task->cdb
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (13 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 14/31] scsi: megasas: check 'read_queue_head' index value Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 16/31] bt: rewrite csrhci_write to avoid out-of-bounds writes Paolo Bonzini
                   ` (16 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Lieven, qemu-stable

From: Peter Lieven <pl@kamp.de>

at least in the path via virtio-blk the maximum size is not
restricted.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1464080368-29584-1-git-send-email-pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/iscsi.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/block/iscsi.c b/block/iscsi.c
index 2ca8e72..e7d5f7b 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -833,6 +833,13 @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
         return &acb->common;
     }
 
+    if (acb->ioh->cmd_len > SCSI_CDB_MAX_SIZE) {
+        error_report("iSCSI: ioctl error CDB exceeds max size (%d > %d)",
+                     acb->ioh->cmd_len, SCSI_CDB_MAX_SIZE);
+        qemu_aio_unref(acb);
+        return NULL;
+    }
+
     acb->task = malloc(sizeof(struct scsi_task));
     if (acb->task == NULL) {
         error_report("iSCSI: Failed to allocate task for scsi command. %s",
-- 
2.5.5

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

* [Qemu-devel] [PULL 16/31] bt: rewrite csrhci_write to avoid out-of-bounds writes
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (14 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 15/31] block/iscsi: avoid potential overflow of acb->task->cdb Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 17/31] docs/atomics: update atomic_read/set comparison with Linux Paolo Bonzini
                   ` (15 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

The usage of INT_MAX in this function confuses Coverity.  I think
the defect is bogus, however there is no protection against
getting more than sizeof(s->inpkt) bytes from the character device
backend.

Rewrite the function to only fill in as much data as needed from
buf into s->inpkt.  The plen variable is replaced by a simple
state machine and there is no need anymore to shift contents to
the beginning of s->inpkt.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/bt/hci-csr.c | 67 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c
index e6b8998..d688372 100644
--- a/hw/bt/hci-csr.c
+++ b/hw/bt/hci-csr.c
@@ -39,9 +39,14 @@ struct csrhci_s {
     int out_size;
     uint8_t outfifo[FIFO_LEN * 2];
     uint8_t inpkt[FIFO_LEN];
+    enum {
+        CSR_HDR_LEN,
+        CSR_DATA_LEN,
+        CSR_DATA
+    } in_state;
     int in_len;
     int in_hdr;
-    int in_data;
+    int in_needed;
     QEMUTimer *out_tm;
     int64_t baud_delay;
 
@@ -296,38 +301,60 @@ static int csrhci_data_len(const uint8_t *pkt)
     exit(-1);
 }
 
+static void csrhci_ready_for_next_inpkt(struct csrhci_s *s)
+{
+    s->in_state = CSR_HDR_LEN;
+    s->in_len = 0;
+    s->in_needed = 2;
+    s->in_hdr = INT_MAX;
+}
+
 static int csrhci_write(struct CharDriverState *chr,
                 const uint8_t *buf, int len)
 {
     struct csrhci_s *s = (struct csrhci_s *) chr->opaque;
-    int plen = s->in_len;
+    int total = 0;
 
     if (!s->enable)
         return 0;
 
-    s->in_len += len;
-    memcpy(s->inpkt + plen, buf, len);
+    for (;;) {
+        int cnt = MIN(len, s->in_needed - s->in_len);
+        if (cnt) {
+            memcpy(s->inpkt + s->in_len, buf, cnt);
+            s->in_len += cnt;
+            buf += cnt;
+            len -= cnt;
+            total += cnt;
+        }
+
+        if (s->in_len < s->in_needed) {
+            break;
+        }
 
-    while (1) {
-        if (s->in_len >= 2 && plen < 2)
+        if (s->in_state == CSR_HDR_LEN) {
             s->in_hdr = csrhci_header_len(s->inpkt) + 1;
+            assert(s->in_hdr >= s->in_needed);
+            s->in_needed = s->in_hdr;
+            s->in_state = CSR_DATA_LEN;
+            continue;
+        }
 
-        if (s->in_len >= s->in_hdr && plen < s->in_hdr)
-            s->in_data = csrhci_data_len(s->inpkt) + s->in_hdr;
+        if (s->in_state == CSR_DATA_LEN) {
+            s->in_needed += csrhci_data_len(s->inpkt);
+            /* hci_acl_hdr could specify more than 4096 bytes, so assert.  */
+            assert(s->in_needed <= sizeof(s->inpkt));
+            s->in_state = CSR_DATA;
+            continue;
+        }
 
-        if (s->in_len >= s->in_data) {
+        if (s->in_state == CSR_DATA) {
             csrhci_in_packet(s, s->inpkt);
-
-            memmove(s->inpkt, s->inpkt + s->in_len, s->in_len - s->in_data);
-            s->in_len -= s->in_data;
-            s->in_hdr = INT_MAX;
-            s->in_data = INT_MAX;
-            plen = 0;
-        } else
-            break;
+            csrhci_ready_for_next_inpkt(s);
+        }
     }
 
-    return len;
+    return total;
 }
 
 static void csrhci_out_hci_packet_event(void *opaque,
@@ -389,11 +416,9 @@ static void csrhci_reset(struct csrhci_s *s)
 {
     s->out_len = 0;
     s->out_size = FIFO_LEN;
-    s->in_len = 0;
+    csrhci_ready_for_next_inpkt(s);
     s->baud_delay = NANOSECONDS_PER_SECOND;
     s->enable = 0;
-    s->in_hdr = INT_MAX;
-    s->in_data = INT_MAX;
 
     s->modem_state = 0;
     /* After a while... (but sooner than 10ms) */
-- 
2.5.5

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

* [Qemu-devel] [PULL 17/31] docs/atomics: update atomic_read/set comparison with Linux
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (15 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 16/31] bt: rewrite csrhci_write to avoid out-of-bounds writes Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 18/31] atomics: emit an smp_read_barrier_depends() barrier only for Alpha and Thread Sanitizer Paolo Bonzini
                   ` (14 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Emilio G. Cota

From: "Emilio G. Cota" <cota@braap.org>

Recently Linux did a mass conversion of its atomic_read/set calls
so that they at least are READ/WRITE_ONCE. See Linux's commit
62e8a325 ("atomic, arch: Audit atomic_{read,set}()"). It seems though
that their documentation hasn't been updated to reflect this.

The appended updates our documentation to reflect the change, which
means there is effectively no difference between our atomic_read/set
and the current Linux implementation.

While at it, fix the statement that a barrier is implied by
atomic_read/set, which is incorrect. Volatile/atomic semantics prevent
transformations pertaining the variable they apply to; this, however,
has no effect on surrounding statements like barriers do. For more
details on this, see:
  https://gcc.gnu.org/onlinedocs/gcc/Volatiles.html

Signed-off-by: Emilio G. Cota <cota@braap.org>
Message-Id: <1464120374-8950-2-git-send-email-cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 docs/atomics.txt | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/docs/atomics.txt b/docs/atomics.txt
index bba771e..67a27ad 100644
--- a/docs/atomics.txt
+++ b/docs/atomics.txt
@@ -326,9 +326,19 @@ and memory barriers, and the equivalents in QEMU:
   use a boxed atomic_t type; atomic operations in QEMU are polymorphic
   and use normal C types.
 
-- atomic_read and atomic_set in Linux give no guarantee at all;
-  atomic_read and atomic_set in QEMU include a compiler barrier
-  (similar to the READ_ONCE/WRITE_ONCE macros in Linux).
+- Originally, atomic_read and atomic_set in Linux gave no guarantee
+  at all. Linux 4.1 updated them to implement volatile
+  semantics via ACCESS_ONCE (or the more recent READ/WRITE_ONCE).
+
+  QEMU's atomic_read/set implement, if the compiler supports it, C11
+  atomic relaxed semantics, and volatile semantics otherwise.
+  Both semantics prevent the compiler from doing certain transformations;
+  the difference is that atomic accesses are guaranteed to be atomic,
+  while volatile accesses aren't. Thus, in the volatile case we just cross
+  our fingers hoping that the compiler will generate atomic accesses,
+  since we assume the variables passed are machine-word sized and
+  properly aligned.
+  No barriers are implied by atomic_read/set in either Linux or QEMU.
 
 - most atomic read-modify-write operations in Linux return void;
   in QEMU, all of them return the old value of the variable.
-- 
2.5.5

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

* [Qemu-devel] [PULL 18/31] atomics: emit an smp_read_barrier_depends() barrier only for Alpha and Thread Sanitizer
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (16 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 17/31] docs/atomics: update atomic_read/set comparison with Linux Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 19/31] atomics: do not emit consume barrier for atomic_rcu_read Paolo Bonzini
                   ` (13 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Emilio G. Cota

From: "Emilio G. Cota" <cota@braap.org>

For correctness, smp_read_barrier_depends() is only required to
emit a barrier on Alpha hosts. However, we are currently emitting
a consume fence unconditionally, and most compilers currently treat
consume and acquire fences as equivalent.

Fix it by keeping the consume fence if we're compiling with Thread
Sanitizer, since this might help prevent false warnings. Otherwise,
only emit the barrier for Alpha hosts. Note that we still guarantee
that smp_read_barrier_depends() is a compiler barrier.

Signed-off-by: Emilio G. Cota <cota@braap.org>
Message-Id: <1464120374-8950-3-git-send-email-cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/atomic.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 5bc4d6c..96db6e9 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -36,7 +36,18 @@
 #define smp_wmb()   ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); barrier(); })
 #define smp_rmb()   ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); barrier(); })
 
+/* Most compilers currently treat consume and acquire the same, but really
+ * no processors except Alpha need a barrier here.  Leave it in if
+ * using Thread Sanitizer to avoid warnings, otherwise optimize it away.
+ */
+#if defined(__SANITIZE_THREAD__)
 #define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); barrier(); })
+#elsif defined(__alpha__)
+#define smp_read_barrier_depends()   asm volatile("mb":::"memory")
+#else
+#define smp_read_barrier_depends()   barrier()
+#endif
+
 
 /* Weak atomic operations prevent the compiler moving other
  * loads/stores past the atomic operation load/store. However there is
-- 
2.5.5

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

* [Qemu-devel] [PULL 19/31] atomics: do not emit consume barrier for atomic_rcu_read
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (17 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 18/31] atomics: emit an smp_read_barrier_depends() barrier only for Alpha and Thread Sanitizer Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 20/31] docs/atomics: update comparison with Linux Paolo Bonzini
                   ` (12 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Emilio G. Cota

From: "Emilio G. Cota" <cota@braap.org>

Currently we emit a consume-load in atomic_rcu_read.  Because of
limitations in current compilers, this is overkill for non-Alpha hosts
and it is only useful to make Thread Sanitizer work.

This patch leaves the consume-load in atomic_rcu_read when
compiling with Thread Sanitizer enabled, and resorts to a
relaxed load + smp_read_barrier_depends otherwise.

On an RMO host architecture, such as aarch64, the performance
improvement of this change is easily measurable. For instance,
qht-bench performs an atomic_rcu_read on every lookup. Performance
before and after applying this patch:

$ tests/qht-bench -d 5 -n 1
Before: 9.78 MT/s
After:  10.96 MT/s

Signed-off-by: Emilio G. Cota <cota@braap.org>
Message-Id: <1464120374-8950-4-git-send-email-cota@braap.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/atomic.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 96db6e9..7a59096 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -67,13 +67,23 @@
     __atomic_store(ptr, &_val, __ATOMIC_RELAXED);     \
 } while(0)
 
-/* Atomic RCU operations imply weak memory barriers */
+/* See above: most compilers currently treat consume and acquire the
+ * same, but this slows down atomic_rcu_read unnecessarily.
+ */
+#ifdef __SANITIZE_THREAD__
+#define atomic_rcu_read__nocheck(ptr, valptr)           \
+    __atomic_load(ptr, valptr, __ATOMIC_CONSUME);
+#else
+#define atomic_rcu_read__nocheck(ptr, valptr)           \
+    __atomic_load(ptr, valptr, __ATOMIC_RELAXED);       \
+    smp_read_barrier_depends();
+#endif
 
 #define atomic_rcu_read(ptr)                          \
     ({                                                \
     QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \
     typeof(*ptr) _val;                                \
-    __atomic_load(ptr, &_val, __ATOMIC_CONSUME);      \
+    atomic_rcu_read__nocheck(ptr, &_val);             \
     _val;                                             \
     })
 
-- 
2.5.5

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

* [Qemu-devel] [PULL 20/31] docs/atomics: update comparison with Linux
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (18 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 19/31] atomics: do not emit consume barrier for atomic_rcu_read Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 21/31] xen-hvm: ignore background I/O sections Paolo Bonzini
                   ` (11 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

Over time, some differences between QEMU and Linux atomics are getting
smoothed.  In particular, Linux grew atomic_fetch_or (and in general
the differences regarding RMW operations were not described accurately)
and smp_load_acquire/smp_store_release.  Also, set_mb was renamed to
smp_store_mb().  Include these changes in the documentation.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 docs/atomics.txt | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/docs/atomics.txt b/docs/atomics.txt
index 67a27ad..c95950b 100644
--- a/docs/atomics.txt
+++ b/docs/atomics.txt
@@ -340,17 +340,27 @@ and memory barriers, and the equivalents in QEMU:
   properly aligned.
   No barriers are implied by atomic_read/set in either Linux or QEMU.
 
-- most atomic read-modify-write operations in Linux return void;
-  in QEMU, all of them return the old value of the variable.
+- atomic read-modify-write operations in Linux are of three kinds:
+
+         atomic_OP          returns void
+         atomic_OP_return   returns new value of the variable
+         atomic_fetch_OP    returns the old value of the variable
+         atomic_cmpxchg     returns the old value of the variable
+
+  In QEMU, the second kind does not exist.  Currently Linux has
+  atomic_fetch_or only.  QEMU provides and, or, inc, dec, add, sub.
 
 - different atomic read-modify-write operations in Linux imply
   a different set of memory barriers; in QEMU, all of them enforce
   sequential consistency, which means they imply full memory barriers
   before and after the operation.
 
-- Linux does not have an equivalent of atomic_mb_read() and
-  atomic_mb_set().  In particular, note that set_mb() is a little
-  weaker than atomic_mb_set().
+- Linux does not have an equivalent of atomic_mb_set().  In particular,
+  note that smp_store_mb() is a little weaker than atomic_mb_set().
+  atomic_mb_read() compiles to the same instructions as Linux's
+  smp_load_acquire(), but this should be treated as an implementation
+  detail.  If required, QEMU might later add atomic_load_acquire() and
+  atomic_store_release() macros.
 
 
 SOURCES
-- 
2.5.5

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

* [Qemu-devel] [PULL 21/31] xen-hvm: ignore background I/O sections
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (19 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 20/31] docs/atomics: update comparison with Linux Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 22/31] scsi-disk: introduce a common base class Paolo Bonzini
                   ` (10 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paul Durrant, Stefano Stabellini, Anthony Perard

From: Paul Durrant <paul.durrant@citrix.com>

Since Xen will correctly handle accesses to unimplemented I/O ports (by
returning all 1's for reads and ignoring writes) there is no need for
QEMU to register backgroud I/O sections.

This patch therefore adds checks to xen_io_add/del so that sections with
memory-region ops pointing at 'unassigned_io_ops' are ignored.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <1462811480-16295-1-git-send-email-paul.durrant@citrix.com>
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 xen-hvm.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/xen-hvm.c b/xen-hvm.c
index c14e778..01ee25d 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -511,8 +511,13 @@ static void xen_io_add(MemoryListener *listener,
                        MemoryRegionSection *section)
 {
     XenIOState *state = container_of(listener, XenIOState, io_listener);
+    MemoryRegion *mr = section->mr;
 
-    memory_region_ref(section->mr);
+    if (mr->ops == &unassigned_io_ops) {
+        return;
+    }
+
+    memory_region_ref(mr);
 
     xen_map_io_section(xen_xc, xen_domid, state->ioservid, section);
 }
@@ -521,10 +526,15 @@ static void xen_io_del(MemoryListener *listener,
                        MemoryRegionSection *section)
 {
     XenIOState *state = container_of(listener, XenIOState, io_listener);
+    MemoryRegion *mr = section->mr;
+
+    if (mr->ops == &unassigned_io_ops) {
+        return;
+    }
 
     xen_unmap_io_section(xen_xc, xen_domid, state->ioservid, section);
 
-    memory_region_unref(section->mr);
+    memory_region_unref(mr);
 }
 
 static void xen_device_realize(DeviceListener *listener,
-- 
2.5.5

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

* [Qemu-devel] [PULL 22/31] scsi-disk: introduce a common base class
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (20 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 21/31] xen-hvm: ignore background I/O sections Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 23/31] scsi-disk: introduce dma_readv and dma_writev Paolo Bonzini
                   ` (9 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

This will be the place to add DMAIOFuncs in the next patch.  There
are also a couple DeviceClass members that can be moved to the
abstract class's initialization function.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/scsi-disk.c | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 8865da5..2d9dcde 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -53,6 +53,8 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 #define DEFAULT_MAX_UNMAP_SIZE      (1 << 30)   /* 1 GB */
 #define DEFAULT_MAX_IO_SIZE         INT_MAX     /* 2 GB - 1 block */
 
+#define TYPE_SCSI_DISK_BASE         "scsi-disk-base"
+
 typedef struct SCSIDiskState SCSIDiskState;
 
 typedef struct SCSIDiskReq {
@@ -2656,6 +2658,21 @@ static int scsi_block_parse_cdb(SCSIDevice *d, SCSICommand *cmd,
 
 #endif
 
+static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->fw_name = "disk";
+    dc->reset = scsi_disk_reset;
+}
+
+static const TypeInfo scsi_disk_base_info = {
+    .name          = TYPE_SCSI_DISK_BASE,
+    .parent        = TYPE_SCSI_DEVICE,
+    .class_init    = scsi_disk_base_class_initfn,
+    .instance_size = sizeof(SCSIDiskState),
+};
+
 #define DEFINE_SCSI_DISK_PROPERTIES()                                \
     DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),               \
     DEFINE_PROP_STRING("ver", SCSIDiskState, version),               \
@@ -2703,17 +2720,14 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
     sc->realize      = scsi_hd_realize;
     sc->alloc_req    = scsi_new_request;
     sc->unit_attention_reported = scsi_disk_unit_attention_reported;
-    dc->fw_name = "disk";
     dc->desc = "virtual SCSI disk";
-    dc->reset = scsi_disk_reset;
     dc->props = scsi_hd_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
 static const TypeInfo scsi_hd_info = {
     .name          = "scsi-hd",
-    .parent        = TYPE_SCSI_DEVICE,
-    .instance_size = sizeof(SCSIDiskState),
+    .parent        = TYPE_SCSI_DISK_BASE,
     .class_init    = scsi_hd_class_initfn,
 };
 
@@ -2735,17 +2749,14 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
     sc->realize      = scsi_cd_realize;
     sc->alloc_req    = scsi_new_request;
     sc->unit_attention_reported = scsi_disk_unit_attention_reported;
-    dc->fw_name = "disk";
     dc->desc = "virtual SCSI CD-ROM";
-    dc->reset = scsi_disk_reset;
     dc->props = scsi_cd_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
 static const TypeInfo scsi_cd_info = {
     .name          = "scsi-cd",
-    .parent        = TYPE_SCSI_DEVICE,
-    .instance_size = sizeof(SCSIDiskState),
+    .parent        = TYPE_SCSI_DISK_BASE,
     .class_init    = scsi_cd_class_initfn,
 };
 
@@ -2763,17 +2774,14 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
     sc->realize      = scsi_block_realize;
     sc->alloc_req    = scsi_block_new_request;
     sc->parse_cdb    = scsi_block_parse_cdb;
-    dc->fw_name = "disk";
     dc->desc = "SCSI block device passthrough";
-    dc->reset = scsi_disk_reset;
     dc->props = scsi_block_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
 }
 
 static const TypeInfo scsi_block_info = {
     .name          = "scsi-block",
-    .parent        = TYPE_SCSI_DEVICE,
-    .instance_size = sizeof(SCSIDiskState),
+    .parent        = TYPE_SCSI_DISK_BASE,
     .class_init    = scsi_block_class_initfn,
 };
 #endif
@@ -2811,13 +2819,13 @@ static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
 
 static const TypeInfo scsi_disk_info = {
     .name          = "scsi-disk",
-    .parent        = TYPE_SCSI_DEVICE,
-    .instance_size = sizeof(SCSIDiskState),
+    .parent        = TYPE_SCSI_DISK_BASE,
     .class_init    = scsi_disk_class_initfn,
 };
 
 static void scsi_disk_register_types(void)
 {
+    type_register_static(&scsi_disk_base_info);
     type_register_static(&scsi_hd_info);
     type_register_static(&scsi_cd_info);
 #ifdef __linux__
-- 
2.5.5

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

* [Qemu-devel] [PULL 23/31] scsi-disk: introduce dma_readv and dma_writev
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (21 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 22/31] scsi-disk: introduce a common base class Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 24/31] scsi-disk: add need_fua_emulation to SCSIDiskClass Paolo Bonzini
                   ` (8 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

These are replacements for blk_aio_readv and blk_aio_writev that allow
customization of the data path.  They reuse the DMA helpers' DMAIOFunc
callback type, so that the same function can be used in either the
QEMUSGList or the bounce-buffered case.

This customization will be needed in the next patch to do zero-copy
SG_IO on scsi-block.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/scsi-disk.c | 64 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 52 insertions(+), 12 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 2d9dcde..040d0c3 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -55,7 +55,21 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 
 #define TYPE_SCSI_DISK_BASE         "scsi-disk-base"
 
+#define SCSI_DISK_BASE(obj) \
+     OBJECT_CHECK(SCSIDiskState, (obj), TYPE_SCSI_DISK_BASE)
+#define SCSI_DISK_BASE_CLASS(klass) \
+     OBJECT_CLASS_CHECK(SCSIDiskClass, (klass), TYPE_SCSI_DISK_BASE)
+#define SCSI_DISK_BASE_GET_CLASS(obj) \
+     OBJECT_GET_CLASS(SCSIDiskClass, (obj), TYPE_SCSI_DISK_BASE)
+
 typedef struct SCSIDiskState SCSIDiskState;
+typedef struct SCSIDiskClass SCSIDiskClass;
+
+typedef struct SCSIDiskClass {
+    SCSIDeviceClass parent_class;
+    DMAIOFunc       *dma_readv;
+    DMAIOFunc       *dma_writev;
+} SCSIDiskClass;
 
 typedef struct SCSIDiskReq {
     SCSIRequest req;
@@ -317,6 +331,7 @@ done:
 static void scsi_do_read(SCSIDiskReq *r, int ret)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
 
     assert (r->req.aiocb == NULL);
 
@@ -337,16 +352,16 @@ static void scsi_do_read(SCSIDiskReq *r, int ret)
     if (r->req.sg) {
         dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BLOCK_ACCT_READ);
         r->req.resid -= r->req.sg->size;
-        r->req.aiocb = dma_blk_read(s->qdev.conf.blk, r->req.sg,
-                                    r->sector << BDRV_SECTOR_BITS,
-                                    scsi_dma_complete, r);
+        r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
+                                  r->req.sg, r->sector << BDRV_SECTOR_BITS,
+                                  sdc->dma_readv, r, scsi_dma_complete, r,
+                                  DMA_DIRECTION_FROM_DEVICE);
     } else {
         scsi_init_iovec(r, SCSI_DMA_BUF_SIZE);
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
                          r->qiov.size, BLOCK_ACCT_READ);
-        r->req.aiocb = blk_aio_preadv(s->qdev.conf.blk,
-                                      r->sector << BDRV_SECTOR_BITS, &r->qiov,
-                                      0, scsi_read_complete, r);
+        r->req.aiocb = sdc->dma_readv(r->sector, &r->qiov,
+                                      scsi_read_complete, r, r);
     }
 
 done:
@@ -506,6 +521,7 @@ static void scsi_write_data(SCSIRequest *req)
 {
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
 
     /* No data transfer may already be in progress */
     assert(r->req.aiocb == NULL);
@@ -542,15 +558,15 @@ static void scsi_write_data(SCSIRequest *req)
     if (r->req.sg) {
         dma_acct_start(s->qdev.conf.blk, &r->acct, r->req.sg, BLOCK_ACCT_WRITE);
         r->req.resid -= r->req.sg->size;
-        r->req.aiocb = dma_blk_write(s->qdev.conf.blk, r->req.sg,
-                                     r->sector << BDRV_SECTOR_BITS,
-                                     scsi_dma_complete, r);
+        r->req.aiocb = dma_blk_io(blk_get_aio_context(s->qdev.conf.blk),
+                                  r->req.sg, r->sector << BDRV_SECTOR_BITS,
+                                  sdc->dma_writev, r, scsi_dma_complete, r,
+                                  DMA_DIRECTION_TO_DEVICE);
     } else {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct,
                          r->qiov.size, BLOCK_ACCT_WRITE);
-        r->req.aiocb = blk_aio_pwritev(s->qdev.conf.blk,
-                                       r->sector << BDRV_SECTOR_BITS, &r->qiov,
-                                       0, scsi_write_complete, r);
+        r->req.aiocb = sdc->dma_writev(r->sector << BDRV_SECTOR_BITS, &r->qiov,
+                                       scsi_write_complete, r, r);
     }
 }
 
@@ -2658,12 +2674,35 @@ static int scsi_block_parse_cdb(SCSIDevice *d, SCSICommand *cmd,
 
 #endif
 
+static
+BlockAIOCB *scsi_dma_readv(int64_t offset, QEMUIOVector *iov,
+                           BlockCompletionFunc *cb, void *cb_opaque,
+                           void *opaque)
+{
+    SCSIDiskReq *r = opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+    return blk_aio_preadv(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
+}
+
+static
+BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov,
+                            BlockCompletionFunc *cb, void *cb_opaque,
+                            void *opaque)
+{
+    SCSIDiskReq *r = opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+    return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque);
+}
+
 static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass);
 
     dc->fw_name = "disk";
     dc->reset = scsi_disk_reset;
+    sdc->dma_readv = scsi_dma_readv;
+    sdc->dma_writev = scsi_dma_writev;
 }
 
 static const TypeInfo scsi_disk_base_info = {
@@ -2671,6 +2710,7 @@ static const TypeInfo scsi_disk_base_info = {
     .parent        = TYPE_SCSI_DEVICE,
     .class_init    = scsi_disk_base_class_initfn,
     .instance_size = sizeof(SCSIDiskState),
+    .class_size    = sizeof(SCSIDiskClass),
 };
 
 #define DEFINE_SCSI_DISK_PROPERTIES()                                \
-- 
2.5.5

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

* [Qemu-devel] [PULL 24/31] scsi-disk: add need_fua_emulation to SCSIDiskClass
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (22 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 23/31] scsi-disk: introduce dma_readv and dma_writev Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 25/31] scsi-disk: introduce scsi_disk_req_check_error Paolo Bonzini
                   ` (7 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

scsi-block will be able to do FUA just by passing the request through
to the LUN (which is also more efficient); there is no need to emulate
it like we do for scsi-disk.

Add a new method to distinguish this.

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

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 040d0c3..7c5c1c0 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -69,6 +69,7 @@ typedef struct SCSIDiskClass {
     SCSIDeviceClass parent_class;
     DMAIOFunc       *dma_readv;
     DMAIOFunc       *dma_writev;
+    bool            (*need_fua_emulation)(SCSICommand *cmd);
 } SCSIDiskClass;
 
 typedef struct SCSIDiskReq {
@@ -78,6 +79,7 @@ typedef struct SCSIDiskReq {
     uint32_t sector_count;
     uint32_t buflen;
     bool started;
+    bool need_fua_emulation;
     struct iovec iov;
     QEMUIOVector qiov;
     BlockAcctCookie acct;
@@ -239,7 +241,7 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
         goto done;
     }
 
-    if (scsi_is_cmd_fua(&r->req.cmd)) {
+    if (r->need_fua_emulation) {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
                          BLOCK_ACCT_FLUSH);
         r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r);
@@ -416,7 +418,7 @@ static void scsi_read_data(SCSIRequest *req)
 
     first = !r->started;
     r->started = true;
-    if (first && scsi_is_cmd_fua(&r->req.cmd)) {
+    if (first && r->need_fua_emulation) {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
                          BLOCK_ACCT_FLUSH);
         r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read_cb, r);
@@ -2156,6 +2158,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
 {
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
+    SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
     uint32_t len;
     uint8_t command;
 
@@ -2214,6 +2217,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
         scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
         return 0;
     }
+    r->need_fua_emulation = sdc->need_fua_emulation(&r->req.cmd);
     if (r->sector_count == 0) {
         scsi_req_complete(&r->req, GOOD);
     }
@@ -2703,6 +2707,7 @@ static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data)
     dc->reset = scsi_disk_reset;
     sdc->dma_readv = scsi_dma_readv;
     sdc->dma_writev = scsi_dma_writev;
+    sdc->need_fua_emulation = scsi_is_cmd_fua;
 }
 
 static const TypeInfo scsi_disk_base_info = {
-- 
2.5.5

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

* [Qemu-devel] [PULL 25/31] scsi-disk: introduce scsi_disk_req_check_error
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (23 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 24/31] scsi-disk: add need_fua_emulation to SCSIDiskClass Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 26/31] scsi-block: always use SG_IO Paolo Bonzini
                   ` (6 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

Commonize all the checks for canceled requests and errors.  The next patch
will add another case to check for, in order to handle passthrough commands.

There is no semantic change here; the only nontrivial modification is in
scsi_write_do_fua, where cancellation has been checked earlier by both
callers.  Thus, the check is replaced with an assertion.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/scsi-disk.c | 89 +++++++++++++----------------------------------------
 1 file changed, 22 insertions(+), 67 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 7c5c1c0..1095263 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -179,6 +179,20 @@ static void scsi_disk_load_request(QEMUFile *f, SCSIRequest *req)
     qemu_iovec_init_external(&r->qiov, &r->iov, 1);
 }
 
+static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed)
+{
+    if (r->req.io_canceled) {
+        scsi_req_cancel_complete(&r->req);
+        return true;
+    }
+
+    if (ret < 0) {
+        return scsi_handle_rw_error(r, -ret, acct_failed);
+    }
+
+    return false;
+}
+
 static void scsi_aio_complete(void *opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
@@ -186,17 +200,10 @@ static void scsi_aio_complete(void *opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
+    if (scsi_disk_req_check_error(r, ret, true)) {
         goto done;
     }
 
-    if (ret < 0) {
-        if (scsi_handle_rw_error(r, -ret, true)) {
-            goto done;
-        }
-    }
-
     block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
     scsi_req_complete(&r->req, GOOD);
 
@@ -235,11 +242,7 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
 
     assert(r->req.aiocb == NULL);
-
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
-        goto done;
-    }
+    assert(!r->req.io_canceled);
 
     if (r->need_fua_emulation) {
         block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0,
@@ -249,26 +252,16 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
     }
 
     scsi_req_complete(&r->req, GOOD);
-
-done:
     scsi_req_unref(&r->req);
 }
 
 static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret)
 {
     assert(r->req.aiocb == NULL);
-
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
+    if (scsi_disk_req_check_error(r, ret, false)) {
         goto done;
     }
 
-    if (ret < 0) {
-        if (scsi_handle_rw_error(r, -ret, false)) {
-            goto done;
-        }
-    }
-
     r->sector += r->sector_count;
     r->sector_count = 0;
     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
@@ -306,17 +299,10 @@ static void scsi_read_complete(void * opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
+    if (scsi_disk_req_check_error(r, ret, true)) {
         goto done;
     }
 
-    if (ret < 0) {
-        if (scsi_handle_rw_error(r, -ret, true)) {
-            goto done;
-        }
-    }
-
     block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
     DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size);
 
@@ -336,18 +322,10 @@ static void scsi_do_read(SCSIDiskReq *r, int ret)
     SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
 
     assert (r->req.aiocb == NULL);
-
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
+    if (scsi_disk_req_check_error(r, ret, false)) {
         goto done;
     }
 
-    if (ret < 0) {
-        if (scsi_handle_rw_error(r, -ret, false)) {
-            goto done;
-        }
-    }
-
     /* The request is used as the AIO opaque value, so add a ref.  */
     scsi_req_ref(&r->req);
 
@@ -475,18 +453,10 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
     uint32_t n;
 
     assert (r->req.aiocb == NULL);
-
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
+    if (scsi_disk_req_check_error(r, ret, false)) {
         goto done;
     }
 
-    if (ret < 0) {
-        if (scsi_handle_rw_error(r, -ret, false)) {
-            goto done;
-        }
-    }
-
     n = r->qiov.size / 512;
     r->sector += n;
     r->sector_count -= n;
@@ -1620,18 +1590,10 @@ static void scsi_unmap_complete_noio(UnmapCBData *data, int ret)
     uint32_t nb_sectors;
 
     assert(r->req.aiocb == NULL);
-
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
+    if (scsi_disk_req_check_error(r, ret, false)) {
         goto done;
     }
 
-    if (ret < 0) {
-        if (scsi_handle_rw_error(r, -ret, false)) {
-            goto done;
-        }
-    }
-
     if (data->count > 0) {
         sector_num = ldq_be_p(&data->inbuf[0]);
         nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
@@ -1731,17 +1693,10 @@ static void scsi_write_same_complete(void *opaque, int ret)
 
     assert(r->req.aiocb != NULL);
     r->req.aiocb = NULL;
-    if (r->req.io_canceled) {
-        scsi_req_cancel_complete(&r->req);
+    if (scsi_disk_req_check_error(r, ret, true)) {
         goto done;
     }
 
-    if (ret < 0) {
-        if (scsi_handle_rw_error(r, -ret, true)) {
-            goto done;
-        }
-    }
-
     block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
 
     data->nb_sectors -= data->iov.iov_len / 512;
-- 
2.5.5

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

* [Qemu-devel] [PULL 26/31] scsi-block: always use SG_IO
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (24 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 25/31] scsi-disk: introduce scsi_disk_req_check_error Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 27/31] scsi-generic: Merge block max xfer len in INQUIRY response Paolo Bonzini
                   ` (5 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

Using pread/pwrite or io_submit has the advantage of eliminating the
bounce buffer, but drops the SCSI status.  This keeps the guest from
seeing unit attention codes, as well as statuses such as RESERVATION
CONFLICT.  Because we know scsi-block operates on an SBC device we can
still use the DMA helpers with SG_IO; just remember to patch the CDBs
if the transfer is split into multiple segments.

This means that scsi-block will always use the thread-pool unfortunately,
instead of respecting aio=native.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/scsi-disk.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 196 insertions(+), 18 deletions(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 1095263..df49164 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -83,6 +83,7 @@ typedef struct SCSIDiskReq {
     struct iovec iov;
     QEMUIOVector qiov;
     BlockAcctCookie acct;
+    unsigned char *status;
 } SCSIDiskReq;
 
 #define SCSI_DISK_F_REMOVABLE             0
@@ -190,6 +191,15 @@ static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_failed)
         return scsi_handle_rw_error(r, -ret, acct_failed);
     }
 
+    if (r->status && *r->status) {
+        if (acct_failed) {
+            SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+            block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
+        }
+        scsi_req_complete(&r->req, *r->status);
+        return true;
+    }
+
     return false;
 }
 
@@ -2555,16 +2565,145 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp)
     scsi_generic_read_device_identification(&s->qdev);
 }
 
+typedef struct SCSIBlockReq {
+    SCSIDiskReq req;
+    sg_io_hdr_t io_header;
+
+    /* Selected bytes of the original CDB, copied into our own CDB.  */
+    uint8_t cmd, cdb1, group_number;
+
+    /* CDB passed to SG_IO.  */
+    uint8_t cdb[16];
+} SCSIBlockReq;
+
+static BlockAIOCB *scsi_block_do_sgio(SCSIBlockReq *req,
+                                      int64_t offset, QEMUIOVector *iov,
+                                      int direction,
+                                      BlockCompletionFunc *cb, void *opaque)
+{
+    sg_io_hdr_t *io_header = &req->io_header;
+    SCSIDiskReq *r = &req->req;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+    int nb_logical_blocks;
+    uint64_t lba;
+    BlockAIOCB *aiocb;
+
+    /* This is not supported yet.  It can only happen if the guest does
+     * reads and writes that are not aligned to one logical sectors
+     * _and_ cover multiple MemoryRegions.
+     */
+    assert(offset % s->qdev.blocksize == 0);
+    assert(iov->size % s->qdev.blocksize == 0);
+
+    io_header->interface_id = 'S';
+
+    /* The data transfer comes from the QEMUIOVector.  */
+    io_header->dxfer_direction = direction;
+    io_header->dxfer_len = iov->size;
+    io_header->dxferp = (void *)iov->iov;
+    io_header->iovec_count = iov->niov;
+    assert(io_header->iovec_count == iov->niov); /* no overflow! */
+
+    /* Build a new CDB with the LBA and length patched in, in case
+     * DMA helpers split the transfer in multiple segments.  Do not
+     * build a CDB smaller than what the guest wanted, and only build
+     * a larger one if strictly necessary.
+     */
+    io_header->cmdp = req->cdb;
+    lba = offset / s->qdev.blocksize;
+    nb_logical_blocks = io_header->dxfer_len / s->qdev.blocksize;
+
+    if ((req->cmd >> 5) == 0 && lba <= 0x1ffff) {
+        /* 6-byte CDB */
+        stl_be_p(&req->cdb[0], lba | (req->cmd << 24));
+        req->cdb[4] = nb_logical_blocks;
+        req->cdb[5] = 0;
+        io_header->cmd_len = 6;
+    } else if ((req->cmd >> 5) <= 1 && lba <= 0xffffffffULL) {
+        /* 10-byte CDB */
+        req->cdb[0] = (req->cmd & 0x1f) | 0x20;
+        req->cdb[1] = req->cdb1;
+        stl_be_p(&req->cdb[2], lba);
+        req->cdb[6] = req->group_number;
+        stw_be_p(&req->cdb[7], nb_logical_blocks);
+        req->cdb[9] = 0;
+        io_header->cmd_len = 10;
+    } else if ((req->cmd >> 5) != 4 && lba <= 0xffffffffULL) {
+        /* 12-byte CDB */
+        req->cdb[0] = (req->cmd & 0x1f) | 0xA0;
+        req->cdb[1] = req->cdb1;
+        stl_be_p(&req->cdb[2], lba);
+        stl_be_p(&req->cdb[6], nb_logical_blocks);
+        req->cdb[10] = req->group_number;
+        req->cdb[11] = 0;
+        io_header->cmd_len = 12;
+    } else {
+        /* 16-byte CDB */
+        req->cdb[0] = (req->cmd & 0x1f) | 0x80;
+        req->cdb[1] = req->cdb1;
+        stq_be_p(&req->cdb[2], lba);
+        stl_be_p(&req->cdb[10], nb_logical_blocks);
+        req->cdb[14] = req->group_number;
+        req->cdb[15] = 0;
+        io_header->cmd_len = 16;
+    }
+
+    /* The rest is as in scsi-generic.c.  */
+    io_header->mx_sb_len = sizeof(r->req.sense);
+    io_header->sbp = r->req.sense;
+    io_header->timeout = UINT_MAX;
+    io_header->usr_ptr = r;
+    io_header->flags |= SG_FLAG_DIRECT_IO;
+
+    aiocb = blk_aio_ioctl(s->qdev.conf.blk, SG_IO, io_header, cb, opaque);
+    assert(aiocb != NULL);
+    return aiocb;
+}
+
+static bool scsi_block_no_fua(SCSICommand *cmd)
+{
+    return false;
+}
+
+static BlockAIOCB *scsi_block_dma_readv(int64_t offset,
+                                        QEMUIOVector *iov,
+                                        BlockCompletionFunc *cb, void *cb_opaque,
+                                        void *opaque)
+{
+    SCSIBlockReq *r = opaque;
+    return scsi_block_do_sgio(r, offset, iov,
+                              SG_DXFER_FROM_DEV, cb, cb_opaque);
+}
+
+static BlockAIOCB *scsi_block_dma_writev(int64_t offset,
+                                         QEMUIOVector *iov,
+                                         BlockCompletionFunc *cb, void *cb_opaque,
+                                         void *opaque)
+{
+    SCSIBlockReq *r = opaque;
+    return scsi_block_do_sgio(r, offset, iov,
+                              SG_DXFER_TO_DEV, cb, cb_opaque);
+}
+
 static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
 {
     switch (buf[0]) {
+    case VERIFY_10:
+    case VERIFY_12:
+    case VERIFY_16:
+        /* Check if BYTCHK == 0x01 (data-out buffer contains data
+         * for the number of logical blocks specified in the length
+         * field).  For other modes, do not use scatter/gather operation.
+         */
+        if ((buf[1] & 6) != 2) {
+            return false;
+        }
+        break;
+
     case READ_6:
     case READ_10:
     case READ_12:
     case READ_16:
-    case VERIFY_10:
-    case VERIFY_12:
-    case VERIFY_16:
     case WRITE_6:
     case WRITE_10:
     case WRITE_12:
@@ -2572,21 +2711,8 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
     case WRITE_VERIFY_10:
     case WRITE_VERIFY_12:
     case WRITE_VERIFY_16:
-        /* If we are not using O_DIRECT, we might read stale data from the
-         * host cache if writes were made using other commands than these
-         * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without
-         * O_DIRECT everything must go through SG_IO.
-         */
-        if (!(blk_get_flags(s->qdev.conf.blk) & BDRV_O_NOCACHE)) {
-            break;
-        }
-
-        /* MMC writing cannot be done via pread/pwrite, because it sometimes
+        /* MMC writing cannot be done via DMA helpers, because it sometimes
          * involves writing beyond the maximum LBA or to negative LBA (lead-in).
-         * And once you do these writes, reading from the block device is
-         * unreliable, too.  It is even possible that reads deliver random data
-         * from the host page cache (this is probably a Linux bug).
-         *
          * We might use scsi_disk_dma_reqops as long as no writing commands are
          * seen, but performance usually isn't paramount on optical media.  So,
          * just make scsi-block operate the same as scsi-generic for them.
@@ -2604,6 +2730,54 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
 }
 
 
+static int32_t scsi_block_dma_command(SCSIRequest *req, uint8_t *buf)
+{
+    SCSIBlockReq *r = (SCSIBlockReq *)req;
+    r->cmd = req->cmd.buf[0];
+    switch (r->cmd >> 5) {
+    case 0:
+        /* 6-byte CDB.  */
+        r->cdb1 = r->group_number = 0;
+        break;
+    case 1:
+        /* 10-byte CDB.  */
+        r->cdb1 = req->cmd.buf[1];
+        r->group_number = req->cmd.buf[6];
+    case 4:
+        /* 12-byte CDB.  */
+        r->cdb1 = req->cmd.buf[1];
+        r->group_number = req->cmd.buf[10];
+        break;
+    case 5:
+        /* 16-byte CDB.  */
+        r->cdb1 = req->cmd.buf[1];
+        r->group_number = req->cmd.buf[14];
+        break;
+    default:
+        abort();
+    }
+
+    if (r->cdb1 & 0xe0) {
+        /* Protection information is not supported.  */
+        scsi_check_condition(&r->req, SENSE_CODE(INVALID_FIELD));
+        return 0;
+    }
+
+    r->req.status = &r->io_header.status;
+    return scsi_disk_dma_command(req, buf);
+}
+
+static const SCSIReqOps scsi_block_dma_reqops = {
+    .size         = sizeof(SCSIBlockReq),
+    .free_req     = scsi_free_request,
+    .send_command = scsi_block_dma_command,
+    .read_data    = scsi_read_data,
+    .write_data   = scsi_write_data,
+    .get_buf      = scsi_get_buf,
+    .load_request = scsi_disk_load_request,
+    .save_request = scsi_disk_save_request,
+};
+
 static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
                                            uint32_t lun, uint8_t *buf,
                                            void *hba_private)
@@ -2614,7 +2788,7 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
         return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,
                               hba_private);
     } else {
-        return scsi_req_alloc(&scsi_disk_dma_reqops, &s->qdev, tag, lun,
+        return scsi_req_alloc(&scsi_block_dma_reqops, &s->qdev, tag, lun,
                               hba_private);
     }
 }
@@ -2770,10 +2944,14 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
+    SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass);
 
     sc->realize      = scsi_block_realize;
     sc->alloc_req    = scsi_block_new_request;
     sc->parse_cdb    = scsi_block_parse_cdb;
+    sdc->dma_readv   = scsi_block_dma_readv;
+    sdc->dma_writev  = scsi_block_dma_writev;
+    sdc->need_fua_emulation = scsi_block_no_fua;
     dc->desc = "SCSI block device passthrough";
     dc->props = scsi_block_properties;
     dc->vmsd  = &vmstate_scsi_disk_state;
-- 
2.5.5

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

* [Qemu-devel] [PULL 27/31] scsi-generic: Merge block max xfer len in INQUIRY response
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (25 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 26/31] scsi-block: always use SG_IO Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 28/31] memory: remove qemu_get_ram_fd, qemu_set_ram_fd, qemu_ram_block_host_ptr Paolo Bonzini
                   ` (4 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: Fam Zheng

From: Fam Zheng <famz@redhat.com>

The rationale is similar to the above mode sense response interception:
this is practically the only channel to communicate restraints from
elsewhere such as host and block driver.

The scsi bus we attach onto can have a larger max xfer len than what is
accepted by the host file system (guarding between the host scsi LUN and
QEMU), in which case the SG_IO we generate would get -EINVAL.

Signed-off-by: Fam Zheng <famz@redhat.com>
Message-Id: <1464243305-10661-3-git-send-email-famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi/scsi-generic.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 7459465..71372a8 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -222,6 +222,18 @@ static void scsi_read_complete(void * opaque, int ret)
             r->buf[3] |= 0x80;
         }
     }
+    if (s->type == TYPE_DISK &&
+        r->req.cmd.buf[0] == INQUIRY &&
+        r->req.cmd.buf[2] == 0xb0) {
+        uint32_t max_xfer_len = blk_get_max_transfer_length(s->conf.blk);
+        if (max_xfer_len) {
+            stl_be_p(&r->buf[8], max_xfer_len);
+            /* Also take care of the opt xfer len. */
+            if (ldl_be_p(&r->buf[12]) > max_xfer_len) {
+                stl_be_p(&r->buf[12], max_xfer_len);
+            }
+        }
+    }
     scsi_req_data(&r->req, len);
     scsi_req_unref(&r->req);
 }
-- 
2.5.5

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

* [Qemu-devel] [PULL 28/31] memory: remove qemu_get_ram_fd, qemu_set_ram_fd, qemu_ram_block_host_ptr
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (26 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 27/31] scsi-generic: Merge block max xfer len in INQUIRY response Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 29/31] exec: remove ram_addr argument from qemu_ram_block_from_host Paolo Bonzini
                   ` (3 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

Remove direct uses of ram_addr_t and optimize memory_region_{get,set}_fd
now that a MemoryRegion knows its RAMBlock directly.

Reviewed-by: Marc-André Lureau <marcandre.lureau@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c                  | 34 ----------------------------------
 hw/misc/ivshmem.c       |  5 ++---
 hw/virtio/vhost-user.c  | 15 +++++++--------
 include/exec/memory.h   | 11 +++++++++++
 include/exec/ram_addr.h |  3 ---
 memory.c                | 21 +++++++++++++++++----
 6 files changed, 37 insertions(+), 52 deletions(-)

diff --git a/exec.c b/exec.c
index a3a93ae..3330e7d 100644
--- a/exec.c
+++ b/exec.c
@@ -1815,40 +1815,6 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 }
 #endif /* !_WIN32 */
 
-int qemu_get_ram_fd(ram_addr_t addr)
-{
-    RAMBlock *block;
-    int fd;
-
-    rcu_read_lock();
-    block = qemu_get_ram_block(addr);
-    fd = block->fd;
-    rcu_read_unlock();
-    return fd;
-}
-
-void qemu_set_ram_fd(ram_addr_t addr, int fd)
-{
-    RAMBlock *block;
-
-    rcu_read_lock();
-    block = qemu_get_ram_block(addr);
-    block->fd = fd;
-    rcu_read_unlock();
-}
-
-void *qemu_get_ram_block_host_ptr(ram_addr_t addr)
-{
-    RAMBlock *block;
-    void *ptr;
-
-    rcu_read_lock();
-    block = qemu_get_ram_block(addr);
-    ptr = ramblock_ptr(block, 0);
-    rcu_read_unlock();
-    return ptr;
-}
-
 /* Return a host pointer to ram allocated with qemu_ram_alloc.
  * This should not be used for general purpose DMA.  Use address_space_map
  * or address_space_rw instead. For local memory (e.g. video ram) that the
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index e40f23b..90be9f7 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -33,7 +33,6 @@
 #include "sysemu/hostmem.h"
 #include "sysemu/qtest.h"
 #include "qapi/visitor.h"
-#include "exec/ram_addr.h"
 
 #include "hw/misc/ivshmem.h"
 
@@ -533,7 +532,7 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp)
     }
     memory_region_init_ram_ptr(&s->server_bar2, OBJECT(s),
                                "ivshmem.bar2", size, ptr);
-    qemu_set_ram_fd(memory_region_get_ram_addr(&s->server_bar2), fd);
+    memory_region_set_fd(&s->server_bar2, fd);
     s->ivshmem_bar2 = &s->server_bar2;
 }
 
@@ -940,7 +939,7 @@ static void ivshmem_exit(PCIDevice *dev)
                              strerror(errno));
             }
 
-            fd = qemu_get_ram_fd(memory_region_get_ram_addr(s->ivshmem_bar2));
+            fd = memory_region_get_fd(s->ivshmem_bar2);
             close(fd);
         }
 
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 5914e85..41908c0 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -248,17 +248,18 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
     for (i = 0; i < dev->mem->nregions; ++i) {
         struct vhost_memory_region *reg = dev->mem->regions + i;
         ram_addr_t ram_addr;
+        MemoryRegion *mr;
 
         assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
-        qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
-                                &ram_addr);
-        fd = qemu_get_ram_fd(ram_addr);
+        mr = qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
+                                     &ram_addr);
+        fd = memory_region_get_fd(mr);
         if (fd > 0) {
             msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
             msg.payload.memory.regions[fd_num].memory_size  = reg->memory_size;
             msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
             msg.payload.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
-                (uintptr_t) qemu_get_ram_block_host_ptr(ram_addr);
+                (uintptr_t) memory_region_get_ram_ptr(mr);
             assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
             fds[fd_num++] = fd;
         }
@@ -621,12 +622,10 @@ static bool vhost_user_can_merge(struct vhost_dev *dev,
     MemoryRegion *mr;
 
     mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
-    assert(mr);
-    mfd = qemu_get_ram_fd(ram_addr);
+    mfd = memory_region_get_fd(mr);
 
     mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
-    assert(mr);
-    rfd = qemu_get_ram_fd(ram_addr);
+    rfd = memory_region_get_fd(mr);
 
     return mfd == rfd;
 }
diff --git a/include/exec/memory.h b/include/exec/memory.h
index f649697..1678494 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -667,6 +667,17 @@ static inline bool memory_region_is_rom(MemoryRegion *mr)
 int memory_region_get_fd(MemoryRegion *mr);
 
 /**
+ * memory_region_set_fd: Mark a RAM memory region as backed by a
+ * file descriptor.
+ *
+ * This function is typically used after memory_region_init_ram_ptr().
+ *
+ * @mr: the memory region being queried.
+ * @fd: the file descriptor that backs @mr.
+ */
+void memory_region_set_fd(MemoryRegion *mr, int fd);
+
+/**
  * memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
  *
  * Returns a host pointer to a RAM memory region (created with
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 5b6e1b8..2a9465d 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -105,9 +105,6 @@ RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
                                                     uint64_t length,
                                                     void *host),
                                     MemoryRegion *mr, Error **errp);
-int qemu_get_ram_fd(ram_addr_t addr);
-void qemu_set_ram_fd(ram_addr_t addr, int fd);
-void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
 void qemu_ram_free(RAMBlock *block);
 
 int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
diff --git a/memory.c b/memory.c
index 0f52522..d6a4a68 100644
--- a/memory.c
+++ b/memory.c
@@ -1626,13 +1626,26 @@ void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
 
 int memory_region_get_fd(MemoryRegion *mr)
 {
-    if (mr->alias) {
-        return memory_region_get_fd(mr->alias);
+    int fd;
+
+    rcu_read_lock();
+    while (mr->alias) {
+        mr = mr->alias;
     }
+    fd = mr->ram_block->fd;
+    rcu_read_unlock();
 
-    assert(mr->ram_block);
+    return fd;
+}
 
-    return qemu_get_ram_fd(memory_region_get_ram_addr(mr));
+void memory_region_set_fd(MemoryRegion *mr, int fd)
+{
+    rcu_read_lock();
+    while (mr->alias) {
+        mr = mr->alias;
+    }
+    mr->ram_block->fd = fd;
+    rcu_read_unlock();
 }
 
 void *memory_region_get_ram_ptr(MemoryRegion *mr)
-- 
2.5.5

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

* [Qemu-devel] [PULL 29/31] exec: remove ram_addr argument from qemu_ram_block_from_host
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (27 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 28/31] memory: remove qemu_get_ram_fd, qemu_set_ram_fd, qemu_ram_block_host_ptr Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 30/31] memory: split memory_region_from_host from qemu_ram_addr_from_host Paolo Bonzini
                   ` (2 subsequent siblings)
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

Of the two callers, one does not use it, and the other can compute
it itself based on the other output argument (offset) and the RAMBlock.

Reviewed-by: Marc-André Lureau <marcandre.lureau@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c                    | 13 ++++++-------
 include/exec/cpu-common.h |  2 +-
 migration/postcopy-ram.c  |  3 +--
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/exec.c b/exec.c
index 3330e7d..65bad53 100644
--- a/exec.c
+++ b/exec.c
@@ -1897,16 +1897,16 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
  * ram_addr_t.
  */
 RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
-                                   ram_addr_t *ram_addr,
                                    ram_addr_t *offset)
 {
     RAMBlock *block;
     uint8_t *host = ptr;
 
     if (xen_enabled()) {
+        ram_addr_t ram_addr;
         rcu_read_lock();
-        *ram_addr = xen_ram_addr_from_mapcache(ptr);
-        block = qemu_get_ram_block(*ram_addr);
+        ram_addr = xen_ram_addr_from_mapcache(ptr);
+        block = qemu_get_ram_block(ram_addr);
         if (block) {
             *offset = (host - block->host);
         }
@@ -1938,7 +1938,6 @@ found:
     if (round_offset) {
         *offset &= TARGET_PAGE_MASK;
     }
-    *ram_addr = block->offset + *offset;
     rcu_read_unlock();
     return block;
 }
@@ -1968,10 +1967,10 @@ RAMBlock *qemu_ram_block_by_name(const char *name)
 MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
     RAMBlock *block;
-    ram_addr_t offset; /* Not used */
-
-    block = qemu_ram_block_from_host(ptr, false, ram_addr, &offset);
+    ram_addr_t offset;
 
+    block = qemu_ram_block_from_host(ptr, false, &offset);
+    *ram_addr = block->offset + offset;
     if (!block) {
         return NULL;
     }
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index a2c3b92..fc609ad 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -60,7 +60,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
 RAMBlock *qemu_ram_block_by_name(const char *name);
 RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
-                                   ram_addr_t *ram_addr, ram_addr_t *offset);
+                                   ram_addr_t *offset);
 void qemu_ram_set_idstr(RAMBlock *block, const char *name, DeviceState *dev);
 void qemu_ram_unset_idstr(RAMBlock *block);
 const char *qemu_ram_get_idstr(RAMBlock *rb);
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index fbd0064..cf7dcd2 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -407,7 +407,6 @@ static void *postcopy_ram_fault_thread(void *opaque)
 
     while (true) {
         ram_addr_t rb_offset;
-        ram_addr_t in_raspace;
         struct pollfd pfd[2];
 
         /*
@@ -459,7 +458,7 @@ static void *postcopy_ram_fault_thread(void *opaque)
 
         rb = qemu_ram_block_from_host(
                  (void *)(uintptr_t)msg.arg.pagefault.address,
-                 true, &in_raspace, &rb_offset);
+                 true, &rb_offset);
         if (!rb) {
             error_report("postcopy_ram_fault_thread: Fault outside guest: %"
                          PRIx64, (uint64_t)msg.arg.pagefault.address);
-- 
2.5.5

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

* [Qemu-devel] [PULL 30/31] memory: split memory_region_from_host from qemu_ram_addr_from_host
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (28 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 29/31] exec: remove ram_addr argument from qemu_ram_block_from_host Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 10:06 ` [Qemu-devel] [PULL 31/31] exec: hide mr->ram_addr from qemu_get_ram_ptr users Paolo Bonzini
  2016-05-27 12:53 ` [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Peter Maydell
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

Move the old qemu_ram_addr_from_host to memory_region_from_host and
make it return an offset within the region.  For qemu_ram_addr_from_host
return the ram_addr_t directly, similar to what it was before
commit 1b5ec23 ("memory: return MemoryRegion from qemu_ram_addr_from_host",
2013-07-04).

Reviewed-by: Marc-André Lureau <marcandre.lureau@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cputlb.c                  |  3 ++-
 exec.c                    | 10 +++++-----
 hw/virtio/vhost-user.c    | 16 +++++++---------
 include/exec/cpu-common.h |  2 +-
 include/exec/memory.h     | 20 ++++++++++++++++++++
 memory.c                  | 14 ++++++++++++--
 target-i386/kvm.c         |  6 ++++--
 7 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 1ff6354..23c9b91 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -246,7 +246,8 @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
 {
     ram_addr_t ram_addr;
 
-    if (qemu_ram_addr_from_host(ptr, &ram_addr) == NULL) {
+    ram_addr = qemu_ram_addr_from_host(ptr);
+    if (ram_addr == RAM_ADDR_INVALID) {
         fprintf(stderr, "Bad ram pointer %p\n", ptr);
         abort();
     }
diff --git a/exec.c b/exec.c
index 65bad53..7f62835 100644
--- a/exec.c
+++ b/exec.c
@@ -1964,18 +1964,17 @@ RAMBlock *qemu_ram_block_by_name(const char *name)
 
 /* Some of the softmmu routines need to translate from a host pointer
    (typically a TLB entry) back to a ram offset.  */
-MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
+ram_addr_t qemu_ram_addr_from_host(void *ptr)
 {
     RAMBlock *block;
     ram_addr_t offset;
 
     block = qemu_ram_block_from_host(ptr, false, &offset);
-    *ram_addr = block->offset + offset;
     if (!block) {
-        return NULL;
+        return RAM_ADDR_INVALID;
     }
 
-    return block->mr;
+    return block->offset + offset;
 }
 
 /* Called within RCU critical section.  */
@@ -2975,8 +2974,9 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
         MemoryRegion *mr;
         ram_addr_t addr1;
 
-        mr = qemu_ram_addr_from_host(buffer, &addr1);
+        mr = memory_region_from_host(buffer, &addr1);
         assert(mr != NULL);
+        addr1 += memory_region_get_ram_addr(mr);
         if (is_write) {
             invalidate_and_set_dirty(mr, addr1, access_len);
         }
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 41908c0..495e09f 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -17,7 +17,6 @@
 #include "sysemu/kvm.h"
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
-#include "exec/ram_addr.h"
 #include "migration/migration.h"
 
 #include <sys/ioctl.h>
@@ -247,19 +246,18 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
 
     for (i = 0; i < dev->mem->nregions; ++i) {
         struct vhost_memory_region *reg = dev->mem->regions + i;
-        ram_addr_t ram_addr;
+        ram_addr_t offset;
         MemoryRegion *mr;
 
         assert((uintptr_t)reg->userspace_addr == reg->userspace_addr);
-        mr = qemu_ram_addr_from_host((void *)(uintptr_t)reg->userspace_addr,
-                                     &ram_addr);
+        mr = memory_region_from_host((void *)(uintptr_t)reg->userspace_addr,
+                                     &offset);
         fd = memory_region_get_fd(mr);
         if (fd > 0) {
             msg.payload.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
             msg.payload.memory.regions[fd_num].memory_size  = reg->memory_size;
             msg.payload.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr;
-            msg.payload.memory.regions[fd_num].mmap_offset = reg->userspace_addr -
-                (uintptr_t) memory_region_get_ram_ptr(mr);
+            msg.payload.memory.regions[fd_num].mmap_offset = offset;
             assert(fd_num < VHOST_MEMORY_MAX_NREGIONS);
             fds[fd_num++] = fd;
         }
@@ -617,14 +615,14 @@ static bool vhost_user_can_merge(struct vhost_dev *dev,
                                  uint64_t start1, uint64_t size1,
                                  uint64_t start2, uint64_t size2)
 {
-    ram_addr_t ram_addr;
+    ram_addr_t offset;
     int mfd, rfd;
     MemoryRegion *mr;
 
-    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start1, &ram_addr);
+    mr = memory_region_from_host((void *)(uintptr_t)start1, &offset);
     mfd = memory_region_get_fd(mr);
 
-    mr = qemu_ram_addr_from_host((void *)(uintptr_t)start2, &ram_addr);
+    mr = memory_region_from_host((void *)(uintptr_t)start2, &offset);
     rfd = memory_region_get_fd(mr);
 
     return mfd == rfd;
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index fc609ad..aaee995 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -57,7 +57,7 @@ typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
 
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should not be used by devices.  */
-MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
+ram_addr_t qemu_ram_addr_from_host(void *ptr);
 RAMBlock *qemu_ram_block_by_name(const char *name);
 RAMBlock *qemu_ram_block_from_host(void *ptr, bool round_offset,
                                    ram_addr_t *offset);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 1678494..71a27ab 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -32,6 +32,8 @@
 #include "qom/object.h"
 #include "qemu/rcu.h"
 
+#define RAM_ADDR_INVALID (~(ram_addr_t)0)
+
 #define MAX_PHYS_ADDR_SPACE_BITS 62
 #define MAX_PHYS_ADDR            (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1)
 
@@ -678,6 +680,24 @@ int memory_region_get_fd(MemoryRegion *mr);
 void memory_region_set_fd(MemoryRegion *mr, int fd);
 
 /**
+ * memory_region_from_host: Convert a pointer into a RAM memory region
+ * and an offset within it.
+ *
+ * Given a host pointer inside a RAM memory region (created with
+ * memory_region_init_ram() or memory_region_init_ram_ptr()), return
+ * the MemoryRegion and the offset within it.
+ *
+ * Use with care; by the time this function returns, the returned pointer is
+ * not protected by RCU anymore.  If the caller is not within an RCU critical
+ * section and does not hold the iothread lock, it must have other means of
+ * protecting the pointer, such as a reference to the region that includes
+ * the incoming ram_addr_t.
+ *
+ * @mr: the memory region being queried.
+ */
+MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset);
+
+/**
  * memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
  *
  * Returns a host pointer to a RAM memory region (created with
diff --git a/memory.c b/memory.c
index d6a4a68..f8085ea 100644
--- a/memory.c
+++ b/memory.c
@@ -33,8 +33,6 @@
 
 //#define DEBUG_UNASSIGNED
 
-#define RAM_ADDR_INVALID (~(ram_addr_t)0)
-
 static unsigned memory_region_transaction_depth;
 static bool memory_region_update_pending;
 static bool ioeventfd_update_pending;
@@ -1665,6 +1663,18 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
     return ptr + offset;
 }
 
+MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset)
+{
+    RAMBlock *block;
+
+    block = qemu_ram_block_from_host(ptr, false, offset);
+    if (!block) {
+        return NULL;
+    }
+
+    return block->mr;
+}
+
 ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
 {
     return mr->ram_block ? mr->ram_block->offset : RAM_ADDR_INVALID;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 7b3667a..abf50e6 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -411,7 +411,8 @@ int kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
 
     if ((env->mcg_cap & MCG_SER_P) && addr
         && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) {
-        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
+        ram_addr = qemu_ram_addr_from_host(addr);
+        if (ram_addr == RAM_ADDR_INVALID ||
             !kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
                     "QEMU itself instead of guest system!\n");
@@ -445,7 +446,8 @@ int kvm_arch_on_sigbus(int code, void *addr)
         hwaddr paddr;
 
         /* Hope we are lucky for AO MCE */
-        if (qemu_ram_addr_from_host(addr, &ram_addr) == NULL ||
+        ram_addr = qemu_ram_addr_from_host(addr);
+        if (ram_addr == RAM_ADDR_INVALID ||
             !kvm_physical_memory_addr_from_host(first_cpu->kvm_state,
                                                 addr, &paddr)) {
             fprintf(stderr, "Hardware memory error for memory used by "
-- 
2.5.5

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

* [Qemu-devel] [PULL 31/31] exec: hide mr->ram_addr from qemu_get_ram_ptr users
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (29 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 30/31] memory: split memory_region_from_host from qemu_ram_addr_from_host Paolo Bonzini
@ 2016-05-27 10:06 ` Paolo Bonzini
  2016-05-27 12:53 ` [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Peter Maydell
  31 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 10:06 UTC (permalink / raw)
  To: qemu-devel

Let users of qemu_get_ram_ptr and qemu_ram_ptr_length pass in an
address that is relative to the MemoryRegion.  This basically means
what address_space_translate returns.

Because the semantics of the second parameter change, rename the
function to qemu_map_ram_ptr.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c                       | 57 +++++++++++++++++++-------------------------
 include/exec/memory.h        |  5 ++--
 memory.c                     |  4 ++--
 scripts/dump-guest-memory.py | 19 +++------------
 4 files changed, 31 insertions(+), 54 deletions(-)

diff --git a/exec.c b/exec.c
index 7f62835..4488821 100644
--- a/exec.c
+++ b/exec.c
@@ -1822,12 +1822,13 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
  *
  * Called within RCU critical section.
  */
-void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
+void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
 {
     RAMBlock *block = ram_block;
 
     if (block == NULL) {
         block = qemu_get_ram_block(addr);
+        addr -= block->offset;
     }
 
     if (xen_enabled() && block->host == NULL) {
@@ -1841,10 +1842,10 @@ void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
 
         block->host = xen_map_cache(block->offset, block->max_length, 1);
     }
-    return ramblock_ptr(block, addr - block->offset);
+    return ramblock_ptr(block, addr);
 }
 
-/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
+/* Return a host pointer to guest's ram. Similar to qemu_map_ram_ptr
  * but takes a size argument.
  *
  * Called within RCU critical section.
@@ -1853,16 +1854,15 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
                                  hwaddr *size)
 {
     RAMBlock *block = ram_block;
-    ram_addr_t offset_inside_block;
     if (*size == 0) {
         return NULL;
     }
 
     if (block == NULL) {
         block = qemu_get_ram_block(addr);
+        addr -= block->offset;
     }
-    offset_inside_block = addr - block->offset;
-    *size = MIN(*size, block->max_length - offset_inside_block);
+    *size = MIN(*size, block->max_length - addr);
 
     if (xen_enabled() && block->host == NULL) {
         /* We need to check if the requested address is in the RAM
@@ -1876,7 +1876,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
         block->host = xen_map_cache(block->offset, block->max_length, 1);
     }
 
-    return ramblock_ptr(block, offset_inside_block);
+    return ramblock_ptr(block, addr);
 }
 
 /*
@@ -1986,13 +1986,13 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
     }
     switch (size) {
     case 1:
-        stb_p(qemu_get_ram_ptr(NULL, ram_addr), val);
+        stb_p(qemu_map_ram_ptr(NULL, ram_addr), val);
         break;
     case 2:
-        stw_p(qemu_get_ram_ptr(NULL, ram_addr), val);
+        stw_p(qemu_map_ram_ptr(NULL, ram_addr), val);
         break;
     case 4:
-        stl_p(qemu_get_ram_ptr(NULL, ram_addr), val);
+        stl_p(qemu_map_ram_ptr(NULL, ram_addr), val);
         break;
     default:
         abort();
@@ -2454,6 +2454,8 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr,
                                      hwaddr length)
 {
     uint8_t dirty_log_mask = memory_region_get_dirty_log_mask(mr);
+    addr += memory_region_get_ram_addr(mr);
+
     /* No early return if dirty_log_mask is or becomes 0, because
      * cpu_physical_memory_set_dirty_range will still call
      * xen_modified_memory.
@@ -2566,9 +2568,8 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
                 abort();
             }
         } else {
-            addr1 += memory_region_get_ram_addr(mr);
             /* RAM case */
-            ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
+            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
             memcpy(ptr, buf, l);
             invalidate_and_set_dirty(mr, addr1, l);
         }
@@ -2659,8 +2660,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
             }
         } else {
             /* RAM case */
-            ptr = qemu_get_ram_ptr(mr->ram_block,
-                                   memory_region_get_ram_addr(mr) + addr1);
+            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
             memcpy(buf, ptr, l);
         }
 
@@ -2743,9 +2743,8 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
               memory_region_is_romd(mr))) {
             l = memory_access_size(mr, l, addr1);
         } else {
-            addr1 += memory_region_get_ram_addr(mr);
             /* ROM/RAM case */
-            ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
+            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
             switch (type) {
             case WRITE_DATA:
                 memcpy(ptr, buf, l);
@@ -2903,7 +2902,6 @@ void *address_space_map(AddressSpace *as,
     hwaddr done = 0;
     hwaddr l, xlat, base;
     MemoryRegion *mr, *this_mr;
-    ram_addr_t raddr;
     void *ptr;
 
     if (len == 0) {
@@ -2938,7 +2936,6 @@ void *address_space_map(AddressSpace *as,
     }
 
     base = xlat;
-    raddr = memory_region_get_ram_addr(mr);
 
     for (;;) {
         len -= l;
@@ -2957,7 +2954,7 @@ void *address_space_map(AddressSpace *as,
 
     memory_region_ref(mr);
     *plen = done;
-    ptr = qemu_ram_ptr_length(mr->ram_block, raddr + base, plen);
+    ptr = qemu_ram_ptr_length(mr->ram_block, base, plen);
     rcu_read_unlock();
 
     return ptr;
@@ -2976,7 +2973,6 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
 
         mr = memory_region_from_host(buffer, &addr1);
         assert(mr != NULL);
-        addr1 += memory_region_get_ram_addr(mr);
         if (is_write) {
             invalidate_and_set_dirty(mr, addr1, access_len);
         }
@@ -3042,8 +3038,7 @@ static inline uint32_t address_space_ldl_internal(AddressSpace *as, hwaddr addr,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_get_ram_ptr(mr->ram_block,
-                               memory_region_get_ram_addr(mr) + addr1);
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldl_le_p(ptr);
@@ -3136,8 +3131,7 @@ static inline uint64_t address_space_ldq_internal(AddressSpace *as, hwaddr addr,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_get_ram_ptr(mr->ram_block,
-                               memory_region_get_ram_addr(mr) + addr1);
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldq_le_p(ptr);
@@ -3250,8 +3244,7 @@ static inline uint32_t address_space_lduw_internal(AddressSpace *as,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_get_ram_ptr(mr->ram_block,
-                               memory_region_get_ram_addr(mr) + addr1);
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = lduw_le_p(ptr);
@@ -3333,13 +3326,13 @@ void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val,
 
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
     } else {
-        addr1 += memory_region_get_ram_addr(mr);
-        ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
         stl_p(ptr, val);
 
         dirty_log_mask = memory_region_get_dirty_log_mask(mr);
         dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE);
-        cpu_physical_memory_set_dirty_range(addr1, 4, dirty_log_mask);
+        cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr) + addr,
+                                            4, dirty_log_mask);
         r = MEMTX_OK;
     }
     if (result) {
@@ -3388,8 +3381,7 @@ static inline void address_space_stl_internal(AddressSpace *as,
         r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
     } else {
         /* RAM case */
-        addr1 += memory_region_get_ram_addr(mr);
-        ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             stl_le_p(ptr, val);
@@ -3498,8 +3490,7 @@ static inline void address_space_stw_internal(AddressSpace *as,
         r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
     } else {
         /* RAM case */
-        addr1 += memory_region_get_ram_addr(mr);
-        ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
+        ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             stw_le_p(ptr, val);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 71a27ab..4ab6800 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1393,7 +1393,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
 					MemoryRegion *mr);
 MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
                                     MemTxAttrs attrs, uint8_t *buf, int len);
-void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
+void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
 
 static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
 {
@@ -1431,8 +1431,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
             l = len;
             mr = address_space_translate(as, addr, &addr1, &l, false);
             if (len == l && memory_access_is_direct(mr, false)) {
-                addr1 += memory_region_get_ram_addr(mr);
-                ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
+                ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
                 memcpy(buf, ptr, len);
             } else {
                 result = address_space_read_continue(as, addr, attrs, buf, len,
diff --git a/memory.c b/memory.c
index f8085ea..8ba496d 100644
--- a/memory.c
+++ b/memory.c
@@ -1657,10 +1657,10 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
         mr = mr->alias;
     }
     assert(mr->ram_block);
-    ptr = qemu_get_ram_ptr(mr->ram_block, memory_region_get_ram_addr(mr));
+    ptr = qemu_map_ram_ptr(mr->ram_block, offset);
     rcu_read_unlock();
 
-    return ptr + offset;
+    return ptr;
 }
 
 MemoryRegion *memory_region_from_host(void *ptr, ram_addr_t *offset)
diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
index eb24f78..9956fc0 100644
--- a/scripts/dump-guest-memory.py
+++ b/scripts/dump-guest-memory.py
@@ -328,23 +328,10 @@ def qlist_foreach(head, field_str):
         yield var
 
 
-def qemu_get_ram_block(ram_addr):
-    """Returns the RAMBlock struct to which the given address belongs."""
-
-    ram_blocks = gdb.parse_and_eval("ram_list.blocks")
-
-    for block in qlist_foreach(ram_blocks, "next"):
-        if (ram_addr - block["offset"]) < block["used_length"]:
-            return block
-
-    raise gdb.GdbError("Bad ram offset %x" % ram_addr)
-
-
-def qemu_get_ram_ptr(ram_addr):
+def qemu_map_ram_ptr(block, offset):
     """Returns qemu vaddr for given guest physical address."""
 
-    block = qemu_get_ram_block(ram_addr)
-    return block["host"] + (ram_addr - block["offset"])
+    return block["host"] + offset
 
 
 def memory_region_get_ram_ptr(memory_region):
@@ -352,7 +339,7 @@ def memory_region_get_ram_ptr(memory_region):
         return (memory_region_get_ram_ptr(memory_region["alias"].dereference())
                 + memory_region["alias_offset"])
 
-    return qemu_get_ram_ptr(memory_region["ram_block"]["offset"])
+    return qemu_map_ram_ptr(memory_region["ram_block"], 0)
 
 
 def get_guest_phys_blocks():
-- 
2.5.5

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

* Re: [Qemu-devel] [PULL 02/31] Revert "memory: Drop FlatRange.romd_mode"
  2016-05-27 10:06 ` [Qemu-devel] [PULL 02/31] Revert "memory: Drop FlatRange.romd_mode" Paolo Bonzini
@ 2016-05-27 10:51   ` Laszlo Ersek
  0 siblings, 0 replies; 44+ messages in thread
From: Laszlo Ersek @ 2016-05-27 10:51 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On 05/27/16 12:06, Paolo Bonzini wrote:
> This reverts commit 5b5660adf1fdb61db14ec681b10463b8cba633f1,
> as it breaks the UEFI guest firmware (known as ArmVirtPkg or AAVMF)
> running in the "virt" machine type of "qemu-system-aarch64":
> 
> Contrary to the commit message, (a->mr == b->mr) does *not* imply
> that (a->romd_mode == b->romd_mode): the pflash device model calls
> memory_region_rom_device_set_romd() -- for switching between the above
> modes --, and that function changes mr->romd_mode but the current
> AddressSpaceDispatch's FlatRange keeps the old value.  Therefore
> region_del/region_add are not called on the KVM MemoryListener.
> 
> Reported-by: Drew Jones <drjones@redhat.com>
> Tested-by: Drew Jones <drjones@redhat.com>
> Analyzed-by: Laszlo Ersek <lersek@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  memory.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/memory.c b/memory.c
> index 4e3cda8..0f52522 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -227,6 +227,7 @@ struct FlatRange {
>      hwaddr offset_in_region;
>      AddrRange addr;
>      uint8_t dirty_log_mask;
> +    bool romd_mode;
>      bool readonly;
>  };
>  
> @@ -251,6 +252,7 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
>      return a->mr == b->mr
>          && addrrange_equal(a->addr, b->addr)
>          && a->offset_in_region == b->offset_in_region
> +        && a->romd_mode == b->romd_mode
>          && a->readonly == b->readonly;
>  }
>  
> @@ -310,6 +312,7 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
>                                  r1->addr.size),
>                       int128_make64(r2->offset_in_region))
>          && r1->dirty_log_mask == r2->dirty_log_mask
> +        && r1->romd_mode == r2->romd_mode
>          && r1->readonly == r2->readonly;
>  }
>  
> @@ -663,6 +666,7 @@ static void render_memory_region(FlatView *view,
>  
>      fr.mr = mr;
>      fr.dirty_log_mask = memory_region_get_dirty_log_mask(mr);
> +    fr.romd_mode = mr->romd_mode;
>      fr.readonly = readonly;
>  
>      /* Render the region itself into any gaps left by the current view. */
> 

Thank you! Also for composing a succinct commit message (with new bits
that I didn't polish in my email).

Cheers,
Laszlo

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

* Re: [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
  2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
                   ` (30 preceding siblings ...)
  2016-05-27 10:06 ` [Qemu-devel] [PULL 31/31] exec: hide mr->ram_addr from qemu_get_ram_ptr users Paolo Bonzini
@ 2016-05-27 12:53 ` Peter Maydell
  2016-05-27 13:04   ` Peter Maydell
  31 siblings, 1 reply; 44+ messages in thread
From: Peter Maydell @ 2016-05-27 12:53 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 27 May 2016 at 11:06, Paolo Bonzini <pbonzini@redhat.com> wrote:
> The following changes since commit b75536c9fa742f887304769d0608557bb8e3a27f:
>
>   blockjob: Remove BlockJob.bs (2016-05-25 19:04:21 +0200)
>
> are available in the git repository at:
>
>   git://github.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to 7052033834d4c2d7ade147cf5b045be6eaf07113:
>
>   exec: hide mr->ram_addr from qemu_get_ram_ptr users (2016-05-27 11:55:23 +0200)
>
> ----------------------------------------------------------------
> * docs/atomics fixes and atomic_rcu_* optimization (Emilio)
> * NBD bugfix (Eric)
> * Memory fixes and cleanups (Paolo, Paul)
> * scsi-block support for SCSI status, including persistent
>   reservations (Paolo)
> * linuxboot support for fw_cfg DMA (Marc, Richard Jones)
> * kvm_stat moves to the Linux repository
> * SCSI bug fixes (Peter, Prasad)
> * Killing qemu_char_get_next_serial, non-ARM parts (Xiaoqiang)

Hi; this fails to build for w32:

  CC    optionrom/linuxboot_dma.o
  Building optionrom/linuxboot_dma.img
linuxboot_dma.o:linuxboot_dma.c:(.text+0x57): undefined reference to
`load_kernel'

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
  2016-05-27 12:53 ` [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Peter Maydell
@ 2016-05-27 13:04   ` Peter Maydell
  2016-05-27 13:38     ` Richard W.M. Jones
  0 siblings, 1 reply; 44+ messages in thread
From: Peter Maydell @ 2016-05-27 13:04 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Marc Marí, Richard W.M. Jones

On 27 May 2016 at 13:53, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 27 May 2016 at 11:06, Paolo Bonzini <pbonzini@redhat.com> wrote:
>> The following changes since commit b75536c9fa742f887304769d0608557bb8e3a27f:
>>
>>   blockjob: Remove BlockJob.bs (2016-05-25 19:04:21 +0200)
>>
>> are available in the git repository at:
>>
>>   git://github.com/bonzini/qemu.git tags/for-upstream
>>
>> for you to fetch changes up to 7052033834d4c2d7ade147cf5b045be6eaf07113:
>>
>>   exec: hide mr->ram_addr from qemu_get_ram_ptr users (2016-05-27 11:55:23 +0200)
>>
>> ----------------------------------------------------------------
>> * docs/atomics fixes and atomic_rcu_* optimization (Emilio)
>> * NBD bugfix (Eric)
>> * Memory fixes and cleanups (Paolo, Paul)
>> * scsi-block support for SCSI status, including persistent
>>   reservations (Paolo)
>> * linuxboot support for fw_cfg DMA (Marc, Richard Jones)
>> * kvm_stat moves to the Linux repository
>> * SCSI bug fixes (Peter, Prasad)
>> * Killing qemu_char_get_next_serial, non-ARM parts (Xiaoqiang)
>
> Hi; this fails to build for w32:
>
>   CC    optionrom/linuxboot_dma.o
>   Building optionrom/linuxboot_dma.img
> linuxboot_dma.o:linuxboot_dma.c:(.text+0x57): undefined reference to
> `load_kernel'

With V=1:

i686-w64-mingw32-ld -m i386pe -Ttext 0 -e _start -s -o
linuxboot_dma.img linuxboot_dma.o
linuxboot_dma.o:linuxboot_dma.c:(.text+0x57): undefined reference to
`load_kernel'

Building an image for the target using our host compiler seems like
an odd choice, but the makefile obviously intends to support it
since it has specific ifdef CONFIG_WIN32 code to adjust the linker
command line.

I suspect this is a mismatch between the symbol the native asm is
using and the one that the C compiler wants:

$ nm build/w32-new/pc-bios/optionrom/linuxboot_dma.o |grep load_kernel
000005dd T _load_kernel
         U load_kernel

since name mangling rules are different for Linux and Windows ABIs.

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
  2016-05-27 13:04   ` Peter Maydell
@ 2016-05-27 13:38     ` Richard W.M. Jones
  2016-05-27 14:04       ` Peter Maydell
  2016-05-27 14:06       ` Paolo Bonzini
  0 siblings, 2 replies; 44+ messages in thread
From: Richard W.M. Jones @ 2016-05-27 13:38 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Paolo Bonzini, QEMU Developers, Marc Marí

On Fri, May 27, 2016 at 02:04:52PM +0100, Peter Maydell wrote:
> With V=1:
> 
> i686-w64-mingw32-ld -m i386pe -Ttext 0 -e _start -s -o
> linuxboot_dma.img linuxboot_dma.o
> linuxboot_dma.o:linuxboot_dma.c:(.text+0x57): undefined reference to
> `load_kernel'
> 
> Building an image for the target using our host compiler seems like
> an odd choice,

Which compiler should I be using?

> but the makefile obviously intends to support it
> since it has specific ifdef CONFIG_WIN32 code to adjust the linker
> command line.
>
> I suspect this is a mismatch between the symbol the native asm is
> using and the one that the C compiler wants:
> 
> $ nm build/w32-new/pc-bios/optionrom/linuxboot_dma.o |grep load_kernel
> 000005dd T _load_kernel
>          U load_kernel
> 
> since name mangling rules are different for Linux and Windows ABIs.

One way to solve this (which works for me) is as below.  There are
some other approaches, eg. using -fno-leading-underscore, or using a
conditional macro to mangle the name.  However I have no idea if there
is some preferred way.

Rich.

diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c
index 86ef1ce..8509b28 100644
--- a/pc-bios/optionrom/linuxboot_dma.c
+++ b/pc-bios/optionrom/linuxboot_dma.c
@@ -213,6 +213,9 @@ static uint32_t get_e801_addr(void)
     return ret;
 }
 
+/* Force the asm name without leading underscore, even on Win32. */
+extern void load_kernel(void) asm("load_kernel");
+
 void load_kernel(void)
 {
     void *setup_addr;


-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
libguestfs lets you edit virtual machines.  Supports shell scripting,
bindings from many languages.  http://libguestfs.org

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

* Re: [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
  2016-05-27 13:38     ` Richard W.M. Jones
@ 2016-05-27 14:04       ` Peter Maydell
  2016-05-27 14:07         ` Paolo Bonzini
  2016-05-27 14:06       ` Paolo Bonzini
  1 sibling, 1 reply; 44+ messages in thread
From: Peter Maydell @ 2016-05-27 14:04 UTC (permalink / raw)
  To: Richard W.M. Jones; +Cc: Paolo Bonzini, QEMU Developers, Marc Marí

On 27 May 2016 at 14:38, Richard W.M. Jones <rjones@redhat.com> wrote:
> On Fri, May 27, 2016 at 02:04:52PM +0100, Peter Maydell wrote:
>> With V=1:
>>
>> i686-w64-mingw32-ld -m i386pe -Ttext 0 -e _start -s -o
>> linuxboot_dma.img linuxboot_dma.o
>> linuxboot_dma.o:linuxboot_dma.c:(.text+0x57): undefined reference to
>> `load_kernel'
>>
>> Building an image for the target using our host compiler seems like
>> an odd choice,
>
> Which compiler should I be using?

I would have expected that how we build a guest image ought to
be the same regardless of how we're building QEMU itself.
(You wouldn't try to build an i386 image with $(CC) if you're
on an ARM host, for instance.)
However, given that the makefile already works this way, better
to go with the flow...

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
  2016-05-27 13:38     ` Richard W.M. Jones
  2016-05-27 14:04       ` Peter Maydell
@ 2016-05-27 14:06       ` Paolo Bonzini
  2016-05-27 14:11         ` Richard W.M. Jones
  1 sibling, 1 reply; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 14:06 UTC (permalink / raw)
  To: Richard W.M. Jones, Peter Maydell; +Cc: QEMU Developers, Marc Marí



On 27/05/2016 15:38, Richard W.M. Jones wrote:
> One way to solve this (which works for me) is as below.  There are
> some other approaches, eg. using -fno-leading-underscore, or using a
> conditional macro to mangle the name.  However I have no idea if there
> is some preferred way.
> 
> Rich.
> 
> diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c
> index 86ef1ce..8509b28 100644
> --- a/pc-bios/optionrom/linuxboot_dma.c
> +++ b/pc-bios/optionrom/linuxboot_dma.c
> @@ -213,6 +213,9 @@ static uint32_t get_e801_addr(void)
>      return ret;
>  }
>  
> +/* Force the asm name without leading underscore, even on Win32. */
> +extern void load_kernel(void) asm("load_kernel");
> +
>  void load_kernel(void)
>  {
>      void *setup_addr;

Yes, that's what I wanted to do.  I also need

diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index 2b11cd3..14e7f71 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -31,6 +31,7 @@ build-all: multiboot.bin linuxboot.bin
linuxboot_dma.bin kvmvapic.bin

 ifdef CONFIG_WIN32
 LD_EMULATION = i386pe
+CFLAGS += -Wa,-32
 else
 LD_EMULATION = elf_i386
 endif

to work around what is likely a GCC bug.

Paolo

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

* Re: [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
  2016-05-27 14:04       ` Peter Maydell
@ 2016-05-27 14:07         ` Paolo Bonzini
  0 siblings, 0 replies; 44+ messages in thread
From: Paolo Bonzini @ 2016-05-27 14:07 UTC (permalink / raw)
  To: Peter Maydell, Richard W.M. Jones; +Cc: QEMU Developers, Marc Marí



On 27/05/2016 16:04, Peter Maydell wrote:
> > > i686-w64-mingw32-ld -m i386pe -Ttext 0 -e _start -s -o
> > > linuxboot_dma.img linuxboot_dma.o
> > > linuxboot_dma.o:linuxboot_dma.c:(.text+0x57): undefined reference to
> > > `load_kernel'
> > >
> > > Building an image for the target using our host compiler seems like
> > > an odd choice,
> >
> > Which compiler should I be using?
>
> I would have expected that how we build a guest image ought to
> be the same regardless of how we're building QEMU itself.
> (You wouldn't try to build an i386 image with $(CC) if you're
> on an ARM host, for instance.)
> However, given that the makefile already works this way, better
> to go with the flow...

Yeah, however currently the ROMs are only built if you are not doing a
cross build.

Thanks,

Paolo

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

* Re: [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27
  2016-05-27 14:06       ` Paolo Bonzini
@ 2016-05-27 14:11         ` Richard W.M. Jones
  0 siblings, 0 replies; 44+ messages in thread
From: Richard W.M. Jones @ 2016-05-27 14:11 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Peter Maydell, QEMU Developers, Marc Marí

On Fri, May 27, 2016 at 04:06:07PM +0200, Paolo Bonzini wrote:
> 
> 
> On 27/05/2016 15:38, Richard W.M. Jones wrote:
> > One way to solve this (which works for me) is as below.  There are
> > some other approaches, eg. using -fno-leading-underscore, or using a
> > conditional macro to mangle the name.  However I have no idea if there
> > is some preferred way.
> > 
> > Rich.
> > 
> > diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c
> > index 86ef1ce..8509b28 100644
> > --- a/pc-bios/optionrom/linuxboot_dma.c
> > +++ b/pc-bios/optionrom/linuxboot_dma.c
> > @@ -213,6 +213,9 @@ static uint32_t get_e801_addr(void)
> >      return ret;
> >  }
> >  
> > +/* Force the asm name without leading underscore, even on Win32. */
> > +extern void load_kernel(void) asm("load_kernel");
> > +
> >  void load_kernel(void)
> >  {
> >      void *setup_addr;
> 
> Yes, that's what I wanted to do.  I also need
> 
> diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
> index 2b11cd3..14e7f71 100644
> --- a/pc-bios/optionrom/Makefile
> +++ b/pc-bios/optionrom/Makefile
> @@ -31,6 +31,7 @@ build-all: multiboot.bin linuxboot.bin
> linuxboot_dma.bin kvmvapic.bin
> 
>  ifdef CONFIG_WIN32
>  LD_EMULATION = i386pe
> +CFLAGS += -Wa,-32
>  else
>  LD_EMULATION = elf_i386
>  endif
> 
> to work around what is likely a GCC bug.

OK I don't need that with mingw32-gcc-6.1.0-1.fc24.x86_64, but on the
other hand it doesn't negatively affect builds for me either.  Next
version coming up soon.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v

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

* Re: [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c
  2016-05-27 10:06 ` [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c Paolo Bonzini
@ 2016-05-31 22:13   ` Mark Cave-Ayland
  2016-06-01  3:06     ` xiaoqiang zhao
  0 siblings, 1 reply; 44+ messages in thread
From: Mark Cave-Ayland @ 2016-05-31 22:13 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: xiaoqiang zhao

On 27/05/16 11:06, Paolo Bonzini wrote:

> From: xiaoqiang zhao <zxq_yx_007@163.com>
> 
> * Drop the old SysBus init function and use instance_init
> * Call qemu_chr_add_handlers in the realize callback
> 
> Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
> Message-Id: <1464158344-12266-2-git-send-email-zxq_yx_007@163.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  hw/char/escc.c | 30 +++++++++++++++++++-----------
>  1 file changed, 19 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/char/escc.c b/hw/char/escc.c
> index 7bf09a0..8e6a7df 100644
> --- a/hw/char/escc.c
> +++ b/hw/char/escc.c
> @@ -983,9 +983,10 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
>      sysbus_mmio_map(s, 0, base);
>  }
>  
> -static int escc_init1(SysBusDevice *dev)
> +static void escc_init1(Object *obj)
>  {
> -    ESCCState *s = ESCC(dev);
> +    ESCCState *s = ESCC(obj);
> +    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
>      unsigned int i;
>  
>      s->chn[0].disabled = s->disabled;
> @@ -994,17 +995,26 @@ static int escc_init1(SysBusDevice *dev)
>          sysbus_init_irq(dev, &s->chn[i].irq);
>          s->chn[i].chn = 1 - i;
>          s->chn[i].clock = s->frequency / 2;
> -        if (s->chn[i].chr) {
> -            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
> -                                  serial_receive1, serial_event, &s->chn[i]);
> -        }
>      }
>      s->chn[0].otherchn = &s->chn[1];
>      s->chn[1].otherchn = &s->chn[0];
>  
> -    memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
> +    memory_region_init_io(&s->mmio, obj, &escc_mem_ops, s, "escc",
>                            ESCC_SIZE << s->it_shift);
>      sysbus_init_mmio(dev, &s->mmio);
> +}
> +
> +static void escc_realize(DeviceState *dev, Error **errp)
> +{
> +    ESCCState *s = ESCC(dev);
> +    unsigned int i;
> +
> +    for (i = 0; i < 2; i++) {
> +        if (s->chn[i].chr) {
> +            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
> +                                  serial_receive1, serial_event, &s->chn[i]);
> +        }
> +    }
>  
>      if (s->chn[0].type == mouse) {
>          qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
> @@ -1014,8 +1024,6 @@ static int escc_init1(SysBusDevice *dev)
>          s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
>                                                     &sunkbd_handler);
>      }
> -
> -    return 0;
>  }
>  
>  static Property escc_properties[] = {
> @@ -1032,10 +1040,9 @@ static Property escc_properties[] = {
>  static void escc_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
> -    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>  
> -    k->init = escc_init1;
>      dc->reset = escc_reset;
> +    dc->realize = escc_realize;
>      dc->vmsd = &vmstate_escc;
>      dc->props = escc_properties;
>      set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
> @@ -1045,6 +1052,7 @@ static const TypeInfo escc_info = {
>      .name          = TYPE_ESCC,
>      .parent        = TYPE_SYS_BUS_DEVICE,
>      .instance_size = sizeof(ESCCState),
> +    .instance_init = escc_init1,
>      .class_init    = escc_class_init,
>  };

Unfortunately this patch causes OpenBIOS to freeze on startup under
qemu-system-ppc (presumably as there is a problem accessing the serial
port). You can reproduce this by starting qemu-system-ppc with no
parameters against the commits below:

Bad : e7c9136977cb99c6eb52c9139f7b8d8b5fa87db9
Good: b138e654a0525f009e7e7c96fc67d74baf3e011b

Note that you'll currently need to use the above two hashes to reproduce
the issue against git master as another regression has just crept in.


ATB,

Mark.

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

* Re: [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c
  2016-05-31 22:13   ` Mark Cave-Ayland
@ 2016-06-01  3:06     ` xiaoqiang zhao
  2016-06-01  7:04       ` Mark Cave-Ayland
  0 siblings, 1 reply; 44+ messages in thread
From: xiaoqiang zhao @ 2016-06-01  3:06 UTC (permalink / raw)
  To: Mark Cave-Ayland; +Cc: Paolo Bonzini, qemu-devel



> 在 2016年6月1日,06:13,Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> 写道:
> 
>> On 27/05/16 11:06, Paolo Bonzini wrote:
>> 
>> From: xiaoqiang zhao <zxq_yx_007@163.com>
>> 
>> * Drop the old SysBus init function and use instance_init
>> * Call qemu_chr_add_handlers in the realize callback
>> 
>> Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
>> Message-Id: <1464158344-12266-2-git-send-email-zxq_yx_007@163.com>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>> hw/char/escc.c | 30 +++++++++++++++++++-----------
>> 1 file changed, 19 insertions(+), 11 deletions(-)
>> 
>> diff --git a/hw/char/escc.c b/hw/char/escc.c
>> index 7bf09a0..8e6a7df 100644
>> --- a/hw/char/escc.c
>> +++ b/hw/char/escc.c
>> @@ -983,9 +983,10 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
>>     sysbus_mmio_map(s, 0, base);
>> }
>> 
>> -static int escc_init1(SysBusDevice *dev)
>> +static void escc_init1(Object *obj)
>> {
>> -    ESCCState *s = ESCC(dev);
>> +    ESCCState *s = ESCC(obj);
>> +    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
>>     unsigned int i;
>> 
>>     s->chn[0].disabled = s->disabled;
>> @@ -994,17 +995,26 @@ static int escc_init1(SysBusDevice *dev)
>>         sysbus_init_irq(dev, &s->chn[i].irq);
>>         s->chn[i].chn = 1 - i;
>>         s->chn[i].clock = s->frequency / 2;
>> -        if (s->chn[i].chr) {
>> -            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
>> -                                  serial_receive1, serial_event, &s->chn[i]);
>> -        }
>>     }
>>     s->chn[0].otherchn = &s->chn[1];
>>     s->chn[1].otherchn = &s->chn[0];
>> 
>> -    memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
>> +    memory_region_init_io(&s->mmio, obj, &escc_mem_ops, s, "escc",
>>                           ESCC_SIZE << s->it_shift);
>>     sysbus_init_mmio(dev, &s->mmio);
>> +}
>> +
>> +static void escc_realize(DeviceState *dev, Error **errp)
>> +{
>> +    ESCCState *s = ESCC(dev);
>> +    unsigned int i;
>> +
>> +    for (i = 0; i < 2; i++) {
>> +        if (s->chn[i].chr) {
>> +            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
>> +                                  serial_receive1, serial_event, &s->chn[i]);
>> +        }
>> +    }
>> 
>>     if (s->chn[0].type == mouse) {
>>         qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
>> @@ -1014,8 +1024,6 @@ static int escc_init1(SysBusDevice *dev)
>>         s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
>>                                                    &sunkbd_handler);
>>     }
>> -
>> -    return 0;
>> }
>> 
>> static Property escc_properties[] = {
>> @@ -1032,10 +1040,9 @@ static Property escc_properties[] = {
>> static void escc_class_init(ObjectClass *klass, void *data)
>> {
>>     DeviceClass *dc = DEVICE_CLASS(klass);
>> -    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>> 
>> -    k->init = escc_init1;
>>     dc->reset = escc_reset;
>> +    dc->realize = escc_realize;
>>     dc->vmsd = &vmstate_escc;
>>     dc->props = escc_properties;
>>     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>> @@ -1045,6 +1052,7 @@ static const TypeInfo escc_info = {
>>     .name          = TYPE_ESCC,
>>     .parent        = TYPE_SYS_BUS_DEVICE,
>>     .instance_size = sizeof(ESCCState),
>> +    .instance_init = escc_init1,
>>     .class_init    = escc_class_init,
>> };
> 
> Unfortunately this patch causes OpenBIOS to freeze on startup under
> qemu-system-ppc (presumably as there is a problem accessing the serial
> port). You can reproduce this by starting qemu-system-ppc with no
> parameters against the commits below:
> 
> Bad : e7c9136977cb99c6eb52c9139f7b8d8b5fa87db9
> Good: b138e654a0525f009e7e7c96fc67d74baf3e011b
> 
> Note that you'll currently need to use the above two hashes to reproduce
> the issue against git master as another regression has just crept in.
> 
> 
> ATB,
> 
> Mark.
> 
> 

Mark:
   Sorry for the inconvenience. This problem is due to the incorrect property value in the realize stage. I have fix this and the test is passed.

Paolo:  Do i need to send a new version or just this one?

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

* Re: [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c
  2016-06-01  3:06     ` xiaoqiang zhao
@ 2016-06-01  7:04       ` Mark Cave-Ayland
  2016-06-01  7:08         ` xiaoqiang zhao
  0 siblings, 1 reply; 44+ messages in thread
From: Mark Cave-Ayland @ 2016-06-01  7:04 UTC (permalink / raw)
  To: xiaoqiang zhao; +Cc: Paolo Bonzini, qemu-devel

On 01/06/16 04:06, xiaoqiang zhao wrote:

>> 在 2016年6月1日,06:13,Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> 写道:
>>
>>> On 27/05/16 11:06, Paolo Bonzini wrote:
>>>
>>> From: xiaoqiang zhao <zxq_yx_007@163.com>
>>>
>>> * Drop the old SysBus init function and use instance_init
>>> * Call qemu_chr_add_handlers in the realize callback
>>>
>>> Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
>>> Message-Id: <1464158344-12266-2-git-send-email-zxq_yx_007@163.com>
>>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>>> ---
>>> hw/char/escc.c | 30 +++++++++++++++++++-----------
>>> 1 file changed, 19 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/hw/char/escc.c b/hw/char/escc.c
>>> index 7bf09a0..8e6a7df 100644
>>> --- a/hw/char/escc.c
>>> +++ b/hw/char/escc.c
>>> @@ -983,9 +983,10 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
>>>     sysbus_mmio_map(s, 0, base);
>>> }
>>>
>>> -static int escc_init1(SysBusDevice *dev)
>>> +static void escc_init1(Object *obj)
>>> {
>>> -    ESCCState *s = ESCC(dev);
>>> +    ESCCState *s = ESCC(obj);
>>> +    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
>>>     unsigned int i;
>>>
>>>     s->chn[0].disabled = s->disabled;
>>> @@ -994,17 +995,26 @@ static int escc_init1(SysBusDevice *dev)
>>>         sysbus_init_irq(dev, &s->chn[i].irq);
>>>         s->chn[i].chn = 1 - i;
>>>         s->chn[i].clock = s->frequency / 2;
>>> -        if (s->chn[i].chr) {
>>> -            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
>>> -                                  serial_receive1, serial_event, &s->chn[i]);
>>> -        }
>>>     }
>>>     s->chn[0].otherchn = &s->chn[1];
>>>     s->chn[1].otherchn = &s->chn[0];
>>>
>>> -    memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
>>> +    memory_region_init_io(&s->mmio, obj, &escc_mem_ops, s, "escc",
>>>                           ESCC_SIZE << s->it_shift);
>>>     sysbus_init_mmio(dev, &s->mmio);
>>> +}
>>> +
>>> +static void escc_realize(DeviceState *dev, Error **errp)
>>> +{
>>> +    ESCCState *s = ESCC(dev);
>>> +    unsigned int i;
>>> +
>>> +    for (i = 0; i < 2; i++) {
>>> +        if (s->chn[i].chr) {
>>> +            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
>>> +                                  serial_receive1, serial_event, &s->chn[i]);
>>> +        }
>>> +    }
>>>
>>>     if (s->chn[0].type == mouse) {
>>>         qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
>>> @@ -1014,8 +1024,6 @@ static int escc_init1(SysBusDevice *dev)
>>>         s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
>>>                                                    &sunkbd_handler);
>>>     }
>>> -
>>> -    return 0;
>>> }
>>>
>>> static Property escc_properties[] = {
>>> @@ -1032,10 +1040,9 @@ static Property escc_properties[] = {
>>> static void escc_class_init(ObjectClass *klass, void *data)
>>> {
>>>     DeviceClass *dc = DEVICE_CLASS(klass);
>>> -    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>>>
>>> -    k->init = escc_init1;
>>>     dc->reset = escc_reset;
>>> +    dc->realize = escc_realize;
>>>     dc->vmsd = &vmstate_escc;
>>>     dc->props = escc_properties;
>>>     set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>>> @@ -1045,6 +1052,7 @@ static const TypeInfo escc_info = {
>>>     .name          = TYPE_ESCC,
>>>     .parent        = TYPE_SYS_BUS_DEVICE,
>>>     .instance_size = sizeof(ESCCState),
>>> +    .instance_init = escc_init1,
>>>     .class_init    = escc_class_init,
>>> };
>>
>> Unfortunately this patch causes OpenBIOS to freeze on startup under
>> qemu-system-ppc (presumably as there is a problem accessing the serial
>> port). You can reproduce this by starting qemu-system-ppc with no
>> parameters against the commits below:
>>
>> Bad : e7c9136977cb99c6eb52c9139f7b8d8b5fa87db9
>> Good: b138e654a0525f009e7e7c96fc67d74baf3e011b
>>
>> Note that you'll currently need to use the above two hashes to reproduce
>> the issue against git master as another regression has just crept in.
>>
>>
>> ATB,
>>
>> Mark.
>>
>>
> 
> Mark:
>    Sorry for the inconvenience. This problem is due to the incorrect property value in the realize stage. I have fix this and the test is passed.

No problem.

> Paolo:  Do i need to send a new version or just this one?

The original patch has already applied to git master, so please send
your fix as a separate patch.


ATB,

Mark.

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

* Re: [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c
  2016-06-01  7:04       ` Mark Cave-Ayland
@ 2016-06-01  7:08         ` xiaoqiang zhao
  0 siblings, 0 replies; 44+ messages in thread
From: xiaoqiang zhao @ 2016-06-01  7:08 UTC (permalink / raw)
  To: Mark Cave-Ayland; +Cc: Paolo Bonzini, qemu-devel



在 2016年06月01日 15:04, Mark Cave-Ayland 写道:
> On 01/06/16 04:06, xiaoqiang zhao wrote:
>
>>> 在 2016年6月1日,06:13,Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> 写道:
>>>
>>>> On 27/05/16 11:06, Paolo Bonzini wrote:
>>>>
>>>> From: xiaoqiang zhao <zxq_yx_007@163.com>
>>>>
>>>> * Drop the old SysBus init function and use instance_init
>>>> * Call qemu_chr_add_handlers in the realize callback
>>>>
>>>> Signed-off-by: xiaoqiang zhao <zxq_yx_007@163.com>
>>>> Message-Id: <1464158344-12266-2-git-send-email-zxq_yx_007@163.com>
>>>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>>>> ---
>>>> hw/char/escc.c | 30 +++++++++++++++++++-----------
>>>> 1 file changed, 19 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/hw/char/escc.c b/hw/char/escc.c
>>>> index 7bf09a0..8e6a7df 100644
>>>> --- a/hw/char/escc.c
>>>> +++ b/hw/char/escc.c
>>>> @@ -983,9 +983,10 @@ void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
>>>>      sysbus_mmio_map(s, 0, base);
>>>> }
>>>>
>>>> -static int escc_init1(SysBusDevice *dev)
>>>> +static void escc_init1(Object *obj)
>>>> {
>>>> -    ESCCState *s = ESCC(dev);
>>>> +    ESCCState *s = ESCC(obj);
>>>> +    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
>>>>      unsigned int i;
>>>>
>>>>      s->chn[0].disabled = s->disabled;
>>>> @@ -994,17 +995,26 @@ static int escc_init1(SysBusDevice *dev)
>>>>          sysbus_init_irq(dev, &s->chn[i].irq);
>>>>          s->chn[i].chn = 1 - i;
>>>>          s->chn[i].clock = s->frequency / 2;
>>>> -        if (s->chn[i].chr) {
>>>> -            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
>>>> -                                  serial_receive1, serial_event, &s->chn[i]);
>>>> -        }
>>>>      }
>>>>      s->chn[0].otherchn = &s->chn[1];
>>>>      s->chn[1].otherchn = &s->chn[0];
>>>>
>>>> -    memory_region_init_io(&s->mmio, OBJECT(s), &escc_mem_ops, s, "escc",
>>>> +    memory_region_init_io(&s->mmio, obj, &escc_mem_ops, s, "escc",
>>>>                            ESCC_SIZE << s->it_shift);
>>>>      sysbus_init_mmio(dev, &s->mmio);
>>>> +}
>>>> +
>>>> +static void escc_realize(DeviceState *dev, Error **errp)
>>>> +{
>>>> +    ESCCState *s = ESCC(dev);
>>>> +    unsigned int i;
>>>> +
>>>> +    for (i = 0; i < 2; i++) {
>>>> +        if (s->chn[i].chr) {
>>>> +            qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
>>>> +                                  serial_receive1, serial_event, &s->chn[i]);
>>>> +        }
>>>> +    }
>>>>
>>>>      if (s->chn[0].type == mouse) {
>>>>          qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
>>>> @@ -1014,8 +1024,6 @@ static int escc_init1(SysBusDevice *dev)
>>>>          s->chn[1].hs = qemu_input_handler_register((DeviceState *)(&s->chn[1]),
>>>>                                                     &sunkbd_handler);
>>>>      }
>>>> -
>>>> -    return 0;
>>>> }
>>>>
>>>> static Property escc_properties[] = {
>>>> @@ -1032,10 +1040,9 @@ static Property escc_properties[] = {
>>>> static void escc_class_init(ObjectClass *klass, void *data)
>>>> {
>>>>      DeviceClass *dc = DEVICE_CLASS(klass);
>>>> -    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
>>>>
>>>> -    k->init = escc_init1;
>>>>      dc->reset = escc_reset;
>>>> +    dc->realize = escc_realize;
>>>>      dc->vmsd = &vmstate_escc;
>>>>      dc->props = escc_properties;
>>>>      set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
>>>> @@ -1045,6 +1052,7 @@ static const TypeInfo escc_info = {
>>>>      .name          = TYPE_ESCC,
>>>>      .parent        = TYPE_SYS_BUS_DEVICE,
>>>>      .instance_size = sizeof(ESCCState),
>>>> +    .instance_init = escc_init1,
>>>>      .class_init    = escc_class_init,
>>>> };
>>> Unfortunately this patch causes OpenBIOS to freeze on startup under
>>> qemu-system-ppc (presumably as there is a problem accessing the serial
>>> port). You can reproduce this by starting qemu-system-ppc with no
>>> parameters against the commits below:
>>>
>>> Bad : e7c9136977cb99c6eb52c9139f7b8d8b5fa87db9
>>> Good: b138e654a0525f009e7e7c96fc67d74baf3e011b
>>>
>>> Note that you'll currently need to use the above two hashes to reproduce
>>> the issue against git master as another regression has just crept in.
>>>
>>>
>>> ATB,
>>>
>>> Mark.
>>>
>>>
>> Mark:
>>     Sorry for the inconvenience. This problem is due to the incorrect property value in the realize stage. I have fix this and the test is passed.
> No problem.
>
>> Paolo:  Do i need to send a new version or just this one?
> The original patch has already applied to git master, so please send
> your fix as a separate patch.
>
>
> ATB,
>
> Mark.
>
Ok, coming soon ;-)

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

end of thread, other threads:[~2016-06-01  7:09 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-27 10:06 [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 01/31] Add optionrom compatible with fw_cfg DMA version Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 02/31] Revert "memory: Drop FlatRange.romd_mode" Paolo Bonzini
2016-05-27 10:51   ` Laszlo Ersek
2016-05-27 10:06 ` [Qemu-devel] [PULL 03/31] hw/char: QOM'ify escc.c Paolo Bonzini
2016-05-31 22:13   ` Mark Cave-Ayland
2016-06-01  3:06     ` xiaoqiang zhao
2016-06-01  7:04       ` Mark Cave-Ayland
2016-06-01  7:08         ` xiaoqiang zhao
2016-05-27 10:06 ` [Qemu-devel] [PULL 04/31] hw/char: QOM'ify etraxfs_ser.c Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 05/31] hw/char: QOM'ify lm32_juart.c Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 06/31] hw/char: QOM'ify lm32_uart.c Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 07/31] hw/char: QOM'ify milkymist-uart.c Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 08/31] nbd: Don't trim unrequested bytes Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 09/31] kvm_stat: Remove Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 10/31] scsi: pvscsi: check command descriptor ring buffer size (CVE-2016-4952) Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 11/31] scsi: mptsas: infinite loop while fetching requests Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 12/31] scsi: megasas: use appropriate property buffer size Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 13/31] scsi: megasas: initialise local configuration data buffer Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 14/31] scsi: megasas: check 'read_queue_head' index value Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 15/31] block/iscsi: avoid potential overflow of acb->task->cdb Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 16/31] bt: rewrite csrhci_write to avoid out-of-bounds writes Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 17/31] docs/atomics: update atomic_read/set comparison with Linux Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 18/31] atomics: emit an smp_read_barrier_depends() barrier only for Alpha and Thread Sanitizer Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 19/31] atomics: do not emit consume barrier for atomic_rcu_read Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 20/31] docs/atomics: update comparison with Linux Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 21/31] xen-hvm: ignore background I/O sections Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 22/31] scsi-disk: introduce a common base class Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 23/31] scsi-disk: introduce dma_readv and dma_writev Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 24/31] scsi-disk: add need_fua_emulation to SCSIDiskClass Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 25/31] scsi-disk: introduce scsi_disk_req_check_error Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 26/31] scsi-block: always use SG_IO Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 27/31] scsi-generic: Merge block max xfer len in INQUIRY response Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 28/31] memory: remove qemu_get_ram_fd, qemu_set_ram_fd, qemu_ram_block_host_ptr Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 29/31] exec: remove ram_addr argument from qemu_ram_block_from_host Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 30/31] memory: split memory_region_from_host from qemu_ram_addr_from_host Paolo Bonzini
2016-05-27 10:06 ` [Qemu-devel] [PULL 31/31] exec: hide mr->ram_addr from qemu_get_ram_ptr users Paolo Bonzini
2016-05-27 12:53 ` [Qemu-devel] [PULL 00/31] Misc changes for 2016-05-27 Peter Maydell
2016-05-27 13:04   ` Peter Maydell
2016-05-27 13:38     ` Richard W.M. Jones
2016-05-27 14:04       ` Peter Maydell
2016-05-27 14:07         ` Paolo Bonzini
2016-05-27 14:06       ` Paolo Bonzini
2016-05-27 14:11         ` Richard W.M. Jones

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.