Aurelien Jarno writes:
> On 2015-08-03 10:14, Alex Bennée wrote:
>> This doesn't just dump CPU state on translation but on every block
>> entrance.
>>
>> Signed-off-by: Alex Bennée
>> Reviewed-by: Andreas Färber
>>
>> ---
>> v4
&g
Richard Henderson writes:
> On 08/03/2015 02:14 AM, Alex Bennée wrote:
>> Each individual architecture needs to use the qemu_log_in_addr_range()
>> feature for enabling in_asm and marking blocks for op/opt_op output.
>>
>> Signed-off-by: Alex Bennée
>> ---
&
Richard Henderson writes:
> On 08/04/2015 08:15 AM, Peter Maydell wrote:
>> On 4 August 2015 at 16:11, Alex Bennée wrote:
>>> Aurelien Jarno writes:
>>>> On 2015-08-03 10:14, Alex Bennée wrote:
>>>> In practice this is not true for linked TB. Should
Richard Henderson writes:
> On 08/04/2015 10:22 AM, Alex Bennée wrote:
>>
>> Richard Henderson writes:
>>
>>> On 08/04/2015 08:15 AM, Peter Maydell wrote:
>>>> On 4 August 2015 at 16:11, Alex Bennée wrote:
>>>>> Aurelien Jar
o options for the talk.
Finally it was agreed with KVM Forum only 2 weeks away to have the next
conference on Monday.
--
Alex Bennée
e make target and test for now until they can be
added in a working manner?
>
> thanks
> -- PMM
--
Alex Bennée
Victor Kaplansky writes:
> In rules like "bar/%.o: %.c" there is a difference between $(*D) and
> $(@D). It is cleaner to generate *.d next to appropriate *.o, because it
> allows precise including of dependency info from .d files.
It might be worth putting the example in the comment as most pe
if the call is just ignored.
If so the argument would be to leave the abort() in and just add the
missing semihosting calls.
> }
> }
--
Alex Bennée
Michael S. Tsirkin writes:
> On Thu, Aug 06, 2015 at 09:57:03AM +0100, Alex Bennée wrote:
>>
>> Victor Kaplansky writes:
>>
>> >
>> > As a hack, we also touch two sources for generated *.hex files. This is
>> > to ensure *.hex rebui
ly mechanical though.
However in the spirit of keeping trees building in the meantime should
we change this from a configure option to just a static option for each
given backend as it is converted?
--
Alex Bennée
Aurelien Jarno writes:
> On 2015-08-09 09:11, Alex Bennée wrote:
>>
>> Aurelien Jarno writes:
>>
>> > On 2015-08-07 19:03, Alvise Rigo wrote:
>> >> Introduce the new --enable-tcg-ldst-excl configure option to enable the
>> >> LL/S
Aurelien Jarno writes:
> On 2015-08-09 10:51, Alex Bennée wrote:
>>
>> Aurelien Jarno writes:
>>
>> > On 2015-08-09 09:11, Alex Bennée wrote:
>> >>
>> >> Aurelien Jarno writes:
>> >>
>> >> > On 2015-
I've missed anything out then please reply and mention it.
--
Alex Bennée
Christopher Covington writes:
> Hi Alex,
>
> On 08/03/2015 05:14 AM, Alex Bennée wrote:
>> When debugging big programs or system emulation sometimes you want both
>> the verbosity of cpu,exec et all but don't want to generate lots of logs
>> for unneeded stu
nslationBlock *tb1, *tb2;
>> +unsigned int n1;
>> /* remove the TB from the hash list */
>> h = tb_jmp_cache_hash_func(tb->pc);
>> CPU_FOREACH(cpu) {
>> @@ -1023,6 +1071,15 @@ void tb_phys_invalidate(TranslationBlock *tb,
>> tb_page_addr_t page_addr)
>> tb1 = tb2;
>> }
>> tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */
>> +#else
>> +CPU_FOREACH(cpu) {
>> +params = g_malloc(sizeof(struct CPUDiscardTBParams));
>> +params->cpu = cpu;
>> +params->tb = tb;
>> +async_run_on_cpu(cpu, cpu_discard_tb_from_jmp_cache, params);
>> +}
>> +async_run_safe_work_on_cpu(first_cpu, tb_invalidate_jmp_remove, tb);
>> +#endif /* MTTCG */
>>
>> tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
>> tb_unlock();
>>
--
Alex Bennée
d on v2.4.0-rc0 (6169b60285fe1ff730d840a49527e721bfb30899).
>
> Changes V5 -> V6:
> * Introduce async_safe_work to do the tb_flush and some part of
> tb_invalidate.
> * Introduce QemuSpin from Guillaume which allow a faster atomic instruction
> (6s to pass Alexander
and
>> tb_gen_code (which calls cpu_gen_code) take the lock. How does it work?
>>
>
> ... ah, the lock is recursive!
>
> I think this can be avoided. Let's look at it next week.
I take it your around on the Tuesday (Fred and I arrive Monday evening).
Shall we pick a time or hunt for each other in the hacking room?
>
> Paolo
--
Alex Bennée
Paolo Bonzini writes:
> On 10/08/2015 17:27, fred.kon...@greensocs.com wrote:
>> From: Alex Bennée
>>
>> Testing with Alexander's bare metal syncronisation tests fails in MTTCG
>> leaving one CPU spinning forever waiting for the second CPU to wake up.
>>
revent it from getting in ? That way
> you can "remotely" invalidate its TLB...
>
>> == Atomic instruction ==
>>
>> For now only ARM on x64 is supported by using an cmpxchg instruction.
>> Specifically the limitation of this approach is that it is harder to
Benjamin Herrenschmidt writes:
> On Tue, 2015-08-11 at 08:54 +0100, Alex Bennée wrote:
>>
>> > How do you handle the memory model ? IE , ARM and PPC are OO while x86
>> > is (mostly) in order, so emulating ARM/PPC on x86 is fine but emulating
>> > x86 on ARM
_broadcast(&qemu_io_proceeded_cond);
>> -}
>> -iothread_locked = true;
>
> "iothread_locked = true" must be kept. Otherwise... yay! :)
>
Also if qemu_cond_broadcast(&qemu_io_proceeded_cond) is being dropped
there is no point keeping the guff around in qemu_tcg_wait_io_event.
--
Alex Bennée
ush
> when required and crashes!
> Fixing that allows me to boot with jessie and virt.
\o/
Do you see crashes while it is running?
It's interesting that I've not had a problem booting jessie with virt
though - just crashes while hanging.
Are you likely to push a v8 this week (or a temp branch?) with this and
any other obvious fixes? I appreciate Paolo has given you a not-so-small
pile of review comments as well so I wasn't looking for a complete new
patch set!
>
> Fred
--
Alex Bennée
ay. However you can
tell bisect which parts of the tree you car about:
git bisect start -- arch/arm64/kvm include/linux/kvm* include/uapi/linux/kvm*
virt/kvm/
>
> Thanks,
> Peter
--
Alex Bennée
Michael Tokarev writes:
> 29.05.2015 19:29, Paolo Bonzini wrote:
>> On 29/05/2015 16:14, Alex Bennée wrote:
>>> You mean just do:
>>>
>>> diff --git a/configure b/configure
>>> index b707429..f13831a 100755
>>> --- a/configure
It makes sense that extra-cflags should be appended after the normal
CFLAGS so they don't get overridden by default behaviour. This way if
you specify something like:
./configure --extra-cflags="-O0"
You will see the requested behaviour.
Signed-off-by: Alex Bennée
---
conf
Paolo Bonzini writes:
> On 02/06/2015 10:01, Alex Bennée wrote:
>>
>> Michael Tokarev writes:
>>
>>> 29.05.2015 19:29, Paolo Bonzini wrote:
>>>> On 29/05/2015 16:14, Alex Bennée wrote:
>>>>> You mean just do:
>>>>>
>
The help text says --extra-ldflags is appended to LDFLAGS so make it so.
Signed-off-by: Alex Bennée
---
configure | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure b/configure
index d1b7b1c..cfccdfa 100755
--- a/configure
+++ b/configure
@@ -356,7 +356,7 @@ for opt
Michael Tokarev writes:
> Applied to -trivial, thanks!
>
> The other nearby case, --extra-ldflags, also wants this reordering :)
sent
One day I'll find a use for such a thing but fortunately my default build
environment has everything I need ;-)
>
> /mjt
--
Alex Bennée
CHECK which wasn't used.
Signed-off-by: Alex Bennée
---
cputlb.c | 47 ---
1 file changed, 28 insertions(+), 19 deletions(-)
diff --git a/cputlb.c b/cputlb.c
index 7606548..ddb7b59 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -30,8 +30,23 @@
#inc
et_mem_index(s));
> -tcg_temp_free_i32(tmp2);
> -tcg_gen_concat_i32_i64(val64, tmp, tmp3);
> -tcg_temp_free_i32(tmp3);
> -} else {
> -tcg_gen_extu_i32_i64(val64, tmp);
> -}
> -tcg_temp_free_i32(tmp);
> -
> -tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
> -tcg_temp_free_i64(val64);
> +TCGv_i32 tmp2;
> +TCGv_i64 val = tcg_temp_new_i64();
> +TCGv_i32 tmp_size = tcg_const_i32(size);
>
> tmp = load_reg(s, rt);
> -switch (size) {
> -case 0:
> -gen_aa32_st8(tmp, addr, get_mem_index(s));
> -break;
> -case 1:
> -gen_aa32_st16(tmp, addr, get_mem_index(s));
> -break;
> -case 2:
> -case 3:
> -gen_aa32_st32(tmp, addr, get_mem_index(s));
> -break;
> -default:
> -abort();
> -}
> +tmp2 = load_reg(s, rt2);
> +tcg_gen_concat_i32_i64(val, tmp, tmp2);
> tcg_temp_free_i32(tmp);
> -if (size == 3) {
> -tcg_gen_addi_i32(addr, addr, 4);
> -tmp = load_reg(s, rt2);
> -gen_aa32_st32(tmp, addr, get_mem_index(s));
> -tcg_temp_free_i32(tmp);
> -}
> -tcg_gen_movi_i32(cpu_R[rd], 0);
> -tcg_gen_br(done_label);
> -gen_set_label(fail_label);
> -tcg_gen_movi_i32(cpu_R[rd], 1);
> -gen_set_label(done_label);
> -tcg_gen_movi_i64(cpu_exclusive_addr, -1);
> +tcg_temp_free_i32(tmp2);
> +
> +gen_helper_atomic_cmpxchg64(cpu_R[rd], cpu_env, addr, val, tmp_size);
> +tcg_temp_free_i64(val);
> +tcg_temp_free_i32(tmp_size);
> }
> #endif
--
Alex Bennée
Alex Bennée writes:
> fred.kon...@greensocs.com writes:
>
>> From: KONRAD Frederic
>>
>> This mechanism replaces the existing load/store exclusive mechanism which
>> seems
>> to be broken for multithread.
>> It follows the intention of the existing m
2u(tmp3, tmp2, get_mem_index(s));
> -tcg_temp_free_i32(tmp2);
> -tcg_gen_concat_i32_i64(val64, tmp, tmp3);
> -tcg_temp_free_i32(tmp3);
> -} else {
> -tcg_gen_extu_i32_i64(val64, tmp);
> -}
> -tcg_temp_free_i32(tmp);
> -
> -tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
> -tcg_temp_free_i64(val64);
> +TCGv_i32 tmp2;
> +TCGv_i64 val = tcg_temp_new_i64();
> +TCGv_i32 tmp_size = tcg_const_i32(size);
>
> tmp = load_reg(s, rt);
> -switch (size) {
> -case 0:
> -gen_aa32_st8(tmp, addr, get_mem_index(s));
> -break;
> -case 1:
> -gen_aa32_st16(tmp, addr, get_mem_index(s));
> -break;
> -case 2:
> -case 3:
> -gen_aa32_st32(tmp, addr, get_mem_index(s));
> -break;
> -default:
> -abort();
> -}
> +tmp2 = load_reg(s, rt2);
> +tcg_gen_concat_i32_i64(val, tmp, tmp2);
> tcg_temp_free_i32(tmp);
> -if (size == 3) {
> -tcg_gen_addi_i32(addr, addr, 4);
> -tmp = load_reg(s, rt2);
> -gen_aa32_st32(tmp, addr, get_mem_index(s));
> -tcg_temp_free_i32(tmp);
> -}
> -tcg_gen_movi_i32(cpu_R[rd], 0);
> -tcg_gen_br(done_label);
> -gen_set_label(fail_label);
> -tcg_gen_movi_i32(cpu_R[rd], 1);
> -gen_set_label(done_label);
> -tcg_gen_movi_i64(cpu_exclusive_addr, -1);
> +tcg_temp_free_i32(tmp2);
> +
> +gen_helper_atomic_cmpxchg64(cpu_R[rd], cpu_env, addr, val, tmp_size);
> +tcg_temp_free_i64(val);
> +tcg_temp_free_i32(tmp_size);
> }
> #endif
--
Alex Bennée
Mark Burton writes:
>> On 9 Jun 2015, at 15:55, Alex Bennée wrote:
>>
>>
>> Alex Bennée writes:
>>
>>> fred.kon...@greensocs.com writes:
>>>
>>>> From: KONRAD Frederic
>>>>
>>>> This mechanism replaces
This isn't used by any of the code. In fact it looks like it was never
used as it came in with ARMv7 support.
Signed-off-by: Alex Bennée
---
target-arm/cpu.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 21b5b8e..7c1d95c 100644
--- a/targe
Richard Henderson writes:
> On 09/10/2015 11:55 AM, Alex Bennée wrote:
>> I've only had a quick glance so far but I'm fairly familiar with the
>> concept from a previous life. I'll aim to do a full review later once
>> I've gotten through my MTTCG review
pu "cortex-a57", got the error "kvm_init_vcpu failed:
> Invalid argument"
> when using cpu "host", got the error "Failed to retrieve host CPU features!"
>
> By the way, all the command line works well under "tcg" mode.
> Anyone has a quick idea? Thanks in advance.
>
> Best,
> Liang
--
Alex Bennée
liang yan writes:
> On 09/16/2015 08:34 AM, Alex Bennée wrote:
>> liang yan writes:
>>
>>> Hello, All,
>>>
>>> I am trying to enable kvm for a guest vm on an APM X-Gene Host with
>>> latest qemu, but could not make it work.
>>>
&g
\
> CPU_COMMON_TLB \
> +AIEEntry *aie_entry;\
> +bool aie_locked; \
> +bool aie_lock_enabled; \
> +bool aie_llsc_st_tracking; \
>
> #endif
> diff --git a/include/qemu/aie-helper.h b/include/qemu/aie-helper.h
> new file mode 100644
> index 000..86a786a
> --- /dev/null
> +++ b/include/qemu/aie-helper.h
> @@ -0,0 +1,6 @@
> +DEF_HELPER_2(aie_ld_pre, void, env, tl)
> +DEF_HELPER_2(aie_st_pre, void, env, tl)
> +DEF_HELPER_2(aie_st_post, void, env, tl)
> +
> +DEF_HELPER_2(aie_ld_lock, void, env, tl)
> +DEF_HELPER_1(aie_unlock__done, void, env)
--
Alex Bennée
gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
> -tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index,
> MO_LEQ);
> +gen_i386_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
> gen_helper_fpop(cpu_env);
> break;
> default:
> @@ -7754,8 +7804,7 @@ static target_ulong disas_insn(CPUX86State *env,
> DisasContext *s,
> goto illegal_op;
> gen_lea_modrm(env, s, modrm);
> if (op == 2) {
> -tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -s->mem_index, MO_LEUL);
> +gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0, s->mem_index,
> MO_LEUL);
> gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
> } else {
> tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
> mxcsr));
> @@ -7763,9 +7812,12 @@ static target_ulong disas_insn(CPUX86State *env,
> DisasContext *s,
> }
> break;
> case 5: /* lfence */
> +tcg_gen_fence_load();
> +break;
> case 6: /* mfence */
> if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
> goto illegal_op;
> +tcg_gen_fence_full();
> break;
> case 7: /* sfence / clflush */
> if ((modrm & 0xc7) == 0xc0) {
> @@ -7773,6 +7825,7 @@ static target_ulong disas_insn(CPUX86State *env,
> DisasContext *s,
> /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX
> */
> if (!(s->cpuid_features & CPUID_SSE))
> goto illegal_op;
> +tcg_gen_fence_store();
> } else {
> /* clflush */
> if (!(s->cpuid_features & CPUID_CLFLUSH))
> @@ -7841,11 +7894,11 @@ static target_ulong disas_insn(CPUX86State *env,
> DisasContext *s,
> }
> /* lock generation */
> if (s->prefix & PREFIX_LOCK)
> -gen_helper_unlock();
> +gen_helper_lock_disable(cpu_env);
> return s->pc;
> illegal_op:
> if (s->prefix & PREFIX_LOCK)
> -gen_helper_unlock();
> +gen_helper_lock_disable(cpu_env);
> /* XXX: ensure that no lock was generated */
> gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
> return s->pc;
> @@ -7899,8 +7952,6 @@ void optimize_flags_init(void)
> offsetof(CPUX86State, regs[i]),
> reg_names[i]);
> }
> -
> -helper_lock_init();
> }
>
> /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
--
Alex Bennée
mios *termp, struct winsize *winp)
> {
> +#if defined(CONFIG_ANDROID)
> +char pty_buf[PATH_MAX];
> +#define ptsname(fd) pty_buf
> +#endif
Indentation not consistent with the rest of the function.
> const char *slave;
> int mfd = -1, sfd = -1;
>
> @@ -67,17 +72,20 @@ static int openpty(int *amaster, int *aslave, char *name,
>
> if (grantpt(mfd) == -1 || unlockpt(mfd) == -1)
> goto err;
> -
> +#if defined(CONFIG_ANDROID)
> +ptsname_r(mfd, pty_buf, PATH_MAX);
> +#endif
Should we be checking for errors here?
> if ((slave = ptsname(mfd)) == NULL)
> goto err;
>
> if ((sfd = open(slave, O_RDONLY | O_NOCTTY)) == -1)
> goto err;
>
> +#ifndef CONFIG_ANDROID
> if (ioctl(sfd, I_PUSH, "ptem") == -1 ||
> (termp != NULL && tcgetattr(sfd, termp) < 0))
> goto err;
> -
> +#endif
> if (amaster)
> *amaster = mfd;
> if (aslave)
> @@ -93,7 +101,8 @@ err:
> close(mfd);
> return -1;
> }
> -
> +#endif
> +#ifdef __sun__
> static void cfmakeraw (struct termios *termios_p)
> {
> termios_p->c_iflag &=
> @@ -112,7 +121,7 @@ int qemu_openpty_raw(int *aslave, char *pty_name)
> {
> int amaster;
> struct termios tty;
> -#if defined(__OpenBSD__) || defined(__DragonFly__)
> +#if defined(__OpenBSD__) || defined(__DragonFly__) || defined(CONFIG_ANDROID)
> char pty_buf[PATH_MAX];
> #define q_ptsname(x) pty_buf
> #else
--
Alex Bennée
t; Paolo
>
>> +aie_st_lock_ret(env, vaddr, GETRA());
>> +} else {
>> +hwaddr paddr = h_get_st_phys(env, vaddr, GETRA());
>> +
>> +if (unlikely(aie_entry_exists(paddr))) {
>> +h_aie_lock(env, paddr);
>> +}
>> +}
>> +}
--
Alex Bennée
works
* What to do about icount?
What is the impact of multi-thread on icount? Do we need to disable it
for MTTCG or can it be correct per-cpu? Can it be updated lock-step?
We need some input from the guys that use icount the most.
Cheers,
--
Alex Bennée
onBlock *tb_find_slow(CPUState *cpu,
> if (!tb) {
> tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
> }
> +mmap_unlock();
> }
>
> /* we add the TB in the virtual pc hash table */
Fix the commit comment s/lock/unlock/ and you can have:
Reviewed-by: Alex Bennée
--
Alex Bennée
insertion(+)
>
> diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
> index 1c3b5b6..a9a33fd 100644
> --- a/hw/i386/kvmvapic.c
> +++ b/hw/i386/kvmvapic.c
> @@ -13,6 +13,7 @@
> #include "sysemu/kvm.h"
> #include "hw/i386/apic_internal.h"
> #include "
; -__thread volatile int have_tb_lock;
> +__thread int have_tb_lock;
Reviewed-by: Alex Bennée
but really should be folded into the original patches.
>
> void tb_lock(void)
> {
--
Alex Bennée
igned start)
> {
> /* Read other fields before reading final sequence. */
> smp_rmb();
Reviewed-by: Alex Bennée
You could send this to qemu-trivial now if you want.
--
Alex Bennée
er fields before reading final sequence. */
> smp_rmb();
> -return unlikely(sl->sequence != start);
> +return unlikely(atomic_read(&sl->sequence) != start);
> }
>
> #endif
--
Alex Bennée
m reading the
pthread_atfork man page right couldn't we just do:
pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_lock);
> rcu_init_complete();
> }
--
Alex Bennée
Emilio G. Cota writes:
> On Tue, Sep 08, 2015 at 18:34:38 +0100, Alex Bennée wrote:
>> Emilio G. Cota writes:
> (snip)
>> > +static void rcu_init_child(void)
>> > +{
>> > +qemu_mutex_init(&rcu_registry_lock);
>> > +}
>> > #endif
if there are statements above.
> +On the other hand, however, it's often best to move that #ifdef/#ifndef
> +block to a separate function altogether.
>
> 6. Conditional statements
Reviewed-by: Alex Bennée
--
Alex Bennée
(rcu_reader_data) node;
> };
Reviewed-by: Alex Bennée
--
Alex Bennée
t_page_size;
> uintptr_t qemu_host_page_mask;
>
> -/* This is a multi-level map on the virtual address space.
> - The bottom level has pointers to PageDesc. */
> +/* The bottom level has pointers to PageDesc */
> static void *l1_map[V_L1_SIZE];
>
> /* code generation context */
Reviewed-by: Alex Bennée
--
Alex Bennée
operation specified in op.
Hardcoded op so no
ETIMEDOUT
Timeout during the FUTEX_WAIT operation.
No timeout specified so we shouldn't hit it
> +}
> + }
> }
> #else
> static inline void futex_wake(QemuEvent *ev, int n)
--
Alex Bennée
use the corresponding iotlb value. */
> uintptr_t addend;
So this ends up expanding the TLB entry size and either pushing the
overall TLB up in size or reducing the number of entries per-TLB so I
think we would need some numbers on the impact on performance this has.
As far as I can see you never use this value in this patch series so
maybe this is worth deferring for now?
--
Alex Bennée
so we cannot use 'node' here */
> +old = atomic_cmpxchg(slot, NULL, new);
> +if (old) {
> +if (level == 1) {
> +delete(node);
> +} else {
> +g_free(node);
> +}
> +node = old;
> +}
> +}
> +shift -= tree->radix;
> +level--;
> +} while (level > 0);
> +return node;
> +}
> +
> +void qemu_radix_tree_init(QemuRadixTree *tree, int bits, int radix)
> +{
> +tree->radix = radix;
> +tree->max_height = 1 + DIV_ROUND_UP(bits, radix);
> +tree->root = g_malloc0(sizeof(*tree->root) + sizeof(void *) *
> BIT(radix));
> +}
--
Alex Bennée
0, IMPL(TCG_TARGET_HAS_muluh_i64))
> DEF(mulsh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i64))
>
> +/* fences */
> +DEF(fence_load, 0, 0, 0, 0)
> +DEF(fence_store, 0, 0, 0, 0)
> +DEF(fence_full, 0, 0, 0, 0)
> +
> /* QEMU specific */
> #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
> DEF(debug_insn_start, 0, 0, 2, TCG_OPF_NOT_PRESENT)
--
Alex Bennée
gt; +
> /* QEMU specific operations. */
>
> #ifndef TARGET_LONG_BITS
--
Alex Bennée
;>if bytemap[vaddr] == 254
>> bytemap[vaddr] = CPU_ID
>>
>> The UP case is optimized because bytemap[vaddr] will always be 0 or 254.
>>
>> The algorithm requires the LL to be cleared e.g. on exceptions.
>> Paolo
>>
>>> alvise
>>>
>>> On Tue, Aug 11, 2015 at 6:32 PM, Paolo Bonzini wrote:
>>>>
>>>>
>>>> On 11/08/2015 18:11, alvise rigo wrote:
>>>>>>> Why flush the entire cache (I understand you mean TLB)?
>>>>> Sorry, I meant the TLB.
>>>>> If for each removal of an exclusive entry we set also the bit to 1, we
>>>>> force the following LL to make a tlb_flush() on every vCPU.
>>>>
>>>> What if you only flush one entry with tlb_flush_entry (on every vCPU)?
>>>>
>>>> Paolo
--
Alex Bennée
7 +++---
> target-xtensa/cpu.h | 1 -
> target-xtensa/translate.c | 52 ++---
> tcg/tcg-op.h | 52 +++--
> tcg/tcg-opc.h | 4 +-
> tcg/tcg.c | 96 -
> tcg/tcg.h | 14 ++-
> tci.c | 9 --
> translate-all.c | 237
> --
> 42 files changed, 578 insertions(+), 1097 deletions(-)
--
Alex Bennée
Michael Tokarev writes:
> 03.08.2015 12:14, Alex Bennée wrote:
>> Hi,
>>
>> This is mostly just a re-base to keep current with master. I've added
>> a couple of outstanding s-o-b and r-b tags. There are also two new
>> patches in this series whi
e week when the kids are back to school ;-)
>
> Paolo
>
>
> -Original Message-
> From: Mark Burton [mark.bur...@greensocs.com]
> Received: mercoledì, 26 ago 2015, 14:21
> To: KONRAD Frédéric [fred.kon...@greensocs.com]
> CC: qemu-devel [qemu-devel@nongnu.org]; Alex Bennée [al
>flush_global = flush_global;
> -async_run_on_cpu(cpu, tlb_flush_async_work, params);
> -}
> -}
> -#endif /* MTTCG */
> + *arg = flush_global;
> +tb_lock();
> +cpu_tcg_sched_work(current_cpu, __tlb_flush_all, arg);
> }
>
> static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
--
Alex Bennée
e CPU to check.
> + *
> + * Checks whether the CPU thread is idle.
> + *
> + * Returns: %true if the thread is idle;
> + * %false otherwise.
> + */
> +bool cpu_thread_is_idle(CPUState *cpu);
> +
> +/**
> * run_on_cpu:
> * @cpu: The vCPU to run on.
> * @func: The function to be executed.
--
Alex Bennée
h"
>
> +#if defined(CONFIG_USER_ONLY)
> +extern QemuMutex global_cpu_lock;
> +#endif
> +
> #ifndef NDEBUG
> static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
> #if TCG_TARGET_REG_BITS == 64
> @@ -2342,6 +2346,10 @@ static void tcg_target_init(TCGContext *s)
> tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
>
> tcg_add_target_add_op_defs(x86_op_defs);
> +
> +#if defined(CONFIG_USER_ONLY)
> +qemu_mutex_init(global_cpu_lock);
> +#endif
> }
>
> typedef struct {
I wonder if it would be better splitting the patches:
- Convert tb spinlocks to use tb_lock
- i386: convert lock helpers to QemuMutex
before the final
- Remove spinlocks
--
Alex Bennée
x.tb_ctx.nb_tbs - 1;
> -while (m_min <= m_max) {
> -m = (m_min + m_max) >> 1;
> - tb = &tcg_ctx.tb_ctx.tbs[m];
> -v = (uintptr_t)tb->tc_ptr;
> -if (v == tc_ptr) {
> -return tb;
> -} else if (tc_ptr < v) {
> -m_max = m - 1;
> -} else {
> -m_min = m + 1;
> +TranslationBlock *tb = NULL;
> +
> +tb_lock();
> +
> +if ((tcg_ctx.tb_ctx.nb_tbs > 0)
> +&& (tc_ptr >= (uintptr_t)tcg_ctx.code_gen_buffer &&
> +tc_ptr < (uintptr_t)tcg_ctx.code_gen_ptr)) {
> +/* binary search (cf Knuth) */
> +m_min = 0;
> +m_max = tcg_ctx.tb_ctx.nb_tbs - 1;
> +while (m_min <= m_max) {
> +m = (m_min + m_max) >> 1;
> +tb = &tcg_ctx.tb_ctx.tbs[m];
> +v = (uintptr_t)tb->tc_ptr;
> +if (v == tc_ptr) {
> +tb_unlock();
> +return tb;
> +} else if (tc_ptr < v) {
> +m_max = m - 1;
> +} else {
> +m_min = m + 1;
> +}
> }
> +tb = &tcg_ctx.tb_ctx.tbs[m_max];
> }
> -return &tcg_ctx.tb_ctx.tbs[m_max];
> +
> +tb_unlock();
> +return tb;
> }
>
> #if !defined(CONFIG_USER_ONLY)
> @@ -1564,6 +1637,8 @@ void dump_exec_info(FILE *f, fprintf_function
> cpu_fprintf)
> int direct_jmp_count, direct_jmp2_count, cross_page;
> TranslationBlock *tb;
>
> +tb_lock();
> +
> target_code_size = 0;
> max_target_code_size = 0;
> cross_page = 0;
> @@ -1619,6 +1694,8 @@ void dump_exec_info(FILE *f, fprintf_function
> cpu_fprintf)
> tcg_ctx.tb_ctx.tb_phys_invalidate_count);
> cpu_fprintf(f, "TLB flush count %d\n", tlb_flush_count);
> tcg_dump_info(f, cpu_fprintf);
> +
> +tb_unlock();
> }
>
> void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf)
--
Alex Bennée
>
>> Paolo
>
> Hmm probably not, though we didn't pay attention to keep the non MTTCG
> working.
> (which is probably not good).
You may want to consider push a branch up to a github mirror and
enabling travis-ci on the repo. That way you'll at least know how broken
the rest of the tree is.
I appreciate we are still at the RFC stage here but it will probably pay
off in the long run to try and avoid breaking the rest of the tree ;-)
--
Alex Bennée
probably load stuff in the memory hence a double lock.
> It will probably disappear with:
>
> http://thread.gmane.org/gmane.comp.emulators.qemu/345258
So I guess this patch will shrink a lot once we re-base ontop of Paolo's
patches (which should be real soon now).
>
> Thanks,
> Fred
>
>>> + */
>>> +qemu_mutex_unlock_iothread();
>>> /* reset all devices */
>>> QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
>>> re->func(re->opaque);
>>> }
>>> +qemu_mutex_lock_iothread();
>>> }
>>>
>>> void qemu_system_reset(bool report)
>>>
--
Alex Bennée
next_cpu != NULL && !first_cpu->exit_request;
> + next_cpu = CPU_NEXT(next_cpu)) {
> CPUState *cpu = next_cpu;
> CPUArchState *env = cpu->env_ptr;
>
> @@ -1410,7 +1420,8 @@ static void tcg_exec_all(void)
> break;
> }
> }
> -exit_request = 0;
> +
> +first_cpu->exit_request = 0;
> }
>
> void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
--
Alex Bennée
; index 108bfa2..ff41a4c 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -249,6 +249,7 @@ static void cpu_common_reset(CPUState *cpu)
> cpu->icount_decr.u32 = 0;
> cpu->can_do_io = 0;
> cpu->exception_index = -1;
> +cpu->tcg_executing = 0;
> memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
> }
--
Alex Bennée
_all(CPUState *cpu)
I'd drop the _all and rename the function tcg_exec() to avoid confusion.
> {
> int r;
> +CPUArchState *env = cpu->env_ptr;
>
> /* Account partial waits to QEMU_CLOCK_VIRTUAL. */
> qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
>
> -if (next_cpu == NULL) {
> -next_cpu = first_cpu;
> -}
> -for (; next_cpu != NULL && !first_cpu->exit_request;
> - next_cpu = CPU_NEXT(next_cpu)) {
> -CPUState *cpu = next_cpu;
> -CPUArchState *env = cpu->env_ptr;
> -
> +while (!cpu->exit_request) {
> qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
>(cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
>
> @@ -1422,7 +1395,7 @@ static void tcg_exec_all(void)
> }
> }
>
> -first_cpu->exit_request = 0;
> +cpu->exit_request = 0;
> }
>
> void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
--
Alex Bennée
all_vcpus(void);
> void pause_all_vcpus(void);
> void cpu_stop_current(void);
> +void qemu_cpu_kick_thread(CPUState *cpu);
Again I couldn't see use outside of cpus.c which could be solved by
putting the declaration at the top.
>
> void cpu_synchronize_all_states(void);
> void cpu_synchronize_all_post_reset(void);
--
Alex Bennée
e_hash_func(tb->pc);
> CPU_FOREACH(cpu) {
> @@ -1022,6 +1070,15 @@ void tb_phys_invalidate(TranslationBlock *tb,
> tb_page_addr_t page_addr)
> tb1 = tb2;
> }
> tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */
> +#else
> +CPU_FOREACH(cpu) {
> +params = g_malloc(sizeof(struct CPUDiscardTBParams));
> +params->cpu = cpu;
> +params->tb = tb;
> +async_run_on_cpu(cpu, cpu_discard_tb_from_jmp_cache, params);
> +}
> +async_run_safe_work_on_cpu(first_cpu, tb_invalidate_jmp_remove, tb);
> +#endif /* MTTCG */
>
> tcg_ctx.tb_ctx.tb_phys_invalidate_count++;
> tb_unlock();
--
Alex Bennée
+96,9 @@ bool qemu_in_vcpu_thread(void);
> void cpu_reload_memory_map(CPUState *cpu);
> void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
> /* cputlb.c */
> +void tlb_flush_page_all(target_ulong addr);
> void tlb_flush_page(CPUState *cpu, target_ulong addr);
> +void tlb_flush_all(int flush_global);
> void tlb_flush(CPUState *cpu, int flush_global);
> void tlb_set_page(CPUState *cpu, target_ulong vaddr,
>hwaddr paddr, int prot,
--
Alex Bennée
> {
> - CPUState *other_cs;
> -int asid = extract64(value, 48, 16);
> -
> -CPU_FOREACH(other_cs) {
> -tlb_flush(other_cs, asid == 0);
> -}
> +tlb_flush_all(extract64(value, 48, 16) == 0);
> }
ditto
>
> static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo
> *ri)
--
Alex Bennée
, tb_flush_work, env);
> +#endif /* MTTCG */
> +}
Same comments about build system fixups.
> +
> /* flush all the translation blocks */
> /* XXX: tb_flush is currently not thread safe */
> void tb_flush(CPUArchState *env1)
--
Alex Bennée
; semantics of non-ARM guests...
>>>
>>> thanks
>>> -- PMM
>> Yes this is not the case as I implemented it.
>>
>> The rest of the TB will be executed before the tlb_flush work really happen.
>> The old version did this, was slow and was a mess (if two VCPUs want to
>> tlb_flush
>> at the same time and an other tlb_flush_page.. it becomes tricky..)
>>
>> I think it's not really terrible if the other VCPU execute some stuff before
>> doing the
>> tlb_flush.? So the solution would be only to cut the TranslationBlock after
>> instruction
>> which require a tlb_flush?
>>
>> Thanks,
>> Fred
>>
--
Alex Bennée
tb_alloc(pc);
> /* Don't forget to invalidate previous TB info. */
--
Alex Bennée
>> cpus: introduce async_run_safe_work_on_cpu.
>>
>> cpu-exec.c| 7 +++
>> cpus.c| 164
>> +-
>> include/qom/cpu.h | 28 ++
>> qom/cpu.c | 2 +
>> 4 files changed, 161 insertions(+), 40 deletions(-)
>>
--
Alex Bennée
PUState);
> diff --git a/qom/cpu.c b/qom/cpu.c
> index 4e12598..62663e5 100644
> --- a/qom/cpu.c
> +++ b/qom/cpu.c
> @@ -249,6 +249,7 @@ static void cpu_common_reset(CPUState *cpu)
> cpu->icount_decr.u32 = 0;
> cpu->can_do_io = 0;
> cpu->exception_index = -1;
> +cpu->tcg_executing = 0;
> memset(cpu->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
> }
--
Alex Bennée
gt; bool created;
> bool stop;
> @@ -546,6 +548,26 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data),
> void *data);
> void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
>
> /**
> + * async_run_safe_work_on_cpu:
> + * @cpu: The vCPU to run on.
> + * @func: The function to be executed.
> + * @data: Data to pass to the function.
> + *
> + * Schedules the function @func for execution on the vCPU @cpu asynchronously
> + * when all the VCPUs are outside their loop.
> + */
> +void async_run_safe_work_on_cpu(CPUState *cpu, void (*func)(void *data),
> +void *data);
We should probably document the fact that the user should allocate a
data structure for each CPU they send async work to.
> +
> +/**
> + * async_safe_work_pending:
> + *
> + * Check whether any safe work is pending on any VCPUs.
> + * Returns: @true if a safe work is pending, @false otherwise.
> + */
> +bool async_safe_work_pending(void);
> +
> +/**
> * qemu_get_cpu:
> * @index: The CPUState@cpu_index value of the CPU to obtain.
> *
Otherwise looks pretty reasonable to me.
--
Alex Bennée
be MMIO (yes, really), so okay.
For some reason I don't find the use of the word "encourage" w.r.t
compiler behaviour particularly encouraging ;-)
--
Alex Bennée
ow unaligned access (it spans two pages or IO). */
> +if (DATA_SIZE > 1
> +&& unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
> + >= TARGET_PAGE_SIZE)) {
> +int i;
> +do_unaligned_access:
> +if ((get_memop(oi) & MO_AMASK) == MO_ALIGN) {
> +cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
> + mmu_idx, retaddr);
> +}
> +/* XXX: not efficient, but simple */
> +/* Note: relies on the fact that tlb_fill() does not remove the
> + * previous page from the TLB cache. */
> +for (i = DATA_SIZE - 1; i >= 0; i--) {
> +/* Big-endian extract. */
> +uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
> +/* Note the adjustment at the beginning of the function.
> + Undo that for the recursion. */
> +glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
> +oi, retaddr + GETPC_ADJ);
> +}
> +return;
> }
> -return;
> }
>
> /* Handle aligned access or unaligned access in the same page. */
--
Alex Bennée
@@ void helper_be_stl_mmu(CPUArchState *env, target_ulong
> addr, uint32_t val,
> TCGMemOpIdx oi, uintptr_t retaddr);
> void helper_be_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
> TCGMemOpIdx oi, uintptr_t retaddr);
> +/* Exclusive variants */
> +tcg_target_ulong helper_ret_stcondb_mmu(CPUArchState *env, target_ulong addr,
> +uint8_t val, int mmu_idx, uintptr_t retaddr);
> +tcg_target_ulong helper_le_stcondw_mmu(CPUArchState *env, target_ulong addr,
> +uint16_t val, int mmu_idx, uintptr_t
> retaddr);
> +tcg_target_ulong helper_le_stcondl_mmu(CPUArchState *env, target_ulong addr,
> +uint32_t val, int mmu_idx, uintptr_t
> retaddr);
> +uint64_t helper_le_stcondq_mmu(CPUArchState *env, target_ulong addr,
> +uint64_t val, int mmu_idx, uintptr_t
> retaddr);
>
> /* Temporary aliases until backends are converted. */
> #ifdef TARGET_WORDS_BIGENDIAN
--
Alex Bennée
uint16_t val, int mmu_idx, uintptr_t
> retaddr);
> +uint16_t val, TCGMemOpIdx oi, uintptr_t retaddr);
> tcg_target_ulong helper_le_stcondl_mmu(CPUArchState *env, target_ulong addr,
> -uint32_t val, int mmu_idx, uintptr_t
> retaddr);
> +uint32_t val, TCGMemOpIdx oi, uintptr_t retaddr);
> uint64_t helper_le_stcondq_mmu(CPUArchState *env, target_ulong addr,
> -uint64_t val, int mmu_idx, uintptr_t
> retaddr);
> +uint64_t val, TCGMemOpIdx oi, uintptr_t retaddr);
>
> /* Temporary aliases until backends are converted. */
> #ifdef TARGET_WORDS_BIGENDIAN
--
Alex Bennée
se /* !CONFIG_SOFTMMU */
> if (GUEST_BASE) {
> tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP, GUEST_BASE);
> @@ -1864,16 +1921,22 @@ static inline void tcg_out_op(TCGContext *s,
> TCGOpcode opc,
> break;
>
> case INDEX_op_qemu_ld_i32:
> -tcg_out_qemu_ld(s, args, 0);
> +tcg_out_qemu_ld(s, args, 0, 0);
> +break;
> +case INDEX_op_qemu_ldlink_i32:
> +tcg_out_qemu_ld(s, args, 0, 1); /* LoadLink */
> break;
> case INDEX_op_qemu_ld_i64:
> -tcg_out_qemu_ld(s, args, 1);
> +tcg_out_qemu_ld(s, args, 1, 0);
> break;
> case INDEX_op_qemu_st_i32:
> -tcg_out_qemu_st(s, args, 0);
> +tcg_out_qemu_st(s, args, 0, 0);
> +break;
> +case INDEX_op_qemu_stcond_i32:
> +tcg_out_qemu_st(s, args, 0, 1); /* StoreConditional */
> break;
> case INDEX_op_qemu_st_i64:
> -tcg_out_qemu_st(s, args, 1);
> +tcg_out_qemu_st(s, args, 1, 0);
> break;
>
> case INDEX_op_bswap16_i32:
> @@ -1957,8 +2020,10 @@ static const TCGTargetOpDef arm_op_defs[] = {
>
> #if TARGET_LONG_BITS == 32
> { INDEX_op_qemu_ld_i32, { "r", "l" } },
> +{ INDEX_op_qemu_ldlink_i32, { "r", "l" } },
> { INDEX_op_qemu_ld_i64, { "r", "r", "l" } },
> { INDEX_op_qemu_st_i32, { "s", "s" } },
> +{ INDEX_op_qemu_stcond_i32, { "r", "s", "s" } },
> { INDEX_op_qemu_st_i64, { "s", "s", "s" } },
> #else
> { INDEX_op_qemu_ld_i32, { "r", "l", "l" } },
--
Alex Bennée
2272,23 @@ static const TCGTargetOpDef x86_op_defs[] = {
>
> #if TCG_TARGET_REG_BITS == 64
> { INDEX_op_qemu_ld_i32, { "r", "L" } },
> +{ INDEX_op_qemu_ldlink_i32, { "r", "L" } },
> { INDEX_op_qemu_st_i32, { "L", "L" } },
> +{ INDEX_op_qemu_stcond_i32, { "r", "L", "L" } },
> { INDEX_op_qemu_ld_i64, { "r", "L" } },
> { INDEX_op_qemu_st_i64, { "L", "L" } },
> #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
> { INDEX_op_qemu_ld_i32, { "r", "L" } },
> +{ INDEX_op_qemu_ldlink_i32, { "r", "L" } },
> { INDEX_op_qemu_st_i32, { "L", "L" } },
> +{ INDEX_op_qemu_stcond_i32, { "r", "L", "L" } },
> { INDEX_op_qemu_ld_i64, { "r", "r", "L" } },
> { INDEX_op_qemu_st_i64, { "L", "L", "L" } },
> #else
> { INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
> +{ INDEX_op_qemu_ldlink_i32, { "r", "L", "L" } },
> { INDEX_op_qemu_st_i32, { "L", "L", "L" } },
> +{ INDEX_op_qemu_stcond_i32, { "r", "L", "L", "L" } },
> { INDEX_op_qemu_ld_i64, { "r", "r", "L", "L" } },
> { INDEX_op_qemu_st_i64, { "L", "L", "L", "L" } },
> #endif
--
Alex Bennée
memory[DIRTY_MEMORY_EXCLUSIVE],
> + addr >> TARGET_PAGE_BITS, 1);
Does this call for simply implementing a clear_bit_atomic() rather than
the fancy bitmap_test_and_clear_atomic. Looking at atomic.h it seems the
primitives you need are there.
> }
>
> #endif
--
Alex Bennée
d cpu_exit_do_rendezvous(CPUState *cpu);
> +void cpu_exit_rendezvous_wait_others(CPUState *cpu);
> +void cpu_exit_rendezvous_release(void);
> +
> struct KVMState;
> struct kvm_run;
>
> @@ -291,6 +305,8 @@ struct CPUState {
>
> void *opaque;
>
> +volatile int pending_rdv;
> +
I will however echo the "hmmm" on Fred's patch about the optimistic use
of volatile here. As Peter mentioned it is a red flag and I would prefer
explicit memory consistency behaviour used and documented.
> /* In order to avoid passing too many arguments to the MMIO helpers,
> * we store some rarely used information in the CPU context.
> */
--
Alex Bennée
/* We set it preventively to true to distinguish the following legacy
> + * access as one made by the store conditional wrapper. If the store
> + * conditional does not succeed, the value will be set to 0.*/
> +env->excl_succeeded = 1;
> +helper_st_legacy(env, addr, val, mmu_idx, retaddr);
>
> -/* The StoreConditional succeeded */
> +if (env->excl_succeeded) {
> +env->excl_succeeded = 0;
> ret = 0;
> +} else {
> +g_usleep(TCG_ATOMIC_INSN_EMUL_DELAY);
> +ret = 1;
> }
>
> -env->tlb_table[mmu_idx][index].addr_write &= ~TLB_EXCL;
> -env->excl_protected_hwaddr = EXCLUSIVE_RESET_ADDR;
> /* It's likely that the page will be used again for exclusive accesses,
> * for this reason we don't flush any TLB cache at the price of some
> * additional slow paths and we don't set the page bit as dirty.
--
Alex Bennée
env->excl_protected_hwaddr = EXCLUSIVE_RESET_ADDR;
> +qemu_mutex_unlock(&tcg_excl_access_lock);
> +env->excl_succeeded = 0;
> +
> +return;
> +}
> +}
Given the amount of copy/paste between the two functions I wonder if
there is some commonality to be re-factored out here?
>
> -if (set_to_dirty) {
> -cpu_physical_memory_set_excl_dirty(hw_addr);
> -} /* the vCPU is legitimately writing to the protected address */
> +haddr = addr + env->tlb_table[mmu_idx][index].addend;
> +
> +glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
> +
> +qemu_mutex_unlock(&tcg_excl_access_lock);
> +env->excl_protected_hwaddr = EXCLUSIVE_RESET_ADDR;
> +
> +return;
> } else {
> if ((addr & (DATA_SIZE - 1)) != 0) {
> goto do_unaligned_access;
--
Alex Bennée
new branch each time the patches get merged into a
new upstream RC. The question then become how to deal with any
cross-dependencies between the slow-path and the main MTTCG branches?
I suspect the initial common branch point would just be
2.4.0-rc1+safe_async.
Does that sound workable?
--
Alex Bennée
fred.kon...@greensocs.com writes:
> From: KONRAD Frederic
>
> This protects queued_work_* used by async_run_on_cpu, run_on_cpu and
> flush_queued_work with a new lock (work_mutex) to prevent multiple
> (concurrent)
> access.
>
> Signed-off-by: KONRAD Frederic
| 10
> cpus.c| 160
> --
> include/qom/cpu.h | 57 +++
> qom/cpu.c | 20 +++
> 4 files changed, 207 insertions(+), 40 deletions(-)
--
Alex Bennée
troduce async_run_safe_work_on_cpu.
Also currently breaks a lot of targets:
https://travis-ci.org/stsquad/qemu/builds/71797143
>
> cpu-exec.c| 10
> cpus.c| 160
> --
> include/qom/cpu.h | 57 +++
> qom/cpu.c | 20 +++
> 4 files changed, 207 insertions(+), 40 deletions(-)
--
Alex Bennée
alvise rigo writes:
> On Mon, Jul 20, 2015 at 8:01 PM, Frederic Konrad
> wrote:
>> On 20/07/2015 19:41, alvise rigo wrote:
>>>
>>> Hi Alex,
>>>
>>> Thank you for this summary.
>>> Some comments below.
>>>
>>
return TRUE;
> +}
Is this right. AIUI we could return FALSE here to remove the watch for
the now closed channel.
--
Alex Bennée
x27;m going to be doing some profiling myself over the next few days so
I'll clean-up the patches and re-submit to the list soon.
--
Alex Bennée
As we only need to manipulate the single flag do it directly though env.
Signed-off-by: Alex Bennée
---
v2:
- remove unused cpsr
- the direct flag setting seems a little hacky?
diff --git a/linux-user/main.c b/linux-user/main.c
index 8848e15..9101541 100644
--- a/linux-user/main.c
+++ b
This adds a universal program state save and restore function. This is
intended to simplify the migration serialisation functionality and avoid
special casing depending on the mode of the CPU at serialisation time.
Signed-off-by: Alex Bennée
---
v2:
- reword commentary for
And use the new machinery to to save and restore program state. The old
cpsr_write function did some special handling for mode switches which
has been moved into the helper function.
Signed-off-by: Alex Bennée
---
v2:
- rebase
- add mask helper function
- checkpatch fixes
diff --git a
801 - 900 of 19066 matches
Mail list logo