[Qemu-devel] [PATCH V9 1/5] target-ppc: Update external_htab even when HTAB is managed by kernel
We will use this in later patches to make sure we use the right load functions when copying hpte entries. Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 1b4e38f50a8d..ac62c8f9294b 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -740,6 +740,13 @@ static void spapr_cpu_reset(void *opaque) env-spr[SPR_HIOR] = 0; env-external_htab = (uint8_t *)spapr-htab; +if (kvm_enabled() !env-external_htab) { +/* + * HV KVM, set external_htab to 1 so our ppc_hash64_load_hpte* + * functions do the right thing. + */ +env-external_htab = (void *)1; +} env-htab_base = -1; env-htab_mask = HTAB_SIZE(spapr) - 1; env-spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr-htab | -- 1.8.5.3
[Qemu-devel] [PATCH V9 3/5] target-ppc: Fix page table lookup with kvm enabled
With kvm enabled, we store the hash page table information in the hypervisor. Use ioctl to read the htab contents. Without this we get the below error when trying to read the guest address (gdb) x/10 do_fork 0xc0098660 do_fork: Cannot access memory at address 0xc0098660 (gdb) Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 1 + hw/ppc/spapr_hcall.c| 50 +++ target-ppc/kvm.c| 53 + target-ppc/kvm_ppc.h| 19 target-ppc/mmu-hash64.c | 78 - target-ppc/mmu-hash64.h | 19 6 files changed, 181 insertions(+), 39 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 009bb0112cc0..9241cdd2a86e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -685,6 +685,7 @@ static void spapr_reset_htab(sPAPREnvironment *spapr) if (shift 0) { /* Kernel handles htab, we don't need to allocate one */ spapr-htab_shift = shift; +kvmppc_kern_htab = true; } else { if (!spapr-htab) { /* Allocate an htab if we don't yet have one */ diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index f755a5392317..01cf6b05fee7 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -50,8 +50,9 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong ptel = args[3]; target_ulong page_shift = 12; target_ulong raddr; -target_ulong i; +target_ulong index; hwaddr hpte; +uint64_t token; /* only handle 4k and 16M pages for now */ if (pteh HPTE64_V_LARGE) { @@ -94,30 +95,37 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, if ((pte_index * HASH_PTE_SIZE_64) ~env-htab_mask) { return H_PARAMETER; } + +index = 0; +hpte = pte_index * HASH_PTE_SIZE_64; if (likely((flags H_EXACT) == 0)) { pte_index = ~7ULL; -hpte = pte_index * HASH_PTE_SIZE_64; -for (i = 0; ; ++i) { -if (i == 8) { +token = ppc_hash64_start_access(cpu, pte_index); +do { +if (index == 8) { +ppc_hash64_stop_access(token); return H_PTEG_FULL; } -if ((ppc_hash64_load_hpte0(env, hpte) HPTE64_V_VALID) == 0) { +if ((ppc_hash64_load_hpte0(env, token, index) HPTE64_V_VALID) == 0) { break; } -hpte += HASH_PTE_SIZE_64; -} +} while (index++); +ppc_hash64_stop_access(token); } else { -i = 0; -hpte = pte_index * HASH_PTE_SIZE_64; -if (ppc_hash64_load_hpte0(env, hpte) HPTE64_V_VALID) { +token = ppc_hash64_start_access(cpu, pte_index); +if (ppc_hash64_load_hpte0(env, token, 0) HPTE64_V_VALID) { +ppc_hash64_stop_access(token); return H_PTEG_FULL; } +ppc_hash64_stop_access(token); } +hpte += index * HASH_PTE_SIZE_64; + ppc_hash64_store_hpte1(env, hpte, ptel); /* eieio(); FIXME: need some sort of barrier for smp? */ ppc_hash64_store_hpte0(env, hpte, pteh | HPTE64_V_HPTE_DIRTY); -args[0] = pte_index + i; +args[0] = pte_index + index; return H_SUCCESS; } @@ -134,16 +142,17 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex, target_ulong *vp, target_ulong *rp) { hwaddr hpte; +uint64_t token; target_ulong v, r, rb; if ((ptex * HASH_PTE_SIZE_64) ~env-htab_mask) { return REMOVE_PARM; } -hpte = ptex * HASH_PTE_SIZE_64; - -v = ppc_hash64_load_hpte0(env, hpte); -r = ppc_hash64_load_hpte1(env, hpte); +token = ppc_hash64_start_access(ppc_env_get_cpu(env), ptex); +v = ppc_hash64_load_hpte0(env, token, 0); +r = ppc_hash64_load_hpte1(env, token, 0); +ppc_hash64_stop_access(token); if ((v HPTE64_V_VALID) == 0 || ((flags H_AVPN) (v ~0x7fULL) != avpn) || @@ -152,6 +161,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex, } *vp = v; *rp = r; +hpte = ptex * HASH_PTE_SIZE_64; ppc_hash64_store_hpte0(env, hpte, HPTE64_V_HPTE_DIRTY); rb = compute_tlbie_rb(v, r, ptex); ppc_tlb_invalidate_one(env, rb); @@ -260,16 +270,17 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong pte_index = args[1]; target_ulong avpn = args[2]; hwaddr hpte; +uint64_t token; target_ulong v, r, rb; if ((pte_index * HASH_PTE_SIZE_64) ~env-htab_mask) { return H_PARAMETER; } -hpte = pte_index * HASH_PTE_SIZE_64; - -v = ppc_hash64_load_hpte0(env, hpte); -r = ppc_hash64_load_hpte1(env, hpte); +token = ppc_hash64_start_access(cpu, pte_index); +v = ppc_hash64_load_hpte0(env, token, 0); +r =
[Qemu-devel] [PATCH V9 0/5] target-ppc: Add support for dumping guest memory using qemu gdb server
Hi, This patch series implement support for dumping guest memory using qemu gdb server. The last patch also enable qemu monitor command dump-guest-memory With this patch series we can now do (gdb) x/4i htab_call_hpte_insert1 0xc00470d8 .htab_call_hpte_insert1:bl 0xc00470d8 .htab_call_hpte_insert1 0xc00470dc .htab_call_hpte_insert1+4: cmpdi r3,0 0xc00470e0 .htab_call_hpte_insert1+8: bge 0xc0047190 htab_pte_insert_ok 0xc00470e4 .htab_call_hpte_insert1+12: cmpdi r3,-2 (gdb) target remote localhost:1234 Remote debugging using localhost:1234 .plpar_hcall_norets () at arch/powerpc/platforms/pseries/hvCall.S:119 119 HCALL_INST_POSTCALL_NORETS (gdb) x/4i htab_call_hpte_insert1 0xc00470d8 .htab_call_hpte_insert1:bl 0xc005f8f0 pSeries_lpar_hpte_insert 0xc00470dc .htab_call_hpte_insert1+4: cmpdi r3,0 0xc00470e0 .htab_call_hpte_insert1+8: bge 0xc0047190 htab_pte_insert_ok 0xc00470e4 .htab_call_hpte_insert1+12: cmpdi r3,-2 (gdb) NOTE: We still don't support inserting breakpoints. Before Fix: (qemu) memsave 0xc00470d8 10 memdump Invalid parameter 'addr' (qemu) After fix: (qemu) memsave 0xc00470d8 10 memdump (qemu) Changes from V8: * Add hpte store support. Currently we don't have any user for this.
[Qemu-devel] [PATCH V9 2/5] target-ppc: Fix htab_mask calculation
Correctly update the htab_mask using the return value of KVM_PPC_ALLOCATE_HTAB ioctl. Also we don't update sdr1 on GET_SREGS for HV. We check for external htab and if found true, we don't need to update sdr1 Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/ppc/spapr.c | 8 +++- target-ppc/cpu.h | 1 + target-ppc/kvm.c | 4 +++- target-ppc/machine.c | 11 +++ target-ppc/misc_helper.c | 4 +++- target-ppc/mmu_helper.c | 3 ++- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ac62c8f9294b..009bb0112cc0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -748,7 +748,13 @@ static void spapr_cpu_reset(void *opaque) env-external_htab = (void *)1; } env-htab_base = -1; -env-htab_mask = HTAB_SIZE(spapr) - 1; +/* + * htab_mask is the mask used to normalize hash value to PTEG index. + * htab_shift is log2 of hash table size. + * We have 8 hpte per group, and each hpte is 16 bytes. + * ie have 128 bytes per hpte entry. + */ +env-htab_mask = (1ULL ((spapr)-htab_shift - 7)) - 1; env-spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr-htab | (spapr-htab_shift - 18); } diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index bb847676a52e..b0f66e5104dd 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -961,6 +961,7 @@ struct CPUPPCState { #endif /* segment registers */ hwaddr htab_base; +/* mask used to normalize hash value to PTEG index */ hwaddr htab_mask; target_ulong sr[32]; /* externally stored hash table */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 781b72f1ea5a..c771ec11ed28 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1029,7 +1029,9 @@ int kvm_arch_get_registers(CPUState *cs) return ret; } -ppc_store_sdr1(env, sregs.u.s.sdr1); +if (!env-external_htab) { +ppc_store_sdr1(env, sregs.u.s.sdr1); +} /* Sync SLB */ #ifdef TARGET_PPC64 diff --git a/target-ppc/machine.c b/target-ppc/machine.c index 12c174f7f3e6..2d46ceccca3a 100644 --- a/target-ppc/machine.c +++ b/target-ppc/machine.c @@ -70,7 +70,9 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) qemu_get_betls(f, env-pb[i]); for (i = 0; i 1024; i++) qemu_get_betls(f, env-spr[i]); -ppc_store_sdr1(env, sdr1); +if (!env-external_htab) { +ppc_store_sdr1(env, sdr1); +} qemu_get_be32s(f, env-vscr); qemu_get_be64s(f, env-spe_acc); qemu_get_be32s(f, env-spe_fscr); @@ -179,9 +181,10 @@ static int cpu_post_load(void *opaque, int version_id) env-IBAT[1][i+4] = env-spr[SPR_IBAT4U + 2*i + 1]; } -/* Restore htab_base and htab_mask variables */ -ppc_store_sdr1(env, env-spr[SPR_SDR1]); - +if (!env-external_htab) { +/* Restore htab_base and htab_mask variables */ +ppc_store_sdr1(env, env-spr[SPR_SDR1]); +} hreg_compute_hflags(env); hreg_compute_mem_idx(env); diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c index 616aab6fb67d..dc2ebfc4524b 100644 --- a/target-ppc/misc_helper.c +++ b/target-ppc/misc_helper.c @@ -38,7 +38,9 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn) void helper_store_sdr1(CPUPPCState *env, target_ulong val) { -ppc_store_sdr1(env, val); +if (!env-external_htab) { +ppc_store_sdr1(env, val); +} } void helper_store_hid0_601(CPUPPCState *env, target_ulong val) diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 04a840b01697..8e2f8e736a12 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -2014,6 +2014,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr) void ppc_store_sdr1(CPUPPCState *env, target_ulong value) { LOG_MMU(%s: TARGET_FMT_lx \n, __func__, value); +assert(!env-external_htab); if (env-spr[SPR_SDR1] != value) { env-spr[SPR_SDR1] = value; #if defined(TARGET_PPC64) @@ -2025,7 +2026,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value) stored in SDR1\n, htabsize); htabsize = 28; } -env-htab_mask = (1ULL (htabsize + 18)) - 1; +env-htab_mask = (1ULL (htabsize + 18 - 7)) - 1; env-htab_base = value SDR_64_HTABORG; } else #endif /* defined(TARGET_PPC64) */ -- 1.8.5.3
[Qemu-devel] [PATCH V9 5/5] target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab
This support updating htab managed by the hypervisor. Currently we don't have any user for this feature. This actually bring the store_hpte interface in-line with the load_hpte one. We may want to use this when we want to emulate henter hcall in qemu for HV kvm. Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- target-ppc/kvm.c| 30 ++ target-ppc/kvm_ppc.h| 10 ++ target-ppc/mmu-hash64.c | 18 ++ target-ppc/mmu-hash64.h | 16 ++-- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index eefd78afc004..893b59f99fa3 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -1989,3 +1989,33 @@ void kvmppc_hash64_free_pteg(uint64_t token) g_free(htab_buf); return; } + +void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, + target_ulong pte0, target_ulong pte1) +{ +int htab_fd; +struct kvm_get_htab_fd ghf; +struct kvm_get_htab_buf hpte_buf; + +ghf.flags = 0; +ghf.start_index = 0; /* Ignored */ +htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, ghf); +if (htab_fd 0) { +goto error_out; +} + +hpte_buf.header.n_valid = 1; +hpte_buf.header.n_invalid = 0; +hpte_buf.header.index = pte_index; +hpte_buf.hpte[0] = pte0; +hpte_buf.hpte[1] = pte1; +/* + * Write the hpte entry + */ +write(htab_fd, hpte_buf, sizeof(hpte_buf)); +close(htab_fd); +return; + +error_out: +return; +} diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index 800e1ad0834f..a65d34571914 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -47,6 +47,9 @@ int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index, uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index); void kvmppc_hash64_free_pteg(uint64_t token); +void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, + target_ulong pte0, target_ulong pte1); + #else static inline uint32_t kvmppc_get_tbfreq(void) @@ -207,6 +210,13 @@ static inline void kvmppc_hash64_free_pteg(uint64_t token) abort(); } +static inline void kvmppc_hash64_write_pte(CPUPPCState *env, + target_ulong pte_index, + target_ulong pte0, target_ulong pte1) +{ +abort(); +} + #endif #ifndef CONFIG_KVM diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index fb297d62e3a6..9f5db1b3d9b5 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -595,3 +595,21 @@ hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr) return ppc_hash64_pte_raddr(slb, pte, addr) TARGET_PAGE_MASK; } + +void ppc_hash64_store_hpte(CPUPPCState *env, + target_ulong pte_index, + target_ulong pte0, target_ulong pte1) +{ +if (kvmppc_kern_htab) { +return kvmppc_hash64_write_pte(env, pte_index, pte0, pte1); +} + +pte_index *= HASH_PTE_SIZE_64; +if (env-external_htab) { +stq_p(env-external_htab + pte_index, pte0); +stq_p(env-external_htab + pte_index + HASH_PTE_SIZE_64/2, pte1); +} else { +stq_phys(env-htab_base + pte_index, pte0); +stq_phys(env-htab_base + pte_index + HASH_PTE_SIZE_64/2, pte1); +} +} diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h index 3b6769ad130b..9c9ca1dfe2b5 100644 --- a/target-ppc/mmu-hash64.h +++ b/target-ppc/mmu-hash64.h @@ -9,6 +9,8 @@ int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs); hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr); int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw, int mmu_idx); +void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong index, + target_ulong pte0, target_ulong pte1); #endif /* @@ -102,20 +104,6 @@ static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env, } } -static inline void ppc_hash64_store_hpte(CPUPPCState *env, - target_ulong pte_index, - target_ulong pte0, target_ulong pte1) -{ -pte_index *= HASH_PTE_SIZE_64; -if (env-external_htab) { -stq_p(env-external_htab + pte_index, pte0); -stq_p(env-external_htab + pte_index + HASH_PTE_SIZE_64/2, pte1); -} else { -stq_phys(env-htab_base + pte_index, pte0); -stq_phys(env-htab_base + pte_index + HASH_PTE_SIZE_64/2, pte1); -} -} - typedef struct { uint64_t pte0, pte1; } ppc_hash_pte64_t; -- 1.8.5.3
[Qemu-devel] [PATCH V9 4/5] target-ppc: Change the hpte sore API
For updating in kernel htab we need to provide both pte0 and pte1, hence update the interface to take pte0 and pte1 together Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/ppc/spapr_hcall.c| 20 ++-- target-ppc/mmu-hash64.c | 3 ++- target-ppc/mmu-hash64.h | 22 -- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 01cf6b05fee7..55d4eef1d960 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -51,7 +51,6 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong page_shift = 12; target_ulong raddr; target_ulong index; -hwaddr hpte; uint64_t token; /* only handle 4k and 16M pages for now */ @@ -97,7 +96,6 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, } index = 0; -hpte = pte_index * HASH_PTE_SIZE_64; if (likely((flags H_EXACT) == 0)) { pte_index = ~7ULL; token = ppc_hash64_start_access(cpu, pte_index); @@ -119,11 +117,9 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, } ppc_hash64_stop_access(token); } -hpte += index * HASH_PTE_SIZE_64; -ppc_hash64_store_hpte1(env, hpte, ptel); -/* eieio(); FIXME: need some sort of barrier for smp? */ -ppc_hash64_store_hpte0(env, hpte, pteh | HPTE64_V_HPTE_DIRTY); +ppc_hash64_store_hpte(env, pte_index + index, + pteh | HPTE64_V_HPTE_DIRTY, ptel); args[0] = pte_index + index; return H_SUCCESS; @@ -141,7 +137,6 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex, target_ulong flags, target_ulong *vp, target_ulong *rp) { -hwaddr hpte; uint64_t token; target_ulong v, r, rb; @@ -161,8 +156,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex, } *vp = v; *rp = r; -hpte = ptex * HASH_PTE_SIZE_64; -ppc_hash64_store_hpte0(env, hpte, HPTE64_V_HPTE_DIRTY); +ppc_hash64_store_hpte(env, ptex, HPTE64_V_HPTE_DIRTY, 0); rb = compute_tlbie_rb(v, r, ptex); ppc_tlb_invalidate_one(env, rb); return REMOVE_SUCCESS; @@ -269,7 +263,6 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, target_ulong flags = args[0]; target_ulong pte_index = args[1]; target_ulong avpn = args[2]; -hwaddr hpte; uint64_t token; target_ulong v, r, rb; @@ -293,12 +286,11 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, r |= (flags 48) HPTE64_R_KEY_HI; r |= flags (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO); rb = compute_tlbie_rb(v, r, pte_index); -hpte = pte_index * HASH_PTE_SIZE_64; -ppc_hash64_store_hpte0(env, hpte, (v ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY); +ppc_hash64_store_hpte(env, pte_index, + (v ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0); ppc_tlb_invalidate_one(env, rb); -ppc_hash64_store_hpte1(env, hpte, r); /* Don't need a memory barrier, due to qemu's global lock */ -ppc_hash64_store_hpte0(env, hpte, v | HPTE64_V_HPTE_DIRTY); +ppc_hash64_store_hpte(env, pte_index, v | HPTE64_V_HPTE_DIRTY, r); return H_SUCCESS; } diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index 11f3f6e731bb..fb297d62e3a6 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -558,7 +558,8 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr, } if (new_pte1 != pte.pte1) { -ppc_hash64_store_hpte1(env, pte_offset, new_pte1); +ppc_hash64_store_hpte(env, pte_offset / HASH_PTE_SIZE_64, + pte.pte0, new_pte1); } /* 7. Determine the real address from the PTE */ diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h index dc027f6d5264..3b6769ad130b 100644 --- a/target-ppc/mmu-hash64.h +++ b/target-ppc/mmu-hash64.h @@ -102,23 +102,17 @@ static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env, } } -static inline void ppc_hash64_store_hpte0(CPUPPCState *env, - hwaddr pte_offset, target_ulong pte0) +static inline void ppc_hash64_store_hpte(CPUPPCState *env, + target_ulong pte_index, + target_ulong pte0, target_ulong pte1) { +pte_index *= HASH_PTE_SIZE_64; if (env-external_htab) { -stq_p(env-external_htab + pte_offset, pte0); +stq_p(env-external_htab + pte_index, pte0); +stq_p(env-external_htab + pte_index + HASH_PTE_SIZE_64/2, pte1); } else { -stq_phys(env-htab_base + pte_offset, pte0); -} -} - -static inline void ppc_hash64_store_hpte1(CPUPPCState *env, - hwaddr pte_offset, target_ulong pte1) -{ -
[Qemu-devel] [PATCH RFC] target-ppc: support ibm, pa-features device property
We will use this later to disable Transactional memory in case of PR KVM Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- NOTE: PPC2_TM value may need update before merging this. hw/ppc/spapr.c | 42 ++ target-ppc/cpu.h| 2 ++ target-ppc/kvm_ppc.h| 10 ++ target-ppc/translate_init.c | 2 +- 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9241cdd2a86e..e6e3fc0a1b55 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -287,6 +287,46 @@ static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop, } while (0) +#define MAX_PA_FEATURES 23 +static void spapr_pa_features_skel(CPUState *cs, void *fdt) +{ +PowerPCCPU *cpu = POWERPC_CPU(cs); +CPUPPCState *env = cpu-env; +char pa_features[2 + MAX_PA_FEATURES]; + +/* + * We are currently using this only to disable P8 TM on PR. + * So don't add the property for any other case + */ +if (!(env-insns_flags2 PPC2_TM) || !kvm_is_pr(cs)) { +return; +} +memset(pa_features, 0, sizeof(pa_features)); +pa_features[0] = MAX_PA_FEATURES; +pa_features[1] = 0; /* We only support a attribute specifier type of 0 */ + +/* + * Linux kernel only looks at the below feature set + * Big Endian/Little Endian + */ +pa_features[2] |= 1 7; /* PPC_FEATURE_HAS_MMU */ +pa_features[2] |= 1 6; /* PPC_FEATURE_HAS_FPU */ +pa_features[2] |= 1 5; /* MMU_FTR_SLB */ +pa_features[2] |= 1 4; /* CPU_FTR_CTRL */ +pa_features[2] |= 1 1; /* CPU_FTR_NOEXECUTE */ + +pa_features[3] |= 1 6; /* CPU_FTR_NODSISRALIGN */ +pa_features[3] |= 1 5; /* MMU_FTR_CI_LARGE_PAGE */ + +pa_features[7] |= 1 7; /* CPU_FTR_REAL_LE */ + +/* pa_features[24] CPU_FTR_TM is disabled */ + +_FDT((fdt_property(fdt, ibm,pa-features, + pa_features, sizeof(pa_features; +return; +} + static void *spapr_create_fdt_skel(hwaddr initrd_base, hwaddr initrd_size, hwaddr kernel_size, @@ -463,6 +503,8 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, page_sizes_prop, page_sizes_prop_size))); } +spapr_pa_features_skel(cs, fdt); + _FDT((fdt_end_node(fdt))); } diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index b0f66e5104dd..cf83bc6c0e0b 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1876,6 +1876,8 @@ enum { PPC2_DBRX = 0x0010ULL, /* Book I 2.05 PowerPC specification */ PPC2_ISA205= 0x0020ULL, +/* Transaction Memory*/ +PPC2_TM= 0x0040ULL, #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \ PPC2_ISA205) diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index a65d34571914..a7c9384efc95 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -14,6 +14,7 @@ void kvmppc_init(void); #ifdef CONFIG_KVM +#include sysemu/kvm.h uint32_t kvmppc_get_tbfreq(void); uint64_t kvmppc_get_clockfreq(void); @@ -35,6 +36,11 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd); int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size); int kvmppc_reset_htab(int shift_hint); uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift); +static inline int kvm_is_pr(CPUState *cs) +{ +return (kvm_check_extension(cs-kvm_state, KVM_CAP_PPC_GET_PVINFO) == 1); +} + #endif /* !CONFIG_USER_ONLY */ int kvmppc_fixup_cpu(PowerPCCPU *cpu); bool kvmppc_has_cap_epr(void); @@ -159,6 +165,10 @@ static inline int kvmppc_update_sdr1(CPUPPCState *env) return 0; } +static inline int kvm_is_pr(CPUState *cs) +{ +return false; +} #endif /* !CONFIG_USER_ONLY */ static inline int kvmppc_fixup_cpu(PowerPCCPU *cpu) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index c030a2032a0f..f41e6b1bdd32 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7312,7 +7312,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC_64B | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; -pcc-insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX; +pcc-insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_TM; pcc-msr_mask = 0x8284FF36ULL; pcc-mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) -- 1.8.5.3
Re: [Qemu-devel] [PATCH] vnc: Fix qemu crashed when vnc client disconnect suddenly
Ping... Best regards, -Gonglei -Original Message- From: Gonglei (Arei) Sent: Thursday, January 23, 2014 9:31 PM To: qemu-devel@nongnu.org Cc: 'aligu...@amazon.com'; Luonengjun; Huangweidong (Hardware); 'Gerd Hoffmann' Subject: [PATCH] vnc: Fix qemu crashed when vnc client disconnect suddenly Hi, When I use RealVNC viewer client (http://www.realvnc.com/) to connect vnc server, the client disconnect suddenly, and I click reconnect button immediately, then the Qemu crashed. In the function vnc_worker_thread_loop, will call vnc_async_encoding_start to set the local vs-output buffer by global queue's buffer. Then send rectangles to the vnc client call function vnc_send_framebuffer_update. Finally, Under normal circumstances, call vnc_async_encoding_end to set the global queue'buffer by the local vs-output conversely. When the vnc client disconnect, the job-vs-csock will be set to -1. And the current prcoess logic will goto disconnected partion without call function vnc_async_encoding_end. But, the function vnc_send_framebuffer_update will call buffer_reserve, which maybe call g_realloc reset the local vs's buffer, meaning the global queue's buffer is modified also. If anyone use the original global queue's buffer memory will cause corruption and then crash qemu. This patch assure the function vnc_async_encoding_end being called even though the vnc client disconnect suddenly. Signed-off-by: Gonglei arei.gong...@huawei.com --- ui/vnc-jobs.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index 2d3fce8..ae9816c 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -252,6 +252,8 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) if (job-vs-csock == -1) { vnc_unlock_display(job-vs-vd); +/* Copy persistent encoding data */ +vnc_async_encoding_end(job-vs, vs); goto disconnected; } @@ -278,6 +280,9 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) vnc_async_encoding_end(job-vs, vs); qemu_bh_schedule(job-vs-bh); +} else { +/* Copy persistent encoding data */ +vnc_async_encoding_end(job-vs, vs); } vnc_unlock_output(job-vs); -- 1.6.0.2 Best regards, -Gonglei
Re: [Qemu-devel] [PATCH v3] migration:fix free XBZRLE decoded_buf wrong
Ping... Best regards, -Gonglei -Original Message- From: Gonglei (Arei) Sent: Thursday, January 23, 2014 3:47 PM To: qemu-devel@nongnu.org Cc: 'Orit Wasserman'; qemu-devel@nongnu.org; Peter Maydell; anth...@codemonkey.ws; pbonz...@redhat.com; Luonengjun; chenliang (T); Huangweidong (Hardware); 'Eric Blake' Subject: [PATCH v3] migration:fix free XBZRLE decoded_buf wrong When qemu do live migration with xbzrle, qemu malloc decoded_buf at destination end but free it at source end. It will crash qemu by double free error in some scenarios. Splitting the XBZRLE structure for clear logic distinguishing src/dst side. Signed-off-by: ChenLiang chenlian...@huawei.com Reviewed-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Orit Wasserman owass...@redhat.com Signed-off-by: GongLei arei.gong...@huawei.com --- Changes: * Removing excess check for g_free * The structure of XBZRLE is split into two halves. * Modify patch format arch_init.c | 23 ++- include/migration/migration.h |1 + migration.c |1 + 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/arch_init.c b/arch_init.c index 77912e7..dd777f3 100644 --- a/arch_init.c +++ b/arch_init.c @@ -164,17 +164,15 @@ static struct { uint8_t *encoded_buf; /* buffer for storing page content */ uint8_t *current_buf; -/* buffer used for XBZRLE decoding */ -uint8_t *decoded_buf; /* Cache for XBZRLE */ PageCache *cache; } XBZRLE = { .encoded_buf = NULL, .current_buf = NULL, -.decoded_buf = NULL, .cache = NULL, }; - +/* buffer used for XBZRLE decoding */ +static uint8_t *xbzrle_decoded_buf; int64_t xbzrle_cache_resize(int64_t new_size) { @@ -602,6 +600,12 @@ uint64_t ram_bytes_total(void) return total; } +void free_xbzrle_decoded_buf(void) +{ +g_free(xbzrle_decoded_buf); +xbzrle_decoded_buf = NULL; +} + static void migration_end(void) { if (migration_bitmap) { @@ -615,8 +619,9 @@ static void migration_end(void) g_free(XBZRLE.cache); g_free(XBZRLE.encoded_buf); g_free(XBZRLE.current_buf); -g_free(XBZRLE.decoded_buf); XBZRLE.cache = NULL; +XBZRLE.encoded_buf = NULL; +XBZRLE.current_buf = NULL; } } @@ -807,8 +812,8 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) unsigned int xh_len; int xh_flags; -if (!XBZRLE.decoded_buf) { -XBZRLE.decoded_buf = g_malloc(TARGET_PAGE_SIZE); +if (!xbzrle_decoded_buf) { +xbzrle_decoded_buf = g_malloc(TARGET_PAGE_SIZE); } /* extract RLE header */ @@ -825,10 +830,10 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) return -1; } /* load data and decode */ -qemu_get_buffer(f, XBZRLE.decoded_buf, xh_len); +qemu_get_buffer(f, xbzrle_decoded_buf, xh_len); /* decode RLE */ -ret = xbzrle_decode_buffer(XBZRLE.decoded_buf, xh_len, host, +ret = xbzrle_decode_buffer(xbzrle_decoded_buf, xh_len, host, TARGET_PAGE_SIZE); if (ret == -1) { fprintf(stderr, Failed to load XBZRLE page - decode error!\n); diff --git a/include/migration/migration.h b/include/migration/migration.h index bfa3951..3e1e6c7 100644 --- a/include/migration/migration.h +++ b/include/migration/migration.h @@ -109,6 +109,7 @@ MigrationState *migrate_get_current(void); uint64_t ram_bytes_remaining(void); uint64_t ram_bytes_transferred(void); uint64_t ram_bytes_total(void); +void free_xbzrle_decoded_buf(void); void acct_update_position(QEMUFile *f, size_t size, bool zero); diff --git a/migration.c b/migration.c index 7235c23..3d46804 100644 --- a/migration.c +++ b/migration.c @@ -105,6 +105,7 @@ static void process_incoming_migration_co(void *opaque) ret = qemu_loadvm_state(f); qemu_fclose(f); +free_xbzrle_decoded_buf(); if (ret 0) { fprintf(stderr, load of migration failed\n); exit(EXIT_FAILURE); -- 1.6.0.2 Best regards, -Gonglei
Re: [Qemu-devel] [PATCH 05/24] target-arm: Add exception level to the AArch64 TB flags
On 28 January 2014 01:28, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Wed, Jan 22, 2014 at 6:12 AM, Peter Maydell peter.mayd...@linaro.org wrote: We already implicitly rely on the exception level being part of the TB flags for coprocessor access, Maybe that's the issue? Why not just treat the exception level as state like any other and generate the TCG to just check it at execution time? That would be ferociously expensive, because am I privileged or not? is baked into every single guest load or store. Including privilege level in the tb flags is standard for every target CPU we have. thanks -- PMM
Re: [Qemu-devel] [PATCH 07/24] target-arm: A64: Make cache ID registers visible to AArch64
On 28 January 2014 01:46, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: There seem to be multiple instances in this series where you fallback to open coded R/W accessor functions for the sake of access checks. Is it better to define a bool check_access() fn hook in ARMCPRegInfo and leave the actual write/read behaviour to the data driven mechanisms? This may also minimise the need for raw_write hook usages as it serves to isolate the actual state change into its own self contained definition (whether open coded or not). Yes, I think it's probably going to be better to do that. We may need to make it more than just bool, though since for AArch64 the kind of exception can be different I think -- the specific syndrome information can vary. thanks -- PMM
Re: [Qemu-devel] [PATCH 11/24] target-arm: Implement AArch64 DAIF system register
On 28 January 2014 01:54, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Wed, Jan 22, 2014 at 6:12 AM, Peter Maydell peter.mayd...@linaro.org wrote: Implement the DAIF system register which is a view of the DAIF bits in PSTATE. TODO: include support for the MSR_i encodings? Isn't this already separately handled by the MSR_i implementation? Yes, just a stray TODO I forgot to delete from the commit message. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Otherwise: Reviewed-by: Peter Crosthwaite peter.crosthwa...@xilinx.com thanks -- PMM
[Qemu-devel] [PATCH] vfio: correct debug macro typo
Change to VFIO_DEBUG in vfio_msi_interrupt() for debug messages to get printed Signed-off-by: Bandan Das b...@redhat.com --- hw/misc/vfio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 9aecaa8..a87078c 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -592,7 +592,7 @@ static void vfio_msi_interrupt(void *opaque) return; } -#ifdef VFIO_DEBUG +#ifdef DEBUG_VFIO MSIMessage msg; if (vdev-interrupt == VFIO_INT_MSIX) { -- 1.8.3.1
Re: [Qemu-devel] [PATCH 19/24] target-arm: Implement AArch64 TTBR*
On 28 January 2014 02:07, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Sat, Jan 25, 2014 at 10:09 AM, Peter Maydell peter.mayd...@linaro.org wrote: On 24 January 2014 23:44, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Wed, Jan 22, 2014 at 6:12 AM, Peter Maydell peter.mayd...@linaro.org wrote: +static int vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +/* 64 bit accesses to the TTBRs can change the ASID and so we + * must flush the TLB. + */ +if ((ri-state == ARM_CP_STATE_AA64) || (ri-type ARM_CP_64BIT)) { +tlb_flush(env, 1); +} With the level of complexity this if has reached, is it better to just check for this ASID change rather than make this overly conservative flush? Adding an is the ASID the same would make the check more complicated again. Maybe we should do it but I'd rather keep that separate from the handle 64 bit formats patches. Seems similar compexity to me. Well, you'd need all the checks we have here, plus another condition for the ASID match: if (((ri-state == ARM_CP_STATE_AA64) || (ri-type ARM_CP_64BIT)) (value some_mask != old_value some_mask)) { tlb_flush(env, 1); } thanks -- PMM
Re: [Qemu-devel] [RFC PATCH v4 3/8] arm_gic: Fix GIC pending behavior
On 28 January 2014 02:09, Christoffer Dall christoffer.d...@linaro.org wrote: On Sun, Jan 19, 2014 at 07:49:58PM +, Peter Maydell wrote: So this means we now have two lots of pending state, the pending and sw_pending fields. I think this is not in fact correct, and there is only one lot of state in a real h/w GIC (it's that flipflop). AIUI the correct behaviour is: * GIC_TEST_PENDING() should read: ((s-irq_state[irq].pending (cm) != 0) || (!GIC_TEST_EDGE_TRIGGER(irq) GIC_TEST_LEVEL(irq, cm)) -- this corresponds to the OR gate in fig 4-10; this is the value to be used in reads from ICPENDR/ISPENDR and other is this interrupt pending checks like the one in gic_update() * in gic_set_irq(), if level is 1 (rising edge) we GIC_SET_PENDING only if the interrupt is edge-triggered (pending status isn't latched for level triggered interrupts). We always GIC_SET_LEVEL(irq, 1). * in gic_set_irq(), if level is 0 (falling edge) we don't touch the pending state, but just GIC_SET_LEVEL(irq, 0) * gic_acknowledge_irq() always does a GIC_CLEAR_PENDING() (this won't actually make a level-triggered interrupt be not pending because of the second clause of our updated GIC_TEST_PENDING) * writes to the I[CS]PENDR registers always result in GIC_SET_PENDING or GIC_CLEAR_PENDING calls (updating the latch state) ok, it's probably cleaner code-wise, but should produce the same result as far as I can see. I guess I see the pending field as the result of the final or-gate (possibly because I'm too tied to the way the in-kernel emulation works where we don't have a separate 'level' state). Anyway, I'll respin the patch according to your directions (my only concern with that is that it feels a bit unlogical to have a bitfield called pending where some of the bits are not set despite the corresponding interrupts being pending, but we'll see if the overall code looks more clean with this approach). The key thing is that we definitely shouldn't be keeping more state than the hardware does; that's always a bad sign. thanks -- PMM
Re: [Qemu-devel] KVM and variable-endianness guest CPUs
On 01/22/2014 12:22 PM, Peter Maydell wrote: On 22 January 2014 05:39, Victor Kamensky victor.kamen...@linaro.org wrote: Hi Guys, Christoffer and I had a bit heated chat :) on this subject last night. Christoffer, really appreciate your time! We did not really reach agreement during the chat and Christoffer asked me to follow up on this thread. Here it goes. Sorry, it is very long email. I don't believe we can assign any endianity to mmio.data[] byte array. I believe mmio.data[] and mmio.len acts just memcpy and that is all. As memcpy does not imply any endianity of underlying data mmio.data[] should not either. This email is about five times too long to be actually useful, but the major issue here is that the data being transferred is not just a bag of bytes. The data[] array plus the size field are being (mis)used to indicate that the memory transaction is one of: * an 8 bit access * a 16 bit access of some uint16_t value * a 32 bit access of some uint32_t value * a 64 bit access of some uint64_t value exactly as a CPU hardware bus would do. It's because the API is defined in this awkward way with a uint8_t[] array that we need to specify how both sides should go from the actual properties of the memory transaction (value and size) to filling in the array. That is not how x86 hardware works. Back when there was a bus, there were no address lines A0-A2; instead we had 8 byte enables BE0-BE7. A memory transaction placed the qword address on the address lines and asserted the byte enables for the appropriate byte, word, dword, or qword, shifted for the low order bits of the address. If you generated an unaligned access, the transaction was split into two, so an 8-byte write might appear as a 5-byte write followed by a 3-byte write. In fact, the two halves of the transaction might go to different devices, or one might go to a device and another to memory. PCI works the same way. Furthermore, device endianness is entirely irrelevant for deciding the properties of mmio.data[], because the thing we're modelling here is essentially the CPU-bus interface. In real hardware, the properties of individual devices on the bus are irrelevant to how the CPU's interface to the bus behaves, and similarly here the properties of emulated devices don't affect how KVM's interface to QEMU userspace needs to work. MemoryRegion's 'endianness' field, incidentally, is a dreadful mess that we should get rid of. It is attempting to model the property that some buses/bridges have of doing byte-lane-swaps on data that passes through as a property of the device itself. It would be better if we modelled it properly, with container regions having possible byte-swapping and devices just being devices. No, that is not what it is modelling. Suppose a little endian cpu writes a dword 0x12345678 to address 0 of a device, and read back a byte from address 0. What value do you read back? Some (most) devices will return 0x78, others will return 0x12. Other devices don't support mixed sizes at all, but many do. PCI configuration space is an example; it is common to read both Device ID and Vendor ID with a single 32-bit transaction, but you can also read them separately with two 16-bit transaction. Because PCI is little-endian, the Vendor ID at address 0 will be returned as the low word of the 32-bit read of a little-endian processor. If you remove device endianness from memory regions, you have to pass the data as arrays of bytes (like the KVM interface) and let the device assemble words from those bytes itself, taking into consideration its own endianness. What MemoryRegion's endianness does is let the device declare its endianness to the API and let it do all the work.
Re: [Qemu-devel] [Qemu-ppc] KVM and variable-endianness guest CPUs
On 01/28/2014 01:27 AM, Benjamin Herrenschmidt wrote: On Wed, 2014-01-22 at 17:29 +, Peter Maydell wrote: Basically if it would be on real bus, get byte value that corresponds to phys_addr + 0 address place it into data[0], get byte value that corresponds to phys_addr + 1 address place it into data[1], etc. This just isn't how real buses work. Actually it can be :-) There is no address + 1, address + 2. There is a single address for the memory transaction and a set of data on data lines and some separate size information. How the device at the far end of the bus chooses to respond to 32 bit accesses to address X versus 8 bit accesses to addresses X through X+3 is entirely its own business and unrelated to the CPU. However the bus has a definition of what byte lane is the lowest in address order. Byte order invariance is an important function of all busses. I think that trying to treat it any differently than an address ordered series of bytes is going to turn into a complete and inextricable mess. I agree. The two options are: (address, byte array, length) and (address, value, word size, endianness) the first is the KVM ABI, the second is how MemoryRegions work. Both are valid, but the first is more general (supports the 3-byte accesses sometimes generated on x86). (It would be perfectly possible to have a device which when you read from address X as 32 bits returned 0x12345678, when you read from address X as 16 bits returned 0x9abc, returned 0x42 for an 8 bit read from X+1, and so on. Having byte reads from X..X+3 return values corresponding to parts of the 32 bit access is purely a convention.) Right, it's possible. It's also stupid and not how most modern devices and busses work. Besides there is no reason why that can't be implemented with Victor proposal anyway. Right.
Re: [Qemu-devel] [PATCH 0/2] Remove unsupported / empty .bdrv_make_empty functions
Am 27.01.2014 um 22:09 hat Jeff Cody geschrieben: QED and QCOW2 both have .bdrv_make_empty stubs that do nothing. In the case of QED, it returns an error (-ENOTSUP), which causes problems with bdrv_commit(). This removes those stubs. Jeff Cody (2): block: remove QED .bdrv_make_empty implementation block: remove qcow2 .bdrv_make_empty implementation Reviewed-by: Kevin Wolf kw...@redhat.com
Re: [Qemu-devel] [PATCH target-arm v5 4/5] arm: Implement reset GPIO.
On 28 January 2014 00:48, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Tue, Jan 28, 2014 at 3:52 AM, Peter Maydell peter.mayd...@linaro.org wrote: On 15 January 2014 09:14, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: Implement a reset GPIO for ARM CPUs. This allows individual reset of ARM CPUs from device land without the need for the much unwanted reset API calls. The CPU is halted as long as the pin is held in reset. Releasing the reset starts the CPU running again. +static void arm_cpu_reset_gpio(void *opaque, int irq, int level) +{ +CPUState *cpu = opaque; + +if (level) { +cpu_reset(cpu); +cpu_interrupt(cpu, CPU_INTERRUPT_HALT); +} else { +cpu_reset_interrupt(cpu, CPU_INTERRUPT_HALT); +cpu_interrupt(cpu, CPU_INTERRUPT_EXITTB); +} +} I don't think this will work properly. For instance, cpu_exec() will bring the CPU out of halt if an inbound interrupt arrives, but we should stay in reset until the reset line is deasserted. I see. I guess I'm going to have to save the reset pin state as a boolean in CPU state (and I guess that means is should be migratable). Then inhibit the true return from cpu_has_work when the pin is asserted. Maybe we can do it with a CPU_INTERRUPT_RESET ? Also ideally speaking we should probably do the reset actions on the falling edge of reset, not the rising edge. Any particular reason? I would have thought that any externally visible state would best be reset ASAP. For level sensitive behavior, the transitionals should happen going into the active level. Unless ARM CPU resets are actually falling edge sensitive (in which case the CPU would continue to run while the reset is held). I'm not an expert here, but what I thought happened was: * on asserting edge of reset CPU stops running and starts resetting its internal state * on real hardware you have to hold the line asserted for N clocks for this to finish * on deasserting edge of reset, CPU samples config lines and starts running again so you should be able to say 'assert reset; change state of configuration signals; deassert reset', for instance. (On QEMU that would probably be 'assert reset; change r/w QOM properties; deassert reset'). Slightly less theoretically, M-class CPUs do the initial read of the PC from memory in cpu_reset(), so if you do that on asserting edge then you prevent hold CPU in reset and modify the vector table before releasing CPU. So at least some of what we do in cpu_reset() ought I think to be done only on deasserting; unless you really want to split reset into two phases, it seems easiest just to hold the CPU not-running while reset is asserted and call cpu_reset() when it is deasserted. Does this work properly when we're running under KVM rather than using the TCG CPU? I must confess no, I explicitly LOG_UNIMP for KVM, as I have no means to develop or test ARM KVM. I definitely don't want to take this if it doesn't cope with KVM. I guess I'll have to take a look at how that would work. Is there anything really ARM-specific in this reset_gpio function, or could it be implemented at a common level for all target architectures? Not yet, but probably will be ARM specific once I add the cpu reset pin state. Unless Andreas is happy for that pin state and all this code to go up to the base TYPE_CPU class. It might be possible for most of the mechanics to be shared (CPU_INTERRUPT_RESET and what setting/clearing it does), just not the gpio pin. I wonder however, whether different arch will have level/edge/high/low variances in reset behavior that must be accommodated. Mmm. thanks -- PMM
[Qemu-devel] [PATCH] qga: Don't require 'time' argument in guest-set-time command
As the description to the guest-set-time states, the command is there to ease time synchronization after resume. If guest was suspended for longer period of time, its system time can go off so badly, that even NTP refuses to set it. That's why the command was invented: to give users chance to set the time (not necessarily 100% correct). However, there's is no real need for us to require users to pass an arbitrary time. Especially if we can read the correct value from RTC (boiling down to reading host's time). Hence this commit enables logic: guest-set-time() == guest-set-time($now_from_rtc) Signed-off-by: Michal Privoznik mpriv...@redhat.com --- Notes: I wasn't sure about enforcing Windows to fetch time from RTC. But I've found this site [1] which seems to presume that GetSystemTime() reads RTC. Although within the page you'll find GetSystemTimeAsFileTime() which is the same except returned time is in different format. That's all. 1: http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking qga/commands-posix.c | 40 qga/commands-win32.c | 33 ++--- qga/qapi-schema.json | 9 + 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 8100bee..6d36ab5 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -142,7 +142,7 @@ int64_t qmp_guest_get_time(Error **errp) return time_ns; } -void qmp_guest_set_time(int64_t time_ns, Error **errp) +void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) { int ret; int status; @@ -150,22 +150,28 @@ void qmp_guest_set_time(int64_t time_ns, Error **errp) Error *local_err = NULL; struct timeval tv; -/* year-2038 will overflow in case time_t is 32bit */ -if (time_ns / 10 != (time_t)(time_ns / 10)) { -error_setg(errp, Time % PRId64 is too large, time_ns); -return; +/* If user has passed a time, validate and set it. */ +if (has_time) { +/* year-2038 will overflow in case time_t is 32bit */ +if (time_ns / 10 != (time_t)(time_ns / 10)) { +error_setg(errp, Time % PRId64 is too large, time_ns); +return; +} + +tv.tv_sec = time_ns / 10; +tv.tv_usec = (time_ns % 10) / 1000; + +ret = settimeofday(tv, NULL); +if (ret 0) { +error_setg_errno(errp, errno, Failed to set time to guest); +return; +} } -tv.tv_sec = time_ns / 10; -tv.tv_usec = (time_ns % 10) / 1000; - -ret = settimeofday(tv, NULL); -if (ret 0) { -error_setg_errno(errp, errno, Failed to set time to guest); -return; -} - -/* Set the Hardware Clock to the current System Time. */ +/* Now, if user has passed a time to set and the system time is set, we + * just need to synchronize the hardware clock. However, if no time was + * passed, user is requesting the opposite: set the system time from the + * hardware clock. */ pid = fork(); if (pid == 0) { setsid(); @@ -173,7 +179,9 @@ void qmp_guest_set_time(int64_t time_ns, Error **errp) reopen_fd_to_null(1); reopen_fd_to_null(2); -execle(/sbin/hwclock, hwclock, -w, NULL, environ); +/* Use '/sbin/hwclock -w' to set RTC from the system time, + * or '/sbin/hwclock -s' to set the system time from RTC. */ +execle(/sbin/hwclock, hwclock, has_time ? -w : -s, NULL, environ); _exit(EXIT_FAILURE); } else if (pid 0) { error_setg_errno(errp, errno, failed to create child process); diff --git a/qga/commands-win32.c b/qga/commands-win32.c index a6a0af2..9ce89ce 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -370,25 +370,36 @@ int64_t qmp_guest_get_time(Error **errp) return time_ns; } -void qmp_guest_set_time(int64_t time_ns, Error **errp) +void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) { SYSTEMTIME ts; FILETIME tf; LONGLONG time; -if (time_ns 0 || time_ns / 100 INT64_MAX - W32_FT_OFFSET) { -error_setg(errp, Time % PRId64 is invalid, time_ns); -return; -} +if (has_time) { +/* Okay, user passed a time to set. Validate it. */ +if (time_ns 0 || time_ns / 100 INT64_MAX - W32_FT_OFFSET) { +error_setg(errp, Time % PRId64 is invalid, time_ns); +return; +} -time = time_ns / 100 + W32_FT_OFFSET; +time = time_ns / 100 + W32_FT_OFFSET; -tf.dwLowDateTime = (DWORD) time; -tf.dwHighDateTime = (DWORD) (time 32); +tf.dwLowDateTime = (DWORD) time; +tf.dwHighDateTime = (DWORD) (time 32); -if (!FileTimeToSystemTime(tf, ts)) { -error_setg(errp, Failed to convert system time %d, (int)GetLastError()); -
Re: [Qemu-devel] [PATCH target-arm v5 4/5] arm: Implement reset GPIO.
Hi, Am 28.01.2014 01:48, schrieb Peter Crosthwaite: On Tue, Jan 28, 2014 at 3:52 AM, Peter Maydell peter.mayd...@linaro.org wrote: Is there anything really ARM-specific in this reset_gpio function, or could it be implemented at a common level for all target architectures? Not yet, but probably will be ARM specific once I add the cpu reset pin state. Unless Andreas is happy for that pin state and all this code to go up to the base TYPE_CPU class. I wonder however, whether different arch will have level/edge/high/low variances in reset behavior that must be accommodated. Andreas, you want this in CPU or should we leave it here in ARM land? I'm currently swimming in work, so haven't really reviewed this yet... If you have a good solution that requires additions to common CPU state then so be it. However, keep in mind that for x86 at least we need to remain migration-compatible, so state additions would need to go into an optional VMState subsection for backwards compatibility. Regards, Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v17 00/10] Shared library module support
Ping? This version has a slight conflict with current qemu.git. Do you want a respin, Paolo? Thanks, Fam On Thu, 01/16 17:48, Fam Zheng wrote: Many thanks for everyones testing and debugging! v17: [01/10] util: Split out qemu_exec_dir from os_find_datadir New. Used in 07 for module searching. [07/10] module: implement module loading Probe for shasum, sha1sum or sha1 in configure. (PMM, Paolo) Search modules in relative paths (./ and ../) of program. (PMM) This makes testing much easier for developers. And end users are safe with the protection of stamp check. Improved error message. Print to stderr when a module is not found. (PMM) Fam Zheng (9): util: Split out qemu_exec_dir from os_find_datadir rules.mak: fix $(obj) to a real relative path rules.mak: allow per object cflags and libs block: use per-object cflags and libs build-sys: introduce common-obj-m and block-obj-m for DSO module: implement module loading Makefile: install modules with make install .gitignore: ignore module related files (dll, so, mo) block: convert block drivers linked with libs to modules Paolo Bonzini (1): darwin: do not use -mdynamic-no-pic .gitignore| 3 ++ Makefile | 30 ++- Makefile.objs | 19 ++- Makefile.target | 21 ++-- block/Makefile.objs | 13 - configure | 91 --- include/qemu/module.h | 18 ++- include/qemu/osdep.h | 4 ++ module-common.c | 10 os-posix.c| 40 +++--- os-win32.c| 19 +-- rules.mak | 81 +++- scripts/create_config | 14 + util/module.c | 145 +- util/oslib-posix.c| 45 util/oslib-win32.c| 24 + 16 files changed, 457 insertions(+), 120 deletions(-) create mode 100644 module-common.c -- 1.8.5.3
Re: [Qemu-devel] fix/re-do query-command-line-options
Amos Kong ak...@redhat.com writes: Hi QEMU/Libvirt list, When I worked on query-command-line-options, I first used some marcos [1] to generate two config option tables. This will cover all the options, but it returns a string, it's difficult for libvirt to parse and use it. Finally I got a suggestion to read info from new interface (QemuOpts), We add opts info to vm_config_groups[], query-command-line-options will visit the array. It doesn't conver all the options, but the latest options are covered, so this implementation is acceptable. Problem: * QemuOpts was designed just for options with parameter, some new option without parameters is lost in query output (eg: -enable-fips) Yes, and that's an issue not just for query-command-line-options, but also for -writeconfig / -readconfig. * block drive uses three QemuOpts, it's legacy issue. Code goes into contortions to extend the old option without breaking it. Part of the contortions is your commit 968854c, which adds special-case code to make the -drive's parameters visible in query-command-line-options again, after commit 0006383 made them invisible. More on the invisible parameters problem below. * QemuOpts of some options aren't updated, it might be difficult to updated when we add some new parameters What do you have in mind here? * other Here's one: QemuOpts *sucks* :) Apart from its general suckage, which has been discussed at some length elsewhere, it sucks as a schema, because it's not nearly expressive enough. With QemuOpts, we can basically enumerate acceptable keys and how their values should be parsed, plus a few extras like an implied key. On value parsing, all we have is on/off, uint64_t in decimal, uint64_t in fancy size syntax, and anything. This is both more and less than a QAPI schema. It's more, because it specifies both type (e.g. uint64_t) and external syntax (e.g. decimal). It's less, because it has fewer basic types, and no composite types. On acceptable keys, all we can do is a list fixed at compile-time. We can't express discriminated unions, such as when key type has value tap, then keys ... are acceptable, when it has value bridge, then keys ... are acceptable, and so forth. We routinely do that in QAPI schemata. We can't collect acceptable keys at run-time. For instance, -device accepts general keys id, bus, and a discriminated union of device model properties, with discriminator driver. But the available device models and their properties are only known at runtime. When we need something like that (and we need it often), we give up and specify any key=value accepted, leaving the actual checking to the code using the option. All command line introspection can see then is the option exists, and it takes a key=value,... argument. Which borders on useless. Options that have this issue now: -acpitable, -smbios, -netdev, -net, -device, -object. Note that several of these are fairly new, which makes me expect more of them. -drive isn't on this list only because your commit 968854c got it off the list after commit 0006383 got it on it. QAPI schema can't yet solve this problem, either. That's why it doesn't cover -device / device_add. Since all QMP commands need to be covered, and QMP surely needs a command to plug devices, the problem will have to be solved there eventually. We discussed to reimplement this command, but it seems DEF maroc is the only point to cover all the options, all the options are described in qemu-options.hx I'm considering to reuse the DEF marocs to generate a table, try to return the crude info if QemuOpts doesn't cover it. Or maintain a split array (like vm_config_groups[]), it only contains the option without parameter (option name help info). I think the data you can usefully collect with this approach is approximately the data getopt_long()[*] gets: list of named command line options, and whether they take an argument. You can use this data to fill in options not covered by QemuOpts. This is a definite improvement. It still falls short of fully solving the command line introspection problem. However, I'm not into rejecting imperfect incremental improvements we can have now in favor of perfect solutions we can maybe have some day. Go right ahead with your incremental improvement! If you touched some problem of the query-command-line-options, welcome to reply it, I will try to satisfy your requests. Thanks, Amos [1] http://www.redhat.com/archives/libvir-list/2013-January/msg01656.html [*] Which we don't use, because we prefer our command line idiosyncratic.
[Qemu-devel] [PATCH 04/42] console: export QemuConsole index, width, height
Add functions to query QemuConsole properties. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/console.h | 3 +++ ui/console.c | 24 2 files changed, 27 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index 4156a87..8543d18 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -289,6 +289,9 @@ QemuConsole *qemu_console_lookup_by_device(DeviceState *dev); bool qemu_console_is_visible(QemuConsole *con); bool qemu_console_is_graphic(QemuConsole *con); bool qemu_console_is_fixedsize(QemuConsole *con); +int qemu_console_get_index(QemuConsole *con); +int qemu_console_get_width(QemuConsole *con, int fallback); +int qemu_console_get_height(QemuConsole *con, int fallback); void text_consoles_set_display(DisplayState *ds); void console_select(unsigned int index); diff --git a/ui/console.c b/ui/console.c index 502e160..0bbefe5 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1641,6 +1641,30 @@ bool qemu_console_is_fixedsize(QemuConsole *con) return con (con-console_type != TEXT_CONSOLE); } +int qemu_console_get_index(QemuConsole *con) +{ +if (con == NULL) { +con = active_console; +} +return con ? con-index : -1; +} + +int qemu_console_get_width(QemuConsole *con, int fallback) +{ +if (con == NULL) { +con = active_console; +} +return con ? surface_width(con-surface) : fallback; +} + +int qemu_console_get_height(QemuConsole *con, int fallback) +{ +if (con == NULL) { +con = active_console; +} +return con ? surface_height(con-surface) : fallback; +} + static void text_console_set_echo(CharDriverState *chr, bool echo) { QemuConsole *s = chr-opaque; -- 1.8.3.1
[Qemu-devel] [PATCH 03/42] sdl2: remove text console logic
sdl2 explicitly binds windows to graphics consoles. No need to handle non-graphic consoles anywhere. Also console switching is pointless. Zap code. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/sdl2.c | 117 +- 1 file changed, 8 insertions(+), 109 deletions(-) diff --git a/ui/sdl2.c b/ui/sdl2.c index 2eb3e9c..e7a30b3 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -345,7 +345,7 @@ static void sdl_show_cursor(void) if (!cursor_hide) return; -if (!kbd_mouse_is_absolute() || !qemu_console_is_graphic(NULL)) { +if (!kbd_mouse_is_absolute()) { SDL_ShowCursor(1); if (guest_cursor (gui_grab || kbd_mouse_is_absolute() || absolute_enabled)) @@ -402,9 +402,7 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) if (kbd_mouse_is_absolute()) { if (!absolute_enabled) { absolute_enabled = 1; -if (qemu_console_is_graphic(NULL)) { -absolute_mouse_grab(sdl2_console[0]); -} +absolute_mouse_grab(sdl2_console[0]); } } else if (absolute_enabled) { if (!gui_fullscreen) { @@ -495,7 +493,7 @@ static void toggle_full_screen(struct sdl2_console_state *scon) } else { do_sdl_resize(scon, width, height, 0); } -if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) { +if (!gui_saved_grab) { sdl_grab_end(scon); } } @@ -535,26 +533,6 @@ static void handle_keydown(SDL_Event *ev) } gui_keysym = 1; break; -case 0x02 ... 0x0a: /* '1' to '9' keys */ -/* Reset the modifiers sent to the current console */ -reset_keys(); -console_select(keycode - 0x02); -gui_keysym = 1; -if (gui_fullscreen) { -break; -} -if (!qemu_console_is_graphic(NULL)) { -/* release grab if going to a text console */ -if (gui_grab) { -sdl_grab_end(scon); -} else if (absolute_enabled) { -sdl_show_cursor(); -} -} else if (absolute_enabled) { -sdl_hide_cursor(); -absolute_mouse_grab(scon); -} -break; case 0x1b: /* '+' */ case 0x35: /* '-' */ if (!gui_fullscreen) { @@ -575,79 +553,8 @@ static void handle_keydown(SDL_Event *ev) default: break; } -} else if (!qemu_console_is_graphic(NULL)) { -int keysym = ev-key.keysym.sym; - -if (ev-key.keysym.mod (KMOD_LCTRL | KMOD_RCTRL)) { -switch (ev-key.keysym.sym) { -case SDLK_UP: -keysym = QEMU_KEY_CTRL_UP; -break; -case SDLK_DOWN: -keysym = QEMU_KEY_CTRL_DOWN; -break; -case SDLK_LEFT: -keysym = QEMU_KEY_CTRL_LEFT; -break; -case SDLK_RIGHT: -keysym = QEMU_KEY_CTRL_RIGHT; -break; -case SDLK_HOME: -keysym = QEMU_KEY_CTRL_HOME; -break; -case SDLK_END: -keysym = QEMU_KEY_CTRL_END; -break; -case SDLK_PAGEUP: -keysym = QEMU_KEY_CTRL_PAGEUP; -break; -case SDLK_PAGEDOWN: -keysym = QEMU_KEY_CTRL_PAGEDOWN; -break; -default: -break; -} -} else { -switch (ev-key.keysym.sym) { -case SDLK_UP: -keysym = QEMU_KEY_UP; -break; -case SDLK_DOWN: -keysym = QEMU_KEY_DOWN; -break; -case SDLK_LEFT: -keysym = QEMU_KEY_LEFT; -break; -case SDLK_RIGHT: -keysym = QEMU_KEY_RIGHT; -break; -case SDLK_HOME: -keysym = QEMU_KEY_HOME; -break; -case SDLK_END: -keysym = QEMU_KEY_END; -break; -case SDLK_PAGEUP: -keysym = QEMU_KEY_PAGEUP; -break; -case SDLK_PAGEDOWN: -keysym = QEMU_KEY_PAGEDOWN; -break; -case SDLK_BACKSPACE: -keysym = QEMU_KEY_BACKSPACE; -break; -case SDLK_DELETE: -keysym = QEMU_KEY_DELETE; -break; -default: -break; -} -} -if (keysym) { -kbd_put_keysym(keysym); -} } -if (qemu_console_is_graphic(NULL) !gui_keysym) { +if (!gui_keysym) { sdl_process_key(ev-key); } } @@ -667,9 +574,7 @@ static void
[Qemu-devel] [PATCH 14/42] input: keyboard: switch sdl ui to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/sdl.c | 27 +-- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/ui/sdl.c b/ui/sdl.c index 736bb95..c3b8036 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -32,6 +32,7 @@ #include qemu-common.h #include ui/console.h +#include ui/input.h #include sysemu/sysemu.h #include x_keymap.h #include sdl_zoom.h @@ -263,9 +264,7 @@ static void reset_keys(void) int i; for(i = 0; i 256; i++) { if (modifiers_state[i]) { -if (i SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -kbd_put_keycode(i | SCANCODE_UP); +qemu_input_event_send_key_number(dcl-con, i, false); modifiers_state[i] = 0; } } @@ -273,16 +272,12 @@ static void reset_keys(void) static void sdl_process_key(SDL_KeyboardEvent *ev) { -int keycode, v; +int keycode; if (ev-keysym.sym == SDLK_PAUSE) { /* specific case */ -v = 0; -if (ev-type == SDL_KEYUP) -v |= SCANCODE_UP; -kbd_put_keycode(0xe1); -kbd_put_keycode(0x1d | v); -kbd_put_keycode(0x45 | v); +qemu_input_event_send_key_qcode(dcl-con, Q_KEY_CODE_PAUSE, +ev-type == SDL_KEYDOWN); return; } @@ -314,19 +309,15 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) case 0x45: /* num lock */ case 0x3a: /* caps lock */ /* SDL does not send the key up event, so we generate it */ -kbd_put_keycode(keycode); -kbd_put_keycode(keycode | SCANCODE_UP); +qemu_input_event_send_key_number(dcl-con, keycode, true); +qemu_input_event_send_key_number(dcl-con, keycode, false); return; #endif } /* now send the key code */ -if (keycode SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -if (ev-type == SDL_KEYUP) -kbd_put_keycode(keycode | SCANCODE_UP); -else -kbd_put_keycode(keycode SCANCODE_KEYCODEMASK); +qemu_input_event_send_key_number(dcl-con, keycode, + ev-type == SDL_KEYDOWN); } static void sdl_update_caption(void) -- 1.8.3.1
[Qemu-devel] [PATCH 01/42] ui/sdl2 : initial port to SDL 2.0 (v2.0)
From: Dave Airlie airl...@redhat.com I've ported the SDL1.2 code over, and rewritten it to use the SDL2 interface. The biggest changes were in the input handling, where SDL2 has done a major overhaul, and I've had to include a generated translation file to get from SDL2 codes back to qemu compatible ones. I'm still not sure how the keyboard layout code works in qemu, so there may be further work if someone can point me a test case that works with SDL1.2 and doesn't with SDL2. Some SDL env vars we used to set are no longer used by SDL2, Windows, OSX support is untested, I don't think we can link to SDL1.2 and SDL2 at the same time, so I felt using --with-sdlabi=2.0 to select the new code should be fine, like how gtk does it. v1.1: fix keys in text console v1.2: fix shutdown, cleanups a bit of code, support ARGB cursor v2.0: merge the SDL multihead patch into this, g_new the number of consoles needed, wrap DCL inside per-console structure. Signed-off-by: Dave Airlie airl...@redhat.com Signed-off-by: Gerd Hoffmann kra...@redhat.com --- configure| 23 +- ui/Makefile.objs | 4 +- ui/sdl.c | 3 + ui/sdl2.c| 981 +++ ui/sdl2_scancode_translate.h | 260 ui/sdl_keysym.h | 3 +- 6 files changed, 1267 insertions(+), 7 deletions(-) create mode 100644 ui/sdl2.c create mode 100644 ui/sdl2_scancode_translate.h diff --git a/configure b/configure index b472694..c4ce6b9 100755 --- a/configure +++ b/configure @@ -172,6 +172,7 @@ fdt= netmap=no pixman= sdl= +sdlabi=1.2 virtfs= vnc=yes sparse=no @@ -324,6 +325,7 @@ query_pkg_config() { } pkg_config=query_pkg_config sdl_config=${SDL_CONFIG-${cross_prefix}sdl-config} +sdl2_config=${SDL2_CONFIG-${cross_prefix}sdl2-config} # If the user hasn't specified ARFLAGS, default to 'rv', just as make does. ARFLAGS=${ARFLAGS-rv} @@ -730,6 +732,8 @@ for opt do ;; --enable-sdl) sdl=yes ;; + --with-sdlabi=*) sdlabi=$optarg + ;; --disable-qom-cast-debug) qom_cast_debug=no ;; --enable-qom-cast-debug) qom_cast_debug=yes @@ -1138,6 +1142,7 @@ Advanced options (experts only): --disable-werror disable compilation abort on warning --disable-sdldisable SDL --enable-sdl enable SDL + --with-sdlabiselect preferred SDL ABI 1.2 or 2.0 --disable-gtkdisable gtk UI --enable-gtk enable gtk UI --disable-virtfs disable VirtFS @@ -1790,12 +1795,22 @@ fi # Look for sdl configuration program (pkg-config or sdl-config). Try # sdl-config even without cross prefix, and favour pkg-config over sdl-config. -if test `basename $sdl_config` != sdl-config ! has ${sdl_config}; then - sdl_config=sdl-config + +if test $sdlabi = 2.0; then +sdl_config=$sdl2_config +sdlname=sdl2 +sdlconfigname=sdl2_config +else +sdlname=sdl +sdlconfigname=sdl_config +fi + +if test `basename $sdl_config` != $sdlconfigname ! has ${sdl_config}; then + sdl_config=$sdlconfigname fi -if $pkg_config sdl --exists; then - sdlconfig=$pkg_config sdl +if $pkg_config $sdlname --exists; then + sdlconfig=$pkg_config $sdlname _sdlversion=`$sdlconfig --modversion 2/dev/null | sed 's/[^0-9]//g'` elif has ${sdl_config}; then sdlconfig=$sdl_config diff --git a/ui/Makefile.objs b/ui/Makefile.objs index f33be47..721ad37 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -9,12 +9,12 @@ vnc-obj-y += vnc-jobs.o common-obj-y += keymaps.o console.o cursor.o input.o qemu-pixman.o common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o -common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o +common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o sdl2.o common-obj-$(CONFIG_COCOA) += cocoa.o common-obj-$(CONFIG_CURSES) += curses.o common-obj-$(CONFIG_VNC) += $(vnc-obj-y) common-obj-$(CONFIG_GTK) += gtk.o x_keymap.o -$(obj)/sdl.o $(obj)/sdl_zoom.o: QEMU_CFLAGS += $(SDL_CFLAGS) +$(obj)/sdl.o $(obj)/sdl_zoom.o $(obj)/sdl2.o: QEMU_CFLAGS += $(SDL_CFLAGS) $(obj)/gtk.o: QEMU_CFLAGS += $(GTK_CFLAGS) $(VTE_CFLAGS) diff --git a/ui/sdl.c b/ui/sdl.c index 9d8583c..736bb95 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -26,6 +26,8 @@ #undef WIN32_LEAN_AND_MEAN #include SDL.h + +#if SDL_MAJOR_VERSION == 1 #include SDL_syswm.h #include qemu-common.h @@ -966,3 +968,4 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) atexit(sdl_cleanup); } +#endif diff --git a/ui/sdl2.c b/ui/sdl2.c new file mode 100644 index 000..2eb3e9c --- /dev/null +++ b/ui/sdl2.c @@ -0,0 +1,981 @@ +/* + * QEMU SDL display driver + * + * Copyright (c) 2003 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use,
[Qemu-devel] [PATCH 17/42] input: keyboard: switch spice ui to new core
--- ui/spice-input.c | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ui/spice-input.c b/ui/spice-input.c index 3beb8de..c9df699 100644 --- a/ui/spice-input.c +++ b/ui/spice-input.c @@ -26,12 +26,15 @@ #include qemu-common.h #include ui/qemu-spice.h #include ui/console.h +#include ui/keymaps.h +#include ui/input.h /* keyboard bits */ typedef struct QemuSpiceKbd { SpiceKbdInstance sin; int ledstate; +bool emul0; } QemuSpiceKbd; static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag); @@ -47,9 +50,24 @@ static const SpiceKbdInterface kbd_interface = { .get_leds = kbd_get_leds, }; -static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag) +static void kbd_push_key(SpiceKbdInstance *sin, uint8_t scancode) { -kbd_put_keycode(frag); +QemuSpiceKbd *kbd = container_of(sin, QemuSpiceKbd, sin); +int keycode; +bool up; + +if (scancode == SCANCODE_EMUL0) { +kbd-emul0 = true; +return; +} +keycode = scancode ~SCANCODE_UP; +up = scancode SCANCODE_UP; +if (kbd-emul0) { +kbd-emul0 = false; +keycode |= SCANCODE_GREY; +} + +qemu_input_event_send_key_number(NULL, keycode, !up); } static uint8_t kbd_get_leds(SpiceKbdInstance *sin) -- 1.8.3.1
[Qemu-devel] [PATCH 12/42] input: keyboard: switch qmp_send_key() to new core.
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/input-legacy.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 80f4f5c..a4006cc 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -260,10 +260,8 @@ static void free_keycodes(void) static void release_keys(void *opaque) { while (keycodes_size 0) { -if (keycodes[--keycodes_size] SCANCODE_GREY) { -kbd_put_keycode(SCANCODE_EMUL0); -} -kbd_put_keycode(keycodes[keycodes_size] | SCANCODE_UP); +qemu_input_event_send_key_number(NULL, keycodes[--keycodes_size], + false); } free_keycodes(); @@ -297,10 +295,7 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, return; } -if (keycode SCANCODE_GREY) { -kbd_put_keycode(SCANCODE_EMUL0); -} -kbd_put_keycode(keycode SCANCODE_KEYCODEMASK); +qemu_input_event_send_key_number(NULL, keycode, true); keycodes = g_realloc(keycodes, sizeof(int) * (keycodes_size + 1)); keycodes[keycodes_size++] = keycode; -- 1.8.3.1
[Qemu-devel] [PATCH 18/42] input: keyboard: switch curses ui to new core
--- ui/curses.c | 47 +-- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/ui/curses.c b/ui/curses.c index dbc3d5e..b044790 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -30,6 +30,7 @@ #include qemu-common.h #include ui/console.h +#include ui/input.h #include sysemu/sysemu.h #define FONT_HEIGHT 16 @@ -274,32 +275,34 @@ static void curses_refresh(DisplayChangeListener *dcl) if (qemu_console_is_graphic(NULL)) { /* since terminals don't know about key press and release * events, we need to emit both for each key received */ -if (keycode SHIFT) -kbd_put_keycode(SHIFT_CODE); -if (keycode CNTRL) -kbd_put_keycode(CNTRL_CODE); -if (keycode ALT) -kbd_put_keycode(ALT_CODE); +if (keycode SHIFT) { +qemu_input_event_send_key_number(NULL, SHIFT_CODE, true); +} +if (keycode CNTRL) { +qemu_input_event_send_key_number(NULL, CNTRL_CODE, true); +} +if (keycode ALT) { +qemu_input_event_send_key_number(NULL, ALT_CODE, true); +} if (keycode ALTGR) { -kbd_put_keycode(SCANCODE_EMUL0); -kbd_put_keycode(ALT_CODE); +qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, true); } -if (keycode GREY) -kbd_put_keycode(GREY_CODE); -kbd_put_keycode(keycode KEY_MASK); -if (keycode GREY) -kbd_put_keycode(GREY_CODE); -kbd_put_keycode((keycode KEY_MASK) | KEY_RELEASE); + +qemu_input_event_send_key_number(NULL, keycode, true); +qemu_input_event_send_key_number(NULL, keycode, false); + if (keycode ALTGR) { -kbd_put_keycode(SCANCODE_EMUL0); -kbd_put_keycode(ALT_CODE | KEY_RELEASE); +qemu_input_event_send_key_number(NULL, GREY | ALT_CODE, false); +} +if (keycode ALT) { +qemu_input_event_send_key_number(NULL, ALT_CODE, false); +} +if (keycode CNTRL) { +qemu_input_event_send_key_number(NULL, CNTRL_CODE, false); +} +if (keycode SHIFT) { +qemu_input_event_send_key_number(NULL, SHIFT_CODE, false); } -if (keycode ALT) -kbd_put_keycode(ALT_CODE | KEY_RELEASE); -if (keycode CNTRL) -kbd_put_keycode(CNTRL_CODE | KEY_RELEASE); -if (keycode SHIFT) -kbd_put_keycode(SHIFT_CODE | KEY_RELEASE); } else { keysym = curses2qemu[chr]; if (keysym == -1) -- 1.8.3.1
[Qemu-devel] [PATCH 23/42] input: mouse: switch gtk ui to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/gtk.c | 58 +++--- 1 file changed, 19 insertions(+), 39 deletions(-) diff --git a/ui/gtk.c b/ui/gtk.c index 74c0936..1851495 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -194,7 +194,7 @@ static void gd_update_cursor(GtkDisplayState *s, gboolean override) on_vga = gd_on_vga(s); if ((override || on_vga) -(s-full_screen || kbd_mouse_is_absolute() || gd_is_grab_active(s))) { +(s-full_screen || qemu_input_is_absolute() || gd_is_grab_active(s))) { gdk_window_set_cursor(window, s-null_cursor); } else { gdk_window_set_cursor(window, NULL); @@ -580,7 +580,6 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, void *opaque) { GtkDisplayState *s = opaque; -int dx, dy; int x, y; int mx, my; int fbh, fbw; @@ -608,25 +607,21 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion, return TRUE; } -if (kbd_mouse_is_absolute()) { -dx = x * 0x7FFF / (surface_width(s-ds) - 1); -dy = y * 0x7FFF / (surface_height(s-ds) - 1); -} else if (s-last_x == -1 || s-last_y == -1) { -dx = 0; -dy = 0; -} else { -dx = x - s-last_x; -dy = y - s-last_y; +if (qemu_input_is_absolute()) { +qemu_input_queue_abs(s-dcl.con, INPUT_AXIS_X, x, + surface_width(s-ds)); +qemu_input_queue_abs(s-dcl.con, INPUT_AXIS_Y, y, + surface_height(s-ds)); +qemu_input_event_sync(); +} else if (s-last_x != -1 s-last_y != -1 gd_is_grab_active(s)) { +qemu_input_queue_rel(s-dcl.con, INPUT_AXIS_X, x - s-last_x); +qemu_input_queue_rel(s-dcl.con, INPUT_AXIS_Y, y - s-last_y); +qemu_input_event_sync(); } - s-last_x = x; s-last_y = y; -if (kbd_mouse_is_absolute() || gd_is_grab_active(s)) { -kbd_mouse_event(dx, dy, 0, s-button_mask); -} - -if (!kbd_mouse_is_absolute() gd_is_grab_active(s)) { +if (!qemu_input_is_absolute() gd_is_grab_active(s)) { GdkScreen *screen = gtk_widget_get_screen(s-drawing_area); int x = (int)motion-x_root; int y = (int)motion-y_root; @@ -671,35 +666,20 @@ static gboolean gd_button_event(GtkWidget *widget, GdkEventButton *button, void *opaque) { GtkDisplayState *s = opaque; -int dx, dy; -int n; +InputButton btn; if (button-button == 1) { -n = 0x01; +btn = INPUT_BUTTON_LEFT; } else if (button-button == 2) { -n = 0x04; +btn = INPUT_BUTTON_MIDDLE; } else if (button-button == 3) { -n = 0x02; -} else { -n = 0x00; -} - -if (button-type == GDK_BUTTON_PRESS) { -s-button_mask |= n; -} else if (button-type == GDK_BUTTON_RELEASE) { -s-button_mask = ~n; -} - -if (kbd_mouse_is_absolute()) { -dx = s-last_x * 0x7FFF / (surface_width(s-ds) - 1); -dy = s-last_y * 0x7FFF / (surface_height(s-ds) - 1); +btn = INPUT_BUTTON_RIGHT; } else { -dx = 0; -dy = 0; +return TRUE; } -kbd_mouse_event(dx, dy, 0, s-button_mask); - +qemu_input_queue_btn(s-dcl.con, btn, button-type == GDK_BUTTON_PRESS); +qemu_input_event_sync(); return TRUE; } -- 1.8.3.1
[Qemu-devel] [PATCH 13/42] input: keyboard: switch gtk ui to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/gtk.c | 19 --- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/ui/gtk.c b/ui/gtk.c index a633d89..74c0936 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -59,6 +59,7 @@ #include trace.h #include ui/console.h +#include ui/input.h #include sysemu/sysemu.h #include qmp-commands.h #include x_keymap.h @@ -280,10 +281,7 @@ static void gtk_release_modifiers(GtkDisplayState *s) if (!s-modifier_pressed[i]) { continue; } -if (keycode SCANCODE_GREY) { -kbd_put_keycode(SCANCODE_EMUL0); -} -kbd_put_keycode(keycode | SCANCODE_UP); +qemu_input_event_send_key_number(s-dcl.con, keycode, false); s-modifier_pressed[i] = false; } } @@ -745,17 +743,8 @@ static gboolean gd_key_event(GtkWidget *widget, GdkEventKey *key, void *opaque) } } -if (qemu_keycode SCANCODE_GREY) { -kbd_put_keycode(SCANCODE_EMUL0); -} - -if (key-type == GDK_KEY_PRESS) { -kbd_put_keycode(qemu_keycode SCANCODE_KEYCODEMASK); -} else if (key-type == GDK_KEY_RELEASE) { -kbd_put_keycode(qemu_keycode | SCANCODE_UP); -} else { -g_assert_not_reached(); -} +qemu_input_event_send_key_number(s-dcl.con, qemu_keycode, + key-type == GDK_KEY_PRESS); return TRUE; } -- 1.8.3.1
[Qemu-devel] [PATCH 09/42] input: add core bits of the new input layer
Register and unregister handlers. Event dispatcher code. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/input.h | 32 + ui/Makefile.objs | 2 +- ui/input.c | 83 ++ 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 include/ui/input.h create mode 100644 ui/input.c diff --git a/include/ui/input.h b/include/ui/input.h new file mode 100644 index 000..3cf3641 --- /dev/null +++ b/include/ui/input.h @@ -0,0 +1,32 @@ +#ifndef INPUT_H +#define INPUT_H + +#include qapi-types.h + +#define INPUT_EVENT_MASK_KEY (1INPUT_EVENT_KIND_KEY) +#define INPUT_EVENT_MASK_BTN (1INPUT_EVENT_KIND_BTN) +#define INPUT_EVENT_MASK_REL (1INPUT_EVENT_KIND_REL) +#define INPUT_EVENT_MASK_ABS (1INPUT_EVENT_KIND_ABS) + +typedef struct QemuInputHandler QemuInputHandler; +typedef struct QemuInputHandlerState QemuInputHandlerState; + +typedef void (*QemuInputHandlerEvent)(DeviceState *dev, QemuConsole *src, + InputEvent *evt); +typedef void (*QemuInputHandlerSync)(DeviceState *dev); + +struct QemuInputHandler { +const char *name; +uint32_t mask; +QemuInputHandlerEvent event; +QemuInputHandlerSync sync; +}; + +QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, + QemuInputHandler *handler); +void qemu_input_handler_activate(QemuInputHandlerState *s); +void qemu_input_handler_unregister(QemuInputHandlerState *s); +void qemu_input_event_send(QemuConsole *src, InputEvent *evt); +void qemu_input_event_sync(void); + +#endif /* INPUT_H */ diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 16db07a..e6a5ec1 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -7,7 +7,7 @@ vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o vnc-obj-$(CONFIG_VNC_WS) += vnc-ws.o vnc-obj-y += vnc-jobs.o -common-obj-y += keymaps.o console.o cursor.o input-legacy.o qemu-pixman.o +common-obj-y += keymaps.o console.o cursor.o input.o input-legacy.o qemu-pixman.o common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o sdl2.o common-obj-$(CONFIG_COCOA) += cocoa.o diff --git a/ui/input.c b/ui/input.c new file mode 100644 index 000..23c84f7 --- /dev/null +++ b/ui/input.c @@ -0,0 +1,83 @@ +#include sysemu/sysemu.h +#include qapi-types.h +#include ui/input.h + +struct QemuInputHandlerState { +DeviceState *dev; +QemuInputHandler *handler; +int id; +int events; +QTAILQ_ENTRY(QemuInputHandlerState) node; +}; +static QTAILQ_HEAD(, QemuInputHandlerState) handlers = +QTAILQ_HEAD_INITIALIZER(handlers); + +QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, + QemuInputHandler *handler) +{ +QemuInputHandlerState *s = g_new0(QemuInputHandlerState, 1); +static int id = 1; + +s-dev = dev; +s-handler = handler; +s-id = id++; +QTAILQ_INSERT_TAIL(handlers, s, node); +return s; +} + +void qemu_input_handler_activate(QemuInputHandlerState *s) +{ +QTAILQ_REMOVE(handlers, s, node); +QTAILQ_INSERT_HEAD(handlers, s, node); +} + +void qemu_input_handler_unregister(QemuInputHandlerState *s) +{ +QTAILQ_REMOVE(handlers, s, node); +g_free(s); +} + +static QemuInputHandlerState* +qemu_input_find_handler(uint32_t mask) +{ +QemuInputHandlerState *s; + +QTAILQ_FOREACH(s, handlers, node) { +if (mask s-handler-mask) { +return s; +} +} +return NULL; +} + +void qemu_input_event_send(QemuConsole *src, InputEvent *evt) +{ +QemuInputHandlerState *s; + +if (!runstate_is_running() !runstate_check(RUN_STATE_SUSPENDED)) { +return; +} + +s = qemu_input_find_handler(1 evt-kind); +s-handler-event(s-dev, src, evt); +s-events++; +} + +void qemu_input_event_sync(void) +{ +QemuInputHandlerState *s; + +if (!runstate_is_running() !runstate_check(RUN_STATE_SUSPENDED)) { +return; +} + +QTAILQ_FOREACH(s, handlers, node) { +if (!s-events) { +continue; +} +if (s-handler-sync) { +s-handler-sync(s-dev); +} +s-events = 0; +} +} -- 1.8.3.1
[Qemu-devel] [PATCH 11/42] input: keyboard: switch legacy handlers to new core
legacy kbd event handlers are registered in the new core, so they receive events from the new input core code. keycode - scancode translation needed here. legacy kbd_put_keycode() sends events to the new core. scancode - keycode translation needed here. So with this patch the new input core is fully functional for keyboard events. New + legacy interfaces can be mixed in any way. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/input-legacy.c | 66 ++- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 1c70f60..80f4f5c 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -29,6 +29,7 @@ #include qmp-commands.h #include qapi-types.h #include ui/keymaps.h +#include ui/input.h struct QEMUPutMouseEntry { QEMUPutMouseEvent *qemu_put_mouse_event; @@ -45,7 +46,7 @@ struct QEMUPutMouseEntry { struct QEMUPutKbdEntry { QEMUPutKBDEvent *put_kbd; void *opaque; -QTAILQ_ENTRY(QEMUPutKbdEntry) next; +QemuInputHandlerState *s; }; struct QEMUPutLEDEntry { @@ -56,8 +57,6 @@ struct QEMUPutLEDEntry { static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers); -static QTAILQ_HEAD(, QEMUPutKbdEntry) kbd_handlers = -QTAILQ_HEAD_INITIALIZER(kbd_handlers); static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers = QTAILQ_HEAD_INITIALIZER(mouse_handlers); static NotifierList mouse_mode_notifiers = @@ -312,20 +311,56 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time, muldiv64(get_ticks_per_sec(), hold_time, 1000)); } +static void legacy_kbd_event(DeviceState *dev, QemuConsole *src, + InputEvent *evt) +{ +QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev; +int keycode = keycode_from_keyvalue(evt-key-key); + +if (!entry || !entry-put_kbd) { +return; +} +if (evt-key-key-kind == KEY_VALUE_KIND_QCODE +evt-key-key-qcode == Q_KEY_CODE_PAUSE) { +/* specific case */ +int v = evt-key-down ? 0 : 0x80; +entry-put_kbd(entry-opaque, 0xe1); +entry-put_kbd(entry-opaque, 0x1d | v); +entry-put_kbd(entry-opaque, 0x45 | v); +return; +} +if (keycode SCANCODE_GREY) { +entry-put_kbd(entry-opaque, SCANCODE_EMUL0); +keycode = ~SCANCODE_GREY; +} +if (!evt-key-down) { +keycode |= SCANCODE_UP; +} +entry-put_kbd(entry-opaque, keycode); +} + +static QemuInputHandler legacy_kbd_handler = { +.name = legacy-kbd, +.mask = INPUT_EVENT_MASK_KEY, +.event = legacy_kbd_event, +}; + QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque) { QEMUPutKbdEntry *entry; -entry = g_malloc0(sizeof(QEMUPutKbdEntry)); +entry = g_new0(QEMUPutKbdEntry, 1); entry-put_kbd = func; entry-opaque = opaque; -QTAILQ_INSERT_HEAD(kbd_handlers, entry, next); +entry-s = qemu_input_handler_register((DeviceState *)entry, + legacy_kbd_handler); return entry; } void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry) { -QTAILQ_REMOVE(kbd_handlers, entry, next); +qemu_input_handler_unregister(entry-s); +g_free(entry); } static void check_mode_change(void) @@ -409,14 +444,25 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) void kbd_put_keycode(int keycode) { -QEMUPutKbdEntry *entry = QTAILQ_FIRST(kbd_handlers); +static bool emul0; +bool up; -if (!runstate_is_running() !runstate_check(RUN_STATE_SUSPENDED)) { +if (keycode == SCANCODE_EMUL0) { +emul0 = true; return; } -if (entry entry-put_kbd) { -entry-put_kbd(entry-opaque, keycode); +if (keycode SCANCODE_UP) { +keycode = ~SCANCODE_UP; +up = true; +} else { +up = false; +} +if (emul0) { +keycode |= SCANCODE_GREY; +emul0 = false; } + +qemu_input_event_send_key_number(NULL, keycode, !up); } void kbd_put_ledstate(int ledstate) -- 1.8.3.1
[Qemu-devel] [PATCH 27/42] input: mouse: switch spice ui to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/spice-input.c | 62 ++-- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/ui/spice-input.c b/ui/spice-input.c index c9df699..6dab23b 100644 --- a/ui/spice-input.c +++ b/ui/spice-input.c @@ -98,41 +98,52 @@ static void kbd_leds(void *opaque, int ledstate) typedef struct QemuSpicePointer { SpiceMouseInstance mouse; SpiceTabletInstance tablet; -int width, height, x, y; +int width, height; +uint32_t last_bmask; Notifier mouse_mode; bool absolute; } QemuSpicePointer; -static int map_buttons(int spice_buttons) +static void spice_update_buttons(QemuSpicePointer *pointer, + int wheel, uint32_t button_mask) { -int qemu_buttons = 0; - -/* - * Note: SPICE_MOUSE_BUTTON_* specifies the wire protocol but this - * isn't what we get passed in via interface callbacks for the - * middle and right button ... - */ -if (spice_buttons SPICE_MOUSE_BUTTON_MASK_LEFT) { -qemu_buttons |= MOUSE_EVENT_LBUTTON; +static uint32_t bmap[INPUT_BUTTON_MAX] = { +[INPUT_BUTTON_LEFT]= 0x01, +[INPUT_BUTTON_MIDDLE] = 0x04, +[INPUT_BUTTON_RIGHT] = 0x02, +[INPUT_BUTTON_WHEEL_UP]= 0x10, +[INPUT_BUTTON_WHEEL_DOWN] = 0x20, +}; + +if (wheel 0) { +button_mask |= 0x10; } -if (spice_buttons 0x04 /* SPICE_MOUSE_BUTTON_MASK_MIDDLE */) { -qemu_buttons |= MOUSE_EVENT_MBUTTON; +if (wheel 0) { +button_mask |= 0x20; } -if (spice_buttons 0x02 /* SPICE_MOUSE_BUTTON_MASK_RIGHT */) { -qemu_buttons |= MOUSE_EVENT_RBUTTON; + +if (pointer-last_bmask == button_mask) { +return; } -return qemu_buttons; +qemu_input_update_buttons(NULL, bmap, pointer-last_bmask, button_mask); +pointer-last_bmask = button_mask; } static void mouse_motion(SpiceMouseInstance *sin, int dx, int dy, int dz, uint32_t buttons_state) { -kbd_mouse_event(dx, dy, dz, map_buttons(buttons_state)); +QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, mouse); +spice_update_buttons(pointer, dz, buttons_state); +qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx); +qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy); +qemu_input_event_sync(); } static void mouse_buttons(SpiceMouseInstance *sin, uint32_t buttons_state) { -kbd_mouse_event(0, 0, 0, map_buttons(buttons_state)); +QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, mouse); +spice_update_buttons(pointer, 0, buttons_state); +qemu_input_event_sync(); } static const SpiceMouseInterface mouse_interface = { @@ -163,9 +174,10 @@ static void tablet_position(SpiceTabletInstance* sin, int x, int y, { QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet); -pointer-x = x * 0x7FFF / (pointer-width - 1); -pointer-y = y * 0x7FFF / (pointer-height - 1); -kbd_mouse_event(pointer-x, pointer-y, 0, map_buttons(buttons_state)); +spice_update_buttons(pointer, 0, buttons_state); +qemu_input_queue_abs(NULL, INPUT_AXIS_X, x, pointer-width); +qemu_input_queue_abs(NULL, INPUT_AXIS_Y, y, pointer-width); +qemu_input_event_sync(); } @@ -174,7 +186,8 @@ static void tablet_wheel(SpiceTabletInstance* sin, int wheel, { QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet); -kbd_mouse_event(pointer-x, pointer-y, wheel, map_buttons(buttons_state)); +spice_update_buttons(pointer, wheel, buttons_state); +qemu_input_event_sync(); } static void tablet_buttons(SpiceTabletInstance *sin, @@ -182,7 +195,8 @@ static void tablet_buttons(SpiceTabletInstance *sin, { QemuSpicePointer *pointer = container_of(sin, QemuSpicePointer, tablet); -kbd_mouse_event(pointer-x, pointer-y, 0, map_buttons(buttons_state)); +spice_update_buttons(pointer, 0, buttons_state); +qemu_input_event_sync(); } static const SpiceTabletInterface tablet_interface = { @@ -199,7 +213,7 @@ static const SpiceTabletInterface tablet_interface = { static void mouse_mode_notifier(Notifier *notifier, void *data) { QemuSpicePointer *pointer = container_of(notifier, QemuSpicePointer, mouse_mode); -bool is_absolute = kbd_mouse_is_absolute(); +bool is_absolute = qemu_input_is_absolute(); if (pointer-absolute == is_absolute) { return; -- 1.8.3.1
[Qemu-devel] [PATCH 34/42] input-legacy: remove kbd_mouse_is_absolute
--- include/ui/console.h | 1 - ui/input-legacy.c| 11 +-- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 53e956d..21b32e4 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -50,7 +50,6 @@ void kbd_put_ledstate(int ledstate); void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); /* Does the current mouse generate absolute events */ -int kbd_mouse_is_absolute(void); void qemu_add_mouse_mode_change_notifier(Notifier *notify); void qemu_remove_mouse_mode_change_notifier(Notifier *notify); diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 22796fa..412d401 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -369,7 +369,7 @@ static void check_mode_change(void) static int current_is_absolute; int is_absolute; -is_absolute = kbd_mouse_is_absolute(); +is_absolute = qemu_input_is_absolute(); if (is_absolute != current_is_absolute) { notifier_list_notify(mouse_mode_notifiers, NULL); @@ -554,15 +554,6 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) } } -int kbd_mouse_is_absolute(void) -{ -if (QTAILQ_EMPTY(mouse_handlers)) { -return 0; -} - -return QTAILQ_FIRST(mouse_handlers)-qemu_put_mouse_event_absolute; -} - MouseInfoList *qmp_query_mice(Error **errp) { MouseInfoList *mice_list = NULL; -- 1.8.3.1
[Qemu-devel] [PATCH 06/42] input: qapi: define event types
Define input event types, using qapi. So we get nicely autogenerated types for our input events. And when it comes to qmp support some day things will be alot easier. Types are modeled after the linux input layer. There are separate event types for each value. There is a sync to indicate the end of a event group. Mouse events are splitted into motion events (one for each axis) and button events, which are grouped by sync. Keyboard events are using the existing KeyValue type. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- qapi-schema.json | 76 1 file changed, 76 insertions(+) diff --git a/qapi-schema.json b/qapi-schema.json index 05ced9d..646d64f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4419,3 +4419,79 @@ # Since: 1.7 ## { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } } + +## +# @InputButton +# +# Button of a pointer input device (mouse, tablet). +# +# Since: 2.0 +## +{ 'enum' : 'InputButton', + 'data' : [ 'Left', 'Middle', 'Right', 'WheelUp', 'WheelDown' ] } + +## +# @InputButton +# +# Position axis of a pointer input device (mouse, tablet). +# +# Since: 2.0 +## +{ 'enum' : 'InputAxis', + 'data' : [ 'X', 'Y' ] } + +## +# @InputKeyEvent +# +# Keyboard input event. +# +# @key:Which key this event is for. +# @down: True for key-down and false for key-up events. +# +# Since: 2.0 +## +{ 'type' : 'InputKeyEvent', + 'data' : { 'key' : 'KeyValue', + 'down': 'bool' } } + +## +# @InputBtnEvent +# +# Pointer button input event. +# +# @button: Which button this event is for. +# @down: True for key-down and false for key-up events. +# +# Since: 2.0 +## +{ 'type' : 'InputBtnEvent', + 'data' : { 'button' : 'InputButton', + 'down': 'bool' } } + +## +# @InputMoveEvent +# +# Pointer motion input event. +# +# @axis: Which axis is referenced by @value. +# @value: Pointer position. For absolute coordinates the +# valid range is 0 - 0x7 +# +# Since: 2.0 +## +{ 'type' : 'InputMoveEvent', + 'data' : { 'axis': 'InputAxis', + 'value' : 'int' } } + +## +# @InputEvent +# +# Input event union. +# +# Since: 2.0 +## +{ 'union' : 'InputEvent', + 'data' : { 'key' : 'InputKeyEvent', + 'btn' : 'InputBtnEvent', + 'rel' : 'InputMoveEvent', + 'abs' : 'InputMoveEvent' } } -- 1.8.3.1
[Qemu-devel] [PATCH 22/42] input: mouse: switch legacy handlers to new core
legacy mouse event handlers are registered in the new core, so they receive events submitted to the new input core. legacy kbd_mouse_event() continues to use the old code paths. So new-core event handlers wouldn't see events submitted via kbd_mouse_event. This leads to the constrain that we we must transition all kbd_mouse_event() users first to keep things working. But that is easier to handle than translating legacy mouse events into new-core mouse events ;) Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/input-legacy.c | 63 +++ 1 file changed, 63 insertions(+) diff --git a/ui/input-legacy.c b/ui/input-legacy.c index a4006cc..dd2dec3 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -41,6 +41,12 @@ struct QEMUPutMouseEntry { /* used internally by qemu for handling mice */ QTAILQ_ENTRY(QEMUPutMouseEntry) node; + +/* new input core */ +QemuInputHandler h; +QemuInputHandlerState *s; +int axis[INPUT_AXIS_MAX]; +int buttons; }; struct QEMUPutKbdEntry { @@ -376,6 +382,51 @@ static void check_mode_change(void) current_has_absolute = has_absolute; } +static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, + InputEvent *evt) +{ +static const int bmap[INPUT_BUTTON_MAX] = { +[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, +[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, +[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, +}; +QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev; + +switch (evt-kind) { +case INPUT_EVENT_KIND_BTN: +if (evt-btn-down) { +s-buttons |= bmap[evt-btn-button]; +} else { +s-buttons = ~bmap[evt-btn-button]; +} +break; +case INPUT_EVENT_KIND_ABS: +s-axis[evt-abs-axis] = evt-abs-value; +break; +case INPUT_EVENT_KIND_REL: +s-axis[evt-rel-axis] += evt-rel-value; +break; +default: +break; +} +} + +static void legacy_mouse_sync(DeviceState *dev) +{ +QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev; + +s-qemu_put_mouse_event(s-qemu_put_mouse_event_opaque, +s-axis[INPUT_AXIS_X], +s-axis[INPUT_AXIS_Y], +0, +s-buttons); + +if (!s-qemu_put_mouse_event_absolute) { +s-axis[INPUT_AXIS_X] = 0; +s-axis[INPUT_AXIS_Y] = 0; +} +} + QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque, int absolute, const char *name) @@ -393,6 +444,14 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, QTAILQ_INSERT_TAIL(mouse_handlers, s, node); +s-h.name = name; +s-h.mask = INPUT_EVENT_MASK_BTN | +(absolute ? INPUT_EVENT_MASK_ABS : INPUT_EVENT_MASK_REL); +s-h.event = legacy_mouse_event; +s-h.sync = legacy_mouse_sync; +s-s = qemu_input_handler_register((DeviceState *)s, + s-h); + check_mode_change(); return s; @@ -403,6 +462,8 @@ void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry) QTAILQ_REMOVE(mouse_handlers, entry, node); QTAILQ_INSERT_HEAD(mouse_handlers, entry, node); +qemu_input_handler_activate(entry-s); + check_mode_change(); } @@ -410,6 +471,8 @@ void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) { QTAILQ_REMOVE(mouse_handlers, entry, node); +qemu_input_handler_unregister(entry-s); + g_free(entry-qemu_put_mouse_event_name); g_free(entry); -- 1.8.3.1
[Qemu-devel] [PATCH 15/42] sdl2: switch keyboard handling to new core
--- ui/sdl2.c | 23 ++- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/ui/sdl2.c b/ui/sdl2.c index e7a30b3..ac3ac19 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -33,6 +33,7 @@ #include qemu-common.h #include ui/console.h +#include ui/input.h #include sysemu/sysemu.h #include x_keymap.h #include sdl_zoom.h @@ -236,9 +237,7 @@ static void reset_keys(void) int i; for(i = 0; i 256; i++) { if (modifiers_state[i]) { -if (i SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -kbd_put_keycode(i | SCANCODE_UP); +qemu_input_event_send_key_number(NULL, i, false); modifiers_state[i] = 0; } } @@ -246,11 +245,12 @@ static void reset_keys(void) static void sdl_process_key(SDL_KeyboardEvent *ev) { -int keycode, v; +int keycode; +#if 0 if (ev-keysym.sym == SDLK_PAUSE) { /* specific case */ -v = 0; +int v = 0; if (ev-type == SDL_KEYUP) v |= SCANCODE_UP; kbd_put_keycode(0xe1); @@ -258,6 +258,7 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) kbd_put_keycode(0x45 | v); return; } +#endif if (kbd_layout) { keycode = sdl_keyevent_to_keycode_generic(ev); @@ -284,18 +285,14 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) case 0x45: /* num lock */ case 0x3a: /* caps lock */ /* SDL does not send the key up event, so we generate it */ -kbd_put_keycode(keycode); -kbd_put_keycode(keycode | SCANCODE_UP); +qemu_input_event_send_key_number(NULL, keycode, true); +qemu_input_event_send_key_number(NULL, keycode, false); return; } /* now send the key code */ -if (keycode SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -if (ev-type == SDL_KEYUP) -kbd_put_keycode(keycode | SCANCODE_UP); -else -kbd_put_keycode(keycode SCANCODE_KEYCODEMASK); +qemu_input_event_send_key_number(NULL, keycode, + ev-type == SDL_KEYDOWN); } static void sdl_update_caption(struct sdl2_console_state *scon) -- 1.8.3.1
[Qemu-devel] [PATCH 32/42] input-legacy: remove kbd_put_keycode
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/console.h | 1 - ui/input-legacy.c| 23 --- 2 files changed, 24 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index a3062d0..c7f4e4f 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -46,7 +46,6 @@ void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry); QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, void *opaque); void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry); -void kbd_put_keycode(int keycode); void kbd_put_ledstate(int ledstate); void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); diff --git a/ui/input-legacy.c b/ui/input-legacy.c index dd2dec3..3ac30e2 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -500,29 +500,6 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry) g_free(entry); } -void kbd_put_keycode(int keycode) -{ -static bool emul0; -bool up; - -if (keycode == SCANCODE_EMUL0) { -emul0 = true; -return; -} -if (keycode SCANCODE_UP) { -keycode = ~SCANCODE_UP; -up = true; -} else { -up = false; -} -if (emul0) { -keycode |= SCANCODE_GREY; -emul0 = false; -} - -qemu_input_event_send_key_number(NULL, keycode, !up); -} - void kbd_put_ledstate(int ledstate) { QEMUPutLEDEntry *cursor; -- 1.8.3.1
[Qemu-devel] [PATCH 40/42] input: move qmp_query_mice to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/input-legacy.c | 23 --- ui/input.c| 29 + 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 7f8e72b..7843482 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -483,29 +483,6 @@ void kbd_put_ledstate(int ledstate) } } -MouseInfoList *qmp_query_mice(Error **errp) -{ -MouseInfoList *mice_list = NULL; -QEMUPutMouseEntry *cursor; -bool current = true; - -QTAILQ_FOREACH(cursor, mouse_handlers, node) { -MouseInfoList *info = g_malloc0(sizeof(*info)); -info-value = g_malloc0(sizeof(*info-value)); -info-value-name = g_strdup(cursor-qemu_put_mouse_event_name); -info-value-index = cursor-index; -info-value-absolute = !!cursor-qemu_put_mouse_event_absolute; -info-value-current = current; - -current = false; - -info-next = mice_list; -mice_list = info; -} - -return mice_list; -} - void do_mouse_set(Monitor *mon, const QDict *qdict) { QEMUPutMouseEntry *cursor; diff --git a/ui/input.c b/ui/input.c index 55449dc..2945a3c 100644 --- a/ui/input.c +++ b/ui/input.c @@ -1,5 +1,6 @@ #include sysemu/sysemu.h #include qapi-types.h +#include qmp-commands.h #include trace.h #include ui/input.h #include ui/console.h @@ -307,3 +308,31 @@ void qemu_remove_mouse_mode_change_notifier(Notifier *notify) { notifier_remove(notify); } + +MouseInfoList *qmp_query_mice(Error **errp) +{ +MouseInfoList *mice_list = NULL; +MouseInfoList *info; +QemuInputHandlerState *s; +bool current = true; + +QTAILQ_FOREACH(s, handlers, node) { +if (!(s-handler-mask + (INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS))) { +continue; +} + +info = g_new0(MouseInfoList, 1); +info-value = g_new0(MouseInfo, 1); +info-value-index = s-id; +info-value-name = g_strdup(s-handler-name); +info-value-absolute = s-handler-mask INPUT_EVENT_MASK_ABS; +info-value-current = current; + +current = false; +info-next = mice_list; +mice_list = info; +} + +return mice_list; +} -- 1.8.3.1
[Qemu-devel] [PATCH 33/42] input-legacy: remove kbd_mouse_has_absolute
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/console.h | 3 --- ui/input-legacy.c| 21 ++--- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index c7f4e4f..53e956d 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -54,9 +54,6 @@ int kbd_mouse_is_absolute(void); void qemu_add_mouse_mode_change_notifier(Notifier *notify); void qemu_remove_mouse_mode_change_notifier(Notifier *notify); -/* Of all the mice, is there one that generates absolute events */ -int kbd_mouse_has_absolute(void); - struct MouseTransformInfo { /* Touchscreen resolution */ int x; diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 3ac30e2..22796fa 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -366,20 +366,16 @@ void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry) static void check_mode_change(void) { -static int current_is_absolute, current_has_absolute; +static int current_is_absolute; int is_absolute; -int has_absolute; is_absolute = kbd_mouse_is_absolute(); -has_absolute = kbd_mouse_has_absolute(); -if (is_absolute != current_is_absolute || -has_absolute != current_has_absolute) { +if (is_absolute != current_is_absolute) { notifier_list_notify(mouse_mode_notifiers, NULL); } current_is_absolute = is_absolute; -current_has_absolute = has_absolute; } static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, @@ -567,19 +563,6 @@ int kbd_mouse_is_absolute(void) return QTAILQ_FIRST(mouse_handlers)-qemu_put_mouse_event_absolute; } -int kbd_mouse_has_absolute(void) -{ -QEMUPutMouseEntry *entry; - -QTAILQ_FOREACH(entry, mouse_handlers, node) { -if (entry-qemu_put_mouse_event_absolute) { -return 1; -} -} - -return 0; -} - MouseInfoList *qmp_query_mice(Error **errp) { MouseInfoList *mice_list = NULL; -- 1.8.3.1
[Qemu-devel] [PATCH 35/42] input-legacy: remove kbd_mouse_event
--- include/ui/console.h | 1 - ui/input-legacy.c| 49 - 2 files changed, 50 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 21b32e4..71a0da3 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -47,7 +47,6 @@ QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, void *opaque) void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry); void kbd_put_ledstate(int ledstate); -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state); /* Does the current mouse generate absolute events */ void qemu_add_mouse_mode_change_notifier(Notifier *notify); diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 412d401..26ff06f 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -505,55 +505,6 @@ void kbd_put_ledstate(int ledstate) } } -void kbd_mouse_event(int dx, int dy, int dz, int buttons_state) -{ -QEMUPutMouseEntry *entry; -QEMUPutMouseEvent *mouse_event; -void *mouse_event_opaque; -int width, height; - -if (!runstate_is_running() !runstate_check(RUN_STATE_SUSPENDED)) { -return; -} -if (QTAILQ_EMPTY(mouse_handlers)) { -return; -} - -entry = QTAILQ_FIRST(mouse_handlers); - -mouse_event = entry-qemu_put_mouse_event; -mouse_event_opaque = entry-qemu_put_mouse_event_opaque; - -if (mouse_event) { -if (entry-qemu_put_mouse_event_absolute) { -width = 0x7fff; -height = 0x7fff; -} else { -width = graphic_width - 1; -height = graphic_height - 1; -} - -switch (graphic_rotate) { -case 0: -mouse_event(mouse_event_opaque, -dx, dy, dz, buttons_state); -break; -case 90: -mouse_event(mouse_event_opaque, -width - dy, dx, dz, buttons_state); -break; -case 180: -mouse_event(mouse_event_opaque, -width - dx, height - dy, dz, buttons_state); -break; -case 270: -mouse_event(mouse_event_opaque, -dy, height - dx, dz, buttons_state); -break; -} -} -} - MouseInfoList *qmp_query_mice(Error **errp) { MouseInfoList *mice_list = NULL; -- 1.8.3.1
[Qemu-devel] [PATCH 29/42] input: keyboard: switch cocoa ui to new core
--- ui/cocoa.m | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 8661777..d4af3e5 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -514,16 +514,14 @@ QemuCocoaView *cocoaView; if (keycode) { if (keycode == 58 || keycode == 69) { // emulate caps lock and num lock keydown and keyup -kbd_put_keycode(keycode); -kbd_put_keycode(keycode | 0x80); +qemu_input_event_send_key_number(dcl-con, keycode, true); +qemu_input_event_send_key_number(dcl-con, keycode, false); } else if (qemu_console_is_graphic(NULL)) { -if (keycode 0x80) -kbd_put_keycode(0xe0); if (modifiers_state[keycode] == 0) { // keydown -kbd_put_keycode(keycode 0x7f); +qemu_input_event_send_key_number(dcl-con, keycode, true); modifiers_state[keycode] = 1; } else { // keyup -kbd_put_keycode(keycode | 0x80); +qemu_input_event_send_key_number(dcl-con, keycode, false); modifiers_state[keycode] = 0; } } @@ -557,9 +555,7 @@ QemuCocoaView *cocoaView; // handle keys for graphic console } else if (qemu_console_is_graphic(NULL)) { -if (keycode 0x80) //check bit for e0 in front -kbd_put_keycode(0xe0); -kbd_put_keycode(keycode 0x7f); //remove e0 bit in front +qemu_input_event_send_key_number(dcl-con, keycode, true); // handlekeys for Monitor } else { @@ -607,9 +603,7 @@ QemuCocoaView *cocoaView; } if (qemu_console_is_graphic(NULL)) { -if (keycode 0x80) -kbd_put_keycode(0xe0); -kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key +qemu_input_event_send_key_number(dcl-con, keycode, false); } break; case NSMouseMoved: -- 1.8.3.1
[Qemu-devel] [PATCH 07/42] input: qapi: add unmapped key
Simplifies building something - QkeyCode mapping tables. Uninitialized entries can easily identified then. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- qapi-schema.json | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qapi-schema.json b/qapi-schema.json index 646d64f..6af22f6 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3429,9 +3429,12 @@ # This is used by the send-key command. # # Since: 1.3.0 +# +# 'unmapped' since 2.0 ## { 'enum': 'QKeyCode', - 'data': [ 'shift', 'shift_r', 'alt', 'alt_r', 'altgr', 'altgr_r', 'ctrl', + 'data': [ 'unmapped', +'shift', 'shift_r', 'alt', 'alt_r', 'altgr', 'altgr_r', 'ctrl', 'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'minus', 'equal', 'backspace', 'tab', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left', 'bracket_right', -- 1.8.3.1
[Qemu-devel] [PATCH 42/42] input: remove index_from_keycode (no users)
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/console.h | 1 - ui/input-legacy.c| 14 -- 2 files changed, 15 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 9a282cb..3bf69ee 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -329,7 +329,6 @@ void curses_display_init(DisplayState *ds, int full_screen); /* input.c */ int index_from_key(const char *key); -int index_from_keycode(int code); /* gtk.c */ void early_gtk_display_init(void); diff --git a/ui/input-legacy.c b/ui/input-legacy.c index b51e6ad..f38984b 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -220,20 +220,6 @@ int index_from_key(const char *key) return i; } -int index_from_keycode(int code) -{ -int i; - -for (i = 0; i Q_KEY_CODE_MAX; i++) { -if (key_defs[i] == code) { -break; -} -} - -/* Return Q_KEY_CODE_MAX if the code is invalid */ -return i; -} - static int *keycodes; static int keycodes_size; static QEMUTimer *key_timer; -- 1.8.3.1
[Qemu-devel] [PATCH 19/42] input: mouse: add helpers functions to core
Likewise a bunch of helper functions to manage mouse button and movement events, again to make life easier for the ui code. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/input.h | 14 +++ ui/input.c | 71 ++ 2 files changed, 85 insertions(+) diff --git a/include/ui/input.h b/include/ui/input.h index 189f131..c6f50c2 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -8,6 +8,8 @@ #define INPUT_EVENT_MASK_REL (1INPUT_EVENT_KIND_REL) #define INPUT_EVENT_MASK_ABS (1INPUT_EVENT_KIND_ABS) +#define INPUT_EVENT_ABS_SIZE 0x8000 + typedef struct QemuInputHandler QemuInputHandler; typedef struct QemuInputHandlerState QemuInputHandlerState; @@ -34,4 +36,16 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down); void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down); void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down); +InputEvent *qemu_input_event_new_btn(InputButton btn, bool down); +void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down); +void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, + uint32_t button_old, uint32_t button_new); + +int qemu_input_scale_axis(int value, int size_in, int size_out); +InputEvent *qemu_input_event_new_move(InputEventKind kind, + InputAxis axis, int value); +void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value); +void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, + int value, int size); + #endif /* INPUT_H */ diff --git a/ui/input.c b/ui/input.c index 61c8089..a02172e 100644 --- a/ui/input.c +++ b/ui/input.c @@ -116,3 +116,74 @@ void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down) key-qcode = q; qemu_input_event_send_key(src, key, down); } + +InputEvent *qemu_input_event_new_btn(InputButton btn, bool down) +{ +InputEvent *evt = g_new0(InputEvent, 1); +evt-btn = g_new0(InputBtnEvent, 1); +evt-kind = INPUT_EVENT_KIND_BTN; +evt-btn-button = btn; +evt-btn-down = down; +return evt; +} + +void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down) +{ +InputEvent *evt; +evt = qemu_input_event_new_btn(btn, down); +qemu_input_event_send(src, evt); +qapi_free_InputEvent(evt); +} + +void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, + uint32_t button_old, uint32_t button_new) +{ +InputButton btn; +uint32_t mask; + +for (btn = 0; btn INPUT_BUTTON_MAX; btn++) { +mask = button_map[btn]; +if ((button_old mask) == (button_new mask)) { +continue; +} +qemu_input_queue_btn(src, btn, button_new mask); +} +} + +int qemu_input_scale_axis(int value, int size_in, int size_out) +{ +if (size_in 2) { +return size_out / 2; +} +return (int64_t)value * (size_out - 1) / (size_in - 1); +} + +InputEvent *qemu_input_event_new_move(InputEventKind kind, + InputAxis axis, int value) +{ +InputEvent *evt = g_new0(InputEvent, 1); +InputMoveEvent *move = g_new0(InputMoveEvent, 1); + +evt-kind = kind; +evt-data = move; +move-axis = axis; +move-value = value; +return evt; +} + +void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value) +{ +InputEvent *evt; +evt = qemu_input_event_new_move(INPUT_EVENT_KIND_REL, axis, value); +qemu_input_event_send(src, evt); +qapi_free_InputEvent(evt); +} + +void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size) +{ +InputEvent *evt; +int scaled = qemu_input_scale_axis(value, size, INPUT_EVENT_ABS_SIZE); +evt = qemu_input_event_new_move(INPUT_EVENT_KIND_ABS, axis, scaled); +qemu_input_event_send(src, evt); +qapi_free_InputEvent(evt); +} -- 1.8.3.1
[Qemu-devel] [PATCH 20/42] input: mouse: add graphic_rotate support
Transform absolute mouse events according to graphic_rotate. Legacy input code does it for both absolute and relative events, but the logic is broken for relative coordinates, so this is most likely not used anyway. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/input.c | 33 + 1 file changed, 33 insertions(+) diff --git a/ui/input.c b/ui/input.c index a02172e..2c4d4d6 100644 --- a/ui/input.c +++ b/ui/input.c @@ -50,6 +50,33 @@ qemu_input_find_handler(uint32_t mask) return NULL; } +static void qemu_input_transform_abs_rotate(InputEvent *evt) +{ +switch (graphic_rotate) { +case 90: +if (evt-abs-axis == INPUT_AXIS_X) { +evt-abs-axis = INPUT_AXIS_Y; +} +if (evt-abs-axis == INPUT_AXIS_Y) { +evt-abs-axis = INPUT_AXIS_X; +evt-abs-axis = INPUT_EVENT_ABS_SIZE - 1 - evt-abs-axis; +} +break; +case 180: +evt-abs-axis = INPUT_EVENT_ABS_SIZE - 1 - evt-abs-axis; +break; +case 270: +if (evt-abs-axis == INPUT_AXIS_X) { +evt-abs-axis = INPUT_AXIS_Y; +evt-abs-axis = INPUT_EVENT_ABS_SIZE - 1 - evt-abs-axis; +} +if (evt-abs-axis == INPUT_AXIS_Y) { +evt-abs-axis = INPUT_AXIS_X; +} +break; +} +} + void qemu_input_event_send(QemuConsole *src, InputEvent *evt) { QemuInputHandlerState *s; @@ -58,6 +85,12 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt) return; } +/* pre processing */ +if (graphic_rotate (evt-kind == INPUT_EVENT_KIND_ABS)) { +qemu_input_transform_abs_rotate(evt); +} + +/* send event */ s = qemu_input_find_handler(1 evt-kind); s-handler-event(s-dev, src, evt); s-events++; -- 1.8.3.1
[Qemu-devel] [PATCH 36/42] input: move mouse mode notifier to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/console.h | 4 include/ui/input.h | 4 ui/input-legacy.c| 34 +- ui/input.c | 30 ++ 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 71a0da3..9a282cb 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -48,10 +48,6 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry); void kbd_put_ledstate(int ledstate); -/* Does the current mouse generate absolute events */ -void qemu_add_mouse_mode_change_notifier(Notifier *notify); -void qemu_remove_mouse_mode_change_notifier(Notifier *notify); - struct MouseTransformInfo { /* Touchscreen resolution */ int x; diff --git a/include/ui/input.h b/include/ui/input.h index 28afc45..4976f3d 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -49,4 +49,8 @@ void qemu_input_queue_rel(QemuConsole *src, InputAxis axis, int value); void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size); +void qemu_input_check_mode_change(void); +void qemu_add_mouse_mode_change_notifier(Notifier *notify); +void qemu_remove_mouse_mode_change_notifier(Notifier *notify); + #endif /* INPUT_H */ diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 26ff06f..7f8e72b 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -65,8 +65,6 @@ static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers); static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers = QTAILQ_HEAD_INITIALIZER(mouse_handlers); -static NotifierList mouse_mode_notifiers = -NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); static const int key_defs[] = { [Q_KEY_CODE_SHIFT] = 0x2a, @@ -364,20 +362,6 @@ void qemu_remove_kbd_event_handler(QEMUPutKbdEntry *entry) g_free(entry); } -static void check_mode_change(void) -{ -static int current_is_absolute; -int is_absolute; - -is_absolute = qemu_input_is_absolute(); - -if (is_absolute != current_is_absolute) { -notifier_list_notify(mouse_mode_notifiers, NULL); -} - -current_is_absolute = is_absolute; -} - static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { @@ -448,8 +432,6 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, s-s = qemu_input_handler_register((DeviceState *)s, s-h); -check_mode_change(); - return s; } @@ -459,8 +441,6 @@ void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry) QTAILQ_INSERT_HEAD(mouse_handlers, entry, node); qemu_input_handler_activate(entry-s); - -check_mode_change(); } void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) @@ -471,8 +451,6 @@ void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) g_free(entry-qemu_put_mouse_event_name); g_free(entry); - -check_mode_change(); } QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func, @@ -551,15 +529,5 @@ void do_mouse_set(Monitor *mon, const QDict *qdict) monitor_printf(mon, Mouse at given index not found\n); } -check_mode_change(); -} - -void qemu_add_mouse_mode_change_notifier(Notifier *notify) -{ -notifier_list_add(mouse_mode_notifiers, notify); -} - -void qemu_remove_mouse_mode_change_notifier(Notifier *notify) -{ -notifier_remove(notify); +qemu_input_check_mode_change(); } diff --git a/ui/input.c b/ui/input.c index 00eef0f..a32bcff 100644 --- a/ui/input.c +++ b/ui/input.c @@ -13,6 +13,8 @@ struct QemuInputHandlerState { }; static QTAILQ_HEAD(, QemuInputHandlerState) handlers = QTAILQ_HEAD_INITIALIZER(handlers); +static NotifierList mouse_mode_notifiers = +NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers); QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, QemuInputHandler *handler) @@ -24,6 +26,8 @@ QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev, s-handler = handler; s-id = id++; QTAILQ_INSERT_TAIL(handlers, s, node); + +qemu_input_check_mode_change(); return s; } @@ -31,12 +35,14 @@ void qemu_input_handler_activate(QemuInputHandlerState *s) { QTAILQ_REMOVE(handlers, s, node); QTAILQ_INSERT_HEAD(handlers, s, node); +qemu_input_check_mode_change(); } void qemu_input_handler_unregister(QemuInputHandlerState *s) { QTAILQ_REMOVE(handlers, s, node); g_free(s); +qemu_input_check_mode_change(); } static QemuInputHandlerState* @@ -276,3 +282,27 @@ void qemu_input_queue_abs(QemuConsole *src, InputAxis axis, int value, int size) qemu_input_event_send(src, evt); qapi_free_InputEvent(evt); } + +void qemu_input_check_mode_change(void) +{ +static int current_is_absolute; +int
[Qemu-devel] [PATCH 37/42] input: add input_mouse_mode tracepoint
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- trace-events | 1 + ui/input.c | 1 + 2 files changed, 2 insertions(+) diff --git a/trace-events b/trace-events index 4b6bb29..04191b7 100644 --- a/trace-events +++ b/trace-events @@ -1027,6 +1027,7 @@ input_event_btn(int conidx, const char *btn, bool down) con %d, button %s, down input_event_rel(int conidx, const char *axis, int value) con %d, axis %s, value %d input_event_abs(int conidx, const char *axis, int value) con %d, axis %s, value 0x%x input_event_sync(void) +input_mouse_mode(int absolute) absolute %d # hw/display/vmware_vga.c vmware_value_read(uint32_t index, uint32_t value) index %d, value 0x%x diff --git a/ui/input.c b/ui/input.c index a32bcff..55449dc 100644 --- a/ui/input.c +++ b/ui/input.c @@ -291,6 +291,7 @@ void qemu_input_check_mode_change(void) is_absolute = qemu_input_is_absolute(); if (is_absolute != current_is_absolute) { +trace_input_mouse_mode(is_absolute); notifier_list_notify(mouse_mode_notifiers, NULL); } -- 1.8.3.1
[Qemu-devel] [PULL 00/42] rework input handling, sdl2 support
Hi, The input layer moves to a model modeled roughly after the linux event layer. It also uses qapi to create all the data types needed. First, because it is convinient to have all the support code generated, and also to make it easier to integrate with qmp some day. Porting work has only be done on the UI side so far. Input device emulation is still to be done. SDL2 consists of dave's original patch with a bunch of cleanups on top. Some of the cleanups depend on the new input layer code, thus the incremental patches are sprinkled all over the patch series for bisectability reasons. v2 fixes a few minor nits pointed out in v1 review. Pull request has the cocoa build fix from Peter squashed in and is otherwise identical to v2. please pull, Gerd The following changes since commit 0169c511554cb0014a00290b0d3d26c31a49818f: Merge remote-tracking branch 'qemu-kvm/uq/master' into staging (2014-01-24 15:52:44 -0800) are available in the git repository at: git://git.kraxel.org/qemu tags/pull-input-1 for you to fetch changes up to 19f3059690bbb1ca6af8277bf262e4b9aea13f8f: input: remove index_from_keycode (no users) (2014-01-28 10:47:54 +0100) Input layer rewrite. SDL2 support. Dave Airlie (1): ui/sdl2 : initial port to SDL 2.0 (v2.0) Gerd Hoffmann (41): sdl2: baum build fix sdl2: remove text console logic console: export QemuConsole index,width,height input: rename file to legacy input: qapi: define event types input: qapi: add unmapped key input: qapi: add pause key input: add core bits of the new input layer input: keyboard: add helper functions to core input: keyboard: switch legacy handlers to new core input: keyboard: switch qmp_send_key() to new core. input: keyboard: switch gtk ui to new core input: keyboard: switch sdl ui to new core sdl2: switch keyboard handling to new core input: keyboard: switch vnc ui to new core input: keyboard: switch spice ui to new core input: keyboard: switch curses ui to new core input: mouse: add helpers functions to core input: mouse: add graphic_rotate support input: mouse: add qemu_input_is_absolute() input: mouse: switch legacy handlers to new core input: mouse: switch gtk ui to new core input: mouse: switch sdl ui to new core sdl2: switch mouse handling to new core input: mouse: switch vnc ui to new core input: mouse: switch spice ui to new core input: mouse: switch monitor to new core input: keyboard: switch cocoa ui to new core input: mouse: switch cocoa ui to new core input: trace events input-legacy: remove kbd_put_keycode input-legacy: remove kbd_mouse_has_absolute input-legacy: remove kbd_mouse_is_absolute input-legacy: remove kbd_mouse_event input: move mouse mode notifier to new core input: add input_mouse_mode tracepoint sdl2: simplify keymap handling sdl2: codestyle fixups input: move qmp_query_mice to new core input: move do_mouse_set to new core input: remove index_from_keycode (no users) backends/baum.c | 4 +- configure| 23 +- include/ui/console.h | 16 +- include/ui/input.h | 56 monitor.c| 31 +- qapi-schema.json | 83 +- trace-events | 9 + ui/Makefile.objs | 6 +- ui/cocoa.m | 81 +++-- ui/console.c | 24 ++ ui/curses.c | 47 +-- ui/gtk.c | 77 ++--- ui/input-legacy.c| 453 ui/input.c | 684 +++--- ui/sdl.c | 114 --- ui/sdl2-keymap.h | 266 + ui/sdl2.c| 829 +++ ui/sdl_keysym.h | 3 +- ui/spice-input.c | 84 -- ui/vnc.c | 71 ++--- ui/vnc.h | 1 + 21 files changed, 2251 insertions(+), 711 deletions(-) create mode 100644 include/ui/input.h create mode 100644 ui/input-legacy.c create mode 100644 ui/sdl2-keymap.h create mode 100644 ui/sdl2.c
[Qemu-devel] [PATCH 24/42] input: mouse: switch sdl ui to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/sdl.c | 84 ++-- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/ui/sdl.c b/ui/sdl.c index c3b8036..c1a16be 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -353,7 +353,7 @@ static void sdl_hide_cursor(void) if (!cursor_hide) return; -if (kbd_mouse_is_absolute()) { +if (qemu_input_is_absolute()) { SDL_ShowCursor(1); SDL_SetCursor(sdl_cursor_hidden); } else { @@ -366,10 +366,10 @@ static void sdl_show_cursor(void) if (!cursor_hide) return; -if (!kbd_mouse_is_absolute() || !qemu_console_is_graphic(NULL)) { +if (!qemu_input_is_absolute() || !qemu_console_is_graphic(NULL)) { SDL_ShowCursor(1); if (guest_cursor -(gui_grab || kbd_mouse_is_absolute() || absolute_enabled)) +(gui_grab || qemu_input_is_absolute() || absolute_enabled)) SDL_SetCursor(guest_sprite); else SDL_SetCursor(sdl_cursor_normal); @@ -388,8 +388,9 @@ static void sdl_grab_start(void) } if (guest_cursor) { SDL_SetCursor(guest_sprite); -if (!kbd_mouse_is_absolute() !absolute_enabled) +if (!qemu_input_is_absolute() !absolute_enabled) { SDL_WarpMouse(guest_x, guest_y); +} } else sdl_hide_cursor(); SDL_WM_GrabInput(SDL_GRAB_ON); @@ -418,7 +419,7 @@ static void absolute_mouse_grab(void) static void sdl_mouse_mode_change(Notifier *notify, void *data) { -if (kbd_mouse_is_absolute()) { +if (qemu_input_is_absolute()) { if (!absolute_enabled) { absolute_enabled = 1; if (qemu_console_is_graphic(NULL)) { @@ -433,33 +434,36 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) } } -static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state) +static void sdl_send_mouse_event(int dx, int dy, int x, int y, int state) { -int buttons = 0; - -if (state SDL_BUTTON(SDL_BUTTON_LEFT)) { -buttons |= MOUSE_EVENT_LBUTTON; -} -if (state SDL_BUTTON(SDL_BUTTON_RIGHT)) { -buttons |= MOUSE_EVENT_RBUTTON; -} -if (state SDL_BUTTON(SDL_BUTTON_MIDDLE)) { -buttons |= MOUSE_EVENT_MBUTTON; -} - -if (kbd_mouse_is_absolute()) { -dx = x * 0x7FFF / (real_screen-w - 1); -dy = y * 0x7FFF / (real_screen-h - 1); +static uint32_t bmap[INPUT_BUTTON_MAX] = { +[INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), +[INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), +[INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), +[INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), +[INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), +}; +static uint32_t prev_state; + +if (prev_state != state) { +qemu_input_update_buttons(dcl-con, bmap, prev_state, state); +prev_state = state; +} + +if (qemu_input_is_absolute()) { +qemu_input_queue_abs(dcl-con, INPUT_AXIS_X, x, + real_screen-w); +qemu_input_queue_abs(dcl-con, INPUT_AXIS_Y, y, + real_screen-h); } else if (guest_cursor) { x -= guest_x; y -= guest_y; guest_x += x; guest_y += y; -dx = x; -dy = y; +qemu_input_queue_rel(dcl-con, INPUT_AXIS_X, x); +qemu_input_queue_rel(dcl-con, INPUT_AXIS_Y, y); } - -kbd_mouse_event(dx, dy, dz, buttons); +qemu_input_event_sync(); } static void sdl_scale(int width, int height) @@ -687,7 +691,7 @@ static void handle_mousemotion(SDL_Event *ev) int max_x, max_y; if (qemu_console_is_graphic(NULL) -(kbd_mouse_is_absolute() || absolute_enabled)) { +(qemu_input_is_absolute() || absolute_enabled)) { max_x = real_screen-w - 1; max_y = real_screen-h - 1; if (gui_grab (ev-motion.x == 0 || ev-motion.y == 0 || @@ -700,8 +704,8 @@ static void handle_mousemotion(SDL_Event *ev) sdl_grab_start(); } } -if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) { -sdl_send_mouse_event(ev-motion.xrel, ev-motion.yrel, 0, +if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { +sdl_send_mouse_event(ev-motion.xrel, ev-motion.yrel, ev-motion.x, ev-motion.y, ev-motion.state); } } @@ -710,35 +714,24 @@ static void handle_mousebutton(SDL_Event *ev) { int buttonstate = SDL_GetMouseState(NULL, NULL); SDL_MouseButtonEvent *bev; -int dz; if (!qemu_console_is_graphic(NULL)) { return; } bev = ev-button; -if (!gui_grab !kbd_mouse_is_absolute()) { +if (!gui_grab !qemu_input_is_absolute()) { if (ev-type == SDL_MOUSEBUTTONUP bev-button == SDL_BUTTON_LEFT) {
[Qemu-devel] [PATCH 41/42] input: move do_mouse_set to new core
This removes the last user of the lecagy input mouse handler list, so we can remove more legacy bits with this. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/input-legacy.c | 43 --- ui/input.c| 21 + 2 files changed, 21 insertions(+), 43 deletions(-) diff --git a/ui/input-legacy.c b/ui/input-legacy.c index 7843482..b51e6ad 100644 --- a/ui/input-legacy.c +++ b/ui/input-legacy.c @@ -35,12 +35,6 @@ struct QEMUPutMouseEntry { QEMUPutMouseEvent *qemu_put_mouse_event; void *qemu_put_mouse_event_opaque; int qemu_put_mouse_event_absolute; -char *qemu_put_mouse_event_name; - -int index; - -/* used internally by qemu for handling mice */ -QTAILQ_ENTRY(QEMUPutMouseEntry) node; /* new input core */ QemuInputHandler h; @@ -412,17 +406,12 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, const char *name) { QEMUPutMouseEntry *s; -static int mouse_index = 0; s = g_malloc0(sizeof(QEMUPutMouseEntry)); s-qemu_put_mouse_event = func; s-qemu_put_mouse_event_opaque = opaque; s-qemu_put_mouse_event_absolute = absolute; -s-qemu_put_mouse_event_name = g_strdup(name); -s-index = mouse_index++; - -QTAILQ_INSERT_TAIL(mouse_handlers, s, node); s-h.name = name; s-h.mask = INPUT_EVENT_MASK_BTN | @@ -437,19 +426,13 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry) { -QTAILQ_REMOVE(mouse_handlers, entry, node); -QTAILQ_INSERT_HEAD(mouse_handlers, entry, node); - qemu_input_handler_activate(entry-s); } void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry) { -QTAILQ_REMOVE(mouse_handlers, entry, node); - qemu_input_handler_unregister(entry-s); -g_free(entry-qemu_put_mouse_event_name); g_free(entry); } @@ -482,29 +465,3 @@ void kbd_put_ledstate(int ledstate) cursor-put_led(cursor-opaque, ledstate); } } - -void do_mouse_set(Monitor *mon, const QDict *qdict) -{ -QEMUPutMouseEntry *cursor; -int index = qdict_get_int(qdict, index); -int found = 0; - -if (QTAILQ_EMPTY(mouse_handlers)) { -monitor_printf(mon, No mouse devices connected\n); -return; -} - -QTAILQ_FOREACH(cursor, mouse_handlers, node) { -if (cursor-index == index) { -found = 1; -qemu_activate_mouse_event_handler(cursor); -break; -} -} - -if (!found) { -monitor_printf(mon, Mouse at given index not found\n); -} - -qemu_input_check_mode_change(); -} diff --git a/ui/input.c b/ui/input.c index 2945a3c..575c50e 100644 --- a/ui/input.c +++ b/ui/input.c @@ -336,3 +336,24 @@ MouseInfoList *qmp_query_mice(Error **errp) return mice_list; } + +void do_mouse_set(Monitor *mon, const QDict *qdict) +{ +QemuInputHandlerState *s; +int index = qdict_get_int(qdict, index); +int found = 0; + +QTAILQ_FOREACH(s, handlers, node) { +if (s-id == index) { +found = 1; +qemu_input_handler_activate(s); +break; +} +} + +if (!found) { +monitor_printf(mon, Mouse at given index not found\n); +} + +qemu_input_check_mode_change(); +} -- 1.8.3.1
[Qemu-devel] [PATCH 30/42] input: mouse: switch cocoa ui to new core
Build fixes by Peter Maydell. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/console.h | 2 ++ ui/cocoa.m | 63 ++-- 2 files changed, 44 insertions(+), 21 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 8543d18..a3062d0 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -14,6 +14,8 @@ #define MOUSE_EVENT_LBUTTON 0x01 #define MOUSE_EVENT_RBUTTON 0x02 #define MOUSE_EVENT_MBUTTON 0x04 +#define MOUSE_EVENT_WHEELUP 0x08 +#define MOUSE_EVENT_WHEELDN 0x10 /* identical to the ps/2 keyboard bits */ #define QEMU_SCROLL_LOCK_LED (1 0) diff --git a/ui/cocoa.m b/ui/cocoa.m index d4af3e5..f20fd1f 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -27,6 +27,7 @@ #include qemu-common.h #include ui/console.h +#include ui/input.h #include sysemu/sysemu.h #ifndef MAC_OS_X_VERSION_10_4 @@ -49,14 +50,6 @@ #endif #define cgrect(nsrect) (*(CGRect *)(nsrect)) -#define COCOA_MOUSE_EVENT \ -if (isTabletEnabled) { \ -kbd_mouse_event((int)(p.x * 0x7FFF / (screen.width - 1)), (int)((screen.height - p.y) * 0x7FFF / (screen.height - 1)), 0, buttons); \ -} else if (isMouseGrabbed) { \ -kbd_mouse_event((int)[event deltaX], (int)[event deltaY], 0, buttons); \ -} else { \ -[NSApp sendEvent:event]; \ -} typedef struct { int width; @@ -67,6 +60,7 @@ typedef struct { NSWindow *normalWindow; static DisplayChangeListener *dcl; +static int last_buttons; int gArgc; char **gArgv; @@ -501,6 +495,7 @@ QemuCocoaView *cocoaView; int buttons = 0; int keycode; +bool mouse_event = false; NSPoint p = [event locationInWindow]; switch ([event type]) { @@ -620,7 +615,7 @@ QemuCocoaView *cocoaView; } } } -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSLeftMouseDown: if ([event modifierFlags] NSCommandKeyMask) { @@ -628,15 +623,15 @@ QemuCocoaView *cocoaView; } else { buttons |= MOUSE_EVENT_LBUTTON; } -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSRightMouseDown: buttons |= MOUSE_EVENT_RBUTTON; -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSOtherMouseDown: buttons |= MOUSE_EVENT_MBUTTON; -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSLeftMouseDragged: if ([event modifierFlags] NSCommandKeyMask) { @@ -644,19 +639,19 @@ QemuCocoaView *cocoaView; } else { buttons |= MOUSE_EVENT_LBUTTON; } -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSRightMouseDragged: buttons |= MOUSE_EVENT_RBUTTON; -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSOtherMouseDragged: buttons |= MOUSE_EVENT_MBUTTON; -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSLeftMouseUp: if (isTabletEnabled) { -COCOA_MOUSE_EVENT +mouse_event = true; } else if (!isMouseGrabbed) { if (p.x -1 p.x screen.width p.y -1 p.y screen.height) { [self grabMouse]; @@ -664,18 +659,20 @@ QemuCocoaView *cocoaView; [NSApp sendEvent:event]; } } else { -COCOA_MOUSE_EVENT +mouse_event = true; } break; case NSRightMouseUp: -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSOtherMouseUp: -COCOA_MOUSE_EVENT +mouse_event = true; break; case NSScrollWheel: if (isTabletEnabled || isMouseGrabbed) { -kbd_mouse_event(0, 0, -[event deltaY], 0); +buttons |= ([event deltaY] 0) ? +MOUSE_EVENT_WHEELUP : MOUSE_EVENT_WHEELDN; +mouse_event = true; } else { [NSApp sendEvent:event]; } @@ -683,6 +680,30 @@ QemuCocoaView *cocoaView; default: [NSApp sendEvent:event]; } + +if (mouse_event) { +if (last_buttons != buttons) { +static uint32_t bmap[INPUT_BUTTON_MAX] = { +[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, +[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, +[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, +[INPUT_BUTTON_WHEEL_UP] = MOUSE_EVENT_WHEELUP, +[INPUT_BUTTON_WHEEL_DOWN] = MOUSE_EVENT_WHEELDN, +}; +
[Qemu-devel] [PATCH 38/42] sdl2: simplify keymap handling
sdl2 gives us scancodes (i.e. identifies keys by location not by keysym mapped to it). We can map them directly to QKeyCodes, pass them on to the new input core and be done with it. No need to jump though any keymap hops. Zap the code. Also operate directly on SDL scancodes for any hotkeys. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/sdl2-keymap.h | 266 +++ ui/sdl2.c| 147 ++-- ui/sdl2_scancode_translate.h | 260 -- 3 files changed, 298 insertions(+), 375 deletions(-) create mode 100644 ui/sdl2-keymap.h delete mode 100644 ui/sdl2_scancode_translate.h diff --git a/ui/sdl2-keymap.h b/ui/sdl2-keymap.h new file mode 100644 index 000..5a12f45 --- /dev/null +++ b/ui/sdl2-keymap.h @@ -0,0 +1,266 @@ + +/* map SDL2 scancodes to QKeyCode */ + +static const int sdl2_scancode_to_qcode[SDL_NUM_SCANCODES] = { +[SDL_SCANCODE_A] = Q_KEY_CODE_A, +[SDL_SCANCODE_B] = Q_KEY_CODE_B, +[SDL_SCANCODE_C] = Q_KEY_CODE_C, +[SDL_SCANCODE_D] = Q_KEY_CODE_D, +[SDL_SCANCODE_E] = Q_KEY_CODE_E, +[SDL_SCANCODE_F] = Q_KEY_CODE_F, +[SDL_SCANCODE_G] = Q_KEY_CODE_G, +[SDL_SCANCODE_H] = Q_KEY_CODE_H, +[SDL_SCANCODE_I] = Q_KEY_CODE_I, +[SDL_SCANCODE_J] = Q_KEY_CODE_J, +[SDL_SCANCODE_K] = Q_KEY_CODE_K, +[SDL_SCANCODE_L] = Q_KEY_CODE_L, +[SDL_SCANCODE_M] = Q_KEY_CODE_M, +[SDL_SCANCODE_N] = Q_KEY_CODE_N, +[SDL_SCANCODE_O] = Q_KEY_CODE_O, +[SDL_SCANCODE_P] = Q_KEY_CODE_P, +[SDL_SCANCODE_Q] = Q_KEY_CODE_Q, +[SDL_SCANCODE_R] = Q_KEY_CODE_R, +[SDL_SCANCODE_S] = Q_KEY_CODE_S, +[SDL_SCANCODE_T] = Q_KEY_CODE_T, +[SDL_SCANCODE_U] = Q_KEY_CODE_U, +[SDL_SCANCODE_V] = Q_KEY_CODE_V, +[SDL_SCANCODE_W] = Q_KEY_CODE_W, +[SDL_SCANCODE_X] = Q_KEY_CODE_X, +[SDL_SCANCODE_Y] = Q_KEY_CODE_Y, +[SDL_SCANCODE_Z] = Q_KEY_CODE_Z, + +[SDL_SCANCODE_1] = Q_KEY_CODE_1, +[SDL_SCANCODE_2] = Q_KEY_CODE_2, +[SDL_SCANCODE_3] = Q_KEY_CODE_3, +[SDL_SCANCODE_4] = Q_KEY_CODE_4, +[SDL_SCANCODE_5] = Q_KEY_CODE_5, +[SDL_SCANCODE_6] = Q_KEY_CODE_6, +[SDL_SCANCODE_7] = Q_KEY_CODE_7, +[SDL_SCANCODE_8] = Q_KEY_CODE_8, +[SDL_SCANCODE_9] = Q_KEY_CODE_9, +[SDL_SCANCODE_0] = Q_KEY_CODE_0, + +[SDL_SCANCODE_RETURN]= Q_KEY_CODE_RET, +[SDL_SCANCODE_ESCAPE]= Q_KEY_CODE_ESC, +[SDL_SCANCODE_BACKSPACE] = Q_KEY_CODE_BACKSPACE, +[SDL_SCANCODE_TAB] = Q_KEY_CODE_TAB, +[SDL_SCANCODE_SPACE] = Q_KEY_CODE_SPC, +[SDL_SCANCODE_MINUS] = Q_KEY_CODE_MINUS, +[SDL_SCANCODE_EQUALS]= Q_KEY_CODE_EQUAL, +[SDL_SCANCODE_LEFTBRACKET] = Q_KEY_CODE_BRACKET_LEFT, +[SDL_SCANCODE_RIGHTBRACKET] = Q_KEY_CODE_BRACKET_RIGHT, +[SDL_SCANCODE_BACKSLASH] = Q_KEY_CODE_BACKSLASH, +#if 0 +[SDL_SCANCODE_NONUSHASH] = Q_KEY_CODE_NONUSHASH, +#endif +[SDL_SCANCODE_SEMICOLON] = Q_KEY_CODE_SEMICOLON, +[SDL_SCANCODE_APOSTROPHE]= Q_KEY_CODE_APOSTROPHE, +[SDL_SCANCODE_GRAVE] = Q_KEY_CODE_GRAVE_ACCENT, +[SDL_SCANCODE_COMMA] = Q_KEY_CODE_COMMA, +[SDL_SCANCODE_PERIOD]= Q_KEY_CODE_DOT, +[SDL_SCANCODE_SLASH] = Q_KEY_CODE_SLASH, +[SDL_SCANCODE_CAPSLOCK] = Q_KEY_CODE_CAPS_LOCK, + +[SDL_SCANCODE_F1]= Q_KEY_CODE_F1, +[SDL_SCANCODE_F2]= Q_KEY_CODE_F2, +[SDL_SCANCODE_F3]= Q_KEY_CODE_F3, +[SDL_SCANCODE_F4]= Q_KEY_CODE_F4, +[SDL_SCANCODE_F5]= Q_KEY_CODE_F5, +[SDL_SCANCODE_F6]= Q_KEY_CODE_F6, +[SDL_SCANCODE_F7]= Q_KEY_CODE_F7, +[SDL_SCANCODE_F8]= Q_KEY_CODE_F8, +[SDL_SCANCODE_F9]= Q_KEY_CODE_F9, +[SDL_SCANCODE_F10] = Q_KEY_CODE_F10, +[SDL_SCANCODE_F11] = Q_KEY_CODE_F11, +[SDL_SCANCODE_F12] = Q_KEY_CODE_F12, + +[SDL_SCANCODE_PRINTSCREEN] = Q_KEY_CODE_PRINT, +[SDL_SCANCODE_SCROLLLOCK]= Q_KEY_CODE_SCROLL_LOCK, +[SDL_SCANCODE_PAUSE] = Q_KEY_CODE_PAUSE, +[SDL_SCANCODE_INSERT]= Q_KEY_CODE_INSERT, +[SDL_SCANCODE_HOME] = Q_KEY_CODE_HOME, +[SDL_SCANCODE_PAGEUP]
Re: [Qemu-devel] [PATCH v3 19/19] bsd-user: fix linking conflicts with FreeBSD libcrypto
Il 27/01/2014 21:07, Peter Maydell ha scritto: You never answered Paolo's question about this patch, I think: What is the error? Do the functions have different signatures or semantics between QEMU and FreeBSD? If we need to resolve a clash, maybe we should just rename the QEMU versions. Paolo? Yeah, but it looks like there's no clash. Perhaps we can use libcrypto if present, and only include aes.c if libcrypto is not there. Paolo
[Qemu-devel] [PATCH 39/42] sdl2: codestyle fixups
--- ui/Makefile.objs | 2 +- ui/sdl2.c| 173 +-- 2 files changed, 104 insertions(+), 71 deletions(-) diff --git a/ui/Makefile.objs b/ui/Makefile.objs index e6a5ec1..6f2294e 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -15,6 +15,6 @@ common-obj-$(CONFIG_CURSES) += curses.o common-obj-$(CONFIG_VNC) += $(vnc-obj-y) common-obj-$(CONFIG_GTK) += gtk.o x_keymap.o -$(obj)/sdl.o $(obj)/sdl_zoom.o $(obj)/sdl2.o: QEMU_CFLAGS += $(SDL_CFLAGS) +$(obj)/sdl.o $(obj)/sdl_zoom.o $(obj)/sdl2.o: QEMU_CFLAGS += $(SDL_CFLAGS) $(obj)/gtk.o: QEMU_CFLAGS += $(GTK_CFLAGS) $(VTE_CFLAGS) diff --git a/ui/sdl2.c b/ui/sdl2.c index 5338b90..f1532e9 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -40,7 +40,7 @@ #include sdl2-keymap.h static int sdl2_num_outputs; -static struct sdl2_console_state { +static struct sdl2_state { DisplayChangeListener dcl; DisplaySurface *surface; SDL_Texture *texture; @@ -66,21 +66,22 @@ static int gui_grab_code = KMOD_LALT | KMOD_LCTRL; static uint8_t modifiers_state[SDL_NUM_SCANCODES]; static SDL_Cursor *sdl_cursor_normal; static SDL_Cursor *sdl_cursor_hidden; -static int absolute_enabled = 0; -static int guest_cursor = 0; +static int absolute_enabled; +static int guest_cursor; static int guest_x, guest_y; -static SDL_Cursor *guest_sprite = NULL; -static int scaling_active = 0; +static SDL_Cursor *guest_sprite; +static int scaling_active; static Notifier mouse_mode_notifier; -static void sdl_update_caption(struct sdl2_console_state *scon); +static void sdl_update_caption(struct sdl2_state *scon); -static struct sdl2_console_state *get_scon_from_window(uint32_t window_id) +static struct sdl2_state *get_scon_from_window(uint32_t window_id) { int i; for (i = 0; i sdl2_num_outputs; i++) { -if (sdl2_console[i].real_window == SDL_GetWindowFromID(window_id)) +if (sdl2_console[i].real_window == SDL_GetWindowFromID(window_id)) { return sdl2_console[i]; +} } return NULL; } @@ -88,14 +89,16 @@ static struct sdl2_console_state *get_scon_from_window(uint32_t window_id) static void sdl_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { -struct sdl2_console_state *scon = container_of(dcl, struct sdl2_console_state, dcl); +struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl); SDL_Rect rect; DisplaySurface *surf = qemu_console_surface(dcl-con); -if (!surf) +if (!surf) { return; -if (!scon-texture) +} +if (!scon-texture) { return; +} rect.x = x; rect.y = y; @@ -108,14 +111,14 @@ static void sdl_update(DisplayChangeListener *dcl, SDL_RenderPresent(scon-real_renderer); } -static void do_sdl_resize(struct sdl2_console_state *scon, int width, int height, int bpp) +static void do_sdl_resize(struct sdl2_state *scon, int width, int height, + int bpp) { int flags; if (scon-real_window scon-real_renderer) { if (width height) { SDL_RenderSetLogicalSize(scon-real_renderer, width, height); - SDL_SetWindowSize(scon-real_window, width, height); } else { SDL_DestroyRenderer(scon-real_renderer); @@ -128,10 +131,11 @@ static void do_sdl_resize(struct sdl2_console_state *scon, int width, int height return; } flags = 0; -if (gui_fullscreen) +if (gui_fullscreen) { flags |= SDL_WINDOW_FULLSCREEN; -else +} else { flags |= SDL_WINDOW_RESIZABLE; +} scon-real_window = SDL_CreateWindow(, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, @@ -144,7 +148,7 @@ static void do_sdl_resize(struct sdl2_console_state *scon, int width, int height static void sdl_switch(DisplayChangeListener *dcl, DisplaySurface *new_surface) { -struct sdl2_console_state *scon = container_of(dcl, struct sdl2_console_state, dcl); +struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl); int format = 0; int idx = scon-idx; DisplaySurface *old_surface = scon-surface; @@ -154,13 +158,16 @@ static void sdl_switch(DisplayChangeListener *dcl, scon-surface = new_surface; } -if (!new_surface idx 0) +if (!new_surface idx 0) { scon-surface = NULL; +} -if (new_surface == NULL) +if (new_surface == NULL) { do_sdl_resize(scon, 0, 0, 0); -else -do_sdl_resize(scon, surface_width(scon-surface), surface_height(scon-surface), 0); +} else { +do_sdl_resize(scon, surface_width(scon-surface), + surface_height(scon-surface), 0); +} if (old_surface scon-texture) { SDL_DestroyTexture(scon-texture); @@ -169,14 +176,16 @@ static void sdl_switch(DisplayChangeListener
[Qemu-devel] [PATCH 05/42] input: rename file to legacy
Rename ui/input.c to ui/input-legacy.c. We are going to replace it step by step. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/Makefile.objs | 2 +- ui/{input.c = input-legacy.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename ui/{input.c = input-legacy.c} (100%) diff --git a/ui/Makefile.objs b/ui/Makefile.objs index 721ad37..16db07a 100644 --- a/ui/Makefile.objs +++ b/ui/Makefile.objs @@ -7,7 +7,7 @@ vnc-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o vnc-obj-$(CONFIG_VNC_WS) += vnc-ws.o vnc-obj-y += vnc-jobs.o -common-obj-y += keymaps.o console.o cursor.o input.o qemu-pixman.o +common-obj-y += keymaps.o console.o cursor.o input-legacy.o qemu-pixman.o common-obj-$(CONFIG_SPICE) += spice-core.o spice-input.o spice-display.o common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o sdl2.o common-obj-$(CONFIG_COCOA) += cocoa.o diff --git a/ui/input.c b/ui/input-legacy.c similarity index 100% rename from ui/input.c rename to ui/input-legacy.c -- 1.8.3.1
[Qemu-devel] input, virtio-vga multihead -- current state
Hi, Input layer + sdl2 pull request just sent. So the first bits will hopefully be merged soon. On top of that I've been working on some multihead and virtio gpu/vga bits. Current state is here: http://www.kraxel.org/cgit/qemu/log/?h=rebase/input-wip Commits are baby steps, build fixes not squashed in yet, commit log needs more info, ... On multihead: * QemuConsole got a new 'head' field for devices with multiple heads, with some infrastructure (func to query head etc.). * Created QemuUIInfo struct. Each QemuConsole gets one of these assigned. It is supposed to carry hints from the UI code for the graphics emulation. For now it carries the window geometry. I think edid information should live there too. Maybe even replace width+height. * gfx hardware - ui notification on head geometry is still to be done. * Dave used dpy_gfx_replace_surface(con, NULL) to disable heads. Nice idea. /me fixed spice to handle that correctly. On virtio-vga: * Both virtio-gpu-pci and virtio-vga are children of virtio-pci-proxy now. * Didn't came very far in testing. Guest kernel just says: [ 50.712897] [drm] got -2147483647 outputs I've used http://cgit.freedesktop.org/~airlied/linux/log/?h=virtio-vga Ideas? cheers, Gerd
[Qemu-devel] check trim/unmap
Hello developers, i am trying to test trim/unmap of qemu. My config is Gentoo x64 stable branch, kernel 3.10, libvirt 1.1.3, qemu 1.5, lvm2(non-thin) on ssd How can i check that if: 1. qemu receives trim/unmap from guest 2. qemu is punching hole/issue blkdiscards/writing zeros? Thanks in advance. ching
Re: [Qemu-devel] fix/re-do query-command-line-options
Il 28/01/2014 10:36, Markus Armbruster ha scritto: I think the data you can usefully collect with this approach is approximately the data getopt_long()[*] gets: list of named command line options, and whether they take an argument. You can use this data to fill in options not covered by QemuOpts. This is a definite improvement. It still falls short of fully solving the command line introspection problem. However, I'm not into rejecting imperfect incremental improvements we can have now in favor of perfect solutions we can maybe have some day. Go right ahead with your incremental improvement! It depends. If we can agree on the following: (a) do not add non-QemuOpts options (we haven't for a while) (b) document the QemuOpts schema for -acpitable, -smbios, -netdev, -net. These options validate the options with OptsVisitor, so we could do without QemuOpts schema, but we know the schema won't bitrot because we never remove suboptions. (c) do not add any more QemuOpts options without a schema, and use -object instead. Then: (a) there is no need to cover non-QemuOpts options in query-command-line-options. libvirt can treat them as crystallized. (b) documenting the schemata is not harder than what Amos proposed. (c) schema inspection for objects remains a problem, but one that we need to solve anyway so it doesn't affect query-command-line-options. Do you agree? Paolo
Re: [Qemu-devel] [PATCH v4 1/3] util/fifo8: implement push/pop of multiple bytes
On 28 January 2014 00:04, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: On Tue, Jan 28, 2014 at 4:32 AM, Peter Maydell peter.mayd...@linaro.org wrote: void fifo8_reset(Fifo8 *fifo) { fifo-num = 0; +fifo-head = 0; This is a bug fix, right? It should go in its own patch. No bug - where the ring buffer starts following a reset is undefined and need not be defined. But it improves the predicatability of the newly added pop_buf fn as you can now following a reset, guarantee that a single pop_buf will take all contents if its the first pop (which is how its being used in P2). True. I still think it should have its own patch (and indeed it would be worth saying what you just did as part of the commit message for that patch...) I think it's also nicer for any state that gets migrated to be reset cleanly. thanks -- PMM
Re: [Qemu-devel] [PATCH v4 4/5] qmp: full introspection support for QMP
On Mon, Jan 27, 2014 at 06:46:31PM +0800, Fam Zheng wrote: On Mon, 01/27 10:38, Paolo Bonzini wrote: Il 27/01/2014 09:17, Amos Kong ha scritto: CC Libvirt-list Original discussion: http://marc.info/?l=qemu-develm=139048842504757w=2 [Qemu-devel] [PATCH v4 0/5] QMP full introspection On Fri, Jan 24, 2014 at 06:48:31PM +0800, Fam Zheng wrote: On Thu, 01/23 22:46, Amos Kong wrote: This patch introduces a new monitor command to query QMP schema information, the return data is a range of schema structs, which contains the useful metadata to help management to check supported features, QMP commands detail, etc. We use qapi-introspect.py to parse all json definition in qapi-schema.json, and generate a range of dictionaries with metadata. The query command will visit the dictionaries and fill the data to allocated struct tree. Then QMP infrastructure will convert the tree to json string and return to QMP client. TODO: Wenchao Xia is working to convert QMP events to qapi-schema.json, then event can also be queried by this interface. I will introduce another command 'query-qga-schema' to query QGA schema information, it's easy to add this support based on this patch. Signed-off-by: Amos Kong ak...@redhat.com --- qapi-schema.json | 11 +++ qmp-commands.hx | 42 +++ qmp.c| 215 +++ 3 files changed, 268 insertions(+) diff --git a/qapi-schema.json b/qapi-schema.json index c63f0ca..6033383 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4411,3 +4411,14 @@ 'reference-type': 'String', 'type': 'DataObjectType', 'unionobj': 'DataObjectUnion' } } + +## +# @query-qmp-schema +# +# Query QMP schema information +# +# @returns: list of @DataObject +# +# Since: 1.8 +## +{ 'command': 'query-qmp-schema', 'returns': ['DataObject'] } diff --git a/qmp-commands.hx b/qmp-commands.hx index 02cc815..b83762d 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -3291,6 +3291,48 @@ Example: } EQMP +{ +.name = query-qmp-schema, +.args_type = , +.mhandler.cmd_new = qmp_marshal_input_query_qmp_schema, +}, + + +SQMP +query-qmp-schema + + +query qmp schema information + +Return a json-object with the following information: + +- name: qmp schema name (json-string) +- type: qmp schema type, it can be 'comand', 'type', 'enum', 'union' +- returns: return data of qmp command (json-object, optional) + +Example: + +- { execute: query-qmp-schema } +- { return: [ + { + name: query-name, + type: command, + returns: { + name: NameInfo, + type: type, + data: [ + { + name: name, + optional: true, + recursive: false, + type: str + } + ] + } + } + } + +EQMP { .name = blockdev-add, diff --git a/qmp.c b/qmp.c index 0f46171..a64ae6d 100644 --- a/qmp.c +++ b/qmp.c @@ -27,6 +27,8 @@ #include qapi/qmp/qobject.h #include qapi/qmp-input-visitor.h #include hw/boards.h +#include qapi/qmp/qjson.h +#include qapi-introspect.h NameInfo *qmp_query_name(Error **errp) { @@ -488,6 +490,219 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp) return arch_query_cpu_definitions(errp); } +static strList *qobject_to_strlist(QObject *data) +{ +strList *list = NULL; +strList **plist = list; +QList *qlist; +const QListEntry *lent; + +qlist = qobject_to_qlist(data); +for (lent = qlist_first(qlist); lent; lent = qlist_next(lent)) { +strList *entry = g_malloc0(sizeof(strList)); +entry-value = g_strdup(qobject_get_str(lent-value)); +*plist = entry; +plist = entry-next; +} + +return list; +} + +static DataObject *qobject_to_dataobj(QObject *data); + +static DataObjectMember *qobject_to_dataobjmem(QObject *data) +{ + +DataObjectMember *member = g_malloc0(sizeof(DataObjectMember)); + +member-type = g_malloc0(sizeof(DataObjectMemberType)); +if (data-type-code == QTYPE_QDICT) { +member-type-kind = DATA_OBJECT_MEMBER_TYPE_KIND_EXTEND; +member-type-extend = qobject_to_dataobj(data); +} else { +member-type-kind = DATA_OBJECT_MEMBER_TYPE_KIND_REFERENCE; +member-type-reference = g_strdup(qobject_get_str(data)); +} + +return member; +} + +static DataObjectMemberList *qobject_to_dict_memlist(QObject *data) +{ +DataObjectMemberList *list = NULL; +DataObjectMemberList **plist = list; +QDict *qdict = qobject_to_qdict(data); +
Re: [Qemu-devel] check trim/unmap
Il 28/01/2014 11:31, ching ha scritto: My config is Gentoo x64 stable branch, kernel 3.10, libvirt 1.1.3, qemu 1.5, lvm2(non-thin) on ssd How can i check that if: 1. qemu receives trim/unmap from guest 2. qemu is punching hole/issue blkdiscards/writing zeros? First of all, I suggest that you use current QEMU git. The trim/unmap feature was completed after 1.7 was released. To use trim/discard, you need to use the discard=on option for QEMU's -drive command-line option. You also need to use cache=none (because of a Linux kernel bug, QEMU may disable thin provisioning in other cache modes). In libvirt, this means adding cache='none and discard='on' like this: driver name='qemu' type='qcow2' cache='none' discard='on'/ You can check if QEMU is punching a hole into a file using qemu-img map on the file. You must not run qemu-img map while the VM is running though; that can give incorrect results. There is no equivalent for block devices yet. Paolo
[Qemu-devel] [PATCH 31/42] input: trace events
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- trace-events | 8 ui/input.c | 48 2 files changed, 56 insertions(+) diff --git a/trace-events b/trace-events index 1b668d1..4b6bb29 100644 --- a/trace-events +++ b/trace-events @@ -1020,6 +1020,14 @@ gd_switch(int width, int height) width=%d, height=%d gd_update(int x, int y, int w, int h) x=%d, y=%d, w=%d, h=%d gd_key_event(int gdk_keycode, int qemu_keycode, const char *action) translated GDK keycode %d to QEMU keycode %d (%s) +# ui/input.c +input_event_key_number(int conidx, int number, bool down) con %d, key number 0x%d, down %d +input_event_key_qcode(int conidx, const char *qcode, bool down) con %d, key qcode %s, down %d +input_event_btn(int conidx, const char *btn, bool down) con %d, button %s, down %d +input_event_rel(int conidx, const char *axis, int value) con %d, axis %s, value %d +input_event_abs(int conidx, const char *axis, int value) con %d, axis %s, value 0x%x +input_event_sync(void) + # hw/display/vmware_vga.c vmware_value_read(uint32_t index, uint32_t value) index %d, value 0x%x vmware_value_write(uint32_t index, uint32_t value) index %d, value 0x%x diff --git a/ui/input.c b/ui/input.c index 30a5b70..00eef0f 100644 --- a/ui/input.c +++ b/ui/input.c @@ -1,6 +1,8 @@ #include sysemu/sysemu.h #include qapi-types.h +#include trace.h #include ui/input.h +#include ui/console.h struct QemuInputHandlerState { DeviceState *dev; @@ -77,6 +79,48 @@ static void qemu_input_transform_abs_rotate(InputEvent *evt) } } +static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt) +{ +const char *name; +int idx = -1; + +if (src) { +idx = qemu_console_get_index(src); +} +switch (evt-kind) { +case INPUT_EVENT_KIND_KEY: +switch (evt-key-key-kind) { +case KEY_VALUE_KIND_NUMBER: +trace_input_event_key_number(idx, evt-key-key-number, + evt-key-down); +break; +case KEY_VALUE_KIND_QCODE: +name = QKeyCode_lookup[evt-key-key-qcode]; +trace_input_event_key_qcode(idx, name, evt-key-down); +break; +case KEY_VALUE_KIND_MAX: +/* keep gcc happy */ +break; +} +break; +case INPUT_EVENT_KIND_BTN: +name = InputButton_lookup[evt-btn-button]; +trace_input_event_btn(idx, name, evt-btn-down); +break; +case INPUT_EVENT_KIND_REL: +name = InputAxis_lookup[evt-rel-axis]; +trace_input_event_rel(idx, name, evt-rel-value); +break; +case INPUT_EVENT_KIND_ABS: +name = InputAxis_lookup[evt-abs-axis]; +trace_input_event_abs(idx, name, evt-abs-value); +break; +case INPUT_EVENT_KIND_MAX: +/* keep gcc happy */ +break; +} +} + void qemu_input_event_send(QemuConsole *src, InputEvent *evt) { QemuInputHandlerState *s; @@ -85,6 +129,8 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt) return; } +qemu_input_event_trace(src, evt); + /* pre processing */ if (graphic_rotate (evt-kind == INPUT_EVENT_KIND_ABS)) { qemu_input_transform_abs_rotate(evt); @@ -104,6 +150,8 @@ void qemu_input_event_sync(void) return; } +trace_input_event_sync(); + QTAILQ_FOREACH(s, handlers, node) { if (!s-events) { continue; -- 1.8.3.1
[Qemu-devel] [PATCH 10/42] input: keyboard: add helper functions to core
A bunch of helper functions to manage keyboard events, to make life simpler for the ui code when submitting keyboard events. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/input.h | 5 + ui/input.c | 35 +++ 2 files changed, 40 insertions(+) diff --git a/include/ui/input.h b/include/ui/input.h index 3cf3641..189f131 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -29,4 +29,9 @@ void qemu_input_handler_unregister(QemuInputHandlerState *s); void qemu_input_event_send(QemuConsole *src, InputEvent *evt); void qemu_input_event_sync(void); +InputEvent *qemu_input_event_new_key(KeyValue *key, bool down); +void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down); +void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down); +void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down); + #endif /* INPUT_H */ diff --git a/ui/input.c b/ui/input.c index 23c84f7..61c8089 100644 --- a/ui/input.c +++ b/ui/input.c @@ -81,3 +81,38 @@ void qemu_input_event_sync(void) s-events = 0; } } + +InputEvent *qemu_input_event_new_key(KeyValue *key, bool down) +{ +InputEvent *evt = g_new0(InputEvent, 1); +evt-key = g_new0(InputKeyEvent, 1); +evt-kind = INPUT_EVENT_KIND_KEY; +evt-key-key = key; +evt-key-down = down; +return evt; +} + +void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down) +{ +InputEvent *evt; +evt = qemu_input_event_new_key(key, down); +qemu_input_event_send(src, evt); +qemu_input_event_sync(); +qapi_free_InputEvent(evt); +} + +void qemu_input_event_send_key_number(QemuConsole *src, int num, bool down) +{ +KeyValue *key = g_new0(KeyValue, 1); +key-kind = KEY_VALUE_KIND_NUMBER; +key-number = num; +qemu_input_event_send_key(src, key, down); +} + +void qemu_input_event_send_key_qcode(QemuConsole *src, QKeyCode q, bool down) +{ +KeyValue *key = g_new0(KeyValue, 1); +key-kind = KEY_VALUE_KIND_QCODE; +key-qcode = q; +qemu_input_event_send_key(src, key, down); +} -- 1.8.3.1
[Qemu-devel] [PATCH] [RESEND-try-3] hw/9pfs: fix P9_STATS_GEN handling
Currently we have few issues with P9_STATS_GEN: - We don't try to read st_gen anything except files or directories, but still set P9_STATS_GEN bit in st_result_mask. It may mislead client: we present garbage as valid st_gen. - If we failed to get valid st_gen with ENOTTY, we ignore error, but still set P9_STATS_GEN bit in st_result_mask. - If we failed to get valid st_gen with any other errno, we fail getattr altogether. It's excessive: we block valid client use-cases, like chdir(2) to non-readable directory with execution bit set. The patch fixes these issues and cleanup code a bit. Signed-off-by: Kirill A. Shutemov kirill.shute...@linux.intel.com Reviewed-by: Daniel P. Berrange berra...@redhat.com Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/9pfs/cofile.c | 4 hw/9pfs/virtio-9p-handle.c | 8 +++- hw/9pfs/virtio-9p-local.c | 10 ++ hw/9pfs/virtio-9p-proxy.c | 3 ++- hw/9pfs/virtio-9p.c| 12 ++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c index 194c1306c665..2efebf35710f 100644 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@ -38,10 +38,6 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, }); v9fs_path_unlock(s); } -/* The ioctl may not be supported depending on the path */ -if (err == -ENOTTY) { -err = 0; -} return err; } diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c index fe8e0ed19dcc..17002a3d2867 100644 --- a/hw/9pfs/virtio-9p-handle.c +++ b/hw/9pfs/virtio-9p-handle.c @@ -582,6 +582,7 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir, static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, mode_t st_mode, uint64_t *st_gen) { +#ifdef FS_IOC_GETVERSION int err; V9fsFidOpenState fid_open; @@ -590,7 +591,8 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, * We can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = handle_open(ctx, path, O_RDONLY, fid_open); if (err 0) { @@ -599,6 +601,10 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); handle_close(ctx, fid_open); return err; +#else +errno = ENOTTY; +return -1; +#endif } static int handle_init(FsContext *ctx) diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index fc93e9e6e8da..df0dbffa7ac4 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -1068,8 +1068,8 @@ err_out: static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, mode_t st_mode, uint64_t *st_gen) { -int err; #ifdef FS_IOC_GETVERSION +int err; V9fsFidOpenState fid_open; /* @@ -1077,7 +1077,8 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, * We can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = local_open(ctx, path, O_RDONLY, fid_open); if (err 0) { @@ -1085,10 +1086,11 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, } err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); local_close(ctx, fid_open); +return err; #else -err = -ENOTTY; +errno = ENOTTY; +return -1; #endif -return err; } static int local_init(FsContext *ctx) diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/virtio-9p-proxy.c index 5f44bb758b35..b57966d9d883 100644 --- a/hw/9pfs/virtio-9p-proxy.c +++ b/hw/9pfs/virtio-9p-proxy.c @@ -1086,7 +1086,8 @@ static int proxy_ioc_getversion(FsContext *fs_ctx, V9fsPath *path, * we can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = v9fs_request(fs_ctx-private, T_GETVERSION, st_gen, s, path); if (err 0) { diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 8cbb8ae32a03..3e51fcd152f8 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1080,10 +1080,18 @@ static void v9fs_getattr(void *opaque) /* fill st_gen if requested and supported by underlying fs */ if (request_mask P9_STATS_GEN) { retval = v9fs_co_st_gen(pdu, fidp-path, stbuf.st_mode, v9stat_dotl); -if (retval 0) { +switch (retval) { +case 0: +/* we have valid st_gen: update result mask */ +v9stat_dotl.st_result_mask |= P9_STATS_GEN; +break; +case -EINTR: +/* request cancelled */ goto out; +default: +/* failed to get st_gen: not fatal,
[Qemu-devel] [PATCH 28/42] input: mouse: switch monitor to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- monitor.c | 31 ++- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/monitor.c b/monitor.c index 80456fb..0df48d8 100644 --- a/monitor.c +++ b/monitor.c @@ -39,6 +39,7 @@ #include monitor/monitor.h #include qemu/readline.h #include ui/console.h +#include ui/input.h #include sysemu/blockdev.h #include audio/audio.h #include disas/disas.h @@ -1457,23 +1458,43 @@ static int mouse_button_state; static void do_mouse_move(Monitor *mon, const QDict *qdict) { -int dx, dy, dz; +int dx, dy, dz, button; const char *dx_str = qdict_get_str(qdict, dx_str); const char *dy_str = qdict_get_str(qdict, dy_str); const char *dz_str = qdict_get_try_str(qdict, dz_str); + dx = strtol(dx_str, NULL, 0); dy = strtol(dy_str, NULL, 0); -dz = 0; -if (dz_str) +qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx); +qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy); + +if (dz_str) { dz = strtol(dz_str, NULL, 0); -kbd_mouse_event(dx, dy, dz, mouse_button_state); +if (dz != 0) { +button = (dz 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN; +qemu_input_queue_btn(NULL, button, true); +qemu_input_event_sync(); +qemu_input_queue_btn(NULL, button, false); +} +} +qemu_input_event_sync(); } static void do_mouse_button(Monitor *mon, const QDict *qdict) { +static uint32_t bmap[INPUT_BUTTON_MAX] = { +[INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, +[INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, +[INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, +}; int button_state = qdict_get_int(qdict, button_state); + +if (mouse_button_state == button_state) { +return; +} +qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state); +qemu_input_event_sync(); mouse_button_state = button_state; -kbd_mouse_event(0, 0, 0, mouse_button_state); } static void do_ioport_read(Monitor *mon, const QDict *qdict) -- 1.8.3.1
[Qemu-devel] [PATCH 21/42] input: mouse: add qemu_input_is_absolute()
Same as kbd_mouse_is_absolute(), but using new input core. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- include/ui/input.h | 1 + ui/input.c | 8 2 files changed, 9 insertions(+) diff --git a/include/ui/input.h b/include/ui/input.h index c6f50c2..28afc45 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -41,6 +41,7 @@ void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down); void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, uint32_t button_old, uint32_t button_new); +bool qemu_input_is_absolute(void); int qemu_input_scale_axis(int value, int size_in, int size_out); InputEvent *qemu_input_event_new_move(InputEventKind kind, InputAxis axis, int value); diff --git a/ui/input.c b/ui/input.c index 2c4d4d6..30a5b70 100644 --- a/ui/input.c +++ b/ui/input.c @@ -183,6 +183,14 @@ void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, } } +bool qemu_input_is_absolute(void) +{ +QemuInputHandlerState *s; + +s = qemu_input_find_handler(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS); +return (s != NULL) (s-handler-mask INPUT_EVENT_MASK_ABS); +} + int qemu_input_scale_axis(int value, int size_in, int size_out) { if (size_in 2) { -- 1.8.3.1
[Qemu-devel] [PATCH 25/42] sdl2: switch mouse handling to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/sdl2.c | 60 +++- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/ui/sdl2.c b/ui/sdl2.c index ac3ac19..e841424 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -329,7 +329,7 @@ static void sdl_hide_cursor(void) if (!cursor_hide) return; -if (kbd_mouse_is_absolute()) { +if (qemu_input_is_absolute()) { SDL_ShowCursor(1); SDL_SetCursor(sdl_cursor_hidden); } else { @@ -342,10 +342,10 @@ static void sdl_show_cursor(void) if (!cursor_hide) return; -if (!kbd_mouse_is_absolute()) { +if (!qemu_input_is_absolute()) { SDL_ShowCursor(1); if (guest_cursor -(gui_grab || kbd_mouse_is_absolute() || absolute_enabled)) +(gui_grab || qemu_input_is_absolute() || absolute_enabled)) SDL_SetCursor(guest_sprite); else SDL_SetCursor(sdl_cursor_normal); @@ -364,7 +364,7 @@ static void sdl_grab_start(struct sdl2_console_state *scon) } if (guest_cursor) { SDL_SetCursor(guest_sprite); -if (!kbd_mouse_is_absolute() !absolute_enabled) { +if (!qemu_input_is_absolute() !absolute_enabled) { SDL_WarpMouseInWindow(scon-real_window, guest_x, guest_y); } } else @@ -396,7 +396,7 @@ static void absolute_mouse_grab(struct sdl2_console_state *scon) static void sdl_mouse_mode_change(Notifier *notify, void *data) { -if (kbd_mouse_is_absolute()) { +if (qemu_input_is_absolute()) { if (!absolute_enabled) { absolute_enabled = 1; absolute_mouse_grab(sdl2_console[0]); @@ -411,19 +411,23 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data) static void sdl_send_mouse_event(struct sdl2_console_state *scon, int dx, int dy, int dz, int x, int y, int state) { -int buttons = 0; +static uint32_t bmap[INPUT_BUTTON_MAX] = { +[INPUT_BUTTON_LEFT] = SDL_BUTTON(SDL_BUTTON_LEFT), +[INPUT_BUTTON_MIDDLE] = SDL_BUTTON(SDL_BUTTON_MIDDLE), +[INPUT_BUTTON_RIGHT] = SDL_BUTTON(SDL_BUTTON_RIGHT), +#if 0 +[INPUT_BUTTON_WHEEL_UP] = SDL_BUTTON(SDL_BUTTON_WHEELUP), +[INPUT_BUTTON_WHEEL_DOWN] = SDL_BUTTON(SDL_BUTTON_WHEELDOWN), +#endif +}; +static uint32_t prev_state; -if (state SDL_BUTTON(SDL_BUTTON_LEFT)) { -buttons |= MOUSE_EVENT_LBUTTON; -} -if (state SDL_BUTTON(SDL_BUTTON_RIGHT)) { -buttons |= MOUSE_EVENT_RBUTTON; -} -if (state SDL_BUTTON(SDL_BUTTON_MIDDLE)) { -buttons |= MOUSE_EVENT_MBUTTON; +if (prev_state != state) { +qemu_input_update_buttons(scon-dcl.con, bmap, prev_state, state); +prev_state = state; } -if (kbd_mouse_is_absolute()) { +if (qemu_input_is_absolute()) { int scr_w, scr_h; int max_w = 0, max_h = 0; int off_x = 0, off_y = 0; @@ -446,19 +450,17 @@ static void sdl_send_mouse_event(struct sdl2_console_state *scon, int dx, int dy } } } - -dx = (off_x + x) * 0x7FFF / (max_w - 1); -dy = (off_y + y) * 0x7FFF / (max_h - 1); +qemu_input_queue_abs(scon-dcl.con, INPUT_AXIS_X, off_x + x, max_w); +qemu_input_queue_abs(scon-dcl.con, INPUT_AXIS_Y, off_y + y, max_h); } else if (guest_cursor) { x -= guest_x; y -= guest_y; guest_x += x; guest_y += y; -dx = x; -dy = y; +qemu_input_queue_rel(scon-dcl.con, INPUT_AXIS_X, x); +qemu_input_queue_rel(scon-dcl.con, INPUT_AXIS_Y, y); } - -kbd_mouse_event(dx, dy, dz, buttons); +qemu_input_event_sync(); } static void sdl_scale(struct sdl2_console_state *scon, int width, int height) @@ -592,7 +594,7 @@ static void handle_mousemotion(SDL_Event *ev) int max_x, max_y; struct sdl2_console_state *scon = get_scon_from_window(ev-key.windowID); -if (kbd_mouse_is_absolute() || absolute_enabled) { +if (qemu_input_is_absolute() || absolute_enabled) { int scr_w, scr_h; SDL_GetWindowSize(scon-real_window, scr_w, scr_h); max_x = scr_w - 1; @@ -607,7 +609,7 @@ static void handle_mousemotion(SDL_Event *ev) sdl_grab_start(scon); } } -if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) { +if (gui_grab || qemu_input_is_absolute() || absolute_enabled) { sdl_send_mouse_event(scon, ev-motion.xrel, ev-motion.yrel, 0, ev-motion.x, ev-motion.y, ev-motion.state); } @@ -621,7 +623,7 @@ static void handle_mousebutton(SDL_Event *ev) int dz; bev = ev-button; -if (!gui_grab !kbd_mouse_is_absolute()) { +if (!gui_grab !qemu_input_is_absolute()) { if (ev-type == SDL_MOUSEBUTTONUP bev-button == SDL_BUTTON_LEFT) { /* start grabbing all events */
[Qemu-devel] [PATCH 26/42] input: mouse: switch vnc ui to new core
Signed-off-by: Gerd Hoffmann kra...@redhat.com --- ui/vnc.c | 46 ++ ui/vnc.h | 1 + 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 4658559..7dfc94a 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1484,7 +1484,7 @@ static void client_cut_text(VncState *vs, size_t len, uint8_t *text) static void check_pointer_type_change(Notifier *notifier, void *data) { VncState *vs = container_of(notifier, VncState, mouse_mode_notifier); -int absolute = kbd_mouse_is_absolute(); +int absolute = qemu_input_is_absolute(); if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE) vs-absolute != absolute) { vnc_lock_output(vs); @@ -1503,39 +1503,37 @@ static void check_pointer_type_change(Notifier *notifier, void *data) static void pointer_event(VncState *vs, int button_mask, int x, int y) { -int buttons = 0; -int dz = 0; +static uint32_t bmap[INPUT_BUTTON_MAX] = { +[INPUT_BUTTON_LEFT] = 0x01, +[INPUT_BUTTON_MIDDLE] = 0x02, +[INPUT_BUTTON_RIGHT] = 0x04, +[INPUT_BUTTON_WHEEL_UP] = 0x08, +[INPUT_BUTTON_WHEEL_DOWN] = 0x10, +}; +QemuConsole *con = vs-vd-dcl.con; int width = surface_width(vs-vd-ds); int height = surface_height(vs-vd-ds); -if (button_mask 0x01) -buttons |= MOUSE_EVENT_LBUTTON; -if (button_mask 0x02) -buttons |= MOUSE_EVENT_MBUTTON; -if (button_mask 0x04) -buttons |= MOUSE_EVENT_RBUTTON; -if (button_mask 0x08) -dz = -1; -if (button_mask 0x10) -dz = 1; +if (vs-last_bmask != button_mask) { +qemu_input_update_buttons(con, bmap, vs-last_bmask, button_mask); +vs-last_bmask = button_mask; +} if (vs-absolute) { -kbd_mouse_event(width 1 ? x * 0x7FFF / (width - 1) : 0x4000, -height 1 ? y * 0x7FFF / (height - 1) : 0x4000, -dz, buttons); +qemu_input_queue_abs(con, INPUT_AXIS_X, x, width); +qemu_input_queue_abs(con, INPUT_AXIS_Y, y, height); } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) { -x -= 0x7FFF; -y -= 0x7FFF; - -kbd_mouse_event(x, y, dz, buttons); +qemu_input_queue_rel(con, INPUT_AXIS_X, x - 0x7FFF); +qemu_input_queue_rel(con, INPUT_AXIS_Y, y - 0x7FFF); } else { -if (vs-last_x != -1) -kbd_mouse_event(x - vs-last_x, -y - vs-last_y, -dz, buttons); +if (vs-last_x != -1) { +qemu_input_queue_rel(con, INPUT_AXIS_X, x - vs-last_x); +qemu_input_queue_rel(con, INPUT_AXIS_Y, y - vs-last_y); +} vs-last_x = x; vs-last_y = y; } +qemu_input_event_sync(); } static void reset_keys(VncState *vs) diff --git a/ui/vnc.h b/ui/vnc.h index 6e99213..e63c142 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -257,6 +257,7 @@ struct VncState int absolute; int last_x; int last_y; +uint32_t last_bmask; int client_width; int client_height; VncShareMode share_mode; -- 1.8.3.1
Re: [Qemu-devel] [PATCH v4 4/5] qmp: full introspection support for QMP
Il 28/01/2014 11:45, Amos Kong ha scritto: My question is why is this generate-and-parse necessary? It's request of Libvirt, actually we can directly return the raw schema to Libvirt without extending/parsing, then Libvirt parse by itself. Can we achieve it with less duplication? Let's see the feedback of Eric. Eric's feedback is certainly useful, but I think we need to look at it from the QEMU perspective more than the libvirt perspective. Passing the raw schema and letting libvirt parse it is a Really Bad idea from the QEMU perspective, in my opinion, even if it means a little more work now and even if libvirt is willing to add the parser. First and foremost, the current pseudo-JSON encoding of the schema is nothing but a QEMU implementation detail. The pseudo-JSON syntax definitely shouldn't percolate to the QAPI documentation. Using normal QAPI structs means that the normal tool for documentation (qapi-schema.json doc comments) applies just as well to QAPI schema introspection Second, if one day we were to change the schema representation from pseudo-JSON to something else, we would have to carry a pseudo-JSON serializer for backwards compatibility. Building QAPI structs and relying on the normal formatting machinery is very different from putting together strings manually. The schema must be emitted as JSON data, not as a string. I'm not willing to compromise on this point. :) Paolo
Re: [Qemu-devel] [PULL v2 00/35] acpi, pci, pc, virtio fixes and enhancements
Hi Peter, could you merge the below please? Thanks in advance! On Sun, Jan 26, 2014 at 06:05:14PM +0200, Michael S. Tsirkin wrote: Hi Anthony, I forgot to Cc you on the previous version of this pull request. So here's v2 - it also includes some more changes that got merged since then. I also used this opportunity for smash in a compat bugfix. Please ignore the previous pull request. The following changes since commit 0169c511554cb0014a00290b0d3d26c31a49818f: Merge remote-tracking branch 'qemu-kvm/uq/master' into staging (2014-01-24 15:52:44 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_anthony for you to fetch changes up to a75143eda2ddf581b51e96c000974bcdfe2cbd10: MAINTAINERS: add self as virtio co-maintainer (2014-01-26 13:11:45 +0200) acpi,pci,pc,virtio fixes and enhancements This includes new unit-tests for acpi by Marcel, hotplug for pci bridges by myself (piix only so far) and cpu hotplug for q35. And a bunch of fixes all over the place as usual. I included the patch to fix memory alignment for q35 as well - even though it limits 32 bit guests to 3G (they previously could address more memory with PAE). To remove the limit, this will have to be fixed in seabios. I also added self as virtio co-maintainer so I don't need to troll the list for patches to review. Signed-off-by: Michael S. Tsirkin m...@redhat.com Alexey Kardashevskiy (1): tests: fix acpi to work on bigendian host Eduardo Habkost (2): pc: Save size of RAM below 4GB acpi: Fix PCI hole handling on build_srat() Gabriel L. Somlo (2): Add DSDT node for AppleSMC ACPI: Fix AppleSMC _STA size Gerd Hoffmann (1): q35: gigabyte alignment for ram Igor Mammedov (9): pc: make: fix dependencies: rebuild when included file is changed acpi: factor out common cpu hotplug code for PIIX4/Q35 acpi: ich9: add CPU hotplug handling to Q35 machine pc: set PRST base in DSDT depending on chipset pc: PIIX DSDT: exclude CPU/PCI hotplug GPE0 IO range from PCI bus resources pc: Q35 DSDT: exclude CPU hotplug IO range from PCI bus resources pc: ACPI: expose PRST IO range via _CRS pc: ACPI: unify source of CPU hotplug IO base/len pc: ACPI: update acpi-dsdt.hex.generated q35-acpi-dsdt.hex.generated Laszlo Ersek (1): Python-lang gdb script to extract x86_64 guest vmcore from qemu coredump Marcel Apfelbaum (11): acpi unit-test: add test files configure: added acpi unit-test files acpi unit-test: compare DSDT and SSDT tables against expected values configure: add CONFIG_IASL to config-host.h acpi unit-test: extract iasl executable from configuration acpi unit-test: added script to rebuild the expected aml files acpi unit-test: hook to rebuild expected aml files acpi unit-test: renamed ssdt_tables to tables acpi unit-test: resolved iasl crash acpi unit-test: do not fail on asl mismatch hw/pci: fix error flow in pci multifunction init Michael S. Tsirkin (7): pci: add pci_for_each_bus_depth_first pcihp: generalization of piix4 acpi piix4: add acpi pci hotplug support acpi-build: enable hotplug for PCI bridges acpi-test: update expected AML since recent changes q35: document gigabyte_align MAINTAINERS: add self as virtio co-maintainer Stefan Weil (1): virtio: Fix return value for dummy function vhost_net_virtqueue_pending configure| 4 + include/hw/acpi/cpu_hotplug.h| 27 ++ include/hw/acpi/cpu_hotplug_defs.h | 24 ++ include/hw/acpi/ich9.h | 4 + include/hw/acpi/pcihp.h | 72 ++ include/hw/i386/pc.h | 7 +- include/hw/isa/isa.h | 7 + include/hw/pci/pci.h | 14 ++ hw/acpi/cpu_hotplug.c| 64 + hw/acpi/ich9.c | 14 ++ hw/acpi/pcihp.c | 316 +++ hw/acpi/piix4.c | 155 ++-- hw/i386/acpi-build.c | 364 +-- hw/i386/pc.c | 1 + hw/i386/pc_q35.c | 20 +- hw/misc/applesmc.c | 1 - hw/net/vhost_net.c | 2 +- hw/pci/pci.c | 48 +++- tests/acpi-test.c| 305 +++--- MAINTAINERS | 1 + docs/specs/acpi_cpu_hotplug.txt | 4 +-
Re: [Qemu-devel] [PATCH] [RESEND-try-3] hw/9pfs: fix P9_STATS_GEN handling
Il 28/01/2014 11:55, Kirill A. Shutemov ha scritto: Currently we have few issues with P9_STATS_GEN: - We don't try to read st_gen anything except files or directories, but still set P9_STATS_GEN bit in st_result_mask. It may mislead client: we present garbage as valid st_gen. - If we failed to get valid st_gen with ENOTTY, we ignore error, but still set P9_STATS_GEN bit in st_result_mask. - If we failed to get valid st_gen with any other errno, we fail getattr altogether. It's excessive: we block valid client use-cases, like chdir(2) to non-readable directory with execution bit set. The patch fixes these issues and cleanup code a bit. Signed-off-by: Kirill A. Shutemov kirill.shute...@linux.intel.com Reviewed-by: Daniel P. Berrange berra...@redhat.com Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com --- hw/9pfs/cofile.c | 4 hw/9pfs/virtio-9p-handle.c | 8 +++- hw/9pfs/virtio-9p-local.c | 10 ++ hw/9pfs/virtio-9p-proxy.c | 3 ++- hw/9pfs/virtio-9p.c| 12 ++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c index 194c1306c665..2efebf35710f 100644 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@ -38,10 +38,6 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, }); v9fs_path_unlock(s); } -/* The ioctl may not be supported depending on the path */ -if (err == -ENOTTY) { -err = 0; -} return err; } diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c index fe8e0ed19dcc..17002a3d2867 100644 --- a/hw/9pfs/virtio-9p-handle.c +++ b/hw/9pfs/virtio-9p-handle.c @@ -582,6 +582,7 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir, static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, mode_t st_mode, uint64_t *st_gen) { +#ifdef FS_IOC_GETVERSION int err; V9fsFidOpenState fid_open; @@ -590,7 +591,8 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, * We can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = handle_open(ctx, path, O_RDONLY, fid_open); if (err 0) { @@ -599,6 +601,10 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); handle_close(ctx, fid_open); return err; +#else +errno = ENOTTY; +return -1; +#endif } static int handle_init(FsContext *ctx) diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index fc93e9e6e8da..df0dbffa7ac4 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -1068,8 +1068,8 @@ err_out: static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, mode_t st_mode, uint64_t *st_gen) { -int err; #ifdef FS_IOC_GETVERSION +int err; V9fsFidOpenState fid_open; /* @@ -1077,7 +1077,8 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, * We can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = local_open(ctx, path, O_RDONLY, fid_open); if (err 0) { @@ -1085,10 +1086,11 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, } err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); local_close(ctx, fid_open); +return err; #else -err = -ENOTTY; +errno = ENOTTY; +return -1; #endif -return err; } static int local_init(FsContext *ctx) diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/virtio-9p-proxy.c index 5f44bb758b35..b57966d9d883 100644 --- a/hw/9pfs/virtio-9p-proxy.c +++ b/hw/9pfs/virtio-9p-proxy.c @@ -1086,7 +1086,8 @@ static int proxy_ioc_getversion(FsContext *fs_ctx, V9fsPath *path, * we can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = v9fs_request(fs_ctx-private, T_GETVERSION, st_gen, s, path); if (err 0) { diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 8cbb8ae32a03..3e51fcd152f8 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1080,10 +1080,18 @@ static void v9fs_getattr(void *opaque) /* fill st_gen if requested and supported by underlying fs */ if (request_mask P9_STATS_GEN) { retval = v9fs_co_st_gen(pdu, fidp-path, stbuf.st_mode, v9stat_dotl); -if (retval 0) { +switch (retval) { +case 0: +/* we have valid st_gen: update result mask */ +v9stat_dotl.st_result_mask |= P9_STATS_GEN; +break; +case -EINTR: +/* request cancelled */ goto out; +default:
[Qemu-devel] [PATCH 08/42] input: qapi: add pause key
It's missing. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- qapi-schema.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index 6af22f6..d848e40 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3430,7 +3430,7 @@ # # Since: 1.3.0 # -# 'unmapped' since 2.0 +# 'unmapped' and 'pause' since 2.0 ## { 'enum': 'QKeyCode', 'data': [ 'unmapped', @@ -3448,7 +3448,7 @@ 'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup', 'pgdn', 'end', 'left', 'up', 'down', 'right', 'insert', 'delete', 'stop', 'again', 'props', 'undo', 'front', 'copy', 'open', 'paste', 'find', 'cut', - 'lf', 'help', 'meta_l', 'meta_r', 'compose' ] } + 'lf', 'help', 'meta_l', 'meta_r', 'compose', 'pause' ] } ## # @KeyValue -- 1.8.3.1
Re: [Qemu-devel] [PATCH] [RESEND-try-3] hw/9pfs: fix P9_STATS_GEN handling
On Tue, Jan 28, 2014 at 12:55:51PM +0200, Kirill A. Shutemov wrote: Currently we have few issues with P9_STATS_GEN: - We don't try to read st_gen anything except files or directories, but still set P9_STATS_GEN bit in st_result_mask. It may mislead client: we present garbage as valid st_gen. - If we failed to get valid st_gen with ENOTTY, we ignore error, but still set P9_STATS_GEN bit in st_result_mask. - If we failed to get valid st_gen with any other errno, we fail getattr altogether. It's excessive: we block valid client use-cases, like chdir(2) to non-readable directory with execution bit set. The patch fixes these issues and cleanup code a bit. Signed-off-by: Kirill A. Shutemov kirill.shute...@linux.intel.com Reviewed-by: Daniel P. Berrange berra...@redhat.com Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com Would be better to split unrelated issues out to separate patches. --- hw/9pfs/cofile.c | 4 hw/9pfs/virtio-9p-handle.c | 8 +++- hw/9pfs/virtio-9p-local.c | 10 ++ hw/9pfs/virtio-9p-proxy.c | 3 ++- hw/9pfs/virtio-9p.c| 12 ++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c index 194c1306c665..2efebf35710f 100644 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@ -38,10 +38,6 @@ int v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, }); v9fs_path_unlock(s); } -/* The ioctl may not be supported depending on the path */ -if (err == -ENOTTY) { -err = 0; -} return err; } diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c index fe8e0ed19dcc..17002a3d2867 100644 --- a/hw/9pfs/virtio-9p-handle.c +++ b/hw/9pfs/virtio-9p-handle.c @@ -582,6 +582,7 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir, static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, mode_t st_mode, uint64_t *st_gen) { +#ifdef FS_IOC_GETVERSION int err; V9fsFidOpenState fid_open; @@ -590,7 +591,8 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, * We can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = handle_open(ctx, path, O_RDONLY, fid_open); if (err 0) { @@ -599,6 +601,10 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); handle_close(ctx, fid_open); return err; +#else +errno = ENOTTY; +return -1; +#endif } static int handle_init(FsContext *ctx) diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index fc93e9e6e8da..df0dbffa7ac4 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -1068,8 +1068,8 @@ err_out: static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, mode_t st_mode, uint64_t *st_gen) { -int err; #ifdef FS_IOC_GETVERSION +int err; V9fsFidOpenState fid_open; /* @@ -1077,7 +1077,8 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, * We can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = local_open(ctx, path, O_RDONLY, fid_open); if (err 0) { @@ -1085,10 +1086,11 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path, } err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); local_close(ctx, fid_open); +return err; #else -err = -ENOTTY; +errno = ENOTTY; +return -1; #endif -return err; } static int local_init(FsContext *ctx) diff --git a/hw/9pfs/virtio-9p-proxy.c b/hw/9pfs/virtio-9p-proxy.c index 5f44bb758b35..b57966d9d883 100644 --- a/hw/9pfs/virtio-9p-proxy.c +++ b/hw/9pfs/virtio-9p-proxy.c @@ -1086,7 +1086,8 @@ static int proxy_ioc_getversion(FsContext *fs_ctx, V9fsPath *path, * we can get fd for regular files and directories only */ if (!S_ISREG(st_mode) !S_ISDIR(st_mode)) { -return 0; +errno = ENOTTY; +return -1; } err = v9fs_request(fs_ctx-private, T_GETVERSION, st_gen, s, path); if (err 0) { diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 8cbb8ae32a03..3e51fcd152f8 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1080,10 +1080,18 @@ static void v9fs_getattr(void *opaque) /* fill st_gen if requested and supported by underlying fs */ if (request_mask P9_STATS_GEN) { retval = v9fs_co_st_gen(pdu, fidp-path, stbuf.st_mode, v9stat_dotl); -if (retval 0) { +switch (retval) { +case 0: +
[Qemu-devel] [PATCH v2 02/11] target-arm: Add AArch32 FP VRINTA, VRINTN, VRINTP and VRINTM
Add support for AArch32 ARMv8 FP VRINTA, VRINTN, VRINTP and VRINTM instructions. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 54 ++ 1 file changed, 54 insertions(+) Changes in v2: - Add comment to fp_decode_rm lookup table diff --git a/target-arm/translate.c b/target-arm/translate.c index 8d240e1..2db6812 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2759,6 +2759,56 @@ static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn, return 0; } +static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp, +int rounding) +{ +TCGv_ptr fpst = get_fpstatus_ptr(0); +TCGv_i32 tcg_rmode; + +tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding)); +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + +if (dp) { +TCGv_i64 tcg_op; +TCGv_i64 tcg_res; +tcg_op = tcg_temp_new_i64(); +tcg_res = tcg_temp_new_i64(); +tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm)); +gen_helper_rintd(tcg_res, tcg_op, fpst); +tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd)); +tcg_temp_free_i64(tcg_op); +tcg_temp_free_i64(tcg_res); +} else { +TCGv_i32 tcg_op; +TCGv_i32 tcg_res; +tcg_op = tcg_temp_new_i32(); +tcg_res = tcg_temp_new_i32(); +tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm)); +gen_helper_rints(tcg_res, tcg_op, fpst); +tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd)); +tcg_temp_free_i32(tcg_op); +tcg_temp_free_i32(tcg_res); +} + +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); +tcg_temp_free_i32(tcg_rmode); + +tcg_temp_free_ptr(fpst); +return 0; +} + + +/* Table for converting the most common AArch32 encoding of + * rounding mode to arm_fprounding order (which matches the + * common AArch64 order); see ARM ARM pseudocode FPDecodeRM(). + */ +static const uint8_t fp_decode_rm[] = { +FPROUNDING_TIEAWAY, +FPROUNDING_TIEEVEN, +FPROUNDING_POSINF, +FPROUNDING_NEGINF, +}; + static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn) { uint32_t rd, rn, rm, dp = extract32(insn, 8, 1); @@ -2781,6 +2831,10 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn) return handle_vsel(insn, rd, rn, rm, dp); } else if ((insn 0x0fb00e10) == 0x0e800a00) { return handle_vminmaxnm(insn, rd, rn, rm, dp); +} else if ((insn 0x0fbc0ed0) == 0x0eb80a40) { +/* VRINTA, VRINTN, VRINTP, VRINTM */ +int rounding = fp_decode_rm[extract32(insn, 16, 2)]; +return handle_vrint(insn, rd, rm, dp, rounding); } return 1; } -- 1.8.1.4
[Qemu-devel] [PATCH v2 01/11] target-arm: Move arm_rmode_to_sf to a shared location.
This function will be needed for AArch32 ARMv8 support, so move it to helper.c where it can be used by both targets. Also moves the code out of line, but as it is quite a large function I don't believe this should be a significant performance impact. Signed-off-by: Will Newton will.new...@linaro.org Reviewed-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/cpu.h | 2 ++ target-arm/helper.c| 28 target-arm/translate-a64.c | 28 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 198b6b8..383c582 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -496,6 +496,8 @@ enum arm_fprounding { FPROUNDING_ODD }; +int arm_rmode_to_sf(int rmode); + enum arm_cpu_mode { ARM_CPU_MODE_USR = 0x10, ARM_CPU_MODE_FIQ = 0x11, diff --git a/target-arm/helper.c b/target-arm/helper.c index c708f15..b1541b9 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -4418,3 +4418,31 @@ float64 HELPER(rintd)(float64 x, void *fp_status) return ret; } + +/* Convert ARM rounding mode to softfloat */ +int arm_rmode_to_sf(int rmode) +{ +switch (rmode) { +case FPROUNDING_TIEAWAY: +rmode = float_round_ties_away; +break; +case FPROUNDING_ODD: +/* FIXME: add support for TIEAWAY and ODD */ +qemu_log_mask(LOG_UNIMP, arm: unimplemented rounding mode: %d\n, + rmode); +case FPROUNDING_TIEEVEN: +default: +rmode = float_round_nearest_even; +break; +case FPROUNDING_POSINF: +rmode = float_round_up; +break; +case FPROUNDING_NEGINF: +rmode = float_round_down; +break; +case FPROUNDING_ZERO: +rmode = float_round_to_zero; +break; +} +return rmode; +} diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index cf80c46..8effbe2 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3186,34 +3186,6 @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn) } } -/* Convert ARM rounding mode to softfloat */ -static inline int arm_rmode_to_sf(int rmode) -{ -switch (rmode) { -case FPROUNDING_TIEAWAY: -rmode = float_round_ties_away; -break; -case FPROUNDING_ODD: -/* FIXME: add support for TIEAWAY and ODD */ -qemu_log_mask(LOG_UNIMP, arm: unimplemented rounding mode: %d\n, - rmode); -case FPROUNDING_TIEEVEN: -default: -rmode = float_round_nearest_even; -break; -case FPROUNDING_POSINF: -rmode = float_round_up; -break; -case FPROUNDING_NEGINF: -rmode = float_round_down; -break; -case FPROUNDING_ZERO: -rmode = float_round_to_zero; -break; -} -return rmode; -} - static void handle_fp_compare(DisasContext *s, bool is_double, unsigned int rn, unsigned int rm, bool cmp_with_zero, bool signal_all_nans) -- 1.8.1.4
[Qemu-devel] [PATCH v2 03/11] target-arm: Add support for AArch32 FP VRINTR
Add support for the AArch32 floating-point VRINTR instruction. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 11 +++ 1 file changed, 11 insertions(+) Changes in v2: - Move code outside the arms of the if diff --git a/target-arm/translate.c b/target-arm/translate.c index 2db6812..2b3157c 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -3379,6 +3379,17 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) gen_vfp_F1_ld0(dp); gen_vfp_cmpe(dp); break; +case 12: /* vrintr */ +{ +TCGv_ptr fpst = get_fpstatus_ptr(0); +if (dp) { +gen_helper_rintd(cpu_F0d, cpu_F0d, fpst); +} else { +gen_helper_rints(cpu_F0s, cpu_F0s, fpst); +} +tcg_temp_free_ptr(fpst); +break; +} case 15: /* single-double conversion */ if (dp) gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); -- 1.8.1.4
[Qemu-devel] [PATCH v2 09/11] target-arm: Add AArch32 FP VCVTA, VCVTN, VCVTP and VCVTM
Add support for the AArch32 floating-point VCVTA, VCVTN, VCVTP and VCVTM instructions. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 61 ++ 1 file changed, 61 insertions(+) diff --git a/target-arm/translate.c b/target-arm/translate.c index 5a8ca24..0fcc159 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -2797,6 +2797,63 @@ static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp, return 0; } +static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp, + int rounding) +{ +bool is_signed = extract32(insn, 7, 1); +TCGv_ptr fpst = get_fpstatus_ptr(0); +TCGv_i32 tcg_rmode, tcg_shift; + +tcg_shift = tcg_const_i32(0); + +tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding)); +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); + +if (dp) { +TCGv_i64 tcg_double, tcg_res; +TCGv_i32 tcg_tmp; +/* Rd is encoded as a single precision register even when the source + * is double precision. + */ +rd = ((rd 1) 0x1e) | ((rd 4) 0x1); +tcg_double = tcg_temp_new_i64(); +tcg_res = tcg_temp_new_i64(); +tcg_tmp = tcg_temp_new_i32(); +tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm)); +if (is_signed) { +gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst); +} else { +gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst); +} +tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res); +tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd)); +tcg_temp_free_i32(tcg_tmp); +tcg_temp_free_i64(tcg_res); +tcg_temp_free_i64(tcg_double); +} else { +TCGv_i32 tcg_single, tcg_res; +tcg_single = tcg_temp_new_i32(); +tcg_res = tcg_temp_new_i32(); +tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm)); +if (is_signed) { +gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst); +} else { +gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst); +} +tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd)); +tcg_temp_free_i32(tcg_res); +tcg_temp_free_i32(tcg_single); +} + +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); +tcg_temp_free_i32(tcg_rmode); + +tcg_temp_free_i32(tcg_shift); + +tcg_temp_free_ptr(fpst); + +return 0; +} /* Table for converting the most common AArch32 encoding of * rounding mode to arm_fprounding order (which matches the @@ -2835,6 +2892,10 @@ static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn) /* VRINTA, VRINTN, VRINTP, VRINTM */ int rounding = fp_decode_rm[extract32(insn, 16, 2)]; return handle_vrint(insn, rd, rm, dp, rounding); +} else if ((insn 0x0fbc0e50) == 0x0ebc0a40) { +/* VCVTA, VCVTN, VCVTP, VCVTM */ +int rounding = fp_decode_rm[extract32(insn, 16, 2)]; +return handle_vcvt(insn, rd, rm, dp, rounding); } return 1; } -- 1.8.1.4
[Qemu-devel] [PATCH v2 04/11] target-arm: Add support for AArch32 FP VRINTZ
Add support for the AArch32 floating-point VRINTZ instruction. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 16 1 file changed, 16 insertions(+) Changes in v2: - Move code outside the arms of the if diff --git a/target-arm/translate.c b/target-arm/translate.c index 2b3157c..9afb19f 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -3390,6 +3390,22 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) tcg_temp_free_ptr(fpst); break; } +case 13: /* vrintz */ +{ +TCGv_ptr fpst = get_fpstatus_ptr(0); +TCGv_i32 tcg_rmode; +tcg_rmode = tcg_const_i32(float_round_to_zero); +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); +if (dp) { +gen_helper_rintd(cpu_F0d, cpu_F0d, fpst); +} else { +gen_helper_rints(cpu_F0s, cpu_F0s, fpst); +} +gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env); +tcg_temp_free_i32(tcg_rmode); +tcg_temp_free_ptr(fpst); +break; +} case 15: /* single-double conversion */ if (dp) gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); -- 1.8.1.4
[Qemu-devel] [PATCH v2 08/11] target-arm: Add AArch32 SIMD VRINTA, VRINTN, VRINTP, VRINTM, VRINTZ
Add support for the AArch32 Advanced SIMD VRINTA, VRINTN, VRINTP VRINTM and VRINTZ instructions. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 40 +++- 1 file changed, 39 insertions(+), 1 deletion(-) Changes in v2: - Merge VRINTZ handling into the same block diff --git a/target-arm/translate.c b/target-arm/translate.c index c179817..5a8ca24 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -4709,9 +4709,14 @@ static const uint8_t neon_3r_sizes[] = { #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */ #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */ #define NEON_2RM_VSHLL 38 +#define NEON_2RM_VRINTN 40 #define NEON_2RM_VRINTX 41 +#define NEON_2RM_VRINTA 42 +#define NEON_2RM_VRINTZ 43 #define NEON_2RM_VCVT_F16_F32 44 +#define NEON_2RM_VRINTM 45 #define NEON_2RM_VCVT_F32_F16 46 +#define NEON_2RM_VRINTP 47 #define NEON_2RM_VRECPE 56 #define NEON_2RM_VRSQRTE 57 #define NEON_2RM_VRECPE_F 58 @@ -4725,7 +4730,9 @@ static int neon_2rm_is_float_op(int op) { /* Return true if this neon 2reg-misc op is float-to-float */ return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F || -op == NEON_2RM_VRINTX || op = NEON_2RM_VRECPE_F); +(op = NEON_2RM_VRINTN op = NEON_2RM_VRINTZ) || +op == NEON_2RM_VRINTM || op == NEON_2RM_VRINTP || +op = NEON_2RM_VRECPE_F); } /* Each entry in this array has bit n set if the insn allows @@ -4769,9 +4776,14 @@ static const uint8_t neon_2rm_sizes[] = { [NEON_2RM_VMOVN] = 0x7, [NEON_2RM_VQMOVN] = 0x7, [NEON_2RM_VSHLL] = 0x7, +[NEON_2RM_VRINTN] = 0x4, [NEON_2RM_VRINTX] = 0x4, +[NEON_2RM_VRINTA] = 0x4, +[NEON_2RM_VRINTZ] = 0x4, [NEON_2RM_VCVT_F16_F32] = 0x2, +[NEON_2RM_VRINTM] = 0x4, [NEON_2RM_VCVT_F32_F16] = 0x2, +[NEON_2RM_VRINTP] = 0x4, [NEON_2RM_VRECPE] = 0x4, [NEON_2RM_VRSQRTE] = 0x4, [NEON_2RM_VRECPE_F] = 0x4, @@ -6482,6 +6494,32 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins } neon_store_reg(rm, pass, tmp2); break; +case NEON_2RM_VRINTN: +case NEON_2RM_VRINTA: +case NEON_2RM_VRINTM: +case NEON_2RM_VRINTP: +case NEON_2RM_VRINTZ: +{ +TCGv_i32 tcg_rmode; +TCGv_ptr fpstatus = get_fpstatus_ptr(1); +int rmode; + +if (op == NEON_2RM_VRINTZ) { +rmode = FPROUNDING_ZERO; +} else { +rmode = fp_decode_rm[((op 0x6) 1) ^ 1]; +} + +tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); +gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); +gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus); +gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); +tcg_temp_free_ptr(fpstatus); +tcg_temp_free_i32(tcg_rmode); +break; +} case NEON_2RM_VRINTX: { TCGv_ptr fpstatus = get_fpstatus_ptr(1); -- 1.8.1.4
Re: [Qemu-devel] [PATCH] sclp-s390: Define new SCLP codes and structures
On 27/01/14 16:57, Matthew Rosato wrote: Define new SCLP codes and structures that will be needed for s390 memory hotplug. Signed-off-by: Matthew Rosato mjros...@linux.vnet.ibm.com Applied with a small fixup. +/* SCLP Memory hotplug codes */ +#define SCLP_NO_CMD_PARM0x00ff I removed this define, since it is already there due to the cpu hotplug patches. (#define SCLP_CMD_CODE_MASK 0x00ff) Christian
[Qemu-devel] [PATCH v2 05/11] target-arm: Add support for AArch32 FP VRINTX
Add support for the AArch32 floating-point VRINTX instruction. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 11 +++ 1 file changed, 11 insertions(+) Changes in v2: - Move code outside the arms of the if diff --git a/target-arm/translate.c b/target-arm/translate.c index 9afb19f..9eb5b92 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -3406,6 +3406,17 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) tcg_temp_free_ptr(fpst); break; } +case 14: /* vrintx */ +{ +TCGv_ptr fpst = get_fpstatus_ptr(0); +if (dp) { +gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst); +} else { +gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst); +} +tcg_temp_free_ptr(fpst); +break; +} case 15: /* single-double conversion */ if (dp) gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); -- 1.8.1.4
[Qemu-devel] [PATCH v2 10/11] target-arm: Add AArch32 SIMD VCVTA, VCVTN, VCVTP and VCVTM
Add support for the AArch32 Advanced SIMD VCVTA, VCVTN, VCVTP and VCVTM instructions. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 53 +- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 0fcc159..e701c0f 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -4778,6 +4778,14 @@ static const uint8_t neon_3r_sizes[] = { #define NEON_2RM_VRINTM 45 #define NEON_2RM_VCVT_F32_F16 46 #define NEON_2RM_VRINTP 47 +#define NEON_2RM_VCVTAU 48 +#define NEON_2RM_VCVTAS 49 +#define NEON_2RM_VCVTNU 50 +#define NEON_2RM_VCVTNS 51 +#define NEON_2RM_VCVTPU 52 +#define NEON_2RM_VCVTPS 53 +#define NEON_2RM_VCVTMU 54 +#define NEON_2RM_VCVTMS 55 #define NEON_2RM_VRECPE 56 #define NEON_2RM_VRSQRTE 57 #define NEON_2RM_VRECPE_F 58 @@ -4792,7 +4800,8 @@ static int neon_2rm_is_float_op(int op) /* Return true if this neon 2reg-misc op is float-to-float */ return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F || (op = NEON_2RM_VRINTN op = NEON_2RM_VRINTZ) || -op == NEON_2RM_VRINTM || op == NEON_2RM_VRINTP || +op == NEON_2RM_VRINTM || +(op = NEON_2RM_VRINTP op = NEON_2RM_VCVTMS) || op = NEON_2RM_VRECPE_F); } @@ -4845,6 +4854,14 @@ static const uint8_t neon_2rm_sizes[] = { [NEON_2RM_VRINTM] = 0x4, [NEON_2RM_VCVT_F32_F16] = 0x2, [NEON_2RM_VRINTP] = 0x4, +[NEON_2RM_VCVTAU] = 0x4, +[NEON_2RM_VCVTAS] = 0x4, +[NEON_2RM_VCVTNU] = 0x4, +[NEON_2RM_VCVTNS] = 0x4, +[NEON_2RM_VCVTPU] = 0x4, +[NEON_2RM_VCVTPS] = 0x4, +[NEON_2RM_VCVTMU] = 0x4, +[NEON_2RM_VCVTMS] = 0x4, [NEON_2RM_VRECPE] = 0x4, [NEON_2RM_VRSQRTE] = 0x4, [NEON_2RM_VRECPE_F] = 0x4, @@ -6588,6 +6605,40 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins tcg_temp_free_ptr(fpstatus); break; } +case NEON_2RM_VCVTAU: +case NEON_2RM_VCVTAS: +case NEON_2RM_VCVTNU: +case NEON_2RM_VCVTNS: +case NEON_2RM_VCVTPU: +case NEON_2RM_VCVTPS: +case NEON_2RM_VCVTMU: +case NEON_2RM_VCVTMS: +{ +bool is_signed = !extract32(insn, 7, 1); +TCGv_ptr fpst = get_fpstatus_ptr(1); +TCGv_i32 tcg_rmode, tcg_shift; +int rmode = fp_decode_rm[extract32(insn, 8, 2)]; + +tcg_shift = tcg_const_i32(0); +tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode)); +gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); + +if (is_signed) { +gen_helper_vfp_tosls(cpu_F0s, cpu_F0s, + tcg_shift, fpst); +} else { +gen_helper_vfp_touls(cpu_F0s, cpu_F0s, + tcg_shift, fpst); +} + +gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, + cpu_env); +tcg_temp_free_i32(tcg_rmode); +tcg_temp_free_i32(tcg_shift); +tcg_temp_free_ptr(fpst); +break; +} case NEON_2RM_VRECPE: gen_helper_recpe_u32(tmp, tmp, cpu_env); break; -- 1.8.1.4
[Qemu-devel] [PATCH v2 07/11] target-arm: Add set_neon_rmode helper
This helper sets the rounding mode in the standard_fp_status word to allow NEON instructions to modify the rounding mode whilst using the standard FPSCR values for everything else. Signed-off-by: Will Newton will.new...@linaro.org Reviewed-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/helper.c | 17 + target-arm/helper.h | 1 + 2 files changed, 18 insertions(+) diff --git a/target-arm/helper.c b/target-arm/helper.c index b1541b9..ca5b000 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -4048,6 +4048,23 @@ uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env) return prev_rmode; } +/* Set the current fp rounding mode in the standard fp status and return + * the old one. This is for NEON instructions that need to change the + * rounding mode but wish to use the standard FPSCR values for everything + * else. Always set the rounding mode back to the correct value after + * modifying it. + * The argument is a softfloat float_round_ value. + */ +uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env) +{ +float_status *fp_status = env-vfp.standard_fp_status; + +uint32_t prev_rmode = get_float_rounding_mode(fp_status); +set_float_rounding_mode(rmode, fp_status); + +return prev_rmode; +} + /* Half precision conversions. */ static float32 do_fcvt_f16_to_f32(uint32_t a, CPUARMState *env, float_status *s) { diff --git a/target-arm/helper.h b/target-arm/helper.h index 70872df..71b8411 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -149,6 +149,7 @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr) DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr) DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, env) +DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env) DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env) DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env) -- 1.8.1.4
[Qemu-devel] [PATCH v2 11/11] target-arm: Add support for AArch32 64bit VCVTB and VCVTT
Add support for the AArch32 floating-point half-precision to double- precision conversion VCVTB and VCVTT instructions. Signed-off-by: Will Newton will.new...@linaro.org --- target-arm/translate.c | 62 ++ 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index e701c0f..dfda2c4 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -3142,14 +3142,16 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) VFP_DREG_N(rn, insn); } -if (op == 15 (rn == 15 || ((rn 0x1c) == 0x18))) { +if (op == 15 (rn == 15 || ((rn 0x1c) == 0x18) || + ((rn 0x1e) == 0x6))) { /* Integer or single precision destination. */ rd = VFP_SREG_D(insn); } else { VFP_DREG_D(rd, insn); } if (op == 15 -(((rn 0x1c) == 0x10) || ((rn 0x14) == 0x14))) { +(((rn 0x1c) == 0x10) || ((rn 0x14) == 0x14) || + ((rn 0x1e) == 0x4))) { /* VCVT from int is always from S reg regardless of dp bit. * VCVT with immediate frac_bits has same format as SREG_M */ @@ -3241,12 +3243,19 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) case 5: case 6: case 7: -/* VCVTB, VCVTT: only present with the halfprec extension, - * UNPREDICTABLE if bit 8 is set (we choose to UNDEF) +/* VCVTB, VCVTT: only present with the halfprec extension + * UNPREDICTABLE if bit 8 is set prior to ARMv8 + * (we choose to UNDEF) */ -if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) { +if ((dp !arm_feature(env, ARM_FEATURE_V8)) || +!arm_feature(env, ARM_FEATURE_VFP_FP16)) { return 1; } +if ((rn 0x1e) == 0x4) { +/* Single precision source */ +gen_mov_F0_vreg(0, rm); +break; +} /* Otherwise fall through */ default: /* One source operand. */ @@ -3394,21 +3403,39 @@ static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn) case 3: /* sqrt */ gen_vfp_sqrt(dp); break; -case 4: /* vcvtb.f32.f16 */ +case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */ tmp = gen_vfp_mrs(); tcg_gen_ext16u_i32(tmp, tmp); -gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); +if (dp) { +gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp, + cpu_env); +} else { +gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, + cpu_env); +} tcg_temp_free_i32(tmp); break; -case 5: /* vcvtt.f32.f16 */ +case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */ tmp = gen_vfp_mrs(); tcg_gen_shri_i32(tmp, tmp, 16); -gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env); +if (dp) { +gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp, + cpu_env); +} else { +gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, + cpu_env); +} tcg_temp_free_i32(tmp); break; -case 6: /* vcvtb.f16.f32 */ +case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */ tmp = tcg_temp_new_i32(); -gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env); +if (dp) { +gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d, + cpu_env); +} else { +gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, + cpu_env); +} gen_mov_F0_vreg(0, rd);
[Qemu-devel] [PATCH 16/42] input: keyboard: switch vnc ui to new core
--- ui/vnc.c | 25 ++--- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 5601cc3..4658559 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -33,6 +33,7 @@ #include qapi/qmp/types.h #include qmp-commands.h #include qemu/osdep.h +#include ui/input.h #define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT #define VNC_REFRESH_INTERVAL_INC 50 @@ -1542,9 +1543,7 @@ static void reset_keys(VncState *vs) int i; for(i = 0; i 256; i++) { if (vs-modifiers_state[i]) { -if (i SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -kbd_put_keycode(i | SCANCODE_UP); +qemu_input_event_send_key_number(vs-vd-dcl.con, i, false); vs-modifiers_state[i] = 0; } } @@ -1553,12 +1552,8 @@ static void reset_keys(VncState *vs) static void press_key(VncState *vs, int keysym) { int keycode = keysym2scancode(vs-vd-kbd_layout, keysym) SCANCODE_KEYMASK; -if (keycode SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -kbd_put_keycode(keycode SCANCODE_KEYCODEMASK); -if (keycode SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -kbd_put_keycode(keycode | SCANCODE_UP); +qemu_input_event_send_key_number(vs-vd-dcl.con, keycode, true); +qemu_input_event_send_key_number(vs-vd-dcl.con, keycode, false); } static int current_led_state(VncState *vs) @@ -1700,12 +1695,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) } if (qemu_console_is_graphic(NULL)) { -if (keycode SCANCODE_GREY) -kbd_put_keycode(SCANCODE_EMUL0); -if (down) -kbd_put_keycode(keycode SCANCODE_KEYCODEMASK); -else -kbd_put_keycode(keycode | SCANCODE_UP); +qemu_input_event_send_key_number(vs-vd-dcl.con, keycode, down); } else { bool numlock = vs-modifiers_state[0x45]; bool control = (vs-modifiers_state[0x1d] || @@ -1826,10 +1816,7 @@ static void vnc_release_modifiers(VncState *vs) if (!vs-modifiers_state[keycode]) { continue; } -if (keycode SCANCODE_GREY) { -kbd_put_keycode(SCANCODE_EMUL0); -} -kbd_put_keycode(keycode | SCANCODE_UP); +qemu_input_event_send_key_number(vs-vd-dcl.con, keycode, false); } } -- 1.8.3.1
[Qemu-devel] [PATCH 02/42] sdl2: baum build fix
--- backends/baum.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/baum.c b/backends/baum.c index 1132899..665107f 100644 --- a/backends/baum.c +++ b/backends/baum.c @@ -566,7 +566,7 @@ CharDriverState *chr_baum_init(void) BaumDriverState *baum; CharDriverState *chr; brlapi_handle_t *handle; -#ifdef CONFIG_SDL +#if defined(CONFIG_SDL) SDL_COMPILEDVERSION SDL_VERSIONNUM(2, 0, 0) SDL_SysWMinfo info; #endif int tty; @@ -595,7 +595,7 @@ CharDriverState *chr_baum_init(void) goto fail; } -#ifdef CONFIG_SDL +#if defined(CONFIG_SDL) SDL_COMPILEDVERSION SDL_VERSIONNUM(2, 0, 0) memset(info, 0, sizeof(info)); SDL_VERSION(info.version); if (SDL_GetWMInfo(info)) -- 1.8.3.1
Re: [Qemu-devel] [PATCH] [RESEND-try-3] hw/9pfs: fix P9_STATS_GEN handling
Michael S. Tsirkin wrote: On Tue, Jan 28, 2014 at 12:55:51PM +0200, Kirill A. Shutemov wrote: Currently we have few issues with P9_STATS_GEN: - We don't try to read st_gen anything except files or directories, but still set P9_STATS_GEN bit in st_result_mask. It may mislead client: we present garbage as valid st_gen. - If we failed to get valid st_gen with ENOTTY, we ignore error, but still set P9_STATS_GEN bit in st_result_mask. - If we failed to get valid st_gen with any other errno, we fail getattr altogether. It's excessive: we block valid client use-cases, like chdir(2) to non-readable directory with execution bit set. The patch fixes these issues and cleanup code a bit. Signed-off-by: Kirill A. Shutemov kirill.shute...@linux.intel.com Reviewed-by: Daniel P. Berrange berra...@redhat.com Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com Would be better to split unrelated issues out to separate patches. They are not totally unrelated: they all unbreak P9_STATS_GEN. But yes, I can split if it needed. diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 8cbb8ae32a03..3e51fcd152f8 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1080,10 +1080,18 @@ static void v9fs_getattr(void *opaque) /* fill st_gen if requested and supported by underlying fs */ if (request_mask P9_STATS_GEN) { retval = v9fs_co_st_gen(pdu, fidp-path, stbuf.st_mode, v9stat_dotl); -if (retval 0) { +switch (retval) { +case 0: +/* we have valid st_gen: update result mask */ +v9stat_dotl.st_result_mask |= P9_STATS_GEN; +break; +case -EINTR: +/* request cancelled */ goto out; Shouldn't EINTR be retried? No. It could be canceled by client (with Tflush) on purpose and client can retry if needed. -- Kirill A. Shutemov
Re: [Qemu-devel] [PATCH 19/24] target-arm: Implement AArch64 TTBR*
On 24 January 2014 23:44, Peter Crosthwaite peter.crosthwa...@xilinx.com wrote: +static int vmsa_ttbr_write(CPUARMState *env, const ARMCPRegInfo *ri, + uint64_t value) +{ +/* 64 bit accesses to the TTBRs can change the ASID and so we + * must flush the TLB. + */ +if ((ri-state == ARM_CP_STATE_AA64) || (ri-type ARM_CP_64BIT)) { +tlb_flush(env, 1); +} With the level of complexity this if has reached, is it better to just check for this ASID change rather than make this overly conservative flush? I just did a test boot on an A15 guest (which uses the long TTBR format) and in a Linux boot to the login prompt it did 9097 TTBR writes; just six of those involved no change to the ASID. So it doesn't seem really worth making the check to me. thanks -- PMM
Re: [Qemu-devel] [PATCH v2 0/5] disas: add libvixl to support A64 disassembly
Ping for review/testing/comments on this version, please? thanks -- PMM On 16 January 2014 11:13, Peter Maydell peter.mayd...@linaro.org wrote: Hi. This is a rebased and mildly cleaned up version of Claudio's RFC patchset from last year to add libvixl to QEMU and use it for A64 disassembly. NOTE NOTE NOTE * we now link with g++, not gcc (even if the target doesn't happen to need the A64 disassembler, since it's a bit hard to tell whether there's a C++-source .o file in the link) * I've tested Linux (including static link of linux-user) and MacOS hosts, but not Windows * if you have a visceral dislike of the idea of C++ in the QEMU binary now would be a good time to say OMG WTF BBQ Changes v1 - v2: * fixed minor libvixl bugs that meant it didn't build on 32 bit hosts or on Windows * only import the files we need from libvixl, rather than pulling in 1 lines of code we never even compile * merge aarch64-cxx.cc and aarch64.c into one file * rename 'aarch64' to 'A64' since the instruction set we're disassembling here is named A64, not AArch64 * tidied the makefiles a little so we only apply the libvixl specific flags to those files Changes RFC - v1: * some support for C++ compilation is already in master, so the rules.mak changes are smaller and simpler * I've fixed the output to better fit in a qemu debug log trace * I simplified the interface between aarch64-cxx.cc and aarch64.c a little bit * correctly handle the no C++ compiler, so no A64 disassembler build case * added support for using this as a disassembler for A64 targets as well as hosts This patchset sits on top of target-arm.next. You can find a git tree here: git://git.linaro.org/people/peter.maydell/qemu-arm.git a64-vixl web UI: https://git.linaro.org/people/peter.maydell/qemu-arm.git/shortlog/refs/heads/a64-vixl Claudio Fontana (1): disas: Implement disassembly output for A64 Peter Maydell (4): rules.mak: Support .cc as a C++ source file suffix rules.mak: Link with C++ if we have a C++ compiler disas: Add subset of libvixl sources for A64 disassembler disas/libvixl: Fix upstream libvixl compilation issues configure |4 + disas.c | 14 +- disas/Makefile.objs |5 + disas/arm-a64.cc | 87 ++ disas/libvixl/LICENCE | 30 + disas/libvixl/Makefile.objs |8 + disas/libvixl/a64/assembler-a64.h | 1784 + disas/libvixl/a64/constants-a64.h | 1104 disas/libvixl/a64/cpu-a64.h | 56 ++ disas/libvixl/a64/decoder-a64.cc | 712 + disas/libvixl/a64/decoder-a64.h | 198 disas/libvixl/a64/disasm-a64.cc | 1678 +++ disas/libvixl/a64/disasm-a64.h| 109 ++ disas/libvixl/a64/instructions-a64.cc | 238 + disas/libvixl/a64/instructions-a64.h | 344 +++ disas/libvixl/globals.h | 65 ++ disas/libvixl/platform.h | 43 + disas/libvixl/utils.cc| 120 +++ disas/libvixl/utils.h | 126 +++ include/disas/bfd.h |1 + rules.mak | 14 +- target-arm/translate-a64.c|2 +- 22 files changed, 6736 insertions(+), 6 deletions(-) create mode 100644 disas/arm-a64.cc create mode 100644 disas/libvixl/LICENCE create mode 100644 disas/libvixl/Makefile.objs create mode 100644 disas/libvixl/a64/assembler-a64.h create mode 100644 disas/libvixl/a64/constants-a64.h create mode 100644 disas/libvixl/a64/cpu-a64.h create mode 100644 disas/libvixl/a64/decoder-a64.cc create mode 100644 disas/libvixl/a64/decoder-a64.h create mode 100644 disas/libvixl/a64/disasm-a64.cc create mode 100644 disas/libvixl/a64/disasm-a64.h create mode 100644 disas/libvixl/a64/instructions-a64.cc create mode 100644 disas/libvixl/a64/instructions-a64.h create mode 100644 disas/libvixl/globals.h create mode 100644 disas/libvixl/platform.h create mode 100644 disas/libvixl/utils.cc create mode 100644 disas/libvixl/utils.h -- 1.8.5
[Qemu-devel] [PATCH v2 06/11] target-arm: Add support for AArch32 SIMD VRINTX
Add support for the AArch32 Advanced SIMD VRINTX instruction. Signed-off-by: Will Newton will.new...@linaro.org Reviewed-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index 9eb5b92..c179817 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -4709,6 +4709,7 @@ static const uint8_t neon_3r_sizes[] = { #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */ #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */ #define NEON_2RM_VSHLL 38 +#define NEON_2RM_VRINTX 41 #define NEON_2RM_VCVT_F16_F32 44 #define NEON_2RM_VCVT_F32_F16 46 #define NEON_2RM_VRECPE 56 @@ -4724,7 +4725,7 @@ static int neon_2rm_is_float_op(int op) { /* Return true if this neon 2reg-misc op is float-to-float */ return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F || -op = NEON_2RM_VRECPE_F); +op == NEON_2RM_VRINTX || op = NEON_2RM_VRECPE_F); } /* Each entry in this array has bit n set if the insn allows @@ -4768,6 +4769,7 @@ static const uint8_t neon_2rm_sizes[] = { [NEON_2RM_VMOVN] = 0x7, [NEON_2RM_VQMOVN] = 0x7, [NEON_2RM_VSHLL] = 0x7, +[NEON_2RM_VRINTX] = 0x4, [NEON_2RM_VCVT_F16_F32] = 0x2, [NEON_2RM_VCVT_F32_F16] = 0x2, [NEON_2RM_VRECPE] = 0x4, @@ -6480,6 +6482,13 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins } neon_store_reg(rm, pass, tmp2); break; +case NEON_2RM_VRINTX: +{ +TCGv_ptr fpstatus = get_fpstatus_ptr(1); +gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus); +tcg_temp_free_ptr(fpstatus); +break; +} case NEON_2RM_VRECPE: gen_helper_recpe_u32(tmp, tmp, cpu_env); break; -- 1.8.1.4
Re: [Qemu-devel] [PATCHv6 0/6] block: add native support for NFS
On Mon, Jan 27, 2014 at 07:28:07PM +0100, Peter Lieven wrote: Am 27.01.2014 17:11, schrieb Stefan Hajnoczi: On Mon, Jan 13, 2014 at 11:21:52AM +0100, Peter Lieven wrote: This adds v6 of the NFS protocol driver + qemu-iotest adjustments. v5-v6: - use internal qemu function to parse the NFS url [Kevin] - zero pad short reads [Kevin, Paolo] - added qemu-iotests patches for basic nfs protocol support v4-v5: - disussed with Ronnie and decided to move URL + Paramter parsing to LibNFS. This allows for URL parameter processing directly in LibNFS without altering the qemu NFS block driver. This bumps the version requirement for LibNFS to 1.9.0 though. - added a pointer to the LibNFS readme where additional information about ROOT privilidge requirements can be found as this raised a few concerns. - removed a trailing dot in an error statement [Fam]. v3-v4: - finally added full implementation of bdrv_get_allocated_file_size [Stefan] - removed trailing \n from error statements [Stefan] v2-v3: - rebased the stefanha/block - use pkg_config to check for libnfs (ignoring cflags which are broken in 1.8.0) [Stefan] - fixed NFSClient declaration [Stefan] - renamed Task variables to task [Stefan] - renamed NFSTask to NFSRPC [Ronnie] - do not update bs-total_sectors in nfs_co_writev [Stefan] - return -ENOMEM on all async call failures [Stefan,Ronnie] - fully implement ftruncate - use util/uri.c for URL parsing [Stefan] - reworked nfs_file_open_common to nfs_client_open which works on NFSClient [Stefan] - added a comment ot the connect message that libnfs support NFSv3 only at the moment. - DID NOT add full implementation of bdrv_get_allocated_file_size because we are not in a coroutine context and I cannot do an async call here. I could do a sync call if there would be a guarantee that no requests are in flight. [Stefan] v1-v2: - fixed block/Makefile.objs [Ronnie] - do not always register a read handler [Ronnie] - add support for reading beyond EOF [Fam] - fixed struct and paramter naming [Fam] - fixed overlong lines and whitespace errors [Fam] - return return status from libnfs whereever possible [Fam] - added comment why we set allocated_file_size to -ENOTSUP after write [Fam] - avoid segfault when parsing filname [Fam] - remove unused close_bh from NFSClient [Fam] - avoid dividing and mutliplying total_size by BDRV_SECTOR_SIZE in nfs_file_create [Fam] Peter Lieven (6): block: add native support for NFS qemu-iotests: change _supported_proto to file for various tests qemu-iotests: enable support for NFS protocol qemu-iotests: enable test 016 and 025 to work with NFS protocol qemu-iotests: fix expected output of test 067 qemu-iotests: blacklist test 020 for NFS protocol MAINTAINERS |5 + block/Makefile.objs |1 + block/nfs.c | 444 ++ configure| 26 +++ qapi-schema.json |1 + tests/qemu-iotests/013 |2 +- tests/qemu-iotests/014 |2 +- tests/qemu-iotests/016 |2 +- tests/qemu-iotests/018 |2 +- tests/qemu-iotests/019 |2 +- tests/qemu-iotests/020 |7 +- tests/qemu-iotests/023 |2 +- tests/qemu-iotests/024 |2 +- tests/qemu-iotests/025 |2 +- tests/qemu-iotests/026 |2 +- tests/qemu-iotests/028 |2 +- tests/qemu-iotests/031 |2 +- tests/qemu-iotests/034 |2 +- tests/qemu-iotests/036 |2 +- tests/qemu-iotests/037 |2 +- tests/qemu-iotests/038 |2 +- tests/qemu-iotests/039 |2 +- tests/qemu-iotests/043 |2 +- tests/qemu-iotests/046 |2 +- tests/qemu-iotests/052 |2 +- tests/qemu-iotests/054 |2 +- tests/qemu-iotests/059 |2 +- tests/qemu-iotests/060 |2 +- tests/qemu-iotests/061 |2 +- tests/qemu-iotests/063 |2 +- tests/qemu-iotests/067.out |8 +- tests/qemu-iotests/069 |2 +- tests/qemu-iotests/common| 22 ++- tests/qemu-iotests/common.rc |3 + 34 files changed, 534 insertions(+), 33 deletions(-) create mode 100644 block/nfs.c Any update on the qemu-iotests changes discussed in this thread? The actual NFS patch looks fine. I would like to leave the rework of patch 5 to the maintainers. Maybe you can merge the rest of the series except for this change in patch 2. diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020 index b3c86d8..a42f32f 100755 --- a/tests/qemu-iotests/020 +++ b/tests/qemu-iotests/020 @@ -43,7 +43,7 @@ trap _cleanup; exit \$status 0 1 2 3 15 # Any format supporting backing files _supported_fmt qcow qcow2
Re: [Qemu-devel] [PATCH v8 08/13] dump: add API to write dump header
On 01/28/2014 10:22 AM, qiaonuohan wrote: the functions are used to write header of kdump-compressed format to vmcore. Header of kdump-compressed format includes: 1. common header: DiskDumpHeader32 / DiskDumpHeader64 2. sub header: KdumpSubHeader32 / KdumpSubHeader64 3. extra information: only elf notes here Signed-off-by: Qiao Nuohan qiaonuo...@cn.fujitsu.com Reviewed-by: Laszlo Ersek ler...@redhat.com --- dump.c| 223 + include/sysemu/dump.h | 96 + 2 files changed, 319 insertions(+), 0 deletions(-) diff --git a/dump.c b/dump.c index 3a1944e..4b2799f 100644 --- a/dump.c +++ b/dump.c @@ -778,6 +778,229 @@ static int buf_write_note(const void *buf, size_t size, void *opaque) return 0; } +/* write common header, sub header and elf note to vmcore */ +static int create_header32(DumpState *s) +{ +int ret = 0; +DiskDumpHeader32 *dh = NULL; +KdumpSubHeader32 *kh = NULL; +size_t size; +int endian = s-dump_info.d_endian; +uint32_t block_size; +uint32_t sub_hdr_size; +uint32_t bitmap_blocks; +uint32_t status = 0; +uint64_t offset_note; + +/* write common header, the version of kdump-compressed format is 6th */ +size = sizeof(DiskDumpHeader32); +dh = g_malloc0(size); + +strncpy(dh-signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); +dh-header_version = cpu_convert_to_target32(6, endian); +block_size = s-page_size; +dh-block_size = cpu_convert_to_target32(block_size, endian); +sub_hdr_size = sizeof(struct KdumpSubHeader32) + s-note_size; +sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size); +dh-sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian); +/* dh-max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */ +dh-max_mapnr = cpu_convert_to_target32(MIN(s-max_mapnr, UINT_MAX), +endian); +dh-nr_cpus = cpu_convert_to_target32(s-nr_cpus, endian); +bitmap_blocks = DIV_ROUND_UP(s-len_dump_bitmap, block_size) * 2; +dh-bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian); +memcpy((dh-utsname.machine), i686, 4); + In my opinion, it's not a right thing to hardcode the architecture in arch-independent module dump.c you hardcode it here in create_header32 routine by memcpy((dh-utsname.machine), i686, 4); and in create_header64 routine by memcpy((dh-utsname.machine), x86_64, 6); Besides that you code actually can work on s390x arch. IMHO, target arch should be coded here. Maybe you could make use of this function: cpu_to_uname_machine. +if (s-flag_compress DUMP_DH_COMPRESSED_ZLIB) { +status |= DUMP_DH_COMPRESSED_ZLIB; +} +#ifdef CONFIG_LZO +if (s-flag_compress DUMP_DH_COMPRESSED_LZO) { +status |= DUMP_DH_COMPRESSED_LZO; +} +#endif +#ifdef CONFIG_SNAPPY +if (s-flag_compress DUMP_DH_COMPRESSED_SNAPPY) { +status |= DUMP_DH_COMPRESSED_SNAPPY; +} +#endif +dh-status = cpu_convert_to_target32(status, endian); + +if (write_buffer(s-fd, 0, dh, size) 0) { +dump_error(s, dump: failed to write disk dump header.\n); +ret = -1; +goto out; +} + +/* write sub header */ +size = sizeof(KdumpSubHeader32); +kh = g_malloc0(size); + +/* 64bit max_mapnr_64 */ +kh-max_mapnr_64 = cpu_convert_to_target64(s-max_mapnr, endian); +kh-phys_base = cpu_convert_to_target32(PHYS_BASE, endian); +kh-dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian); + +offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size; +kh-offset_note = cpu_convert_to_target64(offset_note, endian); +kh-note_size = cpu_convert_to_target32(s-note_size, endian); + +if (write_buffer(s-fd, DISKDUMP_HEADER_BLOCKS * + block_size, kh, size) 0) { +dump_error(s, dump: failed to write kdump sub header.\n); +ret = -1; +goto out; +} + +/* write note */ +s-note_buf = g_malloc0(s-note_size); +s-note_buf_offset = 0; + +/* use s-note_buf to store notes temporarily */ +if (write_elf32_notes(buf_write_note, s) 0) { +ret = -1; +goto out; +} + +if (write_buffer(s-fd, offset_note, s-note_buf, + s-note_size) 0) { +dump_error(s, dump: failed to write notes); +ret = -1; +goto out; +} + +/* get offset of dump_bitmap */ +s-offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) * + block_size; + +/* get offset of page */ +s-offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) * + block_size; + +out: +g_free(dh); +g_free(kh); +g_free(s-note_buf); + +return ret; +} + +/* write common header, sub header and elf note to vmcore */ +static int create_header64(DumpState *s) +{ +int ret = 0; +DiskDumpHeader64 *dh = NULL; +
Re: [Qemu-devel] fix/re-do query-command-line-options
Paolo Bonzini pbonz...@redhat.com writes: Il 28/01/2014 10:36, Markus Armbruster ha scritto: I think the data you can usefully collect with this approach is approximately the data getopt_long()[*] gets: list of named command line options, and whether they take an argument. You can use this data to fill in options not covered by QemuOpts. This is a definite improvement. It still falls short of fully solving the command line introspection problem. However, I'm not into rejecting imperfect incremental improvements we can have now in favor of perfect solutions we can maybe have some day. Go right ahead with your incremental improvement! It depends. If we can agree on the following: (a) do not add non-QemuOpts options (we haven't for a while) That would mean we can't ever add an option that doesn't take an argument again. However, we need to somehow stuff those into QemuOpts anyway, so -readconfig / -writeconfig can cover them. (b) document the QemuOpts schema for -acpitable, -smbios, -netdev, -net. These options validate the options with OptsVisitor, so we could do without QemuOpts schema, but we know the schema won't bitrot because we never remove suboptions. -device? (c) do not add any more QemuOpts options without a schema, and use -object instead. Then: (a) there is no need to cover non-QemuOpts options in query-command-line-options. libvirt can treat them as crystallized. Some options are undef #ifdef. That's actually a good idea, because it permits finding out which options are available via command line introspection. Now, what if a non-QemuOpts option is under #ifdef? I haven't checked... Even if there isn't one now, are we ready to give up the ability to do that for good? (b) documenting the schemata is not harder than what Amos proposed. (c) schema inspection for objects remains a problem, but one that we need to solve anyway so it doesn't affect query-command-line-options. As long as we don't have such schema inspection, I'm rather reluctant to reject alternative means to solve problems people have *now*. Do you agree? It depends :)
Re: [Qemu-devel] [PULL 3/4] trace: add glib 2.32+ static GMutex support
On Mon, Jan 27, 2014 at 03:15:47PM +, Daniel P. Berrange wrote: On Mon, Jan 27, 2014 at 03:53:05PM +0100, Stefan Hajnoczi wrote: The GStaticMutex API was deprecated in glib 2.32. We cannot switch over to GMutex unconditionally since we would drop support for older glib versions. But the deprecated API warnings during build are annoying so use static GMutex when possible. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- trace/simple.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/trace/simple.c b/trace/simple.c index 410172e..57572c4 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -40,7 +40,17 @@ * Trace records are written out by a dedicated thread. The thread waits for * records to become available, writes them out, and then waits again. */ +#if GLIB_CHECK_VERSION(2, 32, 0) +static GMutex trace_lock; +#define lock_trace_lock() g_mutex_lock(trace_lock) +#define unlock_trace_lock() g_mutex_unlock(trace_lock) +#define get_trace_lock_mutex() (trace_lock) +#else static GStaticMutex trace_lock = G_STATIC_MUTEX_INIT; +#define lock_trace_lock() g_static_mutex_lock(trace_lock) +#define unlock_trace_lock() g_static_mutex_unlock(trace_lock) +#define get_trace_lock_mutex() g_static_mutex_get_mutex(trace_lock) +#endif coroutine-gthread.c also uses GStaticMutex - is there somewhere you could put some compat calls tobe shared. Perhaps some hack like #define GStaticMutex GMutex #define g_static_mutex_lock(m) g_mutex_lock(m) ? I'll do a follow-up patch to pull together all the glib version abstraction hacks we have in QEMU. Stefan
Re: [Qemu-devel] [PATCH] [RESEND-try-3] hw/9pfs: fix P9_STATS_GEN handling
On Tue, Jan 28, 2014 at 01:40:59PM +0200, Kirill A. Shutemov wrote: Michael S. Tsirkin wrote: On Tue, Jan 28, 2014 at 12:55:51PM +0200, Kirill A. Shutemov wrote: Currently we have few issues with P9_STATS_GEN: - We don't try to read st_gen anything except files or directories, but still set P9_STATS_GEN bit in st_result_mask. It may mislead client: we present garbage as valid st_gen. - If we failed to get valid st_gen with ENOTTY, we ignore error, but still set P9_STATS_GEN bit in st_result_mask. - If we failed to get valid st_gen with any other errno, we fail getattr altogether. It's excessive: we block valid client use-cases, like chdir(2) to non-readable directory with execution bit set. The patch fixes these issues and cleanup code a bit. Signed-off-by: Kirill A. Shutemov kirill.shute...@linux.intel.com Reviewed-by: Daniel P. Berrange berra...@redhat.com Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com Would be better to split unrelated issues out to separate patches. They are not totally unrelated: they all unbreak P9_STATS_GEN. But yes, I can split if it needed. Probably a good idea. If you can append explanation on how to reproduce the bug that's fixed for each patch, even better. diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 8cbb8ae32a03..3e51fcd152f8 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -1080,10 +1080,18 @@ static void v9fs_getattr(void *opaque) /* fill st_gen if requested and supported by underlying fs */ if (request_mask P9_STATS_GEN) { retval = v9fs_co_st_gen(pdu, fidp-path, stbuf.st_mode, v9stat_dotl); -if (retval 0) { +switch (retval) { +case 0: +/* we have valid st_gen: update result mask */ +v9stat_dotl.st_result_mask |= P9_STATS_GEN; +break; +case -EINTR: +/* request cancelled */ goto out; Shouldn't EINTR be retried? No. It could be canceled by client (with Tflush) on purpose and client can retry if needed. -- Kirill A. Shutemov
Re: [Qemu-devel] fix/re-do query-command-line-options
Il 28/01/2014 12:55, Markus Armbruster ha scritto: Paolo Bonzini pbonz...@redhat.com writes: Il 28/01/2014 10:36, Markus Armbruster ha scritto: I think the data you can usefully collect with this approach is approximately the data getopt_long()[*] gets: list of named command line options, and whether they take an argument. You can use this data to fill in options not covered by QemuOpts. This is a definite improvement. It still falls short of fully solving the command line introspection problem. However, I'm not into rejecting imperfect incremental improvements we can have now in favor of perfect solutions we can maybe have some day. Go right ahead with your incremental improvement! It depends. If we can agree on the following: (a) do not add non-QemuOpts options (we haven't for a while) That would mean we can't ever add an option that doesn't take an argument again. We can add it under an existing QemuOpts group or invent a new one (like we did for -rt or -msg). However, we need to somehow stuff those into QemuOpts anyway, so -readconfig / -writeconfig can cover them. Yep. (b) document the QemuOpts schema for -acpitable, -smbios, -netdev, -net. These options validate the options with OptsVisitor, so we could do without QemuOpts schema, but we know the schema won't bitrot because we never remove suboptions. -device? -device already provides its own introspection via qom-list-types and -device driver,?. -object doesn't have an equivalent of -device driver,?, but that's a separate problem. (a) there is no need to cover non-QemuOpts options in query-command-line-options. libvirt can treat them as crystallized. Some options are undef #ifdef. That's actually a good idea, because it permits finding out which options are available via command line introspection. Now, what if a non-QemuOpts option is under #ifdef? I haven't checked... Even if there isn't one now, are we ready to give up the ability to do that for good? There are some: - legacy slirp options -tftp/-bootp/-redir/-smb - -enable-fips is what triggered this discussion, but we found another solution in Libvirt - -tpmdev is enabled only if CONFIG_TPM, but its presence can be queried via qom-list-types too. (b) documenting the schemata is not harder than what Amos proposed. (c) schema inspection for objects remains a problem, but one that we need to solve anyway so it doesn't affect query-command-line-options. As long as we don't have such schema inspection, I'm rather reluctant to reject alternative means to solve problems people have *now*. Note the doesn't affect query-command-line-options part. Amos's patch do not solve the problem of which classes can be instantiated with -object, or of which properties can be used. Paolo Do you agree? It depends :)
Re: [Qemu-devel] [PATCH] scsi: report thin provisioning errors with werror=report
On Mon, Jan 27, 2014 at 02:08:56PM +0100, Paolo Bonzini wrote: SCSI defines a status code for when a thin-provisioned LUNs would exceed the allocated space, map ENOSPC to it. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/scsi/scsi-bus.c | 5 + hw/scsi/scsi-disk.c| 3 +++ include/hw/scsi/scsi.h | 2 ++ 3 files changed, 10 insertions(+) The SBC confirms that SPACE ALLOCATION WRITE PROTECT is used when there is no space. Reviewed-by: Stefan Hajnoczi stefa...@redhat.com