Re: [Qemu-devel] [V17 3/4] hw/i386: Introduce AMD IOMMU

2016-09-16 Thread David Kiarie



On 16/09/16 21:58, Michael S. Tsirkin wrote:

On Wed, Aug 31, 2016 at 07:17:42PM +0300, David Kiarie wrote:

Hi Michael,

+
+/* issue a PCIe completion packet for devid */
+typedef struct QEMU_PACKED {
+uint32_t reserved_1:16;
+uint32_t devid:16;
+
+#ifdef HOST_WORDS_BIGENDIAN
+uint32_t type:4;  /* command type   */
+uint32_t reserved_2:8;
+uint32_t pasid_19_0:20
+#else
+uint32_t pasid_19_0:20;
+uint32_t reserved_2:8;
+uint32_t type:4;
+#endif /* __BIG_ENDIAN_BITFIELD */
+
+#ifdef HOST_WORDS_BIGENDIAN
+uint32_t reserved_3:29;
+uint32_t guest:1;
+uint32_t reserved_4:2;
+#else
+uint32_t reserved_3:2;
+uint32_t guest:1;
+uint32_t reserved_4:29;
+#endif /* __BIG_ENDIAN_BITFIELD */
+
+uint32_t completion_tag:16;  /* PCIe PRI information */
+uint32_t reserved_5:16;
+} CMDCompletePPR;
So as Peter points, out, we don't do this kind of
thing. Pls drop this ifdefery and rework using
masks and cpu_to_le. E.g.

 > +#ifdef HOST_WORDS_BIGENDIAN
 > +uint32_t reserved_3:29;
 > +uint32_t guest:1;
 > +uint32_t reserved_4:2;
 > +#else
 > +uint32_t reserved_3:2;
 > +uint32_t guest:1;
 > +uint32_t reserved_4:29;
 > +#endif /* __BIG_ENDIAN_BITFIELD */

 guest = 1;

->

#define GUEST cpu_to_le32(0x1 << 2)
uint32_t guest;

guest = GUEST;


This might not solve the problem we are encountering here. I don't 
intent to write any values to these fields. I only intend to read.


I read into these structs using 'dma_memory_read' which gives me a 
memory order dependent on the host. Byte swapping the read buffer will 
lead into some of the fields being permanently corrupted since they span 
across byte boundaries. I actually didn't have any bitfields(and was not 
taking care of BE) but then there were some complains that the code was 
barely readable hence the bitfields and later the ifdefinery but I've 
never checked that the BE code complies.










Re: [Qemu-devel] VGA driver debug output

2016-09-16 Thread Benjamin Herrenschmidt
On Fri, 2016-09-16 at 22:53 -0400, G 3 wrote:
> Is there a way to make the VGA driver print information? I tried  
> building the debug settings in CodeWarrior but it ends with an error.  
> I'm trying to add a feature to the driver that will allow the user to  
> add resolutions via the command-line. With the debug output I can  
> test this driver out.

Yes but you need a patch in qemu that implements the MOL OSI debug
output, it's in my branch.

Then you should be able to build the debug target.

Cheers,
Ben.




[Qemu-devel] VGA driver debug output

2016-09-16 Thread G 3
Is there a way to make the VGA driver print information? I tried  
building the debug settings in CodeWarrior but it ends with an error.  
I'm trying to add a feature to the driver that will allow the user to  
add resolutions via the command-line. With the debug output I can  
test this driver out.




Re: [Qemu-devel] [PATCH v4 26/35] tests: add atomic_add-bench

2016-09-16 Thread Richard Henderson

On 09/16/2016 04:54 PM, Emilio G. Cota wrote:

On Fri, Sep 16, 2016 at 10:46:48 -0700, Richard Henderson wrote:

From: "Emilio G. Cota" 

With this microbenchmark we can measure the overhead of emulating atomic
instructions with a configurable degree of contention.

The benchmark spawns $n threads, each performing $o atomic ops (additions)
in a loop. Each atomic operation is performed on a different cache line
(assuming lines are 64b long) that is randomly selected from a range [0, $r).

[ Note: each $foo corresponds to a -foo flag ]


Hi Richard,

As I mentioned yesterday I have an updated version of this
patch:  http://lists.gnu.org/archive/html/qemu-devel/2016-09/msg03450.html
[ The major change is to run for a certain number of seconds, instead
  of a fixed number of operations. ]

I'll send the full updated patch as a reply to this message to make
it easier to pick up.


Thanks, applied.


r~




Re: [Qemu-devel] [PATCH v4 30/35] target-arm: emulate aarch64's LL/SC using cmpxchg helpers

2016-09-16 Thread Richard Henderson

On 09/16/2016 05:16 PM, Emilio G. Cota wrote:

> +uint64_t *haddr = g2h(addr);
> +o0 = ldq_le_p(haddr + 0);
> +o1 = ldq_le_p(haddr + 1);
> +oldv = int128_make128(o0, o1);
> +
> +success = int128_eq(oldv, cmpv);
> +if (success) {
> +stq_le_p(haddr + 0, int128_getlo(newv));
> +stq_le_p(haddr + 8, int128_gethi(newv));

Shouldn't this be + 1 instead, just like the above load?

If so, the same applies to the store in the _be function.


Yep, good catch.


r~



Re: [Qemu-devel] [PATCH v4 30/35] target-arm: emulate aarch64's LL/SC using cmpxchg helpers

2016-09-16 Thread Emilio G. Cota
On Fri, Sep 16, 2016 at 10:46:52 -0700, Richard Henderson wrote:
(snip)
> +/* Returns 0 on success; 1 otherwise.  */
> +uint64_t HELPER(paired_cmpxchg64_le)(CPUARMState *env, uint64_t addr,
> + uint64_t new_lo, uint64_t new_hi)
> +{
> +uintptr_t ra = GETPC();
> +Int128 oldv, cmpv, newv;
> +bool success;
> +
> +cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
> +newv = int128_make128(new_lo, new_hi);
> +
> +if (parallel_cpus) {
> +#ifndef CONFIG_ATOMIC128
> +cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
> +#else
> +int mem_idx = cpu_mmu_index(env, false);
> +TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
> +oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
> +success = int128_eq(oldv, cmpv);
> +#endif
> +} else {
> +uint64_t o0, o1;
> +
> +#ifdef CONFIG_USER_ONLY
> +/* ??? Enforce alignment.  */
> +uint64_t *haddr = g2h(addr);
> +o0 = ldq_le_p(haddr + 0);
> +o1 = ldq_le_p(haddr + 1);
> +oldv = int128_make128(o0, o1);
> +
> +success = int128_eq(oldv, cmpv);
> +if (success) {
> +stq_le_p(haddr + 0, int128_getlo(newv));
> +stq_le_p(haddr + 8, int128_gethi(newv));

Shouldn't this be + 1 instead, just like the above load?

If so, the same applies to the store in the _be function.

Thanks,

Emilio



[Qemu-devel] [PATCH] tests: add atomic_add-bench

2016-09-16 Thread Emilio G. Cota
With this microbenchmark we can measure the overhead of emulating atomic
instructions with a configurable degree of contention.

The benchmark spawns $n threads, each performing atomic additions in
a loop for $d seconds.
Each atomic operation is performed on a different cache line
(assuming lines are 64b long) that is randomly selected from a range [0, $r).

[ Note: each $foo corresponds to a -foo flag ]

Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
Message-Id: <1467054136-10430-20-git-send-email-c...@braap.org>
---
 tests/.gitignore |   1 +
 tests/Makefile.include   |   4 +-
 tests/atomic_add-bench.c | 163 +++
 3 files changed, 167 insertions(+), 1 deletion(-)
 create mode 100644 tests/atomic_add-bench.c

diff --git a/tests/.gitignore b/tests/.gitignore
index b4a9cfc..6382a93 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,3 +1,4 @@
+atomic_add-bench
 check-qdict
 check-qfloat
 check-qint
diff --git a/tests/Makefile.include b/tests/Makefile.include
index e560ecb..ad4d827 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -441,7 +441,8 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o 
tests/check-qdict.o \
tests/test-opts-visitor.o tests/test-qmp-event.o \
tests/rcutorture.o tests/test-rcu-list.o \
tests/test-qdist.o \
-   tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o
+   tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
+   tests/atomic_add-bench.o
 
 $(test-obj-y): QEMU_INCLUDES += -Itests
 QEMU_CFLAGS += -I$(SRC_PATH)/tests
@@ -485,6 +486,7 @@ tests/test-qdist$(EXESUF): tests/test-qdist.o 
$(test-util-obj-y)
 tests/test-qht$(EXESUF): tests/test-qht.o $(test-util-obj-y)
 tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) 
$(test-util-obj-y)
 tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
+tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y)
 
 tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
diff --git a/tests/atomic_add-bench.c b/tests/atomic_add-bench.c
new file mode 100644
index 000..69c59ad
--- /dev/null
+++ b/tests/atomic_add-bench.c
@@ -0,0 +1,163 @@
+#include "qemu/osdep.h"
+#include "qemu/thread.h"
+#include "qemu/host-utils.h"
+#include "qemu/processor.h"
+
+struct thread_info {
+uint64_t r;
+} QEMU_ALIGNED(64);
+
+struct count {
+unsigned long val;
+} QEMU_ALIGNED(64);
+
+static QemuThread *threads;
+static struct thread_info *th_info;
+static unsigned int n_threads = 1;
+static unsigned int n_ready_threads;
+static struct count *counts;
+static unsigned int duration = 1;
+static unsigned int range = 1024;
+static bool test_start;
+static bool test_stop;
+
+static const char commands_string[] =
+" -n = number of threads\n"
+" -d = duration in seconds\n"
+" -r = range (will be rounded up to pow2)";
+
+static void usage_complete(char *argv[])
+{
+fprintf(stderr, "Usage: %s [options]\n", argv[0]);
+fprintf(stderr, "options:\n%s\n", commands_string);
+}
+
+/*
+ * From: https://en.wikipedia.org/wiki/Xorshift
+ * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
+ * guaranteed to be >= INT_MAX).
+ */
+static uint64_t xorshift64star(uint64_t x)
+{
+x ^= x >> 12; /* a */
+x ^= x << 25; /* b */
+x ^= x >> 27; /* c */
+return x * UINT64_C(2685821657736338717);
+}
+
+static void *thread_func(void *arg)
+{
+struct thread_info *info = arg;
+
+atomic_inc(_ready_threads);
+while (!atomic_mb_read(_start)) {
+cpu_relax();
+}
+
+while (!atomic_read(_stop)) {
+unsigned int index;
+
+info->r = xorshift64star(info->r);
+index = info->r & (range - 1);
+atomic_inc([index].val);
+}
+return NULL;
+}
+
+static void run_test(void)
+{
+unsigned int remaining;
+unsigned int i;
+
+while (atomic_read(_ready_threads) != n_threads) {
+cpu_relax();
+}
+atomic_mb_set(_start, true);
+do {
+remaining = sleep(duration);
+} while (remaining);
+atomic_mb_set(_stop, true);
+
+for (i = 0; i < n_threads; i++) {
+qemu_thread_join([i]);
+}
+}
+
+static void create_threads(void)
+{
+unsigned int i;
+
+threads = g_new(QemuThread, n_threads);
+th_info = g_new(struct thread_info, n_threads);
+counts = qemu_memalign(64, sizeof(*counts) * range);
+memset(counts, 0, sizeof(*counts) * range);
+
+for (i = 0; i < n_threads; i++) {
+struct thread_info *info = _info[i];
+
+info->r = (i + 1) ^ time(NULL);
+qemu_thread_create([i], NULL, thread_func, info,
+   QEMU_THREAD_JOINABLE);
+}
+}
+
+static void pr_params(void)
+{
+printf("Parameters:\n");
+printf(" # of threads:  %u\n", n_threads);
+printf(" duration:

Re: [Qemu-devel] [PATCH v4 26/35] tests: add atomic_add-bench

2016-09-16 Thread Emilio G. Cota
On Fri, Sep 16, 2016 at 10:46:48 -0700, Richard Henderson wrote:
> From: "Emilio G. Cota" 
> 
> With this microbenchmark we can measure the overhead of emulating atomic
> instructions with a configurable degree of contention.
> 
> The benchmark spawns $n threads, each performing $o atomic ops (additions)
> in a loop. Each atomic operation is performed on a different cache line
> (assuming lines are 64b long) that is randomly selected from a range [0, $r).
> 
> [ Note: each $foo corresponds to a -foo flag ]

Hi Richard,

As I mentioned yesterday I have an updated version of this
patch:  http://lists.gnu.org/archive/html/qemu-devel/2016-09/msg03450.html
[ The major change is to run for a certain number of seconds, instead
  of a fixed number of operations. ]

I'll send the full updated patch as a reply to this message to make
it easier to pick up.

Thanks,

Emilio




Re: [Qemu-devel] [PATCH v2 1/6] Pass generic CPUState to gen_intermediate_code()

2016-09-16 Thread Richard Henderson

On 09/09/2016 06:03 AM, Lluís Vilanova wrote:

-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;


Why the variable renames?  I.e. why CPUState *cpu instead of CPUState *cs?


r~



Re: [Qemu-devel] [PATCH v18 00/13] AVR target

2016-09-16 Thread no-reply
Hi,

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

Type: series
Message-id: 1474063242-27419-1-git-send-email-...@twiddle.net
Subject: [Qemu-devel] [PATCH v18 00/13] AVR target

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

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

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

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

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
58f0bcb target-avr: Merge translate-inst.inc.c into translate.c
f0b4956 target-avr: Respect .inc.c convention
390da65 target-avr: Put all translation code into one compilation unit
93e0b30 target-avr: Put env pointer in DisasContext
8862669 target-avr: adding instruction decoder
1b8ab42 target-avr: instruction decoder generator
a243c5a target-avr: adding instruction translation
72ba9fc target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported 
instructions
f85d68f target-avr: adding AVR interrupt handling
7a9f664 target-avr: adding instructions encodings
b7a16a1 target-avr: adding a sample AVR board
140ca0e target-avr: adding AVR CPU features/flavors
7049535 target-avr: AVR cores support is added.

=== OUTPUT BEGIN ===
Checking PATCH 1/13: target-avr: AVR cores support is added
Checking PATCH 2/13: target-avr: adding AVR CPU features/flavors...
Checking PATCH 3/13: target-avr: adding a sample AVR board...
Checking PATCH 4/13: target-avr: adding instructions encodings...
Checking PATCH 5/13: target-avr: adding AVR interrupt handling...
Checking PATCH 6/13: target-avr: adding helpers for IN, OUT, SLEEP, WBR & 
unsupported instructions...
Checking PATCH 7/13: target-avr: adding instruction translation...
Checking PATCH 8/13: target-avr: instruction decoder generator...
ERROR: suspect code indent for conditional statements (4, 4)
#810: FILE: target-avr/cpugen/src/cpugen.cpp:440:
+if (argc != 2) {
[...]
+}

total: 1 errors, 0 warnings, 1220 lines checked

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

Checking PATCH 9/13: target-avr: adding instruction decoder...
Checking PATCH 10/13: target-avr: Put env pointer in DisasContext...
ERROR: "foo* bar" should be "foo *bar"
#1119: FILE: target-avr/translate-inst.h:26:
+int avr_translate_NOP(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1122: FILE: target-avr/translate-inst.h:28:
+int avr_translate_MOVW(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1131: FILE: target-avr/translate-inst.h:39:
+int avr_translate_MULS(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1140: FILE: target-avr/translate-inst.h:50:
+int avr_translate_MULSU(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1149: FILE: target-avr/translate-inst.h:61:
+int avr_translate_FMUL(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1158: FILE: target-avr/translate-inst.h:72:
+int avr_translate_FMULS(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1167: FILE: target-avr/translate-inst.h:83:
+int avr_translate_FMULSU(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1176: FILE: target-avr/translate-inst.h:94:
+int avr_translate_CPC(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1185: FILE: target-avr/translate-inst.h:106:
+int avr_translate_SBC(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1194: FILE: target-avr/translate-inst.h:118:
+int avr_translate_ADD(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1203: FILE: target-avr/translate-inst.h:130:
+int avr_translate_AND(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1212: FILE: target-avr/translate-inst.h:142:
+int avr_translate_EOR(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1221: FILE: target-avr/translate-inst.h:154:
+int avr_translate_OR(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1230: FILE: target-avr/translate-inst.h:166:
+int avr_translate_MOV(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1239: FILE: target-avr/translate-inst.h:178:
+int avr_translate_CPSE(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"
#1248: FILE: target-avr/translate-inst.h:190:
+int avr_translate_CP(DisasContext* ctx, uint32_t opcode);

ERROR: "foo* bar" should be "foo *bar"

[Qemu-devel] [PATCH v18 11/13] target-avr: Put all translation code into one compilation unit

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-avr/Makefile.objs|   2 -
 target-avr/decode.c |   6 +-
 target-avr/translate-inst.c | 198 ++--
 target-avr/translate-inst.h | 113 -
 target-avr/translate.c  | 103 ++-
 target-avr/translate.h  | 112 -
 6 files changed, 182 insertions(+), 352 deletions(-)
 delete mode 100644 target-avr/translate.h

diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
index 9848b1c..48233ef 100644
--- a/target-avr/Makefile.objs
+++ b/target-avr/Makefile.objs
@@ -20,6 +20,4 @@
 
 obj-y += translate.o cpu.o helper.o
 obj-y += gdbstub.o
-obj-y += translate-inst.o
-obj-y += decode.o
 obj-$(CONFIG_SOFTMMU) += machine.o
diff --git a/target-avr/decode.c b/target-avr/decode.c
index 2d2e54e..576dd83 100644
--- a/target-avr/decode.c
+++ b/target-avr/decode.c
@@ -18,10 +18,8 @@
  * 
  */
 
-#include 
-#include "translate.h"
-
-void avr_decode(uint32_t pc, uint32_t *l, uint32_t c, translate_function_t *t)
+static void avr_decode(uint32_t pc, uint32_t *l, uint32_t c,
+   translate_function_t *t)
 {
 uint32_t opc = extract32(c, 0, 16);
 switch (opc & 0xd000) {
diff --git a/target-avr/translate-inst.c b/target-avr/translate-inst.c
index 377263a..827ec7b 100644
--- a/target-avr/translate-inst.c
+++ b/target-avr/translate-inst.c
@@ -18,10 +18,6 @@
  *  
  */
 
-#include "translate.h"
-#include "translate-inst.h"
-#include "qemu/bitops.h"
-
 static void gen_add_CHf(TCGv R, TCGv Rd, TCGv Rr)
 {
 TCGv t1 = tcg_temp_new_i32();
@@ -249,7 +245,7 @@ static TCGv gen_get_zaddr(void)
  *  Adds two registers and the contents of the C Flag and places the result in
  *  the destination register Rd.
  */
-int avr_translate_ADC(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_ADC(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[ADC_Rd(opcode)];
 TCGv Rr = cpu_r[ADC_Rr(opcode)];
@@ -276,7 +272,7 @@ int avr_translate_ADC(DisasContext *ctx, uint32_t opcode)
  *  Adds two registers without the C Flag and places the result in the
  *  destination register Rd.
  */
-int avr_translate_ADD(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_ADD(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[ADD_Rd(opcode)];
 TCGv Rr = cpu_r[ADD_Rr(opcode)];
@@ -305,7 +301,7 @@ int avr_translate_ADD(DisasContext *ctx, uint32_t opcode)
  *  instruction is not available in all devices. Refer to the device specific
  *  instruction set summary.
  */
-int avr_translate_ADIW(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_ADIW(DisasContext *ctx, uint32_t opcode)
 {
 if (avr_feature(ctx->env, AVR_FEATURE_ADIW_SBIW) == false) {
 gen_helper_unsupported(cpu_env);
@@ -355,7 +351,7 @@ int avr_translate_ADIW(DisasContext *ctx, uint32_t opcode)
  *  Performs the logical AND between the contents of register Rd and register
  *  Rr and places the result in the destination register Rd.
  */
-int avr_translate_AND(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_AND(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[AND_Rd(opcode)];
 TCGv Rr = cpu_r[AND_Rr(opcode)];
@@ -384,7 +380,7 @@ int avr_translate_AND(DisasContext *ctx, uint32_t opcode)
  *  Performs the logical AND between the contents of register Rd and a constant
  *  and places the result in the destination register Rd.
  */
-int avr_translate_ANDI(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_ANDI(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[16 + ANDI_Rd(opcode)];
 int Imm = (ANDI_Imm(opcode));
@@ -404,7 +400,7 @@ int avr_translate_ANDI(DisasContext *ctx, uint32_t opcode)
  *  signed value by two without changing its sign. The Carry Flag can be used 
to
  *  round the result.
  */
-int avr_translate_ASR(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_ASR(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[ASR_Rd(opcode)];
 TCGv t1 = tcg_temp_new_i32();
@@ -435,7 +431,7 @@ int avr_translate_ASR(DisasContext *ctx, uint32_t opcode)
 /*
  *  Clears a single Flag in SREG.
  */
-int avr_translate_BCLR(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_BCLR(DisasContext *ctx, uint32_t opcode)
 {
 switch (BCLR_Bit(opcode)) {
 case 0x00:
@@ -470,7 +466,7 @@ int avr_translate_BCLR(DisasContext *ctx, uint32_t opcode)
 /*
  *  Copies the T Flag in the SREG (Status Register) to bit b in register Rd.
  */
-int avr_translate_BLD(DisasContext *ctx, uint32_t opcode)
+static int avr_translate_BLD(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[BLD_Rd(opcode)];
 TCGv t1 = tcg_temp_new_i32();
@@ -491,7 +487,7 @@ int avr_translate_BLD(DisasContext *ctx, uint32_t opcode)
  *  parameter k is the offset from PC and is represented in two's 

[Qemu-devel] [PATCH v18 09/13] target-avr: adding instruction decoder

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-10-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 target-avr/Makefile.objs |   1 +
 target-avr/decode.c  | 691 +++
 target-avr/translate.c   |   2 +
 3 files changed, 694 insertions(+)
 create mode 100644 target-avr/decode.c

diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
index a448792..9848b1c 100644
--- a/target-avr/Makefile.objs
+++ b/target-avr/Makefile.objs
@@ -21,4 +21,5 @@
 obj-y += translate.o cpu.o helper.o
 obj-y += gdbstub.o
 obj-y += translate-inst.o
+obj-y += decode.o
 obj-$(CONFIG_SOFTMMU) += machine.o
diff --git a/target-avr/decode.c b/target-avr/decode.c
new file mode 100644
index 000..2d2e54e
--- /dev/null
+++ b/target-avr/decode.c
@@ -0,0 +1,691 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+#include 
+#include "translate.h"
+
+void avr_decode(uint32_t pc, uint32_t *l, uint32_t c, translate_function_t *t)
+{
+uint32_t opc = extract32(c, 0, 16);
+switch (opc & 0xd000) {
+case 0x: {
+switch (opc & 0x2c00) {
+case 0x: {
+switch (opc & 0x0300) {
+case 0x: {
+*l = 16;
+*t = _translate_NOP;
+break;
+}
+case 0x0100: {
+*l = 16;
+*t = _translate_MOVW;
+break;
+}
+case 0x0200: {
+*l = 16;
+*t = _translate_MULS;
+break;
+}
+case 0x0300: {
+switch (opc & 0x0088) {
+case 0x: {
+*l = 16;
+*t = _translate_MULSU;
+break;
+}
+case 0x0008: {
+*l = 16;
+*t = _translate_FMUL;
+break;
+}
+case 0x0080: {
+*l = 16;
+*t = _translate_FMULS;
+break;
+}
+case 0x0088: {
+*l = 16;
+*t = _translate_FMULSU;
+break;
+}
+}
+break;
+}
+}
+break;
+}
+case 0x0400: {
+*l = 16;
+*t = _translate_CPC;
+break;
+}
+case 0x0800: {
+*l = 16;
+*t = _translate_SBC;
+break;
+}
+case 0x0c00: {
+*l = 16;
+*t = _translate_ADD;
+break;
+}
+case 0x2000: {
+*l = 16;
+*t = _translate_AND;
+break;
+}
+case 0x2400: {
+*l = 16;
+*t = _translate_EOR;
+break;
+}
+case 0x2800: {
+*l = 16;
+*t = _translate_OR;
+break;
+}
+case 0x2c00: {
+*l = 16;
+*t = _translate_MOV;
+break;
+}
+}
+break;
+}
+case 0x1000: {
+   

[Qemu-devel] [PATCH v18 07/13] target-avr: adding instruction translation

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-8-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 target-avr/Makefile.objs|1 +
 target-avr/translate-inst.c | 2608 +++
 target-avr/translate.h  |1 +
 3 files changed, 2610 insertions(+)
 create mode 100644 target-avr/translate-inst.c

diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
index 48233ef..a448792 100644
--- a/target-avr/Makefile.objs
+++ b/target-avr/Makefile.objs
@@ -20,4 +20,5 @@
 
 obj-y += translate.o cpu.o helper.o
 obj-y += gdbstub.o
+obj-y += translate-inst.o
 obj-$(CONFIG_SOFTMMU) += machine.o
diff --git a/target-avr/translate-inst.c b/target-avr/translate-inst.c
new file mode 100644
index 000..6ed98bb
--- /dev/null
+++ b/target-avr/translate-inst.c
@@ -0,0 +1,2608 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#include "translate.h"
+#include "translate-inst.h"
+#include "qemu/bitops.h"
+
+static void gen_add_CHf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+TCGv t3 = tcg_temp_new_i32();
+
+tcg_gen_and_tl(t1, Rd, Rr); /* t1 = Rd & Rr */
+tcg_gen_andc_tl(t2, Rd, R); /* t2 = Rd & ~R */
+tcg_gen_andc_tl(t3, Rr, R); /* t3 = Rr & ~R */
+tcg_gen_or_tl(t1, t1, t2); /* t1 = t1 | t2 | t3 */
+tcg_gen_or_tl(t1, t1, t3);
+
+tcg_gen_shri_tl(cpu_Cf, t1, 7); /* Cf = t1(7) */
+tcg_gen_shri_tl(cpu_Hf, t1, 3); /* Hf = t1(3) */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+static void gen_add_Vf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+
+/* t1 = Rd & Rr & ~R | ~Rd & ~Rr & R = (Rd ^ R) & ~(Rd ^ Rr) */
+tcg_gen_xor_tl(t1, Rd, R);
+tcg_gen_xor_tl(t2, Rd, Rr);
+tcg_gen_andc_tl(t1, t1, t2);
+
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */
+
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+static void gen_sub_CHf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+TCGv t3 = tcg_temp_new_i32();
+
+/* Cf & Hf */
+tcg_gen_not_tl(t1, Rd); /* t1 = ~Rd */
+tcg_gen_and_tl(t2, t1, Rr); /* t2 = ~Rd & Rr */
+tcg_gen_or_tl(t3, t1, Rr); /* t3 = (~Rd | Rr) & R */
+tcg_gen_and_tl(t3, t3, R);
+tcg_gen_or_tl(t2, t2, t3); /* t2 = ~Rd & Rr | ~Rd & R | R & Rr */
+tcg_gen_shri_tl(cpu_Cf, t2, 7); /* Cf = t2(7) */
+tcg_gen_shri_tl(cpu_Hf, t2, 3); /* Hf = t2(3) */
+tcg_gen_andi_tl(cpu_Hf, cpu_Hf, 1);
+
+tcg_temp_free_i32(t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+static void gen_sub_Vf(TCGv R, TCGv Rd, TCGv Rr)
+{
+TCGv t1 = tcg_temp_new_i32();
+TCGv t2 = tcg_temp_new_i32();
+
+/* Vf */
+/* t1 = Rd & ~Rr & ~R | ~Rd & Rr & R = (Rd ^ R) & (Rd ^ R) */
+tcg_gen_xor_tl(t1, Rd, R);
+tcg_gen_xor_tl(t2, Rd, Rr);
+tcg_gen_and_tl(t1, t1, t2);
+tcg_gen_shri_tl(cpu_Vf, t1, 7); /* Vf = t1(7) */
+
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t1);
+}
+
+static void gen_NSf(TCGv R)
+{
+tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
+tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
+}
+
+static void gen_ZNSf(TCGv R)
+{
+tcg_gen_mov_tl(cpu_Zf, R); /* Zf = R */
+tcg_gen_shri_tl(cpu_Nf, R, 7); /* Nf = R(7) */
+tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
+}
+
+static void gen_push_ret(CPUAVRState *env, int ret)
+{
+if (avr_feature(env, AVR_FEATURE_1_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0xff));
+
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_UB);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+
+TCGv t0 = tcg_const_i32((ret & 0x00));
+
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+tcg_gen_qemu_st_tl(t0, cpu_sp, MMU_DATA_IDX, MO_BEUW);
+tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
+
+tcg_temp_free_i32(t0);
+
+} else if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+
+

[Qemu-devel] [PATCH v18 10/13] target-avr: Put env pointer in DisasContext

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-avr/translate-inst.c | 298 ++--
 target-avr/translate-inst.h | 194 ++--
 target-avr/translate.c  |  16 +--
 target-avr/translate.h  |  11 +-
 4 files changed, 257 insertions(+), 262 deletions(-)

diff --git a/target-avr/translate-inst.c b/target-avr/translate-inst.c
index 6ed98bb..377263a 100644
--- a/target-avr/translate-inst.c
+++ b/target-avr/translate-inst.c
@@ -109,9 +109,9 @@ static void gen_ZNSf(TCGv R)
 tcg_gen_xor_tl(cpu_Sf, cpu_Nf, cpu_Vf); /* Sf = Nf ^ Vf */
 }
 
-static void gen_push_ret(CPUAVRState *env, int ret)
+static void gen_push_ret(DisasContext *ctx, int ret)
 {
-if (avr_feature(env, AVR_FEATURE_1_BYTE_PC)) {
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
 
 TCGv t0 = tcg_const_i32((ret & 0xff));
 
@@ -119,7 +119,7 @@ static void gen_push_ret(CPUAVRState *env, int ret)
 tcg_gen_subi_tl(cpu_sp, cpu_sp, 1);
 
 tcg_temp_free_i32(t0);
-} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
 
 TCGv t0 = tcg_const_i32((ret & 0x00));
 
@@ -129,7 +129,7 @@ static void gen_push_ret(CPUAVRState *env, int ret)
 
 tcg_temp_free_i32(t0);
 
-} else if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
 
 TCGv lo = tcg_const_i32((ret & 0xff));
 TCGv hi = tcg_const_i32((ret & 0x00) >> 8);
@@ -144,20 +144,20 @@ static void gen_push_ret(CPUAVRState *env, int ret)
 }
 }
 
-static void gen_pop_ret(CPUAVRState *env, TCGv ret)
+static void gen_pop_ret(DisasContext *ctx, TCGv ret)
 {
-if (avr_feature(env, AVR_FEATURE_1_BYTE_PC)) {
+if (avr_feature(ctx->env, AVR_FEATURE_1_BYTE_PC)) {
 
 tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
 tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_UB);
 
-} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+} else if (avr_feature(ctx->env, AVR_FEATURE_2_BYTE_PC)) {
 
 tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
 tcg_gen_qemu_ld_tl(ret, cpu_sp, MMU_DATA_IDX, MO_BEUW);
 tcg_gen_addi_tl(cpu_sp, cpu_sp, 1);
 
-} else if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+} else if (avr_feature(ctx->env, AVR_FEATURE_3_BYTE_PC)) {
 
 TCGv lo = tcg_temp_new_i32();
 TCGv hi = tcg_temp_new_i32();
@@ -249,7 +249,7 @@ static TCGv gen_get_zaddr(void)
  *  Adds two registers and the contents of the C Flag and places the result in
  *  the destination register Rd.
  */
-int avr_translate_ADC(CPUAVRState *env, DisasContext *ctx, uint32_t opcode)
+int avr_translate_ADC(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[ADC_Rd(opcode)];
 TCGv Rr = cpu_r[ADC_Rr(opcode)];
@@ -276,7 +276,7 @@ int avr_translate_ADC(CPUAVRState *env, DisasContext *ctx, 
uint32_t opcode)
  *  Adds two registers without the C Flag and places the result in the
  *  destination register Rd.
  */
-int avr_translate_ADD(CPUAVRState *env, DisasContext *ctx, uint32_t opcode)
+int avr_translate_ADD(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[ADD_Rd(opcode)];
 TCGv Rr = cpu_r[ADD_Rr(opcode)];
@@ -305,9 +305,9 @@ int avr_translate_ADD(CPUAVRState *env, DisasContext *ctx, 
uint32_t opcode)
  *  instruction is not available in all devices. Refer to the device specific
  *  instruction set summary.
  */
-int avr_translate_ADIW(CPUAVRState *env, DisasContext *ctx, uint32_t opcode)
+int avr_translate_ADIW(DisasContext *ctx, uint32_t opcode)
 {
-if (avr_feature(env, AVR_FEATURE_ADIW_SBIW) == false) {
+if (avr_feature(ctx->env, AVR_FEATURE_ADIW_SBIW) == false) {
 gen_helper_unsupported(cpu_env);
 
 return BS_EXCP;
@@ -355,7 +355,7 @@ int avr_translate_ADIW(CPUAVRState *env, DisasContext *ctx, 
uint32_t opcode)
  *  Performs the logical AND between the contents of register Rd and register
  *  Rr and places the result in the destination register Rd.
  */
-int avr_translate_AND(CPUAVRState *env, DisasContext *ctx, uint32_t opcode)
+int avr_translate_AND(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[AND_Rd(opcode)];
 TCGv Rr = cpu_r[AND_Rr(opcode)];
@@ -384,7 +384,7 @@ int avr_translate_AND(CPUAVRState *env, DisasContext *ctx, 
uint32_t opcode)
  *  Performs the logical AND between the contents of register Rd and a constant
  *  and places the result in the destination register Rd.
  */
-int avr_translate_ANDI(CPUAVRState *env, DisasContext *ctx, uint32_t opcode)
+int avr_translate_ANDI(DisasContext *ctx, uint32_t opcode)
 {
 TCGv Rd = cpu_r[16 + ANDI_Rd(opcode)];
 int Imm = (ANDI_Imm(opcode));
@@ -404,7 +404,7 @@ int avr_translate_ANDI(CPUAVRState *env, DisasContext *ctx, 
uint32_t opcode)
  *  signed value by two without changing its sign. The Carry Flag can be used 
to
  *  round the result.
  */
-int avr_translate_ASR(CPUAVRState *env, 

[Qemu-devel] [PATCH v18 06/13] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-7-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 target-avr/cpu.h   |  10 +++
 target-avr/helper.c| 216 -
 target-avr/helper.h|   7 ++
 target-avr/translate.c |   8 ++
 4 files changed, 239 insertions(+), 2 deletions(-)

diff --git a/target-avr/cpu.h b/target-avr/cpu.h
index 54dc58c..9214324 100644
--- a/target-avr/cpu.h
+++ b/target-avr/cpu.h
@@ -139,6 +139,7 @@ struct CPUAVRState {
 uint32_t sp; /* 16 bits */
 
 uint64_t intsrc; /* interrupt sources */
+bool fullacc;/* CPU/MEM if true MEM only otherwise */
 
 uint32_t features;
 
@@ -181,6 +182,10 @@ int avr_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, 
int rw,
 int avr_cpu_memory_rw_debug(CPUState *cs, vaddr address, uint8_t *buf,
 int len, bool is_write);
 
+enum {
+TB_FLAGS_FULL_ACCESS = 1,
+};
+
 static inline void cpu_get_tb_cpu_state(CPUAVRState *env, target_ulong *pc,
 target_ulong *cs_base, uint32_t *pflags)
 {
@@ -188,6 +193,11 @@ static inline void cpu_get_tb_cpu_state(CPUAVRState *env, 
target_ulong *pc,
 
 *pc = env->pc_w * 2;
 *cs_base = 0;
+
+if (env->fullacc) {
+flags |= TB_FLAGS_FULL_ACCESS;
+}
+
 *pflags = flags;
 }
 
diff --git a/target-avr/helper.c b/target-avr/helper.c
index 61255fd..bc53053 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -28,6 +28,7 @@
 #include "exec/cpu_ldst.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
+#include "exec/ioport.h"
 
 bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
@@ -79,11 +80,11 @@ void avr_cpu_do_interrupt(CPUState *cs)
 
 if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
 cpu_stb_data(env, env->sp--, (ret & 0xff));
-cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >>  8);
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
 cpu_stb_data(env, env->sp--, (ret & 0xff) >> 16);
 } else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
 cpu_stb_data(env, env->sp--, (ret & 0xff));
-cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >>  8);
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >> 8);
 } else {
 cpu_stb_data(env, env->sp--, (ret & 0xff));
 }
@@ -126,7 +127,19 @@ void tlb_fill(CPUState *cs, target_ulong vaddr, 
MMUAccessType access_type,
 if (mmu_idx == MMU_CODE_IDX) {
 paddr = PHYS_BASE_CODE + vaddr - VIRT_BASE_CODE;
 prot = PAGE_READ | PAGE_EXEC;
+} else if (vaddr - VIRT_BASE_REGS < AVR_REGS) {
+/*
+ * this is a write into CPU registers, exit and rebuilt this TB
+ * to use full write
+ */
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+env->fullacc = 1;
+cpu_loop_exit_restore(cs, retaddr);
 } else {
+/*
+ * this is a write into memory. nothing special
+ */
 paddr = PHYS_BASE_DATA + vaddr - VIRT_BASE_DATA;
 prot = PAGE_READ | PAGE_WRITE;
 }
@@ -134,6 +147,30 @@ void tlb_fill(CPUState *cs, target_ulong vaddr, 
MMUAccessType access_type,
 tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, prot, mmu_idx, page_size);
 }
 
+void helper_sleep(CPUAVRState *env)
+{
+CPUState *cs = CPU(avr_env_get_cpu(env));
+
+cs->exception_index = EXCP_HLT;
+cpu_loop_exit(cs);
+}
+
+void helper_unsupported(CPUAVRState *env)
+{
+CPUState *cs = CPU(avr_env_get_cpu(env));
+
+/*
+ *  I count not find what happens on the real platform, so
+ *  it's EXCP_DEBUG for meanwhile
+ */
+cs->exception_index = EXCP_DEBUG;
+if (qemu_loglevel_mask(LOG_UNIMP)) {
+qemu_log("UNSUPPORTED\n");
+cpu_dump_state(cs, qemu_logfile, fprintf, 0);
+}
+cpu_loop_exit(cs);
+}
+
 void helper_debug(CPUAVRState *env)
 {
 CPUState *cs = CPU(avr_env_get_cpu(env));
@@ -141,3 +178,178 @@ void helper_debug(CPUAVRState *env)
 cs->exception_index = EXCP_DEBUG;
 cpu_loop_exit(cs);
 }
+
+void helper_wdr(CPUAVRState *env)
+{
+CPUState *cs = CPU(avr_env_get_cpu(env));
+
+/* WD is not implemented yet, placeholder */
+cs->exception_index = EXCP_DEBUG;
+cpu_loop_exit(cs);
+}
+
+/*
+ * This function implements IN instruction
+ *
+ * It does the following
+ * a.  if an IO register belongs to CPU, its value is read and returned
+ * b.  otherwise io address is translated to mem address and physical memory
+ * is read.
+ * c.  it caches the value for sake of SBI, SBIC, SBIS & CBI implementation
+ *
+ */
+target_ulong helper_inb(CPUAVRState *env, uint32_t port)
+{
+target_ulong data = 0;
+
+switch (port) {
+case 0x38: /* RAMPD */
+data = 0xff & (env->rampD >> 16);
+break;
+case 0x39: /* RAMPX */
+data = 0xff & (env->rampX >> 

[Qemu-devel] [PATCH v18 12/13] target-avr: Respect .inc.c convention

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target-avr/{decode.c => decode.inc.c} | 0
 target-avr/{translate-inst.c => translate-inst.inc.c} | 0
 target-avr/translate.c| 4 ++--
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename target-avr/{decode.c => decode.inc.c} (100%)
 rename target-avr/{translate-inst.c => translate-inst.inc.c} (100%)

diff --git a/target-avr/decode.c b/target-avr/decode.inc.c
similarity index 100%
rename from target-avr/decode.c
rename to target-avr/decode.inc.c
diff --git a/target-avr/translate-inst.c b/target-avr/translate-inst.inc.c
similarity index 100%
rename from target-avr/translate-inst.c
rename to target-avr/translate-inst.inc.c
diff --git a/target-avr/translate.c b/target-avr/translate.c
index cb99b49..657e034 100644
--- a/target-avr/translate.c
+++ b/target-avr/translate.c
@@ -105,8 +105,8 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 
 #include "exec/gen-icount.h"
 #include "translate-inst.h"
-#include "translate-inst.c"
-#include "decode.c"
+#include "translate-inst.inc.c"
+#include "decode.inc.c"
 
 void avr_translate_init(void)
 {
-- 
2.7.4




[Qemu-devel] [PATCH v18 08/13] target-avr: instruction decoder generator

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-9-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 target-avr/cpugen/CMakeLists.txt   |  38 +++
 target-avr/cpugen/README.md|  17 ++
 target-avr/cpugen/cpu/avr.yaml | 213 ++
 target-avr/cpugen/src/CMakeLists.txt   |  62 
 target-avr/cpugen/src/cpugen.cpp   | 457 +
 target-avr/cpugen/src/utils.cpp|  26 ++
 target-avr/cpugen/src/utils.h  |  78 +
 target-avr/cpugen/xsl/decode.c.xsl | 103 +++
 target-avr/cpugen/xsl/translate-inst.h.xsl | 118 
 target-avr/cpugen/xsl/utils.xsl| 108 +++
 10 files changed, 1220 insertions(+)
 create mode 100644 target-avr/cpugen/CMakeLists.txt
 create mode 100644 target-avr/cpugen/README.md
 create mode 100644 target-avr/cpugen/cpu/avr.yaml
 create mode 100644 target-avr/cpugen/src/CMakeLists.txt
 create mode 100644 target-avr/cpugen/src/cpugen.cpp
 create mode 100644 target-avr/cpugen/src/utils.cpp
 create mode 100644 target-avr/cpugen/src/utils.h
 create mode 100644 target-avr/cpugen/xsl/decode.c.xsl
 create mode 100644 target-avr/cpugen/xsl/translate-inst.h.xsl
 create mode 100644 target-avr/cpugen/xsl/utils.xsl

diff --git a/target-avr/cpugen/CMakeLists.txt b/target-avr/cpugen/CMakeLists.txt
new file mode 100644
index 000..ded391c
--- /dev/null
+++ b/target-avr/cpugen/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(cpugen)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -ggdb -g3")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+
+set(Boost_USE_STATIC_LIBS   ON)
+find_package(
+Boost 1.60.0
+REQUIRED
+COMPONENTS
+system
+regex)
+#set(BUILD_SHARED_LIBS   OFF)
+#set(BUILD_STATIC_LIBS   ON)
+add_subdirectory(tinyxml2)
+add_subdirectory(yaml-cpp)
+
+include_directories(
+${CMAKE_CURRENT_SOURCE_DIR}
+${CMAKE_CURRENT_SOURCE_DIR}/..
+${CMAKE_CURRENT_SOURCE_DIR}/../yaml-cpp/include
+${Boost_INCLUDE_DIRS}
+)
+
+add_executable(
+cpugen
+src/cpugen.cpp
+src/utils.cpp
+)
+
+target_link_libraries(
+cpugen
+yaml-cpp
+tinyxml2
+${Boost_LIBRARIES}
+)
diff --git a/target-avr/cpugen/README.md b/target-avr/cpugen/README.md
new file mode 100644
index 000..f0caa8b
--- /dev/null
+++ b/target-avr/cpugen/README.md
@@ -0,0 +1,17 @@
+# CPUGEN
+## How to build
+within ```cpugen``` directory do
+```
+git clone https://github.com/leethomason/tinyxml2
+git clone https://github.com/jbeder/yaml-cpp
+mkdir build
+cd build
+cmake ..
+make
+```
+## How to use
+```
+cpugen ../cpu/avr.yaml
+xsltproc ../xsl/decode.c.xsl output.xml > ../../decode.c
+xsltproc ../xsl/translate-inst.h.xsl output.xml > ../../translate-inst.h
+```
diff --git a/target-avr/cpugen/cpu/avr.yaml b/target-avr/cpugen/cpu/avr.yaml
new file mode 100644
index 000..c36b628
--- /dev/null
+++ b/target-avr/cpugen/cpu/avr.yaml
@@ -0,0 +1,213 @@
+cpu:
+name: avr
+instructions:
+- ADC:
+opcode: 0001 11 hRr[1] Rd[5] lRr[4]
+- ADD:
+opcode:  11 hRr[1] Rd[5] lRr[4]
+- ADIW:
+opcode: 1001 0110 hImm[2] Rd[2] lImm[4]
+- AND:
+opcode: 0010 00 hRr[1] Rd[5] lRr[4]
+- ANDI:
+opcode: 0111 hImm[4] Rd[4] lImm[4]
+- ASR:
+opcode: 1001 010 Rd[5] 0101
+- BCLR:
+opcode: 1001 0100 1 Bit[3] 1000
+- BLD:
+opcode:  100 Rd[5] 0 Bit[3]
+- BRBC:
+opcode:  01 Imm[7] Bit[3]
+- BRBS:
+opcode:  00 Imm[7] Bit[3]
+- BREAK:
+opcode: 1001 0101 1001 1000
+- BSET:
+opcode: 1001 0100 0 Bit[3] 1000
+- BST:
+opcode:  101 Rd[5] 0 Bit[3]
+- CALL:
+opcode: 1001 010 hImm[5] 111 lImm[17]
+- CBI:
+opcode: 1001 1000 Imm[5] Bit[3]
+- COM:
+opcode: 1001 010 Rd[5] 
+- CP:
+opcode: 0001 01 hRr[1] Rd[5] lRr[4]
+- CPC:
+opcode:  01 hRr[1] Rd[5] lRr[4]
+- CPI:
+opcode: 0011 hImm[4] Rd[4] lImm[4]
+- CPSE:
+opcode: 0001 00 hRr[1] Rd[5] lRr[4]
+- DEC:
+opcode: 1001 010 Rd[5] 1010
+- DES:
+opcode: 1001 0100 Imm[4] 1011
+- EICALL:
+opcode: 1001 0101 0001 1001
+- EIJMP:
+opcode: 1001 0100 0001 1001
+- ELPM1:
+opcode: 1001 0101 1101 1000
+- ELPM2:
+opcode: 1001 000 Rd[5] 0110
+- ELPMX:
+opcode: 1001 000 Rd[5] 0111
+- EOR:
+opcode: 0010 01 hRr[1] Rd[5] lRr[4]
+- FMUL:
+opcode:  0011 0 Rd[3] 1 Rr[3]
+- FMULS:
+opcode:  0011 1 Rd[3] 0 Rr[3]

[Qemu-devel] [PATCH v18 04/13] target-avr: adding instructions encodings

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-5-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 target-avr/translate-inst.h | 804 
 1 file changed, 804 insertions(+)
 create mode 100644 target-avr/translate-inst.h

diff --git a/target-avr/translate-inst.h b/target-avr/translate-inst.h
new file mode 100644
index 000..af2e076
--- /dev/null
+++ b/target-avr/translate-inst.h
@@ -0,0 +1,804 @@
+/*
+ *  QEMU AVR CPU
+ *
+ *  Copyright (c) 2016 Michael Rolnik
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, see
+ *  
+ */
+
+#ifndef AVR_TRANSLATE_INST_H_
+#define AVR_TRANSLATE_INST_H_
+
+typedef struct DisasContext DisasContext;
+
+int avr_translate_NOP(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+
+int avr_translate_MOVW(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t MOVW_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+
+static inline uint32_t MOVW_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULS(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t MULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 4);
+}
+
+static inline uint32_t MULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 4);
+}
+
+int avr_translate_MULSU(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t MULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t MULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMUL(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t FMUL_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t FMUL_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULS(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t FMULS_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t FMULS_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_FMULSU(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t FMULSU_Rr(uint32_t opcode)
+{
+return extract32(opcode, 0, 3);
+}
+
+static inline uint32_t FMULSU_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 3);
+}
+
+int avr_translate_CPC(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t CPC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t CPC_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+int avr_translate_SBC(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t SBC_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t SBC_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+int avr_translate_ADD(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t ADD_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t ADD_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+int avr_translate_AND(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t AND_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t AND_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+int avr_translate_EOR(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t EOR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t EOR_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+(extract32(opcode, 0, 4));
+}
+
+int avr_translate_OR(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);
+static inline uint32_t OR_Rd(uint32_t opcode)
+{
+return extract32(opcode, 4, 5);
+}
+
+static inline uint32_t OR_Rr(uint32_t opcode)
+{
+return (extract32(opcode, 9, 1) << 4) |
+

[Qemu-devel] [PATCH v18 02/13] target-avr: adding AVR CPU features/flavors

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-3-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 target-avr/cpu.c | 311 +++
 target-avr/cpu.h |  48 +
 2 files changed, 359 insertions(+)

diff --git a/target-avr/cpu.c b/target-avr/cpu.c
index ed2b1b8..cf66197 100644
--- a/target-avr/cpu.c
+++ b/target-avr/cpu.c
@@ -200,12 +200,323 @@ static void avr_cpu_class_init(ObjectClass *oc, void 
*data)
 dc->cannot_destroy_with_object_finalize_yet = true;
 }
 
+static void avr_avr1_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+}
+
+static void avr_avr2_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env, AVR_FEATURE_SRAM);
+avr_set_feature(env, AVR_FEATURE_BREAK);
+
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+}
+
+static void avr_avr25_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env, AVR_FEATURE_SRAM);
+avr_set_feature(env, AVR_FEATURE_BREAK);
+
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env, AVR_FEATURE_LPMX);
+avr_set_feature(env, AVR_FEATURE_MOVW);
+}
+
+static void avr_avr3_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env, AVR_FEATURE_SRAM);
+avr_set_feature(env, AVR_FEATURE_BREAK);
+
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr31_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env, AVR_FEATURE_SRAM);
+avr_set_feature(env, AVR_FEATURE_BREAK);
+
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env, AVR_FEATURE_RAMPZ);
+avr_set_feature(env, AVR_FEATURE_ELPM);
+avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+}
+
+static void avr_avr35_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env, AVR_FEATURE_SRAM);
+avr_set_feature(env, AVR_FEATURE_BREAK);
+
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+avr_set_feature(env, AVR_FEATURE_LPMX);
+avr_set_feature(env, AVR_FEATURE_MOVW);
+}
+
+static void avr_avr4_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env, AVR_FEATURE_SRAM);
+avr_set_feature(env, AVR_FEATURE_BREAK);
+
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env, AVR_FEATURE_LPMX);
+avr_set_feature(env, AVR_FEATURE_MOVW);
+avr_set_feature(env, AVR_FEATURE_MUL);
+}
+
+static void avr_avr5_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, AVR_FEATURE_IJMP_ICALL);
+avr_set_feature(env, AVR_FEATURE_ADIW_SBIW);
+avr_set_feature(env, AVR_FEATURE_SRAM);
+avr_set_feature(env, AVR_FEATURE_BREAK);
+
+avr_set_feature(env, AVR_FEATURE_2_BYTE_PC);
+avr_set_feature(env, AVR_FEATURE_2_BYTE_SP);
+avr_set_feature(env, AVR_FEATURE_JMP_CALL);
+avr_set_feature(env, AVR_FEATURE_LPMX);
+avr_set_feature(env, AVR_FEATURE_MOVW);
+avr_set_feature(env, AVR_FEATURE_MUL);
+}
+
+static void avr_avr51_initfn(Object *obj)
+{
+AVRCPU *cpu = AVR_CPU(obj);
+CPUAVRState *env = >env;
+
+avr_set_feature(env, AVR_FEATURE_LPM);
+avr_set_feature(env, 

[Qemu-devel] [PATCH v18 01/13] target-avr: AVR cores support is added.

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

1. basic CPU structure
2. registers
3. no instructions
4. saving sreg, rampD, rampX, rampY, rampD, eind in HW representation

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-2-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 MAINTAINERS |   5 +
 arch_init.c |   2 +
 configure   |   5 +
 default-configs/avr-softmmu.mak |  21 +++
 include/disas/bfd.h |   6 +
 include/sysemu/arch_init.h  |   1 +
 target-avr/Makefile.objs|  23 
 target-avr/cpu-qom.h|  84 
 target-avr/cpu.c| 291 
 target-avr/cpu.h| 179 
 target-avr/gdbstub.c|  85 
 target-avr/helper.c |  88 
 target-avr/helper.h |  21 +++
 target-avr/machine.c| 114 
 target-avr/translate.c  | 255 +++
 target-avr/translate.h  | 114 
 16 files changed, 1294 insertions(+)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 target-avr/Makefile.objs
 create mode 100644 target-avr/cpu-qom.h
 create mode 100644 target-avr/cpu.c
 create mode 100644 target-avr/cpu.h
 create mode 100644 target-avr/gdbstub.c
 create mode 100644 target-avr/helper.c
 create mode 100644 target-avr/helper.h
 create mode 100644 target-avr/machine.c
 create mode 100644 target-avr/translate.c
 create mode 100644 target-avr/translate.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7d43026..e526316 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -111,6 +111,11 @@ F: disas/arm.c
 F: disas/arm-a64.cc
 F: disas/libvixl/
 
+AVR
+M: Michael Rolnik 
+S: Maintained
+F: target-avr/
+
 CRIS
 M: Edgar E. Iglesias 
 S: Maintained
diff --git a/arch_init.c b/arch_init.c
index fa05973..be6e6de 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -80,6 +80,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_UNICORE32
 #elif defined(TARGET_TRICORE)
 #define QEMU_ARCH QEMU_ARCH_TRICORE
+#elif defined(TARGET_AVR)
+#define QEMU_ARCH QEMU_ARCH_AVR
 #endif
 
 const uint32_t arch_type = QEMU_ARCH;
diff --git a/configure b/configure
index 7d083bd..737a22e 100755
--- a/configure
+++ b/configure
@@ -5696,6 +5696,8 @@ case "$target_name" in
 bflt="yes"
 gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml 
arm-vfp3.xml arm-neon.xml"
   ;;
+  avr)
+  ;;
   cris)
   ;;
   lm32)
@@ -5894,6 +5896,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   disas_config "ARM_A64"
 fi
   ;;
+  avr)
+disas_config "AVR"
+  ;;
   cris)
 disas_config "CRIS"
   ;;
diff --git a/default-configs/avr-softmmu.mak b/default-configs/avr-softmmu.mak
new file mode 100644
index 000..003465d
--- /dev/null
+++ b/default-configs/avr-softmmu.mak
@@ -0,0 +1,21 @@
+#
+#  QEMU AVR CPU
+#
+#  Copyright (c) 2016 Michael Rolnik
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, see
+#  
+#
+
+# Default configuration for avr-softmmu
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 8a3488c..8ccd108 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -213,6 +213,12 @@ enum bfd_architecture
 #define bfd_mach_m32r  0  /* backwards compatibility */
   bfd_arch_mn10200,/* Matsushita MN10200 */
   bfd_arch_mn10300,/* Matsushita MN10300 */
+  bfd_arch_avr,   /* Atmel AVR microcontrollers.  */
+#define bfd_mach_avr1  1
+#define bfd_mach_avr2  2
+#define bfd_mach_avr3  3
+#define bfd_mach_avr4  4
+#define bfd_mach_avr5  5
   bfd_arch_cris,   /* Axis CRIS */
 #define bfd_mach_cris_v0_v10   255
 #define bfd_mach_cris_v32  32
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 1c9dad1..7c9edbf 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -23,6 +23,7 @@ enum {
 QEMU_ARCH_UNICORE32 = (1 << 14),
 QEMU_ARCH_MOXIE = (1 << 15),
 QEMU_ARCH_TRICORE = (1 << 16),
+QEMU_ARCH_AVR = (1 << 17),
 };
 
 extern const uint32_t arch_type;
diff --git a/target-avr/Makefile.objs b/target-avr/Makefile.objs
new file mode 100644

[Qemu-devel] [PATCH v18 03/13] target-avr: adding a sample AVR board

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-4-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 MAINTAINERS  |   1 +
 hw/avr/Makefile.objs |  21 ++
 hw/avr/sample.c  | 111 +++
 3 files changed, 133 insertions(+)
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/sample.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e526316..3f36b06 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -115,6 +115,7 @@ AVR
 M: Michael Rolnik 
 S: Maintained
 F: target-avr/
+F: hw/avr/
 
 CRIS
 M: Edgar E. Iglesias 
diff --git a/hw/avr/Makefile.objs b/hw/avr/Makefile.objs
new file mode 100644
index 000..8f537c9
--- /dev/null
+++ b/hw/avr/Makefile.objs
@@ -0,0 +1,21 @@
+#
+#  QEMU AVR CPU
+#
+#  Copyright (c) 2016 Michael Rolnik
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, see
+#  
+#
+
+obj-y += sample.o
diff --git a/hw/avr/sample.c b/hw/avr/sample.c
new file mode 100644
index 000..6d15646
--- /dev/null
+++ b/hw/avr/sample.c
@@ -0,0 +1,111 @@
+/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+
+/*
+ *  NOTE:
+ *  This is not a real AVR board !!! This is an example !!!
+ *
+ *This example can be used to build a real AVR board.
+ *
+ *  This example board loads provided binary file into flash memory and
+ *  executes it from 0x address in the code memory space.
+ *
+ *  Currently used for AVR CPU validation
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
+#include "ui/console.h"
+#include "hw/boards.h"
+#include "hw/devices.h"
+#include "hw/loader.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "include/hw/sysbus.h"
+
+#define VIRT_BASE_FLASH 0x
+#define VIRT_BASE_ISRAM 0x0100
+#define VIRT_BASE_EXMEM 0x1100
+#define VIRT_BASE_EEPROM 0x
+
+#define SIZE_FLASH 0x0002
+#define SIZE_ISRAM 0x1000
+#define SIZE_EXMEM 0x0001
+#define SIZE_EEPROM 0x1000
+#define SIZE_IOREG SIZE_REGS
+
+#define PHYS_BASE_FLASH (PHYS_BASE_CODE)
+
+#define PHYS_BASE_ISRAM (PHYS_BASE_DATA)
+#define PHYS_BASE_EXMEM (PHYS_BASE_ISRAM + SIZE_ISRAM)
+#define PHYS_BASE_EEPROM (PHYS_BASE_EXMEM + SIZE_EXMEM)
+
+#define PHYS_BASE_IOREG (PHYS_BASE_REGS + 0x20)
+
+static void sample_init(MachineState *machine)
+{
+MemoryRegion *address_space_mem;
+MemoryRegion *ram;
+MemoryRegion *flash;
+unsigned ram_size = SIZE_ISRAM + SIZE_EXMEM;
+AVRCPU *cpu_avr ATTRIBUTE_UNUSED;
+const char *firmware = NULL;
+const char *filename;
+
+address_space_mem = get_system_memory();
+ram = g_new(MemoryRegion, 1);
+flash = g_new(MemoryRegion, 1);
+
+cpu_avr = cpu_avr_init("avr5");
+
+memory_region_allocate_system_memory(ram, NULL, "avr.ram", ram_size);
+memory_region_add_subregion(address_space_mem, PHYS_BASE_ISRAM, ram);
+
+memory_region_init_rom(flash, NULL, "avr.flash", SIZE_FLASH, _fatal);
+memory_region_add_subregion(address_space_mem, PHYS_BASE_FLASH, flash);
+vmstate_register_ram_global(flash);
+
+if (machine->firmware) {
+firmware = machine->firmware;
+}
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware);
+if (!filename) {
+error_report("Could not find flash image file '%s'", firmware);
+exit(1);
+}
+
+load_image_targphys(filename, PHYS_BASE_FLASH, 

[Qemu-devel] [PATCH v18 00/13] AVR target

2016-09-16 Thread Richard Henderson
This is Michael's v17, with some adjustments of my own:

(1) Fix the whitespace errors reported by "git am",
(2) Replace the utf-8 characters with normal ascii,
(3) Ditch the separate compilation of translate.c.

I retained the two separate files that could be regenerated
from the included cpugen program, but merged in translate-insn.c.
Not that it matters, but the code generated is about 3k smaller.


r~


Michael Rolnik (9):
  target-avr: AVR cores support is added.
  target-avr: adding AVR CPU features/flavors
  target-avr: adding a sample AVR board
  target-avr: adding instructions encodings
  target-avr: adding AVR interrupt handling
  target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported
instructions
  target-avr: adding instruction translation
  target-avr: instruction decoder generator
  target-avr: adding instruction decoder

Richard Henderson (4):
  target-avr: Put env pointer in DisasContext
  target-avr: Put all translation code into one compilation unit
  target-avr: Respect .inc.c convention
  target-avr: Merge translate-inst.inc.c into translate.c

 MAINTAINERS|6 +
 arch_init.c|2 +
 configure  |5 +
 default-configs/avr-softmmu.mak|   21 +
 hw/avr/Makefile.objs   |   21 +
 hw/avr/sample.c|  111 ++
 include/disas/bfd.h|6 +
 include/sysemu/arch_init.h |1 +
 target-avr/Makefile.objs   |   23 +
 target-avr/cpu-qom.h   |   84 +
 target-avr/cpu.c   |  602 ++
 target-avr/cpu.h   |  237 +++
 target-avr/cpugen/CMakeLists.txt   |   38 +
 target-avr/cpugen/README.md|   17 +
 target-avr/cpugen/cpu/avr.yaml |  213 ++
 target-avr/cpugen/src/CMakeLists.txt   |   62 +
 target-avr/cpugen/src/cpugen.cpp   |  457 +
 target-avr/cpugen/src/utils.cpp|   26 +
 target-avr/cpugen/src/utils.h  |   78 +
 target-avr/cpugen/xsl/decode.c.xsl |  103 +
 target-avr/cpugen/xsl/translate-inst.h.xsl |  118 ++
 target-avr/cpugen/xsl/utils.xsl|  108 ++
 target-avr/decode.inc.c|  689 +++
 target-avr/gdbstub.c   |   85 +
 target-avr/helper.c|  355 
 target-avr/helper.h|   28 +
 target-avr/machine.c   |  114 ++
 target-avr/translate-inst.h|  691 +++
 target-avr/translate.c | 2911 
 29 files changed, 7212 insertions(+)
 create mode 100644 default-configs/avr-softmmu.mak
 create mode 100644 hw/avr/Makefile.objs
 create mode 100644 hw/avr/sample.c
 create mode 100644 target-avr/Makefile.objs
 create mode 100644 target-avr/cpu-qom.h
 create mode 100644 target-avr/cpu.c
 create mode 100644 target-avr/cpu.h
 create mode 100644 target-avr/cpugen/CMakeLists.txt
 create mode 100644 target-avr/cpugen/README.md
 create mode 100644 target-avr/cpugen/cpu/avr.yaml
 create mode 100644 target-avr/cpugen/src/CMakeLists.txt
 create mode 100644 target-avr/cpugen/src/cpugen.cpp
 create mode 100644 target-avr/cpugen/src/utils.cpp
 create mode 100644 target-avr/cpugen/src/utils.h
 create mode 100644 target-avr/cpugen/xsl/decode.c.xsl
 create mode 100644 target-avr/cpugen/xsl/translate-inst.h.xsl
 create mode 100644 target-avr/cpugen/xsl/utils.xsl
 create mode 100644 target-avr/decode.inc.c
 create mode 100644 target-avr/gdbstub.c
 create mode 100644 target-avr/helper.c
 create mode 100644 target-avr/helper.h
 create mode 100644 target-avr/machine.c
 create mode 100644 target-avr/translate-inst.h
 create mode 100644 target-avr/translate.c

-- 
2.7.4




[Qemu-devel] [PATCH v18 05/13] target-avr: adding AVR interrupt handling

2016-09-16 Thread Richard Henderson
From: Michael Rolnik 

Signed-off-by: Michael Rolnik 
Message-Id: <1471522070-77598-6-git-send-email-mrol...@gmail.com>
Signed-off-by: Richard Henderson 
---
 target-avr/helper.c | 55 +
 1 file changed, 55 insertions(+)

diff --git a/target-avr/helper.c b/target-avr/helper.c
index c187193..61255fd 100644
--- a/target-avr/helper.c
+++ b/target-avr/helper.c
@@ -32,11 +32,66 @@
 bool avr_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
 bool ret = false;
+CPUClass *cc = CPU_GET_CLASS(cs);
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+if (interrupt_request & CPU_INTERRUPT_RESET) {
+if (cpu_interrupts_enabled(env)) {
+cs->exception_index = EXCP_RESET;
+cc->do_interrupt(cs);
+
+cs->interrupt_request &= ~CPU_INTERRUPT_RESET;
+
+ret = true;
+}
+}
+if (interrupt_request & CPU_INTERRUPT_HARD) {
+if (cpu_interrupts_enabled(env) && env->intsrc != 0) {
+int index = ctz32(env->intsrc);
+cs->exception_index = EXCP_INT(index);
+cc->do_interrupt(cs);
+
+env->intsrc &= env->intsrc - 1; /* clear the interrupt */
+cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
+
+ret = true;
+}
+}
 return ret;
 }
 
 void avr_cpu_do_interrupt(CPUState *cs)
 {
+AVRCPU *cpu = AVR_CPU(cs);
+CPUAVRState *env = >env;
+
+uint32_t ret = env->pc_w;
+int vector = 0;
+int size = avr_feature(env, AVR_FEATURE_JMP_CALL) ? 2 : 1;
+int base = 0; /* TODO: where to get it */
+
+if (cs->exception_index == EXCP_RESET) {
+vector = 0;
+} else if (env->intsrc != 0) {
+vector = ctz32(env->intsrc) + 1;
+}
+
+if (avr_feature(env, AVR_FEATURE_3_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >>  8);
+cpu_stb_data(env, env->sp--, (ret & 0xff) >> 16);
+} else if (avr_feature(env, AVR_FEATURE_2_BYTE_PC)) {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+cpu_stb_data(env, env->sp--, (ret & 0x00ff00) >>  8);
+} else {
+cpu_stb_data(env, env->sp--, (ret & 0xff));
+}
+
+env->pc_w = base + vector * size;
+env->sregI = 0; /* clear Global Interrupt Flag */
+
+cs->exception_index = -1;
 }
 
 int avr_cpu_memory_rw_debug(CPUState *cs, vaddr addr, uint8_t *buf,
-- 
2.7.4




[Qemu-devel] stack size limit issues with xen + qemu + rbd

2016-09-16 Thread Chris Patterson
I have spent some time investigating a case where qemu is failing to
register xenstore watches for a PV guest once I enable vfb (and
thereby triggering the creation of a qemu instance).

The qemu logs show something along the lines of:
xen be core: xen be core: xen be: watching backend path
(backend/console/3) failed
xen be: watching backend path (backend/console/3) failed
xen be core: xen be core: xen be: watching backend path (backend/vkbd/3) failed
xen be: watching backend path (backend/vkbd/3) failed
xen be core: xen be core: xen be: watching backend path (backend/qdisk/3) failed
xen be: watching backend path (backend/qdisk/3) failed
xen be core: xen be core: xen be: watching backend path (backend/qusb/3) failed
xen be: watching backend path (backend/qusb/3) failed
xen be core: xen be core: xen be: watching backend path (backend/vfb/3) failed
xen be: watching backend path (backend/vfb/3) failed
xen be core: xen be core: xen be: watching backend path (backend/qnic/3) failed
xen be: watching backend path (backend/qnic/3) failed

I have tested qemu master, qemu-xen in the master xen tree, as well as
a few tags all with the same issue.

I came across a similar issue reported by Juergen Gross:
https://lists.nongnu.org/archive/html/qemu-devel/2016-07/msg03341.html

Sure enough, the thread stack size was the culprit.  I had been
testing with qemu with the associated fix "vnc-tight: fix regression
with libxenstore" as it is in master, so that wasn't it...

I did some basic analysis of the qemu binary and the libraries it is pulling in:

for lib in $(ldd /usr/local/bin/qemu-system-i386 | grep -o '/.* '); do
echo "lib=$lib"; readelf -S "$lib" | grep -e tbss -e tdata -A1 ; done

The largest consumers were:
lib=/usr/lib/x86_64-linux-gnu/librbd.so.1
  [17] .tbss NOBITS   0088fed0  0068fed0
   1820   WAT   0 0 8
lib=/usr/lib/x86_64-linux-gnu/librados.so.2
  [17] .tbss NOBITS   00718600  00518600
   0aa0   WAT   0 0 8

IIUC, librbd & librados are using nearly 9k of the 16k alone (I am
assuming this thread-local storage must be consumed as part of the
thread's stack)?

I narrowed that down to Ceph's usage of __thread in stringify() in
src/include/stringify.h.

To make things functional, the options were either to:
(a) disable rbd at configure time for qemu
(b) reduce the level of thread-local storage in dependencies
(particularly ceph's stringify)
(c) increase the stack size specified in xenstore's xs.c

Is there is any precedent/policy with regards to expected TLS and/or
stack usage for dependencies?  Is the best course of action (b)? Or
perhaps reconsider the default size for (c)?

Thoughts? :)



Re: [Qemu-devel] [PATCH 2/2] linux-user: remove #define smp_{cores, threads}

2016-09-16 Thread Eduardo Habkost
On Fri, Sep 16, 2016 at 07:50:24PM +0400, Marc-André Lureau wrote:
> Those are unneeded now that CPUState nr_{cores,threads} is always
> initialized.
> 
> Signed-off-by: Marc-André Lureau 

Reviewed-by: Eduardo Habkost 

I will wait for at least an Acked-by from the PPC maintainers
before I merge it, though.

> ---
>  target-i386/cpu.c   | 8 
>  target-ppc/translate_init.c | 3 ++-
>  include/sysemu/cpus.h   | 5 +
>  3 files changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 5a5299a..e863bea 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -2490,13 +2490,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>  
>  switch (count) {
>  case 0:
> -*eax = apicid_core_offset(smp_cores, smp_threads);
> -*ebx = smp_threads;
> +*eax = apicid_core_offset(cs->nr_cores, cs->nr_threads);
> +*ebx = cs->nr_threads;
>  *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
>  break;
>  case 1:
> -*eax = apicid_pkg_offset(smp_cores, smp_threads);
> -*ebx = smp_cores * smp_threads;
> +*eax = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
> +*ebx = cs->nr_cores * cs->nr_threads;
>  *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
>  break;
>  default:
> diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
> index 407ccb9..b66b40b 100644
> --- a/target-ppc/translate_init.c
> +++ b/target-ppc/translate_init.c
> @@ -9943,7 +9943,8 @@ static void ppc_cpu_unrealizefn(DeviceState *dev, Error 
> **errp)
>  
>  int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
>  {
> -int ret = MIN(smp_threads, kvmppc_smt_threads());
> +CPUState *cs = CPU(cpu);
> +int ret = MIN(cs->nr_threads, kvmppc_smt_threads());
>  
>  switch (cpu->cpu_version) {
>  case CPU_POWERPC_LOGICAL_2_05:
> diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
> index fe992a8..3728a1e 100644
> --- a/include/sysemu/cpus.h
> +++ b/include/sysemu/cpus.h
> @@ -29,12 +29,9 @@ void qtest_clock_warp(int64_t dest);
>  
>  #ifndef CONFIG_USER_ONLY
>  /* vl.c */
> +/* *-user doesn't have configurable SMP topology */
>  extern int smp_cores;
>  extern int smp_threads;
> -#else
> -/* *-user doesn't have configurable SMP topology */
> -#define smp_cores   1
> -#define smp_threads 1
>  #endif
>  
>  void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
> -- 
> 2.10.0
> 

-- 
Eduardo



Re: [Qemu-devel] [PATCH v6 7/7] linux-user: Add missing Mips syscalls items in strace.list

2016-09-16 Thread Laurent Vivier


Le 16/09/2016 à 13:14, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic 
> 
> Without this patch, a number of Mips syscalls will be logged in the following
> way (in this examople, this is an invocation of accept4()):
> 
>   86906 Unknown syscall 4334
> 
> This patch provides standard Qemu's strace output for such cases, like this:
> 
>   95861 accept4(3,1996486000,1996486016,128,0,0) = 5
> 
> Such output may be further improvad by providing strace-related functions
> that handle only particular syscalls, but this is beyond the scope of
> this patch.
> 
> Signed-off-by: Aleksandar Markovic 
> ---
>  linux-user/strace.list | 114 
> +
>  1 file changed, 114 insertions(+)

Nice work, we should update strace.list each time we add a syscall (and
personally I don't, it's bad).

How did you choose the list of syscalls to add in this list as some of
them are not implemented in syscall.c?
[for instance "kcmp", I have the patch for it but I don't think I've
already sent it]

Laurent



Re: [Qemu-devel] [PATCH v6 5/7] linux-user: Fix certain argument alignment cases for Mips64

2016-09-16 Thread Laurent Vivier


Le 16/09/2016 à 13:14, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic 
> 
> The function that is changed in this patch is supposed to indicate that
> there was certaing argument rearangement related to 64-bit arguments on
> 32-bit platforms. The background on such rearangements can be found,
> for example, in the man page for syscall(2).
> 
> However, for 64-bit Mips architectures there is no such rearangement,
> and this patch reflects it.
> 
> Signed-off-by: Aleksandar Rikalo 
> Signed-off-by: Aleksandar Markovic 
> ---
>  linux-user/syscall.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ca06943..ee23b29 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -620,7 +620,14 @@ static inline int regpairs_aligned(void *cpu_env) {
>  return CPUARMState *)cpu_env)->eabi) == 1) ;
>  }
>  #elif defined(TARGET_MIPS)
> -static inline int regpairs_aligned(void *cpu_env) { return 1; }
> +static inline int regpairs_aligned(void *cpu_env)
> +{
> +#if TARGET_ABI_BITS == 32
> +return 1;
> +#else
> +return 0;
> +#endif
> +}
>  #elif defined(TARGET_PPC) && !defined(TARGET_PPC64)
>  /* SysV AVI for PPC32 expects 64bit parameters to be passed on odd/even pairs
>   * of registers which translates to the same as ARM/MIPS, because we start 
> with
> 

To mimic PPC, would be cleaner with:

...
#elif defined(TARGET_MIPS) && TARGET_ABI_BITS == 32
static inline int regpairs_aligned(void *cpu_env) { return 1; }
#else
...

Laurent



Re: [Qemu-devel] [PATCH v6 6/7] linux-user: Add missing TARGET_EDQUOT error code for Mips

2016-09-16 Thread Laurent Vivier


Le 16/09/2016 à 13:14, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic 
> 
> EDQUOT is defined for Mips platform in Linux kernel in such a way
> that it has different value than on most other platforms. However,
> correspondant TARGET_EDQUOT for Mips is missing in Qemu code. Moreover,
> TARGET_EDQUOT is missing from the table for conversion of error codes
> from host to target. This patch fixes these problems.
> 
> Without this patch, syscalls add_key(), keyctl(), link(), mkdir(), mknod(),
> open(), rename(), request_key(), setxattr(), symlink(), and write() will not
> be able to return the right error code in some scenarios on Mips platform.
> (Some of these syscalls are not yet supported in Qemu, but once they are
> supported, they will need correct EDQUOT handling.)
> 
> Signed-off-by: Aleksandar Markovic 
Reviewed-by: Laurent Vivier 

> ---
>  linux-user/mips/target_syscall.h   | 2 ++
>  linux-user/mips64/target_syscall.h | 2 ++
>  linux-user/syscall.c   | 1 +
>  3 files changed, 5 insertions(+)
> 
> diff --git a/linux-user/mips/target_syscall.h 
> b/linux-user/mips/target_syscall.h
> index 2b4f390..827799f 100644
> --- a/linux-user/mips/target_syscall.h
> +++ b/linux-user/mips/target_syscall.h
> @@ -221,6 +221,8 @@ struct target_pt_regs {
>  #undef TARGET_ENOTRECOVERABLE
>  #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
>  
> +#undef TARGET_EDQUOT
> +#define TARGET_EDQUOT  1133/* Quota exceeded */
>  
>  #define UNAME_MACHINE "mips"
>  #define UNAME_MINIMUM_RELEASE "2.6.32"
> diff --git a/linux-user/mips64/target_syscall.h 
> b/linux-user/mips64/target_syscall.h
> index 8da9c1f..29c1983 100644
> --- a/linux-user/mips64/target_syscall.h
> +++ b/linux-user/mips64/target_syscall.h
> @@ -218,6 +218,8 @@ struct target_pt_regs {
>  #undef TARGET_ENOTRECOVERABLE
>  #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
>  
> +#undef TARGET_EDQUOT
> +#define TARGET_EDQUOT  1133/* Quota exceeded */
>  
>  #define UNAME_MACHINE "mips64"
>  #define UNAME_MINIMUM_RELEASE "2.6.32"
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index ee23b29..e4bd40d 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -725,6 +725,7 @@ static uint16_t 
> host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
>  [ENAVAIL]= TARGET_ENAVAIL,
>  [EISNAM] = TARGET_EISNAM,
>  [EREMOTEIO]  = TARGET_EREMOTEIO,
> +[EDQUOT]= TARGET_EDQUOT,
>  [ESHUTDOWN]  = TARGET_ESHUTDOWN,
>  [ETOOMANYREFS]   = TARGET_ETOOMANYREFS,
>  [ETIMEDOUT]  = TARGET_ETIMEDOUT,
> 



Re: [Qemu-devel] [V17 0/4] AMD IOMMU

2016-09-16 Thread Michael S. Tsirkin
On Wed, Aug 31, 2016 at 07:17:39PM +0300, David Kiarie wrote:
> Hi all,
> 
> This patchset adds basic AMD IOMMU emulation support to Qemu. 
> 
> Changes since v16 - this is mainly supposed to come as a ping :-)
>-minor endian-ness fixes

This doesn't build on BE so I dropped this.

> Changes since v15
>-Endian-ness issue fix
>-cleaned up unused macros
>-removed guest frame number(gfn) from cache entry
> 
> Changes since v14
>-MMIO register reading/write bug fix [Peter]
>-Endian-ness issue fix[Peter]
>-Bitfields layouts in IOMMU commands fix[Peter]
>-IVRS changed IVHD device entry from type 3 to 1 to save a few bytes
>-coding style issues, comment grammer and other miscellaneous fixes.
> 
> Changes since v13
>-Added an error to make AMD IOMMU incompatible with device 
> assignment.[Alex]
>-Converted AMD IOMMU into a composite PCI and System Bus device. This 
> helps with:
>   -We can now inherit from X86 IOMMU base class(which is implemented as a 
> System Bus device).
>   -We can now reserve MMIO region for IOMMU without a BAR register and 
> without a hack.
> 
> Changes since v12
> 
>-Coding style fixes [Jan, Michael]
>-Error logging fix to avoid using a macro[Jan]
>-moved some PCI macros to PCI header[Jan]
>-Use a lookup table for MMIO register names when tracing[Jan]
> 
> Changes since V11
>-AMD IOMMU is not started with -device amd-iommu (with a dependency on 
> Marcel's patches).
>-IOMMU commands are represented using bitfields which is less error prone 
> and more readable[Peter]
>-Changed from debug fprintfs to tracing[Jan]
> 
> Changes since V10
>  
>-Support for huge pages including some obscure AMD IOMMU feature that 
> allows default page size override[Jan].
>-Fixed an issue with generation of interrupts. We noted that AMD IOMMU has 
> BusMaster- and is therefore not able to generate interrupts like any other 
> PCI device. We have resulted in writing directly to system address but this 
> could be fixed by some patches which have not been merged yet.
> 
> Changes since v9
> 
>-amd_iommu prefixes have been renamed to a shorter 'amdvi' both in the 
> macros
> and in the functions/code. The register macros have not been moved to the 
> implementation file since almost the macros there are basically macros 
> and I 
> reckoned renaming them should suffice.
>-taken care of byte order in the use of 'dma_memory_read'[Michael]
>-Taken care of invalid DTE entries to ensure no DMA unless a device is 
> configured to allow it.
>-An issue with the emulate IOMMU defaulting to AMD_IOMMU has been 
> fixed[Marcel]
>
> You can test[1] this patches by starting with parameters 
> qemu-system-x86_64 -M -device amd-iommu -m 2G -enable-kvm -smp 4 -cpu 
> host -hda file.img -soundhw ac97 
> emulating whatever devices you want.
> 
> Not passing any command line parameters to linux should be enough to test 
> this patches since the devices are basically
> passes-through but to the 'host' (l1 guest). You can still go ahead pass 
> command line parameter 'iommu=pt iommu=1'
> and try to pass a device to L2 guest. This can also done without passing any 
> iommu related parameters to the kernel. 
> 
> David Kiarie (4):
>   hw/pci: Prepare for AMD IOMMU
>   hw/i386/trace-events: Add AMD IOMMU trace events
>   hw/i386: Introduce AMD IOMMU
>   hw/i386: AMD IOMMU IVRS table
> 
>  hw/acpi/aml-build.c |2 +-
>  hw/i386/Makefile.objs   |1 +
>  hw/i386/acpi-build.c|   76 ++-
>  hw/i386/amd_iommu.c | 1383 
> +++
>  hw/i386/amd_iommu.h |  289 +
>  hw/i386/intel_iommu.c   |1 +
>  hw/i386/trace-events|   29 +
>  hw/i386/x86-iommu.c |6 +
>  include/hw/acpi/aml-build.h |1 +
>  include/hw/i386/x86-iommu.h |   12 +
>  include/hw/pci/pci.h|4 +-
>  11 files changed, 1793 insertions(+), 11 deletions(-)
>  create mode 100644 hw/i386/amd_iommu.c
>  create mode 100644 hw/i386/amd_iommu.h
> 
> -- 
> 2.1.4



Re: [Qemu-devel] [V17 3/4] hw/i386: Introduce AMD IOMMU

2016-09-16 Thread Michael S. Tsirkin
On Wed, Aug 31, 2016 at 07:17:42PM +0300, David Kiarie wrote:
> +/* serialize IOMMU command processing */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t type:4;   /* command type   */
> +uint64_t reserved:8;
> +uint64_t store_addr:49;/* addr to write  */
> +uint64_t completion_flush:1;   /* allow more executions  */
> +uint64_t completion_int:1; /* set MMIOWAITINT*/
> +uint64_t completion_store:1;   /* write data to address  */
> +#else
> +uint64_t completion_store:1;
> +uint64_t completion_int:1;
> +uint64_t completion_flush:1;
> +uint64_t store_addr:49;
> +uint64_t reserved:8;
> +uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +uint64_t store_data;   /* data to write  */
> +} CMDCompletionWait;
> +
> +/* invalidate internal caches for devid */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t devid:16; /* device to invalidate   */
> +uint64_t reserved_1:44;
> +uint64_t type:4;   /* command type   */
> +#else
> +uint64_t devid:16;
> +uint64_t reserved_1:44;
> +uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +uint64_t reserved_2;
> +} CMDInvalDevEntry;
> +
> +/* invalidate a range of entries in IOMMU translation cache for devid */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t type:4;   /* command type   */
> +uint64_t reserved_2:12
> +uint64_t domid:16; /* domain to inval for*/
> +uint64_t reserved_1:12;
> +uint64_t pasid:20;
> +#else
> +uint64_t pasid:20;
> +uint64_t reserved_1:12;
> +uint64_t domid:16;
> +uint64_t reserved_2:12;
> +uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t address:51;  /* address to invalidate   */
> +uint64_t reserved_3:10;
> +uint64_t guest:1; /* G/N invalidation*/
> +uint64_t pde:1;   /* invalidate cached ptes  */
> +uint64_t size:1   /* size of invalidation*/
> +#else
> +uint64_t size:1;
> +uint64_t pde:1;
> +uint64_t guest:1;
> +uint64_t reserved_3:10;
> +uint64_t address:51;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +} CMDInvalIommuPages;
> +
> +/* inval specified address for devid from remote IOTLB */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t type:4;/* command type*/
> +uint64_t pasid_19_6:4;
> +uint64_t pasid_7_0:8;
> +uint64_t queuid:16;
> +uint64_t maxpend:8;
> +uint64_t pasid_15_8;
> +uint64_t devid:16; /* related devid*/
> +#else
> +uint64_t devid:16;
> +uint64_t pasid_15_8:8;
> +uint64_t maxpend:8;
> +uint64_t queuid:16;
> +uint64_t pasid_7_0:8;
> +uint64_t pasid_19_6:4;
> +uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t address:52;   /* invalidate addr  */
> +uint64_t reserved_2:9;
> +uint64_t guest:1;  /* G/N invalidate   */
> +uint64_t reserved_1:1;
> +uint64_t size:1;   /* size of invalidation */
> +#else
> +uint64_t size:1;
> +uint64_t reserved_1:1;
> +uint64_t guest:1;
> +uint64_t reserved_2:9;
> +uint64_t address:52;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +} CMDInvalIOTLBPages;
> +
> +/* invalidate all cached interrupt info for devid */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t type:4;  /* command type*/
> +uint64_t reserved_1:44;
> +uint64_t devid:16;/* related devid   */
> +#else
> +uint64_t devid:16;
> +uint64_t reserved_1:44;
> +uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +uint64_t reserved_2;
> +} CMDInvalIntrTable;
> +
> +/* load adddress translation info for devid into translation cache */
> +typedef struct QEMU_PACKED {
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t type:4;  /* command type   */
> +uint64_t reserved_2:8;
> +uint64_t pasid_19_0:20;
> +uint64_t pfcount_7_0:8;
> +uint64_t reserved_1:8;
> +uint64_t devid:16;/* related devid  */
> +#else
> +uint64_t devid:16;
> +uint64_t reserved_1:8;
> +uint64_t pfcount_7_0:8;
> +uint64_t pasid_19_0:20;
> +uint64_t reserved_2:8;
> +uint64_t type:4;
> +#endif /* __BIG_ENDIAN_BITFIELD */
> +
> +#ifdef HOST_WORDS_BIGENDIAN
> +uint64_t address:52; /* invalidate address   */
> +uint64_t reserved_5:7;
> +uint64_t inval:1;/* inval matching entries   */
> +uint64_t reserved_4:1;
> +uint64_t guest:1;/* G/N invalidate   */
> +uint64_t reserved_3:1;
> +uint64_t size:1; /* prefetched page size */
> +#else
> +uint64_t size:1;
> +uint64_t 

Re: [Qemu-devel] [PATCH v6 4/7] linux-user: Fix structure target_semid64_ds definition for Mips

2016-09-16 Thread Laurent Vivier


Le 16/09/2016 à 13:14, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic 
> 
> This patch corrects target_semid64_ds structure definition for Mips.
> 
> See, for example definition of semid64_ds for Mips in Linux kernel:
> arch/mips/include/uapi/asm/sembuf.h#L13.
> 
> This patch will also fix certain semaphore-related LTP tests for Mips,
> if they are executed in Qemu user mode for any Mips platform.
> 
> Signed-off-by: Miodrag Dinic 
> Signed-off-by: Aleksandar Markovic 
> Reviewed-by: Peter Maydell 
> ---
>  linux-user/mips/target_structs.h | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/linux-user/mips/target_structs.h 
> b/linux-user/mips/target_structs.h
> index fbd9955..5ba124d 100644
> --- a/linux-user/mips/target_structs.h
> +++ b/linux-user/mips/target_structs.h
> @@ -45,4 +45,20 @@ struct target_shmid_ds {
>  abi_ulong __unused2;
>  };
>  
> +#define TARGET_SEMID64_DS
> +
> +/*
> + * The semid64_ds structure for the MIPS architecture.
> + * Note extra padding because this structure is passed back and forth
> + * between kernel and user space.
> + */
> +struct target_semid64_ds {
> +struct target_ipc_perm sem_perm;
> +abi_ulong sem_otime;
> +abi_ulong sem_ctime;
> +abi_ulong sem_nsems;
> +abi_ulong __unused3;
> +abi_ulong __unused4;
> +};

Perhaps you can call them __unused1 and __unused2, like they are in the
kernel?

Anyway:

Reviewed-by: Laurent Vivier 

Laurent



[Qemu-devel] [PULL v4 1/2] virtio-bus: Plug devices after features are negotiated

2016-09-16 Thread Michael S. Tsirkin
From: Maxime Coquelin 

Currently, devices are plugged before features are negotiated.
If the backend doesn't support VIRTIO_F_VERSION_1, the transport
needs to rewind some settings.

This is the case for CCW, for which a post_plugged callback had
been introduced, where max_rev field is just updated if
VIRTIO_F_VERSION_1 is not supported by the backend.
For PCI, implementing post_plugged would be much more
complicated, so it needs to know whether the backend supports
VIRTIO_F_VERSION_1 at plug time.

Currently, nothing is done for PCI. Modern capabilities get
exposed to the guest even if VIRTIO_F_VERSION_1 is not supported
by the backend, which confuses the guest.

This patch replaces existing post_plugged solution with an
approach that fits with both transports.
Features negotiation is performed before ->device_plugged() call.
A pre_plugged callback is introduced so that the transports can
set their supported features.

Cc: Michael S. Tsirkin 
Cc: qemu-sta...@nongnu.org
Tested-by: Cornelia Huck  [ccw]
Reviewed-by: Cornelia Huck 
Reviewed-by: Marcel Apfelbaum 
Signed-off-by: Maxime Coquelin 
---
 hw/virtio/virtio-pci.h |  5 +
 include/hw/virtio/virtio-bus.h | 10 +-
 hw/s390x/virtio-ccw.c  | 30 +++---
 hw/virtio/virtio-bus.c |  9 +
 hw/virtio/virtio-pci.c | 36 
 5 files changed, 62 insertions(+), 28 deletions(-)

diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 0698157..541cbdb 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -181,6 +181,11 @@ static inline void 
virtio_pci_force_virtio_1(VirtIOPCIProxy *proxy)
 proxy->disable_legacy = ON_OFF_AUTO_ON;
 }
 
+static inline void virtio_pci_disable_modern(VirtIOPCIProxy *proxy)
+{
+proxy->disable_modern = true;
+}
+
 /*
  * virtio-scsi-pci: This extends VirtioPCIProxy.
  */
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index f3e5ef3..24caa0a 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -54,16 +54,16 @@ typedef struct VirtioBusClass {
 int (*set_guest_notifiers)(DeviceState *d, int nvqs, bool assign);
 void (*vmstate_change)(DeviceState *d, bool running);
 /*
+ * Expose the features the transport layer supports before
+ * the negotiation takes place.
+ */
+void (*pre_plugged)(DeviceState *d, Error **errp);
+/*
  * transport independent init function.
  * This is called by virtio-bus just after the device is plugged.
  */
 void (*device_plugged)(DeviceState *d, Error **errp);
 /*
- * Re-evaluate setup after feature bits have been validated
- * by the device backend.
- */
-void (*post_plugged)(DeviceState *d, Error **errp);
-/*
  * transport independent exit function.
  * This is called by virtio-bus just before the device is unplugged.
  */
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 9678956..9f3f386 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1261,6 +1261,16 @@ static int virtio_ccw_load_config(DeviceState *d, 
QEMUFile *f)
 return 0;
 }
 
+static void virtio_ccw_pre_plugged(DeviceState *d, Error **errp)
+{
+   VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
+   VirtIODevice *vdev = virtio_bus_get_device(>bus);
+
+if (dev->max_rev >= 1) {
+virtio_add_feature(>host_features, VIRTIO_F_VERSION_1);
+}
+}
+
 /* This is called by virtio-bus just after the device is plugged. */
 static void virtio_ccw_device_plugged(DeviceState *d, Error **errp)
 {
@@ -1270,6 +1280,10 @@ static void virtio_ccw_device_plugged(DeviceState *d, 
Error **errp)
 SubchDev *sch = ccw_dev->sch;
 int n = virtio_get_num_queues(vdev);
 
+if (!virtio_has_feature(vdev->host_features, VIRTIO_F_VERSION_1)) {
+dev->max_rev = 0;
+}
+
 if (virtio_get_num_queues(vdev) > VIRTIO_CCW_QUEUE_MAX) {
 error_setg(errp, "The number of virtqueues %d "
"exceeds ccw limit %d", n,
@@ -1283,25 +1297,11 @@ static void virtio_ccw_device_plugged(DeviceState *d, 
Error **errp)
 
 sch->id.cu_model = virtio_bus_get_vdev_id(>bus);
 
-if (dev->max_rev >= 1) {
-virtio_add_feature(>host_features, VIRTIO_F_VERSION_1);
-}
 
 css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
   d->hotplugged, 1);
 }
 
-static void virtio_ccw_post_plugged(DeviceState *d, Error **errp)
-{
-   VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
-   VirtIODevice *vdev = virtio_bus_get_device(>bus);
-
-   if (!virtio_host_has_feature(vdev, VIRTIO_F_VERSION_1)) {
-/* A backend didn't support modern virtio. */
-   dev->max_rev = 0;
-   }
-}
-
 static void virtio_ccw_device_unplugged(DeviceState *d)
 {
 VirtioCcwDevice *dev = 

[Qemu-devel] [PULL v4 2/2] MAINTAINERS: add virtio-* tests

2016-09-16 Thread Michael S. Tsirkin
From: Greg Kurz 

Except virtio-9p, all virtio-* tests are orphan. This patch tries to fix
it, according to the following logic:

- when the related subsystem has its own section in MAINTAINERS, the test
  is added there
- otherwise it is added to the "parent" section (aka. SCSI, Network devices,
  virtio)

Signed-off-by: Greg Kurz 
Reviewed-by: Amit Shah 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4db611f..0e0c326 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -830,6 +830,7 @@ Network devices
 M: Jason Wang 
 S: Odd Fixes
 F: hw/net/
+F: tests/virtio-net-test.c
 T: git git://github.com/jasowang/qemu.git net
 
 SCSI
@@ -837,6 +838,7 @@ M: Paolo Bonzini 
 S: Supported
 F: include/hw/scsi/*
 F: hw/scsi/*
+F: tests/virtio-scsi-test.c
 T: git git://github.com/bonzini/qemu.git scsi-next
 
 LSI53C895A
@@ -889,6 +891,7 @@ S: Supported
 F: hw/*/virtio*
 F: net/vhost-user.c
 F: include/hw/virtio/
+F: tests/virtio-balloon-test.c
 
 virtio-9p
 M: Aneesh Kumar K.V 
@@ -907,6 +910,7 @@ S: Supported
 F: hw/block/virtio-blk.c
 F: hw/block/dataplane/*
 F: hw/virtio/dataplane/*
+F: tests/virtio-blk-test.c
 T: git git://github.com/stefanha/qemu.git block
 
 virtio-ccw
@@ -929,6 +933,8 @@ S: Supported
 F: hw/char/virtio-serial-bus.c
 F: hw/char/virtio-console.c
 F: include/hw/virtio/virtio-serial.h
+F: tests/virtio-console-test.c
+F: tests/virtio-serial-test.c
 
 virtio-rng
 M: Amit Shah 
@@ -937,6 +943,7 @@ F: hw/virtio/virtio-rng.c
 F: include/hw/virtio/virtio-rng.h
 F: include/sysemu/rng*.h
 F: backends/rng*.c
+F: tests/virtio-rng-test.c
 
 nvme
 M: Keith Busch 
-- 
MST




[Qemu-devel] [PULL v4 0/2] virtio: fixes

2016-09-16 Thread Michael S. Tsirkin
The following changes since commit d1eb8f2acba579830cf3798c3c15ce51be852c56:

  fpu: add mechanism to check for invalid long double formats (2016-09-15 
12:43:18 +0100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream

for you to fetch changes up to 6bd7776cd0a9581cdb5e9dd40df8821a96e355d6:

  MAINTAINERS: add virtio-* tests (2016-09-16 21:54:03 +0300)


virtio: fixes

virtio feature negotiation rework

Signed-off-by: Michael S. Tsirkin 


Greg Kurz (1):
  MAINTAINERS: add virtio-* tests

Maxime Coquelin (1):
  virtio-bus: Plug devices after features are negotiated

 hw/virtio/virtio-pci.h |  5 +
 include/hw/virtio/virtio-bus.h | 10 +-
 hw/s390x/virtio-ccw.c  | 30 +++---
 hw/virtio/virtio-bus.c |  9 +
 hw/virtio/virtio-pci.c | 36 
 MAINTAINERS|  7 +++
 6 files changed, 69 insertions(+), 28 deletions(-)




Re: [Qemu-devel] [PULL v3 0/6] virtio,pci: fixes and updates

2016-09-16 Thread Michael S. Tsirkin
On Fri, Sep 16, 2016 at 11:57:54AM +0100, Peter Maydell wrote:
> On 15 September 2016 at 21:38, Michael S. Tsirkin  wrote:
> > The following changes since commit d1eb8f2acba579830cf3798c3c15ce51be852c56:
> >
> >   fpu: add mechanism to check for invalid long double formats (2016-09-15 
> > 12:43:18 +0100)
> >
> > are available in the git repository at:
> >
> >   git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> >
> > for you to fetch changes up to a5a43875b352810d29dc27e7b0fb602eb7ef2d31:
> >
> >   MAINTAINERS: add virtio-* tests (2016-09-15 23:37:16 +0300)
> >
> > 
> > virtio,pci: fixes and updates
> >
> > AMD IOMMU emulation
> > virtio feature negotiation rework
> >
> > Signed-off-by: Michael S. Tsirkin 
> >
> > 
> 
> Fails to build on ppc64be, still:
> /home/pm215/qemu/hw/i386/amd_iommu.c:245:5: error: expected ‘,’, ‘;’
> or ‘}’ before ‘uint32_t’
>  uint32_t reserved_3:29;
>  ^
> /home/pm215/qemu/hw/i386/amd_iommu.c: In function ‘amdvi_complete_ppr’:
> /home/pm215/qemu/hw/i386/amd_iommu.c:588:62: error: ‘CMDCompletePPR’
> has no member named ‘reserved_3’
>  if (pprcomp->reserved_1 || pprcomp->reserved_2 || pprcomp->reserved_3 ||
>   ^
> /home/pm215/qemu/hw/i386/amd_iommu.c:589:16: error: ‘CMDCompletePPR’
> has no member named ‘reserved_4’
>  pprcomp->reserved_4 || pprcomp->reserved_5) {
> ^
> /home/pm215/qemu/hw/i386/amd_iommu.c:589:39: error: ‘CMDCompletePPR’
> has no member named ‘reserved_5’
>  pprcomp->reserved_4 || pprcomp->reserved_5) {
>^
> 
> Missing semicolon, again, line 237.
> 
> In fact looking at this code it just looks broken. Structures
> like this:
> 
> typedef struct QEMU_PACKED {
> #ifdef HOST_WORDS_BIGENDIAN
> uint64_t type:4;  /* command type*/
> uint64_t reserved_1:44;
> uint64_t devid:16;/* related devid   */
> #else
> uint64_t devid:16;
> uint64_t reserved_1:44;
> uint64_t type:4;
> #endif /* __BIG_ENDIAN_BITFIELD */
> uint64_t reserved_2;
> } CMDInvalIntrTable;
> 
> seem to be trying to represent bit layouts in memory using
> bitfields, but this is just not portable. It's not sufficient
> to have a "bigendian vs littleendian" set of ifdefs.
> 
> The portable way to do this is to write the code to use
> bitwise logical operations (and functions like extract64
> and deposit64) to manipulate things. As a bonus you get rid
> of all these host-specific #ifdefs that are tripping you
> up now.
> 
> It would be nice if C bitfields worked the way this code
> wants them to, but they don't, alas.
> 
> thanks
> -- PMM

I agree, I wanted to rework this in tree but maybe best to fix it first.
I dropped all this code from tree for now.

-- 
MST



[Qemu-devel] [PULL v2 2/8] 9pfs: drop duplicate line in proxy backend

2016-09-16 Thread Greg Kurz
This double free did not cause harm because v9fs_string_free() sets
str->data to NULL and g_free(NULL) is valid.

Signed-off-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 hw/9pfs/9p-proxy.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index 52bbf4f1b37c..d091564b6fd2 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -777,7 +777,6 @@ static int proxy_mkdir(FsContext *fs_ctx, V9fsPath 
*dir_path,
 errno = -retval;
 retval = -1;
 }
-v9fs_string_free();
 return retval;
 }
 
-- 
2.5.5




Re: [Qemu-devel] [PATCH v6 2/7] linux-user: Fix TARGET_F_GETOWN definition for Mips

2016-09-16 Thread Laurent Vivier


Le 16/09/2016 à 13:14, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic 
> 
> For some reason, Qemu's TARGET_F_GETOWN constant for Mips does not
> match the correct value of correspondant F_GETOWN. This patch fixes
> this problem.
> 
> For reference, see Mips' F_GETOWN definition in Linux kernel at
> arch/mips/include/uapi/asm/fcntl.h#L44.
> 
> This patch also fixes some fcntl()-related LTP tests for Qemu
> user mode for Mips.
> 
> Signed-off-by: Miodrag Dinic 
> Signed-off-by: Aleksandar Markovic 

Reviewed-by: Laurent Vivier 

> ---
>  linux-user/syscall_defs.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index cf89f16..44b1197 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -2158,7 +2158,7 @@ struct target_statfs64 {
>  #define TARGET_F_SETLK 6
>  #define TARGET_F_SETLKW7
>  #define TARGET_F_SETOWN24   /*  for sockets. */
> -#define TARGET_F_GETOWN25   /*  for sockets. */
> +#define TARGET_F_GETOWN23   /*  for sockets. */
>  #else
>  #define TARGET_F_GETLK 5
>  #define TARGET_F_SETLK 6
> 



[Qemu-devel] [PULL v2 0/8] 9p patches for 2.8 20160916

2016-09-16 Thread Greg Kurz
The following changes since commit 5f473241ac595452ae0638dc63e7af2a2294f5ec:

  Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging 
(2016-09-15 18:12:40 +0100)

are available in the git repository at:

  https://github.com/gkurz/qemu.git tags/for-upstream

for you to fetch changes up to 826742d40aa2a62e17beb9bbe702cd36ccc4b856:

  9pfs: fix potential segfault during walk (2016-09-16 19:48:28 +0200)


This pull request contains:
- a fix for a regression introduced in 2.7
- basic functional testing for virtio-9p
- some code cleanups for 9pfs


Greg Kurz (8):
  9pfs: drop unused fmt strings in the proxy backend
  9pfs: drop duplicate line in proxy backend
  9pfs: drop useless v9fs_string_null() function
  9pfs: introduce v9fs_path_sprintf() helper
  tests: virtio-9p: introduce start/stop functions
  tests: virtio-9p: add basic configuration test
  tests: virtio-9p: add basic transaction test
  9pfs: fix potential segfault during walk

 fsdev/9p-marshal.c |   5 --
 fsdev/9p-marshal.h |   1 -
 hw/9pfs/9p-local.c |   7 +-
 hw/9pfs/9p-proxy.c |  75 +---
 hw/9pfs/9p.c   |  32 ++---
 hw/9pfs/9p.h   |   1 +
 tests/Makefile.include |   2 +-
 tests/virtio-9p-test.c | 182 -
 8 files changed, 225 insertions(+), 80 deletions(-)
-- 
2.5.5




Re: [Qemu-devel] [PATCH v6 3/7] linux-user: Fix structure target_flock definition for Mips

2016-09-16 Thread Laurent Vivier


Le 16/09/2016 à 13:14, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic 
> 
> Structure flock is defined for Mips in a way different from any
> other platform. For reference, see Linux kernel source code files:
> 
> arch/mips/include/uapi/asm/fcntl.h, line 63 (for Mips)
> include/uapi/asm-generic/fcntl.h, line 195 (for all other platforms)
> 
> This patch fix this problem, by amending structure target_flock,
> for Mips only.
> 
> Besides, this patch fixes LTP tests fcntl11, fcntl17, fcntl19, fcntl20,
> and fcntl21, which are currently failing, if executed in Qemu user mode
> for Mips platforms.
> 
> Signed-off-by: Aleksandar Markovic 
> Signed-off-by: Leon Alrae 

Reviewed-by: Laurent Vivier 

> ---
>  linux-user/syscall_defs.h | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> index 44b1197..14a1425 100644
> --- a/linux-user/syscall_defs.h
> +++ b/linux-user/syscall_defs.h
> @@ -2327,7 +2327,13 @@ struct target_flock {
>  short l_whence;
>  abi_long l_start;
>  abi_long l_len;
> +#if defined(TARGET_MIPS)
> +abi_long l_sysid;
> +#endif
>  int l_pid;
> +#if defined(TARGET_MIPS)
> +abi_long pad[4];
> +#endif
>  };
>  
>  struct target_flock64 {
> 



[Qemu-devel] [PULL v2 8/8] 9pfs: fix potential segfault during walk

2016-09-16 Thread Greg Kurz
If the call to fid_to_qid() returns an error, we will call v9fs_path_free()
on uninitialized paths.

It is a regression introduced by the following commit:

56f101ecce0e 9pfs: handle walk of ".." in the root directory

Let's fix this by initializing dpath and path before calling fid_to_qid().

Signed-off-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
[groug: updated the changelog to indicate this is regression and to provide
the offending commit SHA1]
Signed-off-by: Greg Kurz 
---
 hw/9pfs/9p.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index 639f93930285..119ee584969b 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -1333,13 +1333,14 @@ static void v9fs_walk(void *opaque)
 goto out_nofid;
 }
 
+v9fs_path_init();
+v9fs_path_init();
+
 err = fid_to_qid(pdu, fidp, );
 if (err < 0) {
 goto out;
 }
 
-v9fs_path_init();
-v9fs_path_init();
 /*
  * Both dpath and path initially poin to fidp.
  * Needed to handle request with nwnames == 0
-- 
2.5.5




[Qemu-devel] [PATCH v4 34/35] target-alpha: Introduce MMU_PHYS_IDX

2016-09-16 Thread Richard Henderson
Rather than using helpers for physical accesses, use a mmu index.
The primary cleanup is with store-conditional on physical addresses.

Signed-off-by: Richard Henderson 
---
 target-alpha/cpu.h| 18 +---
 target-alpha/helper.c |  8 ++
 target-alpha/helper.h |  9 --
 target-alpha/mem_helper.c | 73 ---
 target-alpha/translate.c  | 50 ++--
 5 files changed, 44 insertions(+), 114 deletions(-)

diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index dcdd041..871d9ba 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -201,7 +201,7 @@ enum {
 
 /* MMU modes definitions */
 
-/* Alpha has 5 MMU modes: PALcode, kernel, executive, supervisor, and user.
+/* Alpha has 5 MMU modes: PALcode, Kernel, Executive, Supervisor, and User.
The Unix PALcode only exposes the kernel and user modes; presumably
executive and supervisor are used by VMS.
 
@@ -209,22 +209,18 @@ enum {
there are PALmode instructions that can access data via physical mode
or via an os-installed "alternate mode", which is one of the 4 above.
 
-   QEMU does not currently properly distinguish between code/data when
-   looking up addresses.  To avoid having to address this issue, our
-   emulated PALcode will cheat and use the KSEG mapping for its code+data
-   rather than physical addresses.
+   That said, we're only emulating Unix PALcode, and not attempting VMS,
+   so we don't need to implement Executive and Supervisor.  QEMU's own
+   PALcode cheats and usees the KSEG mapping for its code+data rather than
+   physical addresses.  */
 
-   Moreover, we're only emulating Unix PALcode, and not attempting VMS.
-
-   All of which allows us to drop all but kernel and user modes.
-   Elide the unused MMU modes to save space.  */
-
-#define NB_MMU_MODES 2
+#define NB_MMU_MODES 3
 
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
 #define MMU_KERNEL_IDX   0
 #define MMU_USER_IDX 1
+#define MMU_PHYS_IDX 2
 
 typedef struct CPUAlphaState CPUAlphaState;
 
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 85168b7..9ba3e1a 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -126,6 +126,14 @@ static int get_physical_address(CPUAlphaState *env, 
target_ulong addr,
 int prot = 0;
 int ret = MM_K_ACV;
 
+/* Handle physical accesses.  */
+if (mmu_idx == MMU_PHYS_IDX) {
+phys = addr;
+prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ret = -1;
+goto exit;
+}
+
 /* Ensure that the virtual address is properly sign-extended from
the last implemented virtual address bit.  */
 if (saddr >> TARGET_VIRT_ADDR_SPACE_BITS != saddr >> 63) {
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index c3d8a3e..004221d 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -92,15 +92,6 @@ DEF_HELPER_FLAGS_2(ieee_input_cmp, TCG_CALL_NO_WG, void, 
env, i64)
 DEF_HELPER_FLAGS_2(ieee_input_s, TCG_CALL_NO_WG, void, env, i64)
 
 #if !defined (CONFIG_USER_ONLY)
-DEF_HELPER_2(ldl_phys, i64, env, i64)
-DEF_HELPER_2(ldq_phys, i64, env, i64)
-DEF_HELPER_2(ldl_l_phys, i64, env, i64)
-DEF_HELPER_2(ldq_l_phys, i64, env, i64)
-DEF_HELPER_3(stl_phys, void, env, i64, i64)
-DEF_HELPER_3(stq_phys, void, env, i64, i64)
-DEF_HELPER_3(stl_c_phys, i64, env, i64, i64)
-DEF_HELPER_3(stq_c_phys, i64, env, i64, i64)
-
 DEF_HELPER_FLAGS_1(tbia, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(tbis, TCG_CALL_NO_RWG, void, env, i64)
 DEF_HELPER_FLAGS_1(tb_flush, TCG_CALL_NO_RWG, void, env)
diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
index 1b2be50..78a7d45 100644
--- a/target-alpha/mem_helper.c
+++ b/target-alpha/mem_helper.c
@@ -25,79 +25,6 @@
 
 /* Softmmu support */
 #ifndef CONFIG_USER_ONLY
-
-uint64_t helper_ldl_phys(CPUAlphaState *env, uint64_t p)
-{
-CPUState *cs = CPU(alpha_env_get_cpu(env));
-return (int32_t)ldl_phys(cs->as, p);
-}
-
-uint64_t helper_ldq_phys(CPUAlphaState *env, uint64_t p)
-{
-CPUState *cs = CPU(alpha_env_get_cpu(env));
-return ldq_phys(cs->as, p);
-}
-
-uint64_t helper_ldl_l_phys(CPUAlphaState *env, uint64_t p)
-{
-CPUState *cs = CPU(alpha_env_get_cpu(env));
-env->lock_addr = p;
-return env->lock_value = (int32_t)ldl_phys(cs->as, p);
-}
-
-uint64_t helper_ldq_l_phys(CPUAlphaState *env, uint64_t p)
-{
-CPUState *cs = CPU(alpha_env_get_cpu(env));
-env->lock_addr = p;
-return env->lock_value = ldq_phys(cs->as, p);
-}
-
-void helper_stl_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
-{
-CPUState *cs = CPU(alpha_env_get_cpu(env));
-stl_phys(cs->as, p, v);
-}
-
-void helper_stq_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
-{
-CPUState *cs = CPU(alpha_env_get_cpu(env));
-stq_phys(cs->as, p, v);
-}
-
-uint64_t helper_stl_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
-{
-CPUState *cs = CPU(alpha_env_get_cpu(env));
-uint64_t 

[Qemu-devel] [PATCH v4 29/35] target-arm: emulate SWP with atomic_xchg helper

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-25-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-arm/translate.c | 25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 2bcc97b..0b35f9e 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8741,25 +8741,26 @@ static void disas_arm_insn(DisasContext *s, unsigned 
int insn)
 }
 tcg_temp_free_i32(addr);
 } else {
+TCGv taddr;
+TCGMemOp opc = s->be_data;
+
 /* SWP instruction */
 rm = (insn) & 0xf;
 
-/* ??? This is not really atomic.  However we know
-   we never have multiple CPUs running in parallel,
-   so it is good enough.  */
-addr = load_reg(s, rn);
-tmp = load_reg(s, rm);
-tmp2 = tcg_temp_new_i32();
 if (insn & (1 << 22)) {
-gen_aa32_ld8u(s, tmp2, addr, get_mem_index(s));
-gen_aa32_st8(s, tmp, addr, get_mem_index(s));
+opc |= MO_UB;
 } else {
-gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
-gen_aa32_st32(s, tmp, addr, get_mem_index(s));
+opc |= MO_UL | MO_ALIGN;
 }
-tcg_temp_free_i32(tmp);
+
+addr = load_reg(s, rn);
+taddr = gen_aa32_addr(s, addr, opc);
 tcg_temp_free_i32(addr);
-store_reg(s, rd, tmp2);
+
+tmp = load_reg(s, rm);
+tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
+get_mem_index(s), opc);
+store_reg(s, rd, tmp);
 }
 }
 } else {
-- 
2.5.5




[Qemu-devel] [PULL v2 7/8] tests: virtio-9p: add basic transaction test

2016-09-16 Thread Greg Kurz
This adds a simple test to validate the device is functional: it transmits
a request with type Terror, which is not used by the 9P protocol [1], and
expects QEMU to return a reply with type Rerror and the "Operation not
supported" error string.

[1] http://lxr.free-electrons.com/source/include/net/9p/9p.h#L121

Signed-off-by: Greg Kurz 
Acked-by: Cornelia Huck 
---
 tests/virtio-9p-test.c | 65 ++
 1 file changed, 65 insertions(+)

diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index b8fb6cd869a9..95cba3fd3e8e 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include 
 #include "libqtest.h"
 #include "qemu-common.h"
 #include "libqos/pci-pc.h"
@@ -17,6 +18,9 @@
 #include "libqos/malloc-pc.h"
 #include "standard-headers/linux/virtio_ids.h"
 #include "standard-headers/linux/virtio_pci.h"
+#include "hw/9pfs/9p.h"
+
+#define QVIRTIO_9P_TIMEOUT_US (1 * 1000 * 1000)
 
 static const char mount_tag[] = "qtest";
 static char *test_share;
@@ -118,11 +122,72 @@ static void pci_basic_config(void)
 qvirtio_9p_stop();
 }
 
+typedef struct VirtIO9PHdr {
+uint32_t size;
+uint8_t id;
+uint16_t tag;
+} QEMU_PACKED VirtIO9PHdr;
+
+typedef struct VirtIO9PMsgRError {
+uint16_t error_len;
+char error[0];
+} QEMU_PACKED VirtIO9PMsgRError;
+
+#define P9_MAX_SIZE 8192
+
+static void pci_basic_transaction(void)
+{
+QVirtIO9P *v9p;
+VirtIO9PHdr hdr;
+VirtIO9PMsgRError *resp;
+uint64_t req_addr, resp_addr;
+uint32_t free_head;
+char *expected_error = strerror(ENOTSUP);
+
+qvirtio_9p_start();
+v9p = qvirtio_9p_pci_init();
+
+hdr.size = cpu_to_le32(sizeof(hdr));
+hdr.id = P9_TERROR;
+hdr.tag = cpu_to_le16(12345);
+
+req_addr = guest_alloc(v9p->alloc, hdr.size);
+memwrite(req_addr, , sizeof(hdr));
+free_head = qvirtqueue_add(v9p->vq, req_addr, hdr.size, false, true);
+
+resp_addr = guest_alloc(v9p->alloc, P9_MAX_SIZE);
+qvirtqueue_add(v9p->vq, resp_addr, P9_MAX_SIZE, true, false);
+
+qvirtqueue_kick(_pci, v9p->dev, v9p->vq, free_head);
+guest_free(v9p->alloc, req_addr);
+qvirtio_wait_queue_isr(_pci, v9p->dev, v9p->vq,
+   QVIRTIO_9P_TIMEOUT_US);
+
+memread(resp_addr, , sizeof(hdr));
+le32_to_cpus();
+le16_to_cpus();
+g_assert_cmpint(hdr.size, <, (uint32_t) P9_MAX_SIZE);
+g_assert_cmpint(hdr.id, ==, (uint8_t) P9_RERROR);
+g_assert_cmpint(hdr.tag, ==, (uint16_t) 12345);
+
+resp = g_malloc(hdr.size);
+memread(resp_addr + sizeof(hdr), resp, hdr.size - sizeof(hdr));
+guest_free(v9p->alloc, resp_addr);
+le16_to_cpus(>error_len);
+g_assert_cmpmem(resp->error, resp->error_len, expected_error,
+strlen(expected_error));
+g_free(resp);
+
+qvirtio_9p_pci_free(v9p);
+qvirtio_9p_stop();
+}
+
 int main(int argc, char **argv)
 {
 g_test_init(, , NULL);
 qtest_add_func("/virtio/9p/pci/nop", pci_nop);
 qtest_add_func("/virtio/9p/pci/basic/configuration", pci_basic_config);
+qtest_add_func("/virtio/9p/pci/basic/transaction", pci_basic_transaction);
 
 return g_test_run();
 }
-- 
2.5.5




[Qemu-devel] [PULL v2 6/8] tests: virtio-9p: add basic configuration test

2016-09-16 Thread Greg Kurz
This adds PCI init code and a basic test that checks the device config
matches what is passed on the command line.

Signed-off-by: Greg Kurz 
Acked-by: Cornelia Huck 
---
 tests/Makefile.include |  2 +-
 tests/virtio-9p-test.c | 77 ++
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 2f11064699d7..6052a3828f68 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -627,7 +627,7 @@ tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o 
$(libqos-virtio-obj-y)
 tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o $(libqos-pc-obj-y) 
$(libqos-virtio-obj-y)
 tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o $(libqos-pc-obj-y)
 tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o 
$(libqos-virtio-obj-y)
-tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o
+tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y)
 tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o
 tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o
 tests/tpci200-test$(EXESUF): tests/tpci200-test.o
diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 45fc8041d7f3..b8fb6cd869a9 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -10,6 +10,13 @@
 #include "qemu/osdep.h"
 #include "libqtest.h"
 #include "qemu-common.h"
+#include "libqos/pci-pc.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+#include "libqos/malloc.h"
+#include "libqos/malloc-pc.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_pci.h"
 
 static const char mount_tag[] = "qtest";
 static char *test_share;
@@ -42,10 +49,80 @@ static void pci_nop(void)
 qvirtio_9p_stop();
 }
 
+typedef struct {
+QVirtioDevice *dev;
+QGuestAllocator *alloc;
+QPCIBus *bus;
+QVirtQueue *vq;
+} QVirtIO9P;
+
+static QVirtIO9P *qvirtio_9p_pci_init(void)
+{
+QVirtIO9P *v9p;
+QVirtioPCIDevice *dev;
+
+v9p = g_new0(QVirtIO9P, 1);
+v9p->alloc = pc_alloc_init();
+v9p->bus = qpci_init_pc();
+
+dev = qvirtio_pci_device_find(v9p->bus, VIRTIO_ID_9P);
+g_assert_nonnull(dev);
+g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_9P);
+v9p->dev = (QVirtioDevice *) dev;
+
+qvirtio_pci_device_enable(dev);
+qvirtio_reset(_pci, v9p->dev);
+qvirtio_set_acknowledge(_pci, v9p->dev);
+qvirtio_set_driver(_pci, v9p->dev);
+
+v9p->vq = qvirtqueue_setup(_pci, v9p->dev, v9p->alloc, 0);
+return v9p;
+}
+
+static void qvirtio_9p_pci_free(QVirtIO9P *v9p)
+{
+qvirtqueue_cleanup(_pci, v9p->vq, v9p->alloc);
+pc_alloc_uninit(v9p->alloc);
+qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev));
+g_free(v9p->dev);
+qpci_free_pc(v9p->bus);
+g_free(v9p);
+}
+
+static void pci_basic_config(void)
+{
+QVirtIO9P *v9p;
+void *addr;
+size_t tag_len;
+char *tag;
+int i;
+
+qvirtio_9p_start();
+v9p = qvirtio_9p_pci_init();
+
+addr = ((QVirtioPCIDevice *) v9p->dev)->addr + 
VIRTIO_PCI_CONFIG_OFF(false);
+tag_len = qvirtio_config_readw(_pci, v9p->dev,
+   (uint64_t)(uintptr_t)addr);
+g_assert_cmpint(tag_len, ==, strlen(mount_tag));
+addr += sizeof(uint16_t);
+
+tag = g_malloc(tag_len);
+for (i = 0; i < tag_len; i++) {
+tag[i] = qvirtio_config_readb(_pci, v9p->dev,
+  (uint64_t)(uintptr_t)addr + i);
+}
+g_assert_cmpmem(tag, tag_len, mount_tag, tag_len);
+g_free(tag);
+
+qvirtio_9p_pci_free(v9p);
+qvirtio_9p_stop();
+}
+
 int main(int argc, char **argv)
 {
 g_test_init(, , NULL);
 qtest_add_func("/virtio/9p/pci/nop", pci_nop);
+qtest_add_func("/virtio/9p/pci/basic/configuration", pci_basic_config);
 
 return g_test_run();
 }
-- 
2.5.5




[Qemu-devel] [PATCH v4 28/35] target-arm: emulate LL/SC using cmpxchg helpers

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

Emulating LL/SC with cmpxchg is not correct, since it can
suffer from the ABA problem. Portable parallel code, however,
is written assuming only cmpxchg--and not LL/SC--is available.
This means that in practice emulating LL/SC with cmpxchg is
a viable alternative.

The appended emulates LL/SC pairs in ARM with cmpxchg helpers.
This works in both user and system mode. In usermode, it avoids
pausing all other CPUs to perform the LL/SC pair. The subsequent
performance and scalability improvement is significant, as the
plots below show. They plot the throughput of atomic_add-bench
compiled for ARM and executed on a 64-core x86 machine.

Hi-res plots: http://imgur.com/a/aNQpB

   atomic_add-bench: 100 ops/thread, [0,1] range

  9 ++-+--+--+--+--+--+---++
+cmpxchg +-E--+   +  +  +  +  +|
  8 +Emaster +-H--+   ++
| ||
  7 ++E   ++
| ||
  6   ++
|  |   |
  5 ++ |  ++
  4 ++ |  ++
|  |   |
  3 ++ |  ++
|   |  |
  2 ++  | ++
|H++E+---  +++  ---+E+--+E+--+E|
  1 +++ +E+-+E+--+E+--+E+--+E+--   +++  +++   ++
++H+   ++++   +  +++    +  +  +|
  0 ++--HH-+-H+--+--+--+--+---++
0  10 20 30 40 50 60
   Number of threads

atomic_add-bench: 100 ops/thread, [0,2] range

  16 ++-+--+-+--+--+--+---++
 +cmpxchg +-E--+   + +  +  +  +|
  14 ++master +-H--+  ++
 | |   |
  12 ++|  ++
 | E   |
  10 ++|  ++
 | |   |
   8  ++
 |E+|  |
 |  |  |
   6 ++ | ++
 |   | |
   4 ++  |++
 |  +E+---   +++  +++  +++   ---+E+--+E|
   2 +H+ +E+--E---+E+-+E+--+E+--+E+--+++
 + |++++   +    +  +  +|
   0 ++H-HH-+-H+-+--+--+--+---++
 0  10 2030 40 50 60
Number of threads

   atomic_add-bench: 100 ops/thread, [0,128] range

  70 ++-+--+-+--+--+--+---++
 +cmpxchg +-E--+   + +  +     +|
  60 ++master +-H--+ E--+E+---++
 |-+E+---   +++ +++  +E|
 |+++  +++   ++|
  50 ++   +++  ---+E+-++
 |-E---|
  40 ++---+++ ++
 |   +++---|
 |  -+E+   |
  30 ++  +++  ++
 |   +E+   |
  20 ++ +++-- ++
 |  +E+ 

[Qemu-devel] [PULL v2 5/8] tests: virtio-9p: introduce start/stop functions

2016-09-16 Thread Greg Kurz
First step to be able to run several functional steps.

Signed-off-by: Greg Kurz 
Acked-by: Cornelia Huck 
---
 tests/virtio-9p-test.c | 42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 1e39335a7945..45fc8041d7f3 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -11,33 +11,41 @@
 #include "libqtest.h"
 #include "qemu-common.h"
 
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
-{
-}
+static const char mount_tag[] = "qtest";
+static char *test_share;
 
-static char test_share[] = "/tmp/qtest.XX";
-
-int main(int argc, char **argv)
+static void qvirtio_9p_start(void)
 {
 char *args;
-int ret;
 
-g_test_init(, , NULL);
-qtest_add_func("/virtio/9p/pci/nop", pci_nop);
-
-g_assert(mkdtemp(test_share));
+test_share = g_strdup("/tmp/qtest.XX");
+g_assert_nonnull(mkdtemp(test_share));
 
 args = g_strdup_printf("-fsdev local,id=fsdev0,security_model=none,path=%s 
"
-   "-device 
virtio-9p-pci,fsdev=fsdev0,mount_tag=qtest",
-   test_share);
+   "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s",
+   test_share, mount_tag);
+
 qtest_start(args);
 g_free(args);
+}
 
-ret = g_test_run();
-
+static void qvirtio_9p_stop(void)
+{
 qtest_end();
 rmdir(test_share);
+g_free(test_share);
+}
+
+static void pci_nop(void)
+{
+qvirtio_9p_start();
+qvirtio_9p_stop();
+}
+
+int main(int argc, char **argv)
+{
+g_test_init(, , NULL);
+qtest_add_func("/virtio/9p/pci/nop", pci_nop);
 
-return ret;
+return g_test_run();
 }
-- 
2.5.5




[Qemu-devel] [PATCH v4 24/35] target-i386: emulate XCHG using atomic helper

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-19-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/translate.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index e781869..c8827f3 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -5564,12 +5564,8 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 gen_lea_modrm(env, s, modrm);
 gen_op_mov_v_reg(ot, cpu_T0, reg);
 /* for xchg, lock is implicit */
-if (!(prefixes & PREFIX_LOCK))
-gen_helper_lock();
-gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
-gen_op_st_v(s, ot, cpu_T0, cpu_A0);
-if (!(prefixes & PREFIX_LOCK))
-gen_helper_unlock();
+tcg_gen_atomic_xchg_tl(cpu_T1, cpu_A0, cpu_T0,
+   s->mem_index, ot | MO_LE);
 gen_op_mov_reg_v(ot, reg, cpu_T1);
 }
 break;
-- 
2.5.5




[Qemu-devel] [PATCH v4 18/35] target-i386: emulate LOCK'ed OP instructions using atomic helpers

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

[rth: Eliminate some unnecessary temporaries.]

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-13-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/translate.c | 76 +
 1 file changed, 58 insertions(+), 18 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 5d9790a..b5c7791 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -1258,55 +1258,95 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp 
ot, int d)
 {
 if (d != OR_TMP0) {
 gen_op_mov_v_reg(ot, cpu_T0, d);
-} else {
+} else if (!(s1->prefix & PREFIX_LOCK)) {
 gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
 }
 switch(op) {
 case OP_ADCL:
 gen_compute_eflags_c(s1, cpu_tmp4);
-tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
-tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
-gen_op_st_rm_T0_A0(s1, ot, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_add_tl(cpu_T0, cpu_tmp4, cpu_T1);
+tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
+s1->mem_index, ot | MO_LE);
+} else {
+tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
+tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_tmp4);
+gen_op_st_rm_T0_A0(s1, ot, d);
+}
 gen_op_update3_cc(cpu_tmp4);
 set_cc_op(s1, CC_OP_ADCB + ot);
 break;
 case OP_SBBL:
 gen_compute_eflags_c(s1, cpu_tmp4);
-tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
-tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
-gen_op_st_rm_T0_A0(s1, ot, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_add_tl(cpu_T0, cpu_T1, cpu_tmp4);
+tcg_gen_neg_tl(cpu_T0, cpu_T0);
+tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
+s1->mem_index, ot | MO_LE);
+} else {
+tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
+tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_tmp4);
+gen_op_st_rm_T0_A0(s1, ot, d);
+}
 gen_op_update3_cc(cpu_tmp4);
 set_cc_op(s1, CC_OP_SBBB + ot);
 break;
 case OP_ADDL:
-tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
-gen_op_st_rm_T0_A0(s1, ot, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
+s1->mem_index, ot | MO_LE);
+} else {
+tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
+gen_op_st_rm_T0_A0(s1, ot, d);
+}
 gen_op_update2_cc();
 set_cc_op(s1, CC_OP_ADDB + ot);
 break;
 case OP_SUBL:
-tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
-tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
-gen_op_st_rm_T0_A0(s1, ot, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_neg_tl(cpu_T0, cpu_T1);
+tcg_gen_atomic_fetch_add_tl(cpu_cc_srcT, cpu_A0, cpu_T0,
+s1->mem_index, ot | MO_LE);
+tcg_gen_sub_tl(cpu_T0, cpu_cc_srcT, cpu_T1);
+} else {
+tcg_gen_mov_tl(cpu_cc_srcT, cpu_T0);
+tcg_gen_sub_tl(cpu_T0, cpu_T0, cpu_T1);
+gen_op_st_rm_T0_A0(s1, ot, d);
+}
 gen_op_update2_cc();
 set_cc_op(s1, CC_OP_SUBB + ot);
 break;
 default:
 case OP_ANDL:
-tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
-gen_op_st_rm_T0_A0(s1, ot, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_atomic_and_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
+s1->mem_index, ot | MO_LE);
+} else {
+tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1);
+gen_op_st_rm_T0_A0(s1, ot, d);
+}
 gen_op_update1_cc();
 set_cc_op(s1, CC_OP_LOGICB + ot);
 break;
 case OP_ORL:
-tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
-gen_op_st_rm_T0_A0(s1, ot, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_atomic_or_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
+   s1->mem_index, ot | MO_LE);
+} else {
+tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_T1);
+gen_op_st_rm_T0_A0(s1, ot, d);
+}
 gen_op_update1_cc();
 set_cc_op(s1, CC_OP_LOGICB + ot);
 break;
 case OP_XORL:
-tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
-gen_op_st_rm_T0_A0(s1, ot, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T1,
+s1->mem_index, ot | MO_LE);
+} else {
+tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_T1);
+gen_op_st_rm_T0_A0(s1, ot, d);
+}
 gen_op_update1_cc();
 set_cc_op(s1, CC_OP_LOGICB + ot);
 break;

[Qemu-devel] [PATCH v4 30/35] target-arm: emulate aarch64's LL/SC using cmpxchg helpers

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

Emulating LL/SC with cmpxchg is not correct, since it can
suffer from the ABA problem. Portable parallel code, however,
is written assuming only cmpxchg--and not LL/SC--is available.
This means that in practice emulating LL/SC with cmpxchg is
a viable alternative.

The appended emulates LL/SC pairs in aarch64 with cmpxchg helpers.
This works in both user and system mode. In usermode, it avoids
pausing all other CPUs to perform the LL/SC pair. The subsequent
performance and scalability improvement is significant, as the
plots below show. They plot the throughput of atomic_add-bench
compiled for ARM and executed on a 64-core x86 machine.

Hi-res plots: http://imgur.com/a/JVc8Y

atomic_add-bench: 100 ops/thread, [0,1] range

  18 ++-+--+-+--+--+--+---++
 +cmpxchg +-E--+   + +  +  +  +|
  16 ++master +-H--+  ++
 |||
  14 ++   ++
 | |   |
  12 ++|  ++
 | |   |
  10  ++
   8 ++E  ++
 |+++  |
   6 ++ | ++
 |  |  |
   4 ++ | ++
 |   | |
   2 +H++E+---++
 + | +E+++E+---+--+E+++E+--+E+--+E+++E+---+--+E|
   0 ++H-HH-+-H+-+--+--+--+---++
 0  10 2030 40 50 60
Number of threads

atomic_add-bench: 100 ops/thread, [0,2] range

  18 ++-+--+-+--+--+--+---++
 +cmpxchg +-E--+   + +  +  +  +|
  16 ++master +-H--+  ++
 | |   |
  14 ++E  ++
 | |   |
  12 ++|  ++
 |+++  |
  10 ++ | ++
   8 ++ | ++
 |  |  |
   6 ++ | ++
 |   | |
   4 ++  |++
 |  +E+--- |
   2 +H+ +E+-+++  +++  +++   ---+E+-+E+--+++
 +++++E+---+--+E+++E+--+E+---   +++   +  +E|
   0 ++H-HH-+-H+-+--+--+--+---++
 0  10 2030 40 50 60
Number of threads

   atomic_add-bench: 100 ops/thread, [0,128] range

  70 ++-+--+-+--+--+--+---++
 +cmpxchg +-E--+   + +  +  +  +|
  60 ++master +-H--+  +++---+E+-+E+--+E+
 |+E+--E---+E+---  |
 | ---+++  |
  50 ++  +++---   ++
 |  -+E+   |
  40 ++  +++  ++
 |E-   |
 |  --||
  30 ++   -- +++  ++
 |  +E+|
  20 ++E+ ++
 |E+  

[Qemu-devel] [PULL v2 4/8] 9pfs: introduce v9fs_path_sprintf() helper

2016-09-16 Thread Greg Kurz
This helper is similar to v9fs_string_sprintf(), but it includes the
terminating NUL character in the size field.

This is to avoid doing v9fs_string_sprintf((V9fsString *) ) and
then bumping the size.

Affected users are changed to use this new helper.

Signed-off-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 hw/9pfs/9p-local.c |  7 ++-
 hw/9pfs/9p-proxy.c |  7 ++-
 hw/9pfs/9p.c   | 19 ---
 hw/9pfs/9p.h   |  1 +
 4 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 3f271fcbd2c5..845675e7a1bb 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1060,13 +1060,10 @@ static int local_name_to_path(FsContext *ctx, V9fsPath 
*dir_path,
   const char *name, V9fsPath *target)
 {
 if (dir_path) {
-v9fs_string_sprintf((V9fsString *)target, "%s/%s",
-dir_path->data, name);
+v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
 } else {
-v9fs_string_sprintf((V9fsString *)target, "%s", name);
+v9fs_path_sprintf(target, "%s", name);
 }
-/* Bump the size for including terminating NULL */
-target->size++;
 return 0;
 }
 
diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index d091564b6fd2..f2417b7fd73d 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -1023,13 +1023,10 @@ static int proxy_name_to_path(FsContext *ctx, V9fsPath 
*dir_path,
   const char *name, V9fsPath *target)
 {
 if (dir_path) {
-v9fs_string_sprintf((V9fsString *)target, "%s/%s",
-dir_path->data, name);
+v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
 } else {
-v9fs_string_sprintf((V9fsString *)target, "%s", name);
+v9fs_path_sprintf(target, "%s", name);
 }
-/* Bump the size for including terminating NULL */
-target->size++;
 return 0;
 }
 
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index d8f48ca76c47..639f93930285 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include 
 #include "hw/virtio/virtio.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
@@ -179,6 +180,20 @@ void v9fs_path_free(V9fsPath *path)
 path->size = 0;
 }
 
+
+void GCC_FMT_ATTR(2, 3)
+v9fs_path_sprintf(V9fsPath *path, const char *fmt, ...)
+{
+va_list ap;
+
+v9fs_path_free(path);
+
+va_start(ap, fmt);
+/* Bump the size for including terminating NULL */
+path->size = g_vasprintf(>data, fmt, ap) + 1;
+va_end(ap);
+}
+
 void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs)
 {
 v9fs_path_free(lhs);
@@ -917,10 +932,8 @@ static void v9fs_fix_path(V9fsPath *dst, V9fsPath *src, 
int len)
 V9fsPath str;
 v9fs_path_init();
 v9fs_path_copy(, dst);
-v9fs_string_sprintf((V9fsString *)dst, "%s%s", src->data, str.data+len);
+v9fs_path_sprintf(dst, "%s%s", src->data, str.data + len);
 v9fs_path_free();
-/* +1 to include terminating NULL */
-dst->size++;
 }
 
 static inline bool is_ro_export(FsContext *ctx)
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index a38603398ef5..d539d2ebe9c0 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -327,6 +327,7 @@ static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu)
 extern void v9fs_reclaim_fd(V9fsPDU *pdu);
 extern void v9fs_path_init(V9fsPath *path);
 extern void v9fs_path_free(V9fsPath *path);
+extern void v9fs_path_sprintf(V9fsPath *path, const char *fmt, ...);
 extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs);
 extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath,
  const char *name, V9fsPath *path);
-- 
2.5.5




[Qemu-devel] [PATCH v4 19/35] target-i386: emulate LOCK'ed INC using atomic helper

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

[rth: Merge gen_inc_locked back into gen_inc to share cc update.]

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-14-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/translate.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index b5c7791..a38d953 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -1362,21 +1362,23 @@ static void gen_op(DisasContext *s1, int op, TCGMemOp 
ot, int d)
 /* if d == OR_TMP0, it means memory operand (address in A0) */
 static void gen_inc(DisasContext *s1, TCGMemOp ot, int d, int c)
 {
-if (d != OR_TMP0) {
-gen_op_mov_v_reg(ot, cpu_T0, d);
+if (s1->prefix & PREFIX_LOCK) {
+tcg_gen_movi_tl(cpu_T0, c > 0 ? 1 : -1);
+tcg_gen_atomic_add_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
+s1->mem_index, ot | MO_LE);
 } else {
-gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
+if (d != OR_TMP0) {
+gen_op_mov_v_reg(ot, cpu_T0, d);
+} else {
+gen_op_ld_v(s1, ot, cpu_T0, cpu_A0);
+}
+tcg_gen_addi_tl(cpu_T0, cpu_T0, (c > 0 ? 1 : -1));
+gen_op_st_rm_T0_A0(s1, ot, d);
 }
+
 gen_compute_eflags_c(s1, cpu_cc_src);
-if (c > 0) {
-tcg_gen_addi_tl(cpu_T0, cpu_T0, 1);
-set_cc_op(s1, CC_OP_INCB + ot);
-} else {
-tcg_gen_addi_tl(cpu_T0, cpu_T0, -1);
-set_cc_op(s1, CC_OP_DECB + ot);
-}
-gen_op_st_rm_T0_A0(s1, ot, d);
 tcg_gen_mov_tl(cpu_cc_dst, cpu_T0);
+set_cc_op(s1, (c > 0 ? CC_OP_INCB : CC_OP_DECB) + ot);
 }
 
 static void gen_shift_flags(DisasContext *s, TCGMemOp ot, TCGv result,
-- 
2.5.5




[Qemu-devel] [PATCH v4 33/35] target-arm: remove EXCP_STREX + cpu_exclusive_{test, info}

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

The exception is not emitted anymore; remove it and the associated
TCG variables.

Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
Message-Id: <1467054136-10430-31-git-send-email-c...@braap.org>
---
 target-arm/cpu.h   | 17 ++---
 target-arm/internals.h |  4 +---
 target-arm/translate.c | 10 --
 target-arm/translate.h |  4 
 4 files changed, 7 insertions(+), 28 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 76d824d..a38cec0 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -46,13 +46,12 @@
 #define EXCP_BKPT7
 #define EXCP_EXCEPTION_EXIT  8   /* Return from v7M exception.  */
 #define EXCP_KERNEL_TRAP 9   /* Jumped to kernel code page.  */
-#define EXCP_STREX  10
-#define EXCP_HVC11   /* HyperVisor Call */
-#define EXCP_HYP_TRAP   12
-#define EXCP_SMC13   /* Secure Monitor Call */
-#define EXCP_VIRQ   14
-#define EXCP_VFIQ   15
-#define EXCP_SEMIHOST   16   /* semihosting call (A64 only) */
+#define EXCP_HVC10   /* HyperVisor Call */
+#define EXCP_HYP_TRAP   11
+#define EXCP_SMC12   /* Secure Monitor Call */
+#define EXCP_VIRQ   13
+#define EXCP_VFIQ   14
+#define EXCP_SEMIHOST   15   /* semihosting call (A64 only) */
 
 #define ARMV7M_EXCP_RESET   1
 #define ARMV7M_EXCP_NMI 2
@@ -475,10 +474,6 @@ typedef struct CPUARMState {
 uint64_t exclusive_addr;
 uint64_t exclusive_val;
 uint64_t exclusive_high;
-#if defined(CONFIG_USER_ONLY)
-uint64_t exclusive_test;
-uint32_t exclusive_info;
-#endif
 
 /* iwMMXt coprocessor state.  */
 struct {
diff --git a/target-arm/internals.h b/target-arm/internals.h
index cd57401..3edccd2 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -46,8 +46,7 @@ static inline bool excp_is_internal(int excp)
 || excp == EXCP_HALTED
 || excp == EXCP_EXCEPTION_EXIT
 || excp == EXCP_KERNEL_TRAP
-|| excp == EXCP_SEMIHOST
-|| excp == EXCP_STREX;
+|| excp == EXCP_SEMIHOST;
 }
 
 /* Exception names for debug logging; note that not all of these
@@ -63,7 +62,6 @@ static const char * const excnames[] = {
 [EXCP_BKPT] = "Breakpoint",
 [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
 [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
-[EXCP_STREX] = "QEMU intercept of STREX",
 [EXCP_HVC] = "Hypervisor Call",
 [EXCP_HYP_TRAP] = "Hypervisor Trap",
 [EXCP_SMC] = "Secure Monitor Call",
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 0b35f9e..604f43f 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -64,10 +64,6 @@ static TCGv_i32 cpu_R[16];
 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
 TCGv_i64 cpu_exclusive_addr;
 TCGv_i64 cpu_exclusive_val;
-#ifdef CONFIG_USER_ONLY
-TCGv_i64 cpu_exclusive_test;
-TCGv_i32 cpu_exclusive_info;
-#endif
 
 /* FIXME:  These should be removed.  */
 static TCGv_i32 cpu_F0s, cpu_F1s;
@@ -101,12 +97,6 @@ void arm_translate_init(void)
 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
 offsetof(CPUARMState, exclusive_val), "exclusive_val");
-#ifdef CONFIG_USER_ONLY
-cpu_exclusive_test = tcg_global_mem_new_i64(cpu_env,
-offsetof(CPUARMState, exclusive_test), "exclusive_test");
-cpu_exclusive_info = tcg_global_mem_new_i32(cpu_env,
-offsetof(CPUARMState, exclusive_info), "exclusive_info");
-#endif
 
 a64_translate_init();
 }
diff --git a/target-arm/translate.h b/target-arm/translate.h
index dbd7ac8..d4e205e 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -77,10 +77,6 @@ extern TCGv_env cpu_env;
 extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
 extern TCGv_i64 cpu_exclusive_addr;
 extern TCGv_i64 cpu_exclusive_val;
-#ifdef CONFIG_USER_ONLY
-extern TCGv_i64 cpu_exclusive_test;
-extern TCGv_i32 cpu_exclusive_info;
-#endif
 
 static inline int arm_dc_feature(DisasContext *dc, int feature)
 {
-- 
2.5.5




Re: [Qemu-devel] [PATCH v6 1/7] linux-user: Fix TARGET_SIOCATMARK definition for Mips

2016-09-16 Thread Laurent Vivier


Le 16/09/2016 à 13:14, Aleksandar Markovic a écrit :
> From: Aleksandar Markovic 
> 
> This patch fixes wrong definition of TARGET_SIOCATMARK for Mips.
> 
> The current definition is:
> 
>   #define SIOCATMARK  0x8905
> 
> while the correct definition is:
> 
>   #define SIOCATMARK  TARGET_IOR('s', 7, int)

According to linux sources, it seems true also for alpha and sh4.

Perhaps you can add them to the patch?
Do you have something to test it doesn't break anything?

Thanks,
Laurent



[Qemu-devel] [PULL v2 3/8] 9pfs: drop useless v9fs_string_null() function

2016-09-16 Thread Greg Kurz
The v9fs_string_null() function just calls v9fs_string_free(). Also it
only has 4 users, whereas v9fs_string_free() has 87.

This patch converts users to call directly v9fs_string_free() and drops
the useless function.

Signed-off-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 fsdev/9p-marshal.c | 5 -
 fsdev/9p-marshal.h | 1 -
 hw/9pfs/9p.c   | 8 
 3 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/fsdev/9p-marshal.c b/fsdev/9p-marshal.c
index 238dbf21b1d5..a01bba6908a8 100644
--- a/fsdev/9p-marshal.c
+++ b/fsdev/9p-marshal.c
@@ -25,11 +25,6 @@ void v9fs_string_free(V9fsString *str)
 str->size = 0;
 }
 
-void v9fs_string_null(V9fsString *str)
-{
-v9fs_string_free(str);
-}
-
 void GCC_FMT_ATTR(2, 3)
 v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
 {
diff --git a/fsdev/9p-marshal.h b/fsdev/9p-marshal.h
index 140db6d99f9c..77f7fef326ee 100644
--- a/fsdev/9p-marshal.h
+++ b/fsdev/9p-marshal.h
@@ -77,7 +77,6 @@ static inline void v9fs_string_init(V9fsString *str)
 str->size = 0;
 }
 extern void v9fs_string_free(V9fsString *str);
-extern void v9fs_string_null(V9fsString *str);
 extern void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...);
 extern void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs);
 
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index dfe293d11d1c..d8f48ca76c47 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -810,15 +810,15 @@ static int stat_to_v9stat(V9fsPDU *pdu, V9fsPath *name,
 v9stat->mtime = stbuf->st_mtime;
 v9stat->length = stbuf->st_size;
 
-v9fs_string_null(>uid);
-v9fs_string_null(>gid);
-v9fs_string_null(>muid);
+v9fs_string_free(>uid);
+v9fs_string_free(>gid);
+v9fs_string_free(>muid);
 
 v9stat->n_uid = stbuf->st_uid;
 v9stat->n_gid = stbuf->st_gid;
 v9stat->n_muid = 0;
 
-v9fs_string_null(>extension);
+v9fs_string_free(>extension);
 
 if (v9stat->mode & P9_STAT_MODE_SYMLINK) {
 err = v9fs_co_readlink(pdu, name, >extension);
-- 
2.5.5




[Qemu-devel] [PATCH v4 14/35] tcg: Add atomic128 helpers

2016-09-16 Thread Richard Henderson
Force the use of cmpxchg16b on x86_64.

Wikipedia suggests that only very old AMD64 (circa 2004) did not have
this instruction.  Further, it's required by Windows 8 so no new cpus
will ever omit it.

If we truely care about these, then we could check this at startup time
and then avoid executing paths that use it.

Signed-off-by: Richard Henderson 
---
 atomic_template.h | 40 +++-
 configure | 29 -
 cputlb.c  |  5 +
 include/qemu/int128.h |  6 ++
 tcg-runtime.c | 20 +++-
 tcg/tcg.h | 24 +++-
 6 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/atomic_template.h b/atomic_template.h
index d2c8a08..4fdf722 100644
--- a/atomic_template.h
+++ b/atomic_template.h
@@ -18,7 +18,11 @@
  * License along with this library; if not, see .
  */
 
-#if DATA_SIZE == 8
+#if DATA_SIZE == 16
+# define SUFFIX o
+# define DATA_TYPE  Int128
+# define BSWAP  bswap128
+#elif DATA_SIZE == 8
 # define SUFFIX q
 # define DATA_TYPE  uint64_t
 # define BSWAP  bswap64
@@ -59,6 +63,21 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, 
target_ulong addr,
 return atomic_cmpxchg__nocheck(haddr, cmpv, newv);
 }
 
+#if DATA_SIZE >= 16
+ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
+{
+DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
+__atomic_load(haddr, , __ATOMIC_RELAXED);
+return val;
+}
+
+void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
+ ABI_TYPE val EXTRA_ARGS)
+{
+DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
+__atomic_store(haddr, , __ATOMIC_RELAXED);
+}
+#else
 ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
ABI_TYPE val EXTRA_ARGS)
 {
@@ -84,6 +103,8 @@ GEN_ATOMIC_HELPER(or_fetch)
 GEN_ATOMIC_HELPER(xor_fetch)
 
 #undef GEN_ATOMIC_HELPER
+#endif /* DATA SIZE >= 16 */
+
 #undef END
 
 #if DATA_SIZE > 1
@@ -101,6 +122,22 @@ ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, 
target_ulong addr,
 return BSWAP(atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv)));
 }
 
+#if DATA_SIZE >= 16
+ABI_TYPE ATOMIC_NAME(ld)(CPUArchState *env, target_ulong addr EXTRA_ARGS)
+{
+DATA_TYPE val, *haddr = ATOMIC_MMU_LOOKUP;
+__atomic_load(haddr, , __ATOMIC_RELAXED);
+return BSWAP(val);
+}
+
+void ATOMIC_NAME(st)(CPUArchState *env, target_ulong addr,
+ ABI_TYPE val EXTRA_ARGS)
+{
+DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
+val = BSWAP(val);
+__atomic_store(haddr, , __ATOMIC_RELAXED);
+}
+#else
 ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
ABI_TYPE val EXTRA_ARGS)
 {
@@ -162,6 +199,7 @@ ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, 
target_ulong addr,
 ldo = ldn;
 }
 }
+#endif /* DATA_SIZE >= 16 */
 
 #undef END
 #endif /* DATA_SIZE > 1 */
diff --git a/configure b/configure
index 7d083bd..b4d3f90 100755
--- a/configure
+++ b/configure
@@ -1217,7 +1217,10 @@ case "$cpu" in
cc_i386='$(CC) -m32'
;;
 x86_64)
-   CPU_CFLAGS="-m64"
+   # ??? Only extremely old AMD cpus do not have cmpxchg16b.
+   # If we truly care, we should simply detect this case at
+   # runtime and generate the fallback to serial emulation.
+   CPU_CFLAGS="-m64 -mcx16"
LDFLAGS="-m64 $LDFLAGS"
cc_i386='$(CC) -m32'
;;
@@ -4456,6 +4459,26 @@ if compile_prog "" "" ; then
 int128=yes
 fi
 
+#
+# See if 128-bit atomic operations are supported.
+
+atomic128=no
+if test "$int128" = "yes"; then
+  cat > $TMPC << EOF
+int main(void)
+{
+  unsigned __int128 x = 0, y = 0;
+  y = __atomic_load_16(, 0);
+  __atomic_store_16(, y, 0);
+  __atomic_compare_exchange_16(, , x, 0, 0, 0);
+  return 0;
+}
+EOF
+  if compile_prog "" "" ; then
+atomic128=yes
+  fi
+fi
+
 
 # check if getauxval is available.
 
@@ -5410,6 +5433,10 @@ if test "$int128" = "yes" ; then
   echo "CONFIG_INT128=y" >> $config_host_mak
 fi
 
+if test "$atomic128" = "yes" ; then
+  echo "CONFIG_ATOMIC128=y" >> $config_host_mak
+fi
+
 if test "$getauxval" = "yes" ; then
   echo "CONFIG_GETAUXVAL=y" >> $config_host_mak
 fi
diff --git a/cputlb.c b/cputlb.c
index 4f2c500..845b2a7 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -690,6 +690,11 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 #define DATA_SIZE 8
 #include "atomic_template.h"
 
+#ifdef CONFIG_ATOMIC128
+#define DATA_SIZE 16
+#include "atomic_template.h"
+#endif
+
 /* Second set of helpers are directly callable from TCG as helpers.  */
 
 #undef EXTRA_ARGS
diff --git a/include/qemu/int128.h b/include/qemu/int128.h
index 67440fa..261b55f 100644
--- a/include/qemu/int128.h
+++ b/include/qemu/int128.h
@@ -2,6 +2,7 @@
 #define 

[Qemu-devel] [PATCH v4 32/35] linux-user: remove handling of aarch64's EXCP_STREX

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

The exception is not emitted anymore.

Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
Message-Id: <1467054136-10430-30-git-send-email-c...@braap.org>
---
 linux-user/main.c | 125 --
 1 file changed, 125 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index f73b294..c225598 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -772,124 +772,6 @@ void cpu_loop(CPUARMState *env)
 
 #else
 
-/*
- * Handle AArch64 store-release exclusive
- *
- * rs = gets the status result of store exclusive
- * rt = is the register that is stored
- * rt2 = is the second register store (in STP)
- *
- */
-static int do_strex_a64(CPUARMState *env)
-{
-uint64_t val;
-int size;
-bool is_pair;
-int rc = 1;
-int segv = 0;
-uint64_t addr;
-int rs, rt, rt2;
-
-start_exclusive();
-/* size | is_pair << 2 | (rs << 4) | (rt << 9) | (rt2 << 14)); */
-size = extract32(env->exclusive_info, 0, 2);
-is_pair = extract32(env->exclusive_info, 2, 1);
-rs = extract32(env->exclusive_info, 4, 5);
-rt = extract32(env->exclusive_info, 9, 5);
-rt2 = extract32(env->exclusive_info, 14, 5);
-
-addr = env->exclusive_addr;
-
-if (addr != env->exclusive_test) {
-goto finish;
-}
-
-switch (size) {
-case 0:
-segv = get_user_u8(val, addr);
-break;
-case 1:
-segv = get_user_u16(val, addr);
-break;
-case 2:
-segv = get_user_u32(val, addr);
-break;
-case 3:
-segv = get_user_u64(val, addr);
-break;
-default:
-abort();
-}
-if (segv) {
-env->exception.vaddress = addr;
-goto error;
-}
-if (val != env->exclusive_val) {
-goto finish;
-}
-if (is_pair) {
-if (size == 2) {
-segv = get_user_u32(val, addr + 4);
-} else {
-segv = get_user_u64(val, addr + 8);
-}
-if (segv) {
-env->exception.vaddress = addr + (size == 2 ? 4 : 8);
-goto error;
-}
-if (val != env->exclusive_high) {
-goto finish;
-}
-}
-/* handle the zero register */
-val = rt == 31 ? 0 : env->xregs[rt];
-switch (size) {
-case 0:
-segv = put_user_u8(val, addr);
-break;
-case 1:
-segv = put_user_u16(val, addr);
-break;
-case 2:
-segv = put_user_u32(val, addr);
-break;
-case 3:
-segv = put_user_u64(val, addr);
-break;
-}
-if (segv) {
-goto error;
-}
-if (is_pair) {
-/* handle the zero register */
-val = rt2 == 31 ? 0 : env->xregs[rt2];
-if (size == 2) {
-segv = put_user_u32(val, addr + 4);
-} else {
-segv = put_user_u64(val, addr + 8);
-}
-if (segv) {
-env->exception.vaddress = addr + (size == 2 ? 4 : 8);
-goto error;
-}
-}
-rc = 0;
-finish:
-env->pc += 4;
-/* rs == 31 encodes a write to the ZR, thus throwing away
- * the status return. This is rather silly but valid.
- */
-if (rs < 31) {
-env->xregs[rs] = rc;
-}
-error:
-/* instruction faulted, PC does not advance */
-/* either way a strex releases any exclusive lock we have */
-env->exclusive_addr = -1;
-end_exclusive();
-return segv;
-}
-
 /* AArch64 main loop */
 void cpu_loop(CPUARMState *env)
 {
@@ -931,11 +813,6 @@ void cpu_loop(CPUARMState *env)
 info._sifields._sigfault._addr = env->pc;
 queue_signal(env, info.si_signo, );
 break;
-case EXCP_STREX:
-if (!do_strex_a64(env)) {
-break;
-}
-/* fall through for segv */
 case EXCP_PREFETCH_ABORT:
 case EXCP_DATA_ABORT:
 info.si_signo = TARGET_SIGSEGV;
@@ -971,8 +848,6 @@ void cpu_loop(CPUARMState *env)
 process_pending_signals(env);
 /* Exception return on AArch64 always clears the exclusive monitor,
  * so any return to running guest code implies this.
- * A strex (successful or otherwise) also clears the monitor, so
- * we don't need to specialcase EXCP_STREX.
  */
 env->exclusive_addr = -1;
 }
-- 
2.5.5




[Qemu-devel] [PATCH v4 35/35] target-alpha: Emulate LL/SC using cmpxchg helpers

2016-09-16 Thread Richard Henderson
Emulating LL/SC with cmpxchg is not correct, since it can
suffer from the ABA problem.  However, portable parallel
code is writting assuming only cmpxchg which means that in
practice this is a viable alternative.

Signed-off-by: Richard Henderson 
---
 linux-user/main.c|  49 --
 target-alpha/cpu.h   |   4 --
 target-alpha/helper.c|   6 ---
 target-alpha/machine.c   |   2 -
 target-alpha/translate.c | 104 ---
 5 files changed, 45 insertions(+), 120 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index c225598..bd3d548 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2903,51 +2903,6 @@ void cpu_loop(CPUM68KState *env)
 #endif /* TARGET_M68K */
 
 #ifdef TARGET_ALPHA
-static void do_store_exclusive(CPUAlphaState *env, int reg, int quad)
-{
-target_ulong addr, val, tmp;
-target_siginfo_t info;
-int ret = 0;
-
-addr = env->lock_addr;
-tmp = env->lock_st_addr;
-env->lock_addr = -1;
-env->lock_st_addr = 0;
-
-start_exclusive();
-mmap_lock();
-
-if (addr == tmp) {
-if (quad ? get_user_s64(val, addr) : get_user_s32(val, addr)) {
-goto do_sigsegv;
-}
-
-if (val == env->lock_value) {
-tmp = env->ir[reg];
-if (quad ? put_user_u64(tmp, addr) : put_user_u32(tmp, addr)) {
-goto do_sigsegv;
-}
-ret = 1;
-}
-}
-env->ir[reg] = ret;
-env->pc += 4;
-
-mmap_unlock();
-end_exclusive();
-return;
-
- do_sigsegv:
-mmap_unlock();
-end_exclusive();
-
-info.si_signo = TARGET_SIGSEGV;
-info.si_errno = 0;
-info.si_code = TARGET_SEGV_MAPERR;
-info._sifields._sigfault._addr = addr;
-queue_signal(env, TARGET_SIGSEGV, );
-}
-
 void cpu_loop(CPUAlphaState *env)
 {
 CPUState *cs = CPU(alpha_env_get_cpu(env));
@@ -3122,10 +3077,6 @@ void cpu_loop(CPUAlphaState *env)
 queue_signal(env, info.si_signo, );
 }
 break;
-case EXCP_STL_C:
-case EXCP_STQ_C:
-do_store_exclusive(env, env->error_code, trapnr - EXCP_STL_C);
-break;
 case EXCP_INTERRUPT:
 /* Just indicate that signals should be handled asap.  */
 break;
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 871d9ba..b08d160 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -230,7 +230,6 @@ struct CPUAlphaState {
 uint64_t pc;
 uint64_t unique;
 uint64_t lock_addr;
-uint64_t lock_st_addr;
 uint64_t lock_value;
 
 /* The FPCR, and disassembled portions thereof.  */
@@ -346,9 +345,6 @@ enum {
 EXCP_ARITH,
 EXCP_FEN,
 EXCP_CALL_PAL,
-/* For Usermode emulation.  */
-EXCP_STL_C,
-EXCP_STQ_C,
 };
 
 /* Alpha-specific interrupt pending bits.  */
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 9ba3e1a..2ef6cbe 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -306,12 +306,6 @@ void alpha_cpu_do_interrupt(CPUState *cs)
 case EXCP_CALL_PAL:
 name = "call_pal";
 break;
-case EXCP_STL_C:
-name = "stl_c";
-break;
-case EXCP_STQ_C:
-name = "stq_c";
-break;
 }
 qemu_log("INT %6d: %s(%#x) pc=%016" PRIx64 " sp=%016" PRIx64 "\n",
  ++count, name, env->error_code, env->pc, env->ir[IR_SP]);
diff --git a/target-alpha/machine.c b/target-alpha/machine.c
index 710b783..b99a123 100644
--- a/target-alpha/machine.c
+++ b/target-alpha/machine.c
@@ -45,8 +45,6 @@ static VMStateField vmstate_env_fields[] = {
 VMSTATE_UINTTL(unique, CPUAlphaState),
 VMSTATE_UINTTL(lock_addr, CPUAlphaState),
 VMSTATE_UINTTL(lock_value, CPUAlphaState),
-/* Note that lock_st_addr is not saved; it is a temporary
-   used during the execution of the st[lq]_c insns.  */
 
 VMSTATE_UINT8(ps, CPUAlphaState),
 VMSTATE_UINT8(intr_flag, CPUAlphaState),
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index a2e2a62..03e4776 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -99,7 +99,6 @@ static TCGv cpu_std_ir[31];
 static TCGv cpu_fir[31];
 static TCGv cpu_pc;
 static TCGv cpu_lock_addr;
-static TCGv cpu_lock_st_addr;
 static TCGv cpu_lock_value;
 
 #ifndef CONFIG_USER_ONLY
@@ -116,7 +115,6 @@ void alpha_translate_init(void)
 static const GlobalVar vars[] = {
 DEF_VAR(pc),
 DEF_VAR(lock_addr),
-DEF_VAR(lock_st_addr),
 DEF_VAR(lock_value),
 };
 
@@ -198,6 +196,23 @@ static TCGv dest_sink(DisasContext *ctx)
 return ctx->sink;
 }
 
+static void free_context_temps(DisasContext *ctx)
+{
+if (!TCGV_IS_UNUSED_I64(ctx->sink)) {
+tcg_gen_discard_i64(ctx->sink);
+tcg_temp_free(ctx->sink);
+TCGV_UNUSED_I64(ctx->sink);
+}
+if (!TCGV_IS_UNUSED_I64(ctx->zero)) {
+

[Qemu-devel] [PATCH v4 15/35] tcg: Add CONFIG_ATOMIC64

2016-09-16 Thread Richard Henderson
Allow qemu to build on 32-bit hosts without 64-bit atomic ops.

Even if we only allow 32-bit hosts to multi-thread emulate 32-bit
guests, we still need some way to handle the 32-bit guest using a
64-bit atomic operation.  Do so by dropping back to single-step.

Signed-off-by: Richard Henderson 
---
 configure | 33 +
 cputlb.c  |  4 
 tcg-runtime.c |  7 +++
 tcg/tcg-op.c  | 22 ++
 tcg/tcg-runtime.h | 46 --
 tcg/tcg.h | 15 ---
 6 files changed, 114 insertions(+), 13 deletions(-)

diff --git a/configure b/configure
index b4d3f90..1ab2e4a 100755
--- a/configure
+++ b/configure
@@ -4479,6 +4479,35 @@ EOF
   fi
 fi
 
+#
+# See if 64-bit atomic operations are supported.
+# Note that without __atomic builtins, we can only
+# assume atomic loads/stores max at pointer size.
+
+cat > $TMPC << EOF
+#include 
+int main(void)
+{
+  uint64_t x = 0, y = 0;
+#ifdef __ATOMIC_RELAXED
+  y = __atomic_load_8(, 0);
+  __atomic_store_8(, y, 0);
+  __atomic_compare_exchange_8(, , x, 0, 0, 0);
+  __atomic_exchange_8(, y, 0);
+  __atomic_fetch_add_8(, y, 0);
+#else
+  char is_host64[sizeof(void *) >= sizeof(uint64_t) ? 1 : -1];
+  __sync_lock_test_and_set(, y);
+  __sync_val_compare_and_swap(, y, 0);
+  __sync_fetch_and_add(, y);
+#endif
+  return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  atomic64=yes
+fi
+
 
 # check if getauxval is available.
 
@@ -5437,6 +5466,10 @@ if test "$atomic128" = "yes" ; then
   echo "CONFIG_ATOMIC128=y" >> $config_host_mak
 fi
 
+if test "$atomic64" = "yes" ; then
+  echo "CONFIG_ATOMIC64=y" >> $config_host_mak
+fi
+
 if test "$getauxval" = "yes" ; then
   echo "CONFIG_GETAUXVAL=y" >> $config_host_mak
 fi
diff --git a/cputlb.c b/cputlb.c
index 845b2a7..cc4da4d 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -687,8 +687,10 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 #define DATA_SIZE 4
 #include "atomic_template.h"
 
+#ifdef CONFIG_ATOMIC64
 #define DATA_SIZE 8
 #include "atomic_template.h"
+#endif
 
 #ifdef CONFIG_ATOMIC128
 #define DATA_SIZE 16
@@ -713,8 +715,10 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 #define DATA_SIZE 4
 #include "atomic_template.h"
 
+#ifdef CONFIG_ATOMIC64
 #define DATA_SIZE 8
 #include "atomic_template.h"
+#endif
 
 /* Code access functions.  */
 
diff --git a/tcg-runtime.c b/tcg-runtime.c
index 0c97cdf..a7011f2 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -101,6 +101,11 @@ int64_t HELPER(mulsh_i64)(int64_t arg1, int64_t arg2)
 return h;
 }
 
+void HELPER(exit_atomic)(CPUArchState *env)
+{
+cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC());
+}
+
 #ifndef CONFIG_SOFTMMU
 /* The softmmu versions of these helpers are in cputlb.c.  */
 
@@ -130,8 +135,10 @@ static void *atomic_mmu_lookup(CPUArchState *env, 
target_ulong addr,
 #define DATA_SIZE 4
 #include "atomic_template.h"
 
+#ifdef CONFIG_ATOMIC64
 #define DATA_SIZE 8
 #include "atomic_template.h"
+#endif
 
 /* The following is only callable from other helpers, and matches up
with the softmmu version.  */
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 65e3663..cdd61d6 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -2040,14 +2040,20 @@ typedef void (*gen_atomic_op_i32)(TCGv_i32, TCGv_env, 
TCGv, TCGv_i32);
 typedef void (*gen_atomic_op_i64)(TCGv_i64, TCGv_env, TCGv, TCGv_i64);
 #endif
 
+#ifdef CONFIG_ATOMIC64
+# define WITH_ATOMIC64(X) X,
+#else
+# define WITH_ATOMIC64(X)
+#endif
+
 static void * const table_cmpxchg[16] = {
 [MO_8] = gen_helper_atomic_cmpxchgb,
 [MO_16 | MO_LE] = gen_helper_atomic_cmpxchgw_le,
 [MO_16 | MO_BE] = gen_helper_atomic_cmpxchgw_be,
 [MO_32 | MO_LE] = gen_helper_atomic_cmpxchgl_le,
 [MO_32 | MO_BE] = gen_helper_atomic_cmpxchgl_be,
-[MO_64 | MO_LE] = gen_helper_atomic_cmpxchgq_le,
-[MO_64 | MO_BE] = gen_helper_atomic_cmpxchgq_be,
+WITH_ATOMIC64([MO_64 | MO_LE] = gen_helper_atomic_cmpxchgq_le)
+WITH_ATOMIC64([MO_64 | MO_BE] = gen_helper_atomic_cmpxchgq_be)
 };
 
 void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, TCGv_i32 cmpv,
@@ -2117,6 +2123,7 @@ void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, 
TCGv_i64 cmpv,
 }
 tcg_temp_free_i64(t1);
 } else if ((memop & MO_SIZE) == MO_64) {
+#ifdef CONFIG_ATOMIC64
 gen_atomic_cx_i64 gen;
 
 gen = table_cmpxchg[memop & (MO_SIZE | MO_BSWAP)];
@@ -2131,6 +2138,9 @@ void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, 
TCGv_i64 cmpv,
 #else
 gen(retv, tcg_ctx.tcg_env, addr, cmpv, newv);
 #endif
+#else
+gen_helper_exit_atomic(tcg_ctx.tcg_env);
+#endif /* CONFIG_ATOMIC64 */
 } else {
 TCGv_i32 c32 = tcg_temp_new_i32();
 TCGv_i32 n32 = tcg_temp_new_i32();
@@ -2218,6 +2228,7 @@ static void do_atomic_op_i64(TCGv_i64 ret, TCGv addr, 

[Qemu-devel] [PATCH v4 27/35] target-arm: Rearrange aa32 load and store functions

2016-09-16 Thread Richard Henderson
Stop specializing on TARGET_LONG_BITS == 32; unconditionally allocate
a temp and expand with tcg_gen_extu_i32_tl.  Split out gen_aa32_addr,
gen_aa32_frob64, gen_aa32_ld_i32 and gen_aa32_st_i32 as separate interfaces.

Signed-off-by: Richard Henderson 
---
 target-arm/translate.c | 171 +++--
 1 file changed, 66 insertions(+), 105 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index 693d4bc..bcd2958 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -926,145 +926,106 @@ static inline void store_reg_from_load(DisasContext *s, 
int reg, TCGv_i32 var)
  * These functions work like tcg_gen_qemu_{ld,st}* except
  * that the address argument is TCGv_i32 rather than TCGv.
  */
-#if TARGET_LONG_BITS == 32
 
-#define DO_GEN_LD(SUFF, OPC, BE32_XOR)   \
-static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val,  \
- TCGv_i32 addr, int index)   \
-{\
-TCGMemOp opc = (OPC) | s->be_data;   \
-/* Not needed for user-mode BE32, where we use MO_BE instead.  */\
-if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) {   \
-TCGv addr_be = tcg_temp_new();   \
-tcg_gen_xori_i32(addr_be, addr, BE32_XOR);   \
-tcg_gen_qemu_ld_i32(val, addr_be, index, opc);   \
-tcg_temp_free(addr_be);  \
-return;  \
-}\
-tcg_gen_qemu_ld_i32(val, addr, index, opc);  \
-}
-
-#define DO_GEN_ST(SUFF, OPC, BE32_XOR)   \
-static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val,  \
- TCGv_i32 addr, int index)   \
-{\
-TCGMemOp opc = (OPC) | s->be_data;   \
-/* Not needed for user-mode BE32, where we use MO_BE instead.  */\
-if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) {   \
-TCGv addr_be = tcg_temp_new();   \
-tcg_gen_xori_i32(addr_be, addr, BE32_XOR);   \
-tcg_gen_qemu_st_i32(val, addr_be, index, opc);   \
-tcg_temp_free(addr_be);  \
-return;  \
-}\
-tcg_gen_qemu_st_i32(val, addr, index, opc);  \
-}
-
-static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
- TCGv_i32 addr, int index)
+static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
 {
-TCGMemOp opc = MO_Q | s->be_data;
-tcg_gen_qemu_ld_i64(val, addr, index, opc);
+TCGv addr = tcg_temp_new();
+tcg_gen_extu_i32_tl(addr, a32);
+
 /* Not needed for user-mode BE32, where we use MO_BE instead.  */
-if (!IS_USER_ONLY && s->sctlr_b) {
-tcg_gen_rotri_i64(val, val, 32);
+if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
+tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
 }
+return addr;
 }
 
-static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
- TCGv_i32 addr, int index)
+static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
+int index, TCGMemOp opc)
 {
-TCGMemOp opc = MO_Q | s->be_data;
-/* Not needed for user-mode BE32, where we use MO_BE instead.  */
-if (!IS_USER_ONLY && s->sctlr_b) {
-TCGv_i64 tmp = tcg_temp_new_i64();
-tcg_gen_rotri_i64(tmp, val, 32);
-tcg_gen_qemu_st_i64(tmp, addr, index, opc);
-tcg_temp_free_i64(tmp);
-return;
-}
-tcg_gen_qemu_st_i64(val, addr, index, opc);
+TCGv addr = gen_aa32_addr(s, a32, opc);
+tcg_gen_qemu_ld_i32(val, addr, index, opc);
+tcg_temp_free(addr);
 }
 
-#else
+static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
+int index, TCGMemOp opc)
+{
+TCGv addr = gen_aa32_addr(s, a32, opc);
+tcg_gen_qemu_st_i32(val, addr, index, opc);
+tcg_temp_free(addr);
+}
 
-#define DO_GEN_LD(SUFF, OPC, BE32_XOR)   \
+#define DO_GEN_LD(SUFF, OPC) \
 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val,  \
- TCGv_i32 addr, int index)   \
+   

[Qemu-devel] [PATCH v4 16/35] tcg: Emit barriers with parallel_cpus

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/tcg-op.c | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index cdd61d6..bb2bfee 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -150,17 +150,7 @@ void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg 
a1, TCGArg a2,
 
 void tcg_gen_mb(TCGBar mb_type)
 {
-bool emit_barriers = true;
-
-#ifndef CONFIG_USER_ONLY
-/* TODO: When MTTCG is available for system mode, we will check
- * the following condition and enable emit_barriers
- * (qemu_tcg_mttcg_enabled() && smp_cpus > 1)
- */
-emit_barriers = false;
-#endif
-
-if (emit_barriers) {
+if (parallel_cpus) {
 tcg_gen_op1(_ctx, INDEX_op_mb, mb_type);
 }
 }
-- 
2.5.5




[Qemu-devel] [PATCH v4 31/35] linux-user: remove handling of ARM's EXCP_STREX

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

The exception is not emitted anymore.

Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
Message-Id: <1467054136-10430-29-git-send-email-c...@braap.org>
---
 linux-user/main.c | 93 ---
 1 file changed, 93 deletions(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 9c4d1de..f73b294 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -553,94 +553,6 @@ do_kernel_trap(CPUARMState *env)
 return 0;
 }
 
-/* Store exclusive handling for AArch32 */
-static int do_strex(CPUARMState *env)
-{
-uint64_t val;
-int size;
-int rc = 1;
-int segv = 0;
-uint32_t addr;
-start_exclusive();
-if (env->exclusive_addr != env->exclusive_test) {
-goto fail;
-}
-/* We know we're always AArch32 so the address is in uint32_t range
- * unless it was the -1 exclusive-monitor-lost value (which won't
- * match exclusive_test above).
- */
-assert(extract64(env->exclusive_addr, 32, 32) == 0);
-addr = env->exclusive_addr;
-size = env->exclusive_info & 0xf;
-switch (size) {
-case 0:
-segv = get_user_u8(val, addr);
-break;
-case 1:
-segv = get_user_data_u16(val, addr, env);
-break;
-case 2:
-case 3:
-segv = get_user_data_u32(val, addr, env);
-break;
-default:
-abort();
-}
-if (segv) {
-env->exception.vaddress = addr;
-goto done;
-}
-if (size == 3) {
-uint32_t valhi;
-segv = get_user_data_u32(valhi, addr + 4, env);
-if (segv) {
-env->exception.vaddress = addr + 4;
-goto done;
-}
-if (arm_cpu_bswap_data(env)) {
-val = deposit64((uint64_t)valhi, 32, 32, val);
-} else {
-val = deposit64(val, 32, 32, valhi);
-}
-}
-if (val != env->exclusive_val) {
-goto fail;
-}
-
-val = env->regs[(env->exclusive_info >> 8) & 0xf];
-switch (size) {
-case 0:
-segv = put_user_u8(val, addr);
-break;
-case 1:
-segv = put_user_data_u16(val, addr, env);
-break;
-case 2:
-case 3:
-segv = put_user_data_u32(val, addr, env);
-break;
-}
-if (segv) {
-env->exception.vaddress = addr;
-goto done;
-}
-if (size == 3) {
-val = env->regs[(env->exclusive_info >> 12) & 0xf];
-segv = put_user_data_u32(val, addr + 4, env);
-if (segv) {
-env->exception.vaddress = addr + 4;
-goto done;
-}
-}
-rc = 0;
-fail:
-env->regs[15] += 4;
-env->regs[(env->exclusive_info >> 4) & 0xf] = rc;
-done:
-end_exclusive();
-return segv;
-}
-
 void cpu_loop(CPUARMState *env)
 {
 CPUState *cs = CPU(arm_env_get_cpu(env));
@@ -812,11 +724,6 @@ void cpu_loop(CPUARMState *env)
 case EXCP_INTERRUPT:
 /* just indicate that signals should be handled asap */
 break;
-case EXCP_STREX:
-if (!do_strex(env)) {
-break;
-}
-/* fall through for segv */
 case EXCP_PREFETCH_ABORT:
 case EXCP_DATA_ABORT:
 addr = env->exception.vaddress;
-- 
2.5.5




[Qemu-devel] [PULL v2 1/8] 9pfs: drop unused fmt strings in the proxy backend

2016-09-16 Thread Greg Kurz
The v9fs_request() function doesn't use its fmt argument: it passes literal
format strings to proxy_marshal() for all commands.

This patch simply drops the unused fmt argument and updates all callers
accordingly.

Signed-off-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 hw/9pfs/9p-proxy.c | 67 --
 1 file changed, 30 insertions(+), 37 deletions(-)

diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index f265501eac1d..52bbf4f1b37c 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -294,8 +294,7 @@ static int v9fs_receive_status(V9fsProxy *proxy,
  * This request read by proxy helper process
  * returns 0 on success and -errno on error
  */
-static int v9fs_request(V9fsProxy *proxy, int type,
-void *response, const char *fmt, ...)
+static int v9fs_request(V9fsProxy *proxy, int type, void *response, ...)
 {
 dev_t rdev;
 va_list ap;
@@ -317,7 +316,7 @@ static int v9fs_request(V9fsProxy *proxy, int type,
 }
 iovec = >out_iovec;
 reply = >in_iovec;
-va_start(ap, fmt);
+va_start(ap, response);
 switch (type) {
 case T_OPEN:
 path = va_arg(ap, V9fsString *);
@@ -605,7 +604,7 @@ close_error:
 static int proxy_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat 
*stbuf)
 {
 int retval;
-retval = v9fs_request(fs_ctx->private, T_LSTAT, stbuf, "s", fs_path);
+retval = v9fs_request(fs_ctx->private, T_LSTAT, stbuf, fs_path);
 if (retval < 0) {
 errno = -retval;
 return -1;
@@ -617,8 +616,7 @@ static ssize_t proxy_readlink(FsContext *fs_ctx, V9fsPath 
*fs_path,
   char *buf, size_t bufsz)
 {
 int retval;
-retval = v9fs_request(fs_ctx->private, T_READLINK, buf, "sd",
-  fs_path, bufsz);
+retval = v9fs_request(fs_ctx->private, T_READLINK, buf, fs_path, bufsz);
 if (retval < 0) {
 errno = -retval;
 return -1;
@@ -639,7 +637,7 @@ static int proxy_closedir(FsContext *ctx, V9fsFidOpenState 
*fs)
 static int proxy_open(FsContext *ctx, V9fsPath *fs_path,
   int flags, V9fsFidOpenState *fs)
 {
-fs->fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, flags);
+fs->fd = v9fs_request(ctx->private, T_OPEN, NULL, fs_path, flags);
 if (fs->fd < 0) {
 errno = -fs->fd;
 fs->fd = -1;
@@ -653,7 +651,7 @@ static int proxy_opendir(FsContext *ctx,
 int serrno, fd;
 
 fs->dir.stream = NULL;
-fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
+fd = v9fs_request(ctx->private, T_OPEN, NULL, fs_path, O_DIRECTORY);
 if (fd < 0) {
 errno = -fd;
 return -1;
@@ -735,8 +733,8 @@ static ssize_t proxy_pwritev(FsContext *ctx, 
V9fsFidOpenState *fs,
 static int proxy_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
 {
 int retval;
-retval = v9fs_request(fs_ctx->private, T_CHMOD, NULL, "sd",
-  fs_path, credp->fc_mode);
+retval = v9fs_request(fs_ctx->private, T_CHMOD, NULL, fs_path,
+  credp->fc_mode);
 if (retval < 0) {
 errno = -retval;
 }
@@ -752,8 +750,8 @@ static int proxy_mknod(FsContext *fs_ctx, V9fsPath 
*dir_path,
 v9fs_string_init();
 v9fs_string_sprintf(, "%s/%s", dir_path->data, name);
 
-retval = v9fs_request(fs_ctx->private, T_MKNOD, NULL, "sdqdd",
-  , credp->fc_mode, credp->fc_rdev,
+retval = v9fs_request(fs_ctx->private, T_MKNOD, NULL, ,
+  credp->fc_mode, credp->fc_rdev,
   credp->fc_uid, credp->fc_gid);
 v9fs_string_free();
 if (retval < 0) {
@@ -772,7 +770,7 @@ static int proxy_mkdir(FsContext *fs_ctx, V9fsPath 
*dir_path,
 v9fs_string_init();
 v9fs_string_sprintf(, "%s/%s", dir_path->data, name);
 
-retval = v9fs_request(fs_ctx->private, T_MKDIR, NULL, "sddd", ,
+retval = v9fs_request(fs_ctx->private, T_MKDIR, NULL, ,
   credp->fc_mode, credp->fc_uid, credp->fc_gid);
 v9fs_string_free();
 if (retval < 0) {
@@ -804,9 +802,8 @@ static int proxy_open2(FsContext *fs_ctx, V9fsPath 
*dir_path, const char *name,
 v9fs_string_init();
 v9fs_string_sprintf(, "%s/%s", dir_path->data, name);
 
-fs->fd = v9fs_request(fs_ctx->private, T_CREATE, NULL, "s",
-  , flags, credp->fc_mode,
-  credp->fc_uid, credp->fc_gid);
+fs->fd = v9fs_request(fs_ctx->private, T_CREATE, NULL, , flags,
+  credp->fc_mode, credp->fc_uid, credp->fc_gid);
 v9fs_string_free();
 if (fs->fd < 0) {
 errno = -fs->fd;
@@ -827,8 +824,8 @@ static int proxy_symlink(FsContext *fs_ctx, const char 
*oldpath,
 v9fs_string_sprintf(, "%s/%s", dir_path->data, name);
 v9fs_string_sprintf(, "%s", oldpath);
 
-retval = v9fs_request(fs_ctx->private, 

[Qemu-devel] [PATCH v4 26/35] tests: add atomic_add-bench

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

With this microbenchmark we can measure the overhead of emulating atomic
instructions with a configurable degree of contention.

The benchmark spawns $n threads, each performing $o atomic ops (additions)
in a loop. Each atomic operation is performed on a different cache line
(assuming lines are 64b long) that is randomly selected from a range [0, $r).

[ Note: each $foo corresponds to a -foo flag ]

Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
Message-Id: <1467054136-10430-20-git-send-email-c...@braap.org>
---
 tests/.gitignore |   1 +
 tests/Makefile.include   |   4 +-
 tests/atomic_add-bench.c | 181 +++
 3 files changed, 185 insertions(+), 1 deletion(-)
 create mode 100644 tests/atomic_add-bench.c

diff --git a/tests/.gitignore b/tests/.gitignore
index b4a9cfc..6382a93 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,3 +1,4 @@
+atomic_add-bench
 check-qdict
 check-qfloat
 check-qint
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 2f11064..260e6b5 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -443,7 +443,8 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o 
tests/check-qdict.o \
tests/test-opts-visitor.o tests/test-qmp-event.o \
tests/rcutorture.o tests/test-rcu-list.o \
tests/test-qdist.o \
-   tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o
+   tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
+   tests/atomic_add-bench.o
 
 $(test-obj-y): QEMU_INCLUDES += -Itests
 QEMU_CFLAGS += -I$(SRC_PATH)/tests
@@ -488,6 +489,7 @@ tests/test-qht$(EXESUF): tests/test-qht.o $(test-util-obj-y)
 tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) 
$(test-util-obj-y)
 tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
 tests/test-bufferiszero$(EXESUF): tests/test-bufferiszero.o $(test-util-obj-y)
+tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y)
 
 tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
diff --git a/tests/atomic_add-bench.c b/tests/atomic_add-bench.c
new file mode 100644
index 000..77a9f03
--- /dev/null
+++ b/tests/atomic_add-bench.c
@@ -0,0 +1,181 @@
+#include "qemu/osdep.h"
+#include "qemu/thread.h"
+#include "qemu/host-utils.h"
+#include "qemu/processor.h"
+
+struct thread_info {
+uint64_t r;
+} QEMU_ALIGNED(64);
+
+struct count {
+unsigned long val;
+} QEMU_ALIGNED(64);
+
+static QemuThread *threads;
+static struct thread_info *th_info;
+static unsigned int n_threads = 1;
+static unsigned int n_ready_threads;
+static struct count *counts;
+static unsigned long n_ops = 1;
+static double duration;
+static unsigned int range = 1;
+static bool test_start;
+
+static const char commands_string[] =
+" -n = number of threads\n"
+" -o = number of ops per thread\n"
+" -r = range (will be rounded up to pow2)";
+
+static void usage_complete(char *argv[])
+{
+fprintf(stderr, "Usage: %s [options]\n", argv[0]);
+fprintf(stderr, "options:\n%s\n", commands_string);
+}
+
+/*
+ * From: https://en.wikipedia.org/wiki/Xorshift
+ * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only
+ * guaranteed to be >= INT_MAX).
+ */
+static uint64_t xorshift64star(uint64_t x)
+{
+x ^= x >> 12; /* a */
+x ^= x << 25; /* b */
+x ^= x >> 27; /* c */
+return x * UINT64_C(2685821657736338717);
+}
+
+static void *thread_func(void *arg)
+{
+struct thread_info *info = arg;
+unsigned long i;
+
+atomic_inc(_ready_threads);
+while (!atomic_mb_read(_start)) {
+cpu_relax();
+}
+
+for (i = 0; i < n_ops; i++) {
+unsigned int index;
+
+info->r = xorshift64star(info->r);
+index = info->r & (range - 1);
+atomic_inc([index].val);
+}
+return NULL;
+}
+
+static inline
+uint64_t ts_subtract(const struct timespec *a, const struct timespec *b)
+{
+uint64_t ns;
+
+ns = (b->tv_sec - a->tv_sec) * 10ULL;
+ns += (b->tv_nsec - a->tv_nsec);
+return ns;
+}
+
+static void run_test(void)
+{
+unsigned int i;
+struct timespec ts_start, ts_end;
+
+while (atomic_read(_ready_threads) != n_threads) {
+cpu_relax();
+}
+atomic_mb_set(_start, true);
+
+clock_gettime(CLOCK_MONOTONIC, _start);
+for (i = 0; i < n_threads; i++) {
+qemu_thread_join([i]);
+}
+clock_gettime(CLOCK_MONOTONIC, _end);
+duration = ts_subtract(_start, _end) / 1e9;
+}
+
+static void create_threads(void)
+{
+unsigned int i;
+
+threads = g_new(QemuThread, n_threads);
+th_info = g_new(struct thread_info, n_threads);
+counts = qemu_memalign(64, sizeof(*counts) * range);
+memset(counts, 0, sizeof(*counts) * range);
+
+for (i = 0; i < n_threads; i++) {
+struct 

[Qemu-devel] [PATCH v4 25/35] target-i386: remove helper_lock()

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

It's been superseded by the atomic helpers.

The use of the atomic helpers provides a significant performance and scalability
improvement. Below is the result of running the atomic_add-test microbenchmark 
with:
 $ x86_64-linux-user/qemu-x86_64 tests/atomic_add-bench -o 500 -r $r -n $n
, where $n is the number of threads and $r is the allowed range for the 
additions.

The scenarios measured are:
- atomic: implements x86' ADDL with the atomic_add helper (i.e. this patchset)
- cmpxchg: implement x86' ADDL with a TCG loop using the cmpxchg helper
- master: before this patchset

Results sorted in ascending range, i.e. descending degree of contention.
Y axis is Throughput in Mops/s. Tests are run on an AMD machine with 64
Opteron 6376 cores.

atomic_add-bench: 500 ops/thread, [0,1] range

  25 ++-+--+-+--+--+--+---++
 + atomic +-E--+   + +  +  +  +|
 |cmpxchg +-H--+   |
  20 +Emaster +-N--+  ++
 |||
 |++   |
 |||
  15 +++  ++
 |N|   |
 |+|   |
  10 ++|  ++
 |+|+  |
 | |-+E+--+++  ---+E+--+E+--+E+-+E+--+E|
 |+E+E+- +++ +E+--+E+--|
   5 ++|+ ++
 |+N+H+--- +++ |
 N+--+H+++++   +  +++  --++H+--+H+--+H+++H+---+--- |
   0 ++-+-H+---H-+--+--+--+---H+
 0  10 2030 40 50 60
Number of threads

atomic_add-bench: 500 ops/thread, [0,2] range

  25 ++-+--+-+--+--+--+---++
 ++atomic +-E--+   + +  +  +  +|
 |cmpxchg +-H--+   |
  20 ++master +-N--+  ++
 |E|   |
 |++   |
 ||E   |
  15 ++|  ++
 |N||  |
 |+||   ---+E+--+E+-+E+--+E|
  10 ++| |---+E+--+E+-+E+---+++  +++
 ||H+E+--+E+-- |
 |+|
 | ||  |
   5 ++|+H+--  +++++
 |+N+-  ---+H+--+H+--  |
 +  +N+--+H+++H+---+--+H+++H+---+  ++H+---+--+H|
   0 ++-+--+-+--+--+--+---++
 0  10 2030 40 50 60
Number of threads

atomic_add-bench: 500 ops/thread, [0,8] range

  40 ++-+--+-+--+--+--+---++
 ++atomic +-E--+   + +  +  +  +|
  35 +cmpxchg +-H--+  ++
 | master +-N--+   ---+E+--+E+--+E+-+E+--+E|
  30 ++|   ---+E+--   +++ ++
 | |-+E+---|
  25 ++E +++  ++
 |+ -+E+   |
  20 +E+ E-- +++  ++
 |H|+++|
 |+|   +H+---  |
  15 ++H+   ---+++  +H+-- ++
 |N++H+-- +++---

[Qemu-devel] [PATCH v4 12/35] cputlb: Tidy some macros

2016-09-16 Thread Richard Henderson
TGT_LE and TGT_BE are not size dependent and do not need to be
redefined.  The others are no longer used at all.

Signed-off-by: Richard Henderson 
---
 cputlb.c   |  8 
 softmmu_template.h | 22 --
 2 files changed, 8 insertions(+), 22 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 1bee47d..82cf46e 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -585,6 +585,14 @@ void probe_write(CPUArchState *env, target_ulong addr, int 
mmu_idx,
 }
 }
 
+#ifdef TARGET_WORDS_BIGENDIAN
+# define TGT_BE(X)  (X)
+# define TGT_LE(X)  BSWAP(X)
+#else
+# define TGT_BE(X)  BSWAP(X)
+# define TGT_LE(X)  (X)
+#endif
+
 #define MMUSUFFIX _mmu
 
 #define DATA_SIZE 1
diff --git a/softmmu_template.h b/softmmu_template.h
index 035ffc8..4a2b665 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -78,14 +78,6 @@
 # define BSWAP(X)  (X)
 #endif
 
-#ifdef TARGET_WORDS_BIGENDIAN
-# define TGT_BE(X)  (X)
-# define TGT_LE(X)  BSWAP(X)
-#else
-# define TGT_BE(X)  BSWAP(X)
-# define TGT_LE(X)  (X)
-#endif
-
 #if DATA_SIZE == 1
 # define helper_le_ld_name  glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)
 # define helper_be_ld_name  helper_le_ld_name
@@ -102,14 +94,6 @@
 # define helper_be_st_name  glue(glue(helper_be_st, SUFFIX), MMUSUFFIX)
 #endif
 
-#ifdef TARGET_WORDS_BIGENDIAN
-# define helper_te_ld_name  helper_be_ld_name
-# define helper_te_st_name  helper_be_st_name
-#else
-# define helper_te_ld_name  helper_le_ld_name
-# define helper_te_st_name  helper_le_st_name
-#endif
-
 #ifndef SOFTMMU_CODE_ACCESS
 static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
   size_t mmu_idx, size_t index,
@@ -441,15 +425,9 @@ void helper_be_st_name(CPUArchState *env, target_ulong 
addr, DATA_TYPE val,
 #undef USUFFIX
 #undef SSUFFIX
 #undef BSWAP
-#undef TGT_BE
-#undef TGT_LE
-#undef CPU_BE
-#undef CPU_LE
 #undef helper_le_ld_name
 #undef helper_be_ld_name
 #undef helper_le_lds_name
 #undef helper_be_lds_name
 #undef helper_le_st_name
 #undef helper_be_st_name
-#undef helper_te_ld_name
-#undef helper_te_st_name
-- 
2.5.5




[Qemu-devel] [PATCH v4 20/35] target-i386: emulate LOCK'ed NOT using atomic helper

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

[rth: Avoid qemu_load that's redundant with the atomic op.]

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-15-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/translate.c | 26 --
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index a38d953..49455a3 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4675,10 +4675,15 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 rm = (modrm & 7) | REX_B(s);
 op = (modrm >> 3) & 7;
 if (mod != 3) {
-if (op == 0)
+if (op == 0) {
 s->rip_offset = insn_const_size(ot);
+}
 gen_lea_modrm(env, s, modrm);
-gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
+/* For those below that handle locked memory, don't load here.  */
+if (!(s->prefix & PREFIX_LOCK)
+|| op != 2) {
+gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
+}
 } else {
 gen_op_mov_v_reg(ot, cpu_T0, rm);
 }
@@ -4691,11 +4696,20 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 set_cc_op(s, CC_OP_LOGICB + ot);
 break;
 case 2: /* not */
-tcg_gen_not_tl(cpu_T0, cpu_T0);
-if (mod != 3) {
-gen_op_st_v(s, ot, cpu_T0, cpu_A0);
+if (s->prefix & PREFIX_LOCK) {
+if (mod == 3) {
+goto illegal_op;
+}
+tcg_gen_movi_tl(cpu_T0, ~0);
+tcg_gen_atomic_xor_fetch_tl(cpu_T0, cpu_A0, cpu_T0,
+s->mem_index, ot | MO_LE);
 } else {
-gen_op_mov_reg_v(ot, rm, cpu_T0);
+tcg_gen_not_tl(cpu_T0, cpu_T0);
+if (mod != 3) {
+gen_op_st_v(s, ot, cpu_T0, cpu_A0);
+} else {
+gen_op_mov_reg_v(ot, rm, cpu_T0);
+}
 }
 break;
 case 3: /* neg */
-- 
2.5.5




[Qemu-devel] [PATCH v4 02/35] atomics: add atomic_op_fetch variants

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

This paves the way for upcoming work.

Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
Message-Id: <1467054136-10430-9-git-send-email-c...@braap.org>
---
 include/qemu/atomic.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 0124289..725144c 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -195,6 +195,14 @@
 #define atomic_fetch_or(ptr, n)  __atomic_fetch_or(ptr, n, __ATOMIC_SEQ_CST)
 #define atomic_fetch_xor(ptr, n) __atomic_fetch_xor(ptr, n, __ATOMIC_SEQ_CST)
 
+#define atomic_inc_fetch(ptr)__atomic_add_fetch(ptr, 1, __ATOMIC_SEQ_CST)
+#define atomic_dec_fetch(ptr)__atomic_sub_fetch(ptr, 1, __ATOMIC_SEQ_CST)
+#define atomic_add_fetch(ptr, n) __atomic_add_fetch(ptr, n, __ATOMIC_SEQ_CST)
+#define atomic_sub_fetch(ptr, n) __atomic_sub_fetch(ptr, n, __ATOMIC_SEQ_CST)
+#define atomic_and_fetch(ptr, n) __atomic_and_fetch(ptr, n, __ATOMIC_SEQ_CST)
+#define atomic_or_fetch(ptr, n)  __atomic_or_fetch(ptr, n, __ATOMIC_SEQ_CST)
+#define atomic_xor_fetch(ptr, n) __atomic_xor_fetch(ptr, n, __ATOMIC_SEQ_CST)
+
 /* And even shorter names that return void.  */
 #define atomic_inc(ptr)((void) __atomic_fetch_add(ptr, 1, 
__ATOMIC_SEQ_CST))
 #define atomic_dec(ptr)((void) __atomic_fetch_sub(ptr, 1, 
__ATOMIC_SEQ_CST))
@@ -390,6 +398,15 @@
 #define atomic_fetch_and   __sync_fetch_and_and
 #define atomic_fetch_or__sync_fetch_and_or
 #define atomic_fetch_xor   __sync_fetch_and_xor
+
+#define atomic_inc_fetch(ptr)  __sync_add_and_fetch(ptr, 1)
+#define atomic_dec_fetch(ptr)  __sync_add_and_fetch(ptr, -1)
+#define atomic_add_fetch   __sync_add_and_fetch
+#define atomic_sub_fetch   __sync_sub_and_fetch
+#define atomic_and_fetch   __sync_and_and_fetch
+#define atomic_or_fetch__sync_or_and_fetch
+#define atomic_xor_fetch   __sync_xor_and_fetch
+
 #define atomic_cmpxchg __sync_val_compare_and_swap
 
 /* And even shorter names that return void.  */
-- 
2.5.5




[Qemu-devel] [PATCH v4 23/35] target-i386: emulate LOCK'ed BTX ops using atomic helpers

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

[rth: Avoid redundant qemu_ld in locked case.  Fix previously unnoticed
incorrect zero-extension of address in register-offset case.]

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-18-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/translate.c | 87 -
 1 file changed, 57 insertions(+), 30 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 049b1e4..e781869 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -6655,7 +6655,9 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 if (mod != 3) {
 s->rip_offset = 1;
 gen_lea_modrm(env, s, modrm);
-gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
+if (!(s->prefix & PREFIX_LOCK)) {
+gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
+}
 } else {
 gen_op_mov_v_reg(ot, cpu_T0, rm);
 }
@@ -6685,44 +6687,69 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 rm = (modrm & 7) | REX_B(s);
 gen_op_mov_v_reg(MO_32, cpu_T1, reg);
 if (mod != 3) {
-gen_lea_modrm(env, s, modrm);
+AddressParts a = gen_lea_modrm_0(env, s, modrm);
 /* specific case: we need to add a displacement */
 gen_exts(ot, cpu_T1);
 tcg_gen_sari_tl(cpu_tmp0, cpu_T1, 3 + ot);
 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
-tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
-gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
+tcg_gen_add_tl(cpu_A0, gen_lea_modrm_1(a), cpu_tmp0);
+gen_lea_v_seg(s, s->aflag, cpu_A0, a.def_seg, s->override);
+if (!(s->prefix & PREFIX_LOCK)) {
+gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
+}
 } else {
 gen_op_mov_v_reg(ot, cpu_T0, rm);
 }
 bt_op:
 tcg_gen_andi_tl(cpu_T1, cpu_T1, (1 << (3 + ot)) - 1);
-tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
-switch(op) {
-case 0:
-break;
-case 1:
-tcg_gen_movi_tl(cpu_tmp0, 1);
-tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
-tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
-break;
-case 2:
-tcg_gen_movi_tl(cpu_tmp0, 1);
-tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
-tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
-break;
-default:
-case 3:
-tcg_gen_movi_tl(cpu_tmp0, 1);
-tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
-tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
-break;
-}
-if (op != 0) {
-if (mod != 3) {
-gen_op_st_v(s, ot, cpu_T0, cpu_A0);
-} else {
-gen_op_mov_reg_v(ot, rm, cpu_T0);
+tcg_gen_movi_tl(cpu_tmp0, 1);
+tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T1);
+if (s->prefix & PREFIX_LOCK) {
+switch (op) {
+case 0: /* bt */
+/* Needs no atomic ops; we surpressed the normal
+   memory load for LOCK above so do it now.  */
+gen_op_ld_v(s, ot, cpu_T0, cpu_A0);
+break;
+case 1: /* bts */
+tcg_gen_atomic_fetch_or_tl(cpu_T0, cpu_A0, cpu_tmp0,
+   s->mem_index, ot | MO_LE);
+break;
+case 2: /* btr */
+tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
+tcg_gen_atomic_fetch_and_tl(cpu_T0, cpu_A0, cpu_tmp0,
+s->mem_index, ot | MO_LE);
+break;
+default:
+case 3: /* btc */
+tcg_gen_atomic_fetch_xor_tl(cpu_T0, cpu_A0, cpu_tmp0,
+s->mem_index, ot | MO_LE);
+break;
+}
+tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
+} else {
+tcg_gen_shr_tl(cpu_tmp4, cpu_T0, cpu_T1);
+switch (op) {
+case 0: /* bt */
+/* Data already loaded; nothing to do.  */
+break;
+case 1: /* bts */
+tcg_gen_or_tl(cpu_T0, cpu_T0, cpu_tmp0);
+break;
+case 2: /* btr */
+tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_tmp0);
+break;
+default:
+case 3: /* btc */
+tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_tmp0);
+break;
+}
+if (op != 0) {
+if (mod != 3) {
+gen_op_st_v(s, ot, cpu_T0, cpu_A0);
+} else {
+gen_op_mov_reg_v(ot, rm, cpu_T0);
+}
 }
 }
 
-- 
2.5.5




[Qemu-devel] [PATCH v4 21/35] target-i386: emulate LOCK'ed NEG using cmpxchg helper

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

[rth: Move redundant qemu_load out of cmpxchg loop.]

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-16-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/translate.c | 38 ++
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 49455a3..17a37a3 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4713,11 +4713,41 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 }
 break;
 case 3: /* neg */
-tcg_gen_neg_tl(cpu_T0, cpu_T0);
-if (mod != 3) {
-gen_op_st_v(s, ot, cpu_T0, cpu_A0);
+if (s->prefix & PREFIX_LOCK) {
+TCGLabel *label1;
+TCGv a0, t0, t1, t2;
+
+if (mod == 3) {
+goto illegal_op;
+}
+a0 = tcg_temp_local_new();
+t0 = tcg_temp_local_new();
+label1 = gen_new_label();
+
+tcg_gen_mov_tl(a0, cpu_A0);
+tcg_gen_mov_tl(t0, cpu_T0);
+
+gen_set_label(label1);
+t1 = tcg_temp_new();
+t2 = tcg_temp_new();
+tcg_gen_mov_tl(t2, t0);
+tcg_gen_neg_tl(t1, t0);
+tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
+  s->mem_index, ot | MO_LE);
+tcg_temp_free(t1);
+tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);
+
+tcg_temp_free(t2);
+tcg_temp_free(a0);
+tcg_gen_mov_tl(cpu_T0, t0);
+tcg_temp_free(t0);
 } else {
-gen_op_mov_reg_v(ot, rm, cpu_T0);
+tcg_gen_neg_tl(cpu_T0, cpu_T0);
+if (mod != 3) {
+gen_op_st_v(s, ot, cpu_T0, cpu_A0);
+} else {
+gen_op_mov_reg_v(ot, rm, cpu_T0);
+}
 }
 gen_op_update_neg_cc();
 set_cc_op(s, CC_OP_SUBB + ot);
-- 
2.5.5




[Qemu-devel] [PATCH v4 09/35] cputlb: Move probe_write out of softmmu_template.h

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 cputlb.c   | 21 +
 softmmu_template.h | 23 ---
 2 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 5575b73..0c9b77b 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -527,6 +527,27 @@ static bool victim_tlb_hit(CPUArchState *env, size_t 
mmu_idx, size_t index,
   victim_tlb_hit(env, mmu_idx, index, offsetof(CPUTLBEntry, TY), \
  (ADDR) & TARGET_PAGE_MASK)
 
+/* Probe for whether the specified guest write access is permitted.
+ * If it is not permitted then an exception will be taken in the same
+ * way as if this were a real write access (and we will not return).
+ * Otherwise the function will return, and there will be a valid
+ * entry in the TLB for this access.
+ */
+void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx,
+ uintptr_t retaddr)
+{
+int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
+
+if ((addr & TARGET_PAGE_MASK)
+!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
+/* TLB entry is for a different page */
+if (!VICTIM_TLB_HIT(addr_write, addr)) {
+tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
+}
+}
+}
+
 #define MMUSUFFIX _mmu
 
 #define DATA_SIZE 1
diff --git a/softmmu_template.h b/softmmu_template.h
index f9c51fe..538cff5 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -464,29 +464,6 @@ void helper_be_st_name(CPUArchState *env, target_ulong 
addr, DATA_TYPE val,
 glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
 }
 #endif /* DATA_SIZE > 1 */
-
-#if DATA_SIZE == 1
-/* Probe for whether the specified guest write access is permitted.
- * If it is not permitted then an exception will be taken in the same
- * way as if this were a real write access (and we will not return).
- * Otherwise the function will return, and there will be a valid
- * entry in the TLB for this access.
- */
-void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx,
- uintptr_t retaddr)
-{
-int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
-target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
-
-if ((addr & TARGET_PAGE_MASK)
-!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-/* TLB entry is for a different page */
-if (!VICTIM_TLB_HIT(addr_write, addr)) {
-tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
-}
-}
-}
-#endif
 #endif /* !defined(SOFTMMU_CODE_ACCESS) */
 
 #undef READ_ACCESS_TYPE
-- 
2.5.5




[Qemu-devel] [PATCH v4 11/35] cputlb: Move most of iotlb code out of line

2016-09-16 Thread Richard Henderson
Saves 2k code size off of a cold path.

Signed-off-by: Richard Henderson 
---
 cputlb.c   | 37 +
 softmmu_template.h | 52 ++--
 2 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 0c9b77b..1bee47d 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -498,6 +498,43 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, 
target_ulong addr)
 return qemu_ram_addr_from_host_nofail(p);
 }
 
+static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
+ target_ulong addr, uintptr_t retaddr, int size)
+{
+CPUState *cpu = ENV_GET_CPU(env);
+hwaddr physaddr = iotlbentry->addr;
+MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
+uint64_t val;
+
+physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
+cpu->mem_io_pc = retaddr;
+if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) {
+cpu_io_recompile(cpu, retaddr);
+}
+
+cpu->mem_io_vaddr = addr;
+memory_region_dispatch_read(mr, physaddr, , size, iotlbentry->attrs);
+return val;
+}
+
+static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
+  uint64_t val, target_ulong addr,
+  uintptr_t retaddr, int size)
+{
+CPUState *cpu = ENV_GET_CPU(env);
+hwaddr physaddr = iotlbentry->addr;
+MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
+
+physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
+if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) {
+cpu_io_recompile(cpu, retaddr);
+}
+
+cpu->mem_io_vaddr = addr;
+cpu->mem_io_pc = retaddr;
+memory_region_dispatch_write(mr, physaddr, val, size, iotlbentry->attrs);
+}
+
 /* Return true if ADDR is present in the victim tlb, and has been copied
back to the main tlb.  */
 static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
diff --git a/softmmu_template.h b/softmmu_template.h
index b9532a4..035ffc8 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -112,25 +112,12 @@
 
 #ifndef SOFTMMU_CODE_ACCESS
 static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
-  CPUIOTLBEntry *iotlbentry,
+  size_t mmu_idx, size_t index,
   target_ulong addr,
   uintptr_t retaddr)
 {
-uint64_t val;
-CPUState *cpu = ENV_GET_CPU(env);
-hwaddr physaddr = iotlbentry->addr;
-MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs);
-
-physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
-cpu->mem_io_pc = retaddr;
-if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) {
-cpu_io_recompile(cpu, retaddr);
-}
-
-cpu->mem_io_vaddr = addr;
-memory_region_dispatch_read(mr, physaddr, , DATA_SIZE,
-iotlbentry->attrs);
-return val;
+CPUIOTLBEntry *iotlbentry = >iotlb[mmu_idx][index];
+return io_readx(env, iotlbentry, addr, retaddr, DATA_SIZE);
 }
 #endif
 
@@ -161,15 +148,13 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, 
target_ulong addr,
 
 /* Handle an IO access.  */
 if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
-CPUIOTLBEntry *iotlbentry;
 if ((addr & (DATA_SIZE - 1)) != 0) {
 goto do_unaligned_access;
 }
-iotlbentry = >iotlb[mmu_idx][index];
 
 /* ??? Note that the io helpers always read data in the target
byte ordering.  We should push the LE/BE request down into io.  */
-res = glue(io_read, SUFFIX)(env, iotlbentry, addr, retaddr);
+res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
 res = TGT_LE(res);
 return res;
 }
@@ -230,15 +215,13 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, 
target_ulong addr,
 
 /* Handle an IO access.  */
 if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
-CPUIOTLBEntry *iotlbentry;
 if ((addr & (DATA_SIZE - 1)) != 0) {
 goto do_unaligned_access;
 }
-iotlbentry = >iotlb[mmu_idx][index];
 
 /* ??? Note that the io helpers always read data in the target
byte ordering.  We should push the LE/BE request down into io.  */
-res = glue(io_read, SUFFIX)(env, iotlbentry, addr, retaddr);
+res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
 res = TGT_BE(res);
 return res;
 }
@@ -289,24 +272,13 @@ WORD_TYPE helper_be_lds_name(CPUArchState *env, 
target_ulong addr,
 #endif
 
 static inline void glue(io_write, SUFFIX)(CPUArchState *env,
-  CPUIOTLBEntry *iotlbentry,
+  size_t mmu_idx, size_t index,
   

[Qemu-devel] [PATCH v4 22/35] target-i386: emulate LOCK'ed XADD using atomic helper

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

[rth: Move load of reg value to common location.]

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-17-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/translate.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 17a37a3..049b1e4 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -5135,19 +5135,24 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 modrm = cpu_ldub_code(env, s->pc++);
 reg = ((modrm >> 3) & 7) | rex_r;
 mod = (modrm >> 6) & 3;
+gen_op_mov_v_reg(ot, cpu_T0, reg);
 if (mod == 3) {
 rm = (modrm & 7) | REX_B(s);
-gen_op_mov_v_reg(ot, cpu_T0, reg);
 gen_op_mov_v_reg(ot, cpu_T1, rm);
 tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
 gen_op_mov_reg_v(ot, reg, cpu_T1);
 gen_op_mov_reg_v(ot, rm, cpu_T0);
 } else {
 gen_lea_modrm(env, s, modrm);
-gen_op_mov_v_reg(ot, cpu_T0, reg);
-gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
-tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
-gen_op_st_v(s, ot, cpu_T0, cpu_A0);
+if (s->prefix & PREFIX_LOCK) {
+tcg_gen_atomic_fetch_add_tl(cpu_T1, cpu_A0, cpu_T0,
+s->mem_index, ot | MO_LE);
+tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
+} else {
+gen_op_ld_v(s, ot, cpu_T1, cpu_A0);
+tcg_gen_add_tl(cpu_T0, cpu_T0, cpu_T1);
+gen_op_st_v(s, ot, cpu_T0, cpu_A0);
+}
 gen_op_mov_reg_v(ot, reg, cpu_T1);
 }
 gen_op_update2_cc();
-- 
2.5.5




[Qemu-devel] [PATCH v4 17/35] target-i386: emulate LOCK'ed cmpxchg using cmpxchg helpers

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

The diff here is uglier than necessary. All this does is to turn

FOO

into:

if (s->prefix & PREFIX_LOCK) {
  BAR
} else {
  FOO
}

where FOO is the original implementation of an unlocked cmpxchg.

[rth: Adjust unlocked cmpxchg to use movcond instead of branches.
Adjust helpers to use atomic helpers.]

Signed-off-by: Emilio G. Cota 
Message-Id: <1467054136-10430-6-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 target-i386/helper.h |   2 +
 target-i386/mem_helper.c | 134 +++
 target-i386/translate.c  |  99 ++
 3 files changed, 169 insertions(+), 66 deletions(-)

diff --git a/target-i386/helper.h b/target-i386/helper.h
index 1320edc..729d4b6 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -74,8 +74,10 @@ DEF_HELPER_3(boundw, void, env, tl, int)
 DEF_HELPER_3(boundl, void, env, tl, int)
 DEF_HELPER_1(rsm, void, env)
 DEF_HELPER_2(into, void, env, int)
+DEF_HELPER_2(cmpxchg8b_unlocked, void, env, tl)
 DEF_HELPER_2(cmpxchg8b, void, env, tl)
 #ifdef TARGET_X86_64
+DEF_HELPER_2(cmpxchg16b_unlocked, void, env, tl)
 DEF_HELPER_2(cmpxchg16b, void, env, tl)
 #endif
 DEF_HELPER_1(single_step, void, env)
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 5bc0594..c4b5c5b 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -22,6 +22,8 @@
 #include "exec/helper-proto.h"
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
+#include "qemu/int128.h"
+#include "tcg.h"
 
 /* broken thread support */
 
@@ -56,53 +58,143 @@ void helper_lock_init(void)
 }
 #endif
 
+void helper_cmpxchg8b_unlocked(CPUX86State *env, target_ulong a0)
+{
+uintptr_t ra = GETPC();
+uint64_t oldv, cmpv, newv;
+int eflags;
+
+eflags = cpu_cc_compute_all(env, CC_OP);
+
+cmpv = deposit64(env->regs[R_EAX], 32, 32, env->regs[R_EDX]);
+newv = deposit64(env->regs[R_EBX], 32, 32, env->regs[R_ECX]);
+
+oldv = cpu_ldq_data_ra(env, a0, ra);
+newv = (cmpv == oldv ? newv : oldv);
+/* always do the store */
+cpu_stq_data_ra(env, a0, newv, ra);
+
+if (oldv == cmpv) {
+eflags |= CC_Z;
+} else {
+env->regs[R_EAX] = (uint32_t)oldv;
+env->regs[R_EDX] = (uint32_t)(oldv >> 32);
+eflags &= ~CC_Z;
+}
+CC_SRC = eflags;
+}
+
 void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
 {
-uint64_t d;
+#ifdef CONFIG_ATOMIC64
+uint64_t oldv, cmpv, newv;
 int eflags;
 
 eflags = cpu_cc_compute_all(env, CC_OP);
-d = cpu_ldq_data_ra(env, a0, GETPC());
-if (d == (((uint64_t)env->regs[R_EDX] << 32) | 
(uint32_t)env->regs[R_EAX])) {
-cpu_stq_data_ra(env, a0, ((uint64_t)env->regs[R_ECX] << 32)
-  | (uint32_t)env->regs[R_EBX], GETPC());
+
+cmpv = deposit64(env->regs[R_EAX], 32, 32, env->regs[R_EDX]);
+newv = deposit64(env->regs[R_EBX], 32, 32, env->regs[R_ECX]);
+
+#ifdef CONFIG_USER_ONLY
+{
+uint64_t *haddr = g2h(a0);
+cmpv = cpu_to_le64(cmpv);
+newv = cpu_to_le64(newv);
+oldv = atomic_cmpxchg__nocheck(haddr, cmpv, newv);
+oldv = le64_to_cpu(oldv);
+}
+#else
+{
+uintptr_t ra = GETPC();
+int mem_idx = cpu_mmu_index(env, false);
+TCGMemOpIdx oi = make_memop_idx(MO_TEQ, mem_idx);
+oldv = helper_atomic_cmpxchgq_le_mmu(env, a0, cmpv, newv, oi, ra);
+}
+#endif
+
+if (oldv == cmpv) {
 eflags |= CC_Z;
 } else {
-/* always do the store */
-cpu_stq_data_ra(env, a0, d, GETPC());
-env->regs[R_EDX] = (uint32_t)(d >> 32);
-env->regs[R_EAX] = (uint32_t)d;
+env->regs[R_EAX] = (uint32_t)oldv;
+env->regs[R_EDX] = (uint32_t)(oldv >> 32);
 eflags &= ~CC_Z;
 }
 CC_SRC = eflags;
+#else
+cpu_loop_exit_atomic(ENV_GET_CPU(env), GETPC());
+#endif /* CONFIG_ATOMIC64 */
 }
 
 #ifdef TARGET_X86_64
-void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
+void helper_cmpxchg16b_unlocked(CPUX86State *env, target_ulong a0)
 {
-uint64_t d0, d1;
+uintptr_t ra = GETPC();
+Int128 oldv, cmpv, newv;
+uint64_t o0, o1;
 int eflags;
+bool success;
 
 if ((a0 & 0xf) != 0) {
 raise_exception_ra(env, EXCP0D_GPF, GETPC());
 }
 eflags = cpu_cc_compute_all(env, CC_OP);
-d0 = cpu_ldq_data_ra(env, a0, GETPC());
-d1 = cpu_ldq_data_ra(env, a0 + 8, GETPC());
-if (d0 == env->regs[R_EAX] && d1 == env->regs[R_EDX]) {
-cpu_stq_data_ra(env, a0, env->regs[R_EBX], GETPC());
-cpu_stq_data_ra(env, a0 + 8, env->regs[R_ECX], GETPC());
+
+cmpv = int128_make128(env->regs[R_EAX], env->regs[R_EDX]);
+newv = int128_make128(env->regs[R_EBX], env->regs[R_ECX]);
+
+o0 = cpu_ldq_data_ra(env, a0 + 0, ra);
+o1 = cpu_ldq_data_ra(env, a0 + 8, ra);
+
+oldv = int128_make128(o0, o1);
+success = 

[Qemu-devel] [PATCH v4 10/35] cputlb: Remove includes from softmmu_template.h

2016-09-16 Thread Richard Henderson
We already include exec/address-spaces.h and exec/memory.h in
cputlb.c; the include of qemu/timer.h appears to be a fossil.

Signed-off-by: Richard Henderson 
---
 softmmu_template.h | 4 
 1 file changed, 4 deletions(-)

diff --git a/softmmu_template.h b/softmmu_template.h
index 538cff5..b9532a4 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -21,10 +21,6 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see .
  */
-#include "qemu/timer.h"
-#include "exec/address-spaces.h"
-#include "exec/memory.h"
-
 #if DATA_SIZE == 8
 #define SUFFIX q
 #define LSUFFIX q
-- 
2.5.5




[Qemu-devel] [PATCH v4 07/35] HACK: Always enable parallel_cpus

2016-09-16 Thread Richard Henderson
This is really just a placeholder for an actual
command-line switch for mttcg.
---
 translate-all.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/translate-all.c b/translate-all.c
index 70f3959..c860cfc 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -119,7 +119,7 @@ static void *l1_map[V_L1_SIZE];
 
 /* code generation context */
 TCGContext tcg_ctx;
-bool parallel_cpus;
+bool parallel_cpus = 1;
 
 /* translation block context */
 #ifdef CONFIG_USER_ONLY
-- 
2.5.5




[Qemu-devel] [PATCH v3 2/3] tests: virtio-9p: add basic configuration test

2016-09-16 Thread Greg Kurz
This adds PCI init code and a basic test that checks the device config
matches what is passed on the command line.

Signed-off-by: Greg Kurz 
Acked-by: Cornelia Huck 
---
V2: - s/char* tag/char *tag/ (patchew)
- moved "mount_tag" change from 2/3 to 1/3 (Cornelia)
- added Cornelia's A-b tag
---
 tests/Makefile.include |2 +
 tests/virtio-9p-test.c |   77 
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 03382b5fe7b8..a9dce206fbf6 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -600,7 +600,7 @@ tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o 
$(libqos-virtio-obj-y)
 tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o $(libqos-pc-obj-y) 
$(libqos-virtio-obj-y)
 tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o $(libqos-pc-obj-y)
 tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o 
$(libqos-virtio-obj-y)
-tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o
+tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y)
 tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o
 tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o
 tests/tpci200-test$(EXESUF): tests/tpci200-test.o
diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 45fc8041d7f3..b8fb6cd869a9 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -10,6 +10,13 @@
 #include "qemu/osdep.h"
 #include "libqtest.h"
 #include "qemu-common.h"
+#include "libqos/pci-pc.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+#include "libqos/malloc.h"
+#include "libqos/malloc-pc.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_pci.h"
 
 static const char mount_tag[] = "qtest";
 static char *test_share;
@@ -42,10 +49,80 @@ static void pci_nop(void)
 qvirtio_9p_stop();
 }
 
+typedef struct {
+QVirtioDevice *dev;
+QGuestAllocator *alloc;
+QPCIBus *bus;
+QVirtQueue *vq;
+} QVirtIO9P;
+
+static QVirtIO9P *qvirtio_9p_pci_init(void)
+{
+QVirtIO9P *v9p;
+QVirtioPCIDevice *dev;
+
+v9p = g_new0(QVirtIO9P, 1);
+v9p->alloc = pc_alloc_init();
+v9p->bus = qpci_init_pc();
+
+dev = qvirtio_pci_device_find(v9p->bus, VIRTIO_ID_9P);
+g_assert_nonnull(dev);
+g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_9P);
+v9p->dev = (QVirtioDevice *) dev;
+
+qvirtio_pci_device_enable(dev);
+qvirtio_reset(_pci, v9p->dev);
+qvirtio_set_acknowledge(_pci, v9p->dev);
+qvirtio_set_driver(_pci, v9p->dev);
+
+v9p->vq = qvirtqueue_setup(_pci, v9p->dev, v9p->alloc, 0);
+return v9p;
+}
+
+static void qvirtio_9p_pci_free(QVirtIO9P *v9p)
+{
+qvirtqueue_cleanup(_pci, v9p->vq, v9p->alloc);
+pc_alloc_uninit(v9p->alloc);
+qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev));
+g_free(v9p->dev);
+qpci_free_pc(v9p->bus);
+g_free(v9p);
+}
+
+static void pci_basic_config(void)
+{
+QVirtIO9P *v9p;
+void *addr;
+size_t tag_len;
+char *tag;
+int i;
+
+qvirtio_9p_start();
+v9p = qvirtio_9p_pci_init();
+
+addr = ((QVirtioPCIDevice *) v9p->dev)->addr + 
VIRTIO_PCI_CONFIG_OFF(false);
+tag_len = qvirtio_config_readw(_pci, v9p->dev,
+   (uint64_t)(uintptr_t)addr);
+g_assert_cmpint(tag_len, ==, strlen(mount_tag));
+addr += sizeof(uint16_t);
+
+tag = g_malloc(tag_len);
+for (i = 0; i < tag_len; i++) {
+tag[i] = qvirtio_config_readb(_pci, v9p->dev,
+  (uint64_t)(uintptr_t)addr + i);
+}
+g_assert_cmpmem(tag, tag_len, mount_tag, tag_len);
+g_free(tag);
+
+qvirtio_9p_pci_free(v9p);
+qvirtio_9p_stop();
+}
+
 int main(int argc, char **argv)
 {
 g_test_init(, , NULL);
 qtest_add_func("/virtio/9p/pci/nop", pci_nop);
+qtest_add_func("/virtio/9p/pci/basic/configuration", pci_basic_config);
 
 return g_test_run();
 }




[Qemu-devel] [PATCH v4 13/35] tcg: Add atomic helpers

2016-09-16 Thread Richard Henderson
Add all of cmpxchg, op_fetch, fetch_op, and xchg.
Handle both endian-ness, and sizes up to 8.
Handle expanding non-atomically, when emulating in serial.

Signed-off-by: Richard Henderson 
---
 Makefile.objs |   1 -
 Makefile.target   |   1 +
 atomic_template.h | 173 ++
 cputlb.c  | 112 -
 include/qemu/atomic.h |  19 ++-
 tcg-runtime.c |  49 ++--
 tcg/tcg-op.c  | 328 ++
 tcg/tcg-op.h  |  44 +++
 tcg/tcg-runtime.h |  75 
 tcg/tcg.h |  53 
 10 files changed, 835 insertions(+), 20 deletions(-)
 create mode 100644 atomic_template.h

diff --git a/Makefile.objs b/Makefile.objs
index 7301544..4420e37 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -89,7 +89,6 @@ endif
 
 ###
 # Target-independent parts used in system and user emulation
-common-obj-y += tcg-runtime.o
 common-obj-y += hw/
 common-obj-y += qom/
 common-obj-y += disas/
diff --git a/Makefile.target b/Makefile.target
index 5f2cf85..1d3213c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -94,6 +94,7 @@ obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
 obj-y += fpu/softfloat.o
 obj-y += target-$(TARGET_BASE_ARCH)/
 obj-y += disas.o
+obj-y += tcg-runtime.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 
diff --git a/atomic_template.h b/atomic_template.h
new file mode 100644
index 000..d2c8a08
--- /dev/null
+++ b/atomic_template.h
@@ -0,0 +1,173 @@
+/*
+ * Atomic helper templates
+ * Included from tcg-runtime.c and cputlb.c.
+ *
+ * Copyright (c) 2016 Red Hat, Inc
+ *
+ * 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 .
+ */
+
+#if DATA_SIZE == 8
+# define SUFFIX q
+# define DATA_TYPE  uint64_t
+# define BSWAP  bswap64
+#elif DATA_SIZE == 4
+# define SUFFIX l
+# define DATA_TYPE  uint32_t
+# define BSWAP  bswap32
+#elif DATA_SIZE == 2
+# define SUFFIX w
+# define DATA_TYPE  uint16_t
+# define BSWAP  bswap16
+#elif DATA_SIZE == 1
+# define SUFFIX b
+# define DATA_TYPE  uint8_t
+# define BSWAP
+#else
+# error unsupported data size
+#endif
+
+#if DATA_SIZE >= 4
+# define ABI_TYPE  DATA_TYPE
+#else
+# define ABI_TYPE  uint32_t
+#endif
+
+#if DATA_SIZE == 1
+# define END
+#elif defined(HOST_WORDS_BIGENDIAN)
+# define END  _be
+#else
+# define END  _le
+#endif
+
+ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
+  ABI_TYPE cmpv, ABI_TYPE newv EXTRA_ARGS)
+{
+DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
+return atomic_cmpxchg__nocheck(haddr, cmpv, newv);
+}
+
+ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
+   ABI_TYPE val EXTRA_ARGS)
+{
+DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
+return atomic_xchg__nocheck(haddr, val);
+}
+
+#define GEN_ATOMIC_HELPER(X)\
+ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr,   \
+ ABI_TYPE val EXTRA_ARGS)   \
+{   \
+DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;   \
+return atomic_##X(haddr, val);  \
+}   \
+
+GEN_ATOMIC_HELPER(fetch_add)
+GEN_ATOMIC_HELPER(fetch_and)
+GEN_ATOMIC_HELPER(fetch_or)
+GEN_ATOMIC_HELPER(fetch_xor)
+GEN_ATOMIC_HELPER(add_fetch)
+GEN_ATOMIC_HELPER(and_fetch)
+GEN_ATOMIC_HELPER(or_fetch)
+GEN_ATOMIC_HELPER(xor_fetch)
+
+#undef GEN_ATOMIC_HELPER
+#undef END
+
+#if DATA_SIZE > 1
+
+#ifdef HOST_WORDS_BIGENDIAN
+# define END  _le
+#else
+# define END  _be
+#endif
+
+ABI_TYPE ATOMIC_NAME(cmpxchg)(CPUArchState *env, target_ulong addr,
+  ABI_TYPE cmpv, ABI_TYPE newv EXTRA_ARGS)
+{
+DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
+return BSWAP(atomic_cmpxchg__nocheck(haddr, BSWAP(cmpv), BSWAP(newv)));
+}
+
+ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
+   ABI_TYPE val EXTRA_ARGS)
+{
+DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
+return BSWAP(atomic_xchg__nocheck(haddr, BSWAP(val)));
+}
+
+#define 

[Qemu-devel] [PATCH v4 05/35] int128: Add int128_make128

2016-09-16 Thread Richard Henderson
Allows Int128 to be used more generally, rather than having to
begin with 64-bit inputs and accumulate.

Signed-off-by: Richard Henderson 
---
 include/qemu/int128.h | 20 +++-
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/include/qemu/int128.h b/include/qemu/int128.h
index 08f1db1..67440fa 100644
--- a/include/qemu/int128.h
+++ b/include/qemu/int128.h
@@ -10,6 +10,11 @@ static inline Int128 int128_make64(uint64_t a)
 return a;
 }
 
+static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
+{
+return (unsigned __int128)hi << 64 | lo;
+}
+
 static inline uint64_t int128_get64(Int128 a)
 {
 uint64_t r = a;
@@ -146,6 +151,11 @@ static inline Int128 int128_make64(uint64_t a)
 return (Int128) { a, 0 };
 }
 
+static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
+{
+return (Int128) { lo, hi };
+}
+
 static inline uint64_t int128_get64(Int128 a)
 {
 assert(!a.hi);
@@ -195,9 +205,9 @@ static inline Int128 int128_rshift(Int128 a, int n)
 }
 h = a.hi >> (n & 63);
 if (n >= 64) {
-return (Int128) { h, h >> 63 };
+return int128_make128(h, h >> 63);
 } else {
-return (Int128) { (a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h };
+return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
 }
 }
 
@@ -211,18 +221,18 @@ static inline Int128 int128_add(Int128 a, Int128 b)
  *
  * So the carry is lo < a.lo.
  */
-return (Int128) { lo, (uint64_t)a.hi + b.hi + (lo < a.lo) };
+return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
 }
 
 static inline Int128 int128_neg(Int128 a)
 {
 uint64_t lo = -a.lo;
-return (Int128) { lo, ~(uint64_t)a.hi + !lo };
+return int128_make128(lo, ~(uint64_t)a.hi + !lo);
 }
 
 static inline Int128 int128_sub(Int128 a, Int128 b)
 {
-return (Int128){ a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo) };
+return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
 }
 
 static inline bool int128_nonneg(Int128 a)
-- 
2.5.5




[Qemu-devel] [PATCH v4 01/35] atomics: add atomic_xor

2016-09-16 Thread Richard Henderson
From: "Emilio G. Cota" 

This paves the way for upcoming work.

Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
Message-Id: <1467054136-10430-8-git-send-email-c...@braap.org>
---
 include/qemu/atomic.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 0cce246..0124289 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -193,6 +193,7 @@
 #define atomic_fetch_sub(ptr, n) __atomic_fetch_sub(ptr, n, __ATOMIC_SEQ_CST)
 #define atomic_fetch_and(ptr, n) __atomic_fetch_and(ptr, n, __ATOMIC_SEQ_CST)
 #define atomic_fetch_or(ptr, n)  __atomic_fetch_or(ptr, n, __ATOMIC_SEQ_CST)
+#define atomic_fetch_xor(ptr, n) __atomic_fetch_xor(ptr, n, __ATOMIC_SEQ_CST)
 
 /* And even shorter names that return void.  */
 #define atomic_inc(ptr)((void) __atomic_fetch_add(ptr, 1, 
__ATOMIC_SEQ_CST))
@@ -201,6 +202,7 @@
 #define atomic_sub(ptr, n) ((void) __atomic_fetch_sub(ptr, n, 
__ATOMIC_SEQ_CST))
 #define atomic_and(ptr, n) ((void) __atomic_fetch_and(ptr, n, 
__ATOMIC_SEQ_CST))
 #define atomic_or(ptr, n)  ((void) __atomic_fetch_or(ptr, n, __ATOMIC_SEQ_CST))
+#define atomic_xor(ptr, n) ((void) __atomic_fetch_xor(ptr, n, 
__ATOMIC_SEQ_CST))
 
 #else /* __ATOMIC_RELAXED */
 
@@ -387,6 +389,7 @@
 #define atomic_fetch_sub   __sync_fetch_and_sub
 #define atomic_fetch_and   __sync_fetch_and_and
 #define atomic_fetch_or__sync_fetch_and_or
+#define atomic_fetch_xor   __sync_fetch_and_xor
 #define atomic_cmpxchg __sync_val_compare_and_swap
 
 /* And even shorter names that return void.  */
@@ -396,6 +399,7 @@
 #define atomic_sub(ptr, n) ((void) __sync_fetch_and_sub(ptr, n))
 #define atomic_and(ptr, n) ((void) __sync_fetch_and_and(ptr, n))
 #define atomic_or(ptr, n)  ((void) __sync_fetch_and_or(ptr, n))
+#define atomic_xor(ptr, n) ((void) __sync_fetch_and_xor(ptr, n))
 
 #endif /* __ATOMIC_RELAXED */
 #endif /* QEMU_ATOMIC_H */
-- 
2.5.5




[Qemu-devel] [PATCH v4 03/35] exec: Avoid direct references to Int128 parts

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 exec.c|  4 ++--
 include/qemu/int128.h | 10 ++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index c8389f9..cc2997e 100644
--- a/exec.c
+++ b/exec.c
@@ -320,9 +320,9 @@ static inline bool section_covers_addr(const 
MemoryRegionSection *section,
 /* Memory topology clips a memory region to [0, 2^64); size.hi > 0 means
  * the section must cover the entire address space.
  */
-return section->size.hi ||
+return int128_gethi(section->size) ||
range_covers_byte(section->offset_within_address_space,
- section->size.lo, addr);
+ int128_getlo(section->size), addr);
 }
 
 static MemoryRegionSection *phys_page_find(PhysPageEntry lp, hwaddr addr,
diff --git a/include/qemu/int128.h b/include/qemu/int128.h
index c598881..52aaf99 100644
--- a/include/qemu/int128.h
+++ b/include/qemu/int128.h
@@ -20,6 +20,16 @@ static inline uint64_t int128_get64(Int128 a)
 return a.lo;
 }
 
+static inline uint64_t int128_getlo(Int128 a)
+{
+return a.lo;
+}
+
+static inline int64_t int128_gethi(Int128 a)
+{
+return a.hi;
+}
+
 static inline Int128 int128_zero(void)
 {
 return int128_make64(0);
-- 
2.5.5




[Qemu-devel] [PATCH v4 04/35] int128: Use __int128 if available

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 include/qemu/int128.h | 135 +-
 tests/test-int128.c   |  22 
 2 files changed, 145 insertions(+), 12 deletions(-)

diff --git a/include/qemu/int128.h b/include/qemu/int128.h
index 52aaf99..08f1db1 100644
--- a/include/qemu/int128.h
+++ b/include/qemu/int128.h
@@ -1,6 +1,138 @@
 #ifndef INT128_H
 #define INT128_H
 
+#ifdef CONFIG_INT128
+
+typedef __int128 Int128;
+
+static inline Int128 int128_make64(uint64_t a)
+{
+return a;
+}
+
+static inline uint64_t int128_get64(Int128 a)
+{
+uint64_t r = a;
+assert(r == a);
+return r;
+}
+
+static inline uint64_t int128_getlo(Int128 a)
+{
+return a;
+}
+
+static inline int64_t int128_gethi(Int128 a)
+{
+return a >> 64;
+}
+
+static inline Int128 int128_zero(void)
+{
+return 0;
+}
+
+static inline Int128 int128_one(void)
+{
+return 1;
+}
+
+static inline Int128 int128_2_64(void)
+{
+return (Int128)1 << 64;
+}
+
+static inline Int128 int128_exts64(int64_t a)
+{
+return a;
+}
+
+static inline Int128 int128_and(Int128 a, Int128 b)
+{
+return a & b;
+}
+
+static inline Int128 int128_rshift(Int128 a, int n)
+{
+return a >> n;
+}
+
+static inline Int128 int128_add(Int128 a, Int128 b)
+{
+return a + b;
+}
+
+static inline Int128 int128_neg(Int128 a)
+{
+return -a;
+}
+
+static inline Int128 int128_sub(Int128 a, Int128 b)
+{
+return a - b;
+}
+
+static inline bool int128_nonneg(Int128 a)
+{
+return a >= 0;
+}
+
+static inline bool int128_eq(Int128 a, Int128 b)
+{
+return a == b;
+}
+
+static inline bool int128_ne(Int128 a, Int128 b)
+{
+return a != b;
+}
+
+static inline bool int128_ge(Int128 a, Int128 b)
+{
+return a >= b;
+}
+
+static inline bool int128_lt(Int128 a, Int128 b)
+{
+return a < b;
+}
+
+static inline bool int128_le(Int128 a, Int128 b)
+{
+return a <= b;
+}
+
+static inline bool int128_gt(Int128 a, Int128 b)
+{
+return a > b;
+}
+
+static inline bool int128_nz(Int128 a)
+{
+return a != 0;
+}
+
+static inline Int128 int128_min(Int128 a, Int128 b)
+{
+return a < b ? a : b;
+}
+
+static inline Int128 int128_max(Int128 a, Int128 b)
+{
+return a > b ? a : b;
+}
+
+static inline void int128_addto(Int128 *a, Int128 b)
+{
+*a += b;
+}
+
+static inline void int128_subfrom(Int128 *a, Int128 b)
+{
+*a -= b;
+}
+
+#else /* !CONFIG_INT128 */
 
 typedef struct Int128 Int128;
 
@@ -153,4 +285,5 @@ static inline void int128_subfrom(Int128 *a, Int128 b)
 *a = int128_sub(*a, b);
 }
 
-#endif
+#endif /* CONFIG_INT128 */
+#endif /* INT128_H */
diff --git a/tests/test-int128.c b/tests/test-int128.c
index 4390123..b86a3c7 100644
--- a/tests/test-int128.c
+++ b/tests/test-int128.c
@@ -41,7 +41,7 @@ static Int128 expand(uint32_t x)
 uint64_t l, h;
 l = expand16(x & 65535);
 h = expand16(x >> 16);
-return (Int128) {l, h};
+return (Int128) int128_make128(l, h);
 };
 
 static void test_and(void)
@@ -54,8 +54,8 @@ static void test_and(void)
 Int128 b = expand(tests[j]);
 Int128 r = expand(tests[i] & tests[j]);
 Int128 s = int128_and(a, b);
-g_assert_cmpuint(r.lo, ==, s.lo);
-g_assert_cmpuint(r.hi, ==, s.hi);
+g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
+g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
 }
 }
 }
@@ -70,8 +70,8 @@ static void test_add(void)
 Int128 b = expand(tests[j]);
 Int128 r = expand(tests[i] + tests[j]);
 Int128 s = int128_add(a, b);
-g_assert_cmpuint(r.lo, ==, s.lo);
-g_assert_cmpuint(r.hi, ==, s.hi);
+g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
+g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
 }
 }
 }
@@ -86,8 +86,8 @@ static void test_sub(void)
 Int128 b = expand(tests[j]);
 Int128 r = expand(tests[i] - tests[j]);
 Int128 s = int128_sub(a, b);
-g_assert_cmpuint(r.lo, ==, s.lo);
-g_assert_cmpuint(r.hi, ==, s.hi);
+g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
+g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
 }
 }
 }
@@ -100,8 +100,8 @@ static void test_neg(void)
 Int128 a = expand(tests[i]);
 Int128 r = expand(-tests[i]);
 Int128 s = int128_neg(a);
-g_assert_cmpuint(r.lo, ==, s.lo);
-g_assert_cmpuint(r.hi, ==, s.hi);
+g_assert_cmpuint(int128_getlo(r), ==, int128_getlo(s));
+g_assert_cmpuint(int128_gethi(r), ==, int128_gethi(s));
 }
 }
 
@@ -180,8 +180,8 @@ test_rshift_one(uint32_t x, int n, uint64_t h, uint64_t l)
 {
 Int128 a = expand(x);
 Int128 r = int128_rshift(a, n);
-g_assert_cmpuint(r.lo, ==, l);
-g_assert_cmpuint(r.hi, ==, h);
+g_assert_cmpuint(int128_getlo(r), ==, l);
+

[Qemu-devel] [PATCH v4 08/35] cputlb: Replace SHIFT with DATA_SIZE

2016-09-16 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 cputlb.c   | 16 
 softmmu_template.h |  7 ++-
 2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/cputlb.c b/cputlb.c
index 3c99c34..5575b73 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -529,16 +529,16 @@ static bool victim_tlb_hit(CPUArchState *env, size_t 
mmu_idx, size_t index,
 
 #define MMUSUFFIX _mmu
 
-#define SHIFT 0
+#define DATA_SIZE 1
 #include "softmmu_template.h"
 
-#define SHIFT 1
+#define DATA_SIZE 2
 #include "softmmu_template.h"
 
-#define SHIFT 2
+#define DATA_SIZE 4
 #include "softmmu_template.h"
 
-#define SHIFT 3
+#define DATA_SIZE 8
 #include "softmmu_template.h"
 #undef MMUSUFFIX
 
@@ -547,14 +547,14 @@ static bool victim_tlb_hit(CPUArchState *env, size_t 
mmu_idx, size_t index,
 #define GETPC() ((uintptr_t)0)
 #define SOFTMMU_CODE_ACCESS
 
-#define SHIFT 0
+#define DATA_SIZE 1
 #include "softmmu_template.h"
 
-#define SHIFT 1
+#define DATA_SIZE 2
 #include "softmmu_template.h"
 
-#define SHIFT 2
+#define DATA_SIZE 4
 #include "softmmu_template.h"
 
-#define SHIFT 3
+#define DATA_SIZE 8
 #include "softmmu_template.h"
diff --git a/softmmu_template.h b/softmmu_template.h
index 27ed269..f9c51fe 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -25,8 +25,6 @@
 #include "exec/address-spaces.h"
 #include "exec/memory.h"
 
-#define DATA_SIZE (1 << SHIFT)
-
 #if DATA_SIZE == 8
 #define SUFFIX q
 #define LSUFFIX q
@@ -134,7 +132,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState 
*env,
 }
 
 cpu->mem_io_vaddr = addr;
-memory_region_dispatch_read(mr, physaddr, , 1 << SHIFT,
+memory_region_dispatch_read(mr, physaddr, , DATA_SIZE,
 iotlbentry->attrs);
 return val;
 }
@@ -311,7 +309,7 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
 
 cpu->mem_io_vaddr = addr;
 cpu->mem_io_pc = retaddr;
-memory_region_dispatch_write(mr, physaddr, val, 1 << SHIFT,
+memory_region_dispatch_write(mr, physaddr, val, DATA_SIZE,
  iotlbentry->attrs);
 }
 
@@ -492,7 +490,6 @@ void probe_write(CPUArchState *env, target_ulong addr, int 
mmu_idx,
 #endif /* !defined(SOFTMMU_CODE_ACCESS) */
 
 #undef READ_ACCESS_TYPE
-#undef SHIFT
 #undef DATA_TYPE
 #undef SUFFIX
 #undef LSUFFIX
-- 
2.5.5




[Qemu-devel] [PATCH v4 00/35] cmpxchg-based emulation of atomics

2016-09-16 Thread Richard Henderson
Rebased on top of Paolo's safe-work series, which means
that we now have cpu_exec_step_atomic for system mode as
well as linux-user.  This should fix the problems with
atomic access to notdirty pages that have been reported.

Folded in some feedback from Alex from v3.

A complete tree may be found at

  git://github.com/rth7680/qemu.git atomic-4


r~


Emilio G. Cota (18):
  atomics: add atomic_xor
  atomics: add atomic_op_fetch variants
  target-i386: emulate LOCK'ed cmpxchg using cmpxchg helpers
  target-i386: emulate LOCK'ed OP instructions using atomic helpers
  target-i386: emulate LOCK'ed INC using atomic helper
  target-i386: emulate LOCK'ed NOT using atomic helper
  target-i386: emulate LOCK'ed NEG using cmpxchg helper
  target-i386: emulate LOCK'ed XADD using atomic helper
  target-i386: emulate LOCK'ed BTX ops using atomic helpers
  target-i386: emulate XCHG using atomic helper
  target-i386: remove helper_lock()
  tests: add atomic_add-bench
  target-arm: emulate LL/SC using cmpxchg helpers
  target-arm: emulate SWP with atomic_xchg helper
  target-arm: emulate aarch64's LL/SC using cmpxchg helpers
  linux-user: remove handling of ARM's EXCP_STREX
  linux-user: remove handling of aarch64's EXCP_STREX
  target-arm: remove EXCP_STREX + cpu_exclusive_{test, info}

Richard Henderson (17):
  exec: Avoid direct references to Int128 parts
  int128: Use __int128 if available
  int128: Add int128_make128
  tcg: Add EXCP_ATOMIC
  HACK: Always enable parallel_cpus
  cputlb: Replace SHIFT with DATA_SIZE
  cputlb: Move probe_write out of softmmu_template.h
  cputlb: Remove includes from softmmu_template.h
  cputlb: Move most of iotlb code out of line
  cputlb: Tidy some macros
  tcg: Add atomic helpers
  tcg: Add atomic128 helpers
  tcg: Add CONFIG_ATOMIC64
  tcg: Emit barriers with parallel_cpus
  target-arm: Rearrange aa32 load and store functions
  target-alpha: Introduce MMU_PHYS_IDX
  target-alpha: Emulate LL/SC using cmpxchg helpers

 Makefile.objs  |   1 -
 Makefile.target|   1 +
 atomic_template.h  | 211 +
 configure  |  62 +++-
 cpu-exec-common.c  |   6 +
 cpu-exec.c |  30 
 cpus.c |   2 +
 cputlb.c   | 203 ++--
 exec.c |   4 +-
 include/exec/cpu-all.h |   1 +
 include/exec/exec-all.h|   1 +
 include/qemu-common.h  |   1 +
 include/qemu/atomic.h  |  40 -
 include/qemu/int128.h  | 171 +++-
 linux-user/main.c  | 312 ++--
 softmmu_template.h | 104 ++--
 target-alpha/cpu.h |  22 +--
 target-alpha/helper.c  |  14 +-
 target-alpha/helper.h  |   9 --
 target-alpha/machine.c |   2 -
 target-alpha/mem_helper.c  |  73 -
 target-alpha/translate.c   | 148 +
 target-arm/cpu.h   |  17 +-
 target-arm/helper-a64.c| 113 +
 target-arm/helper-a64.h|   2 +
 target-arm/internals.h |   4 +-
 target-arm/translate-a64.c | 106 ++---
 target-arm/translate.c | 342 ++-
 target-arm/translate.h |   4 -
 target-i386/helper.h   |   4 +-
 target-i386/mem_helper.c   | 153 --
 target-i386/translate.c| 386 +
 tcg-runtime.c  |  74 +++--
 tcg/tcg-op.c   | 354 +++--
 tcg/tcg-op.h   |  44 ++
 tcg/tcg-runtime.h  | 109 +
 tcg/tcg.h  |  85 ++
 tests/.gitignore   |   1 +
 tests/Makefile.include |   4 +-
 tests/atomic_add-bench.c   | 181 +
 tests/test-int128.c|  22 +--
 translate-all.c|   1 +
 42 files changed, 2336 insertions(+), 1088 deletions(-)
 create mode 100644 atomic_template.h
 create mode 100644 tests/atomic_add-bench.c

-- 
2.5.5




[Qemu-devel] [PATCH v3 1/3] tests: virtio-9p: introduce start/stop functions

2016-09-16 Thread Greg Kurz
First step to be able to run several functional steps.

Signed-off-by: Greg Kurz 
Acked-by: Cornelia Huck 
---
v2: - moved "mount_tag" change from 2/3 to 1/3 (Cornelia)
- added Cornelia's A-b tag
---
 tests/virtio-9p-test.c |   42 +-
 1 file changed, 25 insertions(+), 17 deletions(-)

diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 1e39335a7945..45fc8041d7f3 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -11,33 +11,41 @@
 #include "libqtest.h"
 #include "qemu-common.h"
 
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
-{
-}
+static const char mount_tag[] = "qtest";
+static char *test_share;
 
-static char test_share[] = "/tmp/qtest.XX";
-
-int main(int argc, char **argv)
+static void qvirtio_9p_start(void)
 {
 char *args;
-int ret;
 
-g_test_init(, , NULL);
-qtest_add_func("/virtio/9p/pci/nop", pci_nop);
-
-g_assert(mkdtemp(test_share));
+test_share = g_strdup("/tmp/qtest.XX");
+g_assert_nonnull(mkdtemp(test_share));
 
 args = g_strdup_printf("-fsdev local,id=fsdev0,security_model=none,path=%s 
"
-   "-device 
virtio-9p-pci,fsdev=fsdev0,mount_tag=qtest",
-   test_share);
+   "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s",
+   test_share, mount_tag);
+
 qtest_start(args);
 g_free(args);
+}
 
-ret = g_test_run();
-
+static void qvirtio_9p_stop(void)
+{
 qtest_end();
 rmdir(test_share);
+g_free(test_share);
+}
+
+static void pci_nop(void)
+{
+qvirtio_9p_start();
+qvirtio_9p_stop();
+}
+
+int main(int argc, char **argv)
+{
+g_test_init(, , NULL);
+qtest_add_func("/virtio/9p/pci/nop", pci_nop);
 
-return ret;
+return g_test_run();
 }




[Qemu-devel] [PATCH v3 0/3] tests: more test cases for virtio-9p

2016-09-16 Thread Greg Kurz
This series brings some basic functional testing to 9P (only the virtio
part actually).

As with other virtio-* qtests, PC platform is assumed.

This v3 fixes the endianness issue in patch 3/3.

---

Greg Kurz (3):
  tests: virtio-9p: introduce start/stop functions
  tests: virtio-9p: add basic configuration test
  tests: virtio-9p: add basic transaction test


 tests/Makefile.include |2 -
 tests/virtio-9p-test.c |  182 
 2 files changed, 167 insertions(+), 17 deletions(-)

--
Greg




[Qemu-devel] [PATCH v3 3/3] tests: virtio-9p: add basic transaction test

2016-09-16 Thread Greg Kurz
This adds a simple test to validate the device is functional: it transmits
a request with type Terror, which is not used by the 9P protocol [1], and
expects QEMU to return a reply with type Rerror and the "Operation not
supported" error string.

[1] http://lxr.free-electrons.com/source/include/net/9p/9p.h#L121

Signed-off-by: Greg Kurz 
Acked-by: Cornelia Huck 
---
v3: - the 9P protocol uses little-endian ordering
---
---
 tests/virtio-9p-test.c |   65 
 1 file changed, 65 insertions(+)

diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index b8fb6cd869a9..95cba3fd3e8e 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -8,6 +8,7 @@
  */
 
 #include "qemu/osdep.h"
+#include 
 #include "libqtest.h"
 #include "qemu-common.h"
 #include "libqos/pci-pc.h"
@@ -17,6 +18,9 @@
 #include "libqos/malloc-pc.h"
 #include "standard-headers/linux/virtio_ids.h"
 #include "standard-headers/linux/virtio_pci.h"
+#include "hw/9pfs/9p.h"
+
+#define QVIRTIO_9P_TIMEOUT_US (1 * 1000 * 1000)
 
 static const char mount_tag[] = "qtest";
 static char *test_share;
@@ -118,11 +122,72 @@ static void pci_basic_config(void)
 qvirtio_9p_stop();
 }
 
+typedef struct VirtIO9PHdr {
+uint32_t size;
+uint8_t id;
+uint16_t tag;
+} QEMU_PACKED VirtIO9PHdr;
+
+typedef struct VirtIO9PMsgRError {
+uint16_t error_len;
+char error[0];
+} QEMU_PACKED VirtIO9PMsgRError;
+
+#define P9_MAX_SIZE 8192
+
+static void pci_basic_transaction(void)
+{
+QVirtIO9P *v9p;
+VirtIO9PHdr hdr;
+VirtIO9PMsgRError *resp;
+uint64_t req_addr, resp_addr;
+uint32_t free_head;
+char *expected_error = strerror(ENOTSUP);
+
+qvirtio_9p_start();
+v9p = qvirtio_9p_pci_init();
+
+hdr.size = cpu_to_le32(sizeof(hdr));
+hdr.id = P9_TERROR;
+hdr.tag = cpu_to_le16(12345);
+
+req_addr = guest_alloc(v9p->alloc, hdr.size);
+memwrite(req_addr, , sizeof(hdr));
+free_head = qvirtqueue_add(v9p->vq, req_addr, hdr.size, false, true);
+
+resp_addr = guest_alloc(v9p->alloc, P9_MAX_SIZE);
+qvirtqueue_add(v9p->vq, resp_addr, P9_MAX_SIZE, true, false);
+
+qvirtqueue_kick(_pci, v9p->dev, v9p->vq, free_head);
+guest_free(v9p->alloc, req_addr);
+qvirtio_wait_queue_isr(_pci, v9p->dev, v9p->vq,
+   QVIRTIO_9P_TIMEOUT_US);
+
+memread(resp_addr, , sizeof(hdr));
+le32_to_cpus();
+le16_to_cpus();
+g_assert_cmpint(hdr.size, <, (uint32_t) P9_MAX_SIZE);
+g_assert_cmpint(hdr.id, ==, (uint8_t) P9_RERROR);
+g_assert_cmpint(hdr.tag, ==, (uint16_t) 12345);
+
+resp = g_malloc(hdr.size);
+memread(resp_addr + sizeof(hdr), resp, hdr.size - sizeof(hdr));
+guest_free(v9p->alloc, resp_addr);
+le16_to_cpus(>error_len);
+g_assert_cmpmem(resp->error, resp->error_len, expected_error,
+strlen(expected_error));
+g_free(resp);
+
+qvirtio_9p_pci_free(v9p);
+qvirtio_9p_stop();
+}
+
 int main(int argc, char **argv)
 {
 g_test_init(, , NULL);
 qtest_add_func("/virtio/9p/pci/nop", pci_nop);
 qtest_add_func("/virtio/9p/pci/basic/configuration", pci_basic_config);
+qtest_add_func("/virtio/9p/pci/basic/transaction", pci_basic_transaction);
 
 return g_test_run();
 }




[Qemu-devel] [PATCH 1/3] target-arm: Infrastucture changes to enable handling of tagged address loading into PC

2016-09-16 Thread Thomas Hanson
New arm_regime_tbi0() and arm_regime_tbi0() to extract the TBI values from
the correct TCR for the current EL.

New shift, mask and accessor macro definitions needed to add TBI flag bits
to the TB flags field.

cpu_get_tb_cpu_state() inserst the TBI values into 'flags' parameter
so that they show up in the TB flags field.

tbi0, tbi1 fields added to definition of DisasContext structure.

Signed-off-by: Thomas Hanson 
---
 target-arm/cpu.h   | 20 ++--
 target-arm/helper.c| 42 ++
 target-arm/translate.h |  3 +++
 3 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 76d824d..c2d6e75 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -2191,7 +2191,11 @@ static inline bool 
arm_cpu_data_is_big_endian(CPUARMState *env)
 #define ARM_TBFLAG_BE_DATA_SHIFT20
 #define ARM_TBFLAG_BE_DATA_MASK (1 << ARM_TBFLAG_BE_DATA_SHIFT)
 
-/* Bit usage when in AArch64 state: currently we have no A64 specific bits */
+/* Bit usage when in AArch64 state */
+#define ARM_TBFLAG_TBI0_SHIFT 0/* TBI0 for EL0/1 or TBI for EL2/3 */
+#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
+#define ARM_TBFLAG_TBI1_SHIFT 1/* TBI1 for EL0/1  */
+#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_AARCH64_STATE(F) \
@@ -,6 +2226,10 @@ static inline bool 
arm_cpu_data_is_big_endian(CPUARMState *env)
 (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
 #define ARM_TBFLAG_BE_DATA(F) \
 (((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT)
+#define ARM_TBFLAG_TBI0(F) \
+(((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
+#define ARM_TBFLAG_TBI1(F) \
+(((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
 
 static inline bool bswap_code(bool sctlr_b)
 {
@@ -2319,12 +2327,19 @@ static inline bool arm_cpu_bswap_data(CPUARMState *env)
 }
 #endif
 
+long arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx);
+long arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx);
+
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
 target_ulong *cs_base, uint32_t *flags)
 {
+ARMMMUIdx mmu_idx = cpu_mmu_index(env, false);
 if (is_a64(env)) {
 *pc = env->pc;
 *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
+/* Get control bits for tagged addresses */
+*flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
+*flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
 } else {
 *pc = env->regs[15];
 *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
@@ -2343,7 +2358,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, 
target_ulong *pc,
<< ARM_TBFLAG_XSCALE_CPAR_SHIFT);
 }
 
-*flags |= (cpu_mmu_index(env, false) << ARM_TBFLAG_MMUIDX_SHIFT);
+*flags |= (mmu_idx << ARM_TBFLAG_MMUIDX_SHIFT);
+
 /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
  * states defined in the ARM ARM for software singlestep:
  *  SS_ACTIVE   PSTATE.SS   State
diff --git a/target-arm/helper.c b/target-arm/helper.c
index bdb842c..526306e 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -6720,6 +6720,48 @@ static inline TCR *regime_tcr(CPUARMState *env, 
ARMMMUIdx mmu_idx)
 return >cp15.tcr_el[regime_el(env, mmu_idx)];
 }
 
+/* Returns TBI0 value for current regime el */
+long arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+TCR*tcr;
+uint32_t el;
+
+/* regime_el fails for mmu_idx = ARMMMUIdx_S12NSE0 or ARMMMUIdx_S12NSE1 */
+if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
+mmu_idx += ARMMMUIdx_S1NSE0;
+}
+
+tcr = regime_tcr(env, mmu_idx);
+el = regime_el(env, mmu_idx);
+
+if (el > 1) {
+return extract64(tcr->raw_tcr, 20, 1);
+} else {
+return extract64(tcr->raw_tcr, 37, 1);
+}
+}
+
+/* Returns TBI0 value for current regime el */
+long arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
+{
+TCR*tcr;
+uint32_t el;
+
+/* regime_el fails for mmu_idx = ARMMMUIdx_S12NSE0 or ARMMMUIdx_S12NSE1 */
+if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
+mmu_idx += ARMMMUIdx_S1NSE0;
+}
+
+tcr = regime_tcr(env, mmu_idx);
+el = regime_el(env, mmu_idx);
+
+if (el > 1) {
+return 0;
+} else {
+return extract64(tcr->raw_tcr, 38, 1);
+}
+}
+
 /* Return the TTBR associated with this translation regime */
 static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
int ttbrn)
diff --git a/target-arm/translate.h b/target-arm/translate.h
index dbd7ac8..5dfd394 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -22,6 +22,8 @@ typedef struct DisasContext {
 int user;
 

[Qemu-devel] [PULL 0/8] 9p patches for 2.8 20160916

2016-09-16 Thread Greg Kurz
The following changes since commit 5f473241ac595452ae0638dc63e7af2a2294f5ec:

  Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging 
(2016-09-15 18:12:40 +0100)

are available in the git repository at:

  https://github.com/gkurz/qemu.git tags/for-upstream

for you to fetch changes up to 5c574f1bf92cfaf4aae6cbb66b79066c654920e1:

  9pfs: fix potential segfault during walk (2016-09-16 12:16:29 +0200)


This pull request contains:
- a fix for a regression introduced in 2.7
- basic functional testing for virtio-9p
- some code cleanups for 9pfs


Greg Kurz (8):
  9pfs: drop unused fmt strings in the proxy backend
  9pfs: drop duplicate line in proxy backend
  9pfs: drop useless v9fs_string_null() function
  9pfs: introduce v9fs_path_sprintf() helper
  tests: virtio-9p: introduce start/stop functions
  tests: virtio-9p: add basic configuration test
  tests: virtio-9p: add basic transaction test
  9pfs: fix potential segfault during walk

 fsdev/9p-marshal.c |   5 --
 fsdev/9p-marshal.h |   1 -
 hw/9pfs/9p-local.c |   7 +-
 hw/9pfs/9p-proxy.c |  75 +
 hw/9pfs/9p.c   |  32 ++---
 hw/9pfs/9p.h   |   1 +
 tests/Makefile.include |   2 +-
 tests/virtio-9p-test.c | 179 -
 8 files changed, 222 insertions(+), 80 deletions(-)
-- 
2.5.5




Re: [Qemu-devel] [PATCH v3 09/10] ppc/pnv: add a LPC controller

2016-09-16 Thread Cédric Le Goater
On 09/16/2016 12:13 AM, Benjamin Herrenschmidt wrote:
> On Thu, 2016-09-15 at 14:45 +0200, Cédric Le Goater wrote:
>> This version of the LPC controller model doesn't yet implement
>> support for the SerIRQ deserializer present in the Naples version
>> of the chip though some preliminary work is there.
> 
> The version in my branch has this support btw.

Yes. there is some of it in patch 10 : 

+if (pcc->chip_type == PNV_CHIP_POWER8NVL) {
+irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler, lpc, 16);
+} else {
+irqs = qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, NULL, 16);
+}

but these are empty shell for the moment as I need PSI, and so XICS 
native, to go forward. Working on it.

Cheers,

C.



[Qemu-devel] [PATCH 0/3] tareget-arm: Handle tagged addresses when loading PC

2016-09-16 Thread Thomas Hanson
If tagged addresses are enabled, then addresses being loaded into the 
PC must be cleaned up by overwriting the tag bits with either all 0's 
or all 1's as specified in the ARM ARM spec.  The decision process is 
dependent on whether the code will be running in EL0/1 or in EL2/3 and 
is controlled by a combination of Top Byte Ignored (TBI) bits in the 
TCR and the value of bit 55 in the address being loaded. 

TBI values are extracted from the appropriate TCR and made available 
to TCG code generation routines by inserting them into the TB flags 
field and then transferring them to DisasContext structure in 
gen_intermediate_code_a64().

New function gen_a64_set_pc_reg() encapsulates the logic required to 
determine whether clean up of the tag byte is required and then 
generating the code to correctly load the PC.
  
In addition to those instruction which can directly load a tagged 
address into the PC, there are others which increment or add a value to
the PC.  If 56 bit addressing is used, these instructions can cause an 
arithmetic roll-over into the tag bits.  The ARM ARM specification for 
handling tagged addresses requires that these cases also be addressed
by cleaning up the tag field.  This work has been deferred because 
there is currently no CPU model available for testing with 56 bit 
addresses.


Thomas Hanson (3):
  target-arm: Infrastucture changes to enable handling of tagged address
loading into PC
  target-arm: Code changes to implement overwrite of tag field on PC
load
  target-arm: Comments to mark location of pending work for 56 bit
addresses

 target-arm/cpu.h   | 20 +--
 target-arm/helper.c| 42 +++
 target-arm/translate-a64.c | 85 +-
 target-arm/translate.h |  3 ++
 4 files changed, 140 insertions(+), 10 deletions(-)

-- 
1.9.1




Re: [Qemu-devel] [PULL 0/8] 9p patches for 2.8 20160916

2016-09-16 Thread Greg Kurz
On Fri, 16 Sep 2016 15:46:26 +0100
Peter Maydell  wrote:

> On 16 September 2016 at 15:39, Greg Kurz  wrote:
> > Ok, I'll look into it... but the important part in this pull request is
> > the "9pfs: fix potential segfault during walk" patch. It fixes a regression
> > introduced in 2.7 by the 9P security fixes. And IIUC, Michael Roth is about
> > to release 2.6.1.1 with these fixes and the regression...
> >
> > Should I send a new pull request without the qtest patches ? Or with the
> > regression fix only ?  
> 
> That's up to you, as long as you don't break "make check".
> You probably want to investigate at least enough to be happy that
> this problem is a bug in the test code, not the feature itself.
> 

It is the test code actually: 9P uses little-endian ordering :)

I'll post an updated version which doesn't break "make check" on both
BE and LE hosts, and re-send a pull request.

Cheers.

--
Greg

> thanks
> -- PMM



[Qemu-devel] [PATCH 2/3] target-arm: Code changes to implement overwrite of tag field on PC load

2016-09-16 Thread Thomas Hanson
gen_intermediate_code_a64() transfers TBI values from TB->flags to
DisasContext structure.

disas_uncond_b_reg() calls new function gen_a64_set_pc_reg() to handle BR,
BLR and RET instructions.

gen_a64_set_pc_reg() implements all of the required checks and overwiting
logic to clean up the tag field of an address before loading the PC.
Currently only called in one place, but will be used in the future to
handle arithmetic overflow cases with 56-bit addresses.  (See following
patch.)

Signed-off-by: Thomas Hanson 
---
 target-arm/translate-a64.c | 67 ++
 1 file changed, 62 insertions(+), 5 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f5e29d2..4d6f951 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -41,6 +41,7 @@ static TCGv_i64 cpu_pc;
 
 /* Load/store exclusive handling */
 static TCGv_i64 cpu_exclusive_high;
+static TCGv_i64 cpu_reg(DisasContext *s, int reg);
 
 static const char *regnames[] = {
 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
@@ -176,6 +177,58 @@ void gen_a64_set_pc_im(uint64_t val)
 tcg_gen_movi_i64(cpu_pc, val);
 }
 
+void gen_a64_set_pc_reg(DisasContext *s, unsigned int rn)
+{
+if (s->current_el <= 1) {
+/* Test if NEITHER or BOTH TBI values are set.  If so, no need to
+ * examine bit 55 of address, can just generate code.
+ * If mixed, then test via generated code
+ */
+if (s->tbi0 && s->tbi1) {
+TCGv_i64 tmp_reg = tcg_temp_new_i64();
+/* Both bits set, just fix it */
+tcg_gen_shli_i64(tmp_reg, cpu_reg(s, rn), 8);
+tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
+tcg_temp_free_i64(tmp_reg);
+} else if (!s->tbi0 && !s->tbi1) {
+/* Neither bit set, just load it as-is */
+tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
+} else {
+TCGv_i64 tcg_tmpval = tcg_temp_new_i64();
+TCGv_i64 tcg_bit55  = tcg_temp_new_i64();
+TCGv_i64 tcg_zero   = tcg_const_i64(0);
+
+tcg_gen_andi_i64(tcg_bit55, cpu_reg(s, rn), (1ull << 55));
+
+if (s->tbi0) {
+/* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
+tcg_gen_andi_i64(tcg_tmpval, cpu_reg(s, rn),
+ 0x00FFull);
+tcg_gen_movcond_i64(TCG_COND_EQ, cpu_pc, tcg_bit55, tcg_zero,
+tcg_tmpval, cpu_reg(s, rn));
+} else {
+/* tbi0==0, tbi1==1, so 1-fill upper byte if bit 55 = 1 */
+tcg_gen_ori_i64(tcg_tmpval, cpu_reg(s, rn),
+0xFF00ull);
+tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc, tcg_bit55, tcg_zero,
+tcg_tmpval, cpu_reg(s, rn));
+}
+tcg_temp_free_i64(tcg_zero);
+tcg_temp_free_i64(tcg_bit55);
+tcg_temp_free_i64(tcg_tmpval);
+}
+} else {  /* EL > 1 */
+if (s->tbi0) {
+/* Force tag byte to all zero */
+tcg_gen_andi_i64(cpu_pc, cpu_reg(s, rn), 0x00FFull);
+} else {
+/* Load unmodified address */
+tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
+}
+ }
+
+}
+
 typedef struct DisasCompare64 {
 TCGCond cond;
 TCGv_i64 value;
@@ -1691,12 +1744,14 @@ static void disas_uncond_b_reg(DisasContext *s, 
uint32_t insn)
 
 switch (opc) {
 case 0: /* BR */
-case 2: /* RET */
-tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
-break;
 case 1: /* BLR */
-tcg_gen_mov_i64(cpu_pc, cpu_reg(s, rn));
-tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
+case 2: /* RET */
+/* Check for tagged addresses and generate appropriate code */
+gen_a64_set_pc_reg(s, rn);
+/* BLR also needs to load return address */
+if (opc == 1) {
+tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
+}
 break;
 case 4: /* ERET */
 if (s->current_el == 0) {
@@ -11150,6 +11205,8 @@ void gen_intermediate_code_a64(ARMCPU *cpu, 
TranslationBlock *tb)
 dc->condexec_mask = 0;
 dc->condexec_cond = 0;
 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
+dc->tbi0 = ARM_TBFLAG_TBI0(tb->flags);
+dc->tbi1 = ARM_TBFLAG_TBI1(tb->flags);
 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
 #if !defined(CONFIG_USER_ONLY)
 dc->user = (dc->current_el == 0);
-- 
1.9.1




[Qemu-devel] [PATCH 3/3] target-arm: Comments to mark location of pending work for 56 bit addresses

2016-09-16 Thread Thomas Hanson
Certain instructions which can not directly load a tagged address value
may trigger a corner case when the address size is 56 bits.  This is
because incrementing or offsetting from the current PC can cause an
arithetic roll-over into the tag bits.  Per the ARM ARM spec, these cases
should also be addressed by cleaning up the tag field.

This work was not done at this time since the changes could not be tested
with current CPU models.  Comments have been added to flag the locations
where this will need to be fixed once a model is available.

3 comments added in same file to identify cases in a switch.

Signed-off-by: Thomas Hanson 
---
 target-arm/translate-a64.c | 18 +++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 4d6f951..8810180 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1205,6 +1205,9 @@ static inline AArch64DecodeFn *lookup_disas_fn(const 
AArch64DecodeTable *table,
  */
 static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
 {
+/*If/when address size is 56 bits, this could overflow into address tag
+ * byte, and that byte should be fixed per ARM ARM spec.
+ */
 uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
 
 if (insn & (1U << 31)) {
@@ -1232,6 +1235,9 @@ static void disas_comp_b_imm(DisasContext *s, uint32_t 
insn)
 sf = extract32(insn, 31, 1);
 op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
 rt = extract32(insn, 0, 5);
+/*If/when address size is 56 bits, this could overflow into address tag
+ * byte, and that byte should be fixed per ARM ARM spec.
+ */
 addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
 
 tcg_cmp = read_cpu_reg(s, rt, sf);
@@ -1260,6 +1266,9 @@ static void disas_test_b_imm(DisasContext *s, uint32_t 
insn)
 
 bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
 op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
+/*If/when address size is 56 bits, this could overflow into address tag
+ * byte, and that byte should be fixed per ARM ARM spec.
+ */
 addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
 rt = extract32(insn, 0, 5);
 
@@ -1289,6 +1298,9 @@ static void disas_cond_b_imm(DisasContext *s, uint32_t 
insn)
 unallocated_encoding(s);
 return;
 }
+/*If/when address size is 56 bits, this could overflow into address tag
+ * byte, and that byte should be fixed per ARM ARM spec.
+ */
 addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
 cond = extract32(insn, 0, 4);
 
@@ -1636,12 +1648,12 @@ static void disas_exc(DisasContext *s, uint32_t insn)
  * instruction works properly.
  */
 switch (op2_ll) {
-case 1:
+case 1: /* SVC */
 gen_ss_advance(s);
 gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16),
default_exception_el(s));
 break;
-case 2:
+case 2: /* HVC */
 if (s->current_el == 0) {
 unallocated_encoding(s);
 break;
@@ -1654,7 +1666,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
 gen_ss_advance(s);
 gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
 break;
-case 3:
+case 3: /* SMC */
 if (s->current_el == 0) {
 unallocated_encoding(s);
 break;
-- 
1.9.1




Re: [Qemu-devel] [PATCH 1/2] linux-user-i386: fix crash on cpuid

2016-09-16 Thread Eduardo Habkost
On Fri, Sep 16, 2016 at 07:50:23PM +0400, Marc-André Lureau wrote:
> Running cpuid instructions with a simple run like:
> i386-linux-user/qemu-i386 tests/tcg/sha1-i386
> 
> Results in the following assert:
>  #0  0x764246f5 in raise () from /lib64/libc.so.6
>  #1  0x764262fa in abort () from /lib64/libc.so.6
>  #2  0x77937ec5 in g_assertion_message () from /lib64/libglib-2.0.so.0
>  #3  0x77937f5a in g_assertion_message_expr () from 
> /lib64/libglib-2.0.so.0
>  #4  0x5561b54c in apicid_bitwidth_for_count (count=0) at 
> /home/elmarco/src/qemu/include/hw/i386/topology.h:58
>  #5  0x5561b58a in apicid_smt_width (nr_cores=0, nr_threads=0) at 
> /home/elmarco/src/qemu/include/hw/i386/topology.h:67
>  #6  0x5561b5c3 in apicid_core_offset (nr_cores=0, nr_threads=0) at 
> /home/elmarco/src/qemu/include/hw/i386/topology.h:82
>  #7  0x5561b5e3 in apicid_pkg_offset (nr_cores=0, nr_threads=0) at 
> /home/elmarco/src/qemu/include/hw/i386/topology.h:89
>  #8  0x5561dd86 in cpu_x86_cpuid (env=0x57999550, index=4, 
> count=3, eax=0x7fffcae8, ebx=0x7fffcaec, ecx=0x7fffcaf0, 
> edx=0x7fffcaf4) at /home/elmarco/src/qemu/target-i386/cpu.c:2405
>  #9  0x55638e8e in helper_cpuid (env=0x57999550) at 
> /home/elmarco/src/qemu/target-i386/misc_helper.c:106
>  #10 0x5599dc5e in static_code_gen_buffer ()
>  #11 0x555952f8 in cpu_tb_exec (cpu=0x579912d0, 
> itb=0x74371ab0) at /home/elmarco/src/qemu/cpu-exec.c:166
>  #12 0x55595c8e in cpu_loop_exec_tb (cpu=0x579912d0, 
> tb=0x74371ab0, last_tb=0x7fffd088, tb_exit=0x7fffd084, 
> sc=0x7fffd0a0) at /home/elmarco/src/qemu/cpu-exec.c:517
>  #13 0x55595e50 in cpu_exec (cpu=0x579912d0) at 
> /home/elmarco/src/qemu/cpu-exec.c:612
>  #14 0x555c065b in cpu_loop (env=0x57999550) at 
> /home/elmarco/src/qemu/linux-user/main.c:297
>  #15 0x555c25b2 in main (argc=2, argv=0x7fffd848, 
> envp=0x7fffd860) at /home/elmarco/src/qemu/linux-user/main.c:4803
> 
> The fields are set in qemu_init_vcpu() with softmmu, but it's a stub
> with linux-user.
> 
> Signed-off-by: Marc-André Lureau 

Reviewed-by: Eduardo Habkost 

Applied to x86-next. Thanks.

-- 
Eduardo



Re: [Qemu-devel] [PATCH] hmp: Improve 'info mtree' with optional parm for mapinfo

2016-09-16 Thread Laszlo Ersek
On 09/15/16 11:52, Paolo Bonzini wrote:
> 
> 
> On 07/09/2016 02:48, Thorsten Kohfeldt wrote:
>> From: Thorsten Kohfeldt 
>> Date: Wed, 31 Aug 2016 22:43:14 +0200
>> Subject: [PATCH] hmp: Improve 'info mtree' with optional parm for mapinfo
>>
>> Motivation
>> When 'tuning' 'quirks' for VFIO imported devices, it is not easy to
>> directly grasp the implications of the priorisation algorithms in place
>> for the 'layered mapping' of memory regions.
>> Even though there are rules (documented in docs/memory.txt), once in a
>> while one might question the correctness of the actual implementation of
>> the rules.
>> Particularly, I believe I have uncovered a divergence of (sub-)region
>> priorisation/order/visibility in a corner case of importing a device
>> (which requires a 'quirk') with mmap enabled vs. mmap disabled.
>> This modification provides a means of visualising the ACTUAL
>> mapping/visibility/occlusion of subregions within regions, whereas the
>> current info mtree command only lists the tree of regions (all, visible
>> and invisible ones).
>> It is primarily intended to provide support for easy presentation of my
>> cause, but I strongly believe this modification also has general purpose
>> advantages.
> 
> It is a useful addition, but I think a simpler presentation is also
> fine.  What about "info mtree -f" which would visit the FlatView instead
> of the tree?  The patch would probably be much shorter.

I'm very interested in this feature (as a mere user at this point).
Thorsten, can you please CC me on your next version, and also include an
example command response in either the Notes section of the patch, or in
a separate 0/1 blurb?

Thanks
Laszlo




Re: [Qemu-devel] [PATCH] virtio: add check for descriptor's mapped address

2016-09-16 Thread Laszlo Ersek
CC Stefan

On 09/15/16 13:34, P J P wrote:
> From: Prasad J Pandit 
> 
> virtio back end uses set of buffers to facilitate I/O operations.
> If its size is too large, 'cpu_physical_memory_map' could return
> a null address. This would result in a null dereference
> while un-mapping descriptors. Add check to avoid it.
> 
> Reported-by: Qinghao Tang 
> Signed-off-by: Prasad J Pandit 
> ---
>  hw/virtio/virtio.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 15ee3a7..0a4c5b6 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -472,12 +472,14 @@ static void virtqueue_map_desc(unsigned int *p_num_sg, 
> hwaddr *addr, struct iove
>  }
>  
>  iov[num_sg].iov_base = cpu_physical_memory_map(pa, , is_write);
> -iov[num_sg].iov_len = len;
> -addr[num_sg] = pa;
> +if (iov[num_sg].iov_base) {
> +iov[num_sg].iov_len = len;
> +addr[num_sg] = pa;
>  
> +pa += len;
> +num_sg++;
> +}
>  sz -= len;
> -pa += len;
> -num_sg++;
>  }
>  *p_num_sg = num_sg;
>  }
> 

I think the situation you describe is a guest bug. Just above the code
that you modify, there's already

if (!sz) {
error_report("virtio: zero sized buffers are not allowed");
exit(1);
}

I think it would be reasonable to handle this other guest bug similarly:

if (iov[num_sg].iov_base == NULL) {
error_report("virtio: bogus descriptor or out of resources");
exit(EXIT_FAILURE);
}

The main message is of course "bogus descriptor". OTOH,
cpu_physical_memory_map() / address_space_map() can return NULL for
multiple reasons, not all of which seem guest errors: the loop in
virtqueue_map_desc() handles the case when cpu_physical_memory_map()
cannot map the entire area requested by the descriptor in a single go,
and then mapping (part) of the remaining area might fail due to resource
exhaustion in QEMU (see "resources needed to perform the mapping are
exhausted" on address_space_map()).

So maybe those error returns from address_space_map() should be
disentangled first. (Although, the only difference they'd make at this
point would be in the error message when we bail out anyway.)

So, unless Stefan or someone else has a better idea, I suggest the above
error message, and exit(EXIT_FAILURE). Silently skipping a part (or all
remaining parts) of the area requested by the descriptor is unlikely to
produce predictable results for the guest (and the user).

Thanks
Laszlo



[Qemu-devel] [PULL 4/8] 9pfs: introduce v9fs_path_sprintf() helper

2016-09-16 Thread Greg Kurz
This helper is similar to v9fs_string_sprintf(), but it includes the
terminating NUL character in the size field.

This is to avoid doing v9fs_string_sprintf((V9fsString *) ) and
then bumping the size.

Affected users are changed to use this new helper.

Signed-off-by: Greg Kurz 
Reviewed-by: Cédric Le Goater 
---
 hw/9pfs/9p-local.c |  7 ++-
 hw/9pfs/9p-proxy.c |  7 ++-
 hw/9pfs/9p.c   | 19 ---
 hw/9pfs/9p.h   |  1 +
 4 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 3f271fcbd2c5..845675e7a1bb 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1060,13 +1060,10 @@ static int local_name_to_path(FsContext *ctx, V9fsPath 
*dir_path,
   const char *name, V9fsPath *target)
 {
 if (dir_path) {
-v9fs_string_sprintf((V9fsString *)target, "%s/%s",
-dir_path->data, name);
+v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
 } else {
-v9fs_string_sprintf((V9fsString *)target, "%s", name);
+v9fs_path_sprintf(target, "%s", name);
 }
-/* Bump the size for including terminating NULL */
-target->size++;
 return 0;
 }
 
diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index d091564b6fd2..f2417b7fd73d 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -1023,13 +1023,10 @@ static int proxy_name_to_path(FsContext *ctx, V9fsPath 
*dir_path,
   const char *name, V9fsPath *target)
 {
 if (dir_path) {
-v9fs_string_sprintf((V9fsString *)target, "%s/%s",
-dir_path->data, name);
+v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
 } else {
-v9fs_string_sprintf((V9fsString *)target, "%s", name);
+v9fs_path_sprintf(target, "%s", name);
 }
-/* Bump the size for including terminating NULL */
-target->size++;
 return 0;
 }
 
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index d8f48ca76c47..639f93930285 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -12,6 +12,7 @@
  */
 
 #include "qemu/osdep.h"
+#include 
 #include "hw/virtio/virtio.h"
 #include "qapi/error.h"
 #include "qemu/error-report.h"
@@ -179,6 +180,20 @@ void v9fs_path_free(V9fsPath *path)
 path->size = 0;
 }
 
+
+void GCC_FMT_ATTR(2, 3)
+v9fs_path_sprintf(V9fsPath *path, const char *fmt, ...)
+{
+va_list ap;
+
+v9fs_path_free(path);
+
+va_start(ap, fmt);
+/* Bump the size for including terminating NULL */
+path->size = g_vasprintf(>data, fmt, ap) + 1;
+va_end(ap);
+}
+
 void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs)
 {
 v9fs_path_free(lhs);
@@ -917,10 +932,8 @@ static void v9fs_fix_path(V9fsPath *dst, V9fsPath *src, 
int len)
 V9fsPath str;
 v9fs_path_init();
 v9fs_path_copy(, dst);
-v9fs_string_sprintf((V9fsString *)dst, "%s%s", src->data, str.data+len);
+v9fs_path_sprintf(dst, "%s%s", src->data, str.data + len);
 v9fs_path_free();
-/* +1 to include terminating NULL */
-dst->size++;
 }
 
 static inline bool is_ro_export(FsContext *ctx)
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index a38603398ef5..d539d2ebe9c0 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -327,6 +327,7 @@ static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu)
 extern void v9fs_reclaim_fd(V9fsPDU *pdu);
 extern void v9fs_path_init(V9fsPath *path);
 extern void v9fs_path_free(V9fsPath *path);
+extern void v9fs_path_sprintf(V9fsPath *path, const char *fmt, ...);
 extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs);
 extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath,
  const char *name, V9fsPath *path);
-- 
2.5.5




Re: [Qemu-devel] [PATCH] RFC: linux-user-i386: crash on cpuid

2016-09-16 Thread Eduardo Habkost
On Fri, Sep 16, 2016 at 11:06:34AM -0400, Marc-André Lureau wrote:
> Hi
> 
> - Original Message -
> > >  
> > > -#ifndef CONFIG_USER_ONLY
> > > +#ifdef CONFIG_USER_ONLY
> > > +cs->nr_cores = smp_cores;
> > > +cs->nr_threads = smp_threads;
> > > +#else
> > 
> > On CONFIG_USER_ONLY, smp_cores and smp_threads are defined as:
> > 
> >   /* *-user doesn't have configurable SMP topology */
> >   #define smp_cores   1
> >   #define smp_threads 1
> > 
> > It sounds simpler to just set nr_cores and nr_threads to 1 by
> > default in cpu_common_initfn(). (Preferably with a comment noting
> > that the default value is changed by qemu_init_vcpu() for
> > softmmu).
> 
> Any reason those define exists? It seems we could use cpu state values 
> instead, ex:

Just because there was existing non-softmmu-specific code that
used those variables. If we eliminate their usage (are the ones
below the only cases?), we can remove the macros.

> 
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -2490,13 +2490,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>  
>  switch (count) {
>  case 0:
> -*eax = apicid_core_offset(smp_cores, smp_threads);
> -*ebx = smp_threads;
> +*eax = apicid_core_offset(cs->nr_cores, cs->nr_threads);
> +*ebx = cs->nr_threads;
>  *ecx |= CPUID_TOPOLOGY_LEVEL_SMT;
>  break;
>  case 1:
> -*eax = apicid_pkg_offset(smp_cores, smp_threads);
> -*ebx = smp_cores * smp_threads;
> +*eax = apicid_pkg_offset(cs->nr_cores, cs->nr_threads);
> +*ebx = cs->nr_cores * cs->nr_threads;
>  *ecx |= CPUID_TOPOLOGY_LEVEL_CORE;
>  break;
> 

-- 
Eduardo



Re: [Qemu-devel] [PATCH RFC] docs: add PCIe devices placement guidelines

2016-09-16 Thread Andrea Bolognani
On Thu, 2016-09-15 at 17:20 +0300, Marcel Apfelbaum wrote:
> > Just catching up on mail after vacation and read this thread. Thanks
> > Marcel for writing this document (I guess a v1 is coming soon).
> 
> Yes, I am sorry but I got caught up with other stuff and I am
> going to be in PTO for a week, so V1 will take a little more time
> than I planned.

I finally caught up as well, and while I don't have much
value to contribute to the conversation, let me say this:
everything about this thread is absolutely awesome!

The amount of information one can absorb from the discussion
alone is amazing, but the guidelines contained in the
document we're crafting will certainly prove to be invaluable
to users and people working higher up in the stack alike.

Thanks Marcel and everyone involved. You guys rock! :)

-- 
Andrea Bolognani / Red Hat / Virtualization



Re: [Qemu-devel] [PATCH 2/2] target-mips: reimplement SC instruction and use cmpxchg

2016-09-16 Thread Richard Henderson

On 09/15/2016 01:44 AM, Leon Alrae wrote:

 /* Store conditional */
+static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
+int size)
 {
+TCGv addr, t0, val;
+TCGLabel *l1 = gen_new_label();
+TCGLabel *l2 = gen_new_label();
+TCGLabel *done = gen_new_label();

-#ifdef CONFIG_USER_ONLY
 t0 = tcg_temp_local_new();
+addr = tcg_temp_local_new();
+/* check the alignment of the address */
+gen_base_offset_addr(ctx, addr, base, offset);
+tcg_gen_andi_tl(t0, addr, size - 1);


You shouldn't have to test the alignment here, as the alignment should have 
been tested during the load-locked, and the (aligned) address will be compared.




+/* compare the address against that of the preceeding LL */
+tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l2);
+tcg_gen_movi_tl(t0, 0);
+tcg_gen_br(done);

...

+#ifdef TARGET_MIPS64
+case 8: /* SCD */
+tcg_gen_atomic_cmpxchg_i64(t0, addr, cpu_llval, val,
+   ctx->mem_idx, MO_TEQ);
 break;
 #endif
-case OPC_SC:
-case R6_OPC_SC:
-op_st_sc(t1, t0, rt, ctx);
+case 4: /* SC */
+{
+TCGv_i32 val32 = tcg_temp_new_i32();
+TCGv_i32 llval32 = tcg_temp_new_i32();
+TCGv_i32 old32 = tcg_temp_new_i32();
+tcg_gen_trunc_tl_i32(val32, val);
+tcg_gen_trunc_tl_i32(llval32, cpu_llval);
+
+tcg_gen_atomic_cmpxchg_i32(old32, addr, llval32, val32,
+   ctx->mem_idx, MO_TESL);
+tcg_gen_ext_i32_tl(t0, old32);


You can use tcg_gen_atomic_cmpxchg_tl so that you do not need to do all of this 
truncation yourself.  Which means that if you replace the size parameter with a 
TCGMemOp parameter (MO_TEQ vs MO_TESL) you can make all this code common.


Further, local temporaries are less than ideal and should be avoided if 
possible.  Using them results in an extra store into the local stack frame.


We can avoid this for addr by noting that once you have compared addr to 
cpu_lladdr, you can free addr and use cpu_lladdr in the actual cmpxchg.



r~



  1   2   3   >