[Qemu-devel] [RFC PATCH v9 00/26] translate: [tcg] Generic translation framework

2017-06-25 Thread Lluís Vilanova
This series proposes a generic (target-agnostic) instruction translation
framework.

It basically provides a generic main loop for instruction disassembly, which
calls target-specific functions when necessary. This generalization makes
inserting new code in the main loop easier, and helps in keeping all targets in
synch as to the contents of it.

This series also paves the way towards adding events to trace guest code
execution (BBLs and instructions).

I've ported i386/x86-64 and arm/aarch64 as an example to see how it fits in the
current organization, but will port the rest when this series gets merged.

Signed-off-by: Lluís Vilanova 
---

Changes in v9
=

* Further increase inter-mail sleep time during sending.


Changes in v8
=

* Increase inter-mail sleep time during sending (list keeps refusing some emails
  due to an excessive send rate).


Changes in v7
=

* Change BreakpointHitType (BH_*) for BreakpointCheckType (BC_*).
* Move target-specific translation functions to a struct (TranslatorOps).
* Split target-specific changes into multiple patches.
* Rebase on edf8bc9842.


Changes in v6
=

* Rebase on upstream master (64175afc69).
* Reorder fields in DisasContextBase to minimize padding [Richard Henderson].


Changes in v5
=

* Remove stray uses of "restrict" keyword.


Changes in v4
=

* Document new macro QTAILQ_FOREACH_CONTINUE [Peter Maydell].
* Fix coding style errors reported by checkpatch.
* Remove use of "restrict" in added functions; it makes older gcc versions barf
  about compilation errors.


Changes in v3
=

* Rebase on 0737f32daf.


Changes in v2
=

* Port ARM and AARCH64 targets.
* Fold single-stepping checks into "max_insns" [Richard Henderson].
* Move instruction start marks to target code [Richard Henderson].
* Add target hook for TB start.
* Check for TCG temporary leaks.
* Move instruction disassembly into a target hook.
* Make breakpoint_hit() return an enum to accomodate target's needs (ARM).


Lluís Vilanova (26):
  Pass generic CPUState to gen_intermediate_code()
  queue: Add macro for incremental traversal
  cpu-exec: Avoid global variables in icount-related functions
  target: [tcg] Add generic translation framework
  target: [tcg] Redefine DISAS_* onto the generic translation framework 
(DJ_*)
  target: [tcg,i386] Port to DisasContextBase
  target: [tcg,i386] Refactor init_disas_context
  target: [tcg,i386] Refactor init_globals
  target: [tcg,i386] Refactor insn_start
  target: [tcg,i386] Refactor breakpoint_check
  target: [tcg,i386] Refactor disas_insn
  target: [tcg,i386] Refactor tb_stop
  target: [tcg,i386] Refactor disas_flags
  target: [tcg,i386] Replace DISAS_* with DJ_*
  target: [tcg,i386] Port to generic translation framework
  target: [tcg,arm] Replace DISAS_* with DJ_*
  target: [tcg,arm] Port to DisasContextBase
  target: [tcg,arm] Port to init_disas_context
  target: [tcg,arm] Port to init_globals
  target: [tcg,arm] Port to tb_start
  target: [tcg,arm] Port to insn_start
  target: [tcg,arm] Port to breakpoint_check
  target: [tcg,arm] Port to disas_insn
  target: [tcg,arm] Port to tb_stop
  target: [tcg,arm] Port to disas_flags
  target: [tcg,arm] Port to generic translation framework


 Makefile.target|1 
 include/exec/exec-all.h|   13 +
 include/exec/gen-icount.h  |8 -
 include/exec/translate-block.h |  125 ++
 include/qemu/queue.h   |   12 +
 include/qom/cpu.h  |   22 ++
 target/alpha/translate.c   |   25 +-
 target/arm/translate-a64.c |  312 -
 target/arm/translate.c |  503 ++--
 target/arm/translate.h |   38 ++-
 target/cris/translate.c|   26 +-
 target/hppa/translate.c|6 
 target/i386/translate.c|  353 +++-
 target/lm32/translate.c|   36 +--
 target/m68k/translate.c|   24 +-
 target/microblaze/translate.c  |   28 +-
 target/mips/translate.c|   41 ++-
 target/moxie/translate.c   |   16 +
 target/nios2/translate.c   |6 
 target/openrisc/translate.c|   25 +-
 target/ppc/translate.c |   21 +-
 target/ppc/translate_init.c|   32 +--
 target/s390x/translate.c   |   22 +-
 target/sh4/translate.c |   21 +-
 target/sparc/translate.c   |   17 +
 target/tilegx/translate.c  |9 -
 target/tricore/translate.c |   11 -
 target/unicore32/translate.c   |   26 +-
 target/xtensa/translate.c  |   39 ++-
 translate-all.c|2 
 translate-block.c  |  185 +++
 31 files changed, 1212 insertions(+), 793 deletions(-)
 create mode 100644 include/exec/translate-block.h
 create mode 100644 translate-block.c


To: qemu-devel@nongnu.org
Cc: Paolo Bonzini 
Cc: Peter C

[Qemu-devel] [PATCH v9 01/26] Pass generic CPUState to gen_intermediate_code()

2017-06-25 Thread Lluís Vilanova
Needed to implement a target-agnostic gen_intermediate_code() in the
future.

Signed-off-by: Lluís Vilanova 
Reviewed-by: David Gibson 
Reviewed-by: Richard Henderson 
---
 include/exec/exec-all.h   |2 +-
 target/alpha/translate.c  |   11 +--
 target/arm/translate.c|   20 ++--
 target/cris/translate.c   |   17 -
 target/i386/translate.c   |   13 ++---
 target/lm32/translate.c   |   22 +++---
 target/m68k/translate.c   |   15 +++
 target/microblaze/translate.c |   22 +++---
 target/mips/translate.c   |   15 +++
 target/moxie/translate.c  |   14 +++---
 target/openrisc/translate.c   |   19 ++-
 target/ppc/translate.c|   15 +++
 target/s390x/translate.c  |   13 ++---
 target/sh4/translate.c|   15 +++
 target/sparc/translate.c  |   11 +--
 target/tilegx/translate.c |7 +++
 target/tricore/translate.c|9 -
 target/unicore32/translate.c  |   17 -
 target/xtensa/translate.c |   13 ++---
 translate-all.c   |2 +-
 20 files changed, 130 insertions(+), 142 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 87ae10bcc9..1ec7637170 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -43,7 +43,7 @@ typedef ram_addr_t tb_page_addr_t;
 
 #include "qemu/log.h"
 
-void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb);
+void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
   target_ulong *data);
 
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 7c45ae360c..9b60680454 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -2900,10 +2900,9 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 return ret;
 }
 
-void gen_intermediate_code(CPUAlphaState *env, struct TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, struct TranslationBlock *tb)
 {
-AlphaCPU *cpu = alpha_env_get_cpu(env);
-CPUState *cs = CPU(cpu);
+CPUAlphaState *env = cpu->env_ptr;
 DisasContext ctx, *ctxp = &ctx;
 target_ulong pc_start;
 target_ulong pc_mask;
@@ -2918,7 +2917,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct 
TranslationBlock *tb)
 ctx.pc = pc_start;
 ctx.mem_idx = cpu_mmu_index(env, false);
 ctx.implver = env->implver;
-ctx.singlestep_enabled = cs->singlestep_enabled;
+ctx.singlestep_enabled = cpu->singlestep_enabled;
 
 #ifdef CONFIG_USER_ONLY
 ctx.ir = cpu_std_ir;
@@ -2961,7 +2960,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct 
TranslationBlock *tb)
 tcg_gen_insn_start(ctx.pc);
 num_insns++;
 
-if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
+if (unlikely(cpu_breakpoint_test(cpu, ctx.pc, BP_ANY))) {
 ret = gen_excp(&ctx, EXCP_DEBUG, 0);
 /* The address covered by the breakpoint must be included in
[tb->pc, tb->pc + tb->size) in order to for it to be
@@ -3030,7 +3029,7 @@ void gen_intermediate_code(CPUAlphaState *env, struct 
TranslationBlock *tb)
 && qemu_log_in_addr_range(pc_start)) {
 qemu_log_lock();
 qemu_log("IN: %s\n", lookup_symbol(pc_start));
-log_target_disas(cs, pc_start, ctx.pc - pc_start, 1);
+log_target_disas(cpu, pc_start, ctx.pc - pc_start, 1);
 qemu_log("\n");
 qemu_log_unlock();
 }
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 0862f9e4aa..96272a9888 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11787,10 +11787,10 @@ static bool insn_crosses_page(CPUARMState *env, 
DisasContext *s)
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-ARMCPU *cpu = arm_env_get_cpu(env);
-CPUState *cs = CPU(cpu);
+CPUARMState *env = cpu->env_ptr;
+ARMCPU *arm_cpu = arm_env_get_cpu(env);
 DisasContext dc1, *dc = &dc1;
 target_ulong pc_start;
 target_ulong next_page_start;
@@ -11804,7 +11804,7 @@ void gen_intermediate_code(CPUARMState *env, 
TranslationBlock *tb)
  * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
  */
 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
-gen_intermediate_code_a64(cpu, tb);
+gen_intermediate_code_a64(arm_cpu, tb);
 return;
 }
 
@@ -11814,7 +11814,7 @@ void gen_intermediate_code(CPUARMState *env, 
TranslationBlock *tb)
 
 dc->is_jmp = DISAS_NEXT;
 dc->pc = pc_start;
-dc->singlestep_enabled = cs->singlestep_enabled;
+dc->singlestep_enabled = cpu->singlestep_enabled;
   

[Qemu-devel] [PATCH v9 02/26] queue: Add macro for incremental traversal

2017-06-25 Thread Lluís Vilanova
Adds macro QTAILQ_FOREACH_CONTINUE to support incremental list
traversal.

Signed-off-by: Lluís Vilanova 
---
 include/qemu/queue.h |   12 
 1 file changed, 12 insertions(+)

diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 35292c3155..eb2bf9cb1c 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -415,6 +415,18 @@ struct {   
 \
 (var);  \
 (var) = ((var)->field.tqe_next))
 
+/**
+ * QTAILQ_FOREACH_CONTINUE:
+ * @var: Variable to resume iteration from.
+ * @field: Field in @var holding a QTAILQ_ENTRY for this queue.
+ *
+ * Resumes iteration on a queue from the element in @var.
+ */
+#define QTAILQ_FOREACH_CONTINUE(var, field) \
+for ((var) = ((var)->field.tqe_next);   \
+(var);  \
+(var) = ((var)->field.tqe_next))
+
 #define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
 for ((var) = ((head)->tqh_first);   \
 (var) && ((next_var) = ((var)->field.tqe_next), 1); \




[Qemu-devel] [PATCH v9 03/26] cpu-exec: Avoid global variables in icount-related functions

2017-06-25 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 include/exec/gen-icount.h |6 +++--
 target/alpha/translate.c  |   14 ++--
 target/arm/translate-a64.c|   10 -
 target/arm/translate.c|   10 -
 target/cris/translate.c   |6 +++--
 target/hppa/translate.c   |6 +++--
 target/i386/translate.c   |   46 +
 target/lm32/translate.c   |   14 ++--
 target/m68k/translate.c   |6 +++--
 target/microblaze/translate.c |6 +++--
 target/mips/translate.c   |   26 ---
 target/moxie/translate.c  |2 +-
 target/nios2/translate.c  |6 +++--
 target/openrisc/translate.c   |6 +++--
 target/ppc/translate.c|6 +++--
 target/ppc/translate_init.c   |   32 ++---
 target/s390x/translate.c  |6 +++--
 target/sh4/translate.c|6 +++--
 target/sparc/translate.c  |6 +++--
 target/tilegx/translate.c |2 +-
 target/tricore/translate.c|2 +-
 target/unicore32/translate.c  |6 +++--
 target/xtensa/translate.c |   26 ---
 23 files changed, 128 insertions(+), 128 deletions(-)

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 62d462e494..9b26c7da5f 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -8,7 +8,7 @@
 static int icount_start_insn_idx;
 static TCGLabel *exitreq_label;
 
-static inline void gen_tb_start(TranslationBlock *tb)
+static inline void gen_tb_start(TranslationBlock *tb, TCGv_env cpu_env)
 {
 TCGv_i32 count, imm;
 
@@ -59,14 +59,14 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns)
 tcg_ctx.gen_op_buf[tcg_ctx.gen_op_buf[0].prev].next = 0;
 }
 
-static inline void gen_io_start(void)
+static inline void gen_io_start(TCGv_env cpu_env)
 {
 TCGv_i32 tmp = tcg_const_i32(1);
 tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
 tcg_temp_free_i32(tmp);
 }
 
-static inline void gen_io_end(void)
+static inline void gen_io_end(TCGv_env cpu_env)
 {
 TCGv_i32 tmp = tcg_const_i32(0);
 tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 9b60680454..fdc49109ad 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -1329,9 +1329,9 @@ static ExitStatus gen_mfpr(DisasContext *ctx, TCGv va, 
int regno)
 helper = gen_helper_get_vmtime;
 do_helper:
 if (use_icount) {
-gen_io_start();
+gen_io_start(cpu_env);
 helper(va);
-gen_io_end();
+gen_io_end(cpu_env);
 return EXIT_PC_STALE;
 } else {
 helper(va);
@@ -2379,9 +2379,9 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 /* RPCC */
 va = dest_gpr(ctx, ra);
 if (ctx->tb->cflags & CF_USE_ICOUNT) {
-gen_io_start();
+gen_io_start(cpu_env);
 gen_helper_load_pcc(va, cpu_env);
-gen_io_end();
+gen_io_end(cpu_env);
 ret = EXIT_PC_STALE;
 } else {
 gen_helper_load_pcc(va, cpu_env);
@@ -2955,7 +2955,7 @@ void gen_intermediate_code(CPUState *cpu, struct 
TranslationBlock *tb)
 pc_mask = ~TARGET_PAGE_MASK;
 }
 
-gen_tb_start(tb);
+gen_tb_start(tb, cpu_env);
 do {
 tcg_gen_insn_start(ctx.pc);
 num_insns++;
@@ -2970,7 +2970,7 @@ void gen_intermediate_code(CPUState *cpu, struct 
TranslationBlock *tb)
 break;
 }
 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-gen_io_start();
+gen_io_start(cpu_env);
 }
 insn = cpu_ldl_code(env, ctx.pc);
 
@@ -2991,7 +2991,7 @@ void gen_intermediate_code(CPUState *cpu, struct 
TranslationBlock *tb)
 } while (ret == NO_EXIT);
 
 if (tb->cflags & CF_LAST_IO) {
-gen_io_end();
+gen_io_end(cpu_env);
 }
 
 switch (ret) {
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 860e279658..43261e7939 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1558,7 +1558,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 }
 
 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
-gen_io_start();
+gen_io_start(cpu_env);
 }
 
 tcg_rt = cpu_reg(s, rt);
@@ -1590,7 +1590,7 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 
 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
 /* I/O operations must end the TB here (whether read or write) */
-gen_io_end();
+gen_io_end(cpu_env);
 s->is_jmp = DISAS_UPDATE;
 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
 /* We default to ending the TB on a coproc

[Qemu-devel] [PATCH v9 04/26] target: [tcg] Add generic translation framework

2017-06-25 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 Makefile.target|1 
 include/exec/gen-icount.h  |2 
 include/exec/translate-block.h |  125 +++
 include/qom/cpu.h  |   22 +
 translate-block.c  |  185 
 5 files changed, 334 insertions(+), 1 deletion(-)
 create mode 100644 include/exec/translate-block.h
 create mode 100644 translate-block.c

diff --git a/Makefile.target b/Makefile.target
index ce8dfe44a8..253c6e7999 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -90,6 +90,7 @@ all: $(PROGS) stap
 # cpu emulator library
 obj-y = exec.o translate-all.o cpu-exec.o
 obj-y += translate-common.o
+obj-y += translate-block.o
 obj-y += cpu-exec-common.o
 obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 9b26c7da5f..f4ad61014b 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -44,7 +44,7 @@ static inline void gen_tb_start(TranslationBlock *tb, 
TCGv_env cpu_env)
 tcg_temp_free_i32(count);
 }
 
-static void gen_tb_end(TranslationBlock *tb, int num_insns)
+static inline void gen_tb_end(TranslationBlock *tb, int num_insns)
 {
 if (tb->cflags & CF_USE_ICOUNT) {
 /* Update the num_insn immediate parameter now that we know
diff --git a/include/exec/translate-block.h b/include/exec/translate-block.h
new file mode 100644
index 00..d14d23f2cb
--- /dev/null
+++ b/include/exec/translate-block.h
@@ -0,0 +1,125 @@
+/*
+ * Generic intermediate code generation.
+ *
+ * Copyright (C) 2016-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef EXEC__TRANSLATE_BLOCK_H
+#define EXEC__TRANSLATE_BLOCK_H
+
+/*
+ * Include this header from a target-specific file, and add a
+ *
+ * DisasContextBase base;
+ *
+ * member in your target-specific DisasContext.
+ */
+
+
+#include "exec/exec-all.h"
+#include "tcg/tcg.h"
+
+
+/**
+ * BreakpointCheckType:
+ * @BC_MISS: No hit
+ * @BC_HIT_INSN: Hit, but continue translating TB
+ * @BC_HIT_TB: Hit, stop translating TB
+ *
+ * How to react to a breakpoint. A hit means no more breakpoints will be 
checked
+ * for the current instruction.
+ *
+ * Not all breakpoints associated to an address are necessarily raised by
+ * targets (e.g., due to conditions encoded in their flags), so tey can decide
+ * that a breakpoint missed the address (@BP_MISS).
+ */
+typedef enum BreakpointCheckType {
+BC_MISS,
+BC_HIT_INSN,
+BC_HIT_TB,
+} BreakpointCheckType;
+
+/**
+ * DisasJumpType:
+ * @DJ_NEXT: Next instruction in program order.
+ * @DJ_TOO_MANY: Too many instructions translated.
+ * @DJ_TARGET: Start of target-specific conditions.
+ *
+ * What instruction to disassemble next.
+ */
+typedef enum DisasJumpType {
+DJ_NEXT,
+DJ_TOO_MANY,
+DJ_TARGET,
+} DisasJumpType;
+
+/**
+ * DisasContextBase:
+ * @tb: Translation block for this disassembly.
+ * @pc_first: Address of first guest instruction in this TB.
+ * @pc_next: Address of next guest instruction in this TB (current during
+ *   disassembly).
+ * @is_jmp: What instruction to disassemble next.
+ * @num_insns: Number of translated instructions (including current).
+ * @singlestep_enabled: "Hardware" single stepping enabled.
+ *
+ * Architecture-agnostic disassembly context.
+ */
+typedef struct DisasContextBase {
+TranslationBlock *tb;
+target_ulong pc_first;
+target_ulong pc_next;
+DisasJumpType is_jmp;
+unsigned int num_insns;
+bool singlestep_enabled;
+} DisasContextBase;
+
+/**
+ * TranslatorOps:
+ * @init_disas_context: Initialize a DisasContext struct (DisasContextBase has
+ *  already been initialized).
+ * @init_globals: Initialize global variables.
+ * @tb_start: Start translating a new TB.
+ * @insn_start: Start translating a new instruction.
+ * @breakpoint_check: Check if a breakpoint did hit. When called, the 
breakpoint
+ *has already been checked to match the PC.
+ * @disas_insn: Disassemble one instruction an return the PC for the next
+ *  one. Can set db->is_jmp to DJ_TARGET or above to stop
+ *  translation.
+ * @tb_stop: Stop translating a TB.
+ * @disas_flags: Get flags argument for log_target_disas().
+ *
+ * Target-specific operations for the generic translator loop.
+ *
+ * All operations but disas_insn() are optional, and ignored when not set.
+ * A missing breakpoint_check() will ignore breakpoints. A missing 
disas_flags()
+ * will pass no flags.
+ */
+typedef struct TranslatorOps {
+void (*init_disas_context)(DisasContextBase *db, CPUState *cpu);
+void (*init_globals)(DisasContextBase *db, CPUState *cpu);
+void (*tb_start)(DisasContextBase *db, CPUState *cpu);
+void (*insn_start)(DisasContextBase *db, CPUState *cpu);
+

[Qemu-devel] [PATCH v9 05/26] target: [tcg] Redefine DISAS_* onto the generic translation framework (DJ_*)

2017-06-25 Thread Lluís Vilanova
Temporarily redefine DISAS_* values based on DJ_TARGET. They should
disappear as targets get ported to the generic framework.

Signed-off-by: Lluís Vilanova 
Acked-by: David Gibson  (ppc)
Acked-by: Eduardo Habkost 
Reviewed-by: Eduardo Habkost  (i386)
Acked-by: Laurent Vivier  (m68k)
Reviewed-by: Alex Benée  (arm)
---
 include/exec/exec-all.h  |   11 +++
 target/arm/translate.h   |   19 ++-
 target/cris/translate.c  |3 ++-
 target/m68k/translate.c  |3 ++-
 target/s390x/translate.c |3 ++-
 target/unicore32/translate.c |3 ++-
 6 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 1ec7637170..5d693cefd1 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -36,10 +36,13 @@ typedef ram_addr_t tb_page_addr_t;
 #endif
 
 /* is_jmp field values */
-#define DISAS_NEXT0 /* next instruction can be analyzed */
-#define DISAS_JUMP1 /* only pc was modified dynamically */
-#define DISAS_UPDATE  2 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP 3 /* only pc was modified statically */
+/* TODO: delete after all targets are transitioned to generic translation */
+#include "exec/translate-block.h"
+#define DISAS_NEXTDJ_NEXT   /* next instruction can be analyzed */
+#define DISAS_JUMP(DJ_TARGET + 0)   /* only pc was modified dynamically */
+#define DISAS_UPDATE  (DJ_TARGET + 1)   /* cpu state was modified dynamically 
*/
+#define DISAS_TB_JUMP (DJ_TARGET + 2)   /* only pc was modified statically */
+#define DISAS_TARGET  (DJ_TARGET + 3)   /* base for target-specific values */
 
 #include "qemu/log.h"
 
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 15d383d9af..e42fdbe61c 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -120,29 +120,30 @@ static void disas_set_insn_syndrome(DisasContext *s, 
uint32_t syn)
 }
 
 /* target-specific extra values for is_jmp */
+/* TODO: rename as DJ_* when transitioning this target to generic translation 
*/
 /* These instructions trap after executing, so the A32/T32 decoder must
  * defer them until after the conditional execution state has been updated.
  * WFI also needs special handling when single-stepping.
  */
-#define DISAS_WFI 4
-#define DISAS_SWI 5
+#define DISAS_WFI (DISAS_TARGET + 0)
+#define DISAS_SWI (DISAS_TARGET + 1)
 /* For instructions which unconditionally cause an exception we can skip
  * emitting unreachable code at the end of the TB in the A64 decoder
  */
-#define DISAS_EXC 6
+#define DISAS_EXC (DISAS_TARGET + 2)
 /* WFE */
-#define DISAS_WFE 7
-#define DISAS_HVC 8
-#define DISAS_SMC 9
-#define DISAS_YIELD 10
+#define DISAS_WFE (DISAS_TARGET + 3)
+#define DISAS_HVC (DISAS_TARGET + 4)
+#define DISAS_SMC (DISAS_TARGET + 5)
+#define DISAS_YIELD (DISAS_TARGET + 6)
 /* M profile branch which might be an exception return (and so needs
  * custom end-of-TB code)
  */
-#define DISAS_BX_EXCRET 11
+#define DISAS_BX_EXCRET (DISAS_TARGET + 7)
 /* For instructions which want an immediate exit to the main loop,
  * as opposed to attempting to use lookup_and_goto_ptr.
  */
-#define DISAS_EXIT 12
+#define DISAS_EXIT (DISAS_TARGET + 8)
 
 #ifdef TARGET_AARCH64
 void a64_translate_init(void);
diff --git a/target/cris/translate.c b/target/cris/translate.c
index 90424abe00..fca831cd6f 100644
--- a/target/cris/translate.c
+++ b/target/cris/translate.c
@@ -50,7 +50,8 @@
 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
 #define BUG_ON(x) ({if (x) BUG();})
 
-#define DISAS_SWI 5
+/* TODO: rename as DJ_* when transitioning this target to generic translation 
*/
+#define DISAS_SWI (DISAS_TARGET + 0)
 
 /* Used by the decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 5fac91aec5..e75e893056 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -190,7 +190,8 @@ static void do_writebacks(DisasContext *s)
 }
 }
 
-#define DISAS_JUMP_NEXT 4
+/* TODO: rename as DJ_* when transitioning this target to generic translation 
*/
+#define DISAS_JUMP_NEXT (DISAS_TARGET + 0)
 
 #if defined(CONFIG_USER_ONLY)
 #define IS_USER(s) 1
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 14abb6e6b9..49eddb061b 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -76,7 +76,8 @@ typedef struct {
 } u;
 } DisasCompare;
 
-#define DISAS_EXCP 4
+/* TODO: rename as DJ_* when transitioning this target to generic translation 
*/
+#define DISAS_EXCP (DISAS_TARGET + 0)
 
 #ifdef DEBUG_INLINE_BRANCHES
 static uint64_t inline_branch_hit[CC_OP_MAX];
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
index a7878ffd81..8bc6db61bb 100644
--- a/target/unicore32/translate.c
+++ b/target/unicore32/translate.c
@@ -45,9 +45,10 @@ typedef struct DisasContext {
 #define IS_USER(s)  1
 #endif
 
+/* TODO: rename as DJ_* when transitioning this target to generic translat

[Qemu-devel] [PATCH v9 06/26] target: [tcg, i386] Port to DisasContextBase

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |  164 ++-
 1 file changed, 92 insertions(+), 72 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 9f42a5509d..5a801766e5 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -30,6 +30,7 @@
 
 #include "trace-tcg.h"
 #include "exec/log.h"
+#include "exec/translate-block.h"
 
 
 #define PREFIX_REPZ   0x01
@@ -95,6 +96,8 @@ static int x86_64_hregs;
 #endif
 
 typedef struct DisasContext {
+DisasContextBase base;
+
 /* current insn context */
 int override; /* -1 if no override */
 int prefix;
@@ -102,8 +105,6 @@ typedef struct DisasContext {
 TCGMemOp dflag;
 target_ulong pc_start;
 target_ulong pc; /* pc = eip + cs_base */
-int is_jmp; /* 1 = means jump (stop translation), 2 means CPU
-   static state change (stop translation) */
 /* current block context */
 target_ulong cs_base; /* base of CS segment */
 int pe; /* protected mode */
@@ -124,12 +125,10 @@ typedef struct DisasContext {
 int cpl;
 int iopl;
 int tf; /* TF cpu flag */
-int singlestep_enabled; /* "hardware" single step enabled */
 int jmp_opt; /* use direct block chaining for direct jumps */
 int repz_opt; /* optimize jumps within repz instructions */
 int mem_index; /* select memory access functions */
 uint64_t flags; /* all execution flags */
-struct TranslationBlock *tb;
 int popl_esp_hack; /* for correct popl with esp base handling */
 int rip_offset; /* only used in x86_64, but left for simplicity */
 int cpuid_features;
@@ -1119,7 +1118,9 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, 
int ot)
 
 static inline void gen_ins(DisasContext *s, TCGMemOp ot)
 {
-if (s->tb->cflags & CF_USE_ICOUNT) {
+DisasContextBase *b = &s->base;
+
+if (b->tb->cflags & CF_USE_ICOUNT) {
 gen_io_start(cpu_env);
 }
 gen_string_movl_A0_EDI(s);
@@ -1134,14 +1135,16 @@ static inline void gen_ins(DisasContext *s, TCGMemOp ot)
 gen_op_movl_T0_Dshift(ot);
 gen_op_add_reg_T0(s->aflag, R_EDI);
 gen_bpt_io(s, cpu_tmp2_i32, ot);
-if (s->tb->cflags & CF_USE_ICOUNT) {
+if (b->tb->cflags & CF_USE_ICOUNT) {
 gen_io_end(cpu_env);
 }
 }
 
 static inline void gen_outs(DisasContext *s, TCGMemOp ot)
 {
-if (s->tb->cflags & CF_USE_ICOUNT) {
+DisasContextBase *b = &s->base;
+
+if (b->tb->cflags & CF_USE_ICOUNT) {
 gen_io_start(cpu_env);
 }
 gen_string_movl_A0_ESI(s);
@@ -1154,7 +1157,7 @@ static inline void gen_outs(DisasContext *s, TCGMemOp ot)
 gen_op_movl_T0_Dshift(ot);
 gen_op_add_reg_T0(s->aflag, R_ESI);
 gen_bpt_io(s, cpu_tmp2_i32, ot);
-if (s->tb->cflags & CF_USE_ICOUNT) {
+if (b->tb->cflags & CF_USE_ICOUNT) {
 gen_io_end(cpu_env);
 }
 }
@@ -2137,7 +2140,9 @@ static inline int insn_const_size(TCGMemOp ot)
 static inline bool use_goto_tb(DisasContext *s, target_ulong pc)
 {
 #ifndef CONFIG_USER_ONLY
-return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
+DisasContextBase *b = &s->base;
+
+return (pc & TARGET_PAGE_MASK) == (b->tb->pc & TARGET_PAGE_MASK) ||
(pc & TARGET_PAGE_MASK) == (s->pc_start & TARGET_PAGE_MASK);
 #else
 return true;
@@ -2146,13 +2151,14 @@ static inline bool use_goto_tb(DisasContext *s, 
target_ulong pc)
 
 static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
 {
+DisasContextBase *b = &s->base;
 target_ulong pc = s->cs_base + eip;
 
 if (use_goto_tb(s, pc))  {
 /* jump to same page: we can use a direct jump */
 tcg_gen_goto_tb(tb_num);
 gen_jmp_im(eip);
-tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
+tcg_gen_exit_tb((uintptr_t)b->tb + tb_num);
 } else {
 /* jump to another page */
 gen_jmp_im(eip);
@@ -2173,7 +2179,7 @@ static inline void gen_jcc(DisasContext *s, int b,
 
 gen_set_label(l1);
 gen_goto_tb(s, 1, val);
-s->is_jmp = DISAS_TB_JUMP;
+s->base.is_jmp = DISAS_TB_JUMP;
 } else {
 l1 = gen_new_label();
 l2 = gen_new_label();
@@ -2236,6 +2242,8 @@ static inline void gen_op_movl_seg_T0_vm(int seg_reg)
call this function with seg_reg == R_CS */
 static void gen_movl_seg_T0(DisasContext *s, int seg_reg)
 {
+DisasContextBase *b = &s->base;
+
 if (s->pe && !s->vm86) {
 tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);
 gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);
@@ -2244,11 +2252,11 @@ static void gen_movl_seg_T0(DisasContext *s, int 
seg_reg)
stop as a special handling must be done to disable hardware
interrupts for the next instruction */
 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
-s->is_jm

[Qemu-devel] [PATCH v9 07/26] target: [tcg, i386] Refactor init_disas_context

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |   43 ---
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 5a801766e5..84ff49030b 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -8396,21 +8396,12 @@ void tcg_x86_init(void)
 }
 }
 
-/* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
+static void i386_trblock_init_disas_context(DisasContextBase *db, CPUState 
*cpu)
 {
+DisasContext *dc = container_of(db, DisasContext, base);
 CPUX86State *env = cpu->env_ptr;
-DisasContext dc1, *dc = &dc1;
-DisasContextBase *db = &dc1.base;
-uint32_t flags;
-target_ulong cs_base;
-int num_insns;
-int max_insns;
-
-/* generate intermediate code */
-db->pc_first = tb->pc;
-cs_base = tb->cs_base;
-flags = tb->flags;
+uint32_t flags = db->tb->flags;
+target_ulong cs_base = db->tb->cs_base;
 
 dc->pe = (flags >> HF_PE_SHIFT) & 1;
 dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
@@ -8421,11 +8412,9 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
 dc->iopl = (flags >> IOPL_SHIFT) & 3;
 dc->tf = (flags >> TF_SHIFT) & 1;
-db->singlestep_enabled = cpu->singlestep_enabled;
 dc->cc_op = CC_OP_DYNAMIC;
 dc->cc_op_dirty = false;
 dc->cs_base = cs_base;
-db->tb = tb;
 dc->popl_esp_hack = 0;
 /* select memory access functions */
 dc->mem_index = 0;
@@ -8455,12 +8444,30 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
record/replay modes and there will always be an
additional step for ecx=0 when icount is enabled.
  */
-dc->repz_opt = !dc->jmp_opt && !(tb->cflags & CF_USE_ICOUNT);
+dc->repz_opt = !dc->jmp_opt && !(db->tb->cflags & CF_USE_ICOUNT);
 #if 0
 /* check addseg logic */
 if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
 printf("ERROR addseg\n");
 #endif
+}
+
+/* generate intermediate code for basic block 'tb'.  */
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
+{
+CPUX86State *env = cpu->env_ptr;
+DisasContext dc1, *dc = &dc1;
+DisasContextBase *db = &dc1.base;
+int num_insns;
+int max_insns;
+
+/* generate intermediate code */
+db->singlestep_enabled = cpu->singlestep_enabled;
+db->tb = tb;
+db->is_jmp = DISAS_NEXT;
+db->pc_first = tb->pc;
+db->pc_next = db->pc_first;
+i386_trblock_init_disas_context(db, cpu);
 
 cpu_T0 = tcg_temp_new();
 cpu_T1 = tcg_temp_new();
@@ -8475,8 +8482,6 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 cpu_ptr1 = tcg_temp_new_ptr();
 cpu_cc_srcT = tcg_temp_local_new();
 
-db->is_jmp = DISAS_NEXT;
-db->pc_next = db->pc_first;
 num_insns = 0;
 max_insns = tb->cflags & CF_COUNT_MASK;
 if (max_insns == 0) {
@@ -8518,7 +8523,7 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
the flag and abort the translation to give the irqs a
change to be happen */
 if (dc->tf || db->singlestep_enabled ||
-(flags & HF_INHIBIT_IRQ_MASK)) {
+(db->tb->flags & HF_INHIBIT_IRQ_MASK)) {
 gen_jmp_im(db->pc_next - dc->cs_base);
 gen_eob(dc);
 break;




[Qemu-devel] [PATCH v9 08/26] target: [tcg, i386] Refactor init_globals

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |   29 +
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 84ff49030b..f0d12a3d13 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -8452,6 +8452,22 @@ static void 
i386_trblock_init_disas_context(DisasContextBase *db, CPUState *cpu)
 #endif
 }
 
+static void i386_trblock_init_globals(DisasContextBase *db, CPUState *cpu)
+{
+cpu_T0 = tcg_temp_new();
+cpu_T1 = tcg_temp_new();
+cpu_A0 = tcg_temp_new();
+
+cpu_tmp0 = tcg_temp_new();
+cpu_tmp1_i64 = tcg_temp_new_i64();
+cpu_tmp2_i32 = tcg_temp_new_i32();
+cpu_tmp3_i32 = tcg_temp_new_i32();
+cpu_tmp4 = tcg_temp_new();
+cpu_ptr0 = tcg_temp_new_ptr();
+cpu_ptr1 = tcg_temp_new_ptr();
+cpu_cc_srcT = tcg_temp_local_new();
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
@@ -8469,18 +8485,7 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 db->pc_next = db->pc_first;
 i386_trblock_init_disas_context(db, cpu);
 
-cpu_T0 = tcg_temp_new();
-cpu_T1 = tcg_temp_new();
-cpu_A0 = tcg_temp_new();
-
-cpu_tmp0 = tcg_temp_new();
-cpu_tmp1_i64 = tcg_temp_new_i64();
-cpu_tmp2_i32 = tcg_temp_new_i32();
-cpu_tmp3_i32 = tcg_temp_new_i32();
-cpu_tmp4 = tcg_temp_new();
-cpu_ptr0 = tcg_temp_new_ptr();
-cpu_ptr1 = tcg_temp_new_ptr();
-cpu_cc_srcT = tcg_temp_local_new();
+i386_trblock_init_globals(db, cpu);
 
 num_insns = 0;
 max_insns = tb->cflags & CF_COUNT_MASK;




[Qemu-devel] [PATCH v9 09/26] target: [tcg, i386] Refactor insn_start

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index f0d12a3d13..3c7ef4af67 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -8468,6 +8468,12 @@ static void i386_trblock_init_globals(DisasContextBase 
*db, CPUState *cpu)
 cpu_cc_srcT = tcg_temp_local_new();
 }
 
+static void i386_trblock_insn_start(DisasContextBase *db, CPUState *cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+tcg_gen_insn_start(db->pc_next, dc->cc_op);
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
@@ -8498,7 +8504,7 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 
 gen_tb_start(tb, cpu_env);
 for(;;) {
-tcg_gen_insn_start(db->pc_next, dc->cc_op);
+i386_trblock_insn_start(db, cpu);
 num_insns++;
 
 /* If RF is set, suppress an internally generated breakpoint.  */




[Qemu-devel] [PATCH v9 10/26] target: [tcg, i386] Refactor breakpoint_check

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |   48 +++
 1 file changed, 36 insertions(+), 12 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 3c7ef4af67..04d65b8416 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -18,6 +18,7 @@
  */
 #include "qemu/osdep.h"
 
+#include "qemu/error-report.h"
 #include "qemu/host-utils.h"
 #include "cpu.h"
 #include "disas/disas.h"
@@ -8474,12 +8475,32 @@ static void i386_trblock_insn_start(DisasContextBase 
*db, CPUState *cpu)
 tcg_gen_insn_start(db->pc_next, dc->cc_op);
 }
 
+static BreakpointCheckType i386_trblock_breakpoint_check(
+DisasContextBase *db, CPUState *cpu, const CPUBreakpoint *bp)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+/* If RF is set, suppress an internally generated breakpoint.  */
+int flags = db->tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY;
+if (bp->flags & flags) {
+gen_debug(dc, db->pc_next - dc->cs_base);
+/* The address covered by the breakpoint must be included in
+   [tb->pc, tb->pc + tb->size) in order to for it to be
+   properly cleared -- thus we increment the PC here so that
+   the logic setting tb->size below does the right thing.  */
+db->pc_next += 1;
+return BC_HIT_TB;
+} else {
+return BC_MISS;
+}
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
 CPUX86State *env = cpu->env_ptr;
 DisasContext dc1, *dc = &dc1;
 DisasContextBase *db = &dc1.base;
+CPUBreakpoint *bp;
 int num_insns;
 int max_insns;
 
@@ -8507,18 +8528,21 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 i386_trblock_insn_start(db, cpu);
 num_insns++;
 
-/* If RF is set, suppress an internally generated breakpoint.  */
-if (unlikely(cpu_breakpoint_test(cpu, db->pc_next,
- tb->flags & HF_RF_MASK
- ? BP_GDB : BP_ANY))) {
-gen_debug(dc, db->pc_next - dc->cs_base);
-/* The address covered by the breakpoint must be included in
-   [tb->pc, tb->pc + tb->size) in order to for it to be
-   properly cleared -- thus we increment the PC here so that
-   the logic setting tb->size below does the right thing.  */
-db->pc_next += 1;
-goto done_generating;
-}
+bp = NULL;
+do {
+bp = cpu_breakpoint_get(cpu, db->pc_next, bp);
+if (unlikely(bp)) {
+BreakpointCheckType bp_check = i386_trblock_breakpoint_check(
+db, cpu, bp);
+if (bp_check == BC_HIT_TB) {
+goto done_generating;
+} else {
+error_report("Unexpected BreakpointCheckType %d", 
bp_check);
+abort();
+}
+}
+} while (bp != NULL);
+
 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
 gen_io_start(cpu_env);
 }




[Qemu-devel] [PATCH v9 11/26] target: [tcg, i386] Refactor disas_insn

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |   72 +++
 1 file changed, 47 insertions(+), 25 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 04d65b8416..34e7cf6788 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -4436,16 +4436,17 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
int b,
 
 /* convert one instruction. s->base.is_jmp is set if the translation must
be stopped. Return the next pc value */
-static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
-   target_ulong pc_start)
+static target_ulong disas_insn(DisasContextBase *db, CPUState *cpu)
 {
-DisasContextBase *db = &s->base;
+DisasContext *s = container_of(db, DisasContext, base);
+CPUX86State *env = cpu->env_ptr;
 int b, prefixes;
 int shift;
 TCGMemOp ot, aflag, dflag;
 int modrm, reg, rm, mod, op, opreg, val;
 target_ulong next_eip, tval;
 int rex_w, rex_r;
+target_ulong pc_start = db->pc_next;
 
 s->pc_start = s->pc = pc_start;
 prefixes = 0;
@@ -8494,10 +8495,50 @@ static BreakpointCheckType 
i386_trblock_breakpoint_check(
 }
 }
 
+static target_ulong i386_trblock_disas_insn(DisasContextBase *db, CPUState 
*cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+target_ulong pc_next = disas_insn(db, cpu);
+
+if (db->is_jmp) {
+return pc_next;
+}
+
+if (dc->tf || (db->tb->flags & HF_INHIBIT_IRQ_MASK)) {
+/* if single step mode, we generate only one instruction and
+   generate an exception */
+/* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
+   the flag and abort the translation to give the irqs a
+   change to be happen */
+gen_jmp_im(pc_next - dc->cs_base);
+gen_eob(dc);
+db->is_jmp = DJ_TOO_MANY;
+} else if ((db->tb->cflags & CF_USE_ICOUNT)
+   && ((db->pc_next & TARGET_PAGE_MASK)
+   != ((db->pc_next + TARGET_MAX_INSN_SIZE - 1)
+   & TARGET_PAGE_MASK)
+   || (db->pc_next & ~TARGET_PAGE_MASK) == 0)) {
+/* Do not cross the boundary of the pages in icount mode,
+   it can cause an exception. Do it only when boundary is
+   crossed by the first instruction in the block.
+   If current instruction already crossed the bound - it's ok,
+   because an exception hasn't stopped this code.
+ */
+gen_jmp_im(pc_next - dc->cs_base);
+gen_eob(dc);
+db->is_jmp = DJ_TOO_MANY;
+} else if ((pc_next - db->pc_first) >= (TARGET_PAGE_SIZE - 32)) {
+gen_jmp_im(pc_next - dc->cs_base);
+gen_eob(dc);
+db->is_jmp = DJ_TOO_MANY;
+}
+
+return pc_next;
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-CPUX86State *env = cpu->env_ptr;
 DisasContext dc1, *dc = &dc1;
 DisasContextBase *db = &dc1.base;
 CPUBreakpoint *bp;
@@ -8547,39 +8588,20 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 gen_io_start(cpu_env);
 }
 
-db->pc_next = disas_insn(env, dc, db->pc_next);
+db->pc_next = i386_trblock_disas_insn(db, cpu);
 /* stop translation if indicated */
 if (db->is_jmp) {
 break;
 }
 /* if single step mode, we generate only one instruction and
generate an exception */
-/* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
-   the flag and abort the translation to give the irqs a
-   change to be happen */
-if (dc->tf || db->singlestep_enabled ||
-(db->tb->flags & HF_INHIBIT_IRQ_MASK)) {
-gen_jmp_im(db->pc_next - dc->cs_base);
-gen_eob(dc);
-break;
-}
-/* Do not cross the boundary of the pages in icount mode,
-   it can cause an exception. Do it only when boundary is
-   crossed by the first instruction in the block.
-   If current instruction already crossed the bound - it's ok,
-   because an exception hasn't stopped this code.
- */
-if ((tb->cflags & CF_USE_ICOUNT)
-&& ((db->pc_next & TARGET_PAGE_MASK)
-!= ((db->pc_next + TARGET_MAX_INSN_SIZE - 1) & 
TARGET_PAGE_MASK)
-|| (db->pc_next & ~TARGET_PAGE_MASK) == 0)) {
+if (db->singlestep_enabled) {
 gen_jmp_im(db->pc_next - dc->cs_base);
 gen_eob(dc);
 break;
 }
 /* if too long translation, stop generation too */
 if (tcg_op_buf_full() ||
-(db->pc_next - db->pc_first) >= (TARGET_PAGE_SIZE - 32) ||
 num_insns >= max_insns) {
 gen_jmp_im(db->pc_n

[Qemu-devel] [PATCH v9 12/26] target: [tcg,i386] Refactor tb_stop

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |   26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 34e7cf6788..e7b46d282a 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -8510,8 +8510,6 @@ static target_ulong 
i386_trblock_disas_insn(DisasContextBase *db, CPUState *cpu)
 /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
the flag and abort the translation to give the irqs a
change to be happen */
-gen_jmp_im(pc_next - dc->cs_base);
-gen_eob(dc);
 db->is_jmp = DJ_TOO_MANY;
 } else if ((db->tb->cflags & CF_USE_ICOUNT)
&& ((db->pc_next & TARGET_PAGE_MASK)
@@ -8524,18 +8522,24 @@ static target_ulong 
i386_trblock_disas_insn(DisasContextBase *db, CPUState *cpu)
If current instruction already crossed the bound - it's ok,
because an exception hasn't stopped this code.
  */
-gen_jmp_im(pc_next - dc->cs_base);
-gen_eob(dc);
 db->is_jmp = DJ_TOO_MANY;
 } else if ((pc_next - db->pc_first) >= (TARGET_PAGE_SIZE - 32)) {
-gen_jmp_im(pc_next - dc->cs_base);
-gen_eob(dc);
 db->is_jmp = DJ_TOO_MANY;
 }
 
 return pc_next;
 }
 
+static void i386_trblock_tb_stop(DisasContextBase *db, CPUState *cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+if (db->is_jmp == DJ_TOO_MANY) {
+gen_jmp_im(db->pc_next - dc->cs_base);
+gen_eob(dc);
+}
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
@@ -8596,23 +8600,21 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 /* if single step mode, we generate only one instruction and
generate an exception */
 if (db->singlestep_enabled) {
-gen_jmp_im(db->pc_next - dc->cs_base);
-gen_eob(dc);
+db->is_jmp = DJ_TOO_MANY;
 break;
 }
 /* if too long translation, stop generation too */
 if (tcg_op_buf_full() ||
 num_insns >= max_insns) {
-gen_jmp_im(db->pc_next - dc->cs_base);
-gen_eob(dc);
+db->is_jmp = DJ_TOO_MANY;
 break;
 }
 if (singlestep) {
-gen_jmp_im(db->pc_next - dc->cs_base);
-gen_eob(dc);
+db->is_jmp = DJ_TOO_MANY;
 break;
 }
 }
+i386_trblock_tb_stop(db, cpu);
 if (tb->cflags & CF_LAST_IO)
 gen_io_end(cpu_env);
 done_generating:




[Qemu-devel] [PATCH v9 13/26] target: [tcg, i386] Refactor disas_flags

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |   25 +
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index e7b46d282a..5e426de947 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -8540,10 +8540,25 @@ static void i386_trblock_tb_stop(DisasContextBase *db, 
CPUState *cpu)
 }
 }
 
+static int i386_trblock_disas_flags(const DisasContextBase *db)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+#ifdef TARGET_X86_64
+if (dc->code64) {
+return 2;
+} else {
+return !dc->code32;
+}
+#else
+return !dc->code32;
+#endif
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
-DisasContext dc1, *dc = &dc1;
+DisasContext dc1;
 DisasContextBase *db = &dc1.base;
 CPUBreakpoint *bp;
 int num_insns;
@@ -8623,16 +8638,10 @@ done_generating:
 #ifdef DEBUG_DISAS
 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
 && qemu_log_in_addr_range(db->pc_first)) {
-int disas_flags;
+int disas_flags = i386_trblock_disas_flags(db);
 qemu_log_lock();
 qemu_log("\n");
 qemu_log("IN: %s\n", lookup_symbol(db->pc_first));
-#ifdef TARGET_X86_64
-if (dc->code64)
-disas_flags = 2;
-else
-#endif
-disas_flags = !dc->code32;
 log_target_disas(cpu, db->pc_first, db->pc_next - db->pc_first,
  disas_flags);
 qemu_log("\n");




[Qemu-devel] [PATCH v9 14/26] target: [tcg, i386] Replace DISAS_* with DJ_*

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/i386/translate.c |   27 +++
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/target/i386/translate.c b/target/i386/translate.c
index 5e426de947..c7bb6efbf5 100644
--- a/target/i386/translate.c
+++ b/target/i386/translate.c
@@ -71,6 +71,9 @@
 case (2 << 6) | (OP << 3) | 0 ... (2 << 6) | (OP << 3) | 7: \
 case (3 << 6) | (OP << 3) | 0 ... (3 << 6) | (OP << 3) | 7
 
+#define DJ_JUMP (DJ_TARGET + 0) /* end of block due to call/jump */
+#define DJ_MISC (DJ_TARGET + 1) /* some other reason */
+
 //#define MACRO_TEST   1
 
 /* global register indexes */
@@ -2180,7 +2183,7 @@ static inline void gen_jcc(DisasContext *s, int b,
 
 gen_set_label(l1);
 gen_goto_tb(s, 1, val);
-s->base.is_jmp = DISAS_TB_JUMP;
+s->base.is_jmp = DJ_JUMP;
 } else {
 l1 = gen_new_label();
 l2 = gen_new_label();
@@ -2253,11 +2256,11 @@ static void gen_movl_seg_T0(DisasContext *s, int 
seg_reg)
stop as a special handling must be done to disable hardware
interrupts for the next instruction */
 if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
-b->is_jmp = DISAS_TB_JUMP;
+b->is_jmp = DJ_JUMP;
 } else {
 gen_op_movl_seg_T0_vm(seg_reg);
 if (seg_reg == R_SS)
-b->is_jmp = DISAS_TB_JUMP;
+b->is_jmp = DJ_JUMP;
 }
 }
 
@@ -2431,7 +2434,7 @@ static void gen_exception(DisasContext *s, int trapno, 
target_ulong cur_eip)
 gen_update_cc_op(s);
 gen_jmp_im(cur_eip);
 gen_helper_raise_exception(cpu_env, tcg_const_i32(trapno));
-b->is_jmp = DISAS_TB_JUMP;
+b->is_jmp = DJ_JUMP;
 }
 
 /* Generate #UD for the current instruction.  The assumption here is that
@@ -2471,7 +2474,7 @@ static void gen_interrupt(DisasContext *s, int intno,
 gen_jmp_im(cur_eip);
 gen_helper_raise_interrupt(cpu_env, tcg_const_i32(intno),
tcg_const_i32(next_eip - cur_eip));
-b->is_jmp = DISAS_TB_JUMP;
+b->is_jmp = DJ_JUMP;
 }
 
 static void gen_debug(DisasContext *s, target_ulong cur_eip)
@@ -2481,7 +2484,7 @@ static void gen_debug(DisasContext *s, target_ulong 
cur_eip)
 gen_update_cc_op(s);
 gen_jmp_im(cur_eip);
 gen_helper_debug(cpu_env);
-b->is_jmp = DISAS_TB_JUMP;
+b->is_jmp = DJ_JUMP;
 }
 
 static void gen_set_hflag(DisasContext *s, uint32_t mask)
@@ -2558,7 +2561,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool 
recheck_tf, TCGv jr)
 } else {
 tcg_gen_exit_tb(0);
 }
-b->is_jmp = DISAS_TB_JUMP;
+b->is_jmp = DJ_JUMP;
 }
 
 static inline void
@@ -2599,7 +2602,7 @@ static void gen_jmp_tb(DisasContext *s, target_ulong eip, 
int tb_num)
 set_cc_op(s, CC_OP_DYNAMIC);
 if (s->jmp_opt) {
 gen_goto_tb(s, tb_num, eip);
-b->is_jmp = DISAS_TB_JUMP;
+b->is_jmp = DJ_JUMP;
 } else {
 gen_jmp_im(eip);
 gen_eob(s);
@@ -6963,7 +6966,7 @@ static target_ulong disas_insn(DisasContextBase *db, 
CPUState *cpu)
 gen_update_cc_op(s);
 gen_jmp_im(pc_start - s->cs_base);
 gen_helper_pause(cpu_env, tcg_const_i32(s->pc - pc_start));
-db->is_jmp = DISAS_TB_JUMP;
+db->is_jmp = DJ_JUMP;
 }
 break;
 case 0x9b: /* fwait */
@@ -7208,7 +7211,7 @@ static target_ulong disas_insn(DisasContextBase *db, 
CPUState *cpu)
 gen_update_cc_op(s);
 gen_jmp_im(pc_start - s->cs_base);
 gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
-db->is_jmp = DISAS_TB_JUMP;
+db->is_jmp = DJ_JUMP;
 }
 break;
 case 0x100:
@@ -7391,7 +7394,7 @@ static target_ulong disas_insn(DisasContextBase *db, 
CPUState *cpu)
 gen_helper_vmrun(cpu_env, tcg_const_i32(s->aflag - 1),
  tcg_const_i32(s->pc - pc_start));
 tcg_gen_exit_tb(0);
-db->is_jmp = DISAS_TB_JUMP;
+db->is_jmp = DJ_JUMP;
 break;
 
 case 0xd9: /* VMMCALL */
@@ -8567,7 +8570,7 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 /* generate intermediate code */
 db->singlestep_enabled = cpu->singlestep_enabled;
 db->tb = tb;
-db->is_jmp = DISAS_NEXT;
+db->is_jmp = DJ_NEXT;
 db->pc_first = tb->pc;
 db->pc_next = db->pc_first;
 i386_trblock_init_disas_context(db, cpu);




Re: [Qemu-devel] [PATCH v8 2/7] cpu: allocate cpu->trace_dstate in place

2017-06-25 Thread Lluís Vilanova
Lluís Vilanova writes:

> Emilio G Cota writes:
>> There's little point in dynamically allocating the bitmap if we
>> know at compile-time the max number of events we want to support.
>> Thus, make room in the struct for the bitmap, which will make things
>> easier later: this paves the way for upcoming changes, in which
>> we'll use a u32 to fully capture cpu->trace_dstate.

>> This change also increases performance by saving a dereference and
>> improving locality--note that this is important since upcoming work
>> makes reading this bitmap fairly common.

>> Signed-off-by: Emilio G. Cota 

> Reviewed-by: Lluís Vilanova 

BTW, I think this partially undoes Daniel's changes in
b7d48952c375842bd669460fd8384d90cc12286c.

You should check with him (CC'ed).

Lluis


>> ---
>> include/qom/cpu.h | 9 +++--
>> qom/cpu.c | 8 
>> trace/control.c   | 9 -
>> 3 files changed, 11 insertions(+), 15 deletions(-)

>> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
>> index 89ddb68..bc6e20f 100644
>> --- a/include/qom/cpu.h
>> +++ b/include/qom/cpu.h
>> @@ -259,6 +259,7 @@ typedef void (*run_on_cpu_func)(CPUState *cpu, 
>> run_on_cpu_data data);
>> struct qemu_work_item;
 
>> #define CPU_UNSET_NUMA_NODE_ID -1
>> +#define CPU_TRACE_DSTATE_MAX_EVENTS 32
 
>> /**
>> * CPUState:
>> @@ -373,12 +374,8 @@ struct CPUState {
>> struct KVMState *kvm_state;
>> struct kvm_run *kvm_run;
 
>> -/*
>> - * Used for events with 'vcpu' and *without* the 'disabled' properties.
>> - * Dynamically allocated based on bitmap requried to hold up to
>> - * trace_get_vcpu_event_count() entries.
>> - */
>> -unsigned long *trace_dstate;
>> +/* Used for events with 'vcpu' and *without* the 'disabled' properties 
>> */
>> +DECLARE_BITMAP(trace_dstate, CPU_TRACE_DSTATE_MAX_EVENTS);
 
>> /* TODO Move common fields from CPUArchState here. */
>> int cpu_index; /* used by alpha TCG */
>> diff --git a/qom/cpu.c b/qom/cpu.c
>> index 5069876..69fbb9c 100644
>> --- a/qom/cpu.c
>> +++ b/qom/cpu.c
>> @@ -382,7 +382,6 @@ static void cpu_common_unrealizefn(DeviceState *dev, 
>> Error **errp)
 
>> static void cpu_common_initfn(Object *obj)
>> {
>> -uint32_t count;
>> CPUState *cpu = CPU(obj);
>> CPUClass *cc = CPU_GET_CLASS(obj);
 
>> @@ -397,18 +396,11 @@ static void cpu_common_initfn(Object *obj)
>> QTAILQ_INIT(&cpu->breakpoints);
>> QTAILQ_INIT(&cpu->watchpoints);
 
>> -count = trace_get_vcpu_event_count();
>> -if (count) {
>> -cpu->trace_dstate = bitmap_new(count);
>> -}
>> -
>> cpu_exec_initfn(cpu);
>> }
 
>> static void cpu_common_finalize(Object *obj)
>> {
>> -CPUState *cpu = CPU(obj);
>> -g_free(cpu->trace_dstate);
>> }
 
>> static int64_t cpu_common_get_arch_id(CPUState *cpu)
>> diff --git a/trace/control.c b/trace/control.c
>> index 9b157b0..83740aa 100644
>> --- a/trace/control.c
>> +++ b/trace/control.c
>> @@ -65,8 +65,15 @@ void trace_event_register_group(TraceEvent **events)
>> size_t i;
>> for (i = 0; events[i] != NULL; i++) {
>> events[i]->id = next_id++;
>> -if (events[i]->vcpu_id != TRACE_VCPU_EVENT_NONE) {
>> +if (events[i]->vcpu_id == TRACE_VCPU_EVENT_NONE) {
>> +continue;
>> +}
>> +
>> +if (likely(next_vcpu_id < CPU_TRACE_DSTATE_MAX_EVENTS)) {
>> events[i]->vcpu_id = next_vcpu_id++;
>> +} else {
>> +error_report("WARNING: too many vcpu trace events; dropping 
>> '%s'",
>> + events[i]->name);
>> }
>> }
>> event_groups = g_renew(TraceEventGroup, event_groups, nevent_groups + 1);
>> -- 
>> 2.7.4





[Qemu-devel] [PATCH v9 16/26] target: [tcg, arm] Replace DISAS_* with DJ_*

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |   58 ++--
 target/arm/translate.c |   90 ++--
 target/arm/translate.h |   24 ++--
 3 files changed, 87 insertions(+), 85 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 43261e7939..d2fe2718ad 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -304,7 +304,7 @@ static void gen_exception_internal_insn(DisasContext *s, 
int offset, int excp)
 {
 gen_a64_set_pc_im(s->pc - offset);
 gen_exception_internal(excp);
-s->is_jmp = DISAS_EXC;
+s->is_jmp = DJ_EXC;
 }
 
 static void gen_exception_insn(DisasContext *s, int offset, int excp,
@@ -312,7 +312,7 @@ static void gen_exception_insn(DisasContext *s, int offset, 
int excp,
 {
 gen_a64_set_pc_im(s->pc - offset);
 gen_exception(excp, syndrome, target_el);
-s->is_jmp = DISAS_EXC;
+s->is_jmp = DJ_EXC;
 }
 
 static void gen_ss_advance(DisasContext *s)
@@ -340,7 +340,7 @@ static void gen_step_complete_exception(DisasContext *s)
 gen_ss_advance(s);
 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
   default_exception_el(s));
-s->is_jmp = DISAS_EXC;
+s->is_jmp = DJ_EXC;
 }
 
 static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
@@ -371,7 +371,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, 
uint64_t dest)
 tcg_gen_goto_tb(n);
 gen_a64_set_pc_im(dest);
 tcg_gen_exit_tb((intptr_t)tb + n);
-s->is_jmp = DISAS_TB_JUMP;
+s->is_jmp = DJ_TB_JUMP;
 } else {
 gen_a64_set_pc_im(dest);
 if (s->ss_active) {
@@ -380,7 +380,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, 
uint64_t dest)
 gen_exception_internal(EXCP_DEBUG);
 } else {
 tcg_gen_lookup_and_goto_ptr(cpu_pc);
-s->is_jmp = DISAS_TB_JUMP;
+s->is_jmp = DJ_TB_JUMP;
 }
 }
 }
@@ -1331,16 +1331,16 @@ static void handle_hint(DisasContext *s, uint32_t insn,
 case 0: /* NOP */
 return;
 case 3: /* WFI */
-s->is_jmp = DISAS_WFI;
+s->is_jmp = DJ_WFI;
 return;
 case 1: /* YIELD */
 if (!parallel_cpus) {
-s->is_jmp = DISAS_YIELD;
+s->is_jmp = DJ_YIELD;
 }
 return;
 case 2: /* WFE */
 if (!parallel_cpus) {
-s->is_jmp = DISAS_WFE;
+s->is_jmp = DJ_WFE;
 }
 return;
 case 4: /* SEV */
@@ -1393,7 +1393,7 @@ static void handle_sync(DisasContext *s, uint32_t insn,
  * a self-modified code correctly and also to take
  * any pending interrupts immediately.
  */
-s->is_jmp = DISAS_UPDATE;
+s->is_jmp = DJ_UPDATE;
 return;
 default:
 unallocated_encoding(s);
@@ -1422,7 +1422,7 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
 gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
 tcg_temp_free_i32(tcg_imm);
 tcg_temp_free_i32(tcg_op);
-s->is_jmp = DISAS_UPDATE;
+s->is_jmp = DJ_UPDATE;
 break;
 }
 default:
@@ -1591,13 +1591,13 @@ static void handle_sys(DisasContext *s, uint32_t insn, 
bool isread,
 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
 /* I/O operations must end the TB here (whether read or write) */
 gen_io_end(cpu_env);
-s->is_jmp = DISAS_UPDATE;
+s->is_jmp = DJ_UPDATE;
 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
 /* We default to ending the TB on a coprocessor register write,
  * but allow this to be suppressed by the register definition
  * (usually only necessary to work around guest bugs).
  */
-s->is_jmp = DISAS_UPDATE;
+s->is_jmp = DJ_UPDATE;
 }
 }
 
@@ -1786,7 +1786,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 return;
 }
 gen_helper_exception_return(cpu_env);
-s->is_jmp = DISAS_JUMP;
+s->is_jmp = DJ_JUMP;
 return;
 case 5: /* DRPS */
 if (rn != 0x1f) {
@@ -1800,7 +1800,7 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 return;
 }
 
-s->is_jmp = DISAS_JUMP;
+s->is_jmp = DJ_JUMP;
 }
 
 /* C3.2 Branches, exception generating and system instructions */
@@ -11202,7 +11202,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, 
TranslationBlock *tb)
 
 dc->tb = tb;
 
-dc->is_jmp = DISAS_NEXT;
+dc->is_jmp = DJ_NEXT;
 dc->pc = pc_start;
 dc->singlestep_enabled = cs->singlestep_enabled;
 dc->condjmp = 0;
@@ -11280,7 +11280,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, 
TranslationBlock *tb)
 gen_a64_set_pc_im(dc->pc);
 g

[Qemu-devel] [PATCH v9 17/26] target: [tcg, arm] Port to DisasContextBase

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |  113 ++--
 target/arm/translate.c |  154 
 target/arm/translate.h |   11 ++-
 3 files changed, 167 insertions(+), 111 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index d2fe2718ad..8d48251321 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -302,17 +302,21 @@ static void gen_exception(int excp, uint32_t syndrome, 
uint32_t target_el)
 
 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
 {
+DisasContextBase *b = &s->base;
+
 gen_a64_set_pc_im(s->pc - offset);
 gen_exception_internal(excp);
-s->is_jmp = DJ_EXC;
+b->is_jmp = DJ_EXC;
 }
 
 static void gen_exception_insn(DisasContext *s, int offset, int excp,
uint32_t syndrome, uint32_t target_el)
 {
+DisasContextBase *b = &s->base;
+
 gen_a64_set_pc_im(s->pc - offset);
 gen_exception(excp, syndrome, target_el);
-s->is_jmp = DJ_EXC;
+b->is_jmp = DJ_EXC;
 }
 
 static void gen_ss_advance(DisasContext *s)
@@ -328,6 +332,8 @@ static void gen_ss_advance(DisasContext *s)
 
 static void gen_step_complete_exception(DisasContext *s)
 {
+DisasContextBase *b = &s->base;
+
 /* We just completed step of an insn. Move from Active-not-pending
  * to Active-pending, and then also take the swstep exception.
  * This corresponds to making the (IMPDEF) choice to prioritize
@@ -340,21 +346,23 @@ static void gen_step_complete_exception(DisasContext *s)
 gen_ss_advance(s);
 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
   default_exception_el(s));
-s->is_jmp = DJ_EXC;
+b->is_jmp = DJ_EXC;
 }
 
 static inline bool use_goto_tb(DisasContext *s, int n, uint64_t dest)
 {
+DisasContextBase *b = &s->base;
+
 /* No direct tb linking with singlestep (either QEMU's or the ARM
  * debug architecture kind) or deterministic io
  */
-if (s->singlestep_enabled || s->ss_active || (s->tb->cflags & CF_LAST_IO)) 
{
+if (b->singlestep_enabled || s->ss_active || (b->tb->cflags & CF_LAST_IO)) 
{
 return false;
 }
 
 #ifndef CONFIG_USER_ONLY
 /* Only link tbs from inside the same guest page */
-if ((s->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
+if ((b->tb->pc & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
 return false;
 }
 #endif
@@ -364,23 +372,24 @@ static inline bool use_goto_tb(DisasContext *s, int n, 
uint64_t dest)
 
 static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
 {
+DisasContextBase *b = &s->base;
 TranslationBlock *tb;
 
-tb = s->tb;
+tb = b->tb;
 if (use_goto_tb(s, n, dest)) {
 tcg_gen_goto_tb(n);
 gen_a64_set_pc_im(dest);
 tcg_gen_exit_tb((intptr_t)tb + n);
-s->is_jmp = DJ_TB_JUMP;
+b->is_jmp = DJ_TB_JUMP;
 } else {
 gen_a64_set_pc_im(dest);
 if (s->ss_active) {
 gen_step_complete_exception(s);
-} else if (s->singlestep_enabled) {
+} else if (b->singlestep_enabled) {
 gen_exception_internal(EXCP_DEBUG);
 } else {
 tcg_gen_lookup_and_goto_ptr(cpu_pc);
-s->is_jmp = DJ_TB_JUMP;
+b->is_jmp = DJ_TB_JUMP;
 }
 }
 }
@@ -1320,6 +1329,7 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t 
insn)
 static void handle_hint(DisasContext *s, uint32_t insn,
 unsigned int op1, unsigned int op2, unsigned int crm)
 {
+DisasContextBase *b = &s->base;
 unsigned int selector = crm << 3 | op2;
 
 if (op1 != 3) {
@@ -1331,16 +1341,16 @@ static void handle_hint(DisasContext *s, uint32_t insn,
 case 0: /* NOP */
 return;
 case 3: /* WFI */
-s->is_jmp = DJ_WFI;
+b->is_jmp = DJ_WFI;
 return;
 case 1: /* YIELD */
 if (!parallel_cpus) {
-s->is_jmp = DJ_YIELD;
+b->is_jmp = DJ_YIELD;
 }
 return;
 case 2: /* WFE */
 if (!parallel_cpus) {
-s->is_jmp = DJ_WFE;
+b->is_jmp = DJ_WFE;
 }
 return;
 case 4: /* SEV */
@@ -1362,6 +1372,7 @@ static void gen_clrex(DisasContext *s, uint32_t insn)
 static void handle_sync(DisasContext *s, uint32_t insn,
 unsigned int op1, unsigned int op2, unsigned int crm)
 {
+DisasContextBase *b = &s->base;
 TCGBar bar;
 
 if (op1 != 3) {
@@ -1393,7 +1404,7 @@ static void handle_sync(DisasContext *s, uint32_t insn,
  * a self-modified code correctly and also to take
  * any pending interrupts immediately.
  */
-s->is_jmp = DJ_UPDATE;
+b->is_jmp = DJ_UPDATE;
 return;
 default:
 unallocated_enco

[Qemu-devel] [PATCH v9 18/26] target: [tcg, arm] Port to init_disas_context

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |   51 +++---
 target/arm/translate.c |   87 
 2 files changed, 78 insertions(+), 60 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 8d48251321..1959f27377 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11202,21 +11202,12 @@ static void disas_a64_insn(CPUARMState *env, 
DisasContext *s)
 free_tmp_a64(s);
 }
 
-void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
-   TranslationBlock *tb)
+static void aarch64_trblock_init_disas_context(DisasContextBase *db,
+   CPUState *cpu)
 {
-CPUState *cs = CPU(cpu);
-CPUARMState *env = &cpu->env;
 DisasContext *dc = container_of(db, DisasContext, base);
-target_ulong next_page_start;
-int max_insns;
-
-db->tb = tb;
-db->pc_first = tb->pc;
-db->pc_next = db->pc_first;
-db->is_jmp = DJ_NEXT;
-db->num_insns = 0;
-db->singlestep_enabled = cs->singlestep_enabled;
+CPUARMState *env = cpu->env_ptr;
+ARMCPU *arm_cpu = arm_env_get_cpu(env);
 
 dc->pc = db->pc_first;
 dc->condjmp = 0;
@@ -11229,20 +11220,20 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
!arm_el_is_aa64(env, 3);
 dc->thumb = 0;
 dc->sctlr_b = 0;
-dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
+dc->be_data = ARM_TBFLAG_BE_DATA(db->tb->flags) ? MO_BE : MO_LE;
 dc->condexec_mask = 0;
 dc->condexec_cond = 0;
-dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
-dc->tbi0 = ARM_TBFLAG_TBI0(tb->flags);
-dc->tbi1 = ARM_TBFLAG_TBI1(tb->flags);
+dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(db->tb->flags));
+dc->tbi0 = ARM_TBFLAG_TBI0(db->tb->flags);
+dc->tbi1 = ARM_TBFLAG_TBI1(db->tb->flags);
 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
 dc->user = (dc->current_el == 0);
 #endif
-dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
+dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(db->tb->flags);
 dc->vec_len = 0;
 dc->vec_stride = 0;
-dc->cp_regs = cpu->cp_regs;
+dc->cp_regs = arm_cpu->cp_regs;
 dc->features = env->features;
 
 /* Single step state. The code-generation logic here is:
@@ -11260,12 +11251,30 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
  *   emit code to generate a software step exception
  *   end the TB
  */
-dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
-dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
+dc->ss_active = ARM_TBFLAG_SS_ACTIVE(db->tb->flags);
+dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(db->tb->flags);
 dc->is_ldex = false;
 dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
 
 init_tmp_a64_array(dc);
+}
+
+void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
+   TranslationBlock *tb)
+{
+CPUState *cs = CPU(cpu);
+CPUARMState *env = &cpu->env;
+DisasContext *dc = container_of(db, DisasContext, base);
+target_ulong next_page_start;
+int max_insns;
+
+db->tb = tb;
+db->pc_first = tb->pc;
+db->pc_next = db->pc_first;
+db->is_jmp = DISAS_NEXT;
+db->num_insns = 0;
+db->singlestep_enabled = cs->singlestep_enabled;
+aarch64_trblock_init_disas_context(db, cs);
 
 next_page_start = (db->pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 max_insns = tb->cflags & CF_COUNT_MASK;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 19d042d843..c469bc70ac 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11823,33 +11823,11 @@ static bool insn_crosses_page(CPUARMState *env, 
DisasContext *s)
 return false;
 }
 
-/* generate intermediate code for basic block 'tb'.  */
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
+static void arm_trblock_init_disas_context(DisasContextBase *db, CPUState *cpu)
 {
+DisasContext *dc = container_of(db, DisasContext, base);
 CPUARMState *env = cpu->env_ptr;
 ARMCPU *arm_cpu = arm_env_get_cpu(env);
-DisasContext dc1, *dc = &dc1;
-DisasContextBase *db = &dc->base;
-target_ulong next_page_start;
-int max_insns;
-bool end_of_page;
-
-/* generate intermediate code */
-
-/* The A64 decoder has its own top level loop, because it doesn't need
- * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
- */
-if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
-gen_intermediate_code_a64(db, arm_cpu, tb);
-return;
-}
-
-db->tb = tb;
-db->pc_first = tb->pc;
-db->pc_next = db->pc_first;
-db->is_jmp = DJ_NEXT;
-db->num_insns = 0;
-db->singl

[Qemu-devel] [PATCH v9 19/26] target: [tcg, arm] Port to init_globals

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate.c |   21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index c469bc70ac..cc11dacd56 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11879,6 +11879,18 @@ static void 
arm_trblock_init_disas_context(DisasContextBase *db, CPUState *cpu)
 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
 }
 
+static void arm_trblock_init_globals(DisasContextBase *db, CPUState *cpu)
+{
+cpu_F0s = tcg_temp_new_i32();
+cpu_F1s = tcg_temp_new_i32();
+cpu_F0d = tcg_temp_new_i64();
+cpu_F1d = tcg_temp_new_i64();
+cpu_V0 = cpu_F0d;
+cpu_V1 = cpu_F1d;
+/* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
+cpu_M0 = tcg_temp_new_i64();
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
@@ -11909,14 +11921,7 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 arm_trblock_init_disas_context(db, cpu);
 
 
-cpu_F0s = tcg_temp_new_i32();
-cpu_F1s = tcg_temp_new_i32();
-cpu_F0d = tcg_temp_new_i64();
-cpu_F1d = tcg_temp_new_i64();
-cpu_V0 = cpu_F0d;
-cpu_V1 = cpu_F1d;
-/* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
-cpu_M0 = tcg_temp_new_i64();
+arm_trblock_init_globals(db, cpu);
 next_page_start = (db->pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 max_insns = tb->cflags & CF_COUNT_MASK;
 if (max_insns == 0) {




[Qemu-devel] [PATCH v9 20/26] target: [tcg,arm] Port to tb_start

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate.c |   82 ++--
 1 file changed, 44 insertions(+), 38 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index cc11dacd56..ae3f772446 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11891,6 +11891,49 @@ static void arm_trblock_init_globals(DisasContextBase 
*db, CPUState *cpu)
 cpu_M0 = tcg_temp_new_i64();
 }
 
+static void arm_trblock_tb_start(DisasContextBase *db, CPUState *cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+/* A note on handling of the condexec (IT) bits:
+ *
+ * We want to avoid the overhead of having to write the updated condexec
+ * bits back to the CPUARMState for every instruction in an IT block. So:
+ * (1) if the condexec bits are not already zero then we write
+ * zero back into the CPUARMState now. This avoids complications trying
+ * to do it at the end of the block. (For example if we don't do this
+ * it's hard to identify whether we can safely skip writing condexec
+ * at the end of the TB, which we definitely want to do for the case
+ * where a TB doesn't do anything with the IT state at all.)
+ * (2) if we are going to leave the TB then we call gen_set_condexec()
+ * which will write the correct value into CPUARMState if zero is wrong.
+ * This is done both for leaving the TB at the end, and for leaving
+ * it because of an exception we know will happen, which is done in
+ * gen_exception_insn(). The latter is necessary because we need to
+ * leave the TB with the PC/IT state just prior to execution of the
+ * instruction which caused the exception.
+ * (3) if we leave the TB unexpectedly (eg a data abort on a load)
+ * then the CPUARMState will be wrong and we need to reset it.
+ * This is handled in the same way as restoration of the
+ * PC in these situations; we save the value of the condexec bits
+ * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
+ * then uses this to restore them after an exception.
+ *
+ * Note that there are no instructions which can read the condexec
+ * bits, and none which can write non-static values to them, so
+ * we don't need to care about whether CPUARMState is correct in the
+ * middle of a TB.
+ */
+
+/* Reset the conditional execution bits immediately. This avoids
+   complications trying to do it at the end of the block.  */
+if (dc->condexec_mask || dc->condexec_cond) {
+TCGv_i32 tmp = tcg_temp_new_i32();
+tcg_gen_movi_i32(tmp, 0);
+store_cpu_field(tmp, condexec_bits);
+}
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
@@ -11934,45 +11977,8 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 gen_tb_start(tb, cpu_env);
 
 tcg_clear_temp_count();
+arm_trblock_tb_start(db, cpu);
 
-/* A note on handling of the condexec (IT) bits:
- *
- * We want to avoid the overhead of having to write the updated condexec
- * bits back to the CPUARMState for every instruction in an IT block. So:
- * (1) if the condexec bits are not already zero then we write
- * zero back into the CPUARMState now. This avoids complications trying
- * to do it at the end of the block. (For example if we don't do this
- * it's hard to identify whether we can safely skip writing condexec
- * at the end of the TB, which we definitely want to do for the case
- * where a TB doesn't do anything with the IT state at all.)
- * (2) if we are going to leave the TB then we call gen_set_condexec()
- * which will write the correct value into CPUARMState if zero is wrong.
- * This is done both for leaving the TB at the end, and for leaving
- * it because of an exception we know will happen, which is done in
- * gen_exception_insn(). The latter is necessary because we need to
- * leave the TB with the PC/IT state just prior to execution of the
- * instruction which caused the exception.
- * (3) if we leave the TB unexpectedly (eg a data abort on a load)
- * then the CPUARMState will be wrong and we need to reset it.
- * This is handled in the same way as restoration of the
- * PC in these situations; we save the value of the condexec bits
- * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
- * then uses this to restore them after an exception.
- *
- * Note that there are no instructions which can read the condexec
- * bits, and none which can write non-static values to them, so
- * we don't need to care about whether CPUARMState is correct in the
- * middle of a TB.
- */
-
-/* Reset the conditional execution bits immediate

[Qemu-devel] [PATCH v9 21/26] target: [tcg, arm] Port to insn_start

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |   11 +--
 target/arm/translate.c |   36 +---
 2 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 1959f27377..bfc2cdabb5 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11259,6 +11259,14 @@ static void 
aarch64_trblock_init_disas_context(DisasContextBase *db,
 init_tmp_a64_array(dc);
 }
 
+static void aarch64_trblock_insn_start(DisasContextBase *db, CPUState *cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+dc->insn_start_idx = tcg_op_buf_count();
+tcg_gen_insn_start(dc->pc, 0, 0);
+}
+
 void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
TranslationBlock *tb)
 {
@@ -11291,8 +11299,7 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
 
 do {
 db->num_insns++;
-dc->insn_start_idx = tcg_op_buf_count();
-tcg_gen_insn_start(dc->pc, 0, 0);
+aarch64_trblock_insn_start(db, cs);
 
 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
 CPUBreakpoint *bp;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index ae3f772446..18b0e8fbb6 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11934,6 +11934,26 @@ static void arm_trblock_tb_start(DisasContextBase *db, 
CPUState *cpu)
 }
 }
 
+static void arm_trblock_insn_start(DisasContextBase *db, CPUState *cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+dc->insn_start_idx = tcg_op_buf_count();
+tcg_gen_insn_start(dc->pc,
+   (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
+   0);
+
+#ifdef CONFIG_USER_ONLY
+/* Intercept jump to the magic kernel page.  */
+if (dc->pc >= 0x) {
+/* We always get here via a jump, so know we are not in a
+   conditional execution block.  */
+gen_exception_internal(EXCP_KERNEL_TRAP);
+dc->is_jmp = DJ_EXC;
+}
+#endif
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
@@ -11981,21 +12001,7 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 
 do {
 db->num_insns++;
-dc->insn_start_idx = tcg_op_buf_count();
-tcg_gen_insn_start(dc->pc,
-   (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
-   0);
-
-#ifdef CONFIG_USER_ONLY
-/* Intercept jump to the magic kernel page.  */
-if (dc->pc >= 0x) {
-/* We always get here via a jump, so know we are not in a
-   conditional execution block.  */
-gen_exception_internal(EXCP_KERNEL_TRAP);
-dc->is_jmp = DJ_EXC;
-break;
-}
-#endif
+arm_trblock_insn_start(db, cpu);
 
 if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
 CPUBreakpoint *bp;




[Qemu-devel] [PATCH v9 22/26] target: [tcg, arm] Port to breakpoint_check

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |   59 ++-
 target/arm/translate.c |   66 +---
 2 files changed, 82 insertions(+), 43 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index bfc2cdabb5..4321767355 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11267,6 +11267,29 @@ static void 
aarch64_trblock_insn_start(DisasContextBase *db, CPUState *cpu)
 tcg_gen_insn_start(dc->pc, 0, 0);
 }
 
+static BreakpointCheckType aarch64_trblock_breakpoint_check(
+DisasContextBase *db, CPUState *cpu, const CPUBreakpoint *bp)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+if (bp->flags & BP_CPU) {
+gen_a64_set_pc_im(dc->pc);
+gen_helper_check_breakpoints(cpu_env);
+/* End the TB early; it likely won't be executed */
+db->is_jmp = DJ_UPDATE;
+return BC_HIT_INSN;
+} else {
+gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
+/* The address covered by the breakpoint must be
+   included in [tb->pc, tb->pc + tb->size) in order
+   to for it to be properly cleared -- thus we
+   increment the PC here so that the logic setting
+   tb->size below does the right thing.  */
+dc->pc += 4;
+return BC_HIT_TB;
+}
+}
+
 void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
TranslationBlock *tb)
 {
@@ -11275,6 +11298,7 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
 DisasContext *dc = container_of(db, DisasContext, base);
 target_ulong next_page_start;
 int max_insns;
+CPUBreakpoint *bp;
 
 db->tb = tb;
 db->pc_first = tb->pc;
@@ -11301,29 +11325,24 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
 db->num_insns++;
 aarch64_trblock_insn_start(db, cs);
 
-if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
-CPUBreakpoint *bp;
-QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
-if (bp->pc == dc->pc) {
-if (bp->flags & BP_CPU) {
-gen_a64_set_pc_im(dc->pc);
-gen_helper_check_breakpoints(cpu_env);
-/* End the TB early; it likely won't be executed */
-db->is_jmp = DJ_UPDATE;
-} else {
-gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
-/* The address covered by the breakpoint must be
-   included in [tb->pc, tb->pc + tb->size) in order
-   to for it to be properly cleared -- thus we
-   increment the PC here so that the logic setting
-   tb->size below does the right thing.  */
-dc->pc += 4;
-goto done_generating;
-}
+bp = NULL;
+do {
+bp = cpu_breakpoint_get(cs, db->pc_next, bp);
+if (unlikely(bp)) {
+BreakpointCheckType bp_check =
+aarch64_trblock_breakpoint_check(db, cs, bp);
+if (bp_check == BC_HIT_INSN) {
+/* Hit, keep translating */
+/*
+ * TODO: if we're never going to have more than one BP in a
+ *   single address, we can simply use a bool here.
+ */
 break;
+} else {
+goto done_generating;
 }
 }
-}
+} while (bp != NULL);
 
 if (db->num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
 gen_io_start(cpu_env);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 18b0e8fbb6..a7fcaf2a21 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11954,6 +11954,33 @@ static void arm_trblock_insn_start(DisasContextBase 
*db, CPUState *cpu)
 #endif
 }
 
+static BreakpointCheckType arm_trblock_breakpoint_check(DisasContextBase *db,
+CPUState *cpu,
+const CPUBreakpoint 
*bp)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+if (bp->flags & BP_CPU) {
+gen_set_condexec(dc);
+gen_set_pc_im(dc, dc->pc);
+gen_helper_check_breakpoints(cpu_env);
+/* End the TB early; it's likely not going to be executed */
+db->is_jmp = DJ_UPDATE;
+return BC_HIT_INSN;
+} else {
+gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
+/* The address covered by the breakpoint must be
+   included in [tb->pc, tb->pc + tb->size) in order
+

[Qemu-devel] [PATCH v9 23/26] target: [tcg, arm] Port to disas_insn

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |   73 ++
 target/arm/translate.c |  144 +---
 target/arm/translate.h |4 +
 3 files changed, 131 insertions(+), 90 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 4321767355..f618a15062 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11256,6 +11256,8 @@ static void 
aarch64_trblock_init_disas_context(DisasContextBase *db,
 dc->is_ldex = false;
 dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
 
+dc->next_page_start = (db->pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+
 init_tmp_a64_array(dc);
 }
 
@@ -11290,13 +11292,46 @@ static BreakpointCheckType 
aarch64_trblock_breakpoint_check(
 }
 }
 
+static target_ulong aarch64_trblock_disas_insn(DisasContextBase *db,
+   CPUState *cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+CPUARMState *env = cpu->env_ptr;
+
+
+if (dc->ss_active && !dc->pstate_ss) {
+/* Singlestep state is Active-pending.
+ * If we're in this state at the start of a TB then either
+ *  a) we just took an exception to an EL which is being debugged
+ * and this is the first insn in the exception handler
+ *  b) debug exceptions were masked and we just unmasked them
+ * without changing EL (eg by clearing PSTATE.D)
+ * In either case we're going to take a swstep exception in the
+ * "did not step an insn" case, and so the syndrome ISV and EX
+ * bits should be zero.
+ */
+assert(db->num_insns == 1);
+gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
+  default_exception_el(dc));
+db->is_jmp = DJ_EXC;
+} else {
+disas_a64_insn(env, dc);
+}
+
+if (dc->ss_active) {
+db->is_jmp = DJ_SS;
+} else if (dc->pc >= dc->next_page_start) {
+db->is_jmp = DJ_PAGE_CROSS;
+}
+
+return dc->pc;
+}
+
 void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
TranslationBlock *tb)
 {
 CPUState *cs = CPU(cpu);
-CPUARMState *env = &cpu->env;
 DisasContext *dc = container_of(db, DisasContext, base);
-target_ulong next_page_start;
 int max_insns;
 CPUBreakpoint *bp;
 
@@ -11308,7 +11343,6 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
 db->singlestep_enabled = cs->singlestep_enabled;
 aarch64_trblock_init_disas_context(db, cs);
 
-next_page_start = (db->pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 max_insns = tb->cflags & CF_COUNT_MASK;
 if (max_insns == 0) {
 max_insns = CF_COUNT_MASK;
@@ -11348,42 +11382,24 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
 gen_io_start(cpu_env);
 }
 
-if (dc->ss_active && !dc->pstate_ss) {
-/* Singlestep state is Active-pending.
- * If we're in this state at the start of a TB then either
- *  a) we just took an exception to an EL which is being debugged
- * and this is the first insn in the exception handler
- *  b) debug exceptions were masked and we just unmasked them
- * without changing EL (eg by clearing PSTATE.D)
- * In either case we're going to take a swstep exception in the
- * "did not step an insn" case, and so the syndrome ISV and EX
- * bits should be zero.
- */
-assert(db->num_insns == 1);
-gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
-  default_exception_el(dc));
-db->is_jmp = DJ_EXC;
-break;
-}
-
-disas_a64_insn(env, dc);
+db->pc_next = aarch64_trblock_disas_insn(db, cs);
 
 if (tcg_check_temp_count()) {
 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
 dc->pc);
 }
 
+if (!db->is_jmp && (tcg_op_buf_full() || cs->singlestep_enabled ||
+singlestep || db->num_insns >= max_insns)) {
+db->is_jmp = DJ_TOO_MANY;
+}
+
 /* Translation stops when a conditional branch is encountered.
  * Otherwise the subsequent code could get translated several times.
  * Also stop translation when a page boundary is reached.  This
  * ensures prefetch aborts occur at the right place.
  */
-} while (!db->is_jmp && !tcg_op_buf_full() &&
- !cs->singlestep_enabled &&
- !singlestep &&
- !dc->ss_active &&
- dc->pc < next_page_start &&
- db->num_insns < max_insns);
+} while (!db->is_jmp);
 
 if 

[Qemu-devel] [PATCH v9 24/26] target: [tcg,arm] Port to tb_stop

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |  121 +++--
 target/arm/translate.c |  185 
 2 files changed, 164 insertions(+), 142 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f618a15062..b14e96cd58 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11327,6 +11327,68 @@ static target_ulong 
aarch64_trblock_disas_insn(DisasContextBase *db,
 return dc->pc;
 }
 
+static void aarch64_trblock_tb_stop(DisasContextBase *db, CPUState *cpu)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+if (unlikely(db->singlestep_enabled || dc->ss_active)
+&& db->is_jmp != DJ_EXC) {
+/* Note that this means single stepping WFI doesn't halt the CPU.
+ * For conditional branch insns this is harmless unreachable code as
+ * gen_goto_tb() has already handled emitting the debug exception
+ * (and thus a tb-jump is not possible when singlestepping).
+ */
+assert(db->is_jmp != DJ_TB_JUMP);
+if (db->is_jmp != DJ_JUMP) {
+gen_a64_set_pc_im(dc->pc);
+}
+if (db->singlestep_enabled) {
+gen_exception_internal(EXCP_DEBUG);
+} else {
+gen_step_complete_exception(dc);
+}
+} else {
+/* Cast because target-specific values are not in generic enum */
+unsigned int is_jmp = (unsigned int)db->is_jmp;
+switch (is_jmp) {
+case DJ_NEXT:
+case DJ_TOO_MANY:
+gen_goto_tb(dc, 1, dc->pc);
+break;
+default:
+case DJ_UPDATE:
+gen_a64_set_pc_im(dc->pc);
+/* fall through */
+case DJ_JUMP:
+tcg_gen_lookup_and_goto_ptr(cpu_pc);
+break;
+case DJ_TB_JUMP:
+case DJ_EXC:
+case DJ_SWI:
+break;
+case DJ_WFE:
+gen_a64_set_pc_im(dc->pc);
+gen_helper_wfe(cpu_env);
+break;
+case DJ_YIELD:
+gen_a64_set_pc_im(dc->pc);
+gen_helper_yield(cpu_env);
+break;
+case DJ_WFI:
+/* This is a special case because we don't want to just halt the 
CPU
+ * if trying to debug across a WFI.
+ */
+gen_a64_set_pc_im(dc->pc);
+gen_helper_wfi(cpu_env);
+/* The helper doesn't necessarily throw an exception, but we
+ * must go back to the main loop to check for interrupts anyway.
+ */
+tcg_gen_exit_tb(0);
+break;
+}
+}
+}
+
 void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
TranslationBlock *tb)
 {
@@ -11401,67 +11463,12 @@ void gen_intermediate_code_a64(DisasContextBase *db, 
ARMCPU *cpu,
  */
 } while (!db->is_jmp);
 
+aarch64_trblock_tb_stop(db, cs);
+
 if (tb->cflags & CF_LAST_IO) {
 gen_io_end(cpu_env);
 }
 
-if (unlikely(cs->singlestep_enabled || dc->ss_active)
-&& db->is_jmp != DJ_EXC) {
-/* Note that this means single stepping WFI doesn't halt the CPU.
- * For conditional branch insns this is harmless unreachable code as
- * gen_goto_tb() has already handled emitting the debug exception
- * (and thus a tb-jump is not possible when singlestepping).
- */
-assert(db->is_jmp != DJ_TB_JUMP);
-if (db->is_jmp != DJ_JUMP) {
-gen_a64_set_pc_im(dc->pc);
-}
-if (cs->singlestep_enabled) {
-gen_exception_internal(EXCP_DEBUG);
-} else {
-gen_step_complete_exception(dc);
-}
-} else {
-/* Cast because target-specific values are not in generic enum */
-unsigned int is_jmp = (unsigned int)db->is_jmp;
-switch (is_jmp) {
-case DJ_NEXT:
-case DJ_TOO_MANY:
-gen_goto_tb(dc, 1, dc->pc);
-break;
-default:
-case DJ_UPDATE:
-gen_a64_set_pc_im(dc->pc);
-/* fall through */
-case DJ_JUMP:
-tcg_gen_lookup_and_goto_ptr(cpu_pc);
-break;
-case DJ_TB_JUMP:
-case DJ_EXC:
-case DJ_SWI:
-break;
-case DJ_WFE:
-gen_a64_set_pc_im(dc->pc);
-gen_helper_wfe(cpu_env);
-break;
-case DJ_YIELD:
-gen_a64_set_pc_im(dc->pc);
-gen_helper_yield(cpu_env);
-break;
-case DJ_WFI:
-/* This is a special case because we don't want to just halt the 
CPU
- * if trying to debug across a WFI.
- */
-gen_a64_set_pc_im(dc->pc);
-gen_helper_wfi(cpu_env);
-/* The helper doesn't necessarily throw an exception, but we
-

[Qemu-devel] [PATCH v9 25/26] target: [tcg, arm] Port to disas_flags

2017-06-25 Thread Lluís Vilanova
Incrementally paves the way towards using the generic instruction translation
loop.

Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |   10 +-
 target/arm/translate.c |   10 +-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index b14e96cd58..97e8bda230 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11389,6 +11389,13 @@ static void aarch64_trblock_tb_stop(DisasContextBase 
*db, CPUState *cpu)
 }
 }
 
+static int aarch64_trblock_disas_flags(const DisasContextBase *db)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+return 4 | (bswap_code(dc->sctlr_b) ? 2 : 0);
+}
+
 void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
TranslationBlock *tb)
 {
@@ -11475,11 +11482,12 @@ done_generating:
 #ifdef DEBUG_DISAS
 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
 qemu_log_in_addr_range(db->pc_first)) {
+int disas_flags = aarch64_trblock_disas_flags(db);
 qemu_log_lock();
 qemu_log("\n");
 qemu_log("IN: %s\n", lookup_symbol(db->pc_first));
 log_target_disas(cs, db->pc_first, dc->pc - db->pc_first,
- 4 | (bswap_code(dc->sctlr_b) ? 2 : 0));
+ disas_flags);
 qemu_log("\n");
 qemu_log_unlock();
 }
diff --git a/target/arm/translate.c b/target/arm/translate.c
index db31611258..d87328602a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -12179,6 +12179,13 @@ static void arm_trblock_tb_stop(DisasContextBase *db, 
CPUState *cpu)
 }
 }
 
+static int arm_trblock_disas_flags(const DisasContextBase *db)
+{
+DisasContext *dc = container_of(db, DisasContext, base);
+
+return dc->thumb | (dc->sctlr_b << 1);
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
 {
@@ -12274,11 +12281,12 @@ done_generating:
 #ifdef DEBUG_DISAS
 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
 qemu_log_in_addr_range(db->pc_first)) {
+int disas_flags = arm_trblock_disas_flags(db);
 qemu_log_lock();
 qemu_log("\n");
 qemu_log("IN: %s\n", lookup_symbol(db->pc_first));
 log_target_disas(cpu, db->pc_first, dc->pc - db->pc_first,
- dc->thumb | (dc->sctlr_b << 1));
+ disas_flags);
 qemu_log("\n");
 qemu_log_unlock();
 }




[Qemu-devel] [PATCH v9 26/26] target: [tcg, arm] Port to generic translation framework

2017-06-25 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 target/arm/translate-a64.c |  110 ++-
 target/arm/translate.c |  112 +++-
 target/arm/translate.h |6 +-
 3 files changed, 36 insertions(+), 192 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 97e8bda230..59c5d58dd1 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11387,6 +11387,9 @@ static void aarch64_trblock_tb_stop(DisasContextBase 
*db, CPUState *cpu)
 break;
 }
 }
+
+/* Functions above can change dc->pc, so re-align db->pc_next */
+db->pc_next = dc->pc;
 }
 
 static int aarch64_trblock_disas_flags(const DisasContextBase *db)
@@ -11396,102 +11399,17 @@ static int aarch64_trblock_disas_flags(const 
DisasContextBase *db)
 return 4 | (bswap_code(dc->sctlr_b) ? 2 : 0);
 }
 
-void gen_intermediate_code_a64(DisasContextBase *db, ARMCPU *cpu,
+static TranslatorOps aarch64_translator_ops = {
+.init_disas_context = aarch64_trblock_init_disas_context,
+.insn_start = aarch64_trblock_insn_start,
+.breakpoint_check = aarch64_trblock_breakpoint_check,
+.disas_insn = aarch64_trblock_disas_insn,
+.tb_stop = aarch64_trblock_tb_stop,
+.disas_flags = aarch64_trblock_disas_flags,
+};
+
+void gen_intermediate_code_a64(DisasContextBase *db, CPUState *cpu,
TranslationBlock *tb)
 {
-CPUState *cs = CPU(cpu);
-DisasContext *dc = container_of(db, DisasContext, base);
-int max_insns;
-CPUBreakpoint *bp;
-
-db->tb = tb;
-db->pc_first = tb->pc;
-db->pc_next = db->pc_first;
-db->is_jmp = DISAS_NEXT;
-db->num_insns = 0;
-db->singlestep_enabled = cs->singlestep_enabled;
-aarch64_trblock_init_disas_context(db, cs);
-
-max_insns = tb->cflags & CF_COUNT_MASK;
-if (max_insns == 0) {
-max_insns = CF_COUNT_MASK;
-}
-if (max_insns > TCG_MAX_INSNS) {
-max_insns = TCG_MAX_INSNS;
-}
-
-gen_tb_start(tb, cpu_env);
-
-tcg_clear_temp_count();
-
-do {
-db->num_insns++;
-aarch64_trblock_insn_start(db, cs);
-
-bp = NULL;
-do {
-bp = cpu_breakpoint_get(cs, db->pc_next, bp);
-if (unlikely(bp)) {
-BreakpointCheckType bp_check =
-aarch64_trblock_breakpoint_check(db, cs, bp);
-if (bp_check == BC_HIT_INSN) {
-/* Hit, keep translating */
-/*
- * TODO: if we're never going to have more than one BP in a
- *   single address, we can simply use a bool here.
- */
-break;
-} else {
-goto done_generating;
-}
-}
-} while (bp != NULL);
-
-if (db->num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-gen_io_start(cpu_env);
-}
-
-db->pc_next = aarch64_trblock_disas_insn(db, cs);
-
-if (tcg_check_temp_count()) {
-fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
-dc->pc);
-}
-
-if (!db->is_jmp && (tcg_op_buf_full() || cs->singlestep_enabled ||
-singlestep || db->num_insns >= max_insns)) {
-db->is_jmp = DJ_TOO_MANY;
-}
-
-/* Translation stops when a conditional branch is encountered.
- * Otherwise the subsequent code could get translated several times.
- * Also stop translation when a page boundary is reached.  This
- * ensures prefetch aborts occur at the right place.
- */
-} while (!db->is_jmp);
-
-aarch64_trblock_tb_stop(db, cs);
-
-if (tb->cflags & CF_LAST_IO) {
-gen_io_end(cpu_env);
-}
-
-done_generating:
-gen_tb_end(tb, db->num_insns);
-
-#ifdef DEBUG_DISAS
-if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
-qemu_log_in_addr_range(db->pc_first)) {
-int disas_flags = aarch64_trblock_disas_flags(db);
-qemu_log_lock();
-qemu_log("\n");
-qemu_log("IN: %s\n", lookup_symbol(db->pc_first));
-log_target_disas(cs, db->pc_first, dc->pc - db->pc_first,
- disas_flags);
-qemu_log("\n");
-qemu_log_unlock();
-}
-#endif
-tb->size = dc->pc - db->pc_first;
-tb->icount = db->num_insns;
+translate_block(&aarch64_translator_ops, db, cpu, &cpu_env, tb);
 }
diff --git a/target/arm/translate.c b/target/arm/translate.c
index d87328602a..d9a7d870cb 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -12177,6 +12177,9 @@ static void arm_trblock_tb_stop(DisasContextBase *db, 
CPUState *cpu)
 gen_goto_tb(dc, 1, dc->pc);
 }
 }
+
+/* Functions above can change dc->pc, so re-align db->pc_next */
+db->pc_next = dc->pc;
 }
 
 static int arm_trb

[Qemu-devel] [PATCH] trace: Fix early setting of events with the "vcpu" property

2017-06-25 Thread Lluís Vilanova
Events with the "vcpu" property need to be set globally (i.e., as if they didn't
have that property) while we have not yet created any vCPU.

Signed-off-by: Lluís Vilanova 
---
 trace/control-target.c |   10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/trace/control-target.c b/trace/control-target.c
index 6266e6380d..99a8ed5157 100644
--- a/trace/control-target.c
+++ b/trace/control-target.c
@@ -1,7 +1,7 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2014-2016 Lluís Vilanova 
+ * Copyright (C) 2014-2017 Lluís Vilanova 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -38,12 +38,16 @@ void trace_event_set_state_dynamic(TraceEvent *ev, bool 
state)
 {
 CPUState *vcpu;
 assert(trace_event_get_state_static(ev));
-if (trace_event_is_vcpu(ev)) {
+if (trace_event_is_vcpu(ev) && likely(first_cpu != NULL)) {
 CPU_FOREACH(vcpu) {
 trace_event_set_vcpu_state_dynamic(vcpu, ev, state);
 }
 } else {
-/* Without the "vcpu" property, dstate can only be 1 or 0 */
+/*
+ * Without the "vcpu" property, dstate can only be 1 or 0. With it, we
+ * haven't instantiated any vCPU yet, so we will set a global state
+ * instead, and trace_init_vcpu will reconcile it afterwards.
+ */
 bool state_pre = *ev->dstate;
 if (state_pre != state) {
 if (state) {




Re: [Qemu-devel] [PATCH] target/i386: fix interrupt CPL error when

2017-06-25 Thread Wu Xiang
In-Reply-To: <641e1f35-813a-4244-0194-ffce08130...@redhat.com>

On Fri, Jun 23, 2017 at 01:19:35PM +0200, Paolo Bonzini wrote:
> 
> 
> On 21/06/2017 16:21, Wu Xiang wrote:
> > In do_interrupt64(), when interrupt stack table(ist) is enabled
> > and the the target code segment is conforming(e2 & DESC_C_MASK), the
> > old implementation always set new CPL to 0, and SS.RPL to 0.
> > 
> > This is incorrect for when CPL3 code access a CPL0 conforming code
> > segment, the CPL should remain unchanged. Otherwise higher privileged
> > code can be compromised.
> > 
> > The patch fix this for always set dpl = cpl when the target code segment
> > is conforming, and modify the last parameter `flags`, which contains
> > correct new CPL, in cpu_x86_load_seg_cache().
> > 
> > Signed-off-by: Wu Xiang 
> > ---
> >  target/i386/seg_helper.c | 6 --
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> The patch looks good, but I'm thinking of a cleanup on top that simplifies
> the handling of conforming code segments:
> 
> diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
> index 9af69c23e0..600a4d7586 100644
> --- a/target/i386/seg_helper.c
> +++ b/target/i386/seg_helper.c
> @@ -692,7 +692,10 @@ static void do_interrupt_protected(CPUX86State *env, int 
> intno, int is_int,
>  if (!(e2 & DESC_P_MASK)) {
>  raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
>  }
> -if (!(e2 & DESC_C_MASK) && dpl < cpl) {
> +if (e2 & DESC_C_MASK) {
> +dpl = cpl;
> +}
> +if (dpl < cpl) {
>  /* to inner privilege */
>  get_ss_esp_from_tss(env, &ss, &esp, dpl, 0);
>  if ((ss & 0xfffc) == 0) {
> @@ -719,7 +722,7 @@ static void do_interrupt_protected(CPUX86State *env, int 
> intno, int is_int,
>  new_stack = 1;
>  sp_mask = get_sp_mask(ss_e2);
>  ssp = get_seg_base(ss_e1, ss_e2);
> -} else if ((e2 & DESC_C_MASK) || dpl == cpl) {
> +} else  {
>  /* to same privilege */
>  if (vm86) {
>  raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> @@ -728,13 +731,6 @@ static void do_interrupt_protected(CPUX86State *env, int 
> intno, int is_int,
>  sp_mask = get_sp_mask(env->segs[R_SS].flags);
>  ssp = env->segs[R_SS].base;
>  esp = env->regs[R_ESP];
> -dpl = cpl;
> -} else {
> -raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> -new_stack = 0; /* avoid warning */
> -sp_mask = 0; /* avoid warning */
> -ssp = 0; /* avoid warning */
> -esp = 0; /* avoid warning */
>  }
>  
>  shift = type >> 3;
> @@ -919,25 +915,21 @@ static void do_interrupt64(CPUX86State *env, int intno, 
> int is_int,
>  if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) {
>  raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
>  }
> -if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
> +if (e2 & DESC_C_MASK) {
> +dpl = cpl;
> +}
> +if (dpl < cpl || ist != 0) {
>  /* to inner privilege */
>  new_stack = 1;
>  esp = get_rsp_from_tss(env, ist != 0 ? ist + 3 : dpl);
>  ss = 0;
> -} else if ((e2 & DESC_C_MASK) || dpl == cpl) {
> +} else {
>  /* to same privilege */
>  if (env->eflags & VM_MASK) {
>  raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
>  }
>  new_stack = 0;
>  esp = env->regs[R_ESP];
> -} else {
> -raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> -new_stack = 0; /* avoid warning */
> -esp = 0; /* avoid warning */
> -}
> -if (e2 & DESC_C_MASK) {
> -dpl = cpl;
>  }
>  esp &= ~0xfLL; /* align stack */
>  
> 
> Because dpl == cpl after the new "if", it's now unnecessary to check
> the C bit when testing dpl < cpl.  Furthermore, dpl > cpl is checked
> slightly above this code, so the final "else" is unreachable.
> 
> What do you think?
> 
> Paolo

The patch seems good and clean.

However I am not quite familiar with the code review process. Now that
you have come up with the new patch, do I have to re-send a v2?

Xiang

> 
> > diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
> > index 0374031..9af69c2 100644
> > --- a/target/i386/seg_helper.c
> > +++ b/target/i386/seg_helper.c
> > @@ -931,12 +931,14 @@ static void do_interrupt64(CPUX86State *env, int 
> > intno, int is_int,
> >  }
> >  new_stack = 0;
> >  esp = env->regs[R_ESP];
> > -dpl = cpl;
> >  } else {
> >  raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> >  new_stack = 0; /* avoid warning */
> >  esp = 0; /* avoid warning */
> >  }
> > +if (e2 & DESC_C_MASK) {
> > +dpl = cpl;
> > +}
> >  esp &= ~0xfLL; /* align stack */
> >  
> >  PUSHQ(esp, env->segs[R_SS].selector);
> > @@ -956,7 +958,7 @@ static void do_interrupt64(CPUX86State *env, int intno, 
> > int is_int,
> >  

Re: [Qemu-devel] [PATCH] target/i386: fix interrupt CPL error when

2017-06-25 Thread Paolo Bonzini


- Original Message -
> From: "Wu Xiang" 
> To: "Paolo Bonzini" , qemu-devel@nongnu.org
> Cc: "Eduardo Habkost" , "RichardHenderson" 
> 
> Sent: Sunday, June 25, 2017 1:13:24 PM
> Subject: Re: [Qemu-devel][PATCH] target/i386: fix interrupt CPL error when
> 
> In-Reply-To: <641e1f35-813a-4244-0194-ffce08130...@redhat.com>
> 
> On Fri, Jun 23, 2017 at 01:19:35PM +0200, Paolo Bonzini wrote:
> > 
> > 
> > On 21/06/2017 16:21, Wu Xiang wrote:
> > > In do_interrupt64(), when interrupt stack table(ist) is enabled
> > > and the the target code segment is conforming(e2 & DESC_C_MASK), the
> > > old implementation always set new CPL to 0, and SS.RPL to 0.
> > > 
> > > This is incorrect for when CPL3 code access a CPL0 conforming code
> > > segment, the CPL should remain unchanged. Otherwise higher privileged
> > > code can be compromised.
> > > 
> > > The patch fix this for always set dpl = cpl when the target code segment
> > > is conforming, and modify the last parameter `flags`, which contains
> > > correct new CPL, in cpu_x86_load_seg_cache().
> > > 
> > > Signed-off-by: Wu Xiang 
> > > ---
> > >  target/i386/seg_helper.c | 6 --
> > >  1 file changed, 4 insertions(+), 2 deletions(-)
> > 
> > The patch looks good, but I'm thinking of a cleanup on top that simplifies
> > the handling of conforming code segments:
> > 
> > diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
> > index 9af69c23e0..600a4d7586 100644
> > --- a/target/i386/seg_helper.c
> > +++ b/target/i386/seg_helper.c
> > @@ -692,7 +692,10 @@ static void do_interrupt_protected(CPUX86State *env,
> > int intno, int is_int,
> >  if (!(e2 & DESC_P_MASK)) {
> >  raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);
> >  }
> > -if (!(e2 & DESC_C_MASK) && dpl < cpl) {
> > +if (e2 & DESC_C_MASK) {
> > +dpl = cpl;
> > +}
> > +if (dpl < cpl) {
> >  /* to inner privilege */
> >  get_ss_esp_from_tss(env, &ss, &esp, dpl, 0);
> >  if ((ss & 0xfffc) == 0) {
> > @@ -719,7 +722,7 @@ static void do_interrupt_protected(CPUX86State *env,
> > int intno, int is_int,
> >  new_stack = 1;
> >  sp_mask = get_sp_mask(ss_e2);
> >  ssp = get_seg_base(ss_e1, ss_e2);
> > -} else if ((e2 & DESC_C_MASK) || dpl == cpl) {
> > +} else  {
> >  /* to same privilege */
> >  if (vm86) {
> >  raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> > @@ -728,13 +731,6 @@ static void do_interrupt_protected(CPUX86State *env,
> > int intno, int is_int,
> >  sp_mask = get_sp_mask(env->segs[R_SS].flags);
> >  ssp = env->segs[R_SS].base;
> >  esp = env->regs[R_ESP];
> > -dpl = cpl;
> > -} else {
> > -raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> > -new_stack = 0; /* avoid warning */
> > -sp_mask = 0; /* avoid warning */
> > -ssp = 0; /* avoid warning */
> > -esp = 0; /* avoid warning */
> >  }
> >  
> >  shift = type >> 3;
> > @@ -919,25 +915,21 @@ static void do_interrupt64(CPUX86State *env, int
> > intno, int is_int,
> >  if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) {
> >  raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> >  }
> > -if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) {
> > +if (e2 & DESC_C_MASK) {
> > +dpl = cpl;
> > +}
> > +if (dpl < cpl || ist != 0) {
> >  /* to inner privilege */
> >  new_stack = 1;
> >  esp = get_rsp_from_tss(env, ist != 0 ? ist + 3 : dpl);
> >  ss = 0;
> > -} else if ((e2 & DESC_C_MASK) || dpl == cpl) {
> > +} else {
> >  /* to same privilege */
> >  if (env->eflags & VM_MASK) {
> >  raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> >  }
> >  new_stack = 0;
> >  esp = env->regs[R_ESP];
> > -} else {
> > -raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc);
> > -new_stack = 0; /* avoid warning */
> > -esp = 0; /* avoid warning */
> > -}
> > -if (e2 & DESC_C_MASK) {
> > -dpl = cpl;
> >  }
> >  esp &= ~0xfLL; /* align stack */
> >  
> > 
> > Because dpl == cpl after the new "if", it's now unnecessary to check
> > the C bit when testing dpl < cpl.  Furthermore, dpl > cpl is checked
> > slightly above this code, so the final "else" is unreachable.
> > 
> > What do you think?
> > 
> > Paolo
> 
> The patch seems good and clean.
> 
> However I am not quite familiar with the code review process. Now that
> you have come up with the new patch, do I have to re-send a v2?

No, your patch is okay.  Mine comes after yours, I'll send it out
tomorrow.

Paolo



Re: [Qemu-devel] Tracing guest virtual addresses

2017-06-25 Thread Lluís Vilanova
Lluís Vilanova writes:

> Jayanto Minocha writes:
>> Lluis,
>> My modifications were almost the same as those done by Emilio. There were
>> no memory trace events in the trace file.

> I'll take a look at it after I finish revamping the generic translation loop
> series (hopefully today).

I just sent a patch that should fix it:

  https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg05491.html


Cheers,
  Lluis



>> -J

>> On Tue, Jun 20, 2017 at 10:20 AM, Emilio G. Cota  wrote:

>>> On Tue, Jun 20, 2017 at 14:02:02 +0300, Lluís Vilanova wrote:
>>> > Jayanto Minocha writes:
>>> >
>>> > > Hi,
>>> > > I think there have been a few threads on the mailing list regarding
>>> tracing
>>> > > guest virtual addresses for load and store instructions, but I have
>>> been
>>> > > unable to get it to work. I am trying this for an AArch64 machine, and
>>> am
>>> > > using the softmmu.
>>> >
>>> > > The tracing infrastructure provides the following event:
>>> >
>>> > > vcpu tcg guest_mem_before(...).
>>> >
>>> > > But that is only used to instrument the cpu_ld/cpu_st macros, which is
>>> only
>>> > > called in the case of a tlb miss.
>>> >
>>> > > I've been going over the archives, and it looks like I need to
>>> instrument
>>> > > tcg_out_tlb_load. Am I on the right path ?
>>> >
>>> > That event should trace all guest memory accesses performed by the CPU.
>>> If you
>>> > found any case where this does not hold, it is likely a bug and I'd
>>> appreciate
>>> > it if you can point me to the smallest possible failing example.
>>> 
>>> I'm having trouble with this as well, although I'm pretty sure I must be
>>> doing
>>> something wrong (never used the tracing infrastructure before). Here's what
>>> I'm doing:
>>> 
>>> $ git show --pretty=short
>>> commit e85c0d14014514a2f0faeae5b4c23fab5b234de4
>>> Merge: 65a0e3e 7f3cf2d
>>> Author: Peter Maydell 
>>> 
>>> Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into
>>> staging
>>> 
>>> 
>>> $ git diff
>>> diff --git a/accel/tcg/trace-events b/accel/tcg/trace-events
>>> index 2de8359..385a462 100644
>>> --- a/accel/tcg/trace-events
>>> +++ b/accel/tcg/trace-events
>>> @@ -2,7 +2,7 @@
>>> 
>>> # TCG related tracing (mostly disabled by default)
>>> # cpu-exec.c
>>> -disable exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
>>> +exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
>>> disable exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
>>> disable exec_tb_exit(void *last_tb, unsigned int flags) "tb:%p flags=%x"
>>> 
>>> diff --git a/trace-events b/trace-events
>>> index bae63fd..7df49a3 100644
>>> --- a/trace-events
>>> +++ b/trace-events
>>> @@ -106,7 +106,7 @@ vcpu guest_cpu_reset(void)
>>> #
>>> # Mode: user, softmmu
>>> # Targets: TCG(all)
>>> -disable vcpu tcg guest_mem_before(TCGv vaddr, uint8_t info) "info=%d",
>>> "vaddr=0x%016"PRIx64" info=%d"
>>> +vcpu tcg guest_mem_before(TCGv vaddr, uint8_t info) "info=%d",
>>> "vaddr=0x%016"PRIx64" info=%d"
>>> 
>>> # @num: System call number.
>>> # @arg*: System call argument value.
>>> 
>>> $ mkdir build
>>> $ cd build
>>> $ ../configure --target-list=arm-softmmu,x86_64-linux-user
>>> --enable-trace-backends=simple && make -j 12
>>> [...]
>>> 
>>> $ cat ../ev
>>> guest_mem_before_exec
>>> guest_mem_before_trans
>>> exec_tb
>>> 
>>> $ x86_64-linux-user/qemu-x86_64 -trace events=../ev /bin/date
>>> Tue Jun 20 13:11:49 EDT 2017
>>> 
>>> $ ls -lt | head | grep trace
>>> -rw-rw-r--  1 cota cota   169721 Jun 20 13:11 trace-2150
>>> 
>>> $ scripts/simpletrace.py trace-events-all trace-2150
>>> exec_tb 0.000 pid=2150 tb=0x7f5896667010 pc=0x4000801cc0
>>> exec_tb 21.648 pid=2150 tb=0x7f5896667088 pc=0x4000805c00
>>> [...]
>>> 
>>> 100% of the file is exec_tb lines, i.e. no memory references whatsoever.
>>> 
>>> Similar results with arm-softmmu.
>>> 
>>> Thanks,
>>> 
>>> Emilio
>>> 
>>> 




Re: [Qemu-devel] Tracing guest virtual addresses

2017-06-25 Thread Lluís Vilanova
Alex Bennée writes:

> Peter Maydell  writes:

>> On 20 June 2017 at 12:02, Lluís Vilanova  wrote:
>>> Jayanto Minocha writes:
 But that is only used to instrument the cpu_ld/cpu_st macros, which is only
 called in the case of a tlb miss.
>>> 
 I've been going over the archives, and it looks like I need to instrument
 tcg_out_tlb_load. Am I on the right path ?
>>> 
>>> That event should trace all guest memory accesses performed by the CPU. If 
>>> you
>>> found any case where this does not hold, it is likely a bug and I'd 
>>> appreciate
>>> it if you can point me to the smallest possible failing example.
>> 
>> Does it catch memory accesses that are performed via helper functions,
>> or only ones done by inline TCG code?

> AFAICT it inserts a helper call on the TCG ld/st ops. I wonder why not
> just ensure we always take the slow path and put the helpers in the
> access functions there? You could even apply an address mask if you only
> want to look at certain address ranges.

It also catches accesses performed by helpers.


Cheers,
  Lluis



[Qemu-devel] [Bug 1700380] [NEW] commit snapshot image got Permission denied error

2017-06-25 Thread jiangyd
Public bug reported:

qemu 2.9.0, adm64, start image with -snapshot param, make some changes
in the image, then:

$telnet localhost 7000

(qemu) commit virtio0
'commit' error for 'virtio0': Permission denied

Nerver met this problem before, commit is ok. I recently compiled
v2.9.0, so is there some new param in qemu-qemu-system-x86_64 to avoid
commit Permission denied?

Regards.

** 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/1700380

Title:
  commit snapshot image got Permission denied error

Status in QEMU:
  New

Bug description:
  qemu 2.9.0, adm64, start image with -snapshot param, make some changes
  in the image, then:

  $telnet localhost 7000

  (qemu) commit virtio0
  'commit' error for 'virtio0': Permission denied

  Nerver met this problem before, commit is ok. I recently compiled
  v2.9.0, so is there some new param in qemu-qemu-system-x86_64 to avoid
  commit Permission denied?

  Regards.

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



[Qemu-devel] [PATCH RFC] Generic PCIE-to-PCI Bridge

2017-06-25 Thread Aleksandr Bezzubikov
This patch introduces a new device - generic PCI Express to PCI bridge.

Now only x86-specific DMI-to-PCI bridge can be used to enable 
usage of legacy PCI devices on Q35 machine. But this bridge isn't 
cross-platform 
and doesn't support hotplugging.
That's why we need a new generic cross-platform bridge device, which supports 
hotplugging.

This patch creates device only for static CLI usage, 
the next goal is to add ACPI hotplug support.  It will utilize 
in some way past Marcel's RFC series for Q35 ACPI PCI hotplug support 
https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg05681.html, 
but will require dynamic ACPI code emission in case when the bridge was 
hotplugged itself.

Aleksandr Bezzubikov (1):
  hw/pci-bridge: implement pcie-pci-bridge device

 hw/pci-bridge/Makefile.objs |   2 +-
 hw/pci-bridge/pcie_pci_bridge.c | 152 
 include/hw/pci/pci.h|   1 +
 3 files changed, 154 insertions(+), 1 deletion(-)
 create mode 100644 hw/pci-bridge/pcie_pci_bridge.c

-- 
2.7.4




[Qemu-devel] [PATCH RFC] hw/pci-bridge: implement pcie-pci-bridge device

2017-06-25 Thread Aleksandr Bezzubikov
Signed-off-by: Aleksandr Bezzubikov 
---
 hw/pci-bridge/Makefile.objs |   2 +-
 hw/pci-bridge/pcie_pci_bridge.c | 152 
 include/hw/pci/pci.h|   1 +
 3 files changed, 154 insertions(+), 1 deletion(-)
 create mode 100644 hw/pci-bridge/pcie_pci_bridge.c

diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs
index c4683cf..666db37 100644
--- a/hw/pci-bridge/Makefile.objs
+++ b/hw/pci-bridge/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y += pci_bridge_dev.o
+common-obj-y += pci_bridge_dev.o pcie_pci_bridge.o
 common-obj-$(CONFIG_PCIE_PORT) += pcie_root_port.o gen_pcie_root_port.o
 common-obj-$(CONFIG_PXB) += pci_expander_bridge.o
 common-obj-$(CONFIG_XIO3130) += xio3130_upstream.o xio3130_downstream.o
diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c
new file mode 100644
index 000..06b19d6
--- /dev/null
+++ b/hw/pci-bridge/pcie_pci_bridge.c
@@ -0,0 +1,152 @@
+/*
+ * QEMU Generic PCIE-PCI Bridge
+ *
+ * Copyright (c) 2017 Aleksandr Bezzubikov
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_bridge.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/slotid_cap.h"
+
+typedef struct PCIEPCIBridge {
+/*< private >*/
+PCIBridge parent_obj;
+
+#define PCI_BRIDGE_DEV_F_SHPC_REQ 0
+uint32_t flags;
+/*< public >*/
+} PCIEPCIBridge;
+
+#define TYPE_PCIE_PCI_BRIDGE_DEV  "pcie-pci-bridge"
+#define PCIE_PCI_BRIDGE_DEV(obj) \
+OBJECT_CHECK(PCIEPCIBridge, (obj), TYPE_PCIE_PCI_BRIDGE_DEV)
+
+static void pciepci_bridge_realize(PCIDevice *d, Error **errp)
+{
+int rc, pos;
+Error *local_err = NULL;
+
+pci_bridge_initfn(d, TYPE_PCI_BUS);
+
+rc = pci_bridge_ssvid_init(d, 0, 0, 0x32);
+if (rc < 0) {
+error_setg(errp, "Can't add SSVID, error %d", rc);
+goto error;
+}
+
+rc = pcie_cap_init(d, 0, PCI_EXP_TYPE_PCI_BRIDGE, 0);
+if (rc < 0) {
+error_setg(errp, "Can't add PCIE-PCI bridge capability, error %d", rc);
+goto error;
+}
+
+pos = pci_add_capability(d, PCI_CAP_ID_PM, 0, PCI_PM_SIZEOF);
+assert(pos > 0);
+d->exp.pm_cap = pos;
+pci_set_word(d->config + pos + PCI_PM_PMC, 0x3);
+
+pcie_cap_arifwd_init(d);
+pcie_cap_deverr_init(d);
+
+rc = pcie_aer_init(d, PCI_ERR_VER, 0x100, PCI_ERR_SIZEOF, &local_err);
+if (rc < 0) {
+error_propagate(errp, local_err);
+goto error;
+}
+
+rc = msi_init(d, 0, 1, 1, 1, &local_err);
+if (rc < 0) {
+error_propagate(errp, local_err);
+}
+
+return;
+
+error:
+pci_bridge_exitfn(d);
+}
+
+static void pciepci_bridge_exit(PCIDevice *d)
+{
+pcie_cap_exit(d);
+pci_bridge_exitfn(d);
+}
+
+static void pciepci_bridge_reset(DeviceState *qdev)
+{
+pci_bridge_reset(qdev);
+}
+
+static void pcie_pci_bridge_write_config(PCIDevice *d,
+uint32_t address, uint32_t val, int len)
+{
+pci_bridge_write_config(d, address, val, len);
+msi_write_config(d, address, val, len);
+}
+
+
+static Property pcie_pci_bridge_dev_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription pciepci_bridge_dev_vmstate = {
+.name = TYPE_PCIE_PCI_BRIDGE_DEV,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(parent_obj, PCIBridge),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void pciepci_bridge_class_init(ObjectClass *klass, void *data)
+{
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+k->is_express = 1;
+k->is_bridge = 1;
+k->vendor_id = PCI_VENDOR_ID_REDHAT;
+k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE;
+k->realize = pciepci_bridge_realize;
+k->exit = pciepci_bridge_exit;
+k->config_write = pcie_pci_bridge_write_config;
+dc->vmsd = &p

Re: [Qemu-devel] Tracing guest virtual addresses

2017-06-25 Thread Alex Bennée

Lluís Vilanova  writes:

> Alex Bennée writes:
>
>> Peter Maydell  writes:
>
>>> On 20 June 2017 at 12:02, Lluís Vilanova  wrote:
 Jayanto Minocha writes:
> But that is only used to instrument the cpu_ld/cpu_st macros, which is 
> only
> called in the case of a tlb miss.

> I've been going over the archives, and it looks like I need to instrument
> tcg_out_tlb_load. Am I on the right path ?

 That event should trace all guest memory accesses performed by the CPU. If 
 you
 found any case where this does not hold, it is likely a bug and I'd 
 appreciate
 it if you can point me to the smallest possible failing example.
>>>
>>> Does it catch memory accesses that are performed via helper functions,
>>> or only ones done by inline TCG code?
>
>> AFAICT it inserts a helper call on the TCG ld/st ops. I wonder why not
>> just ensure we always take the slow path and put the helpers in the
>> access functions there? You could even apply an address mask if you only
>> want to look at certain address ranges.
>
> It also catches accesses performed by helpers.

Don't helper accesses also pass through the SoftMMU? Or are we talking
about user-space access as well here?

>
>
> Cheers,
>   Lluis


--
Alex Bennée



Re: [Qemu-devel] [PATCHv6 3/5] fw_cfg: move assert() and linking of fw_cfg device to the machine into instance_init()

2017-06-25 Thread Mark Cave-Ayland
On 23/06/17 19:50, Eduardo Habkost wrote:

>> Really, please go back to the earlier discussion around fw_cfg_init1()
>> and you'll see my original point (which matches what you just voiced).
> 
> Yep.  I was just not sure validation on realize was necessary or
> convenient.  It looks like we agree it is just convenient.
> 
> 
>>
>>> All that said, I don't have a strong argument against doing it on
>>> realize, except my gut feeling that this is not how qdev was
>>> designed[1].  If doing it on realize is the simplest way to do it, I
>>> won't be the one complaining.
>>>
>>> [1] I believe the original intent was to make every single device
>>> user-creatable and define boards in a declarative way in config
>>> files.  We are very far from that goal.
>>
>> I'm fine either way, I just wanted to accommodate Mark's preference,
>> because he seemed to strongly dislike having to call any helper
>> functions from board code, beyond initing and realizing the device.
>>
>> This is my recollection of the earlier discussion anyway.
> 
> I think we are in agreement, then.  If there are no objections from
> others against doing object_property_add_child() on realize, I'm also OK
> with that.

Just to clarify here that my objection wasn't so much about calling
helper functions from board code, it was that as the current patch
exposes the MemoryRegions in TYPE_FW_CFG_IO and TYPE_FW_CFG_MEM then as
per my example where the machine link is omitted then the check becomes
useless.

I can see that device_set_realized() will always set the device parent
to /machine/unattached before calling the realize function if the device
doesn't have a parent. So is it even possible to add the device via
object_property_add_child() to the machine during realize? Or could it
be done by making /machine/fw_cfg an alias to its real location in the
QOM tree at realize time without breaking the object_resolve_path_type()
check?

The other interesting option to explore is that since fw_cfg already has
a machine_ready notifier, the check could be moved there similar to as
done in hw/core/machine.c's error_on_sysbus_device() if the check
shouldn't be present in realize. That still doesn't answer the question
as to how to enforce that the device is correctly linked to the machine
though.


ATB,

Mark.




[Qemu-devel] [PATCH 1/7] target/m68k: add fscc.

2017-06-25 Thread Laurent Vivier
use DisasCompare with FPU conditions in fscc and fbcc.

Signed-off-by: Laurent Vivier 
---
 target/m68k/translate.c | 213 ++--
 1 file changed, 134 insertions(+), 79 deletions(-)

diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 7aa0fdc..099cb69 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4633,142 +4633,196 @@ undef:
 disas_undef_fpu(env, s, insn);
 }
 
-DISAS_INSN(fbcc)
+static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond)
 {
-uint32_t offset;
-uint32_t addr;
-TCGLabel *l1;
-TCGv tmp, fpsr;
-
-addr = s->pc;
-offset = cpu_ldsw_code(env, s->pc);
-s->pc += 2;
-if (insn & (1 << 6)) {
-offset = (offset << 16) | read_im16(env, s);
-}
+TCGv fpsr;
 
+c->g1 = 0;
+c->v2 = tcg_const_i32(0);
+c->g2 = 1;
+/* TODO: Raise BSUN exception.  */
 fpsr = tcg_temp_new();
 gen_load_fcr(s, fpsr, M68K_FPSR);
-l1 = gen_new_label();
-/* TODO: Raise BSUN exception.  */
-/* Jump to l1 if condition is true.  */
-switch (insn & 0x3f)  {
+switch (cond) {
 case 0:  /* False */
 case 16: /* Signaling False */
+c->v1 = c->v2;
+c->tcond = TCG_COND_NEVER;
 break;
 case 1:  /* EQual Z */
 case 17: /* Signaling EQual Z */
-tmp = tcg_temp_new();
-tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_Z);
-tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+c->v1 = tcg_temp_new();
+c->g1 = 1;
+tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_Z);
+c->tcond = TCG_COND_NE;
 break;
 case 2:  /* Ordered Greater Than !(A || Z || N) */
 case 18: /* Greater Than !(A || Z || N) */
-tmp = tcg_temp_new();
-tcg_gen_andi_i32(tmp, fpsr,
+c->v1 = tcg_temp_new();
+c->g1 = 1;
+tcg_gen_andi_i32(c->v1, fpsr,
  FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N);
-tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+c->tcond = TCG_COND_EQ;
 break;
 case 3:  /* Ordered Greater than or Equal Z || !(A || N) */
 case 19: /* Greater than or Equal Z || !(A || N) */
-assert(FPSR_CC_A == (FPSR_CC_N >> 3));
-tmp = tcg_temp_new();
-tcg_gen_shli_i32(tmp, fpsr, 3);
-tcg_gen_or_i32(tmp, tmp, fpsr);
-tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N);
-tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_Z);
-tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+g_assert(FPSR_CC_A == (FPSR_CC_N >> 3));
+c->v1 = tcg_temp_new();
+c->g1 = 1;
+tcg_gen_shli_i32(c->v1, fpsr, 3);
+tcg_gen_or_i32(c->v1, c->v1, fpsr);
+tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N);
+tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_Z);
+c->tcond = TCG_COND_NE;
 break;
 case 4:  /* Ordered Less Than !(!N || A || Z); */
 case 20: /* Less Than !(!N || A || Z); */
-tmp = tcg_temp_new();
-tcg_gen_xori_i32(tmp, fpsr, FPSR_CC_N);
-tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
-tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+c->v1 = tcg_temp_new();
+c->g1 = 1;
+tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_N);
+tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z);
+c->tcond = TCG_COND_EQ;
 break;
 case 5:  /* Ordered Less than or Equal Z || (N && !A) */
 case 21: /* Less than or Equal Z || (N && !A) */
-assert(FPSR_CC_A == (FPSR_CC_N >> 3));
-tmp = tcg_temp_new();
-tcg_gen_xori_i32(tmp, fpsr, FPSR_CC_A);
-tcg_gen_shli_i32(tmp, tmp, 3);
-tcg_gen_ori_i32(tmp, tmp, FPSR_CC_Z);
-tcg_gen_and_i32(tmp, tmp, fpsr);
-tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+g_assert(FPSR_CC_A == (FPSR_CC_N >> 3));
+c->v1 = tcg_temp_new();
+c->g1 = 1;
+tcg_gen_xori_i32(c->v1, fpsr, FPSR_CC_A);
+tcg_gen_shli_i32(c->v1, c->v1, 3);
+tcg_gen_ori_i32(c->v1, c->v1, FPSR_CC_Z);
+tcg_gen_and_i32(c->v1, c->v1, fpsr);
+c->tcond = TCG_COND_NE;
 break;
 case 6:  /* Ordered Greater or Less than !(A || Z) */
 case 22: /* Greater or Less than !(A || Z) */
-tmp = tcg_temp_new();
-tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A | FPSR_CC_Z);
-tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+c->v1 = tcg_temp_new();
+c->g1 = 1;
+tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A | FPSR_CC_Z);
+c->tcond = TCG_COND_EQ;
 break;
 case 7:  /* Ordered !A */
 case 23: /* Greater, Less or Equal !A */
-tmp = tcg_temp_new();
-tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_A);
-tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
+c->v1 = tcg_temp_new();
+c->g1 = 1;
+tcg_gen_andi_i32(c->v1, fpsr, FPSR_CC_A);
+c->tcond = TCG_COND_EQ;
 break;
 case 8:  /* Unordered A */

[Qemu-devel] [PATCH 0/7] target/m68k: implement 680x0 FPU (part 2)

2017-06-25 Thread Laurent Vivier
Second part of patches submitted in the v3.

This series adds a subset of single precision and
double precision instructions using
set_floatx80_rounding_precision() to round the result.

For some other instructions, we introduce a new
function, floatx80_round(), to round them manually.

It also adds instructions fsglmul, fsgldiv,
fmovecr and fscc (since v3, use tcg_gen_setcond())

fmovem manages static and dynamic register list,
all the code has been moved to an helper.

Laurent Vivier (7):
  target/m68k: add fscc.
  target/m68k: add fmovecr
  target/m68k: add fsglmul and fsgldiv
  target/m68k: add explicit single and double precision operations
  softfloat: define floatx80_round()
  target/m68k: add explicit single and double precision operations (part
2)
  target/m68k: add fmovem

 fpu/softfloat.c  |  15 ++
 include/fpu/softfloat.h  |   1 +
 target/m68k/fpu_helper.c | 283 -
 target/m68k/helper.h |  22 ++-
 target/m68k/translate.c  | 357 +++
 5 files changed, 555 insertions(+), 123 deletions(-)

-- 
2.9.4




[Qemu-devel] [PATCH 2/7] target/m68k: add fmovecr

2017-06-25 Thread Laurent Vivier
fmovecr moves a floating point constant from the
FPU ROM to a floating point register.

Signed-off-by: Laurent Vivier 
---
 target/m68k/fpu_helper.c | 30 ++
 target/m68k/helper.h |  1 +
 target/m68k/translate.c  | 13 -
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index a9e17f5..912c0b7 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -23,6 +23,31 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 
+static const floatx80 fpu_rom[128] = {
+[0x00] = floatx80_pi,   /* Pi */
+[0x0b] = make_floatx80(0x3ffd, 0x9a209a84fbcff798ULL),  /* Log10(2) */
+[0x0c] = make_floatx80(0x4000, 0xadf85458a2bb4a9aULL),  /* e*/
+[0x0d] = make_floatx80(0x3fff, 0xb8aa3b295c17f0bcULL),  /* Log2(e)  */
+[0x0e] = make_floatx80(0x3ffd, 0xde5bd8a937287195ULL),  /* Log10(e) */
+[0x0f] = floatx80_zero, /* Zero */
+[0x30] = floatx80_ln2,  /* ln(2)*/
+[0x31] = make_floatx80(0x4000, 0x935d8dddaaa8ac17ULL),  /* ln(10)   */
+[0x32] = floatx80_one,  /* 10^0 */
+[0x33] = make_floatx80(0x4002, 0xa000ULL),  /* 10^1 */
+[0x34] = make_floatx80(0x4005, 0xc800ULL),  /* 10^2 */
+[0x35] = make_floatx80(0x400c, 0x9c40ULL),  /* 10^4 */
+[0x36] = make_floatx80(0x4019, 0xbebc2000ULL),  /* 10^8 */
+[0x37] = make_floatx80(0x4034, 0x8e1bc9bf0400ULL),  /* 10^16*/
+[0x38] = make_floatx80(0x4069, 0x9dc5ada82b70b59eULL),  /* 10^32*/
+[0x39] = make_floatx80(0x40d3, 0xc2781f49ffcfa6d5ULL),  /* 10^64*/
+[0x3a] = make_floatx80(0x41a8, 0x93ba47c980e98ce0ULL),  /* 10^128   */
+[0x3b] = make_floatx80(0x4351, 0xaa7eebfb9df9de8eULL),  /* 10^256   */
+[0x3c] = make_floatx80(0x46a3, 0xe319a0aea60e91c7ULL),  /* 10^512   */
+[0x3d] = make_floatx80(0x4d48, 0xc976758681750c17ULL),  /* 10^1024  */
+[0x3e] = make_floatx80(0x5a92, 0x9e8b3b5dc53d5de5ULL),  /* 10^2048  */
+[0x3f] = make_floatx80(0x7525, 0xc46052028a20979bULL),  /* 10^4096  */
+};
+
 int32_t HELPER(reds32)(CPUM68KState *env, FPReg *val)
 {
 return floatx80_to_int32(val->d, &env->fp_status);
@@ -204,3 +229,8 @@ void HELPER(ftst)(CPUM68KState *env, FPReg *val)
 }
 env->fpsr = (env->fpsr & ~FPSR_CC_MASK) | cc;
 }
+
+void HELPER(fconst)(CPUM68KState *env, FPReg *val, uint32_t offset)
+{
+val->d = fpu_rom[offset];
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 98cbf18..d6e80e4 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -35,6 +35,7 @@ DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
 DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
 DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
 DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
+DEF_HELPER_3(fconst, void, env, fp, i32)
 
 DEF_HELPER_3(mac_move, void, env, i32, i32)
 DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 099cb69..a54da87 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4510,6 +4510,7 @@ static void gen_op_fmove_fcr(CPUM68KState *env, 
DisasContext *s,
 DISAS_INSN(fpu)
 {
 uint16_t ext;
+uint8_t rom_offset;
 int opmode;
 TCGv tmp32;
 int opsize;
@@ -4518,10 +4519,20 @@ DISAS_INSN(fpu)
 ext = read_im16(env, s);
 opmode = ext & 0x7f;
 switch ((ext >> 13) & 7) {
-case 0: case 2:
+case 0:
 break;
 case 1:
 goto undef;
+case 2:
+if (insn == 0xf200 && (ext & 0xfc00) == 0x5c00) {
+/* fmovecr */
+rom_offset = ext & 0x7f;
+cpu_dest = gen_fp_ptr(REG(ext, 7));
+gen_helper_fconst(cpu_env, cpu_dest, tcg_const_i32(rom_offset));
+tcg_temp_free_ptr(cpu_dest);
+return;
+}
+break;
 case 3: /* fmove out */
 cpu_src = gen_fp_ptr(REG(ext, 7));
 opsize = ext_opsize(ext, 10);
-- 
2.9.4




[Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv

2017-06-25 Thread Laurent Vivier
fsglmul and fsgldiv truncate data to single precision before computing
results.

Signed-off-by: Laurent Vivier 
---
 target/m68k/fpu_helper.c | 22 ++
 target/m68k/helper.h |  2 ++
 target/m68k/translate.c  |  6 ++
 3 files changed, 30 insertions(+)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 912c0b7..0d83925 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -183,11 +183,33 @@ void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg 
*val0, FPReg *val1)
 res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
 }
 
+void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+float32 a, b, c;
+
+a = floatx80_to_float32(val0->d, &env->fp_status);
+b = floatx80_to_float32(val1->d, &env->fp_status);
+c = float32_mul(a, b, &env->fp_status);
+
+res->d = float32_to_floatx80(c, &env->fp_status);
+}
+
 void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
 res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
 }
 
+void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+float32 a, b, c;
+
+a = floatx80_to_float32(val1->d, &env->fp_status);
+b = floatx80_to_float32(val0->d, &env->fp_status);
+c = float32_div(a, b, &env->fp_status);
+
+res->d = float32_to_floatx80(c, &env->fp_status);
+}
+
 static int float_comp_to_cc(int float_compare)
 {
 switch (float_compare) {
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index d6e80e4..5a006de 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -31,7 +31,9 @@ DEF_HELPER_3(fchs, void, env, fp, fp)
 DEF_HELPER_4(fadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fsub, void, env, fp, fp, fp)
 DEF_HELPER_4(fmul, void, env, fp, fp, fp)
+DEF_HELPER_4(fsglmul, void, env, fp, fp, fp)
 DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
+DEF_HELPER_4(fsgldiv, void, env, fp, fp, fp)
 DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
 DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
 DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index a54da87..a50bf5f 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4622,6 +4622,12 @@ DISAS_INSN(fpu)
 case 0x23: case 0x63: case 0x67: /* fmul */
 gen_helper_fmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
 break;
+case 0x24: /* fsgldiv */
+gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
+break;
+case 0x27: /* fsglmul */
+gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
+break;
 case 0x28: case 0x68: case 0x6c: /* fsub */
 gen_helper_fsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
 break;
-- 
2.9.4




[Qemu-devel] [PATCH 6/7] target/m68k: add explicit single and double precision operations (part 2)

2017-06-25 Thread Laurent Vivier
Add fsabs, fdabs, fsneg, fdneg, fsmove and fdmove.

The value is converted using the new floatx80_round() function.

Signed-off-by: Laurent Vivier 
---
 target/m68k/fpu_helper.c | 48 +---
 target/m68k/helper.h |  8 +++-
 target/m68k/translate.c  | 26 ++
 3 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 3518863..38370d0 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -163,6 +163,20 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
 set_floatx80_rounding_precision(old, &env->fp_status);  \
 } while (0)
 
+void HELPER(fsround)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+PREC_BEGIN(32);
+res->d = floatx80_round(val->d, &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fdround)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+PREC_BEGIN(64);
+res->d = floatx80_round(val->d, &env->fp_status);
+PREC_END();
+}
+
 void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
 res->d = floatx80_sqrt(val->d, &env->fp_status);
@@ -184,12 +198,40 @@ void HELPER(fdsqrt)(CPUM68KState *env, FPReg *res, FPReg 
*val)
 
 void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
-res->d = floatx80_abs(val->d);
+res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status);
+}
+
+void HELPER(fsabs)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+PREC_BEGIN(32);
+res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fdabs)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+PREC_BEGIN(64);
+res->d = floatx80_round(floatx80_abs(val->d), &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fneg)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status);
 }
 
-void HELPER(fchs)(CPUM68KState *env, FPReg *res, FPReg *val)
+void HELPER(fsneg)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
-res->d = floatx80_chs(val->d);
+PREC_BEGIN(32);
+res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fdneg)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+PREC_BEGIN(64);
+res->d = floatx80_round(floatx80_chs(val->d), &env->fp_status);
+PREC_END();
 }
 
 void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index f05191b..b396899 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -23,13 +23,19 @@ DEF_HELPER_2(redf32, f32, env, fp)
 DEF_HELPER_2(redf64, f64, env, fp)
 DEF_HELPER_2(reds32, s32, env, fp)
 
+DEF_HELPER_3(fsround, void, env, fp, fp)
+DEF_HELPER_3(fdround, void, env, fp, fp)
 DEF_HELPER_3(firound, void, env, fp, fp)
 DEF_HELPER_3(fitrunc, void, env, fp, fp)
 DEF_HELPER_3(fsqrt, void, env, fp, fp)
 DEF_HELPER_3(fssqrt, void, env, fp, fp)
 DEF_HELPER_3(fdsqrt, void, env, fp, fp)
 DEF_HELPER_3(fabs, void, env, fp, fp)
-DEF_HELPER_3(fchs, void, env, fp, fp)
+DEF_HELPER_3(fsabs, void, env, fp, fp)
+DEF_HELPER_3(fdabs, void, env, fp, fp)
+DEF_HELPER_3(fneg, void, env, fp, fp)
+DEF_HELPER_3(fsneg, void, env, fp, fp)
+DEF_HELPER_3(fdneg, void, env, fp, fp)
 DEF_HELPER_4(fadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fsadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fdadd, void, env, fp, fp, fp)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 22d499f..3a1bdc1 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4595,9 +4595,15 @@ DISAS_INSN(fpu)
 }
 cpu_dest = gen_fp_ptr(REG(ext, 7));
 switch (opmode) {
-case 0: case 0x40: case 0x44: /* fmove */
+case 0: /* fmove */
 gen_fp_move(cpu_dest, cpu_src);
 break;
+case 0x40: /* fsmove */
+gen_helper_fsround(cpu_env, cpu_dest, cpu_src);
+break;
+case 0x44: /* fdmove */
+gen_helper_fdround(cpu_env, cpu_dest, cpu_src);
+break;
 case 1: /* fint */
 gen_helper_firound(cpu_env, cpu_dest, cpu_src);
 break;
@@ -4613,11 +4619,23 @@ DISAS_INSN(fpu)
 case 0x45: /* fdsqrt */
 gen_helper_fdsqrt(cpu_env, cpu_dest, cpu_src);
 break;
-case 0x18: case 0x58: case 0x5c: /* fabs */
+case 0x18: /* fabs */
 gen_helper_fabs(cpu_env, cpu_dest, cpu_src);
 break;
-case 0x1a: case 0x5a: case 0x5e: /* fneg */
-gen_helper_fchs(cpu_env, cpu_dest, cpu_src);
+case 0x58: /* fsabs */
+gen_helper_fsabs(cpu_env, cpu_dest, cpu_src);
+break;
+case 0x5c: /* fdabs */
+gen_helper_fdabs(cpu_env, cpu_dest, cpu_src);
+break;
+case 0x1a: /* fneg */
+gen_helper_fneg(cpu_env, cpu_dest, cpu_src);
+break;
+case 0x5a: /* fsneg */
+gen_helper_fsneg(cpu_env, cpu_dest, cpu_src);
+break;
+case 0x5e: /* fdneg */
+gen_helper_fdneg(cpu_env, cpu_dest, cpu_src);
 break;
 case 0x20

[Qemu-devel] [PATCH 5/7] softfloat: define floatx80_round()

2017-06-25 Thread Laurent Vivier
Add a function to round a floatx80 to the defined precision
(floatx80_rounding_precision)

Signed-off-by: Laurent Vivier 
---
 fpu/softfloat.c | 15 +++
 include/fpu/softfloat.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7af14e2..e9bf359 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5086,6 +5086,21 @@ float128 floatx80_to_float128(floatx80 a, float_status 
*status)
 }
 
 /*
+| Rounds the extended double-precision floating-point value `a'
+| and returns the result as an extended double-precision floating-point
+| value.  The operation is performed according to the IEC/IEEE Standard for
+| Binary Floating-Point Arithmetic.
+**/
+
+floatx80 floatx80_round(floatx80 a, float_status *status)
+{
+return roundAndPackFloatx80(status->floatx80_rounding_precision,
+extractFloatx80Sign(a),
+extractFloatx80Exp(a),
+extractFloatx80Frac(a), 0, status);
+}
+
+/*
 | Rounds the extended double-precision floating-point value `a' to an integer,
 | and returns the result as an extended quadruple-precision floating-point
 | value.  The operation is performed according to the IEC/IEEE Standard for
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index f1288ef..d9689ec 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -621,6 +621,7 @@ float128 floatx80_to_float128(floatx80, float_status 
*status);
 /*
 | Software IEC/IEEE extended double-precision operations.
 **/
+floatx80 floatx80_round(floatx80 a, float_status *status);
 floatx80 floatx80_round_to_int(floatx80, float_status *status);
 floatx80 floatx80_add(floatx80, floatx80, float_status *status);
 floatx80 floatx80_sub(floatx80, floatx80, float_status *status);
-- 
2.9.4




[Qemu-devel] [PATCH 4/7] target/m68k: add explicit single and double precision operations

2017-06-25 Thread Laurent Vivier
Add fssqrt, fdsqrt, fsadd, fdadd, fssub, fdsub, fsmul, fdmul,
fsdiv, fddiv.

The precision is managed using set_floatx80_rounding_precision().

Signed-off-by: Laurent Vivier 
---
 target/m68k/fpu_helper.c | 80 
 target/m68k/helper.h | 10 ++
 target/m68k/translate.c  | 40 +---
 3 files changed, 125 insertions(+), 5 deletions(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 0d83925..3518863 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -153,11 +153,35 @@ void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
 cpu_m68k_set_fpcr(env, val);
 }
 
+#define PREC_BEGIN(prec)\
+do {\
+int old;\
+old = get_floatx80_rounding_precision(&env->fp_status); \
+set_floatx80_rounding_precision(prec, &env->fp_status)  \
+
+#define PREC_END()  \
+set_floatx80_rounding_precision(old, &env->fp_status);  \
+} while (0)
+
 void HELPER(fsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
 res->d = floatx80_sqrt(val->d, &env->fp_status);
 }
 
+void HELPER(fssqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+PREC_BEGIN(32);
+res->d = floatx80_sqrt(val->d, &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fdsqrt)(CPUM68KState *env, FPReg *res, FPReg *val)
+{
+PREC_BEGIN(64);
+res->d = floatx80_sqrt(val->d, &env->fp_status);
+PREC_END();
+}
+
 void HELPER(fabs)(CPUM68KState *env, FPReg *res, FPReg *val)
 {
 res->d = floatx80_abs(val->d);
@@ -173,16 +197,58 @@ void HELPER(fadd)(CPUM68KState *env, FPReg *res, FPReg 
*val0, FPReg *val1)
 res->d = floatx80_add(val0->d, val1->d, &env->fp_status);
 }
 
+void HELPER(fsadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(32);
+res->d = floatx80_add(val0->d, val1->d, &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fdadd)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(64);
+res->d = floatx80_add(val0->d, val1->d, &env->fp_status);
+PREC_END();
+}
+
 void HELPER(fsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
 res->d = floatx80_sub(val1->d, val0->d, &env->fp_status);
 }
 
+void HELPER(fssub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(32);
+res->d = floatx80_sub(val1->d, val0->d, &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fdsub)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(64);
+res->d = floatx80_sub(val1->d, val0->d, &env->fp_status);
+PREC_END();
+}
+
 void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
 res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
 }
 
+void HELPER(fsmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(32);
+res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fdmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(64);
+res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
+PREC_END();
+}
+
 void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
 float32 a, b, c;
@@ -199,6 +265,20 @@ void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg 
*val0, FPReg *val1)
 res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
 }
 
+void HELPER(fsdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(32);
+res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
+PREC_END();
+}
+
+void HELPER(fddiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
+{
+PREC_BEGIN(64);
+res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
+PREC_END();
+}
+
 void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
 {
 float32 a, b, c;
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index 5a006de..f05191b 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -26,13 +26,23 @@ DEF_HELPER_2(reds32, s32, env, fp)
 DEF_HELPER_3(firound, void, env, fp, fp)
 DEF_HELPER_3(fitrunc, void, env, fp, fp)
 DEF_HELPER_3(fsqrt, void, env, fp, fp)
+DEF_HELPER_3(fssqrt, void, env, fp, fp)
+DEF_HELPER_3(fdsqrt, void, env, fp, fp)
 DEF_HELPER_3(fabs, void, env, fp, fp)
 DEF_HELPER_3(fchs, void, env, fp, fp)
 DEF_HELPER_4(fadd, void, env, fp, fp, fp)
+DEF_HELPER_4(fsadd, void, env, fp, fp, fp)
+DEF_HELPER_4(fdadd, void, env, fp, fp, fp)
 DEF_HELPER_4(fsub, void, env, fp, fp, fp)
+DEF_HELPER_4(fssub, void, env, fp, fp, fp)
+DEF_HELPER_4(fdsub, void, env, fp, fp, fp)
 DEF_HELPER_4(fmul, void, env, fp, fp, fp)
+DEF_HELPER_4(fsmul, void, env, fp, fp, fp)
+DEF_HELPER_4(fdmul, void, env, fp, fp, fp)
 DEF_HELPER_4(fsglmul, void, env, fp, fp, fp)
 DEF_HELPER_4(fdiv, void, env, fp, f

[Qemu-devel] [PATCH 7/7] target/m68k: add fmovem

2017-06-25 Thread Laurent Vivier
Signed-off-by: Laurent Vivier 
---
 target/m68k/fpu_helper.c | 103 +++
 target/m68k/helper.h |   1 +
 target/m68k/translate.c  |  59 +--
 3 files changed, 133 insertions(+), 30 deletions(-)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 38370d0..3e765d6 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -22,6 +22,7 @@
 #include "cpu.h"
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
 
 static const floatx80 fpu_rom[128] = {
 [0x00] = floatx80_pi,   /* Pi */
@@ -378,3 +379,105 @@ void HELPER(fconst)(CPUM68KState *env, FPReg *val, 
uint32_t offset)
 {
 val->d = fpu_rom[offset];
 }
+
+static void cpu_ld_floatx80_ra(CPUM68KState *env, FPReg *fp,  uint32_t addr,
+   uintptr_t ra)
+{
+uint32_t high;
+uint64_t low;
+
+high = cpu_ldl_data_ra(env, addr, ra);
+low = cpu_ldq_data_ra(env, addr + 4, ra);
+
+fp->l.upper = high >> 16;
+fp->l.lower = low;
+}
+
+static void cpu_st_floatx80_ra(CPUM68KState *env, uint32_t addr, FPReg *fp,
+   uintptr_t ra)
+{
+cpu_stl_data_ra(env, addr, fp->l.upper << 16, ra);
+cpu_stq_data_ra(env, addr + 4, fp->l.lower, ra);
+}
+
+static void cpu_ld_float64_ra(CPUM68KState *env, FPReg *fp,  uint32_t addr,
+  uintptr_t ra)
+{
+uint64_t val;
+
+val = cpu_ldq_data_ra(env, addr, ra);
+fp->d = float64_to_floatx80(*(float64 *)&val, &env->fp_status);
+}
+
+static void cpu_st_float64_ra(CPUM68KState *env, uint32_t addr, FPReg *fp,
+  uintptr_t ra)
+{
+float64 val;
+
+val = floatx80_to_float64(fp->d, &env->fp_status);
+cpu_stq_data_ra(env, addr, *(uint64_t *)&val, ra);
+}
+
+uint32_t HELPER(fmovem)(CPUM68KState *env, uint32_t addr, uint32_t ext)
+{
+uintptr_t ra = GETPC();
+int mode = (ext >> 11) & 0x3;
+int is_load = ((ext & 0x2000) == 0);
+uint16_t mask;
+int incr, i;
+
+if (m68k_feature(env, M68K_FEATURE_FPU)) {
+incr = 12;
+} else {
+incr = 8;
+}
+
+if ((mode & 0x1) == 1) {
+/* Dynamic register list */
+int reg = extract32(ext, 4, 3);
+mask = env->dregs[reg] & 0x00FF;
+} else {
+/* Static register list */
+mask = ext & 0x00FF;
+}
+
+if (!is_load && (mode & 2) == 0) {
+/* predecrement addressing mode
+ * only available to store register to memory
+ */
+for (i = 7; i >= 0; i--, mask <<= 1) {
+if (mask & 0x80) {
+if (incr == 8) {
+cpu_st_float64_ra(env, addr, &env->fregs[i], ra);
+} else {
+cpu_st_floatx80_ra(env, addr, &env->fregs[i], ra);
+}
+if ((mask & 0xff) != 0x80) {
+addr -= incr;
+}
+}
+}
+return addr;
+}
+/* postincrement addressing mode */
+for (i = 0; i < 8; i++, mask <<= 1) {
+if (mask & 0x80) {
+if (is_load) {
+if (incr == 8) {
+cpu_ld_float64_ra(env, &env->fregs[i], addr, ra);
+} else {
+cpu_ld_floatx80_ra(env, &env->fregs[i], addr, ra);
+}
+} else {
+if (incr == 8) {
+cpu_st_float64_ra(env, addr, &env->fregs[i], ra);
+} else {
+cpu_st_floatx80_ra(env, addr, &env->fregs[i], ra);
+}
+}
+addr += incr;
+}
+}
+
+return addr;
+}
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index b396899..eb3d243 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -54,6 +54,7 @@ DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
 DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
 DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
 DEF_HELPER_3(fconst, void, env, fp, i32)
+DEF_HELPER_3(fmovem, i32, env, i32, i32)
 
 DEF_HELPER_3(mac_move, void, env, i32, i32)
 DEF_HELPER_3(macmulf, i64, env, i32, i32)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 3a1bdc1..5061619 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4505,6 +4505,32 @@ static void gen_op_fmove_fcr(CPUM68KState *env, 
DisasContext *s,
 tcg_temp_free_i32(addr);
 }
 
+static void gen_op_fmovem(CPUM68KState *env, DisasContext *s,
+  uint32_t insn, uint32_t ext)
+{
+int opsize;
+TCGv addr, tmp;
+
+if (m68k_feature(s->env, M68K_FEATURE_FPU)) {
+opsize = OS_EXTENDED;
+} else {
+opsize = OS_DOUBLE;  /* FIXME */
+}
+
+addr = gen_lea(env, s, insn, opsize);
+if (IS_NULL_QREG(addr)) {
+gen_addr_fault(s);
+return;
+}
+
+tmp = tcg_const_i32(ext);
+

[Qemu-devel] [RFC PATCH 2/4] coccinelle: ignore ASTs pre-parsed cached C files

2017-06-25 Thread Philippe Mathieu-Daudé
files generated using coccinelle tool: 'spatch --use-cache'

Signed-off-by: Philippe Mathieu-Daudé 
---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 09c2363acf..cf65316863 100644
--- a/.gitignore
+++ b/.gitignore
@@ -116,6 +116,8 @@ tags
 TAGS
 docker-src.*
 *~
+*.ast_raw
+*.depend_raw
 trace.h
 trace.c
 trace-ust.h
-- 
2.13.1




[Qemu-devel] [RFC PATCH 0/4] travis: run all coccinelle scripts

2017-06-25 Thread Philippe Mathieu-Daudé
Another item from my 'automated testing' list: use travis-ci to run coccinelle
scripts. This series is more of a PoC. The idea would be to run it once a day
only on /master.

Patch 1 is here only to speedup travis testing.

Patch 3 add a script which run each cocci script sequencially. If the script
modified any file from the repo, changes are commited. If the script generated
some output (i.e. using python), this output is logged in an empty commit.
Spatch is run thru a debian-based Docker image.

Patch 4 is the travis job: it calls the previous script. To respect travis time
limit timeout, each script is limited to <10min. If any commit were
generated, they are pushed to my gh-repo:

https://github.com/philmd/qemu/compare/travis-cocci_v1...philmd:autogenerated-coccinelle-20170625-126

Build output (Ran for 23 min 7 sec):
https://travis-ci.org/philmd/qemu/builds/246848085

Any idea is welcome :)

Regards,

Phil.

Philippe Mathieu-Daudé (4):
  travis: simplify matrix
  coccinelle: ignore ASTs pre-parsed cached C files
  coccinelle: script to run them all
  travis: add job to run coccinelle scripts

 .gitignore |   2 +
 .travis.sshkey | Bin 0 -> 1296 bytes
 .travis.yml| 145 ++---
 scripts/check-cocci-scripts.sh |  47 +
 4 files changed, 69 insertions(+), 125 deletions(-)
 create mode 100644 .travis.sshkey
 create mode 100755 scripts/check-cocci-scripts.sh

-- 
2.13.1




[Qemu-devel] [RFC PATCH 1/4] XXX travis: simplify matrix

2017-06-25 Thread Philippe Mathieu-Daudé
to speedup further testing

Signed-off-by: Philippe Mathieu-Daudé 
---
 .travis.yml | 119 
 1 file changed, 119 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 27a2d9cfb3..4761569183 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -48,11 +48,6 @@ env:
 - TEST_CMD="make check"
   matrix:
 - CONFIG=""
-- CONFIG="--enable-debug --enable-debug-tcg --enable-trace-backends=log"
-- CONFIG="--disable-linux-aio --disable-cap-ng --disable-attr 
--disable-brlapi --disable-uuid --disable-libusb"
-- CONFIG="--enable-modules"
-- CONFIG="--with-coroutine=ucontext"
-- CONFIG="--with-coroutine=sigaltstack"
 git:
   # we want to do this ourselves
   submodules: false
@@ -67,39 +62,6 @@ script:
   - make -j3 && ${TEST_CMD}
 matrix:
   include:
-# Test with CLang for compile portability
-- env: CONFIG=""
-  compiler: clang
-# gprof/gcov are GCC features
-- env: CONFIG="--enable-gprof --enable-gcov --disable-pie"
-  compiler: gcc
-# We manually include builds which we disable "make check" for
-- env: CONFIG="--enable-debug --enable-tcg-interpreter"
-   TEST_CMD=""
-  compiler: gcc
-- env: CONFIG="--enable-trace-backends=simple"
-   TEST_CMD=""
-  compiler: gcc
-- env: CONFIG="--enable-trace-backends=ftrace"
-   TEST_CMD=""
-  compiler: gcc
-- env: CONFIG="--enable-trace-backends=ust"
-   TEST_CMD=""
-  compiler: gcc
-- env: CONFIG=""
-  os: osx
-  compiler: clang
-# Plain Trusty System Build
-- env: CONFIG="--disable-linux-user"
-  sudo: required
-  addons:
-  dist: trusty
-  compiler: gcc
-  before_install:
-- sudo apt-get update -qq
-- sudo apt-get build-dep -qq qemu
-- wget -O - 
http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
-- git submodule update --init --recursive
 # Plain Trusty Linux User Build
 - env: CONFIG="--disable-system"
   sudo: required
@@ -111,84 +73,3 @@ matrix:
 - sudo apt-get build-dep -qq qemu
 - wget -O - 
http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
 - git submodule update --init --recursive
-# Trusty System build with latest stable clang
-- sudo: required
-  addons:
-  dist: trusty
-  language: generic
-  compiler: none
-  env:
-- COMPILER_NAME=clang CXX=clang++-3.9 CC=clang-3.9
-- CONFIG="--disable-linux-user --cc=clang-3.9 --cxx=clang++-3.9"
-  before_install:
-- wget -nv -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo 
apt-key add -
-- sudo apt-add-repository -y 'deb http://llvm.org/apt/trusty 
llvm-toolchain-trusty-3.9 main'
-- sudo apt-get update -qq
-- sudo apt-get install -qq -y clang-3.9
-- sudo apt-get build-dep -qq qemu
-- wget -O - 
http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
-- git submodule update --init --recursive
-  before_script:
-- ./configure ${CONFIG} || cat config.log
-# Trusty Linux User build with latest stable clang
-- sudo: required
-  addons:
-  dist: trusty
-  language: generic
-  compiler: none
-  env:
-- COMPILER_NAME=clang CXX=clang++-3.9 CC=clang-3.9
-- CONFIG="--disable-system --cc=clang-3.9 --cxx=clang++-3.9"
-  before_install:
-- wget -nv -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo 
apt-key add -
-- sudo apt-add-repository -y 'deb http://llvm.org/apt/trusty 
llvm-toolchain-trusty-3.9 main'
-- sudo apt-get update -qq
-- sudo apt-get install -qq -y clang-3.9
-- sudo apt-get build-dep -qq qemu
-- wget -O - 
http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
-- git submodule update --init --recursive
-  before_script:
-- ./configure ${CONFIG} || cat config.log
-# Using newer GCC with sanitizers
-- addons:
-apt:
-  sources:
-# PPAs for newer toolchains
-- ubuntu-toolchain-r-test
-  packages:
-# Extra toolchains
-- gcc-5
-- g++-5
-# Build dependencies
-- libaio-dev
-- libattr1-dev
-- libbrlapi-dev
-- libcap-ng-dev
-- libgnutls-dev
-- libgtk-3-dev
-- libiscsi-dev
-- liblttng-ust-dev
-- libnfs-dev
-- libncurses5-dev
-- libnss3-dev
-- libpixman-1-dev
-- libpng12-dev
-- librados-dev
-- libsdl1.2-dev
-- libseccomp-dev
-- libspice-protocol-dev
-- libspice-server-dev
-- libssh2-1-dev
-- liburcu-dev
-- libusb-1.0-0-dev
-- libvte-2.90-dev
-- spa

[Qemu-devel] [RFC PATCH 3/4] coccinelle: script to run them all

2017-06-25 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 scripts/check-cocci-scripts.sh | 47 ++
 1 file changed, 47 insertions(+)
 create mode 100755 scripts/check-cocci-scripts.sh

diff --git a/scripts/check-cocci-scripts.sh b/scripts/check-cocci-scripts.sh
new file mode 100755
index 00..ec3a8b39ef
--- /dev/null
+++ b/scripts/check-cocci-scripts.sh
@@ -0,0 +1,47 @@
+#! /usr/bin/env bash
+
+test -d scripts/coccinelle || exit 1
+
+SPATCH_IMAGE="philmd/coccinelle:1.0.4"
+
+GIT_AUTHOR_NAME="Coccinelle Spatch"
+GIT_COMMITTER_NAME="Coccinelle Spatch"
+
+if [ -n "$TRAVIS" ]; then
+   # avoid stalling builds: 
https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-received
+   TIMEOUT_S=530
+   TIMEOUT_CMD="timeout -k 550 500"
+   EXTRA_ARGS="--timeout ${TIMEOUT_S}"
+else
+   TIMEOUT_S=0
+fi
+
+HEAD=19 #`echo -n scripts/coccinelle/ | wc -c`
+TAIL=6 #`echo -n .cocci | wc -c`
+
+test -z "$(${SUDO} docker images -q ${SPATCH_IMAGE})" && ${SUDO} docker pull 
${SPATCH_IMAGE}
+
+LOG=/tmp/cocci-spatch-$$
+for script in scripts/coccinelle/*.cocci; do
+   desc=${script:$HEAD:-$TAIL}
+   echo -e "\nRunning ${script}...\n"
+   echo -e "coccinelle: committing changes after running \"$desc\" 
script\n" > ${LOG}.topic
+   ${TIMEOUT_CMD} ${SUDO} \
+   docker run --rm -v `pwd`:`pwd` -w `pwd` -u `id -u` \
+   ${SPATCH_IMAGE} --use-cache --use-gitgrep --keep-comments \
+   --very-quiet ${EXTRA_ARGS} \
+   --sp-file ${script} \
+   --macro-file scripts/cocci-macro-file.h \
+   --dir . \
+   --in-place | tee ${LOG}.content
+   git add -u
+   git diff --cached --exit-code -s
+   if [ $? -ne 0 ]; then
+   :> ${LOG}.content
+   else
+   test -s ${LOG}.content || continue
+   fi
+   cat ${LOG}.{topic,content} | git commit --allow-empty -F -
+done
+
+rm -f ${LOG}.{topic,content}
-- 
2.13.1




[Qemu-devel] [RFC PATCH 4/4] travis: add job to run coccinelle scripts

2017-06-25 Thread Philippe Mathieu-Daudé
result pushed to my gh repo via ssh deploy key

Signed-off-by: Philippe Mathieu-Daudé 
---
 .travis.sshkey | Bin 0 -> 1296 bytes
 .travis.yml|  26 --
 2 files changed, 20 insertions(+), 6 deletions(-)
 create mode 100644 .travis.sshkey

diff --git a/.travis.sshkey b/.travis.sshkey
new file mode 100644
index 
..5921e953c8d91461ae193c15922d658834f8d6c5
GIT binary patch
literal 1296
zcmV+r1@HPCoP~Uo`}Gc5AacL0i>ciVZGDC=x67D__o=U=ig02!0StKv2oE-TL@8$>
zU0$F^xr)f=@8?MPI@}e&`i8?|`SXQ<@(;6hZnSBYT!2m}p#!07TN{#iIdPyKQH>(O
z66UEPdqEDb%~tpi+Wxb^jo$Z$8V9xkj&Zf#;-Em>m@d<_%#}N$?$af5jn}TO^)Vlf
zv~Wb!S$UnnnwWL0duGIR)=(GR15y%p)Twy93gpSGUnb!u&lx@E3~(dg5R~~?^OObe
zl>p3F$Wk~ik$4);k?zOq%6LU@vd$}DY@%-TIBpF^@?;3!jJIsNPFFjay`~et1EgI_
zMpprT%uH4i;`<##f$cFhAhk$2#|jPI
zwFds#72`WsQ;CX*$iOAWaBaq(yR_<(-4OyZ)W8r7tdsTF)tQm5Qm`^JN5YDL*JlT~`LrPzh9I_~Tjf$99HM${l=EjEK6KQ{9GBvA~8p(*N%B
zJjX9tqMli6nykS@*a;;AVjl4dK$JliASAv_9zckAQ(;U=eB6m4R>^&EcZlFAo)OTn
zhPz5?A<|tKZVuhRnfQaTkv2h_>sWH#oVnH&eV29jt8gH>IZRo%gY?A3HSG`Ale19DS3X
z$iXSp$>v;MD2S0N6g53BQ(RU;;@E5r{H8kkSs{|&8&eF%15L|}>u8)}p({!79kYTk
z;$4d%3*h6V@-)s;l4i{7st?~{!Z}gK+`j*^jc?cPZ#Qr|g~^Be+DW&OJr@k
z%MDv7*PmucM^qRj*rK36
zfqH&%?QJB>cjUoZwq;2=%@5{=((`nIe_+#`n{ivY53v36@`pdZdyiN3iDy^T1ltVW
zYXJh3g4aNoPZQNn7a$l}6B;&sWe8n=CCj>F>s;W!(Dd-BcWFcnhHn?XZ|&RY7MUC=
z=!4=WHQ==S-C?Ms3cH)W^?%>IHJ>ZD*0le4eX5_T4Rs&?k;0~OG5Ludm-uuHi-{vX
zWKVyW?2=Uy6RCl8gNjW+e|AfO^6EJ}=upJqIUHpXNd(-E*ZgN%A0-L4r<`IbRB?4y
z)w%*$FPwBYRmfJ7U}7|Wpd2&o+nj#Dk9Dk=w`L}&Y@Zs4DKinczsaDO&ifLs6YnIA
zAcKDL;g+m+!ByZV67En&W{lNMy7g?{
GW~j`fDT25F

literal 0
HcmV?d1

diff --git a/.travis.yml b/.travis.yml
index 4761569183..52665273ba 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -51,6 +51,9 @@ env:
 git:
   # we want to do this ourselves
   submodules: false
+branches:
+  except:
+  - /^autogenerated-.*/
 before_install:
   - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update ; fi
   - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install libffi gettext glib 
pixman ; fi
@@ -62,14 +65,25 @@ script:
   - make -j3 && ${TEST_CMD}
 matrix:
   include:
-# Plain Trusty Linux User Build
-- env: CONFIG="--disable-system"
+# Coccinelle using Trusty
+- env: TEST_CMD=""
+   GIT_AUTHOR_EMAIL="coccinelle@travis-ci"
+   GIT_COMMITTER_EMAIL="f4...@amsat.org"
   sudo: required
-  addons:
+  services:
+  - docker
   dist: trusty
+  group: deprecated-2017Q2
   compiler: gcc
   before_install:
-- sudo apt-get update -qq
 - sudo apt-get build-dep -qq qemu
-- wget -O - 
http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ
-- git submodule update --init --recursive
+- git submodule update --init dtc
+  script:
+- ORIGIN=$(git rev-parse HEAD)
+- scripts/check-cocci-scripts.sh
+  after_success:
+- if [ ${ORIGIN} = $(git rev-parse HEAD) ]; then exit; fi
+- eval "$(ssh-agent -s)"
+- openssl aes-256-cbc -K $encrypted_8b1bab3b4d04_key -iv 
$encrypted_8b1bab3b4d04_iv -in .travis.sshkey -d | ssh-add -
+- BRANCH=autogenerated-coccinelle-`date +%Y%m%d`-${TRAVIS_BUILD_NUMBER}
+- git checkout -b ${BRANCH} && git remote add deploy 
g...@github.com:${TRAVIS_REPO_SLUG}.git && git push -f deploy ${BRANCH}
-- 
2.13.1




Re: [Qemu-devel] [PATCH 3/7] target/m68k: add fsglmul and fsgldiv

2017-06-25 Thread Philippe Mathieu-Daudé

Hi Laurent,

On 06/25/2017 04:21 PM, Laurent Vivier wrote:

fsglmul and fsgldiv truncate data to single precision before computing
results.

Signed-off-by: Laurent Vivier 
---
  target/m68k/fpu_helper.c | 22 ++
  target/m68k/helper.h |  2 ++
  target/m68k/translate.c  |  6 ++
  3 files changed, 30 insertions(+)

diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 912c0b7..0d83925 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -183,11 +183,33 @@ void HELPER(fmul)(CPUM68KState *env, FPReg *res, FPReg 
*val0, FPReg *val1)
  res->d = floatx80_mul(val0->d, val1->d, &env->fp_status);
  }
  
+void HELPER(fsglmul)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)

+{
+float32 a, b, c;
+
+a = floatx80_to_float32(val0->d, &env->fp_status);
+b = floatx80_to_float32(val1->d, &env->fp_status);
+c = float32_mul(a, b, &env->fp_status);


Why not use floatx80_mul() directly?


+
+res->d = float32_to_floatx80(c, &env->fp_status);
+}
+
  void HELPER(fdiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
  {
  res->d = floatx80_div(val1->d, val0->d, &env->fp_status);
  }
  
+void HELPER(fsgldiv)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)

+{
+float32 a, b, c;
+
+a = floatx80_to_float32(val1->d, &env->fp_status);
+b = floatx80_to_float32(val0->d, &env->fp_status);
+c = float32_div(a, b, &env->fp_status);


floatx80_div()?


+
+res->d = float32_to_floatx80(c, &env->fp_status);
+}
+
  static int float_comp_to_cc(int float_compare)
  {
  switch (float_compare) {
diff --git a/target/m68k/helper.h b/target/m68k/helper.h
index d6e80e4..5a006de 100644
--- a/target/m68k/helper.h
+++ b/target/m68k/helper.h
@@ -31,7 +31,9 @@ DEF_HELPER_3(fchs, void, env, fp, fp)
  DEF_HELPER_4(fadd, void, env, fp, fp, fp)
  DEF_HELPER_4(fsub, void, env, fp, fp, fp)
  DEF_HELPER_4(fmul, void, env, fp, fp, fp)
+DEF_HELPER_4(fsglmul, void, env, fp, fp, fp)
  DEF_HELPER_4(fdiv, void, env, fp, fp, fp)
+DEF_HELPER_4(fsgldiv, void, env, fp, fp, fp)
  DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_RWG, void, env, fp, fp)
  DEF_HELPER_FLAGS_2(set_fpcr, TCG_CALL_NO_RWG, void, env, i32)
  DEF_HELPER_FLAGS_2(ftst, TCG_CALL_NO_RWG, void, env, fp)
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index a54da87..a50bf5f 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4622,6 +4622,12 @@ DISAS_INSN(fpu)
  case 0x23: case 0x63: case 0x67: /* fmul */
  gen_helper_fmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
  break;
+case 0x24: /* fsgldiv */
+gen_helper_fsgldiv(cpu_env, cpu_dest, cpu_src, cpu_dest);
+break;
+case 0x27: /* fsglmul */
+gen_helper_fsglmul(cpu_env, cpu_dest, cpu_src, cpu_dest);
+break;
  case 0x28: case 0x68: case 0x6c: /* fsub */
  gen_helper_fsub(cpu_env, cpu_dest, cpu_src, cpu_dest);
  break;





Re: [Qemu-devel] [PATCH 1/7] target/m68k: add fscc.

2017-06-25 Thread Richard Henderson

On 06/25/2017 12:21 PM, Laurent Vivier wrote:

+c->g1 = 0;
+c->v2 = tcg_const_i32(0);
+c->g2 = 1;
+/* TODO: Raise BSUN exception.  */
  fpsr = tcg_temp_new();
  gen_load_fcr(s, fpsr, M68K_FPSR);
-l1 = gen_new_label();
-/* TODO: Raise BSUN exception.  */
-/* Jump to l1 if condition is true.  */
-switch (insn & 0x3f)  {
+switch (cond) {
  case 0:  /* False */
  case 16: /* Signaling False */
+c->v1 = c->v2;
+c->tcond = TCG_COND_NEVER;
  break;
  case 1:  /* EQual Z */
  case 17: /* Signaling EQual Z */
-tmp = tcg_temp_new();
-tcg_gen_andi_i32(tmp, fpsr, FPSR_CC_Z);
-tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
+c->v1 = tcg_temp_new();
+c->g1 = 1;


g[12] means "global", i.e. don't free the temp in free_cond.
Which is not true of any of the temps that you allocate here.


r~



Re: [Qemu-devel] [RFC 0/3] qemu-ga: support for sending events

2017-06-25 Thread Tomáš Golembiovský
Hi,

On Fri, 23 Jun 2017 13:25:34 +
Marc-André Lureau  wrote:

> Hi
> 
> On Fri, Jun 23, 2017 at 3:03 PM Tomáš Golembiovský 
> wrote:
> 
> > This is just a draft, or a request for comments if you will.
> >
> > This patch sets drafts the support of sending events by QEMU Guest Agent.
> > Events can plan important role in monitoring of the guest OS behaviour. The
> > range of use cases ranges from events important for scheduling, e.g.
> > memory and
> > CPU usage statistics, to things like changes to IP addresses on network
> > interfaces to for example changes in the list of active users.
> >
> > For now the patch set adds single periodic callback function to the GA main
> > loop that can perform checks and trigger events that have occured since
> > previous run of the callback.
> >
> > We can of course take it one step further and add a general framwork for
> > periodically running any of the already implemented commands. Add a
> > function
> > that would maintain a list of registered checks. Client would use some
> > command
> > (register-monitor-command) passing it a command name and timeout in
> > seconds and
> > the monitoring handler would then run the specified command and report the
> > result... or report only if the return value changed since previous
> > invocation.
> > This feature would remove part of the communication overhead between
> > client and
> > GA.
> >
> > So before I invest any more time in either of these approaches, tell me.
> > Would
> > somethign like this be wanted or is that too controversial? Any other
> > thoughts
> > and ideas?
> >
> >  
> It doesn't feel wrong, but Is there really too much overhead and/or latency
> if a request is periodic from the client? ie did you do some measurements
> before coming to this proposal?

No, I didn't do any measurements. And it may be even true that in the
grand scheme of things the overhead/latency may be insignificant, if we
imagine a client that repeatedly calls about 5 to 10 commands every 5 or
10 seconds. Still, it just feels like a more correct approach to me. But
that may be just my feeling, that's why I brought this to the list to
get the opinion of others.

Tomas

> 
> Tomáš Golembiovský (3):
> >   qemu-ga: add support for events
> >   qemu-ga: add simple event reporting memory statistics
> >   qemu-ga: add support for periodic command runner
> >
> >  Makefile   |  7 +++-
> >  qga/Makefile.objs  |  2 +-
> >  qga/channel-posix.c|  8 +
> >  qga/channel-win32.c|  6 
> >  qga/channel.h  |  1 +
> >  qga/guest-agent-core.h |  1 +
> >  qga/main.c | 98
> > ++
> >  qga/qapi-event.json| 35 ++
> >  qga/qapi-schema.json   |  2 ++
> >  9 files changed, 158 insertions(+), 2 deletions(-)
> >  create mode 100644 qga/qapi-event.json
> >
> > --
> > 2.13.1
> >
> >
> > --  
> Marc-André Lureau


-- 
Tomáš Golembiovský 



[Qemu-devel] glue(glue(ld, USUFFIX), _p)

2017-06-25 Thread Theodore Dubois
In include/exec/cpu_ldst_useronly_template.h, there’s references to 
glue(glue(ld, USUFFIX), _p), which would expand to a call to a function looking 
something like uint32_t lduw_p(void *) (for example). Where is this function 
defined?

~Theodore




Re: [Qemu-devel] [PATCH v1] target-s390x: fix risbg handling

2017-06-25 Thread Aurelien Jarno
On 2017-06-23 01:12, David Hildenbrand wrote:
> If we have for example: r3 contains 0x
> ec 33 3f bf 61 55   risbg   %r3,%r3,63,191,97
> 
> We want to rotate 33 to the left and only keep MSB bit 63 of that. So the
> result is then exactly 1 (we're reading the sign of the 32 bit value).
> 
> Current code assumes that we can do that via an extract, which is not
> true (at least not that easy) and produces a 0.

I think the mistake there is that the rotation is done to the left,
while in extract the "shift" is done to the right. The following patch
should be enough:

--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -3441,8 +3441,8 @@ static ExitStatus op_risbg(DisasContext *s, DisasOps *o)
 }
 
 /* In some cases we can implement this with extract.  */
-if (imask == 0 && pos == 0 && len > 0 && rot + len <= 64) {
-tcg_gen_extract_i64(o->out, o->in2, rot, len);
+if (imask == 0 && pos == 0 && len > 0 && rot - len >= 0) {
+tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len);
 return NO_EXIT;


> Let's just get rid of this special handling.
> 
> Signed-off-by: David Hildenbrand 
> ---
> 
> This effectively allows to start a linux kernel, compiled for z10 using
> the qemu model under tcg (with other patches currently on the list):
> 
> qemu-system-s390x ... -cpu qemu,mvcos=on,stfle=on,ldisp=on,ldisphp=on, \
>eimm=on,stckf=on,csst=on,csst2=on,ginste=on, \
>exrl=on ...
> 
> I found this by compiling the kvm-unit-tests for z10 and noticing
> elementary selftests failing. The kernel would trigger weird
> BUG_ONs very early while starting up, which basically gave not really
> many hints of what was actually going wrong.
> 
>  target/s390x/translate.c | 6 --
>  1 file changed, 6 deletions(-)

But the patch is also correct.

Reviewed-by: Aurelien Jarno 

-- 
Aurelien Jarno  GPG: 4096R/1DDD8C9B
aurel...@aurel32.net http://www.aurel32.net



Re: [Qemu-devel] [PATCH] target-i386: add Skylake-Server cpu model

2017-06-25 Thread Boqun Feng
On Fri, Jun 23, 2017 at 10:38:14AM -0300, Eduardo Habkost wrote:
> On Wed, Jun 21, 2017 at 01:29:34PM +0800, Boqun Feng (Intel) wrote:
> > Introduce Skylake-Server cpu mode which inherits the features from
> > Skylake-Client and supports some additional features that are: AVX512,
> > CWLB and PGPE1GB.
> 
> I will fix this to "CLWB" when applying the patch.
> 

Oops.. thank you for pointing this out.

> > 
> > Signed-off-by: Boqun Feng (Intel) 
> > ---
> >  target/i386/cpu.c | 42 ++
> >  1 file changed, 42 insertions(+)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index b2b1d20cee51..1bed722ac2fd 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -1349,6 +1349,48 @@ static X86CPUDefinition builtin_x86_defs[] = {
> >  .model_id = "Intel Core Processor (Skylake)",
> >  },
> >  {
> > +.name = "Skylake-Server",
> > +.level = 0xd,
> > +.vendor = CPUID_VENDOR_INTEL,
> > +.family = 6,
> > +.model = 85,
> > +.stepping = 4,
> > +.features[FEAT_1_EDX] =
> > +CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
> > +CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | 
> > CPUID_MCA |
> > +CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
> > +CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> > +CPUID_DE | CPUID_FP87,
> > +.features[FEAT_1_ECX] =
> > +CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
> > +CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
> > +CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> > +CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
> > +CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE 
> > |
> > +CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
> > +.features[FEAT_8000_0001_EDX] =
> > +CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
> > +CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
> > +.features[FEAT_8000_0001_ECX] =
> > +CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
> > +.features[FEAT_7_0_EBX] =
> > +CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
> > +CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
> > +CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | 
> > CPUID_7_0_EBX_INVPCID |
> > +CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
> > +CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
> > +CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
> > +CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
> > +CPUID_7_0_EBX_AVX512VL,
> 
> I believe we should add the same comment about XSAVES from
> Skylake-Cliente here, for consistency:
> 
> /* Missing: XSAVES (not supported by some Linux versions,
>  * including v4.1 to v4.6).
>  * KVM doesn't yet expose any XSAVES state save component,
>  * and the only one defined in Skylake (processor tracing)
>  * probably will block migration anyway.
>  */
> 

Make sense.

> I can add it when applying the patch.
> 

Please do, thanks! Or you prefer that I send out a V2 with typo fixed
and comment added?

Regards,
Boqun

> > +.features[FEAT_XSAVE] =
> > +CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
> > +CPUID_XSAVE_XGETBV1,
> > +.features[FEAT_6_EAX] =
> > +CPUID_6_EAX_ARAT,
> > +.xlevel = 0x8008,
> > +.model_id = "Intel Xeon Processor (Skylake)",
> > +},
> > +{
> >  .name = "Opteron_G1",
> >  .level = 5,
> >  .vendor = CPUID_VENDOR_AMD,
> > -- 
> > 2.13.1
> > 
> 
> -- 
> Eduardo


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v7 7/9] pci: Convert shpc_init() to Error

2017-06-25 Thread Mao Zhongyi



On 06/23/2017 05:56 PM, Marcel Apfelbaum wrote:

On 22/06/2017 11:14, Mao Zhongyi wrote:

In order to propagate error message better, convert shpc_init() to
Error also convert the pci_bridge_dev_initfn() to realize.

Cc: m...@redhat.com
Cc: mar...@redhat.com
Cc: arm...@redhat.com
Signed-off-by: Mao Zhongyi 
---
v7:
* drop the !local_err assert is really not appropriate,
   now revert it.[Marcel Apfelbaum]

  hw/pci-bridge/pci_bridge_dev.c | 14 ++
  hw/pci/shpc.c  | 11 +--
  hw/pci/slotid_cap.c| 11 +--
  include/hw/pci/shpc.h  |  3 ++-
  include/hw/pci/slotid_cap.h|  3 ++-
  5 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 5dbd933..4373f1d 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -49,7 +49,7 @@ struct PCIBridgeDev {
  };
  typedef struct PCIBridgeDev PCIBridgeDev;
  -static int pci_bridge_dev_initfn(PCIDevice *dev)
+static void pci_bridge_dev_realize(PCIDevice *dev, Error **errp)
  {
  PCIBridge *br = PCI_BRIDGE(dev);
  PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
@@ -62,7 +62,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  dev->config[PCI_INTERRUPT_PIN] = 0x1;
  memory_region_init(&bridge_dev->bar, OBJECT(dev), "shpc-bar",
 shpc_bar_size(dev));
-err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0);
+err = shpc_init(dev, &br->sec_bus, &bridge_dev->bar, 0, errp);
  if (err) {
  goto shpc_error;
  }
@@ -71,7 +71,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  bridge_dev->msi = ON_OFF_AUTO_OFF;
  }
  -err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0);
+err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0, errp);
  if (err) {
  goto slotid_error;
  }
@@ -87,7 +87,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  /* Can't satisfy user's explicit msi=on request, fail */
  error_append_hint(&local_err, "You have to use msi=auto (default) 
"
  "or msi=off with this machine type.\n");
-error_report_err(local_err);
+error_propagate(errp, local_err);
  goto msi_error;
  }
  assert(!local_err || bridge_dev->msi == ON_OFF_AUTO_AUTO);
@@ -101,7 +101,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
   PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar);
  }
-return 0;
+return;
msi_error:
  slotid_cap_cleanup(dev);
@@ -111,8 +111,6 @@ slotid_error:
  }
  shpc_error:
  pci_bridge_exitfn(dev);
-
-return err;
  }
static void pci_bridge_dev_exitfn(PCIDevice *dev)
@@ -216,7 +214,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, 
void *data)
  PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
  -k->init = pci_bridge_dev_initfn;
+k->realize = pci_bridge_dev_realize;
  k->exit = pci_bridge_dev_exitfn;
  k->config_write = pci_bridge_dev_write_config;
  k->vendor_id = PCI_VENDOR_ID_REDHAT;
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index d72d5e4..69fc14b 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -446,16 +446,14 @@ static void shpc_cap_update_dword(PCIDevice *d)
  }
/* Add SHPC capability to the config space for the device. */
-static int shpc_cap_add_config(PCIDevice *d)
+static int shpc_cap_add_config(PCIDevice *d, Error **errp)
  {
  uint8_t *config;
  int config_offset;
-Error *local_err = NULL;
  config_offset = pci_add_capability(d, PCI_CAP_ID_SHPC,
 0, SHPC_CAP_LENGTH,
-   &local_err);
+   errp);
  if (config_offset < 0) {
-error_report_err(local_err);
  return config_offset;
  }
  config = d->config + config_offset;
@@ -584,13 +582,14 @@ void shpc_device_hot_unplug_request_cb(HotplugHandler 
*hotplug_dev,
  }
/* Initialize the SHPC structure in bridge's BAR. */
-int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar, unsigned 
offset)
+int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar,
+  unsigned offset, Error **errp)
  {
  int i, ret;
  int nslots = SHPC_MAX_SLOTS; /* TODO: qdev property? */
  SHPCDevice *shpc = d->shpc = g_malloc0(sizeof(*d->shpc));
  shpc->sec_bus = sec_bus;
-ret = shpc_cap_add_config(d);
+ret = shpc_cap_add_config(d, errp);
  if (ret) {
  g_free(d->shpc);
  return ret;
diff --git a/hw/pci/slotid_cap.c b/hw/pci/slotid_cap.c
index bdca205..36d021b 100644
--- a/hw/pci/slotid_cap.c
+++ b/hw/pci/slotid_cap.c
@@ -9,14 +9,14 @@
int slotid_cap_init(PCIDevice *d, int nslots,
   

Re: [Qemu-devel] NVDIMM live migration broken?

2017-06-25 Thread Haozhong Zhang
On 06/23/17 10:55 +0100, Stefan Hajnoczi wrote:
> On Fri, Jun 23, 2017 at 08:13:13AM +0800, haozhong.zh...@intel.com wrote:
> > On 06/22/17 15:08 +0100, Stefan Hajnoczi wrote:
> > > I tried live migrating a guest with NVDIMM on qemu.git/master (edf8bc984):
> > > 
> > >   $ qemu -M accel=kvm,nvdimm=on -m 1G,slots=4,maxmem=8G -cpu host \
> > >  -object 
> > > memory-backend-file,id=mem1,share=on,mem-path=nvdimm.dat,size=1G \
> > >-device nvdimm,id=nvdimm1,memdev=mem1 \
> > >-drive if=virtio,file=test.img,format=raw
> > > 
> > >   $ qemu -M accel=kvm,nvdimm=on -m 1G,slots=4,maxmem=8G -cpu host \
> > >  -object 
> > > memory-backend-file,id=mem1,share=on,mem-path=nvdimm.dat,size=1G \
> > >-device nvdimm,id=nvdimm1,memdev=mem1 \
> > >-drive if=virtio,file=test.img,format=raw \
> > >-incoming tcp::1234
> > > 
> > >   (qemu) migrate tcp:127.0.0.1:1234
> > > 
> > > The guest kernel panics or hangs every time on the destination.  It
> > > happens as long as the nvdimm device is present - I didn't even mount it
> > > inside the guest.
> > > 
> > > Is migration expected to work?
> > 
> > Yes, I tested on QEMU 2.8.0 several months ago and it worked. I'll
> > have a look at this issue.
> 
> Great, thanks!
> 
> David Gilbert suggested the following on IRC, it sounds like a good
> starting point for debugging:
> 
> Launch the destination QEMU with -S (vcpus will be paused) and after
> migration has completed, compare the NVDIMM contents on source and
> destination.
> 

Which host and guest kernel are you testing? Is any workload running
in guest when migration?

I just tested QEMU commit edf8bc984 with host/guest kernel 4.8.0, and
could not reproduce the issue.

Haozhong



Re: [Qemu-devel] [PATCH v5 01/10] machine: export register_compat_prop()

2017-06-25 Thread Peter Xu
On Fri, Jun 23, 2017 at 06:24:32PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 23, 2017 at 12:46:37PM +0800, Peter Xu wrote:
> > We have HW_COMPAT_*, however that's only bound to machines, not other
> > things (like accelerators).  Behind it, it was register_compat_prop()
> > that played the trick.  Let's export the function for further use
> > outside HW_COMPAT_* magic.
> > 
> > Meanwhile, move it to qdev-properties.c where seems more proper (since
> > it'll be used not only in machine codes).
> > 
> > Signed-off-by: Peter Xu 
> > ---
> >  hw/core/machine.c| 13 -
> >  hw/core/qdev-properties.c| 13 +
> >  include/hw/qdev-properties.h |  3 +++
> >  3 files changed, 16 insertions(+), 13 deletions(-)
> > 
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index 2e7e977..ecb5552 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -770,19 +770,6 @@ static void machine_class_finalize(ObjectClass *klass, 
> > void *data)
> >  g_free(mc->name);
> >  }
> >  
> > -static void register_compat_prop(const char *driver,
> > - const char *property,
> > - const char *value)
> > -{
> > -GlobalProperty *p = g_new0(GlobalProperty, 1);
> > -/* Machine compat_props must never cause errors: */
> > -p->errp = &error_abort;
> > -p->driver = driver;
> > -p->property = property;
> > -p->value = value;
> > -qdev_prop_register_global(p);
> > -}
> > -
> >  static void machine_register_compat_for_subclass(ObjectClass *oc, void 
> > *opaque)
> >  {
> >  GlobalProperty *p = opaque;
> > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> > index 9f1a497..6ff1ac3 100644
> > --- a/hw/core/qdev-properties.c
> > +++ b/hw/core/qdev-properties.c
> > @@ -1047,6 +1047,19 @@ void qdev_prop_register_global(GlobalProperty *prop)
> >  global_props = g_list_append(global_props, prop);
> >  }
> >  
> > +void register_compat_prop(const char *driver,
> > +  const char *property,
> > +  const char *value)
> > +{
> > +GlobalProperty *p = g_new0(GlobalProperty, 1);
> > +/* Machine compat_props must never cause errors: */
> 
> Now this won't be used only for machine compat_props, so this comment
> needs to be deleted or updated (see suggestion below).

Yes. Fixing.

> 
> 
> > +p->errp = &error_abort;
> > +p->driver = driver;
> > +p->property = property;
> > +p->value = value;
> > +qdev_prop_register_global(p);
> > +}
> > +
> >  void qdev_prop_register_global_list(GlobalProperty *props)
> >  {
> >  int i;
> > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> > index d206fc9..1722ca4 100644
> > --- a/include/hw/qdev-properties.h
> > +++ b/include/hw/qdev-properties.h
> > @@ -201,6 +201,9 @@ void qdev_prop_set_globals(DeviceState *dev);
> >  void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState 
> > *dev,
> >  Property *prop, const char *value);
> >  
> 
> As this function is very easy to be misused, I suggest including the
> following documentation:
> 
> /**
>  * register_compat_prop:
>  *
>  * Register internal (not user-provided) global property, changing the
>  * default value of a given property in a device type.  This can be used
>  * for enabling machine-type compatibility or for enabling
>  * accelerator-specific defaults in devices.
>  *
>  * The property values set using this function must be always valid and
>  * never report setter errors, as they property have
>  * GlobalProperty::errp set to &error_abort.
>  *
>  * User-provided global properties should override internal global
>  * properties, so callers of this function should ensure that it is
>  * called before user-provided global properties are registered.
>  *
>  * @driver: Device type to be affected
>  * @property: Property whose default value is going to be changed
>  * @value: New default value for the property
>  */

Sure. Will take it directly. Thanks!

> 
> > +void register_compat_prop(const char *driver, const char *property,
> > +  const char *value);
> > +
> >  /**
> >   * qdev_property_add_static:
> >   * @dev: Device to add the property to.
> > -- 
> > 2.7.4
> > 
> > 
> 
> -- 
> Eduardo

-- 
Peter Xu



Re: [Qemu-devel] [PATCH v5 03/10] vl: clean up global property registerations

2017-06-25 Thread Peter Xu
On Fri, Jun 23, 2017 at 06:35:29PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 23, 2017 at 12:46:39PM +0800, Peter Xu wrote:
> > It's not that clear on how the global properties are registered to
> > global_props (and also its priority relationship). Let's provide a
> > single function to be called in main() for that, with comment to explain
> > it a bit.
> > 
> > Signed-off-by: Peter Xu 
> > ---
> >  vl.c | 29 -
> >  1 file changed, 24 insertions(+), 5 deletions(-)
> > 
> > diff --git a/vl.c b/vl.c
> > index 4452d7a..cdd2ec8 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -2969,6 +2969,25 @@ static int qemu_read_default_config_file(void)
> >  return 0;
> >  }
> >  
> > +static void user_register_compat_props(void)
> > +{
> > +qemu_opts_foreach(qemu_find_opts("global"),
> > +  global_init_func, NULL, NULL);
> 
> I suggest using "compat props" only when referring to global properties
> registered for internal use (because they help us ensure command-line
> compatibility).  User-provided global properties are just "global
> properties", not "compat props".

Agree. Fixing up. Thanks,

-- 
Peter Xu



Re: [Qemu-devel] [PATCH v5 02/10] accel: introduce AccelClass.global_props

2017-06-25 Thread Peter Xu
On Fri, Jun 23, 2017 at 06:31:27PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 23, 2017 at 12:46:38PM +0800, Peter Xu wrote:
> > Introduce this new field for the accelerator classes so that each
> > specific accelerator in the future can register its own global
> > properties to be used further by the system. It works just like how the
> > old machine compatible properties do, but only tailored for
> > accelerators.
> > 
> > Introduce register_compat_props_array() for it. Export it so that it may
> > be used in other codes as well in the future.
> > 
> > Suggested-by: Eduardo Habkost 
> > Signed-off-by: Peter Xu 
> > ---
> >  accel/accel.c|  6 ++
> >  hw/core/qdev-properties.c|  7 +++
> >  include/hw/qdev-properties.h |  1 +
> >  include/sysemu/accel.h   | 10 ++
> >  vl.c |  1 +
> >  5 files changed, 25 insertions(+)
> > 
> > diff --git a/accel/accel.c b/accel/accel.c
> > index 7c079a5..fa85844 100644
> > --- a/accel/accel.c
> > +++ b/accel/accel.c
> > @@ -120,6 +120,12 @@ void configure_accelerator(MachineState *ms)
> >  }
> >  }
> >  
> > +void accel_register_compat_props(AccelState *accel)
> > +{
> > +AccelClass *class = ACCEL_GET_CLASS(accel);
> > +register_compat_props_array(class->global_props);
> > +}
> > +
> >  static void register_accel_types(void)
> >  {
> >  type_register_static(&accel_type);
> > diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> > index 6ff1ac3..19fa335 100644
> > --- a/hw/core/qdev-properties.c
> > +++ b/hw/core/qdev-properties.c
> > @@ -1060,6 +1060,13 @@ void register_compat_prop(const char *driver,
> >  qdev_prop_register_global(p);
> >  }
> >  
> > +void register_compat_props_array(GlobalProperty *prop)
> 
> Note for a later: we need to stop reusing struct GlobalProperty here,
> because the 'user_provided', 'used', and 'errp' fields are ignored by
> register_compat_prop(), but people may believe the are not.
> 
> I suggest defining:
> 
>   struct GlobalPropertyValue {
>   const char *driver, *property, *value;
>   };
> 
> and use it instead of GlobalProperty for MachineClass::compat_props,
> AccelClass::global_props, and register_compat_prop().

Yeah maybe another definition would be nicer.

Do you mind I skip this change in this series? After all it can be
done on top, and can be separated from current work.

> 
> > +{
> > +for (; prop && prop->driver; prop++) {
> > +register_compat_prop(prop->driver, prop->property, prop->value);
> > +}
> > +}
> > +
> >  void qdev_prop_register_global_list(GlobalProperty *props)
> >  {
> >  int i;
> > diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
> > index 1722ca4..2bac6a0 100644
> > --- a/include/hw/qdev-properties.h
> > +++ b/include/hw/qdev-properties.h
> > @@ -203,6 +203,7 @@ void error_set_from_qdev_prop_error(Error **errp, int 
> > ret, DeviceState *dev,
> >  
> >  void register_compat_prop(const char *driver, const char *property,
> >const char *value);
> 
> I suggest documenting here that this function will call
> register_compat_prop(), so it will register internal (not user-provided)
> global properties.

Will do.

> 
> > +void register_compat_props_array(GlobalProperty *prop);
> >  
> >  /**
> >   * qdev_property_add_static:
> > diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
> > index 15944c1..effcd7f 100644
> > --- a/include/sysemu/accel.h
> > +++ b/include/sysemu/accel.h
> > @@ -24,6 +24,7 @@
> >  #define HW_ACCEL_H
> >  
> >  #include "qom/object.h"
> > +#include "hw/qdev-properties.h"
> >  
> >  typedef struct AccelState {
> >  /*< private >*/
> > @@ -40,6 +41,13 @@ typedef struct AccelClass {
> >  int (*available)(void);
> >  int (*init_machine)(MachineState *ms);
> >  bool *allowed;
> > +/*
> > + * Array of global properties that would be applied when specific
> > + * accelerator is chosen. It works just like
> > + * MachineClass.compat_props but it's for accelerators not
> > + * machines.
> 
> I suggest adding this:
> 
> "Accelerator-provided global properties may be overridden by
> machine-type compat_props or user-provided global properties."

Will do.

Thanks,

-- 
Peter Xu



[Qemu-devel] [Bug 1700380] Re: commit snapshot image got Permission denied error

2017-06-25 Thread jiangyd
only the winxp guest image get this error, linux guest do not.

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

Title:
  commit snapshot image got Permission denied error

Status in QEMU:
  New

Bug description:
  qemu 2.9.0, adm64, start image with -snapshot param, make some changes
  in the image, then:

  $telnet localhost 7000

  (qemu) commit virtio0
  'commit' error for 'virtio0': Permission denied

  Nerver met this problem before, commit is ok. I recently compiled
  v2.9.0, so is there some new param in qemu-qemu-system-x86_64 to avoid
  commit Permission denied?

  Regards.

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



Re: [Qemu-devel] [PATCH v5 04/10] migration: let MigrationState be a qdev

2017-06-25 Thread Peter Xu
On Fri, Jun 23, 2017 at 07:18:19PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 23, 2017 at 12:46:40PM +0800, Peter Xu wrote:
> > Let the old man "MigrationState" join the object family. Direct benefit
> > is that we can start to use all the property features derived from
> > current QDev, like: HW_COMPAT_* bits, command line setup for migration
> > parameters (so will never need to set them up each time using HMP/QMP,
> > this is really, really attractive for test writters), etc.
> > 
> > I see no reason to disallow this happen yet. So let's start from this
> > one, to see whether it would be anything good.
> > 
> > Now we init the MigrationState struct statically in main() to make sure
> > it's initialized after global properties are applied, since we'll use
> > them during creation of the object.
> > 
> > No functional change at all.
> > 
> > Reviewed-by: Juan Quintela 
> > Signed-off-by: Peter Xu 
> > ---
> >  include/migration/misc.h |  1 +
> >  migration/migration.c| 78 
> > ++--
> >  migration/migration.h| 19 
> >  vl.c |  6 
> >  4 files changed, 81 insertions(+), 23 deletions(-)
> > 
> [...]
> > diff --git a/vl.c b/vl.c
> > index cdd2ec8..9b04ba7 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -4596,6 +4596,12 @@ int main(int argc, char **argv, char **envp)
> >   */
> >  register_global_properties(current_machine);
> >  
> > +/*
> > + * Migration object can only be created after global properties
> > + * are applied correctly.
> > + */
> > +migration_object_init();
> > +
> 
> Do we really need this? Can't be we just do:
> 
> if (!current_migration) {
> current_migration = MIGRATION_OBJ(object_new(TYPE_MIGRATION));
> }
> 
> inside migration_get_current()?

I did this change on purpose (after AccelClass.global_props is
introduced). The comment above tried to explain it but looks like it's
still not clear enough... The reason is that currently the creation of
migration object is depending on the global properties, so we need to
create the object after register_global_properties(), while the old
migrate_get_current() cannot really be sure of this ordering: it just
creates the object on the first call of the function, but the first
call can be even before register_global_properties(). If so, we'll
have a problem (e.g. Xen compat properties will be missing).

Now this restriction is strictly followed if we create the migrate
object here. If anyone calls migrate_get_current() before
register_global_properties(), there will be an assert, and that should
be treated as a programming error.

Thanks,

-- 
Peter Xu



Re: [Qemu-devel] BUG: KASAN: use-after-free in free_old_xmit_skbs

2017-06-25 Thread Jason Wang



On 2017年06月24日 06:32, Cong Wang wrote:

On Fri, Jun 23, 2017 at 1:43 AM, Jason Wang  wrote:


On 2017年06月23日 02:53, Michael S. Tsirkin wrote:

On Thu, Jun 22, 2017 at 08:15:58AM +0200, jean-philippe menil wrote:

Hi Michael,

from what i see, the race appear when we hit virtnet_reset in
virtnet_xdp_set.
virtnet_reset
_remove_vq_common
  virtnet_del_vqs
virtnet_free_queues
  kfree(vi->sq)
when the xdp program (with two instances of the program to trigger it
faster)
is added or removed.

It's easily repeatable, with 2 cpus and 4 queues on the qemu command
line,
running the xdp_ttl tool from Jesper.

For now, i'm able to continue my qualification, testing if xdp_qp is not
null,
but do not seem to be a sustainable trick.
if (xdp_qp && vi->xdp_queues_pairs != xdp_qp)

Maybe it will be more clear to you with theses informations.

Best regards.

Jean-Philippe


I'm pretty clear about the issue here, I was trying to figure out a fix.
Jason, any thoughts?



Hi Jean:

Does the following fix this issue? (I can't reproduce it locally through
xdp_ttl)

It is tricky here.

 From my understanding of the code base, the tx_lock is not sufficient
here, because in virtnet_del_vqs() all vqs are deleted and one vp
maps to one txq.

I am afraid you have to add a spinlock somewhere to serialized
free_old_xmit_skbs() vs. vring_del_virtqueue(). As you can see
they are in different layers, so it is hard to figure out where to add
it...

Also, make sure we don't sleep inside the spinlock, I see a
synchronize_net().


Looks like I miss something. I thought free_old_xmit_skbs() were 
serialized in this case since we disable all tx queues after 
netif_tx_unlock_bh()?


Jean:

I thought this could be easily reproduced by e.g produce some traffic 
and in the same time try to attach an xdp program. But looks not. How do 
you trigger this? What's your qemu command line for this?


Thanks



Re: [Qemu-devel] [PATCH v5 05/10] migration: move global_state.optional out

2017-06-25 Thread Peter Xu
On Fri, Jun 23, 2017 at 07:19:01PM -0300, Eduardo Habkost wrote:
> On Fri, Jun 23, 2017 at 12:46:41PM +0800, Peter Xu wrote:
> > Put it into MigrationState then we can use the properties to specify
> > whether to enable storing global state.
> > 
> > Removing global_state_set_optional() since now we can use HW_COMPAT_2_3
> > for x86/power, and AccelClass.global_props for Xen.
> > 
> > Reviewed-by: Juan Quintela 
> > Signed-off-by: Peter Xu 
> > ---
> >  hw/i386/pc_piix.c|  1 -
> >  hw/ppc/spapr.c   |  1 -
> >  hw/xen/xen-common.c  | 11 ++-
> >  include/hw/compat.h  |  4 
> >  include/migration/global_state.h |  1 -
> >  migration/global_state.c |  9 ++---
> >  migration/migration.c|  7 +++
> >  migration/migration.h|  6 ++
> >  8 files changed, 29 insertions(+), 11 deletions(-)
> > 
> [...]
> > diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c
> > index d3fa705..9163a0a 100644
> > --- a/hw/xen/xen-common.c
> > +++ b/hw/xen/xen-common.c
> > @@ -139,19 +139,28 @@ static int xen_init(MachineState *ms)
> >  }
> >  qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
> >  
> > -global_state_set_optional();
> >  savevm_skip_configuration();
> >  savevm_skip_section_footers();
> >  
> >  return 0;
> >  }
> >  
> > +GlobalProperty xen_compat_props[] = {
> 
> This can be static.

Yep.

> 
> > +{
> > +.driver = "migration",
> > +.property = "store-global-state",
> > +.value = "off",
> > +},
> > +{ .driver = NULL, .property = NULL, .value = NULL },
> 
> Normally this is written as:
> 
>{ /* end of list */ },

Let me switch.

> 
> > +};
> > +
> [...]
> 
> I didn't review the rest yet, but it seems to be good.

Thanks!

-- 
Peter Xu



[Qemu-devel] [Bug 1700380] Re: commit snapshot image got Permission denied error

2017-06-25 Thread jiangyd
v2.9.0 must start the image with full path can commit the snapshot
changes, https://bugs.launchpad.net/bugs/1700380

Title:
  commit snapshot image got Permission denied error

Status in QEMU:
  New

Bug description:
  qemu 2.9.0, adm64, start image with -snapshot param, make some changes
  in the image, then:

  $telnet localhost 7000

  (qemu) commit virtio0
  'commit' error for 'virtio0': Permission denied

  Nerver met this problem before, commit is ok. I recently compiled
  v2.9.0, so is there some new param in qemu-qemu-system-x86_64 to avoid
  commit Permission denied?

  Regards.

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



Re: [Qemu-devel] [PATCH v3 1/2] virtio-net: enable configurable tx queue size

2017-06-25 Thread Jason Wang



On 2017年06月23日 10:32, Wei Wang wrote:

This patch enables the virtio-net tx queue size to be configurable
between 256 (the default queue size) and 1024 by the user when the
vhost-user backend is used.

Currently, the maximum tx queue size for other backends is 512 due
to the following limitations:
- QEMU backend: the QEMU backend implementation in some cases may
send 1024+1 iovs to writev.
- Vhost_net backend: there are possibilities that the guest sends
a vring_desc of memory which corsses a MemoryRegion thereby
generating more than 1024 iovs after translattion from guest-physical
address in the backend.

Signed-off-by: Wei Wang 
---
  hw/net/virtio-net.c| 45 +-
  include/hw/virtio/virtio-net.h |  1 +
  2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 91eddaf..d13ca60 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -34,8 +34,11 @@
  
  /* previously fixed value */

  #define VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE 256
+#define VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE 256
+
  /* for now, only allow larger queues; with virtio-1, guest can downsize */
  #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
+#define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
  
  /*

   * Calculate the number of bytes up to and including the given 'field' of
@@ -1508,15 +1511,18 @@ static void virtio_net_add_queue(VirtIONet *n, int 
index)
  
  n->vqs[index].rx_vq = virtio_add_queue(vdev, n->net_conf.rx_queue_size,

 virtio_net_handle_rx);
+


Unnecessary whitespace change.


  if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
  n->vqs[index].tx_vq =
-virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
+virtio_add_queue(vdev, n->net_conf.tx_queue_size,
+ virtio_net_handle_tx_timer);
  n->vqs[index].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
virtio_net_tx_timer,
&n->vqs[index]);
  } else {
  n->vqs[index].tx_vq =
-virtio_add_queue(vdev, 256, virtio_net_handle_tx_bh);
+virtio_add_queue(vdev, n->net_conf.tx_queue_size,
+ virtio_net_handle_tx_bh);
  n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[index]);
  }
  
@@ -1927,6 +1933,17 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)

  return;
  }
  
+if (n->net_conf.tx_queue_size < VIRTIO_NET_TX_QUEUE_MIN_SIZE ||

+n->net_conf.tx_queue_size > VIRTQUEUE_MAX_SIZE ||
+!is_power_of_2(n->net_conf.tx_queue_size)) {
+error_setg(errp, "Invalid tx_queue_size (= %" PRIu16 "), "
+   "must be a power of 2 between %d and %d",
+   n->net_conf.tx_queue_size, VIRTIO_NET_TX_QUEUE_MIN_SIZE,
+   VIRTQUEUE_MAX_SIZE);
+virtio_cleanup(vdev);
+return;
+}
+
  n->max_queues = MAX(n->nic_conf.peers.queues, 1);
  if (n->max_queues * 2 + 1 > VIRTIO_QUEUE_MAX) {
  error_setg(errp, "Invalid number of queues (= %" PRIu32 "), "
@@ -1947,17 +1964,11 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
  error_report("Defaulting to \"bh\"");
  }
  
-for (i = 0; i < n->max_queues; i++) {

-virtio_net_add_queue(n, i);
-}
-
-n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
  qemu_macaddr_default_if_unset(&n->nic_conf.macaddr);
  memcpy(&n->mac[0], &n->nic_conf.macaddr, sizeof(n->mac));
  n->status = VIRTIO_NET_S_LINK_UP;
  n->announce_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
   virtio_net_announce_timer, n);
-


Unnecessary whitespace change.


  if (n->netclient_type) {
  /*
   * Happen when virtio_net_set_netclient_name has been called.
@@ -1968,6 +1979,21 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
  n->nic = qemu_new_nic(&net_virtio_info, &n->nic_conf,
object_get_typename(OBJECT(dev)), dev->id, n);
  }
+nc = qemu_get_queue(n->nic);
+
+/*
+ * Currently, backends other than vhost-user don't support 1024 queue
+ * size.
+ */
+if (n->net_conf.tx_queue_size == VIRTQUEUE_MAX_SIZE &&
+nc->peer->info->type != NET_CLIENT_DRIVER_VHOST_USER) {
+n->net_conf.tx_queue_size = VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE;


Do we really want assume all vhost-user backend support 1024 queue size?


+}
+
+for (i = 0; i < n->max_queues; i++) {
+virtio_net_add_queue(n, i);
+}


Any reason to move virtio_net_add_queue() here?


+n->ctrl_vq = virtio_add_queue(vdev, 64, virtio_net_handle_ctrl);
  
  peer_test_vnet_hdr(n);

  if (peer_has_vnet_hdr(n)) {
@@ -1990

Re: [Qemu-devel] glue(glue(ld, USUFFIX), _p)

2017-06-25 Thread Philippe Mathieu-Daudé
Hi Theodore,

> In include/exec/cpu_ldst_useronly_template.h, there’s references to 
> glue(glue(ld, USUFFIX), _p), which would expand to a call to a function 
> looking something like uint32_t lduw_p(void *) (for example). Where is this 
> function defined?

You might be looking for the glue address_space_lduw_internal() at
line 251 of memory_ldst.inc.c:

https://github.com/qemu/qemu/blob/master/memory_ldst.inc.c#L251

Regards,

Phil.



Re: [Qemu-devel] [RFC PATCH 1/2] arm/highbank: use defined type name instead of hard-coded string

2017-06-25 Thread Philippe Mathieu-Daudé
On Fri, Jun 23, 2017 at 7:18 PM, John Snow  wrote:
> This patch is fine, I took a stab at fixing the include issues in a
> separate series. Try it all out and let me know.

Thank John, your series does fix my include issues :)



Re: [Qemu-devel] [PATCH 2/3] ahci: Isolate public AHCI interface

2017-06-25 Thread Philippe Mathieu-Daudé
On Fri, Jun 23, 2017 at 7:09 PM, John Snow  wrote:
> Begin separating the public/private interface by removing the minimum
> set of information used by code outside of hw/ide/ and calling this
> a new ahci_public.h file, which will be renamed to ahci.h in a future
> patch.
>
> Signed-off-by: John Snow 

Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 

> ---
>  include/hw/ide/ahci.h| 57 +++
>  include/hw/ide/ahci_public.h | 91 
> 
>  2 files changed, 96 insertions(+), 52 deletions(-)
>  create mode 100644 include/hw/ide/ahci_public.h
>
> diff --git a/include/hw/ide/ahci.h b/include/hw/ide/ahci.h
> index f866bbf..70a0140 100644
> --- a/include/hw/ide/ahci.h
> +++ b/include/hw/ide/ahci.h
> @@ -21,9 +21,10 @@
>   *
>   */
>
> -#ifndef HW_IDE_AHCI_H
> -#define HW_IDE_AHCI_H
> +#ifndef HW_IDE_AHCI_INTERNAL_H
> +#define HW_IDE_AHCI_INTERNAL_H
>
> +#include "hw/ide/ahci_public.h"
>  #include "hw/sysbus.h"
>
>  #define AHCI_MEM_BAR_SIZE 0x1000
> @@ -210,14 +211,6 @@
>  #define SATA_CAP_REV0x2
>  #define SATA_CAP_BAR0x4
>
> -typedef struct AHCIControlRegs {
> -uint32_tcap;
> -uint32_tghc;
> -uint32_tirqstatus;
> -uint32_timpl;
> -uint32_tversion;
> -} AHCIControlRegs;
> -
>  typedef struct AHCIPortRegs {
>  uint32_tlst_addr;
>  uint32_tlst_addr_hi;
> @@ -251,8 +244,6 @@ typedef struct AHCI_SG {
>  uint32_tflags_size;
>  } QEMU_PACKED AHCI_SG;
>
> -typedef struct AHCIDevice AHCIDevice;
> -
>  typedef struct NCQTransferState {
>  AHCIDevice *drive;
>  BlockAIOCB *aiocb;
> @@ -286,27 +277,13 @@ struct AHCIDevice {
>  NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
>  };
>
> -typedef struct AHCIState {
> -DeviceState *container;
> -
> -AHCIDevice *dev;
> -AHCIControlRegs control_regs;
> -MemoryRegion mem;
> -MemoryRegion idp;   /* Index-Data Pair I/O port space */
> -unsigned idp_offset;/* Offset of index in I/O port space */
> -uint32_t idp_index; /* Current IDP index */
> -int32_t ports;
> -qemu_irq irq;
> -AddressSpace *as;
> -} AHCIState;
> -
> -typedef struct AHCIPCIState {
> +struct AHCIPCIState {
>  /*< private >*/
>  PCIDevice parent_obj;
>  /*< public >*/
>
>  AHCIState ahci;
> -} AHCIPCIState;
> +};
>
>  #define TYPE_ICH9_AHCI "ich9-ahci"
>
> @@ -372,35 +349,11 @@ void ahci_uninit(AHCIState *s);
>
>  void ahci_reset(AHCIState *s);
>
> -int32_t ahci_get_num_ports(PCIDevice *dev);
> -void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd);
> -
>  #define TYPE_SYSBUS_AHCI "sysbus-ahci"
>  #define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj), 
> TYPE_SYSBUS_AHCI)
>
> -typedef struct SysbusAHCIState {
> -/*< private >*/
> -SysBusDevice parent_obj;
> -/*< public >*/
> -
> -AHCIState ahci;
> -uint32_t num_ports;
> -} SysbusAHCIState;
> -
>  #define TYPE_ALLWINNER_AHCI "allwinner-ahci"
>  #define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \
> TYPE_ALLWINNER_AHCI)
>
> -#define ALLWINNER_AHCI_MMIO_OFF  0x80
> -#define ALLWINNER_AHCI_MMIO_SIZE 0x80
> -
> -struct AllwinnerAHCIState {
> -/*< private >*/
> -SysbusAHCIState parent_obj;
> -/*< public >*/
> -
> -MemoryRegion mmio;
> -uint32_t regs[ALLWINNER_AHCI_MMIO_SIZE/4];
> -};
> -
>  #endif /* HW_IDE_AHCI_H */
> diff --git a/include/hw/ide/ahci_public.h b/include/hw/ide/ahci_public.h
> new file mode 100644
> index 000..5a06537
> --- /dev/null
> +++ b/include/hw/ide/ahci_public.h
> @@ -0,0 +1,91 @@
> +/*
> + * QEMU AHCI Emulation
> + *
> + * Copyright (c) 2010 qiaoch...@loongson.cn
> + * Copyright (c) 2010 Roland Elek 
> + * Copyright (c) 2010 Sebastian Herbszt 
> + * Copyright (c) 2010 Alexander Graf 
> + *
> + * 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 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 
> .
> + *
> + */
> +
> +#ifndef HW_IDE_AHCI_H
> +#define HW_IDE_AHCI_H
> +
> +#include "hw/sysbus.h"
> +
> +typedef struct AHCIDevice AHCIDevice;
> +
> +typedef struct AHCIControlRegs {
> +uint32_tcap;
> +uint32_tghc;
> +uint32_tirqstatus;
> +uint32_timpl;
> +uint32_tversion;
> +} AHCIControlRegs;
> +
> +typedef struct AHCIState {
> +DeviceState *container;
> +
> +AHCIDevice *d

Re: [Qemu-devel] [PATCH 3/3] ahci: split public and private interface

2017-06-25 Thread Philippe Mathieu-Daudé
On Fri, Jun 23, 2017 at 7:09 PM, John Snow  wrote:
> Complete the split by renaming ahci_public.h --> ahci.h and
> moving the current ahci.h to hw/ide/ahci_internal.h.
>
> Adjust ahci_internal.h to now load ahci.h instead of ahci_public.h.
>
> Finalize the split by switching external users to the new header.
>
> Signed-off-by: John Snow 

Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 

> ---
>  hw/ide/ahci.c|   2 +-
>  hw/ide/ahci_internal.h   | 359 +
>  hw/ide/ich.c |   2 +-
>  include/hw/ide/ahci.h| 368 
> ++-
>  include/hw/ide/ahci_public.h |  91 ---
>  5 files changed, 411 insertions(+), 411 deletions(-)
>  create mode 100644 hw/ide/ahci_internal.h
>  delete mode 100644 include/hw/ide/ahci_public.h
>
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 1ab3245..fdb1b11 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -32,7 +32,7 @@
>  #include "sysemu/dma.h"
>  #include "hw/ide/internal.h"
>  #include "hw/ide/pci.h"
> -#include "hw/ide/ahci.h"
> +#include "hw/ide/ahci_internal.h"
>
>  #define DEBUG_AHCI 0
>
> diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h
> new file mode 100644
> index 000..1e21169
> --- /dev/null
> +++ b/hw/ide/ahci_internal.h
> @@ -0,0 +1,359 @@
> +/*
> + * QEMU AHCI Emulation
> + *
> + * Copyright (c) 2010 qiaoch...@loongson.cn
> + * Copyright (c) 2010 Roland Elek 
> + * Copyright (c) 2010 Sebastian Herbszt 
> + * Copyright (c) 2010 Alexander Graf 
> + *
> + * 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 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 
> .
> + *
> + */
> +
> +#ifndef HW_IDE_AHCI_INTERNAL_H
> +#define HW_IDE_AHCI_INTERNAL_H
> +
> +#include "hw/ide/ahci.h"
> +#include "hw/sysbus.h"
> +
> +#define AHCI_MEM_BAR_SIZE 0x1000
> +#define AHCI_MAX_PORTS32
> +#define AHCI_MAX_SG   168 /* hardware max is 64K */
> +#define AHCI_DMA_BOUNDARY 0x
> +#define AHCI_USE_CLUSTERING   0
> +#define AHCI_MAX_CMDS 32
> +#define AHCI_CMD_SZ   32
> +#define AHCI_CMD_SLOT_SZ  (AHCI_MAX_CMDS * AHCI_CMD_SZ)
> +#define AHCI_RX_FIS_SZ256
> +#define AHCI_CMD_TBL_CDB  0x40
> +#define AHCI_CMD_TBL_HDR_SZ   0x80
> +#define AHCI_CMD_TBL_SZ   (AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16))
> +#define AHCI_CMD_TBL_AR_SZ(AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS)
> +#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + \
> +   AHCI_RX_FIS_SZ)
> +
> +#define AHCI_IRQ_ON_SG(1U << 31)
> +#define AHCI_CMD_ATAPI(1 << 5)
> +#define AHCI_CMD_WRITE(1 << 6)
> +#define AHCI_CMD_PREFETCH (1 << 7)
> +#define AHCI_CMD_RESET(1 << 8)
> +#define AHCI_CMD_CLR_BUSY (1 << 10)
> +
> +#define RX_FIS_D2H_REG0x40 /* offset of D2H Register FIS data */
> +#define RX_FIS_SDB0x58 /* offset of SDB FIS data */
> +#define RX_FIS_UNK0x60 /* offset of Unknown FIS data */
> +
> +/* global controller registers */
> +#define HOST_CAP  0x00 /* host capabilities */
> +#define HOST_CTL  0x04 /* global host control */
> +#define HOST_IRQ_STAT 0x08 /* interrupt status */
> +#define HOST_PORTS_IMPL   0x0c /* bitmap of implemented ports */
> +#define HOST_VERSION  0x10 /* AHCI spec. version compliancy */
> +
> +/* HOST_CTL bits */
> +#define HOST_CTL_RESET(1 << 0)  /* reset controller; self-clear 
> */
> +#define HOST_CTL_IRQ_EN   (1 << 1)  /* global IRQ enable */
> +#define HOST_CTL_AHCI_EN  (1U << 31) /* AHCI enabled */
> +
> +/* HOST_CAP bits */
> +#define HOST_CAP_SSC  (1 << 14) /* Slumber capable */
> +#define HOST_CAP_AHCI (1 << 18) /* AHCI only */
> +#define HOST_CAP_CLO  (1 << 24) /* Command List Override support 
> */
> +#define HOST_CAP_SSS  (1 << 27) /* Staggered Spin-up */
> +#define HOST_CAP_NCQ  (1 << 30) /* Native Command Queueing */
> +#define HOST_CAP_64   (1U << 31) /* PCI DAC (64-bit DMA) support 
> */
> +
> +/* registers for each SATA port */
> +#define PORT_LST_ADDR 0x00 /* command list DMA addr */
> +#define PORT_LST_A

Re: [Qemu-devel] [PATCH 1/3] ahci: add ahci_get_num_ports

2017-06-25 Thread Philippe Mathieu-Daudé
On Fri, Jun 23, 2017 at 7:09 PM, John Snow  wrote:
> Instead of reaching into the PCI state, allow the AHCIDevice to
> respond with how many ports it has.
>
> Signed-off-by: John Snow 

Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 

> ---
>  hw/i386/pc_q35.c  | 4 ++--
>  hw/ide/ahci.c | 8 
>  hw/mips/boston.c  | 4 ++--
>  include/hw/ide/ahci.h | 1 +
>  4 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index 1523ef3..8715514 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -241,8 +241,8 @@ static void pc_q35_init(MachineState *machine)
> true, "ich9-ahci");
>  idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0");
>  idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1");
> -g_assert(MAX_SATA_PORTS == ICH_AHCI(ahci)->ahci.ports);
> -ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
> +g_assert(MAX_SATA_PORTS == ahci_get_num_ports(ahci));
> +ide_drive_get(hd, ahci_get_num_ports(ahci));
>  ahci_ide_create_devs(ahci, hd);
>  } else {
>  idebus[0] = idebus[1] = NULL;
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index f60826d..1ab3245 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1833,6 +1833,14 @@ static void sysbus_ahci_register_types(void)
>
>  type_init(sysbus_ahci_register_types)
>
> +int32_t ahci_get_num_ports(PCIDevice *dev)
> +{
> +AHCIPCIState *d = ICH_AHCI(dev);
> +AHCIState *ahci = &d->ahci;
> +
> +return ahci->ports;
> +}
> +
>  void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd)
>  {
>  AHCIPCIState *d = ICH_AHCI(dev);
> diff --git a/hw/mips/boston.c b/hw/mips/boston.c
> index a4677f7..ad59404 100644
> --- a/hw/mips/boston.c
> +++ b/hw/mips/boston.c
> @@ -538,8 +538,8 @@ static void boston_mach_init(MachineState *machine)
>  ahci = 
> pci_create_simple_multifunction(&PCI_BRIDGE(&pcie2->root)->sec_bus,
> PCI_DEVFN(0, 0),
> true, TYPE_ICH9_AHCI);
> -g_assert(ARRAY_SIZE(hd) == ICH_AHCI(ahci)->ahci.ports);
> -ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
> +g_assert(ARRAY_SIZE(hd) == ahci_get_num_ports(ahci));
> +ide_drive_get(hd, ahci_get_num_ports(ahci));
>  ahci_ide_create_devs(ahci, hd);
>
>  if (machine->firmware) {
> diff --git a/include/hw/ide/ahci.h b/include/hw/ide/ahci.h
> index 0ca7c65..f866bbf 100644
> --- a/include/hw/ide/ahci.h
> +++ b/include/hw/ide/ahci.h
> @@ -372,6 +372,7 @@ void ahci_uninit(AHCIState *s);
>
>  void ahci_reset(AHCIState *s);
>
> +int32_t ahci_get_num_ports(PCIDevice *dev);
>  void ahci_ide_create_devs(PCIDevice *dev, DriveInfo **hd);
>
>  #define TYPE_SYSBUS_AHCI "sysbus-ahci"
> --
> 2.9.4
>



Re: [Qemu-devel] [PATCH v5 3/6] target-m68k: use floatx80 internally

2017-06-25 Thread Philippe Mathieu-Daudé
On Wed, Jun 21, 2017 at 1:37 PM, Richard Henderson  wrote:
> On 06/21/2017 09:18 AM, Philippe Mathieu-Daudé wrote:
>> What an awful name... Anyway checking on "qemu/bswap.h" it seems there is
>> some endianess issue with it if your host is little-endian.
>
>
> There is no endian-ness issue because we do not attempt to read that
> structure from memory as a whole.  Instead, Laurent uses two big-endian
> loads (with appropriate address arithmetic) and stores the result into this
> host structure in host-endian order.  Further, the host routines use the
> structure members by name and do not assume any particular relationship
> between them.

Ok, thank your Richard for this clear explanation.
("Endian-ness" ok, Peter also corrected me, I'll give a try to some speller...)

>
>> Do you have a way to run Berkeley TestFloat?
>
>
> As noted in Laurent's cover message, floatx80 isn't quite right -- that is
> the x86 data type, and the proper m68k data type is slightly different.
>
> I would expect the results from using floatx80 to be Just Good Enough to
> produce a working m68k user-land.  It will produce correct results for
> normal numbers in arithmetic such as 1.0 + 10.0.  But I would expect many of
> the edge conditions that TestFloat would attempt (especially de-normals and
> un-normals) would fail.

Ok. I'm asking thinking about cross unit-tests I can add to our
continuous integration system, this might be a candidate.

Regards,

Phil.



Re: [Qemu-devel] [PATCH v3 1/2] virtio-net: enable configurable tx queue size

2017-06-25 Thread Wei Wang

On 06/26/2017 11:18 AM, Jason Wang wrote:


On 2017年06月23日 10:32, Wei Wang wrote:

This patch enables the virtio-net tx queue size to be configurable
between 256 (the default queue size) and 1024 by the user when the
vhost-user backend is used.

Currently, the maximum tx queue size for other backends is 512 due
to the following limitations:
- QEMU backend: the QEMU backend implementation in some cases may
send 1024+1 iovs to writev.
- Vhost_net backend: there are possibilities that the guest sends
a vring_desc of memory which corsses a MemoryRegion thereby
generating more than 1024 iovs after translattion from guest-physical
address in the backend.

Signed-off-by: Wei Wang 
---
  hw/net/virtio-net.c| 45 
+-

  include/hw/virtio/virtio-net.h |  1 +
  2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 91eddaf..d13ca60 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -34,8 +34,11 @@
/* previously fixed value */
  #define VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE 256
+
+/*
+ * Currently, backends other than vhost-user don't support 1024 
queue

+ * size.
+ */
+if (n->net_conf.tx_queue_size == VIRTQUEUE_MAX_SIZE &&
+nc->peer->info->type != NET_CLIENT_DRIVER_VHOST_USER) {
+n->net_conf.tx_queue_size = VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE;


Do we really want assume all vhost-user backend support 1024 queue size?



 Do you know any vhost-user backend implementation that doesn't support
1024 tx queue size?




+}
+
+for (i = 0; i < n->max_queues; i++) {
+virtio_net_add_queue(n, i);
+}


Any reason to move virtio_net_add_queue() here?



Please check the whole init steps.  It was moved here (after qemu_new_nic())
to make sure nc->peer is not NULL.

Best,
Wei



Re: [Qemu-devel] [RFC PATCH 0/4] travis: run all coccinelle scripts

2017-06-25 Thread Philippe Mathieu-Daudé
> Patch 4 is the travis job: it calls the previous script. To respect travis 
> time
> limit timeout, each script is limited to <10min. If any commit were
> generated, they are pushed to my gh-repo

Initially I wanted to use git format-patch/send-email to send to the
list as a series but it seems too verbose and Travis doesn't seem to
allow to send mails. Another possibility is to send to a S3 bucket or
gh-page. The push-to-repo way involves deploy ssh key but is easier to
manage with regular git commands, I can fetch this repo and
cherry-pick/rework/amend commits.

I also plan to add Marc-André Lureau clang-tidy work:
http://lists.nongnu.org/archive/html/qemu-devel/2017-06/msg05034.html



[Qemu-devel] [PATCH v4 2/7] Move CONFIG_KVM related definitions to kvm_i386.h

2017-06-25 Thread Thomas Huth
pc.h and sysemu/kvm.h are also included from common code (where
CONFIG_KVM is not available), so the #defines that depend on CONFIG_KVM
should not be declared here to avoid that anybody is using them in a
wrong way. Since we're also going to poison CONFIG_KVM for common code,
let's move them to kvm_i386.h instead. Most of the dummy definitions
from sysemu/kvm.h are also unused since the code that uses them is
only compiled for CONFIG_KVM (e.g. target/i386/kvm.c), so the unused
defines are also simply dropped here instead of being moved.

Signed-off-by: Thomas Huth 
---
 hw/i386/pc_q35.c   |  1 +
 include/hw/i386/pc.h   | 13 -
 include/sysemu/kvm.h   | 15 ---
 target/i386/kvm_i386.h | 23 +++
 4 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 1523ef3..8f696b7 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -36,6 +36,7 @@
 #include "hw/timer/mc146818rtc.h"
 #include "hw/xen/xen.h"
 #include "sysemu/kvm.h"
+#include "kvm_i386.h"
 #include "hw/kvm/clock.h"
 #include "hw/pci-host/q35.h"
 #include "exec/address-spaces.h"
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 233216a..f48d167 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -20,19 +20,6 @@
 
 #define HPET_INTCAP "hpet-intcap"
 
-#ifdef CONFIG_KVM
-#define kvm_pit_in_kernel() \
-(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
-#define kvm_pic_in_kernel()  \
-(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
-#define kvm_ioapic_in_kernel() \
-(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
-#else
-#define kvm_pit_in_kernel()  0
-#define kvm_pic_in_kernel()  0
-#define kvm_ioapic_in_kernel()   0
-#endif
-
 /**
  * PCMachineState:
  * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 1e91613..ca40b6e 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -22,21 +22,6 @@
 #ifdef CONFIG_KVM
 #include 
 #include 
-#else
-/* These constants must never be used at runtime if kvm_enabled() is false.
- * They exist so we don't need #ifdefs around KVM-specific code that already
- * checks kvm_enabled() properly.
- */
-#define KVM_CPUID_SIGNATURE  0
-#define KVM_CPUID_FEATURES   0
-#define KVM_FEATURE_CLOCKSOURCE  0
-#define KVM_FEATURE_NOP_IO_DELAY 0
-#define KVM_FEATURE_MMU_OP   0
-#define KVM_FEATURE_CLOCKSOURCE2 0
-#define KVM_FEATURE_ASYNC_PF 0
-#define KVM_FEATURE_STEAL_TIME   0
-#define KVM_FEATURE_PV_EOI   0
-#define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT 0
 #endif
 
 extern bool kvm_allowed;
diff --git a/target/i386/kvm_i386.h b/target/i386/kvm_i386.h
index bfce427..1de9876 100644
--- a/target/i386/kvm_i386.h
+++ b/target/i386/kvm_i386.h
@@ -15,6 +15,29 @@
 
 #define kvm_apic_in_kernel() (kvm_irqchip_in_kernel())
 
+#ifdef CONFIG_KVM
+
+#define kvm_pit_in_kernel() \
+(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#define kvm_pic_in_kernel()  \
+(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+#define kvm_ioapic_in_kernel() \
+(kvm_irqchip_in_kernel() && !kvm_irqchip_is_split())
+
+#else
+
+#define kvm_pit_in_kernel()  0
+#define kvm_pic_in_kernel()  0
+#define kvm_ioapic_in_kernel()   0
+
+/* These constants must never be used at runtime if kvm_enabled() is false.
+ * They exist so we don't need #ifdefs around KVM-specific code that already
+ * checks kvm_enabled() properly.
+ */
+#define KVM_CPUID_FEATURES   0
+
+#endif  /* CONFIG_KVM */
+
 bool kvm_allows_irq0_override(void);
 bool kvm_has_smm(void);
 bool kvm_has_adjust_clock_stable(void);
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 5/7] include/exec/poison: Mark CONFIG_SOFTMMU as poisoned

2017-06-25 Thread Thomas Huth
CONFIG_SOFTMMU should never be used in common code, so mark
it as poisoned, too.

Reviewed-by: Richard Henderson 
Signed-off-by: Thomas Huth 
---
 include/exec/poison.h | 1 +
 include/qom/cpu.h | 8 
 2 files changed, 9 insertions(+)

diff --git a/include/exec/poison.h b/include/exec/poison.h
index 32707cd..41cd2eb 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -87,6 +87,7 @@
 #pragma GCC poison CONFIG_LINUX_USER
 #pragma GCC poison CONFIG_VHOST_NET
 #pragma GCC poison CONFIG_KVM
+#pragma GCC poison CONFIG_SOFTMMU
 
 #endif
 #endif
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 89ddb68..c41e1e3 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -783,6 +783,8 @@ bool cpu_throttle_active(void);
  */
 int cpu_throttle_get_percentage(void);
 
+#ifdef NEED_CPU_H
+
 #ifndef CONFIG_USER_ONLY
 
 typedef void (*CPUInterruptHandler)(CPUState *, int);
@@ -829,6 +831,8 @@ static inline void cpu_unaligned_access(CPUState *cpu, 
vaddr addr,
 }
 #endif
 
+#endif /* NEED_CPU_H */
+
 /**
  * cpu_set_pc:
  * @cpu: The CPU to set the program counter for.
@@ -1005,6 +1009,8 @@ void cpu_exec_initfn(CPUState *cpu);
 void cpu_exec_realizefn(CPUState *cpu, Error **errp);
 void cpu_exec_unrealizefn(CPUState *cpu);
 
+#ifdef NEED_CPU_H
+
 #ifdef CONFIG_SOFTMMU
 extern const struct VMStateDescription vmstate_cpu_common;
 #else
@@ -1019,6 +1025,8 @@ extern const struct VMStateDescription vmstate_cpu_common;
 .offset = 0,\
 }
 
+#endif /* NEED_CPU_H */
+
 #define UNASSIGNED_CPU_INDEX -1
 
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 3/7] include/exec/poison: Mark CONFIG_KVM as poisoned, too

2017-06-25 Thread Thomas Huth
CONFIG_KVM is only defined for target-specific code, so nobody should
use it by accident in common code. To avoid such subtle bugs,
CONFIG_KVM is now marked as poisoned in common code. The header
include/sysemu/kvm.h is somewhat special since it is included
all over the place from common code, too, so we need some extra
logic via "#ifdef NEED_CPU_H" here to make sure that we can
compile all files without problems.

Signed-off-by: Thomas Huth 
---
 hw/acpi/ich9.c|  1 -
 include/exec/poison.h |  1 +
 include/sysemu/kvm.h  | 18 +-
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 5c279bb..c5d8646 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -33,7 +33,6 @@
 #include "sysemu/sysemu.h"
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/tco.h"
-#include "sysemu/kvm.h"
 #include "exec/address-spaces.h"
 
 #include "hw/i386/ich9.h"
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 7a025b2..32707cd 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -86,6 +86,7 @@
 
 #pragma GCC poison CONFIG_LINUX_USER
 #pragma GCC poison CONFIG_VHOST_NET
+#pragma GCC poison CONFIG_KVM
 
 #endif
 #endif
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index ca40b6e..052e11f 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -19,11 +19,18 @@
 #include "exec/memattrs.h"
 #include "hw/irq.h"
 
-#ifdef CONFIG_KVM
-#include 
-#include 
+#ifdef NEED_CPU_H
+# ifdef CONFIG_KVM
+#  include 
+#  include 
+#  define CONFIG_KVM_IS_POSSIBLE
+# endif
+#else
+# define CONFIG_KVM_IS_POSSIBLE
 #endif
 
+#ifdef CONFIG_KVM_IS_POSSIBLE
+
 extern bool kvm_allowed;
 extern bool kvm_kernel_irqchip;
 extern bool kvm_split_irqchip;
@@ -40,7 +47,6 @@ extern bool kvm_direct_msi_allowed;
 extern bool kvm_ioeventfd_any_length_allowed;
 extern bool kvm_msi_use_devid;
 
-#if defined CONFIG_KVM || !defined NEED_CPU_H
 #define kvm_enabled()   (kvm_allowed)
 /**
  * kvm_irqchip_in_kernel:
@@ -163,6 +169,7 @@ extern bool kvm_msi_use_devid;
 #define kvm_msi_devid_required() (kvm_msi_use_devid)
 
 #else
+
 #define kvm_enabled()   (0)
 #define kvm_irqchip_in_kernel() (false)
 #define kvm_irqchip_is_split() (false)
@@ -178,7 +185,8 @@ extern bool kvm_msi_use_devid;
 #define kvm_direct_msi_enabled() (false)
 #define kvm_ioeventfd_any_length_enabled() (false)
 #define kvm_msi_devid_required() (false)
-#endif
+
+#endif  /* CONFIG_KVM_IS_POSSIBLE */
 
 struct kvm_run;
 struct kvm_lapic_state;
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 1/7] include/exec/poison: Add some more missing TARGET and CONFIG defines

2017-06-25 Thread Thomas Huth
The defines of some *-linux-user targets were still missing.

Suggested-by: Richard Henderson 
Signed-off-by: Thomas Huth 
---
 include/exec/poison.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/include/exec/poison.h b/include/exec/poison.h
index 5ffed4d..7a025b2 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -7,13 +7,16 @@
 
 #pragma GCC poison TARGET_I386
 #pragma GCC poison TARGET_X86_64
+#pragma GCC poison TARGET_AARCH64
 #pragma GCC poison TARGET_ALPHA
 #pragma GCC poison TARGET_ARM
 #pragma GCC poison TARGET_CRIS
+#pragma GCC poison TARGET_HPPA
 #pragma GCC poison TARGET_LM32
 #pragma GCC poison TARGET_M68K
 #pragma GCC poison TARGET_MICROBLAZE
 #pragma GCC poison TARGET_MIPS
+#pragma GCC poison TARGET_ABI_MIPSN32
 #pragma GCC poison TARGET_ABI_MIPSO32
 #pragma GCC poison TARGET_MIPS64
 #pragma GCC poison TARGET_ABI_MIPSN64
@@ -28,10 +31,12 @@
 #pragma GCC poison TARGET_SH4
 #pragma GCC poison TARGET_SPARC
 #pragma GCC poison TARGET_SPARC64
+#pragma GCC poison TARGET_TILEGX
 #pragma GCC poison TARGET_TRICORE
 #pragma GCC poison TARGET_UNICORE32
 #pragma GCC poison TARGET_XTENSA
 
+#pragma GCC poison TARGET_HAS_BFLT
 #pragma GCC poison TARGET_NAME
 #pragma GCC poison TARGET_SUPPORTS_MTTCG
 #pragma GCC poison TARGET_WORDS_BIGENDIAN
@@ -65,6 +70,7 @@
 #pragma GCC poison CONFIG_ARM_A64_DIS
 #pragma GCC poison CONFIG_ARM_DIS
 #pragma GCC poison CONFIG_CRIS_DIS
+#pragma GCC poison CONFIG_HPPA_DIS
 #pragma GCC poison CONFIG_I386_DIS
 #pragma GCC poison CONFIG_LM32_DIS
 #pragma GCC poison CONFIG_M68K_DIS
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 0/7] Poison some more target-specific defines

2017-06-25 Thread Thomas Huth
This series marks some more #defines as poisoned, which are
target-specific (declared in config-target.h) and thus must
not be used in common code.

v4:
- Rebased to master since the v2 versions of the first two patches
  have already been merged. The diff between v2 and v3 can now be
  found in the first patch of this series.

v3:
- Mark some more TARGET_xxx and CONFIG_xxx defines as poisoned in
  the first two patches (as requested by Richard)
- Added the final patch to move the edu device to common-obj-y

v2:
- First two patches are the same as in v1
- Reworked the CONFIG_KVM patches according to Paolo's review feedback
- Added two new patches to finally poison CONFIG_SOFTMMU, too
- Added a final patch to move bootdevice.o to common-obj now
  (based on an earlier patch where I also tried to move numa.o and
  balloon.o, too - but these files are indirectly target-dependent as
  I now know, so they can't be moved)

Thomas Huth (7):
  include/exec/poison: Add some more missing TARGET and CONFIG defines
  Move CONFIG_KVM related definitions to kvm_i386.h
  include/exec/poison: Mark CONFIG_KVM as poisoned, too
  cpu: Introduce a wrapper for tlb_flush() that can be used in common
code
  include/exec/poison: Mark CONFIG_SOFTMMU as poisoned
  Makefile: Move bootdevice.o to common-obj-y
  hw/misc/edu: Compile the edu device as common object

 Makefile.objs |  2 +-
 Makefile.target   |  2 +-
 accel/tcg/translate-all.c |  8 
 bootdevice.c  |  2 +-
 hw/acpi/ich9.c|  1 -
 hw/i386/pc_q35.c  |  1 +
 hw/misc/Makefile.objs |  2 +-
 include/exec/cpu-common.h |  2 ++
 include/exec/poison.h |  8 
 include/hw/i386/pc.h  | 13 -
 include/qom/cpu.h |  8 
 include/sysemu/kvm.h  | 31 ---
 qom/cpu.c |  5 ++---
 target/i386/kvm_i386.h| 23 +++
 14 files changed, 68 insertions(+), 40 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v4 4/7] cpu: Introduce a wrapper for tlb_flush() that can be used in common code

2017-06-25 Thread Thomas Huth
Commit 1f5c00cfdb8114c ("qom/cpu: move tlb_flush to cpu_common_reset")
moved the call to tlb_flush() from the target-specific reset handlers
into the common code qom/cpu.c file, and protected the call with
"#ifdef CONFIG_SOFTMMU" to avoid that it is called for linux-user
only targets. But since qom/cpu.c is common code, CONFIG_SOFTMMU is
*never* defined here, so the tlb_flush() was simply never executed
anymore. Fix it by introducing a wrapper for tlb_flush() in a file
that is re-compiled for each target, i.e. in translate-all.c.

Fixes: 1f5c00cfdb8114c1e3a13426588ceb64f82c9ddb
Reviewed-by: Richard Henderson 
Signed-off-by: Thomas Huth 
---
 accel/tcg/translate-all.c | 8 
 include/exec/cpu-common.h | 2 ++
 qom/cpu.c | 5 ++---
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index f6ad46b..a3f374e 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -2225,3 +2225,11 @@ int page_unprotect(target_ulong address, uintptr_t pc)
 return 0;
 }
 #endif /* CONFIG_USER_ONLY */
+
+/* This is a wrapper for common code that can not use CONFIG_SOFTMMU */
+void tcg_flush_softmmu_tlb(CPUState *cs)
+{
+#ifdef CONFIG_SOFTMMU
+tlb_flush(cs);
+#endif
+}
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 4d45a72..74341b1 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -28,6 +28,8 @@ void qemu_init_cpu_list(void);
 void cpu_list_lock(void);
 void cpu_list_unlock(void);
 
+void tcg_flush_softmmu_tlb(CPUState *cs);
+
 #if !defined(CONFIG_USER_ONLY)
 
 enum device_endian {
diff --git a/qom/cpu.c b/qom/cpu.c
index 5069876..303eb42 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -26,6 +26,7 @@
 #include "qemu/notify.h"
 #include "qemu/log.h"
 #include "exec/log.h"
+#include "exec/cpu-common.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
 #include "hw/qdev-properties.h"
@@ -296,9 +297,7 @@ static void cpu_common_reset(CPUState *cpu)
 atomic_set(&cpu->tb_jmp_cache[i], NULL);
 }
 
-#ifdef CONFIG_SOFTMMU
-tlb_flush(cpu, 0);
-#endif
+tcg_flush_softmmu_tlb(cpu);
 }
 }
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 6/7] Makefile: Move bootdevice.o to common-obj-y

2017-06-25 Thread Thomas Huth
There does not seem to be any target specific code in this file, so
we can put it into "common-obj" instead of "obj" to compile it only
once for all targets.

Signed-off-by: Thomas Huth 
---
 Makefile.objs   | 2 +-
 Makefile.target | 2 +-
 bootdevice.c| 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index b2e6322..756644c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -40,7 +40,7 @@ io-obj-y = io/
 
 ifeq ($(CONFIG_SOFTMMU),y)
 common-obj-y = blockdev.o blockdev-nbd.o block/
-common-obj-y += iothread.o
+common-obj-y += bootdevice.o iothread.o
 common-obj-y += net/
 common-obj-y += qdev-monitor.o device-hotplug.o
 common-obj-$(CONFIG_WIN32) += os-win32.o
diff --git a/Makefile.target b/Makefile.target
index 0066579..ffa7a8f 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -137,7 +137,7 @@ endif #CONFIG_BSD_USER
 # System emulator target
 ifdef CONFIG_SOFTMMU
 obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
-obj-y += qtest.o bootdevice.o
+obj-y += qtest.o
 obj-y += hw/
 obj-y += memory.o
 obj-y += memory_mapping.o
diff --git a/bootdevice.c b/bootdevice.c
index 33e3029..1141009 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -27,7 +27,7 @@
 #include "sysemu/sysemu.h"
 #include "qapi/visitor.h"
 #include "qemu/error-report.h"
-#include "hw/hw.h"
+#include "sysemu/reset.h"
 #include "hw/qdev-core.h"
 
 typedef struct FWBootEntry FWBootEntry;
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 7/7] hw/misc/edu: Compile the edu device as common object

2017-06-25 Thread Thomas Huth
edu.c does not contain any target-specific code, so we can put
it into common-obj-y to compile it only once for all targets.

Signed-off-by: Thomas Huth 
---
 hw/misc/Makefile.objs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 2019846..7fc4e41 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -6,6 +6,7 @@ common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
 common-obj-$(CONFIG_SGA) += sga.o
 common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
 common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
+common-obj-$(CONFIG_EDU) += edu.o
 
 common-obj-y += unimp.o
 
@@ -53,7 +54,6 @@ obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
 obj-$(CONFIG_MIPS_ITU) += mips_itu.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
-obj-$(CONFIG_EDU) += edu.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
 obj-$(CONFIG_AUX) += auxbus.o
 obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v3 1/3] arm64: kvm: support kvmtool to detect RAS extension feature

2017-06-25 Thread gengdongjiu
Hi James,

   I have changed the SEA/SEI injection method according you suggestion, but I 
think this patch may also be needed.
Now for the  SEI, the virtual ESR value is specified by the userspace. only RAS 
extension support to set the virtual ESR value. so user space will check it to 
decide whether pass the virtual ESR value.
At the same time, reserve this interface for other possible usage by user 
space. what do you think about this patch?



On 2017/5/2 23:29, James Morse wrote:
> Hi Dongjiu Geng,
> 
> On 30/04/17 06:37, Dongjiu Geng wrote:
>> Handle kvmtool's detection for RAS extension, because sometimes
>> the APP needs to know the CPU's capacity
> 
>> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
>> index d9e9697..1004039 100644
>> --- a/arch/arm64/kvm/reset.c
>> +++ b/arch/arm64/kvm/reset.c
>> @@ -64,6 +64,14 @@ static bool cpu_has_32bit_el1(void)
>>  return !!(pfr0 & 0x20);
>>  }
>>  
>> +static bool kvm_arm_support_ras_extension(void)
>> +{
>> +u64 pfr0;
>> +
>> +pfr0 = read_system_reg(SYS_ID_AA64PFR0_EL1);
>> +return !!(pfr0 & 0x1000);
>> +}
> 
> Why are we telling user-space that the CPU has RAS extensions? EL0 can't do
> anything with this and the guest EL1 can detect it from the id registers.
> 
> 
> Are you using this to decide whether or not to generate a HEST for the guest?
> 
> If Qemu/kvmtool supports handling memory-failure notifications from signals 
> you
> should always generate a HEST. The GHES notification method could be anything
> Qemu can deliver to the guest using the KVM APIs. Notifications from Qemu to 
> the
> guest don't depend on the RAS extensions. KVM has APIs for IRQ and SEA (you 
> can
> use KVM_SET_ONE_REG).
> 
> 
> I think we need a new API for injecting SError for SEI from Qemu/kvmtool, but 
> it
> shouldn't be related to the RAS extensions. All v8.0 CPUs have HCR_EL2.VSE, so
> we need to know KVM supports this API.
> 
> Your later patch adds code to set VSESR to make virtual RAS SErrors work, I
> think we need to expose that to user-space.
> 
> 
> Thanks,
> 
> James
> .
> 




Re: [Qemu-devel] [PATCH v4 1/4] net/socket: Drop the odd 'default' case and comment

2017-06-25 Thread Mao Zhongyi

Hi, Markus


On 06/23/2017 09:36 PM, Markus Armbruster wrote:

Mao Zhongyi  writes:


In the net_socket_fd_init(), the 'default' case and comment is odd.
If @fd really was a pty, getsockopt() would fail with ENOTSOCK. If
@fd was a socket, but neither SOCK_DGRAM nor SOCK_STREAM. It should
not be treated as if it was SOCK_STREAM.

If there is a genuine reason to support something like SOCK_RAW, it
should be explicitly handled.

So, drop the 'default' case since it is broken already.

Cc: jasow...@redhat.com
Cc: arm...@redhat.com
Cc: berra...@redhat.com
Cc: arm...@redhat.com
Suggested-by: Markus Armbruster 
Suggested-by: Daniel P. Berrange 
Signed-off-by: Mao Zhongyi 
---
 net/socket.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index dcae1ae..53765bd 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -449,9 +449,9 @@ static NetSocketState *net_socket_fd_init(NetClientState 
*peer,
 case SOCK_STREAM:
 return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
 default:
-/* who knows ... this could be a eg. a pty, do warn and continue as 
stream */
-fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM 
or SOCK_STREAM\n", so_type, fd);
-return net_socket_fd_init_stream(peer, model, name, fd, is_connected);
+error_report("qemu: error: socket type=%d for fd=%d is not"
+" SOCK_DGRAM or SOCK_STREAM", so_type, fd);
+closesocket(fd);
 }
 return NULL;
 }


You don't actually "drop the 'default' case", as your commit message
claims.  Perhaps:

net/socket: Don't treat odd socket type as SOCK_STREAM

In net_socket_fd_init(), the 'default' case is odd: it warns, then
continues as if the socket type was SOCK_STREAM.  The comment
explains "this could be a eg. a pty", but that makes no sense.  If
@fd really was a pty, getsockopt() would fail with ENOTSOCK.  If @fd
was a socket, but neither SOCK_DGRAM nor SOCK_STREAM, it should not
be treated as if it was SOCK_STREAM.

Turn this case into an error.  If there is a genuine reason to
support something like SOCK_RAW, it should be handled explicitly.

With something like that:



Yes, I have noticed that the commit message is really not very match this
patch after read your exact description. I will fix it in the next version.

Thank you very much. :)
Mao


Reviewed-by: Markus Armbruster 









Re: [Qemu-devel] [PATCH v4 2/4] net/net: Convert parse_host_port() to Error

2017-06-25 Thread Mao Zhongyi

Hi, Markus


On 06/23/2017 10:21 PM, Markus Armbruster wrote:

Markus Armbruster  writes:


Mao Zhongyi  writes:


Cc: berra...@redhat.com
Cc: kra...@redhat.com
Cc: pbonz...@redhat.com
Cc: jasow...@redhat.com
Cc: arm...@redhat.com
Signed-off-by: Mao Zhongyi 
---
 include/qemu/sockets.h |  2 +-
 net/net.c  | 21 -
 net/socket.c   | 37 ++---
 3 files changed, 39 insertions(+), 21 deletions(-)

diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 5c326db..7abffc4 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -53,7 +53,7 @@ void socket_listen_cleanup(int fd, Error **errp);
 int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp);

 /* Old, ipv4 only bits.  Don't use for new code. */
-int parse_host_port(struct sockaddr_in *saddr, const char *str);
+int parse_host_port(struct sockaddr_in *saddr, const char *str, Error **errp);
 int socket_init(void);

 /**
diff --git a/net/net.c b/net/net.c
index 6235aab..e55869a 100644
--- a/net/net.c
+++ b/net/net.c
@@ -100,7 +100,7 @@ static int get_str_sep(char *buf, int buf_size, const char 
**pp, int sep)
 return 0;
 }

-int parse_host_port(struct sockaddr_in *saddr, const char *str)
+int parse_host_port(struct sockaddr_in *saddr, const char *str, Error **errp)
 {
 char buf[512];
 struct hostent *he;
@@ -108,24 +108,35 @@ int parse_host_port(struct sockaddr_in *saddr, const char 
*str)
 int port;

 p = str;
-if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
+if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
+error_setg(errp, "The address should contain ':', for example: "
+   "=230.0.0.1:1234");
 return -1;
+}
 saddr->sin_family = AF_INET;
 if (buf[0] == '\0') {
 saddr->sin_addr.s_addr = 0;
 } else {
 if (qemu_isdigit(buf[0])) {
-if (!inet_aton(buf, &saddr->sin_addr))
+if (!inet_aton(buf, &saddr->sin_addr)) {
+error_setg(errp, "Host address '%s' is not a valid "
+   "IPv4 address", buf);
 return -1;
+}
 } else {
-if ((he = gethostbyname(buf)) == NULL)
+he = gethostbyname(buf);
+if (he == NULL) {
+error_setg(errp, "Specified hostname is error.");
 return - 1;
+}
 saddr->sin_addr = *(struct in_addr *)he->h_addr;
 }
 }
 port = strtol(p, (char **)&r, 0);
-if (r == p)
+if (r == p) {
+error_setg(errp, "The port number is illegal");
 return -1;
+}
 saddr->sin_port = htons(port);
 return 0;
 }
diff --git a/net/socket.c b/net/socket.c
index 53765bd..66016c8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -485,15 +485,17 @@ static void net_socket_accept(void *opaque)
 static int net_socket_listen_init(NetClientState *peer,
   const char *model,
   const char *name,
-  const char *host_str)
+  const char *host_str,
+  Error **errp)


You convert net_socket_listen_init() to Error.  This means you have to
make it set an error on failure.  You do ...


 {
 NetClientState *nc;
 NetSocketState *s;
 struct sockaddr_in saddr;
 int fd, ret;

-if (parse_host_port(&saddr, host_str) < 0)
+if (parse_host_port(&saddr, host_str, errp) < 0) {
 return -1;
+}


... here, ...



 fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 if (fd < 0) {

   perror("socket");
   return -1;
   }

... but not here.  Two more error returns follow.

Preexisting bug: net_socket_listen_init() reports to stderr for three
out of four failures.  Functions should either report on no failure or
on all.  Conversion to Error should fix that, but yours isn't complete.
When it is, the fix should be mentioned in the commit message.


@@ -531,14 +533,16 @@ static int net_socket_listen_init(NetClientState *peer,
 static int net_socket_connect_init(NetClientState *peer,
const char *model,
const char *name,
-   const char *host_str)
+   const char *host_str,
+   Error **errp)
 {
 NetSocketState *s;
 int fd, connected, ret;
 struct sockaddr_in saddr;

-if (parse_host_port(&saddr, host_str) < 0)
+if (parse_host_port(&saddr, host_str, errp) < 0) {
 return -1;
+}

 fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
 if (fd < 0) {


Again, you have to make the function set an error on all failures, not
just this one.

Additionally:

   s = net_socket_fd_init(peer, model, name, fd, connected);
   if (!s)
   return -1;

net_socket_fd_init() still prints to

Re: [Qemu-devel] [PATCH] xen/disk: don't leak stack data via response ring

2017-06-25 Thread Jan Beulich
>>> Stefano Stabellini  06/23/17 8:43 PM >>>
>On Fri, 23 Jun 2017, Jan Beulich wrote:
>> >>> On 22.06.17 at 20:52,  wrote:
>> > I am happy to write the code and/or the commit message. Would a simple
>> > cast like below work to fix the security issue?
>> 
>> I suppose so, but you do realize that this is _exactly_ what
>> my patch does, except you use dangerous casts while I play
>> type-safe?
>
>Why is the cast dangerous?

Casts, and especially pointer ones) are always dangerous, as they have
the potential of type changes elsewhere going unnoticed. You may have
noticed that in reviews I'm often picking at casts, because in a majority
of cases people use them they're not needed and hence their use is a
(latent) risk.

> Both your patch and my version of it rely on
>inner knowledge of the way the rings are laid out in memory, but at
>least my patch doesn't introduce the risk of instantiating broken
>structs. Besides, type safety checks don't add much value, given that we
>rely on the way the ring.h macros have been written, which weren't even
>imported in the QEMU project until March this year.

That's said, as it seems to imply backporting of the change to older
qemu may then be problematic. Otoh I don't recall having had problems
with using the patch with only minor adjustments on older trees of ours.

>These are the reasons why I prefer my version, but I would consider your
>version with clear in-code comments that warn users to avoid
>instantiating the structs because they are not ABI compliant.
>
>How do you want to proceed?

I can provide a version with comments added, but only next week. If you
feel like you want to go with your variant, I won't stand in the way, but I
also wouldn't give it my ack or alike (which you don't depend on anyway).

Jan