[Qemu-devel] [Bug 1653384] [NEW] Assertion failed with USB pass through with XHCI controller

2016-12-31 Thread Razzloss
Public bug reported:

Starting qemu 2.8.0 with XHCI controller and host device passed through
results in an assertion failure:

qemu-system-x86_64: hw/usb/core.c:623: usb_packet_cleanup: Assertion
`!usb_packet_is_inflight(p)' failed.

Can be reproduced with the following command (passing through a Lenovo
keyboard):

qemu-system-x86_64 -usb  -device nec-usb-xhci,id=usb -device usb-
host,vendorid=0x04b3,productid=0x3025,id=hostdev0,bus=usb.0,port=1

If nec-usb-xhci is changed to usb-ehci, qemu tries to boot without
assertion failures.


Can be reproduced with the latest master (commit dbe2b65) and v2.8.0.

Bisected the issue to following commit:
first bad commit: [94b037f2a451b3dc855f9f2c346e5049a361bd55] xhci: use linked 
list for transfers


Backtrace from commit dbe2b65:

#0  0x7f2eb4657227 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/unix/sysv/linux/raise.c:55
resultvar = 0
pid = 3453
selftid = 3453
#1  0x7f2eb465867a in __GI_abort () at abort.c:89
save_stage = 2
act = {__sigaction_handler = {sa_handler = 0x4, sa_sigaction = 0x4}, 
sa_mask = {__val = {140734740550528, 93876690035339, 
  140734740550624, 48833659808, 0, 0, 0, 21474836480, 
140734740550792, 139838573009553, 140734740550560, 139838573043008, 
  139838573024160, 9387665872, 139838702616576, 
139838573024160}}, sa_flags = 1528954938, 
  sa_restorer = 0x55615b2202c0 <__PRETTY_FUNCTION__.38612>}
sigs = {__val = {32, 0 }}
#2  0x7f2eb46502cd in __assert_fail_base (fmt=0x7f2eb47893a0 "%s%s%s:%u: 
%s%sAssertion `%s' failed.\n%n", 
assertion=assertion@entry=0x55615b22003a "!usb_packet_is_inflight(p)", 
file=file@entry=0x55615b21fdf0 "hw/usb/core.c", line=line@entry=619, 
function=function@entry=0x55615b2202c0 <__PRETTY_FUNCTION__.38612> 
"usb_packet_cleanup") at assert.c:92
str = 0x55615cfdf510 ""
total = 4096
#3  0x7f2eb4650382 in __GI___assert_fail (assertion=0x55615b22003a 
"!usb_packet_is_inflight(p)", file=0x55615b21fdf0 "hw/usb/core.c", 
line=619, function=0x55615b2202c0 <__PRETTY_FUNCTION__.38612> 
"usb_packet_cleanup") at assert.c:101
No locals.
#4  0x55615afc385e in usb_packet_cleanup ()
No symbol table info available.
#5  0x55615afda555 in xhci_ep_free_xfer ()
No symbol table info available.
#6  0x55615afdc156 in xhci_kick_epctx ()
No symbol table info available.
#7  0x55615afda099 in xhci_ep_kick_timer ()
No symbol table info available.
#8  0x55615b08ceee in timerlist_run_timers ()
No symbol table info available.
#9  0x55615b08cf36 in qemu_clock_run_timers ()
No symbol table info available.
#10 0x55615b08d2df in qemu_clock_run_all_timers ()
No symbol table info available.
#11 0x55615b08be40 in main_loop_wait ()
No symbol table info available.
#12 0x55615ae3870f in main_loop ()
No symbol table info available.
#13 0x55615ae4027b in main ()

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  Assertion failed with USB pass through with XHCI controller

Status in QEMU:
  New

Bug description:
  Starting qemu 2.8.0 with XHCI controller and host device passed
  through results in an assertion failure:

  qemu-system-x86_64: hw/usb/core.c:623: usb_packet_cleanup: Assertion
  `!usb_packet_is_inflight(p)' failed.

  Can be reproduced with the following command (passing through a Lenovo
  keyboard):

  qemu-system-x86_64 -usb  -device nec-usb-xhci,id=usb -device usb-
  host,vendorid=0x04b3,productid=0x3025,id=hostdev0,bus=usb.0,port=1

  If nec-usb-xhci is changed to usb-ehci, qemu tries to boot without
  assertion failures.

  
  Can be reproduced with the latest master (commit dbe2b65) and v2.8.0.

  Bisected the issue to following commit:
  first bad commit: [94b037f2a451b3dc855f9f2c346e5049a361bd55] xhci: use linked 
list for transfers

  
  Backtrace from commit dbe2b65:

  #0  0x7f2eb4657227 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/unix/sysv/linux/raise.c:55
  resultvar = 0
  pid = 3453
  selftid = 3453
  #1  0x7f2eb465867a in __GI_abort () at abort.c:89
  save_stage = 2
  act = {__sigaction_handler = {sa_handler = 0x4, sa_sigaction = 0x4}, 
sa_mask = {__val = {140734740550528, 93876690035339, 
140734740550624, 48833659808, 0, 0, 0, 21474836480, 
140734740550792, 139838573009553, 140734740550560, 139838573043008, 
139838573024160, 9387665872, 139838702616576, 
139838573024160}}, sa_flags = 1528954938, 
sa_restorer = 0x55615b2202c0 <__PRETTY_FUNCTION__.38612>}
  sigs = {__val = {32, 0 }}
  #2  0x7f2eb46502cd in __assert_fail_base (fmt=0x7f2eb47893a0 "%s%s%s:%u: 
%s%sAssertion `%s' failed.\n%n", 
  assertion=assertion@entry=0x55615b22003a "!usb_packet_is_inflight(p)", 

[Qemu-devel] [PATCH] vl: disable default cdrom when using explicitely scsi-hd

2016-12-31 Thread Hervé Poussineau
'ide-hd', 'ide-cd' and 'scsi-cd' devices already disable default cdrom.
Make it the same for 'scsi-hd'.

That way, we can add/replace the device on lun=2 without using -nodefaults.

Signed-off-by: Hervé Poussineau 
---
 vl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/vl.c b/vl.c
index d77dd86..da97fe2 100644
--- a/vl.c
+++ b/vl.c
@@ -223,6 +223,7 @@ static struct {
 { .driver = "ide-hd",   .flag = _cdrom },
 { .driver = "ide-drive",.flag = _cdrom },
 { .driver = "scsi-cd",  .flag = _cdrom },
+{ .driver = "scsi-hd",  .flag = _cdrom },
 { .driver = "virtio-serial-pci",.flag = _virtcon   },
 { .driver = "virtio-serial",.flag = _virtcon   },
 { .driver = "VGA",  .flag = _vga   },
-- 
2.1.4




[Qemu-devel] [PATCH V3 1/7] nios2: Add disas entries

2016-12-31 Thread Marek Vasut
Add nios2 disassembler support. This patch is composed from binutils files
from commit "Opcodes and assembler support for Nios II R2". The files from
binutils used in this patch are:

include/opcode/nios2.h
include/opcode/nios2r1.h
include/opcode/nios2r2.h
opcodes/nios2-opc.c
opcodes/nios2-dis.c

Checkpatch says total: 114 errors, 0 warnings, 3609 lines checked , which
is caused by a different coding style in those files. These warnings and
errors are not addressed To let these files be easily synchronized between
binutils and qemu.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
---
V2: Replace the nios2.c with GPL2 licensed version
V3: Rebase on top of qemu/master
---
 disas/Makefile.objs |1 +
 disas/nios2.c   | 3534 +++
 include/disas/bfd.h |6 +
 3 files changed, 3541 insertions(+)
 create mode 100644 disas/nios2.c

diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 09bc992..ac79d16 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -14,6 +14,7 @@ common-obj-$(CONFIG_IA64_DIS) += ia64.o
 common-obj-$(CONFIG_M68K_DIS) += m68k.o
 common-obj-$(CONFIG_MICROBLAZE_DIS) += microblaze.o
 common-obj-$(CONFIG_MIPS_DIS) += mips.o
+common-obj-$(CONFIG_NIOS2_DIS) += nios2.o
 common-obj-$(CONFIG_MOXIE_DIS) += moxie.o
 common-obj-$(CONFIG_PPC_DIS) += ppc.o
 common-obj-$(CONFIG_S390_DIS) += s390.o
diff --git a/disas/nios2.c b/disas/nios2.c
new file mode 100644
index 000..b342936
--- /dev/null
+++ b/disas/nios2.c
@@ -0,0 +1,3534 @@
+/* Nios II opcode library for QEMU.
+   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+   Contributed by Nigel Gray (ng...@altera.com).
+   Contributed by Mentor Graphics, Inc.
+
+   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, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA  02110-1301, USA.  */
+
+/* This file resembles a concatenation of the following files from
+   binutils:
+
+   include/opcode/nios2.h
+   include/opcode/nios2r1.h
+   include/opcode/nios2r2.h
+   opcodes/nios2-opc.c
+   opcodes/nios2-dis.c
+
+   It has been derived from the original patches which have been
+   relicensed by the contributors as GPL version 2 for inclusion
+   in QEMU.  */
+
+#ifndef _NIOS2_H_
+#define _NIOS2_H_
+
+/*#include "bfd.h"*/
+#include "qemu/osdep.h"
+#include "disas/bfd.h"
+
+
+/
+ * This file contains structures, bit masks and shift counts used
+ * by the GNU toolchain to define the Nios II instruction set and
+ * access various opcode fields.
+ /
+
+/* Instruction encoding formats.  */
+enum iw_format_type {
+  /* R1 formats.  */
+  iw_i_type,
+  iw_r_type,
+  iw_j_type,
+  iw_custom_type,
+
+  /* 32-bit R2 formats.  */
+  iw_L26_type,
+  iw_F2I16_type,
+  iw_F2X4I12_type,
+  iw_F1X4I12_type,
+  iw_F1X4L17_type,
+  iw_F3X6L5_type,
+  iw_F2X6L10_type,
+  iw_F3X6_type,
+  iw_F3X8_type,
+
+  /* 16-bit R2 formats.  */
+  iw_I10_type,
+  iw_T1I7_type,
+  iw_T2I4_type,
+  iw_T1X1I6_type,
+  iw_X1I7_type,
+  iw_L5I4X1_type,
+  iw_T2X1L3_type,
+  iw_T2X1I3_type,
+  iw_T3X1_type,
+  iw_T2X3_type,
+  iw_F1X1_type,
+  iw_X2L5_type,
+  iw_F1I5_type,
+  iw_F2_type
+};
+
+/* Identify different overflow situations for error messages.  */
+enum overflow_type
+{
+  call_target_overflow = 0,
+  branch_target_overflow,
+  address_offset_overflow,
+  signed_immed16_overflow,
+  unsigned_immed16_overflow,
+  unsigned_immed5_overflow,
+  signed_immed12_overflow,
+  custom_opcode_overflow,
+  enumeration_overflow,
+  no_overflow
+};
+
+/* This structure holds information for a particular instruction. 
+
+   The args field is a string describing the operands.  The following
+   letters can appear in the args:
+ c - a 5-bit control register index
+ d - a 5-bit destination register index
+ s - a 5-bit left source register index
+ t - a 5-bit right source register index
+ D - a 3-bit encoded destination register
+ S - a 3-bit encoded left source register
+ T - a 3-bit encoded right source register
+ i - a 16-bit signed 

[Qemu-devel] [PATCH V4 3/7] nios2: Add usermode binaries emulation

2016-12-31 Thread Marek Vasut
Add missing bits for qemu-user required for emulating Altera Nios2
userspace binaries.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
---
V3: Checkpatch cleanup
V4: Rebase on top of qemu/master
---
 include/elf.h |   2 +
 linux-user/elfload.c  |  57 +++
 linux-user/main.c | 140 +++-
 linux-user/nios2/syscall_nr.h | 329 ++
 linux-user/nios2/target_cpu.h |  39 +
 linux-user/nios2/target_signal.h  |  26 +++
 linux-user/nios2/target_structs.h |  58 +++
 linux-user/nios2/target_syscall.h |  37 +
 linux-user/nios2/termbits.h   | 220 +
 linux-user/signal.c   | 238 ++-
 linux-user/syscall_defs.h |   8 +-
 11 files changed, 1147 insertions(+), 7 deletions(-)
 create mode 100644 linux-user/nios2/syscall_nr.h
 create mode 100644 linux-user/nios2/target_cpu.h
 create mode 100644 linux-user/nios2/target_signal.h
 create mode 100644 linux-user/nios2/target_structs.h
 create mode 100644 linux-user/nios2/target_syscall.h
 create mode 100644 linux-user/nios2/termbits.h

diff --git a/include/elf.h b/include/elf.h
index 1c2975d..0dbd3e9 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -126,6 +126,8 @@ typedef int64_t  Elf64_Sxword;
  */
 #define EM_S390_OLD 0xA390
 
+#define EM_ALTERA_NIOS2 113 /* Altera Nios II soft-core processor */
+
 #define EM_MICROBLAZE  189
 #define EM_MICROBLAZE_OLD  0xBAAB
 
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 547053c..17f7766 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -967,6 +967,63 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, 
const CPUMBState *env
 
 #endif /* TARGET_MICROBLAZE */
 
+#ifdef TARGET_NIOS2
+
+#define ELF_START_MMAP 0x8000
+
+#define elf_check_arch(x) ((x) == EM_ALTERA_NIOS2)
+
+#define ELF_CLASS   ELFCLASS32
+#define ELF_ARCHEM_ALTERA_NIOS2
+
+static void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+regs->ea = infop->entry;
+regs->sp = infop->start_stack;
+regs->estatus = 0x3;
+}
+
+#define ELF_EXEC_PAGESIZE4096
+
+#define USE_ELF_CORE_DUMP
+#define ELF_NREG 49
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+/* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs.  */
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+   const CPUNios2State *env)
+{
+int i;
+
+(*regs)[0] = -1;
+for (i = 1; i < 8; i++)/* r0-r7 */
+(*regs)[i] = tswapreg(env->regs[i + 7]);
+
+for (i = 8; i < 16; i++)   /* r8-r15 */
+(*regs)[i] = tswapreg(env->regs[i - 8]);
+
+for (i = 16; i < 24; i++)  /* r16-r23 */
+(*regs)[i] = tswapreg(env->regs[i + 7]);
+(*regs)[24] = -1;/* R_ET */
+(*regs)[25] = -1;/* R_BT */
+(*regs)[26] = tswapreg(env->regs[R_GP]);
+(*regs)[27] = tswapreg(env->regs[R_SP]);
+(*regs)[28] = tswapreg(env->regs[R_FP]);
+(*regs)[29] = tswapreg(env->regs[R_EA]);
+(*regs)[30] = -1;/* R_SSTATUS */
+(*regs)[31] = tswapreg(env->regs[R_RA]);
+
+(*regs)[32] = tswapreg(env->regs[R_PC]);
+
+(*regs)[33] = -1; /* R_STATUS */
+(*regs)[34] = tswapreg(env->regs[CR_ESTATUS]);
+
+for (i = 35; i < 49; i++)/* ... */
+(*regs)[i] = -1;
+}
+
+#endif /* TARGET_NIOS2 */
+
 #ifdef TARGET_OPENRISC
 
 #define ELF_START_MMAP 0x0800
diff --git a/linux-user/main.c b/linux-user/main.c
index c1d5eb4..32b7115 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -68,8 +68,11 @@ do { 
   \
  * This way we will never overlap with our own libraries or binaries or stack
  * or anything else that QEMU maps.
  */
-# ifdef TARGET_MIPS
-/* MIPS only supports 31 bits of virtual address space for user space */
+# if defined(TARGET_MIPS) || defined(TARGET_NIOS2)
+/*
+ * MIPS only supports 31 bits of virtual address space for user space.
+ * Nios2 also only supports 31 bits.
+ */
 unsigned long reserved_va = 0x7700;
 # else
 unsigned long reserved_va = 0xf700;
@@ -2462,6 +2465,109 @@ error:
 }
 #endif
 
+#ifdef TARGET_NIOS2
+
+void cpu_loop(CPUNios2State *env)
+{
+CPUState *cs = ENV_GET_CPU(env);
+Nios2CPU *cpu = NIOS2_CPU(cs);
+target_siginfo_t info;
+int trapnr, gdbsig, ret;
+
+for (;;) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+gdbsig = 0;
+
+switch (trapnr) {
+case EXCP_INTERRUPT:
+/* just indicate that signals should be handled asap */
+break;
+case EXCP_TRAP:
+if (env->regs[R_AT] == 0) {
+abi_long ret;
+

[Qemu-devel] [PATCH V8 2/7] nios2: Add architecture emulation support

2016-12-31 Thread Marek Vasut
From: Chris Wulff 

Add support for emulating Altera NiosII R1 architecture into qemu.
This patch is based on previous work by Chris Wulff from 2012 and
updated to latest mainline QEMU.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
---
V3: Thorough cleanup, deal with the review comments all over the place
V4: - Use extract32()
- Fix gen_goto_tb() , suppress tcg_gen_goto_tb()
- Clean up gen_check_supervisor() helper
- Use TCGMemOp type for flags
- Drop jump labels from wrctl/rdctl
- More TCG cleanup
V5: - Simplify load/store handling
- Handle loads into R_ZERO from protected page, add comment
V6: - Fix division opcode handling
- Add missing disas handling
- V5 review comments cleanup
V7: - Drop newline at the end of file
V8: - Rebase on top of qemu/master
- Move the target-nios2 to target/nios2
---
 target/nios2/Makefile.objs |   4 +
 target/nios2/cpu.c | 232 +++
 target/nios2/cpu.h | 269 +
 target/nios2/helper.c  | 313 +++
 target/nios2/helper.h  |  27 ++
 target/nios2/mmu.c | 292 ++
 target/nios2/mmu.h |  54 +++
 target/nios2/monitor.c |  35 ++
 target/nios2/op_helper.c   |  47 +++
 target/nios2/translate.c   | 953 +
 10 files changed, 2226 insertions(+)
 create mode 100644 target/nios2/Makefile.objs
 create mode 100644 target/nios2/cpu.c
 create mode 100644 target/nios2/cpu.h
 create mode 100644 target/nios2/helper.c
 create mode 100644 target/nios2/helper.h
 create mode 100644 target/nios2/mmu.c
 create mode 100644 target/nios2/mmu.h
 create mode 100644 target/nios2/monitor.c
 create mode 100644 target/nios2/op_helper.c
 create mode 100644 target/nios2/translate.c

diff --git a/target/nios2/Makefile.objs b/target/nios2/Makefile.objs
new file mode 100644
index 000..2a11c5c
--- /dev/null
+++ b/target/nios2/Makefile.objs
@@ -0,0 +1,4 @@
+obj-y += translate.o op_helper.o helper.o cpu.o mmu.o
+obj-$(CONFIG_SOFTMMU) += monitor.o
+
+$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
new file mode 100644
index 000..658d684
--- /dev/null
+++ b/target/nios2/cpu.c
@@ -0,0 +1,232 @@
+/*
+ * QEMU Nios II CPU
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "exec/log.h"
+#include "exec/gdbstub.h"
+#include "hw/qdev-properties.h"
+
+static void nios2_cpu_set_pc(CPUState *cs, vaddr value)
+{
+Nios2CPU *cpu = NIOS2_CPU(cs);
+CPUNios2State *env = >env;
+
+env->regs[R_PC] = value;
+}
+
+static bool nios2_cpu_has_work(CPUState *cs)
+{
+return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+/* CPUClass::reset() */
+static void nios2_cpu_reset(CPUState *cs)
+{
+Nios2CPU *cpu = NIOS2_CPU(cs);
+Nios2CPUClass *ncc = NIOS2_CPU_GET_CLASS(cpu);
+CPUNios2State *env = >env;
+
+if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+qemu_log("CPU Reset (CPU %d)\n", cs->cpu_index);
+log_cpu_state(cs, 0);
+}
+
+ncc->parent_reset(cs);
+
+tlb_flush(cs, 1);
+
+memset(env->regs, 0, sizeof(uint32_t) * NUM_CORE_REGS);
+env->regs[R_PC] = cpu->reset_addr;
+
+#if defined(CONFIG_USER_ONLY)
+/* Start in user mode with interrupts enabled. */
+env->regs[CR_STATUS] = CR_STATUS_U | CR_STATUS_PIE;
+#endif
+}
+
+static void nios2_cpu_initfn(Object *obj)
+{
+CPUState *cs = CPU(obj);
+Nios2CPU *cpu = NIOS2_CPU(obj);
+CPUNios2State *env = >env;
+static bool tcg_initialized;
+
+cpu->mmu_present = true;
+cs->env_ptr = env;
+
+#if !defined(CONFIG_USER_ONLY)
+mmu_init(>mmu);
+#endif
+
+if (tcg_enabled() && !tcg_initialized) {
+tcg_initialized = true;
+nios2_tcg_init();
+}
+}
+
+Nios2CPU *cpu_nios2_init(const char *cpu_model)
+{
+Nios2CPU *cpu = NIOS2_CPU(object_new(TYPE_NIOS2_CPU));
+
+object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+
+return cpu;
+}

[Qemu-devel] [PATCH V5 6/7] nios2: Add Altera 10M50 GHRD emulation

2016-12-31 Thread Marek Vasut
Add the Altera 10M50 Nios2 GHRD model. This allows emulating the
10M50 development kit with the Nios2 GHRD loaded in the FPGA. It
is possible to boot Linux kernel and run userspace, thus far only
from initrd as storage support is not yet implemented.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
---
V3: Checkpatch cleanup, move cpu_pic.c here
V4: Add initrd DT address translation (thanks Guenter)
V5: Rebase on top of qemu/master
---
 hw/nios2/10m50_devboard.c | 126 ++
 hw/nios2/Makefile.objs|   1 +
 hw/nios2/boot.c   | 223 ++
 hw/nios2/boot.h   |  11 +++
 hw/nios2/cpu_pic.c|  70 +++
 5 files changed, 431 insertions(+)
 create mode 100644 hw/nios2/10m50_devboard.c
 create mode 100644 hw/nios2/Makefile.objs
 create mode 100644 hw/nios2/boot.c
 create mode 100644 hw/nios2/boot.h
 create mode 100644 hw/nios2/cpu_pic.c

diff --git a/hw/nios2/10m50_devboard.c b/hw/nios2/10m50_devboard.c
new file mode 100644
index 000..62e5738
--- /dev/null
+++ b/hw/nios2/10m50_devboard.c
@@ -0,0 +1,126 @@
+/*
+ * Altera 10M50 Nios2 GHRD
+ *
+ * Copyright (c) 2016 Marek Vasut 
+ *
+ * Based on LabX device code
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+#include "hw/char/serial.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+#include "qemu/config-file.h"
+
+#include "boot.h"
+
+#define BINARY_DEVICE_TREE_FILE"10m50-devboard.dtb"
+
+static void nios2_10m50_ghrd_init(MachineState *machine)
+{
+Nios2CPU *cpu;
+DeviceState *dev;
+MemoryRegion *address_space_mem = get_system_memory();
+MemoryRegion *phys_tcm = g_new(MemoryRegion, 1);
+MemoryRegion *phys_tcm_alias = g_new(MemoryRegion, 1);
+MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
+MemoryRegion *phys_ram_alias = g_new(MemoryRegion, 1);
+ram_addr_t tcm_base = 0x0;
+ram_addr_t tcm_size = 0x1000;/* 1 kiB, but QEMU limit is 4 kiB */
+ram_addr_t ram_base = 0x0800;
+ram_addr_t ram_size = 0x0800;
+qemu_irq *cpu_irq, irq[32];
+int i;
+
+/* Physical TCM (tb_ram_1k) with alias at 0xc000 */
+memory_region_init_ram(phys_tcm, NULL, "nios2.tcm", tcm_size, 
_abort);
+memory_region_init_alias(phys_tcm_alias, NULL, "nios2.tcm.alias",
+ phys_tcm, 0, tcm_size);
+vmstate_register_ram_global(phys_tcm);
+memory_region_add_subregion(address_space_mem, tcm_base, phys_tcm);
+memory_region_add_subregion(address_space_mem, 0xc000 + tcm_base,
+phys_tcm_alias);
+
+/* Physical DRAM with alias at 0xc000 */
+memory_region_init_ram(phys_ram, NULL, "nios2.ram", ram_size, 
_abort);
+memory_region_init_alias(phys_ram_alias, NULL, "nios2.ram.alias",
+ phys_ram, 0, ram_size);
+vmstate_register_ram_global(phys_ram);
+memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+memory_region_add_subregion(address_space_mem, 0xc000 + ram_base,
+phys_ram_alias);
+
+/* Create CPU -- FIXME */
+cpu = cpu_nios2_init("nios2");
+
+/* Register: CPU interrupt controller (PIC) */
+cpu_irq = nios2_cpu_pic_init(cpu);
+
+/* Register: Internal Interrupt Controller (IIC) */
+dev = qdev_create(NULL, "altera,iic");
+qdev_prop_set_ptr(dev, "cpu", cpu);
+qdev_init_nofail(dev);
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, cpu_irq[0]);
+for (i = 0; i < 32; i++) {
+irq[i] = qdev_get_gpio_in(dev, i);
+}
+
+/* Register: Altera 16550 UART */
+serial_mm_init(address_space_mem, 0xf8001600, 2, irq[1], 115200,
+   serial_hds[0], DEVICE_NATIVE_ENDIAN);
+
+/* Register: Timer sys_clk_timer  */
+dev = qdev_create(NULL, "ALTR.timer");
+qdev_prop_set_uint32(dev, 

[Qemu-devel] [PATCH V4 7/7] nios2: Add support for Nios-II R1

2016-12-31 Thread Marek Vasut
Add remaining bits of the Altera NiosII R1 support into qemu, which
is documentation, MAINTAINERS file entry, configure bits, arch_init
and configuration files for both linux-user (userland binaries) and
softmmu (hardware emulation).

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
---
V3: Checkpatch cleanup
V4: Rebase on top of qemu/master
---
 MAINTAINERS  | 8 
 arch_init.c  | 2 ++
 configure| 5 +
 default-configs/nios2-linux-user.mak | 1 +
 default-configs/nios2-softmmu.mak| 6 ++
 include/sysemu/arch_init.h   | 1 +
 qemu-doc.texi| 3 +++
 7 files changed, 26 insertions(+)
 create mode 100644 default-configs/nios2-linux-user.mak
 create mode 100644 default-configs/nios2-softmmu.mak

diff --git a/MAINTAINERS b/MAINTAINERS
index 585cd5a..aa7f8fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -181,6 +181,14 @@ F: disas/moxie.c
 F: hw/moxie/
 F: default-configs/moxie-softmmu.mak
 
+NiosII
+M: Chris Wulff 
+M: Marek Vasut 
+S: Maintained
+F: target/nios2/
+F: hw/nios2/
+F: disas/nios2.c
+
 OpenRISC
 M: Jia Liu 
 S: Maintained
diff --git a/arch_init.c b/arch_init.c
index 5cc58b2..20d83ff 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -64,6 +64,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_MIPS
 #elif defined(TARGET_MOXIE)
 #define QEMU_ARCH QEMU_ARCH_MOXIE
+#elif defined(TARGET_NIOS2)
+#define QEMU_ARCH QEMU_ARCH_NIOS2
 #elif defined(TARGET_OPENRISC)
 #define QEMU_ARCH QEMU_ARCH_OPENRISC
 #elif defined(TARGET_PPC)
diff --git a/configure b/configure
index 218df87..81604f1 100755
--- a/configure
+++ b/configure
@@ -5935,6 +5935,8 @@ case "$target_name" in
   ;;
   moxie)
   ;;
+  nios2)
+  ;;
   or32)
 TARGET_ARCH=openrisc
 TARGET_BASE_ARCH=openrisc
@@ -6128,6 +6130,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   moxie*)
 disas_config "MOXIE"
   ;;
+  nios2)
+disas_config "NIOS2"
+  ;;
   or32)
 disas_config "OPENRISC"
   ;;
diff --git a/default-configs/nios2-linux-user.mak 
b/default-configs/nios2-linux-user.mak
new file mode 100644
index 000..5be3eb7
--- /dev/null
+++ b/default-configs/nios2-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for nios2-linux-user
diff --git a/default-configs/nios2-softmmu.mak 
b/default-configs/nios2-softmmu.mak
new file mode 100644
index 000..74dc70c
--- /dev/null
+++ b/default-configs/nios2-softmmu.mak
@@ -0,0 +1,6 @@
+# Default configuration for nios2-softmmu
+
+CONFIG_NIOS2=y
+CONFIG_SERIAL=y
+CONFIG_PTIMER=y
+CONFIG_ALTERA_TIMER=y
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 1c9dad1..fe60e11 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
 QEMU_ARCH_UNICORE32 = (1 << 14),
 QEMU_ARCH_MOXIE = (1 << 15),
 QEMU_ARCH_TRICORE = (1 << 16),
+QEMU_ARCH_NIOS2 = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 02cb39d..672ed3a 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2891,6 +2891,9 @@ The binary format is detected automatically.
 @command{qemu-mips} TODO.
 @command{qemu-mipsel} TODO.
 
+@cindex user mode (NiosII)
+@command{qemu-nios2} TODO.
+
 @cindex user mode (PowerPC)
 @command{qemu-ppc64abi32} TODO.
 @command{qemu-ppc64} TODO.
-- 
2.10.2




[Qemu-devel] [PATCH V4 4/7] nios2: Add IIC interrupt controller emulation

2016-12-31 Thread Marek Vasut
From: Chris Wulff 

Add the Altera Nios2 internal interrupt controller model.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
---
V3: Checkpatch cleanup
V4: Rebase on top of qemu/master
---
 hw/intc/Makefile.objs |   1 +
 hw/intc/nios2_iic.c   | 103 ++
 2 files changed, 104 insertions(+)
 create mode 100644 hw/intc/nios2_iic.c

diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 2f44a2d..8948106 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -41,3 +41,4 @@ obj-$(CONFIG_S390_FLIC_KVM) += s390_flic_kvm.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_vic.o
 obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
 obj-$(CONFIG_MIPS_CPS) += mips_gic.o
+obj-$(CONFIG_NIOS2) += nios2_iic.o
diff --git a/hw/intc/nios2_iic.c b/hw/intc/nios2_iic.c
new file mode 100644
index 000..818ab1b
--- /dev/null
+++ b/hw/intc/nios2_iic.c
@@ -0,0 +1,103 @@
+/*
+ * QEMU Altera Internal Interrupt Controller.
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+
+#include "hw/sysbus.h"
+#include "cpu.h"
+
+#define TYPE_ALTERA_IIC "altera,iic"
+#define ALTERA_IIC(obj) \
+OBJECT_CHECK(AlteraIIC, (obj), TYPE_ALTERA_IIC)
+
+typedef struct AlteraIIC {
+SysBusDevice  parent_obj;
+void *cpu;
+qemu_irq  parent_irq;
+} AlteraIIC;
+
+static void update_irq(AlteraIIC *pv)
+{
+CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
+
+qemu_set_irq(pv->parent_irq,
+ env->regs[CR_IPENDING] & env->regs[CR_IENABLE]);
+}
+
+static void irq_handler(void *opaque, int irq, int level)
+{
+AlteraIIC *pv = opaque;
+CPUNios2State *env = &((Nios2CPU *)(pv->cpu))->env;
+
+env->regs[CR_IPENDING] &= ~(1 << irq);
+env->regs[CR_IPENDING] |= !!level << irq;
+
+update_irq(pv);
+}
+
+static void altera_iic_init(Object *obj)
+{
+AlteraIIC *pv = ALTERA_IIC(obj);
+
+qdev_init_gpio_in(DEVICE(pv), irq_handler, 32);
+sysbus_init_irq(SYS_BUS_DEVICE(obj), >parent_irq);
+}
+
+static Property altera_iic_properties[] = {
+DEFINE_PROP_PTR("cpu", AlteraIIC, cpu),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void altera_iic_realize(DeviceState *dev, Error **errp)
+{
+struct AlteraIIC *pv = ALTERA_IIC(dev);
+
+if (!pv->cpu) {
+error_setg(errp, "altera,iic: CPU not connected");
+return;
+}
+}
+
+static void altera_iic_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->props = altera_iic_properties;
+/* Reason: pointer property "cpu" */
+dc->cannot_instantiate_with_device_add_yet = true;
+dc->realize = altera_iic_realize;
+}
+
+static TypeInfo altera_iic_info = {
+.name  = "altera,iic",
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(AlteraIIC),
+.instance_init = altera_iic_init,
+.class_init= altera_iic_class_init,
+};
+
+static void altera_iic_register(void)
+{
+type_register_static(_iic_info);
+}
+
+type_init(altera_iic_register)
-- 
2.10.2




[Qemu-devel] [PATCH V4 5/7] nios2: Add periodic timer emulation

2016-12-31 Thread Marek Vasut
From: Chris Wulff 

Add the Altera timer model.

Signed-off-by: Marek Vasut 
Cc: Chris Wulff 
Cc: Jeff Da Silva 
Cc: Ley Foon Tan 
Cc: Sandra Loosemore 
Cc: Yves Vandervennet 
---
V3: Checkpatch cleanup
V4: Rebase on top of qemu/master
---
 hw/timer/Makefile.objs  |   1 +
 hw/timer/altera_timer.c | 237 
 2 files changed, 238 insertions(+)
 create mode 100644 hw/timer/altera_timer.c

diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 7ba8c23..0867a64 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
 
+obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_rtc.o
diff --git a/hw/timer/altera_timer.c b/hw/timer/altera_timer.c
new file mode 100644
index 000..885242b
--- /dev/null
+++ b/hw/timer/altera_timer.c
@@ -0,0 +1,237 @@
+/*
+ * QEMU model of the Altera timer.
+ *
+ * Copyright (c) 2012 Chris Wulff 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/error.h"
+
+#include "hw/sysbus.h"
+#include "sysemu/sysemu.h"
+#include "hw/ptimer.h"
+
+#define R_STATUS  0
+#define R_CONTROL 1
+#define R_PERIODL 2
+#define R_PERIODH 3
+#define R_SNAPL   4
+#define R_SNAPH   5
+#define R_MAX 6
+
+#define STATUS_TO 0x0001
+#define STATUS_RUN0x0002
+
+#define CONTROL_ITO   0x0001
+#define CONTROL_CONT  0x0002
+#define CONTROL_START 0x0004
+#define CONTROL_STOP  0x0008
+
+#define TYPE_ALTERA_TIMER "ALTR.timer"
+#define ALTERA_TIMER(obj) \
+OBJECT_CHECK(AlteraTimer, (obj), TYPE_ALTERA_TIMER)
+
+typedef struct AlteraTimer {
+SysBusDevice  busdev;
+MemoryRegion  mmio;
+qemu_irq  irq;
+uint32_t  freq_hz;
+QEMUBH   *bh;
+ptimer_state *ptimer;
+uint32_t  regs[R_MAX];
+} AlteraTimer;
+
+static int timer_irq_state(AlteraTimer *t)
+{
+bool irq = (t->regs[R_STATUS] & STATUS_TO) &&
+   (t->regs[R_CONTROL] & CONTROL_ITO);
+return irq;
+}
+
+static uint64_t timer_read(void *opaque, hwaddr addr,
+   unsigned int size)
+{
+AlteraTimer *t = opaque;
+uint64_t r = 0;
+
+addr >>= 2;
+addr &= 0x7;
+switch (addr) {
+case R_CONTROL:
+r = t->regs[R_CONTROL] & (CONTROL_ITO | CONTROL_CONT);
+break;
+
+default:
+if (addr < ARRAY_SIZE(t->regs)) {
+r = t->regs[addr];
+}
+break;
+}
+
+return r;
+}
+
+static void timer_write(void *opaque, hwaddr addr,
+uint64_t value, unsigned int size)
+{
+AlteraTimer *t = opaque;
+uint64_t tvalue;
+uint32_t count = 0;
+int irqState = timer_irq_state(t);
+
+addr >>= 2;
+addr &= 0x7;
+switch (addr) {
+case R_STATUS:
+/* The timeout bit is cleared by writing the status register. */
+t->regs[R_STATUS] &= ~STATUS_TO;
+break;
+
+case R_CONTROL:
+t->regs[R_CONTROL] = value & (CONTROL_ITO | CONTROL_CONT);
+if ((value & CONTROL_START) &&
+!(t->regs[R_STATUS] & STATUS_RUN)) {
+ptimer_run(t->ptimer, 1);
+t->regs[R_STATUS] |= STATUS_RUN;
+}
+if ((value & CONTROL_STOP) && (t->regs[R_STATUS] & STATUS_RUN)) {
+ptimer_stop(t->ptimer);
+t->regs[R_STATUS] &= ~STATUS_RUN;
+}
+break;
+
+case R_PERIODL:
+case R_PERIODH:
+t->regs[addr] = value & 0x;
+if (t->regs[R_STATUS] & STATUS_RUN) {
+ptimer_stop(t->ptimer);
+t->regs[R_STATUS] &= ~STATUS_RUN;
+}
+tvalue = (t->regs[R_PERIODH] << 16) | t->regs[R_PERIODL];
+ptimer_set_limit(t->ptimer, tvalue + 1, 1);
+break;
+
+case R_SNAPL:
+case R_SNAPH:
+count = ptimer_get_count(t->ptimer);
+t->regs[R_SNAPL] = count & 0x;
+t->regs[R_SNAPH] = count >> 16;
+break;
+
+  

Re: [Qemu-devel] [PATCH RFC v11 0/4] vfio-pci: pass non-fatal error to guest

2016-12-31 Thread no-reply
Hi,

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

Message-id: 1483175588-17006-1-git-send-email-caoj.f...@cn.fujitsu.com
Type: series
Subject: [Qemu-devel] [PATCH RFC v11 0/4] vfio-pci: pass non-fatal error to 
guest

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

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

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

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

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] 
patchew/1483175588-17006-1-git-send-email-caoj.f...@cn.fujitsu.com -> 
patchew/1483175588-17006-1-git-send-email-caoj.f...@cn.fujitsu.com
Switched to a new branch 'test'
7f7bb75 vfio: add 'aer' property to expose aercap
a62d474 vfio-pci: pass the aer error to guest
6678558 vfio: new function to init aer cap for vfio device
6e3e08c pcie_aer: support configurable AER capa version

=== OUTPUT BEGIN ===
Checking PATCH 1/4: pcie_aer: support configurable AER capa version...
Checking PATCH 2/4: vfio: new function to init aer cap for vfio device...
Checking PATCH 3/4: vfio-pci: pass the aer error to guest...
ERROR: do not use C99 // comments
#44: FILE: hw/vfio/pci.c:2486:
+return; //Or goto stop?

ERROR: code indent should never use tabs
#57: FILE: hw/vfio/pci.c:2499:
+^Iif (isfatal) {$

ERROR: code indent should never use tabs
#58: FILE: hw/vfio/pci.c:2500:
+^Igoto stop;$

ERROR: code indent should never use tabs
#59: FILE: hw/vfio/pci.c:2501:
+^I}$

total: 4 errors, 0 warnings, 63 lines checked

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

Checking PATCH 4/4: vfio: add 'aer' property to expose aercap...
=== OUTPUT END ===

Test command exited with code: 1


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

[Qemu-devel] [PATCH v2] vfio/pci: Support error recovery

2016-12-31 Thread Cao jin
Support serious device error recovery

Signed-off-by: Cao jin 
---
 drivers/vfio/pci/vfio_pci.c | 70 +++--
 drivers/vfio/pci/vfio_pci_private.h |  2 ++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 712a849..752af20 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -534,6 +534,15 @@ static long vfio_pci_ioctl(void *device_data,
 {
struct vfio_pci_device *vdev = device_data;
unsigned long minsz;
+   int ret;
+
+   if (vdev->aer_recovering && (cmd == VFIO_DEVICE_SET_IRQS ||
+   cmd == VFIO_DEVICE_RESET || cmd == VFIO_DEVICE_PCI_HOT_RESET)) {
+   ret = wait_for_completion_interruptible(
+   >aer_completion);
+   if (ret)
+   return ret;
+   }
 
if (cmd == VFIO_DEVICE_GET_INFO) {
struct vfio_device_info info;
@@ -953,6 +962,15 @@ static ssize_t vfio_pci_rw(void *device_data, char __user 
*buf,
 {
unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
struct vfio_pci_device *vdev = device_data;
+   int ret;
+
+   /* block all kinds of access during host recovery */
+   if (vdev->aer_recovering) {
+   ret = wait_for_completion_interruptible(
+   >aer_completion);
+   if (ret)
+   return ret;
+   }
 
if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)
return -EINVAL;
@@ -1117,6 +1135,7 @@ static int vfio_pci_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
vdev->irq_type = VFIO_PCI_NUM_IRQS;
mutex_init(>igate);
spin_lock_init(>irqlock);
+   init_completion(>aer_completion);
 
ret = vfio_add_group_dev(>dev, _pci_ops, vdev);
if (ret) {
@@ -1176,6 +1195,9 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct 
pci_dev *pdev,
 {
struct vfio_pci_device *vdev;
struct vfio_device *device;
+   u32 uncor_status;
+   unsigned int aer_cap_offset;
+   int ret;
 
device = vfio_device_get_from_dev(>dev);
if (device == NULL)
@@ -1187,10 +1209,29 @@ static pci_ers_result_t 
vfio_pci_aer_err_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_DISCONNECT;
}
 
+   /*
+* get device's uncorrectable error status as soon as possible,
+* and signal it to user space. The later we read it, the possibility
+* the register value is mangled grows.
+*/
+   aer_cap_offset = pci_find_ext_capability(vdev->pdev, 
PCI_EXT_CAP_ID_ERR);
+   ret = pci_read_config_dword(vdev->pdev, aer_cap_offset +
+PCI_ERR_UNCOR_STATUS, _status);
+if (ret)
+return PCI_ERS_RESULT_DISCONNECT;
+
+   pr_info("device %d got AER detect notification. uncorrectable error 
status = 0x%x\n", pdev->devfn, uncor_status);//to be removed
mutex_lock(>igate);
 
-   if (vdev->err_trigger)
-   eventfd_signal(vdev->err_trigger, 1);
+   vdev->aer_recovering = true;
+   reinit_completion(>aer_completion);
+
+   if (vdev->err_trigger && uncor_status) {
+   pr_info("device %d signal uncor status 0x%x to user",
+   pdev->devfn, uncor_status);
+   /* signal uncorrectable error status to user space */
+   eventfd_signal(vdev->err_trigger, uncor_status);
+}
 
mutex_unlock(>igate);
 
@@ -1199,8 +1240,33 @@ static pci_ers_result_t vfio_pci_aer_err_detected(struct 
pci_dev *pdev,
return PCI_ERS_RESULT_CAN_RECOVER;
 }
 
+static void vfio_pci_aer_resume(struct pci_dev *pdev)
+{
+   struct vfio_pci_device *vdev;
+   struct vfio_device *device;
+
+   device = vfio_device_get_from_dev(>dev);
+   if (device == NULL)
+   return;
+
+   vdev = vfio_device_data(device);
+   if (vdev == NULL) {
+   vfio_device_put(device);
+   return;
+   }
+
+   mutex_lock(>igate);
+   vdev->aer_recovering = false;
+   mutex_unlock(>igate);
+
+   complete_all(>aer_completion);
+
+   vfio_device_put(device);
+}
+
 static const struct pci_error_handlers vfio_err_handlers = {
.error_detected = vfio_pci_aer_err_detected,
+   .resume = vfio_pci_aer_resume,
 };
 
 static struct pci_driver vfio_pci_driver = {
diff --git a/drivers/vfio/pci/vfio_pci_private.h 
b/drivers/vfio/pci/vfio_pci_private.h
index 8a7d546..ba8471f 100644
--- a/drivers/vfio/pci/vfio_pci_private.h
+++ b/drivers/vfio/pci/vfio_pci_private.h
@@ -83,6 +83,8 @@ struct vfio_pci_device {
boolbardirty;
boolhas_vga;
boolneeds_reset;
+   boolaer_recovering;
+   struct completion   

[Qemu-devel] [PATCH RFC v11 4/4] vfio: add 'aer' property to expose aercap

2016-12-31 Thread Cao jin
From: Chen Fan 

Add 'aer' property, let user choose whether expose the aer capability
or not. Should disable aer feature by default, because only non-fatal
error is supported now.

Signed-off-by: Chen Fan 
Signed-off-by: Dou Liyang 
Signed-off-by: Cao jin 
---
 hw/vfio/pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 9861f72..fc9db66 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -3057,6 +3057,8 @@ static Property vfio_pci_dev_properties[] = {
 DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
sub_device_id, PCI_ANY_ID),
 DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
+DEFINE_PROP_BIT("aer", VFIOPCIDevice, features,
+VFIO_FEATURE_ENABLE_AER_BIT, false),
 /*
  * TODO - support passed fds... is this necessary?
  * DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name),
-- 
1.8.3.1






[Qemu-devel] [PATCH RFC v11 2/4] vfio: new function to init aer cap for vfio device

2016-12-31 Thread Cao jin
From: Chen Fan 

Introduce new function to initilize AER capability registers
for vfio-pci device.

Signed-off-by: Chen Fan 
Signed-off-by: Dou Liyang 
Signed-off-by: Cao jin 
---
 hw/vfio/pci.c | 87 +++
 hw/vfio/pci.h |  3 +++
 2 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index d7dbe0e..76a8ac3 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1851,18 +1851,81 @@ out:
 return 0;
 }
 
-static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
+static int vfio_setup_aer(VFIOPCIDevice *vdev, uint8_t cap_ver,
+  int pos, uint16_t size, Error **errp)
+{
+PCIDevice *pdev = >pdev;
+PCIDevice *dev_iter;
+uint8_t type;
+uint32_t errcap;
+
+/* In case the physical device has AER cap while user doesn't enable AER,
+ * still allocate the config space in the emulated device for AER */
+if (!(vdev->features & VFIO_FEATURE_ENABLE_AER)) {
+pcie_add_capability(pdev, PCI_EXT_CAP_ID_ERR,
+cap_ver, pos, size);
+return 0;
+}
+
+dev_iter = pci_bridge_get_device(pdev->bus);
+if (!dev_iter) {
+goto error;
+}
+
+while (dev_iter) {
+if (!pci_is_express(dev_iter)) {
+goto error;
+}
+
+type = pcie_cap_get_type(dev_iter);
+if ((type != PCI_EXP_TYPE_ROOT_PORT &&
+ type != PCI_EXP_TYPE_UPSTREAM &&
+ type != PCI_EXP_TYPE_DOWNSTREAM)) {
+goto error;
+}
+
+if (!dev_iter->exp.aer_cap) {
+goto error;
+}
+
+dev_iter = pci_bridge_get_device(dev_iter->bus);
+}
+
+errcap = vfio_pci_read_config(pdev, pos + PCI_ERR_CAP, 4);
+/*
+ * The ability to record multiple headers is depending on
+ * the state of the Multiple Header Recording Capable bit and
+ * enabled by the Multiple Header Recording Enable bit.
+ */
+if ((errcap & PCI_ERR_CAP_MHRC) &&
+(errcap & PCI_ERR_CAP_MHRE)) {
+pdev->exp.aer_log.log_max = PCIE_AER_LOG_MAX_DEFAULT;
+} else {
+pdev->exp.aer_log.log_max = 0;
+}
+
+pcie_cap_deverr_init(pdev);
+return pcie_aer_init(pdev, cap_ver, pos, size);
+
+error:
+error_setg(errp, "vfio: Unable to enable AER for device %s, parent bus "
+   "does not support AER signaling", vdev->vbasedev.name);
+return -1;
+}
+
+static int vfio_add_ext_cap(VFIOPCIDevice *vdev, Error **errp)
 {
 PCIDevice *pdev = >pdev;
 uint32_t header;
 uint16_t cap_id, next, size;
 uint8_t cap_ver;
 uint8_t *config;
+int ret = 0;
 
 /* Only add extended caps if we have them and the guest can see them */
 if (!pci_is_express(pdev) || !pci_bus_is_express(pdev->bus) ||
 !pci_get_long(pdev->config + PCI_CONFIG_SPACE_SIZE)) {
-return;
+return 0;
 }
 
 /*
@@ -1911,6 +1974,9 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
PCI_EXT_CAP_NEXT_MASK);
 
 switch (cap_id) {
+case PCI_EXT_CAP_ID_ERR:
+ret = vfio_setup_aer(vdev, cap_ver, next, size, errp);
+break;
 case PCI_EXT_CAP_ID_SRIOV: /* Read-only VF BARs confuse OVMF */
 case PCI_EXT_CAP_ID_ARI: /* XXX Needs next function virtualization */
 trace_vfio_add_ext_cap_dropped(vdev->vbasedev.name, cap_id, next);
@@ -1919,6 +1985,9 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
 pcie_add_capability(pdev, cap_id, cap_ver, next, size);
 }
 
+if (ret) {
+goto out;
+}
 }
 
 /* Cleanup chain head ID if necessary */
@@ -1926,8 +1995,9 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
 pci_set_word(pdev->config + PCI_CONFIG_SPACE_SIZE, 0);
 }
 
+out:
 g_free(config);
-return;
+return ret;
 }
 
 static int vfio_add_capabilities(VFIOPCIDevice *vdev, Error **errp)
@@ -1945,8 +2015,8 @@ static int vfio_add_capabilities(VFIOPCIDevice *vdev, 
Error **errp)
 return ret;
 }
 
-vfio_add_ext_cap(vdev);
-return 0;
+ret = vfio_add_ext_cap(vdev, errp);
+return ret;
 }
 
 static void vfio_pci_pre_reset(VFIOPCIDevice *vdev)
@@ -2769,6 +2839,13 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
 goto out_teardown;
 }
 
+if ((vdev->features & VFIO_FEATURE_ENABLE_AER) &&
+!pdev->exp.aer_cap) {
+error_setg(errp, "vfio: Unable to enable AER for device %s, device "
+   "does not support AER signaling", vdev->vbasedev.name);
+return;
+}
+
 if (vdev->vga) {
 vfio_vga_quirk_setup(vdev);
 }
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index a8366bb..64701c4 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -15,6 +15,7 @@
 #include "qemu-common.h"
 #include 

[Qemu-devel] [PATCH RFC v11 3/4] vfio-pci: pass the aer error to guest

2016-12-31 Thread Cao jin
From: Chen Fan 

When physical device has uncorrectable error hanppened, the vfio_pci
driver will signal the uncorrectable error status register value to
corresponding QEMU's vfio-pci device via the eventfd registered by this
device, then, the vfio-pci's error eventfd handler will be invoked in
event loop.

Construct and pass the aer message to root port, root port will trigger an
interrupt to signal guest, then, the guest driver will do the recovery.

Note: Now only support non-fatal error's recovery, fatal error will
still result in vm stop.

Signed-off-by: Chen Fan 
Signed-off-by: Dou Liyang 
Signed-off-by: Cao jin 
---
 hw/vfio/pci.c | 50 ++
 1 file changed, 42 insertions(+), 8 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 76a8ac3..9861f72 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2470,21 +2470,55 @@ static void vfio_put_device(VFIOPCIDevice *vdev)
 static void vfio_err_notifier_handler(void *opaque)
 {
 VFIOPCIDevice *vdev = opaque;
+PCIDevice *dev = >pdev;
+PCIEAERMsg msg = {
+.severity = 0,
+.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn,
+};
+int len;
+uint64_t uncor_status;
+
+/* Read uncorrectable error status from driver */
+len = read(vdev->err_notifier.rfd, _status, sizeof(uncor_status));
+if (len != sizeof(uncor_status)) {
+error_report("vfio-pci: uncor error status reading returns"
+ " invalid number of bytes: %d", len);
+return; //Or goto stop?
+}
+
+if (!(vdev->features & VFIO_FEATURE_ENABLE_AER)) {
+goto stop;
+}
+
+/* Populate the aer msg and send it to root port */
+if (dev->exp.aer_cap) {
+uint8_t *aer_cap = dev->config + dev->exp.aer_cap;
+bool isfatal = uncor_status &
+   pci_get_long(aer_cap + PCI_ERR_UNCOR_SEVER);
+
+   if (isfatal) {
+   goto stop;
+   }
+
+msg.severity = isfatal ? PCI_ERR_ROOT_CMD_FATAL_EN :
+ PCI_ERR_ROOT_CMD_NONFATAL_EN;
 
-if (!event_notifier_test_and_clear(>err_notifier)) {
+error_report("vfio-pci device %d sending AER to root port. uncor"
+ " status = 0x%"PRIx64, dev->devfn, uncor_status);
+pcie_aer_msg(dev, );
 return;
 }
 
+stop:
 /*
- * TBD. Retrieve the error details and decide what action
- * needs to be taken. One of the actions could be to pass
- * the error to the guest and have the guest driver recover
- * from the error. This requires that PCIe capabilities be
- * exposed to the guest. For now, we just terminate the
- * guest to contain the error.
+ * Terminate the guest in case of
+ * 1. AER capability is not exposed to guest.
+ * 2. AER capability is exposed, but error is fatal, only non-fatal
+ * error is handled now.
  */
 
-error_report("%s(%s) Unrecoverable error detected. Please collect any data 
possible and then kill the guest", __func__, vdev->vbasedev.name);
+error_report("%s(%s) fatal error detected. Please collect any data"
+" possible and then kill the guest", __func__, 
vdev->vbasedev.name);
 
 vm_stop(RUN_STATE_INTERNAL_ERROR);
 }
-- 
1.8.3.1






[Qemu-devel] [PATCH v11 1/4] pcie_aer: support configurable AER capa version

2016-12-31 Thread Cao jin
From: Dou Liyang 

Now, AER capa version is fixed to v2, if assigned device is actually
v1, this value will be inconsistent between guest and host

Signed-off-by: Dou Liyang 
Signed-off-by: Cao jin 
---
 hw/net/e1000e.c| 3 ++-
 hw/pci-bridge/ioh3420.c| 2 +-
 hw/pci-bridge/xio3130_downstream.c | 2 +-
 hw/pci-bridge/xio3130_upstream.c   | 2 +-
 hw/pci/pcie_aer.c  | 5 +++--
 include/hw/pci/pcie_aer.h  | 3 ++-
 6 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index 4994e1c..66de849 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -472,7 +472,8 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error 
**errp)
 hw_error("Failed to initialize PM capability");
 }
 
-if (pcie_aer_init(pci_dev, e1000e_aer_offset, PCI_ERR_SIZEOF) < 0) {
+if (pcie_aer_init(pci_dev, PCI_ERR_VER, e1000e_aer_offset,
+  PCI_ERR_SIZEOF) < 0) {
 hw_error("Failed to initialize AER capability");
 }
 
diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
index c8b5ac4..d70784c 100644
--- a/hw/pci-bridge/ioh3420.c
+++ b/hw/pci-bridge/ioh3420.c
@@ -135,7 +135,7 @@ static int ioh3420_initfn(PCIDevice *d)
 goto err_pcie_cap;
 }
 
-rc = pcie_aer_init(d, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF);
+rc = pcie_aer_init(d, PCI_ERR_VER, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF);
 if (rc < 0) {
 goto err;
 }
diff --git a/hw/pci-bridge/xio3130_downstream.c 
b/hw/pci-bridge/xio3130_downstream.c
index cef6e13..5d1ce01 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -97,7 +97,7 @@ static int xio3130_downstream_initfn(PCIDevice *d)
 goto err_pcie_cap;
 }
 
-rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
+rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
 if (rc < 0) {
 goto err;
 }
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 4ad0440..3819964 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -85,7 +85,7 @@ static int xio3130_upstream_initfn(PCIDevice *d)
 pcie_cap_flr_init(d);
 pcie_cap_deverr_init(d);
 
-rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
+rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
 if (rc < 0) {
 goto err;
 }
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 048ce6a..ac47f34 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -96,11 +96,12 @@ static void aer_log_clear_all_err(PCIEAERLog *aer_log)
 aer_log->log_num = 0;
 }
 
-int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size)
+int pcie_aer_init(PCIDevice *dev, uint8_t cap_ver, uint16_t offset,
+  uint16_t size)
 {
 PCIExpressDevice *exp;
 
-pcie_add_capability(dev, PCI_EXT_CAP_ID_ERR, PCI_ERR_VER,
+pcie_add_capability(dev, PCI_EXT_CAP_ID_ERR, cap_ver,
 offset, size);
 exp = >exp;
 exp->aer_cap = offset;
diff --git a/include/hw/pci/pcie_aer.h b/include/hw/pci/pcie_aer.h
index c2ee4e2..c373591 100644
--- a/include/hw/pci/pcie_aer.h
+++ b/include/hw/pci/pcie_aer.h
@@ -87,7 +87,8 @@ struct PCIEAERErr {
 
 extern const VMStateDescription vmstate_pcie_aer_log;
 
-int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size);
+int pcie_aer_init(PCIDevice *dev, uint8_t cap_ver, uint16_t offset,
+  uint16_t size);
 void pcie_aer_exit(PCIDevice *dev);
 void pcie_aer_write_config(PCIDevice *dev,
uint32_t addr, uint32_t val, int len);
-- 
1.8.3.1






[Qemu-devel] [PATCH RFC v11 0/4] vfio-pci: pass non-fatal error to guest

2016-12-31 Thread Cao jin
As previous discussion suggest, we could take a step back to handle non-fatal
error first, this will make this patchset much more thinner, because we could
drop all the configuration restriction related patches.

FYI: patch 1 has been cherry picked into another series, and wait to be merged
first, so this patchset can't compile in your host.

v11 changelog:
1. drop a bunch of code which check the configuration.
2. modify patch 3 to handle non-fatal error only, fatal error still
   results in vm stop.
   Doesn't modify as suggestion "add another eventfd do distinguish fatal &
   non-fatal error", because 1st, user has the ability to distinguish them
   just from the uncorrectable error status; 2nd, for back compatible, e.g.
   an old user handle both error, rely on the current error eventfd.

Test:
Test it with intel 82576 NIC, which has 2 functions, function 1 has cable
connected to gateway, function 0 has no link. Test in 4 scenario.
1. just assign function 1 to one vm, function 0 has no user
2. assign 2 function to one vm, totally comply previous configuraton restrction
3. assign 2 function to one vm, under different virtual bus
4, assign functions to 2 different vm

The test steps are the same as v10: assign ip to function 1, add route info,
and ping the gateway. The results meet expectation. But the unsteady hardware
often emit fatal error, still don't know why. And igb driver in guest seems
has bug: ping gateway for a while, even if I don't do anything, it will show
"Destination Host Unreachable" after many successful ping. But obviously,
neither of these has relationship with this patchset.


Chen Fan (3):
  vfio: new function to init aer cap for vfio device
  vfio-pci: pass the aer error to guest
  vfio: add 'aer' property to expose aercap

Dou Liyang (1):
  pcie_aer: support configurable AER capa version

 hw/net/e1000e.c|   3 +-
 hw/pci-bridge/ioh3420.c|   2 +-
 hw/pci-bridge/xio3130_downstream.c |   2 +-
 hw/pci-bridge/xio3130_upstream.c   |   2 +-
 hw/pci/pcie_aer.c  |   5 +-
 hw/vfio/pci.c  | 139 +
 hw/vfio/pci.h  |   3 +
 include/hw/pci/pcie_aer.h  |   3 +-
 8 files changed, 139 insertions(+), 20 deletions(-)

-- 
1.8.3.1