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

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

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

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




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

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

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

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




[Qemu-devel] [PATCH v3 5/8] cpu: Introduce a wrapper for tlb_flush() that can be used in common code

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

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

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




[Qemu-devel] [PATCH v3 6/8] include/exec/poison: Mark CONFIG_SOFTMMU as poisoned

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

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

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




[Qemu-devel] [PATCH v3 1/8] include/exec/poison: Add missing TARGET defines

2017-06-19 Thread Thomas Huth
Since we've got some new CPU targets in QEMU during the last months
and years, we've got some new TARGET_xxx defines now which should
be marked as poisoned for common code.

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

diff --git a/include/exec/poison.h b/include/exec/poison.h
index 3ca7929..859bd56 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -7,22 +7,38 @@
 
 #pragma GCC poison TARGET_I386
 #pragma GCC poison TARGET_X86_64
+#pragma GCC poison TARGET_AARCH64
 #pragma GCC poison TARGET_ALPHA
 #pragma GCC poison TARGET_ARM
 #pragma GCC poison TARGET_CRIS
+#pragma GCC poison TARGET_HPPA
 #pragma GCC poison TARGET_LM32
 #pragma GCC poison TARGET_M68K
+#pragma GCC poison TARGET_MICROBLAZE
 #pragma GCC poison TARGET_MIPS
+#pragma GCC poison TARGET_ABI_MIPSN32
+#pragma GCC poison TARGET_ABI_MIPSO32
 #pragma GCC poison TARGET_MIPS64
+#pragma GCC poison TARGET_ABI_MIPSN64
+#pragma GCC poison TARGET_MOXIE
+#pragma GCC poison TARGET_NIOS2
 #pragma GCC poison TARGET_OPENRISC
 #pragma GCC poison TARGET_PPC
 #pragma GCC poison TARGET_PPCEMB
 #pragma GCC poison TARGET_PPC64
 #pragma GCC poison TARGET_ABI32
+#pragma GCC poison TARGET_S390X
 #pragma GCC poison TARGET_SH4
 #pragma GCC poison TARGET_SPARC
 #pragma GCC poison TARGET_SPARC64
+#pragma GCC poison TARGET_TILEGX
+#pragma GCC poison TARGET_TRICORE
+#pragma GCC poison TARGET_UNICORE32
+#pragma GCC poison TARGET_XTENSA
 
+#pragma GCC poison TARGET_HAS_BFLT
+#pragma GCC poison TARGET_NAME
+#pragma GCC poison TARGET_SUPPORTS_MTTCG
 #pragma GCC poison TARGET_WORDS_BIGENDIAN
 #pragma GCC poison BSWAP_NEEDED
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 4/8] include/exec/poison: Mark CONFIG_KVM as poisoned, too

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

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

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




[Qemu-devel] [PATCH v3 3/8] Move CONFIG_KVM related definitions to kvm_i386.h

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

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

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




[Qemu-devel] [PATCH v3 2/8] include/exec/poison: Mark some CONFIG defines as poisoned, too

2017-06-19 Thread Thomas Huth
These are defined in config-target.h and thus should never be
used in common code.

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

diff --git a/include/exec/poison.h b/include/exec/poison.h
index 859bd56..7a025b2 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -66,5 +66,26 @@
 #pragma GCC poison CPU_INTERRUPT_TGT_INT_1
 #pragma GCC poison CPU_INTERRUPT_TGT_INT_2
 
+#pragma GCC poison CONFIG_ALPHA_DIS
+#pragma GCC poison CONFIG_ARM_A64_DIS
+#pragma GCC poison CONFIG_ARM_DIS
+#pragma GCC poison CONFIG_CRIS_DIS
+#pragma GCC poison CONFIG_HPPA_DIS
+#pragma GCC poison CONFIG_I386_DIS
+#pragma GCC poison CONFIG_LM32_DIS
+#pragma GCC poison CONFIG_M68K_DIS
+#pragma GCC poison CONFIG_MICROBLAZE_DIS
+#pragma GCC poison CONFIG_MIPS_DIS
+#pragma GCC poison CONFIG_MOXIE_DIS
+#pragma GCC poison CONFIG_NIOS2_DIS
+#pragma GCC poison CONFIG_PPC_DIS
+#pragma GCC poison CONFIG_S390_DIS
+#pragma GCC poison CONFIG_SH4_DIS
+#pragma GCC poison CONFIG_SPARC_DIS
+#pragma GCC poison CONFIG_XTENSA_DIS
+
+#pragma GCC poison CONFIG_LINUX_USER
+#pragma GCC poison CONFIG_VHOST_NET
+
 #endif
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 0/8] Poison some more target-specific defines

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

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

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

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

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

-- 
1.8.3.1




Re: [Qemu-devel] [PATCH 1/4] include/exec/poison: Add missing TARGET defines

2017-06-19 Thread Thomas Huth
On 19.06.2017 23:49, Richard Henderson wrote:
> On 06/14/2017 12:21 PM, Thomas Huth wrote:
>>   #pragma GCC poison TARGET_CRIS
>>   #pragma GCC poison TARGET_LM32
> 
> Missing HPPA and TILEGX.

Oh, looks like I missed the new defines from the -linux-user targets ...
thanks for the hint, I'll send a new version.

 Thomas



Re: [Qemu-devel] [PATCH] AcpiDeviceIf: More readable bitmask definition

2017-06-19 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH] AcpiDeviceIf: More readable bitmask definition
Type: series
Message-id: 1497879848-7612-1-git-send-email-clud...@genua.de

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

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

git config --local diff.renamelimit 0
git config --local diff.renames True

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

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
7da9f99 AcpiDeviceIf: More readable bitmask definition

=== OUTPUT BEGIN ===
Checking PATCH 1/1: AcpiDeviceIf: More readable bitmask definition...
ERROR: code indent should never use tabs
#28: FILE: include/hw/acpi/acpi_dev_interface.h:10:
+ACPI_PCI_HOTPLUG_STATUS =^I^I(1 << 1),$

ERROR: code indent should never use tabs
#29: FILE: include/hw/acpi/acpi_dev_interface.h:11:
+ACPI_CPU_HOTPLUG_STATUS =^I^I(1 << 2),$

ERROR: code indent should never use tabs
#30: FILE: include/hw/acpi/acpi_dev_interface.h:12:
+ACPI_MEMORY_HOTPLUG_STATUS =^I(1 << 3),$

ERROR: code indent should never use tabs
#31: FILE: include/hw/acpi/acpi_dev_interface.h:13:
+ACPI_NVDIMM_HOTPLUG_STATUS =^I(1 << 4),$

ERROR: code indent should never use tabs
#32: FILE: include/hw/acpi/acpi_dev_interface.h:14:
+ACPI_VMGENID_CHANGE_STATUS =^I(1 << 5),$

total: 5 errors, 0 warnings, 16 lines checked

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

=== OUTPUT END ===

Test command exited with code: 1


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

Re: [Qemu-devel] [PATCH] target/s390x: Implement CSST

2017-06-19 Thread Thomas Huth
On 20.06.2017 01:44, Richard Henderson wrote:
> On 06/19/2017 01:08 AM, Thomas Huth wrote:
>>> +/* Sanity check the function code and storage characteristic.  */
>>> +if (fc > 1 || sc > 3) {
>>> +if (!s390_has_feat(S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2)) {
>>> +goto spec_exception;
>>> +}
>>> +if (fc > 2 || sc > 4 || (fc == 2 && (r3 & 1))) {
>>
>> I think you could omit the "fc == 2" here. fc has to be bigger than 1
>> due to the outer if-statement, and if it is not 2, the first "fc > 1"
>> has already triggered. So "fc" has to be 2 here and the "fc == 2" is a
>> redundant check.
> 
> Not so.  We can also get here with fc == 0 && sc == 4.

Uh, right, sorry for the confusion!

 Thomas



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

2017-06-19 Thread Mao Zhongyi

Hi, Marcel

On 06/19/2017 08:05 PM, Marcel Apfelbaum wrote:

On 12/06/2017 16:48, Mao Zhongyi wrote:

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

Cc: m...@redhat.com
Cc: mar...@redhat.com
Cc: arm...@redhat.com
Signed-off-by: Mao Zhongyi 
---
  hw/pci-bridge/pci_bridge_dev.c | 21 -
  hw/pci/shpc.c  | 11 +--
  hw/pci/slotid_cap.c| 11 +--
  include/hw/pci/shpc.h  |  3 ++-
  include/hw/pci/slotid_cap.h|  3 ++-
  5 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 5dbd933..30c4186 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -49,12 +49,11 @@ struct PCIBridgeDev {
  };
  typedef struct PCIBridgeDev PCIBridgeDev;
  -static int pci_bridge_dev_initfn(PCIDevice *dev)
+static void pci_bridge_dev_realize(PCIDevice *dev, Error **errp)
  {
  PCIBridge *br = PCI_BRIDGE(dev);
  PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev);
  int err;
-Error *local_err = NULL;
pci_bridge_initfn(dev, TYPE_PCI_BUS);
  @@ -62,7 +61,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  dev->config[PCI_INTERRUPT_PIN] = 0x1;
  memory_region_init(_dev->bar, OBJECT(dev), "shpc-bar",
 shpc_bar_size(dev));
-err = shpc_init(dev, >sec_bus, _dev->bar, 0);
+err = shpc_init(dev, >sec_bus, _dev->bar, 0, errp);
  if (err) {
  goto shpc_error;
  }
@@ -71,7 +70,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  bridge_dev->msi = ON_OFF_AUTO_OFF;
  }
  -err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0);
+err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0, errp);
  if (err) {
  goto slotid_error;
  }
@@ -79,20 +78,18 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  if (bridge_dev->msi != ON_OFF_AUTO_OFF) {
  /* it means SHPC exists, because MSI is needed by SHPC */
  -err = msi_init(dev, 0, 1, true, true, _err);
+err = msi_init(dev, 0, 1, true, true, errp);
  /* Any error other than -ENOTSUP(board's MSI support is broken)
   * is a programming error */
  assert(!err || err == -ENOTSUP);
  if (err && bridge_dev->msi == ON_OFF_AUTO_ON) {
  /* Can't satisfy user's explicit msi=on request, fail */
-error_append_hint(_err, "You have to use msi=auto (default) "
+error_append_hint(errp, "You have to use msi=auto (default) "
  "or msi=off with this machine type.\n");
-error_report_err(local_err);
  goto msi_error;
  }
-assert(!local_err || bridge_dev->msi == ON_OFF_AUTO_AUTO);
+assert(bridge_dev->msi == ON_OFF_AUTO_AUTO);


I am not sure we can drop the !local_err assert.
We don't have a local_err anymore, but the error
is stored now in errp.



I think it's OK if we drop the !local_err assert; even if we don't store the 
error
message to errp.

Because the code can go to assert(!local_err || bridge_dev->msi == 
ON_OFF_AUTO_AUTO)
only if the return value of msi_init is 0(success), then the local_err is NULL, 
no
error message in it. So the assertation of local_err is always superfluous.

Thanks
Mao



Other than that, the patch looks OK to me.

Thanks,
Marcel


  /* With msi=auto, we fall back to MSI off silently */
-error_free(local_err);
  }
if (shpc_present(dev)) {
@@ -101,7 +98,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev)
  pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
   PCI_BASE_ADDRESS_MEM_TYPE_64, _dev->bar);
  }
-return 0;
+return;
msi_error:
  slotid_cap_cleanup(dev);
@@ -111,8 +108,6 @@ slotid_error:
  }
  shpc_error:
  pci_bridge_exitfn(dev);
-
-return err;
  }
static void pci_bridge_dev_exitfn(PCIDevice *dev)
@@ -216,7 +211,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, 
void *data)
  PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
  -k->init = pci_bridge_dev_initfn;
+k->realize = pci_bridge_dev_realize;
  k->exit = pci_bridge_dev_exitfn;
  k->config_write = pci_bridge_dev_write_config;
  k->vendor_id = PCI_VENDOR_ID_REDHAT;
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index d72d5e4..69fc14b 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -446,16 +446,14 @@ static void shpc_cap_update_dword(PCIDevice *d)
  }
/* Add SHPC capability to the config space for the device. */
-static int shpc_cap_add_config(PCIDevice *d)
+static int shpc_cap_add_config(PCIDevice *d, Error **errp)
  {
  uint8_t *config;
  int config_offset;
-Error *local_err = NULL;
  config_offset = pci_add_capability(d, 

Re: [Qemu-devel] [PATCHv6 2/5] fw_cfg: move setting of FW_CFG_VERSION_DMA bit to fw_cfg_init1()

2017-06-19 Thread Philippe Mathieu-Daudé

On 06/19/2017 09:59 AM, Mark Cave-Ayland wrote:

The setting of the FW_CFG_VERSION_DMA bit is the same across both the
TYPE_FW_CFG_MEM and TYPE_FW_CFG_IO devices, so unify the logic in
fw_cfg_init1().

Signed-off-by: Mark Cave-Ayland 
Reviewed-by: Laszlo Ersek 
Tested-by: Laszlo Ersek 


Reviewed-by: Philippe Mathieu-Daudé 


---
 hw/nvram/fw_cfg.c |   16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 4e4f71a..99bdbc2 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -913,6 +913,7 @@ static void fw_cfg_init1(DeviceState *dev)
 {
 FWCfgState *s = FW_CFG(dev);
 MachineState *machine = MACHINE(qdev_get_machine());
+uint32_t version = FW_CFG_VERSION;

 assert(!object_resolve_path(FW_CFG_PATH, NULL));

@@ -927,6 +928,12 @@ static void fw_cfg_init1(DeviceState *dev)
 fw_cfg_bootsplash(s);
 fw_cfg_reboot(s);

+if (s->dma_enabled) {
+version |= FW_CFG_VERSION_DMA;
+}
+
+fw_cfg_add_i32(s, FW_CFG_ID, version);
+
 s->machine_ready.notify = fw_cfg_machine_ready;
 qemu_add_machine_init_done_notifier(>machine_ready);
 }
@@ -938,7 +945,6 @@ FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t 
dma_iobase,
 SysBusDevice *sbd;
 FWCfgIoState *ios;
 FWCfgState *s;
-uint32_t version = FW_CFG_VERSION;
 bool dma_requested = dma_iobase && dma_as;

 dev = qdev_create(NULL, TYPE_FW_CFG_IO);
@@ -959,12 +965,8 @@ FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t 
dma_iobase,
 s->dma_as = dma_as;
 s->dma_addr = 0;
 sysbus_add_io(sbd, dma_iobase, >dma_iomem);
-
-version |= FW_CFG_VERSION_DMA;
 }

-fw_cfg_add_i32(s, FW_CFG_ID, version);
-
 return s;
 }

@@ -980,7 +982,6 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
 DeviceState *dev;
 SysBusDevice *sbd;
 FWCfgState *s;
-uint32_t version = FW_CFG_VERSION;
 bool dma_requested = dma_addr && dma_as;

 dev = qdev_create(NULL, TYPE_FW_CFG_MEM);
@@ -1001,11 +1002,8 @@ FWCfgState *fw_cfg_init_mem_wide(hwaddr ctl_addr,
 s->dma_as = dma_as;
 s->dma_addr = 0;
 sysbus_mmio_map(sbd, 2, dma_addr);
-version |= FW_CFG_VERSION_DMA;
 }

-fw_cfg_add_i32(s, FW_CFG_ID, version);
-
 return s;
 }






Re: [Qemu-devel] [PATCH v3 18/18] target/s390x: Clean up TB flag bits

2017-06-19 Thread Philippe Mathieu-Daudé

On 06/19/2017 09:04 PM, Richard Henderson wrote:

Most of the PSW bits that were being copied into TB->flags
are not relevant to translation.  Removing those that are
unnecessary reduces the amount of translation required.

Signed-off-by: Richard Henderson 


Reviewed-by: Philippe Mathieu-Daudé 


---
 target/s390x/cpu.h   | 24 +---
 target/s390x/translate.c | 16 
 2 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 5b94ace..9faca04 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -346,19 +346,14 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);

 /* tb flags */

-#define FLAG_MASK_PER   (PSW_MASK_PER>> 32)
-#define FLAG_MASK_DAT   (PSW_MASK_DAT>> 32)
-#define FLAG_MASK_IO(PSW_MASK_IO >> 32)
-#define FLAG_MASK_EXT   (PSW_MASK_EXT>> 32)
-#define FLAG_MASK_KEY   (PSW_MASK_KEY>> 32)
-#define FLAG_MASK_MCHECK(PSW_MASK_MCHECK >> 32)
-#define FLAG_MASK_WAIT  (PSW_MASK_WAIT   >> 32)
-#define FLAG_MASK_PSTATE(PSW_MASK_PSTATE >> 32)
-#define FLAG_MASK_ASC   (PSW_MASK_ASC>> 32)
-#define FLAG_MASK_CC(PSW_MASK_CC >> 32)
-#define FLAG_MASK_PM(PSW_MASK_PM >> 32)
-#define FLAG_MASK_64(PSW_MASK_64 >> 32)
-#define FLAG_MASK_320x1000
+#define FLAG_MASK_PSW_SHIFT 31
+#define FLAG_MASK_PER   (PSW_MASK_PER>> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_PSTATE(PSW_MASK_PSTATE >> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_ASC   (PSW_MASK_ASC>> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_64(PSW_MASK_64 >> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_32(PSW_MASK_32 >> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_PSW  (FLAG_MASK_PER | FLAG_MASK_PSTATE \
+| FLAG_MASK_ASC | FLAG_MASK_64 | FLAG_MASK_32)

 /* Control register 0 bits */
 #define CR0_LOWPROT 0x1000ULL
@@ -416,8 +411,7 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, 
target_ulong *pc,
 {
 *pc = env->psw.addr;
 *cs_base = env->ex_value;
-*flags = ((env->psw.mask >> 32) & ~FLAG_MASK_CC) |
- ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
+*flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
 }

 #define MAX_ILEN 6
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 9893551..bee163f 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -323,11 +323,11 @@ static inline uint64_t ld_code4(CPUS390XState *env, 
uint64_t pc)
 static int get_mem_index(DisasContext *s)
 {
 switch (s->tb->flags & FLAG_MASK_ASC) {
-case PSW_ASC_PRIMARY >> 32:
+case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 return 0;
-case PSW_ASC_SECONDARY >> 32:
+case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
 return 1;
-case PSW_ASC_HOME >> 32:
+case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
 return 2;
 default:
 tcg_abort();
@@ -387,7 +387,7 @@ static inline void gen_trap(DisasContext *s)
 #ifndef CONFIG_USER_ONLY
 static void check_privileged(DisasContext *s)
 {
-if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) {
+if (s->tb->flags & FLAG_MASK_PSTATE) {
 gen_program_exception(s, PGM_PRIVILEGED);
 }
 }
@@ -2985,20 +2985,20 @@ static ExitStatus op_mov2e(DisasContext *s, DisasOps *o)
 o->g_in2 = false;

 switch (s->tb->flags & FLAG_MASK_ASC) {
-case PSW_ASC_PRIMARY >> 32:
+case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 tcg_gen_movi_i64(ar1, 0);
 break;
-case PSW_ASC_ACCREG >> 32:
+case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT:
 tcg_gen_movi_i64(ar1, 1);
 break;
-case PSW_ASC_SECONDARY >> 32:
+case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
 if (b2) {
 tcg_gen_ld32u_i64(ar1, cpu_env, offsetof(CPUS390XState, 
aregs[b2]));
 } else {
 tcg_gen_movi_i64(ar1, 0);
 }
 break;
-case PSW_ASC_HOME >> 32:
+case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
 tcg_gen_movi_i64(ar1, 2);
 break;
 }





Re: [Qemu-devel] spapr guests warn "System page size 0x2000 is not enabled in page_size_mask (0x11000). Performance may be slow" on SPARC hosts

2017-06-19 Thread Alexey Kardashevskiy
On 20/06/17 11:02, David Gibson wrote:
> On Mon, Jun 19, 2017 at 12:32:48PM +0200, Thomas Huth wrote:
>> On 19.06.2017 11:39, Alexander Graf wrote:
>>> On 06/15/2017 03:33 PM, Peter Maydell wrote:
 I've just noticed that on a SPARC host, some of the PPC guests
 warn during make check:

/ppc64/prom-env/pseries:
 qemu-system-ppc64: System page size 0x2000 is not enabled in
 page_size_mask (0x11000). Performance may be slow

 Is this really a performance problem on a TCG guest?
 It makes the 'make check' output a bit noisy, but not
 unbearably so.
>>>
>>> From what I can tell this really only affects DDW which should be page
>>> size agnostic when only using emulated devices. Maybe Alexey thought of
>>> using VFIO-pci devices in a TCG guest?
>>
>> Maybe we could at least silence the warning by checking
>> qtest_enabled()?
> 
> 
> So,
> 
> 1) Yes, we should at least silence the warning.

Agree, wrapping it into kvm_enabled() should do it.


> 
> 2) Certainly the mentioned slowdown shouldn't be significant for TCG
> guests.

It is not significant at all. While in-kernel TCE handling improves
throughput for VFIO devices quite a lot (200mb/s -> 1000mb/s), TCG could
not do any better than 20mb/s anyway.


> 3) I _think_ the restriction which causes the slowdown doesn't even
> exist for TCG, but I haven't 100% convinced myself of this.  I've been
> sick lately, so my brain isn't working all that well.

Mismatch between system page size and IOMMU page size means H_PUT_TCE is
going to be called more often than needed; if VFIO is involved, then more
ioctl(vfio_container_fd, DMAP_MAP) calls. But - we cannot do 8K IOMMU pages
at all, SPARC does not support VFIO (or does it?), and TCG is slow anyway.



-- 
Alexey



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v5 6/9] pci: Convert to realize

2017-06-19 Thread Mao Zhongyi

Hi, Marcel

On 06/19/2017 07:42 PM, Marcel Apfelbaum wrote:

On 12/06/2017 16:48, Mao Zhongyi wrote:

The pci-birdge device i82801b11


It is a dmi-to-pci brigde


and io3130_upstream/downstream


You forgot to mention the pcie_root_port.


still implements the old PCIDeviceClass .init() through *_init()
instead of the new .realize(). All devices need to be converted
to .realize(). So convert it and rename it to *_realize().




I would change the message to something more concise like:

"Convert i82801b11, xio3130_downstream, xio3130_upstream
 and pcie_root_port devices to realize."

I am sure it worth a re-spin though.


Thanks for your kind suggestion, I will. :)




Cc: m...@redhat.com
Cc: mar...@redhat.com
Cc: arm...@redhat.com
Signed-off-by: Mao Zhongyi 
---
  hw/pci-bridge/i82801b11.c  | 11 +--
  hw/pci-bridge/pcie_root_port.c | 15 ++-
  hw/pci-bridge/xio3130_downstream.c | 20 +---
  hw/pci-bridge/xio3130_upstream.c   | 20 +---
  hw/pci/pci_bridge.c|  7 +++
  hw/pci/pcie.c  | 11 ++-
  include/hw/pci/pci_bridge.h|  3 ++-
  include/hw/pci/pcie.h  |  3 ++-
  8 files changed, 42 insertions(+), 48 deletions(-)

diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
index 2c065c3..2c1b747 100644
--- a/hw/pci-bridge/i82801b11.c
+++ b/hw/pci-bridge/i82801b11.c
@@ -59,24 +59,23 @@ typedef struct I82801b11Bridge {
  /*< public >*/
  } I82801b11Bridge;
  -static int i82801b11_bridge_initfn(PCIDevice *d)
+static void i82801b11_bridge_realize(PCIDevice *d, Error **errp)
  {
  int rc;
pci_bridge_initfn(d, TYPE_PCI_BUS);
rc = pci_bridge_ssvid_init(d, I82801ba_SSVID_OFFSET,
-   I82801ba_SSVID_SVID, I82801ba_SSVID_SSID);
+   I82801ba_SSVID_SVID, I82801ba_SSVID_SSID,
+   errp);
  if (rc < 0) {
  goto err_bridge;
  }
  pci_config_set_prog_interface(d->config, PCI_CLASS_BRIDGE_PCI_INF_SUB);
-return 0;
+return;
err_bridge:
  pci_bridge_exitfn(d);
-
-return rc;
  }
static const VMStateDescription i82801b11_bridge_dev_vmstate = {
@@ -96,7 +95,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, 
void *data)
  k->vendor_id = PCI_VENDOR_ID_INTEL;
  k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
  k->revision = ICH9_D2P_A2_REVISION;
-k->init = i82801b11_bridge_initfn;
+k->realize = i82801b11_bridge_realize;
  k->config_write = pci_bridge_write_config;
  dc->vmsd = _bridge_dev_vmstate;
  set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index cf36318..00f0b1f 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -59,29 +59,27 @@ static void rp_realize(PCIDevice *d, Error **errp)
  PCIDeviceClass *dc = PCI_DEVICE_GET_CLASS(d);
  PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d);
  int rc;
-Error *local_err = NULL;
pci_config_set_interrupt_pin(d->config, 1);
  pci_bridge_initfn(d, TYPE_PCIE_BUS);
  pcie_port_init_reg(d);
  -rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id, 
rpc->ssid);
+rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id,
+   rpc->ssid, errp);
  if (rc < 0) {
-error_setg(errp, "Can't init SSV ID, error %d", rc);



I suggest using 'error_append_hint' instead of removing
the message; even if it does not add a lot of information,
maybe someone is expecting it to be in the logs.


OK, I see.




  goto err_bridge;
  }
if (rpc->interrupts_init) {
-rc = rpc->interrupts_init(d, _err);
+rc = rpc->interrupts_init(d, errp);
  if (rc < 0) {
-error_propagate(errp, local_err);
  goto err_bridge;
  }
  }
  -rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT, p->port);
+rc = pcie_cap_init(d, rpc->exp_offset, PCI_EXP_TYPE_ROOT_PORT,
+   p->port, errp);
  if (rc < 0) {
-error_setg(errp, "Can't add Root Port capability, error %d", rc);
  goto err_int;
  }
  @@ -98,9 +96,8 @@ static void rp_realize(PCIDevice *d, Error **errp)
  }
rc = pcie_aer_init(d, PCI_ERR_VER, rpc->aer_offset,
-   PCI_ERR_SIZEOF, _err);
+   PCI_ERR_SIZEOF, errp);
  if (rc < 0) {
-error_propagate(errp, local_err);
  goto err;
  }
  pcie_aer_root_init(d);
diff --git a/hw/pci-bridge/xio3130_downstream.c 
b/hw/pci-bridge/xio3130_downstream.c
index cfe8a36..e706f36 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -56,33 +56,33 @@ static void xio3130_downstream_reset(DeviceState *qdev)
  pci_bridge_reset(qdev);
  }
  -static 

Re: [Qemu-devel] Fwd: [DPDK-memory] how qemu waste such long time under dpdk huge page envriment?

2017-06-19 Thread Sam
OK,

Grub is bellow, which use huge page 1G.

linux16 /boot/vmlinuz-0-rescue-1324ca4d8099476d99a8633e7cb952b7
> root=UUID=9c3cf5ff-7c35-40c4-a6d9-0fc67683c4ed ro crashkernel=auto rhgb
> quiet default_hugepagesz=1G hugepagesz=1G hugepages=112, isolcpus=2,18


this is command line, ddc979cd is vhostuser interface connect with
ovs-dpdk. For normal ovs, which is not ovs-dpdk, start time is 2 second,
and there is no dpdk vhost user interface. For ovs-dpdk, start time is 15+
second, and there is dpdk vhost user interface.

CMD="$QEMU_CMD -enable-kvm -cpu
> qemu64,+vmx,+ssse3,+sse4.1,+sse4.2,+x2apic,+aes,+avx,+vme,+pat,+ss,+pclmulqdq,+xsave,level=13
> -machine pc,accel=kvm -chardev
> socket,id=hmqmondev,port=55902,host=127.0.0.1,nodelay,server,nowait -mon
> chardev=hmqmondev,id=hmqmon,mode=readline -rtc
> base=utc,clock=host,driftfix=none -usb -device usb-tablet -daemonize
> -nodefaults -nodefconfig -no-kvm-pit-reinjection -global
> kvm-pit.lost_tick_policy=discard -vga std -k en-us -smp 8 -name test-name-5
> -m 40960 -boot order=cdn -vnc :2,password -drive
> file=$DISK_0,if=none,id=drive_0,format=qcow2,cache=none,aio=native -device
> virtio-blk-pci,id=dev_drive_0,drive=drive_0,bus=pci.0,addr=0x5 -drive
> file=$DISK_1,if=none,id=drive_1,format=qcow2,cache=none,aio=native -device
> virtio-blk-pci,id=dev_drive_1,drive=drive_1,bus=pci.0,addr=0x6 -drive
> file=$DISK_2,if=none,id=drive_2,format=qcow2,cache=none,aio=native -device
> virtio-blk-pci,id=dev_drive_2,drive=drive_2,bus=pci.0,addr=0x7 -device
> ide-cd,drive=ide0-cd0,bus=ide.1,unit=1 -drive
> id=ide0-cd0,media=cdrom,if=none -chardev
> socket,id=char-n-ddc979cd,path=/usr/local/var/run/openvswitch/n-ddc979cd,server
> -netdev type=vhost-user,id=n-ddc979cd,chardev=char-n-ddc979cd,vhostforce=on
> -device
> virtio-net-pci,netdev=n-ddc979cd,mac=00:22:dd:c9:79:cd,id=netdev-n-ddc979cd,addr=0xf$(nic_speed
> 1) -object
> memory-backend-file,id=mem,size=40960M,mem-path=/mnt/huge,share=on -numa
> node,memdev=mem -mem-prealloc -pidfile $PID_FILE -chardev
> socket,path=/opt/cloud/workspace/servers/b2cebb02-d171-4929-95d6-61e54cd647f7/qga.sock,server,nowait,id=qga0
> -device virtio-serial -device
> virtserialport,chardev=qga0,name=org.qemu.guest_agent.0"


$QEMU_CMD is qemu binary file like 'qemu-system-x86_64_2.6.0'.

BTW, when I only start ovs-dpdk in huge page enviroment, ovs-dpdk start
time is also longer then normal ovs, and it is hang in EAL initializition
and seetting up physical contiguous memory, log like this:

EAL: Setting up physically contiguous memory...


But qemu don't need EAL initilizition, that's the question I can't figure
out.

And qemu long time start up only happened in huge page enviroment, I don't
know why.









2017-06-19 17:45 GMT+08:00 Daniel P. Berrange :

> On Mon, Jun 19, 2017 at 05:30:59PM +0800, Sam wrote:
> > Hi all,
> >
> > I'm running `QEMU_CMD ...` to create a vm under dpdk huge page envriment
> > (which set huge page 1G). And I enable all events in qemu.
>
> Please provide the full QEMU command line you are using.
>
> > For qemu and ovs-dpdk(ovs-2.4.9 with dpdk-2.2.0) environment, detail log
> is:
> >
> > > 30012@1497443246.678304:object_dynamic_cast_assert
> > qemu:memory-region->qemu:memory-region (/home/hu
> > > anghuai/cloud/contrib/qemu-2.6.0/memory.c:1076:memory_region_initfn)
> > > 30012@1497443256.274866:object_dynamic_cast_assert
> > qio-channel-socket->qio-channel-socket (io/chann
> > > el-socket.c:389:qio_channel_socket_init)
> >
> >
> > I don't know why qemu doing 'memory_region_initfn' function in this 10
> > second, does anyone know this?
>
> If memory initialization takes a long time, this is likely a result of
> QEMU pre-allocating the memory pages, which is a fairly slow procedure,
> that can have noticable startup time impact for guests with large RAM
>
>
> > static void memory_region_initfn(Object *obj)
> > > {
> > > MemoryRegion *mr = MEMORY_REGION(obj);
> > > ObjectProperty *op;
> > > mr->ops = _mem_ops;
> > > mr->enabled = true;
> > > mr->romd_mode = true;
> > > mr->global_locking = true;
> > > mr->destructor = memory_region_destructor_none;
> > > QTAILQ_INIT(>subregions);
> > > QTAILQ_INIT(>coalesced);
> > > op = object_property_add(OBJECT(mr), "container",
> > >  "link<" TYPE_MEMORY_REGION ">",
> > >  memory_region_get_container,
> > >  NULL, /* memory_region_set_container */
> > >  NULL, NULL, _abort);
> > > op->resolve = memory_region_resolve_container;
> > > object_property_add(OBJECT(mr), "addr", "uint64",
> > > memory_region_get_addr,
> > > NULL, /* memory_region_set_addr */
> > > NULL, NULL, _abort);
> > > object_property_add(OBJECT(mr), "priority", "uint32",
> > > memory_region_get_priority,
> > > 

[Qemu-devel] [PATCH 5/5] spapr: Use unplug_request for PCI hot unplug

2017-06-19 Thread David Gibson
AIUI, ->unplug_request in the HotplugHandler is used for "soft"
unplug, where acknowledgement from the guest is required before
completing the unplug, whereas ->unplug is used for "hard" unplug
where qemu unilaterally removes the device, and the guest just has to
cope with its sudden absence.  For spapr we (correctly) use
->unplug_request for CPU and memory hot unplug but we use ->unplug for
PCI.

While I think it might be possible to support "hard" PCI unplug within
the PAPR model, that's not how it actually works now.  Although it's
called from ->unplug, the PCI unplug path will usually just mark the
device for removal, with completion of the unplug delayed until
userspace responds to the unplug notification. If the guest doesn't
respond as expected, that could delay the unplug completiong
arbitrarily long.

To reflect that, change the PCI unplug path to be called from
->unplug_request.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_pci.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index f2543ef..bda8938 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1469,8 +1469,8 @@ out:
 }
 }
 
-static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,
-   DeviceState *plugged_dev, Error **errp)
+static void spapr_pci_unplug_request(HotplugHandler *plug_handler,
+ DeviceState *plugged_dev, Error **errp)
 {
 sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));
 PCIDevice *pdev = PCI_DEVICE(plugged_dev);
@@ -1485,6 +1485,7 @@ static void spapr_phb_hot_unplug_child(HotplugHandler 
*plug_handler,
 }
 
 g_assert(drc);
+g_assert(drc->dev == plugged_dev);
 
 drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
 if (!drck->release_pending(drc)) {
@@ -1973,7 +1974,7 @@ static void spapr_phb_class_init(ObjectClass *klass, void 
*data)
 dc->user_creatable = true;
 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 hp->plug = spapr_phb_hot_plug_child;
-hp->unplug = spapr_phb_hot_unplug_child;
+hp->unplug_request = spapr_pci_unplug_request;
 }
 
 static const TypeInfo spapr_phb_info = {
-- 
2.9.4




[Qemu-devel] [PATCH 3/5] spapr: Add DRC release method

2017-06-19 Thread David Gibson
At the moment, spapr_drc_release() has an ugly switch on the DRC type to
call the right, device-specific release function.  This cleans it up by
doing that via a proper QOM method.

It's still arguably an abstraction violation for the DRC code to call into
the specific device code, but one mess at a time.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_drc.c | 22 ++
 include/hw/ppc/spapr_drc.h |  1 +
 2 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index e5dff16..32e39f2 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -370,22 +370,9 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState 
*d, void *fdt,
 
 static void spapr_drc_release(sPAPRDRConnector *drc)
 {
-/* Calling release callbacks based on spapr_drc_type(drc). */
-switch (spapr_drc_type(drc)) {
-case SPAPR_DR_CONNECTOR_TYPE_CPU:
-spapr_core_release(drc->dev);
-break;
-case SPAPR_DR_CONNECTOR_TYPE_PCI:
-spapr_phb_remove_pci_device_cb(drc->dev);
-break;
-case SPAPR_DR_CONNECTOR_TYPE_LMB:
-spapr_lmb_release(drc->dev);
-break;
-case SPAPR_DR_CONNECTOR_TYPE_PHB:
-case SPAPR_DR_CONNECTOR_TYPE_VIO:
-default:
-g_assert(false);
-}
+sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+
+drck->release(drc->dev);
 
 drc->awaiting_release = false;
 g_free(drc->fdt);
@@ -629,6 +616,7 @@ static void spapr_drc_cpu_class_init(ObjectClass *k, void 
*data)
 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_CPU;
 drck->typename = "CPU";
 drck->drc_name_prefix = "CPU ";
+drck->release = spapr_core_release;
 }
 
 static void spapr_drc_pci_class_init(ObjectClass *k, void *data)
@@ -638,6 +626,7 @@ static void spapr_drc_pci_class_init(ObjectClass *k, void 
*data)
 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_PCI;
 drck->typename = "28";
 drck->drc_name_prefix = "C";
+drck->release = spapr_phb_remove_pci_device_cb;
 }
 
 static void spapr_drc_lmb_class_init(ObjectClass *k, void *data)
@@ -647,6 +636,7 @@ static void spapr_drc_lmb_class_init(ObjectClass *k, void 
*data)
 drck->typeshift = SPAPR_DR_CONNECTOR_TYPE_SHIFT_LMB;
 drck->typename = "MEM";
 drck->drc_name_prefix = "LMB ";
+drck->release = spapr_lmb_release;
 }
 
 static const TypeInfo spapr_dr_connector_info = {
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index d9cacb3..6fd84d1 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -217,6 +217,7 @@ typedef struct sPAPRDRConnectorClass {
 sPAPRDREntitySense (*dr_entity_sense)(sPAPRDRConnector *drc);
 uint32_t (*isolate)(sPAPRDRConnector *drc);
 uint32_t (*unisolate)(sPAPRDRConnector *drc);
+void (*release)(DeviceState *dev);
 
 /* QEMU interfaces for managing hotplug operations */
 bool (*release_pending)(sPAPRDRConnector *drc);
-- 
2.9.4




[Qemu-devel] [PATCH 0/5] spapr: DRC cleanups (part V)

2017-06-19 Thread David Gibson
This fifth set of cleanups to the DRC code mostly deals with removing
unnecessary differences between different cases on the various hot
plug and unplug paths.

David Gibson (5):
  spapr: Leave DR-indicator management to the guest
  spapr: Uniform DRC reset paths
  spapr: Add DRC release method
  spapr: Remove unnecessary differences between hotplug and coldplug
paths
  spapr: Use unplug_request for PCI hot unplug

 hw/ppc/spapr.c | 44 +++-
 hw/ppc/spapr_drc.c | 37 -
 hw/ppc/spapr_pci.c | 10 +-
 include/hw/ppc/spapr_drc.h |  3 ++-
 4 files changed, 26 insertions(+), 68 deletions(-)

-- 
2.9.4




[Qemu-devel] [PATCH 2/5] spapr: Uniform DRC reset paths

2017-06-19 Thread David Gibson
DRC objects have a regular device reset method.  However, it only gets
called in the usual way for PCI DRCs.  Because of where CPU and LMB DRCs
are in the QOM tree, their device reset method isn't automatically called.
So, the machine manually registers reset handlers to call device_reset().

This patch removes the device reset method, and instead always explicitly
registers the reset handler from realize().  This means the callers don't
have to worry about the two cases, and we always get proper resets.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 31 ---
 hw/ppc/spapr_drc.c |  6 +++---
 2 files changed, 7 insertions(+), 30 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8a0c247..f12bc4d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1967,24 +1967,6 @@ static void spapr_boot_set(void *opaque, const char 
*boot_device,
 machine->boot_order = g_strdup(boot_device);
 }
 
-/*
- * Reset routine for LMB DR devices.
- *
- * Unlike PCI DR devices, LMB DR devices explicitly register this reset
- * routine. Reset for PCI DR devices will be handled by PHB reset routine
- * when it walks all its children devices. LMB devices reset occurs
- * as part of spapr_ppc_reset().
- */
-static void spapr_drc_reset(void *opaque)
-{
-sPAPRDRConnector *drc = opaque;
-DeviceState *d = DEVICE(drc);
-
-if (d) {
-device_reset(d);
-}
-}
-
 static void spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr)
 {
 MachineState *machine = MACHINE(spapr);
@@ -1993,13 +1975,11 @@ static void 
spapr_create_lmb_dr_connectors(sPAPRMachineState *spapr)
 int i;
 
 for (i = 0; i < nr_lmbs; i++) {
-sPAPRDRConnector *drc;
 uint64_t addr;
 
 addr = i * lmb_size + spapr->hotplug_memory.base;
-drc = spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_LMB,
- addr/lmb_size);
-qemu_register_reset(spapr_drc_reset, drc);
+spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_LMB,
+   addr / lmb_size);
 }
 }
 
@@ -2093,11 +2073,8 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
 int core_id = i * smp_threads;
 
 if (mc->has_hotpluggable_cpus) {
-sPAPRDRConnector *drc =
-spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU,
-   (core_id / smp_threads) * smt);
-
-qemu_register_reset(spapr_drc_reset, drc);
+spapr_dr_connector_new(OBJECT(spapr), TYPE_SPAPR_DRC_CPU,
+   (core_id / smp_threads) * smt);
 }
 
 if (i < boot_cores_nr) {
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 0bc9046..e5dff16 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -426,9 +426,9 @@ static bool release_pending(sPAPRDRConnector *drc)
 return drc->awaiting_release;
 }
 
-static void reset(DeviceState *d)
+static void drc_reset(void *opaque)
 {
-sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
+sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(opaque);
 
 trace_spapr_drc_reset(spapr_drc_index(drc));
 
@@ -536,6 +536,7 @@ static void realize(DeviceState *d, Error **errp)
 g_free(child_name);
 vmstate_register(DEVICE(drc), spapr_drc_index(drc), _spapr_drc,
  drc);
+qemu_register_reset(drc_reset, drc);
 trace_spapr_drc_realize_complete(spapr_drc_index(drc));
 }
 
@@ -594,7 +595,6 @@ static void spapr_dr_connector_class_init(ObjectClass *k, 
void *data)
 DeviceClass *dk = DEVICE_CLASS(k);
 sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
 
-dk->reset = reset;
 dk->realize = realize;
 dk->unrealize = unrealize;
 drck->release_pending = release_pending;
-- 
2.9.4




[Qemu-devel] [PATCH 4/5] spapr: Remove unnecessary differences between hotplug and coldplug paths

2017-06-19 Thread David Gibson
spapr_drc_attach() has a 'coldplug' parameter which sets the DRC into
configured state initially, instead of the usual ISOLATED/UNUSABLE state.
It turns out this is unnecessary: although coldplugged devices do need to
be in CONFIGURED state once the guest starts, that will already be
accomplished by the reset code which will move DRCs for already plugged
devices into a coldplug equivalent state.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr.c | 13 +++--
 hw/ppc/spapr_drc.c |  5 ++---
 hw/ppc/spapr_pci.c |  3 +--
 include/hw/ppc/spapr_drc.h |  2 +-
 4 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index f12bc4d..35f2d4b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -2611,7 +2611,7 @@ static void spapr_add_lmbs(DeviceState *dev, uint64_t 
addr_start, uint64_t size,
 fdt_offset = spapr_populate_memory_node(fdt, node, addr,
 SPAPR_MEMORY_BLOCK_SIZE);
 
-spapr_drc_attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp);
+spapr_drc_attach(drc, dev, fdt, fdt_offset, errp);
 addr += SPAPR_MEMORY_BLOCK_SIZE;
 }
 /* send hotplug notification to the
@@ -2955,17 +2955,10 @@ static void spapr_core_plug(HotplugHandler 
*hotplug_dev, DeviceState *dev,
 
 g_assert(drc || !mc->has_hotpluggable_cpus);
 
-/*
- * Setup CPU DT entries only for hotplugged CPUs. For boot time or
- * coldplugged CPUs DT entries are setup in spapr_build_fdt().
- */
-if (dev->hotplugged) {
-fdt = spapr_populate_hotplug_cpu_dt(cs, _offset, spapr);
-}
+fdt = spapr_populate_hotplug_cpu_dt(cs, _offset, spapr);
 
 if (drc) {
-spapr_drc_attach(drc, dev, fdt, fdt_offset, !dev->hotplugged,
- _err);
+spapr_drc_attach(drc, dev, fdt, fdt_offset, _err);
 if (local_err) {
 g_free(fdt);
 error_propagate(errp, local_err);
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 32e39f2..e70879a 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -340,7 +340,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const 
char *name,
 }
 
 void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
-  int fdt_start_offset, bool coldplug, Error **errp)
+  int fdt_start_offset, Error **errp)
 {
 trace_spapr_drc_attach(spapr_drc_index(drc));
 
@@ -351,12 +351,11 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState 
*d, void *fdt,
 if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_PCI) {
 g_assert(drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE);
 }
-g_assert(fdt || coldplug);
+g_assert(fdt);
 
 drc->dev = d;
 drc->fdt = fdt;
 drc->fdt_start_offset = fdt_start_offset;
-drc->configured = coldplug;
 
 if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {
 drc->awaiting_allocation = true;
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 0b447f2..f2543ef 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1435,8 +1435,7 @@ static void spapr_phb_hot_plug_child(HotplugHandler 
*plug_handler,
 goto out;
 }
 
-spapr_drc_attach(drc, DEVICE(pdev), fdt, fdt_start_offset,
- !plugged_dev->hotplugged, _err);
+spapr_drc_attach(drc, DEVICE(pdev), fdt, fdt_start_offset, _err);
 if (local_err) {
 goto out;
 }
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index 6fd84d1..d15e9eb 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -234,7 +234,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object 
*owner,
   uint32_t drc_type_mask);
 
 void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
-  int fdt_start_offset, bool coldplug, Error **errp);
+  int fdt_start_offset, Error **errp);
 void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp);
 
 #endif /* HW_SPAPR_DRC_H */
-- 
2.9.4




[Qemu-devel] [PATCH 1/5] spapr: Leave DR-indicator management to the guest

2017-06-19 Thread David Gibson
The DR-indicator is essentially a "virtual LED" attached to a hotpluggable
device, which the guest can set to various states for the attention of
the operator or management layers.

It's mostly guest managed, except that we once-off set it to
ACTIVE/INACTIVE in the attach/detach path.  While that makes certain sense,
there's no indication in PAPR that the hypervisor should do this, and the
drmgr code on the guest side doesn't appear to need it (it will already set
the indicator to ACTIVE on hotplug, and INACTIVE on remove).

So, leave the DR-indicator entirely to the guest; the only thing we need
to do is ensure it's in a sane state on reset.

Signed-off-by: David Gibson 
---
 hw/ppc/spapr_drc.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index fd9e07d..0bc9046 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -353,8 +353,6 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState 
*d, void *fdt,
 }
 g_assert(fdt || coldplug);
 
-drc->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;
-
 drc->dev = d;
 drc->fdt = fdt;
 drc->fdt_start_offset = fdt_start_offset;
@@ -372,8 +370,6 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState 
*d, void *fdt,
 
 static void spapr_drc_release(sPAPRDRConnector *drc)
 {
-drc->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE;
-
 /* Calling release callbacks based on spapr_drc_type(drc). */
 switch (spapr_drc_type(drc)) {
 case SPAPR_DR_CONNECTOR_TYPE_CPU:
@@ -452,12 +448,14 @@ static void reset(DeviceState *d)
 if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {
 drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE;
 }
+drc->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE;
 } else {
 /* Otherwise device is absent, but might be hotplugged */
 drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
 if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) {
 drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_UNUSABLE;
 }
+drc->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE;
 }
 }
 
-- 
2.9.4




Re: [Qemu-devel] [PATCH 6/6] spapr: Clean up DRC set_isolation_state() path

2017-06-19 Thread David Gibson
On Mon, Jun 19, 2017 at 05:52:27PM -0500, Michael Roth wrote:
> Quoting David Gibson (2017-06-08 00:09:30)
> > There are substantial differences in the various paths through
> > set_isolation_state(), both for setting to ISOLATED versus UNISOLATED
> > state and for logical versus physical DRCs.
> > 
> > So, split the set_isolation_state() method into isolate() and unisolate()
> > methods, and give it different implementations for the two DRC types.
> > 
> > Factor some minimal common checks, including for valid indicator values
> > (which we weren't previously checking) into rtas_set_isolation_state().
> > 
> > Signed-off-by: David Gibson 
> > ---
> >  hw/ppc/spapr_drc.c | 145 
> > -
> >  include/hw/ppc/spapr_drc.h |   6 +-
> >  2 files changed, 105 insertions(+), 46 deletions(-)
> > 
> > diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> > index 9e01d7b..90c0fde 100644
> > --- a/hw/ppc/spapr_drc.c
> > +++ b/hw/ppc/spapr_drc.c
> > @@ -46,30 +46,64 @@ uint32_t spapr_drc_index(sPAPRDRConnector *drc)
> >  | (drc->id & DRC_INDEX_ID_MASK);
> >  }
> > 
> > -static uint32_t set_isolation_state(sPAPRDRConnector *drc,
> > -sPAPRDRIsolationState state)
> > +static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
> >  {
> > -trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
> > -
> >  /* if the guest is configuring a device attached to this DRC, we
> >   * should reset the configuration state at this point since it may
> >   * no longer be reliable (guest released device and needs to start
> >   * over, or unplug occurred so the FDT is no longer valid)
> >   */
> > -if (state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
> > -g_free(drc->ccs);
> > -drc->ccs = NULL;
> > -}
> > +g_free(drc->ccs);
> > +drc->ccs = NULL;
> > 
> > -if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
> > -/* cannot unisolate a non-existent resource, and, or resources
> > - * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 
> > 13.5.3.5)
> > - */
> > -if (!drc->dev ||
> > -drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
> > -return RTAS_OUT_NO_SUCH_INDICATOR;
> > +drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
> > +
> > +/* if we're awaiting release, but still in an unconfigured state,
> > + * it's likely the guest is still in the process of configuring
> > + * the device and is transitioning the devices to an ISOLATED
> > + * state as a part of that process. so we only complete the
> > + * removal when this transition happens for a device in a
> > + * configured state, as suggested by the state diagram from PAPR+
> > + * 2.7, 13.4
> > + */
> > +if (drc->awaiting_release) {
> > +uint32_t drc_index = spapr_drc_index(drc);
> > +if (drc->configured) {
> > +trace_spapr_drc_set_isolation_state_finalizing(drc_index);
> > +spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
> > +} else {
> > +trace_spapr_drc_set_isolation_state_deferring(drc_index);
> >  }
> >  }
> > +drc->configured = false;
> > +
> > +return RTAS_OUT_SUCCESS;
> > +}
> > +
> > +static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
> > +{
> > +/* cannot unisolate a non-existent resource, and, or resources
> > + * which are in an 'UNUSABLE' allocation state. (PAPR 2.7,
> > + * 13.5.3.5)
> > + */
> > +if (!drc->dev) {
> > +return RTAS_OUT_NO_SUCH_INDICATOR;
> > +}
> > +
> > +drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
> > +
> > +return RTAS_OUT_SUCCESS;
> > +}
> > +
> > +static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
> > +{
> > +/* if the guest is configuring a device attached to this DRC, we
> > + * should reset the configuration state at this point since it may
> > + * no longer be reliable (guest released device and needs to start
> > + * over, or unplug occurred so the FDT is no longer valid)
> > + */
> > +g_free(drc->ccs);
> > +drc->ccs = NULL;
> > 
> >  /*
> >   * Fail any requests to ISOLATE the LMB DRC if this LMB doesn't
> > @@ -81,35 +115,47 @@ static uint32_t set_isolation_state(sPAPRDRConnector 
> > *drc,
> >   * If the LMB being removed doesn't belong to a DIMM device that is
> >   * actually being unplugged, fail the isolation request here.
> >   */
> > -if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) {
> > -if ((state == SPAPR_DR_ISOLATION_STATE_ISOLATED) &&
> > - !drc->awaiting_release) {
> > -return RTAS_OUT_HW_ERROR;
> > -}
> > +if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB
> > +&& !drc->awaiting_release) {
> > +return RTAS_OUT_HW_ERROR;
> >  }
> > 
> > -

Re: [Qemu-devel] spapr guests warn "System page size 0x2000 is not enabled in page_size_mask (0x11000). Performance may be slow" on SPARC hosts

2017-06-19 Thread David Gibson
On Mon, Jun 19, 2017 at 12:32:48PM +0200, Thomas Huth wrote:
> On 19.06.2017 11:39, Alexander Graf wrote:
> > On 06/15/2017 03:33 PM, Peter Maydell wrote:
> >> I've just noticed that on a SPARC host, some of the PPC guests
> >> warn during make check:
> >>
> >>/ppc64/prom-env/pseries:
> >> qemu-system-ppc64: System page size 0x2000 is not enabled in
> >> page_size_mask (0x11000). Performance may be slow
> >>
> >> Is this really a performance problem on a TCG guest?
> >> It makes the 'make check' output a bit noisy, but not
> >> unbearably so.
> > 
> > From what I can tell this really only affects DDW which should be page
> > size agnostic when only using emulated devices. Maybe Alexey thought of
> > using VFIO-pci devices in a TCG guest?
> 
> Maybe we could at least silence the warning by checking
> qtest_enabled()?


So,

1) Yes, we should at least silence the warning.

2) Certainly the mentioned slowdown shouldn't be significant for TCG
guests.

3) I _think_ the restriction which causes the slowdown doesn't even
exist for TCG, but I haven't 100% convinced myself of this.  I've been
sick lately, so my brain isn't working all that well.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v3] usb-host: support devices with sparse/non-sequential USB interfaces

2017-06-19 Thread Samuel Brian

Sorry I botched the format in the previous two versions.
And that automatic build test failure was unrelated.


Gerd, regarding your response to the original patch:
> Patch looks good but fails to apply.

Have you had a chance to consider/test this further?
Is there anything you would like me to change?

Sam


On 14/06/17 09:40, Samuel Brian wrote:

Some USB devices have sparse interface numbering which is not able to be
passthroughed.
For example, the Sierra Wireless MC7455/MC7430:

   # lsusb  -D /dev/bus/usb/003/003 | egrep 
'1199|9071|bNumInterfaces|bInterfaceNumber'
   Device: ID 1199:9071 Sierra Wireless, Inc.
 idVendor   0x1199 Sierra Wireless, Inc.
 idProduct  0x9071
   bNumInterfaces  5
 bInterfaceNumber0
 bInterfaceNumber2
 bInterfaceNumber3
 bInterfaceNumber8
 bInterfaceNumber   10

In this case, the interface numbers are 0, 2, 3, 8, 10 and not the
0, 1, 2, 3, 4 that QEMU tries to claim.

This change allows sparse USB interface numbering.
Instead of only claiming the interfaces in the range reported by the USB
device through bNumInterfaces, QEMU attempts to claim all possible
interfaces.

v2 to fix broken v1 patch formatting.
v3 to fix indentation.

Signed-off-by: Samuel Brian 
---
  hw/usb/host-libusb.c | 24 ++--
  1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index f9c8eafe06..1b0be071cc 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1107,7 +1107,7 @@ static void usb_host_detach_kernel(USBHostDevice *s)
  if (rc != 0) {
  return;
  }
-for (i = 0; i < conf->bNumInterfaces; i++) {
+for (i = 0; i < USB_MAX_INTERFACES; i++) {
  rc = libusb_kernel_driver_active(s->dh, i);
  usb_host_libusb_error("libusb_kernel_driver_active", rc);
  if (rc != 1) {
@@ -1130,7 +1130,7 @@ static void usb_host_attach_kernel(USBHostDevice *s)
  if (rc != 0) {
  return;
  }
-for (i = 0; i < conf->bNumInterfaces; i++) {
+for (i = 0; i < USB_MAX_INTERFACES; i++) {
  if (!s->ifs[i].detached) {
  continue;
  }
@@ -1145,7 +1145,7 @@ static int usb_host_claim_interfaces(USBHostDevice *s, 
int configuration)
  {
  USBDevice *udev = USB_DEVICE(s);
  struct libusb_config_descriptor *conf;
-int rc, i;
+int rc, i, claimed;
  
  for (i = 0; i < USB_MAX_INTERFACES; i++) {

  udev->altsetting[i] = 0;
@@ -1164,14 +1164,19 @@ static int usb_host_claim_interfaces(USBHostDevice *s, 
int configuration)
  return USB_RET_STALL;
  }
  
-for (i = 0; i < conf->bNumInterfaces; i++) {

+claimed = 0;
+for (i = 0; i < USB_MAX_INTERFACES; i++) {
  trace_usb_host_claim_interface(s->bus_num, s->addr, configuration, i);
  rc = libusb_claim_interface(s->dh, i);
-usb_host_libusb_error("libusb_claim_interface", rc);
-if (rc != 0) {
-return USB_RET_STALL;
+if (rc == 0) {
+s->ifs[i].claimed = true;
+if (++claimed == conf->bNumInterfaces) {
+break;
+}
  }
-s->ifs[i].claimed = true;
+}
+if (claimed != conf->bNumInterfaces) {
+return USB_RET_STALL;
  }
  
  udev->ninterfaces   = conf->bNumInterfaces;

@@ -1183,10 +1188,9 @@ static int usb_host_claim_interfaces(USBHostDevice *s, 
int configuration)
  
  static void usb_host_release_interfaces(USBHostDevice *s)

  {
-USBDevice *udev = USB_DEVICE(s);
  int i, rc;
  
-for (i = 0; i < udev->ninterfaces; i++) {

+for (i = 0; i < USB_MAX_INTERFACES; i++) {
  if (!s->ifs[i].claimed) {
  continue;
  }





Re: [Qemu-devel] [PATCH 0/6] spapr: DRC cleanups (part IV)

2017-06-19 Thread David Gibson
On Thu, Jun 08, 2017 at 03:09:24PM +1000, David Gibson wrote:
> This fourth isntallment of cleanups to the DRC code introduces the
> first changes to the fundamental state handling.  We change the
> initial states in the reset code and attach code for PCI devices, and
> are able to remove the 'signalled' state variable with those fixes.
> 
> There are also some more mechanical cleanups in preparation for
> further cleanups and fixes to the state management.

Merged to ppc-for-2.10.

> 
> David Gibson (6):
>   spapr: Start hotplugged PCI devices in ISOLATED state
>   spapr: Eliminate DRC 'signalled' state variable
>   spapr: Split DRC release from DRC detach
>   spapr: Make DRC reset force DRC into known state
>   spapr: Clean up DRC set_allocation_state path
>   spapr: Clean up DRC set_isolation_state() path
> 
>  hw/ppc/spapr.c |  15 --
>  hw/ppc/spapr_drc.c | 363 
> +++--
>  hw/ppc/spapr_events.c  |  10 --
>  include/hw/ppc/spapr_drc.h |  10 +-
>  4 files changed, 188 insertions(+), 210 deletions(-)
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v3 16/18] target/s390x: Implement TRTR

2017-06-19 Thread Richard Henderson
Drop TRT from the set of insns handled internally by EXECUTE.
It's more important to adjust the existing helper to handle
both TRT and TRTR.

Signed-off-by: Richard Henderson 
---
 target/s390x/helper.h  |  1 +
 target/s390x/insn-data.def |  2 ++
 target/s390x/mem_helper.c  | 20 +---
 target/s390x/translate.c   |  9 +
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 58d7f5b..61533b9 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -97,6 +97,7 @@ DEF_HELPER_FLAGS_3(tp, TCG_CALL_NO_WG, i32, env, i64, i32)
 DEF_HELPER_FLAGS_4(tr, TCG_CALL_NO_WG, void, env, i32, i64, i64)
 DEF_HELPER_4(tre, i64, env, i64, i64, i64)
 DEF_HELPER_4(trt, i32, env, i32, i64, i64)
+DEF_HELPER_4(trtr, i32, env, i32, i64, i64)
 DEF_HELPER_5(trXX, i32, env, i32, i32, i32, i32)
 DEF_HELPER_4(cksm, i64, env, i64, i64, i64)
 DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_NO_RWG_SE, i32, env, i32, i64, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 1bebcf2..7d558df 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -915,6 +915,8 @@
 C(0xdc00, TR,  SS_a,  Z,   la1, a2, 0, 0, tr, 0)
 /* TRANSLATE AND TEST */
 C(0xdd00, TRT, SS_a,  Z,   la1, a2, 0, 0, trt, 0)
+/* TRANSLATE AND TEST REVERSE */
+C(0xd000, TRTR,SS_a,  ETF3, la1, a2, 0, 0, trtr, 0)
 /* TRANSLATE EXTENDED */
 C(0xb2a5, TRE, RRE,   Z,   0, r2, r1_P, 0, tre, 0)
 
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index ce288d9..80926fa 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -1282,17 +1282,18 @@ uint64_t HELPER(tre)(CPUS390XState *env, uint64_t array,
 return array + i;
 }
 
-static uint32_t do_helper_trt(CPUS390XState *env, uint32_t len, uint64_t array,
-  uint64_t trans, uintptr_t ra)
+static inline uint32_t do_helper_trt(CPUS390XState *env, int len,
+ uint64_t array, uint64_t trans,
+ int inc, uintptr_t ra)
 {
-uint32_t i;
+int i;
 
 for (i = 0; i <= len; i++) {
-uint8_t byte = cpu_ldub_data_ra(env, array + i, ra);
+uint8_t byte = cpu_ldub_data_ra(env, array + i * inc, ra);
 uint8_t sbyte = cpu_ldub_data_ra(env, trans + byte, ra);
 
 if (sbyte != 0) {
-set_address(env, 1, array + i);
+set_address(env, 1, array + i * inc);
 env->regs[2] = deposit64(env->regs[2], 0, 8, sbyte);
 return (i == len) ? 2 : 1;
 }
@@ -1304,7 +1305,13 @@ static uint32_t do_helper_trt(CPUS390XState *env, 
uint32_t len, uint64_t array,
 uint32_t HELPER(trt)(CPUS390XState *env, uint32_t len, uint64_t array,
  uint64_t trans)
 {
-return do_helper_trt(env, len, array, trans, GETPC());
+return do_helper_trt(env, len, array, trans, 1, GETPC());
+}
+
+uint32_t HELPER(trtr)(CPUS390XState *env, uint32_t len, uint64_t array,
+  uint64_t trans)
+{
+return do_helper_trt(env, len, array, trans, -1, GETPC());
 }
 
 /* Translate one/two to one/two */
@@ -2068,7 +2075,6 @@ void HELPER(ex)(CPUS390XState *env, uint32_t ilen, 
uint64_t r1, uint64_t addr)
 [0x6] = do_helper_oc,
 [0x7] = do_helper_xc,
 [0xc] = do_helper_tr,
-[0xd] = do_helper_trt,
 };
 dx_helper helper = dx[opc & 0xf];
 
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index e594b91..9893551 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -4406,6 +4406,15 @@ static ExitStatus op_trt(DisasContext *s, DisasOps *o)
 return NO_EXIT;
 }
 
+static ExitStatus op_trtr(DisasContext *s, DisasOps *o)
+{
+TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
+gen_helper_trtr(cc_op, cpu_env, l, o->addr1, o->in2);
+tcg_temp_free_i32(l);
+set_cc_static(s);
+return NO_EXIT;
+}
+
 static ExitStatus op_trXX(DisasContext *s, DisasOps *o)
 {
 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
-- 
2.9.4




[Qemu-devel] [PATCH v3 14/18] target/s390x: Tidy SRST

2017-06-19 Thread Richard Henderson
Since we require all registers saved on input, read R0 from ENV instead
of passing it manually.  Recognize the specification exception when R0
contains incorrect data.

Signed-off-by: Richard Henderson 
---
 target/s390x/helper.h |  2 +-
 target/s390x/mem_helper.c | 11 ---
 target/s390x/translate.c  |  2 +-
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index c014820..cd51b89 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -12,7 +12,7 @@ DEF_HELPER_FLAGS_3(divs32, TCG_CALL_NO_WG, s64, env, s64, s64)
 DEF_HELPER_FLAGS_3(divu32, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(divs64, TCG_CALL_NO_WG, s64, env, s64, s64)
 DEF_HELPER_FLAGS_4(divu64, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
-DEF_HELPER_4(srst, i64, env, i64, i64, i64)
+DEF_HELPER_3(srst, i64, env, i64, i64)
 DEF_HELPER_4(clst, i64, env, i64, i64, i64)
 DEF_HELPER_FLAGS_4(mvn, TCG_CALL_NO_WG, void, env, i32, i64, i64)
 DEF_HELPER_FLAGS_4(mvo, TCG_CALL_NO_WG, void, env, i32, i64, i64)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index df082f5..990858e 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -538,12 +538,17 @@ static inline void set_length(CPUS390XState *env, int 
reg, uint64_t length)
 }
 
 /* search string (c is byte to search, r2 is string, r1 end of string) */
-uint64_t HELPER(srst)(CPUS390XState *env, uint64_t r0, uint64_t end,
-  uint64_t str)
+uint64_t HELPER(srst)(CPUS390XState *env, uint64_t end, uint64_t str)
 {
 uintptr_t ra = GETPC();
 uint32_t len;
-uint8_t v, c = r0;
+uint8_t v, c = env->regs[0];
+
+/* Bits 32-55 must contain all 0.  */
+if (env->regs[0] & 0xff00u) {
+cpu_restore_state(ENV_GET_CPU(env), ra);
+program_interrupt(env, PGM_SPECIFICATION, 6);
+}
 
 str = wrap_address(env, str);
 end = wrap_address(env, end);
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index f8989ec..4a860f1 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -4256,7 +4256,7 @@ static ExitStatus op_stpq(DisasContext *s, DisasOps *o)
 
 static ExitStatus op_srst(DisasContext *s, DisasOps *o)
 {
-gen_helper_srst(o->in1, cpu_env, regs[0], o->in1, o->in2);
+gen_helper_srst(o->in1, cpu_env, o->in1, o->in2);
 set_cc_static(s);
 return_low128(o->in2);
 return NO_EXIT;
-- 
2.9.4




[Qemu-devel] [PATCH v3 12/18] target/s390x: Finish implementing ETF2-ENH

2017-06-19 Thread Richard Henderson
Missed the proper alignment in TRTO/TRTT, and ignoring the M3
field for all TRXX insns without ETF2-ENH.

Signed-off-by: Richard Henderson 
---
 target/s390x/mem_helper.c | 11 ++-
 target/s390x/translate.c  |  5 +++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 4a7d770..4376c72 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -1265,13 +1265,22 @@ uint32_t HELPER(trXX)(CPUS390XState *env, uint32_t r1, 
uint32_t r2,
 uintptr_t ra = GETPC();
 int dsize = (sizes & 1) ? 1 : 2;
 int ssize = (sizes & 2) ? 1 : 2;
-uint64_t tbl = get_address(env, 1) & ~7;
+uint64_t tbl = get_address(env, 1);
 uint64_t dst = get_address(env, r1);
 uint64_t len = get_length(env, r1 + 1);
 uint64_t src = get_address(env, r2);
 uint32_t cc = 3;
 int i;
 
+/* The lower address bits of TBL are ignored.  For TROO, TROT, it's
+   the low 3 bits (double-word aligned).  For TRTO, TRTT, it's either
+   the low 12 bits (4K, without ETF2-ENH) or 3 bits (with ETF2-ENH).  */
+if (ssize == 2 && !s390_has_feat(S390_FEAT_ETF2_ENH)) {
+tbl &= -4096;
+} else {
+tbl &= -8;
+}
+
 check_alignment(env, len, ssize, ra);
 
 /* Lest we fail to service interrupts in a timely manner, */
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 3ffb304..630eacb 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -4363,8 +4363,9 @@ static ExitStatus op_trXX(DisasContext *s, DisasOps *o)
 TCGv_i32 tst = tcg_temp_new_i32();
 int m3 = get_field(s->fields, m3);
 
-/* XXX: the C bit in M3 should be considered as 0 when the
-   ETF2-enhancement facility is not installed.  */
+if (!s390_has_feat(S390_FEAT_ETF2_ENH)) {
+m3 = 0;
+}
 if (m3 & 1) {
 tcg_gen_movi_i32(tst, -1);
 } else {
-- 
2.9.4




[Qemu-devel] [PATCH v3 13/18] target/s390x: Implement CONVERT UNICODE insns

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/helper.h  |   6 +
 target/s390x/insn-data.def |  13 ++
 target/s390x/mem_helper.c  | 309 +
 target/s390x/translate.c   |  44 +++
 4 files changed, 372 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 456aaa9..c014820 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -107,6 +107,12 @@ DEF_HELPER_2(stfle, i32, env, i64)
 DEF_HELPER_FLAGS_2(lpq, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_4(stpq, TCG_CALL_NO_WG, void, env, i64, i64, i64)
 DEF_HELPER_4(mvcos, i32, env, i64, i64, i64)
+DEF_HELPER_4(cu12, i32, env, i32, i32, i32)
+DEF_HELPER_4(cu14, i32, env, i32, i32, i32)
+DEF_HELPER_4(cu21, i32, env, i32, i32, i32)
+DEF_HELPER_4(cu24, i32, env, i32, i32, i32)
+DEF_HELPER_4(cu41, i32, env, i32, i32, i32)
+DEF_HELPER_4(cu42, i32, env, i32, i32, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 9c8f184..634ef98 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -313,6 +313,19 @@
 C(0xb3a1, CDLGBR,  RRF_e, FPE, 0, r2_o, f1, 0, cdlgb, 0)
 C(0xb3a2, CXLGBR,  RRF_e, FPE, 0, r2_o, x1, 0, cxlgb, 0)
 
+/* CONVERT UTF-8 TO UTF-16 */
+D(0xb2a7, CU12,RRF_c, Z,   0, 0, 0, 0, cuXX, 0, 12)
+/* CONVERT UTF-8 TO UTF-32 */
+D(0xb9b0, CU14,RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 14)
+/* CONVERT UTF-16 to UTF-8 */
+D(0xb2a6, CU21,RRF_c, Z,   0, 0, 0, 0, cuXX, 0, 21)
+/* CONVERT UTF-16 to UTF-32 */
+D(0xb9b1, CU24,RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 24)
+/* CONVERT UTF-32 to UTF-8 */
+D(0xb9b3, CU41,RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 41)
+/* CONVERT UTF-32 to UTF-16 */
+D(0xb9b2, CU42,RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 42)
+
 /* DIVIDE */
 C(0x1d00, DR,  RR_a,  Z,   r1_D32, r2_32s, new_P, r1_P32, divs32, 0)
 C(0x5d00, D,   RX_a,  Z,   r1_D32, m2_32s, new_P, r1_P32, divs32, 0)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 4376c72..df082f5 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -2140,3 +2140,312 @@ uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t 
dest, uint64_t src,
 
 return cc;
 }
+
+/* Decode a Unicode character.  A return value < 0 indicates success, storing
+   the UTF-32 result into OCHAR and the input length into OLEN.  A return
+   value >= 0 indicates failure, and the CC value to be returned.  */
+typedef int (*decode_unicode_fn)(CPUS390XState *env, uint64_t addr,
+ uint64_t ilen, bool enh_check, uintptr_t ra,
+ uint32_t *ochar, uint32_t *olen);
+
+/* Encode a Unicode character.  A return value < 0 indicates success, storing
+   the bytes into ADDR and the output length into OLEN.  A return value >= 0
+   indicates failure, and the CC value to be returned.  */
+typedef int (*encode_unicode_fn)(CPUS390XState *env, uint64_t addr,
+ uint64_t ilen, uintptr_t ra, uint32_t c,
+ uint32_t *olen);
+
+static int decode_utf8(CPUS390XState *env, uint64_t addr, uint64_t ilen,
+   bool enh_check, uintptr_t ra,
+   uint32_t *ochar, uint32_t *olen)
+{
+uint8_t s0, s1, s2, s3;
+uint32_t c, l;
+
+if (ilen < 1) {
+return 0;
+}
+s0 = cpu_ldub_data_ra(env, addr, ra);
+if (s0 <= 0x7f) {
+/* one byte character */
+l = 1;
+c = s0;
+} else if (s0 <= (enh_check ? 0xc1 : 0xbf)) {
+/* invalid character */
+return 2;
+} else if (s0 <= 0xdf) {
+/* two byte character */
+l = 2;
+if (ilen < 2) {
+return 0;
+}
+s1 = cpu_ldub_data_ra(env, addr + 1, ra);
+c = s0 & 0x1f;
+c = (c << 6) | (s1 & 0x3f);
+if (enh_check && (s1 & 0xc0) != 0x80) {
+return 2;
+}
+} else if (s0 <= 0xef) {
+/* three byte character */
+l = 3;
+if (ilen < 3) {
+return 0;
+}
+s1 = cpu_ldub_data_ra(env, addr + 1, ra);
+s2 = cpu_ldub_data_ra(env, addr + 2, ra);
+c = s0 & 0x0f;
+c = (c << 6) | (s1 & 0x3f);
+c = (c << 6) | (s2 & 0x3f);
+/* Fold the byte-by-byte range descriptions in the PoO into
+   tests against the complete value.  It disallows encodings
+   that could be smaller, and the UTF-16 surrogates.  */
+if (enh_check
+&& ((s1 & 0xc0) != 0x80
+|| (s2 & 0xc0) != 0x80
+|| c < 0x1000
+|| (c >= 0xd800 && c <= 0xdfff))) {
+return 2;
+}
+} else if (s0 <= (enh_check ? 0xf4 : 0xf7)) {
+/* four byte character */
+l = 4;
+if (ilen < 4) {
+return 0;
+}
+s1 = cpu_ldub_data_ra(env, 

[Qemu-devel] [PATCH v3 17/18] target/s390x: Mark ETF3 and ETF3_ENH facilities as available

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/cpu_models.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index be7757c..16129f6 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -678,11 +678,13 @@ static void add_qemu_cpu_model_features(S390FeatBitmap 
fbm)
 S390_FEAT_STFLE,
 S390_FEAT_EXTENDED_IMMEDIATE,
 S390_FEAT_EXTENDED_TRANSLATION_2,
+S390_FEAT_EXTENDED_TRANSLATION_3,
 S390_FEAT_LONG_DISPLACEMENT,
 S390_FEAT_LONG_DISPLACEMENT_FAST,
 S390_FEAT_ETF2_ENH,
 S390_FEAT_STORE_CLOCK_FAST,
 S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
+S390_FEAT_ETF3_ENH,
 S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
 S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
 S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
-- 
2.9.4




[Qemu-devel] [PATCH v3 18/18] target/s390x: Clean up TB flag bits

2017-06-19 Thread Richard Henderson
Most of the PSW bits that were being copied into TB->flags
are not relevant to translation.  Removing those that are
unnecessary reduces the amount of translation required.

Signed-off-by: Richard Henderson 
---
 target/s390x/cpu.h   | 24 +---
 target/s390x/translate.c | 16 
 2 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 5b94ace..9faca04 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -346,19 +346,14 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
 
 /* tb flags */
 
-#define FLAG_MASK_PER   (PSW_MASK_PER>> 32)
-#define FLAG_MASK_DAT   (PSW_MASK_DAT>> 32)
-#define FLAG_MASK_IO(PSW_MASK_IO >> 32)
-#define FLAG_MASK_EXT   (PSW_MASK_EXT>> 32)
-#define FLAG_MASK_KEY   (PSW_MASK_KEY>> 32)
-#define FLAG_MASK_MCHECK(PSW_MASK_MCHECK >> 32)
-#define FLAG_MASK_WAIT  (PSW_MASK_WAIT   >> 32)
-#define FLAG_MASK_PSTATE(PSW_MASK_PSTATE >> 32)
-#define FLAG_MASK_ASC   (PSW_MASK_ASC>> 32)
-#define FLAG_MASK_CC(PSW_MASK_CC >> 32)
-#define FLAG_MASK_PM(PSW_MASK_PM >> 32)
-#define FLAG_MASK_64(PSW_MASK_64 >> 32)
-#define FLAG_MASK_320x1000
+#define FLAG_MASK_PSW_SHIFT 31
+#define FLAG_MASK_PER   (PSW_MASK_PER>> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_PSTATE(PSW_MASK_PSTATE >> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_ASC   (PSW_MASK_ASC>> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_64(PSW_MASK_64 >> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_32(PSW_MASK_32 >> FLAG_MASK_PSW_SHIFT)
+#define FLAG_MASK_PSW  (FLAG_MASK_PER | FLAG_MASK_PSTATE \
+| FLAG_MASK_ASC | FLAG_MASK_64 | FLAG_MASK_32)
 
 /* Control register 0 bits */
 #define CR0_LOWPROT 0x1000ULL
@@ -416,8 +411,7 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, 
target_ulong *pc,
 {
 *pc = env->psw.addr;
 *cs_base = env->ex_value;
-*flags = ((env->psw.mask >> 32) & ~FLAG_MASK_CC) |
- ((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
+*flags = (env->psw.mask >> FLAG_MASK_PSW_SHIFT) & FLAG_MASK_PSW;
 }
 
 #define MAX_ILEN 6
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 9893551..bee163f 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -323,11 +323,11 @@ static inline uint64_t ld_code4(CPUS390XState *env, 
uint64_t pc)
 static int get_mem_index(DisasContext *s)
 {
 switch (s->tb->flags & FLAG_MASK_ASC) {
-case PSW_ASC_PRIMARY >> 32:
+case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 return 0;
-case PSW_ASC_SECONDARY >> 32:
+case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
 return 1;
-case PSW_ASC_HOME >> 32:
+case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
 return 2;
 default:
 tcg_abort();
@@ -387,7 +387,7 @@ static inline void gen_trap(DisasContext *s)
 #ifndef CONFIG_USER_ONLY
 static void check_privileged(DisasContext *s)
 {
-if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) {
+if (s->tb->flags & FLAG_MASK_PSTATE) {
 gen_program_exception(s, PGM_PRIVILEGED);
 }
 }
@@ -2985,20 +2985,20 @@ static ExitStatus op_mov2e(DisasContext *s, DisasOps *o)
 o->g_in2 = false;
 
 switch (s->tb->flags & FLAG_MASK_ASC) {
-case PSW_ASC_PRIMARY >> 32:
+case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 tcg_gen_movi_i64(ar1, 0);
 break;
-case PSW_ASC_ACCREG >> 32:
+case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT:
 tcg_gen_movi_i64(ar1, 1);
 break;
-case PSW_ASC_SECONDARY >> 32:
+case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
 if (b2) {
 tcg_gen_ld32u_i64(ar1, cpu_env, offsetof(CPUS390XState, 
aregs[b2]));
 } else {
 tcg_gen_movi_i64(ar1, 0);
 }
 break;
-case PSW_ASC_HOME >> 32:
+case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
 tcg_gen_movi_i64(ar1, 2);
 break;
 }
-- 
2.9.4




[Qemu-devel] [PATCH v3 04/18] target/s390x: Implement CSST

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/cpu_models.c  |   2 +
 target/s390x/helper.h  |   1 +
 target/s390x/insn-data.def |   2 +
 target/s390x/mem_helper.c  | 189 +
 target/s390x/translate.c   |  13 +++-
 5 files changed, 206 insertions(+), 1 deletion(-)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index c3a4ce6..68fa481 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -683,6 +683,8 @@ static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
 S390_FEAT_ETF2_ENH,
 S390_FEAT_STORE_CLOCK_FAST,
 S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
+S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
+S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
 S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
 S390_FEAT_EXECUTE_EXT,
 S390_FEAT_STFLE_45,
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index b268367..456aaa9 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -33,6 +33,7 @@ DEF_HELPER_3(celgb, i64, env, i64, i32)
 DEF_HELPER_3(cdlgb, i64, env, i64, i32)
 DEF_HELPER_3(cxlgb, i64, env, i64, i32)
 DEF_HELPER_4(cdsg, void, env, i64, i32, i32)
+DEF_HELPER_4(csst, i32, env, i32, i64, i64)
 DEF_HELPER_FLAGS_3(aeb, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(adb, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_5(axb, TCG_CALL_NO_WG, i64, env, i64, i64, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index aa4c5b2..ef02a8e 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -256,6 +256,8 @@
 D(0xbb00, CDS, RS_a,  Z,   r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEQ)
 D(0xeb31, CDSY,RSY_a, LD,  r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEQ)
 C(0xeb3e, CDSG,RSY_a, Z,   0, 0, 0, 0, cdsg, 0)
+/* COMPARE AND SWAP AND STORE */
+C(0xc802, CSST,SSF,   CASS, la1, a2, 0, 0, csst, 0)
 
 /* COMPARE AND TRAP */
 D(0xb972, CRT, RRF_c, GIE, r1_32s, r2_32s, 0, 0, ct, 0, 0)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 6125725..4a7d770 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -1344,6 +1344,195 @@ void HELPER(cdsg)(CPUS390XState *env, uint64_t addr,
 env->regs[r1 + 1] = int128_getlo(oldv);
 }
 
+uint32_t HELPER(csst)(CPUS390XState *env, uint32_t r3, uint64_t a1, uint64_t 
a2)
+{
+#if !defined(CONFIG_USER_ONLY) || defined(CONFIG_ATOMIC128)
+uint32_t mem_idx = cpu_mmu_index(env, false);
+#endif
+uintptr_t ra = GETPC();
+uint32_t fc = extract32(env->regs[0], 0, 8);
+uint32_t sc = extract32(env->regs[0], 8, 8);
+uint64_t pl = get_address(env, 1) & -16;
+uint64_t svh, svl;
+uint32_t cc;
+
+/* Sanity check the function code and storage characteristic.  */
+if (fc > 1 || sc > 3) {
+if (!s390_has_feat(S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2)) {
+goto spec_exception;
+}
+if (fc > 2 || sc > 4 || (fc == 2 && (r3 & 1))) {
+goto spec_exception;
+}
+}
+
+/* Sanity check the alignments.  */
+if (extract32(a1, 0, 4 << fc) || extract32(a2, 0, 1 << sc)) {
+goto spec_exception;
+}
+
+/* Sanity check writability of the store address.  */
+#ifndef CONFIG_USER_ONLY
+probe_write(env, a2, mem_idx, ra);
+#endif
+
+/* Note that the compare-and-swap is atomic, and the store is atomic, but
+   the complete operation is not.  Therefore we do not need to assert 
serial
+   context in order to implement this.  That said, restart early if we 
can't
+   support either operation that is supposed to be atomic.  */
+if (parallel_cpus) {
+int mask = 0;
+#if !defined(CONFIG_ATOMIC64)
+mask = -8;
+#elif !defined(CONFIG_ATOMIC128)
+mask = -16;
+#endif
+if (((4 << fc) | (1 << sc)) & mask) {
+cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
+}
+}
+
+/* All loads happen before all stores.  For simplicity, load the entire
+   store value area from the parameter list.  */
+svh = cpu_ldq_data_ra(env, pl + 16, ra);
+svl = cpu_ldq_data_ra(env, pl + 24, ra);
+
+switch (fc) {
+case 0:
+{
+uint32_t nv = cpu_ldl_data_ra(env, pl, ra);
+uint32_t cv = env->regs[r3];
+uint32_t ov;
+
+if (parallel_cpus) {
+#ifdef CONFIG_USER_ONLY
+uint32_t *haddr = g2h(a1);
+ov = atomic_cmpxchg__nocheck(haddr, cv, nv);
+#else
+TCGMemOpIdx oi = make_memop_idx(MO_TEUL | MO_ALIGN, mem_idx);
+ov = helper_atomic_cmpxchgl_be_mmu(env, a1, cv, nv, oi, ra);
+#endif
+} else {
+ov = cpu_ldl_data_ra(env, a1, ra);
+cpu_stl_data_ra(env, a1, (ov == cv ? nv : ov), ra);
+}
+cc = (ov != cv);
+env->regs[r3] = deposit64(env->regs[r3], 32, 32, ov);
+}
+break;
+
+case 

[Qemu-devel] [PATCH v3 11/18] target/s390x: Mark STFLE_49 facility as available

2017-06-19 Thread Richard Henderson
This facility bit includes execution-hint, load-and-trap,
miscellaneous-instruction-extensions and processor-assist.

Signed-off-by: Richard Henderson 
---
 target/s390x/cpu_models.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 1db814b..be7757c 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -689,6 +689,7 @@ static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
 S390_FEAT_EXECUTE_EXT,
 S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
 S390_FEAT_STFLE_45,
+S390_FEAT_STFLE_49,
 S390_FEAT_STFLE_53,
 };
 int i;
-- 
2.9.4




[Qemu-devel] [PATCH v3 15/18] target/s390x: Implement SRSTU

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/helper.h  |  1 +
 target/s390x/insn-data.def |  2 ++
 target/s390x/mem_helper.c  | 44 
 target/s390x/translate.c   |  8 
 4 files changed, 55 insertions(+)

diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index cd51b89..58d7f5b 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -13,6 +13,7 @@ DEF_HELPER_FLAGS_3(divu32, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(divs64, TCG_CALL_NO_WG, s64, env, s64, s64)
 DEF_HELPER_FLAGS_4(divu64, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
 DEF_HELPER_3(srst, i64, env, i64, i64)
+DEF_HELPER_3(srstu, i64, env, i64, i64)
 DEF_HELPER_4(clst, i64, env, i64, i64, i64)
 DEF_HELPER_FLAGS_4(mvn, TCG_CALL_NO_WG, void, env, i32, i64, i64)
 DEF_HELPER_FLAGS_4(mvo, TCG_CALL_NO_WG, void, env, i32, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index 634ef98..1bebcf2 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -736,6 +736,8 @@
 
 /* SEARCH STRING */
 C(0xb25e, SRST,RRE,   Z,   r1_o, r2_o, 0, 0, srst, 0)
+/* SEARCH STRING UNICODE */
+C(0xb9be, SRSTU,   RRE,   ETF3, r1_o, r2_o, 0, 0, srstu, 0)
 
 /* SET ACCESS */
 C(0xb24e, SAR, RRE,   Z,   0, r2_o, 0, 0, sar, 0)
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 990858e..ce288d9 100644
--- a/target/s390x/mem_helper.c
+++ b/target/s390x/mem_helper.c
@@ -578,6 +578,50 @@ uint64_t HELPER(srst)(CPUS390XState *env, uint64_t end, 
uint64_t str)
 return end;
 }
 
+uint64_t HELPER(srstu)(CPUS390XState *env, uint64_t end, uint64_t str)
+{
+uintptr_t ra = GETPC();
+uint32_t len;
+uint16_t v, c = env->regs[0];
+uint64_t adj_end;
+
+/* Bits 32-47 of R0 must be zero.  */
+if (env->regs[0] & 0xu) {
+cpu_restore_state(ENV_GET_CPU(env), ra);
+program_interrupt(env, PGM_SPECIFICATION, 6);
+}
+
+str = wrap_address(env, str);
+end = wrap_address(env, end);
+
+/* If the LSB of the two addresses differ, use one extra byte.  */
+adj_end = end + ((str ^ end) & 1);
+
+/* Assume for now that R2 is unmodified.  */
+env->retxl = str;
+
+/* Lest we fail to service interrupts in a timely manner, limit the
+   amount of work we're willing to do.  For now, let's cap at 8k.  */
+for (len = 0; len < 0x2000; len += 2) {
+if (str + len == adj_end) {
+/* End of input found.  */
+env->cc_op = 2;
+return end;
+}
+v = cpu_lduw_data_ra(env, str + len, ra);
+if (v == c) {
+/* Character found.  Set R1 to the location; R2 is unmodified.  */
+env->cc_op = 1;
+return str + len;
+}
+}
+
+/* CPU-determined bytes processed.  Advance R2 to next byte to process.  */
+env->retxl = str + len;
+env->cc_op = 3;
+return end;
+}
+
 /* unsigned string compare (c is string terminator) */
 uint64_t HELPER(clst)(CPUS390XState *env, uint64_t c, uint64_t s1, uint64_t s2)
 {
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 4a860f1..e594b91 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -4262,6 +4262,14 @@ static ExitStatus op_srst(DisasContext *s, DisasOps *o)
 return NO_EXIT;
 }
 
+static ExitStatus op_srstu(DisasContext *s, DisasOps *o)
+{
+gen_helper_srstu(o->in1, cpu_env, o->in1, o->in2);
+set_cc_static(s);
+return_low128(o->in2);
+return NO_EXIT;
+}
+
 static ExitStatus op_sub(DisasContext *s, DisasOps *o)
 {
 tcg_gen_sub_i64(o->out, o->in1, o->in2);
-- 
2.9.4




[Qemu-devel] [PATCH v3 10/18] target/s390x: Implement processor-assist insn

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/insn-data.def | 3 +++
 target/s390x/translate.c   | 1 +
 2 files changed, 4 insertions(+)

diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index b64d465..9c8f184 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -700,6 +700,9 @@
 /* Implemented as nops of course.  */
 C(0xe336, PFD, RXY_b, GIE, 0, 0, 0, 0, 0, 0)
 C(0xc602, PFDRL,   RIL_c, GIE, 0, 0, 0, 0, 0, 0)
+/* PERFORM PROCESSOR ASSIST */
+/* Implemented as nop of course.  */
+C(0xb2e8, PPA, RRF_c, PPA, 0, 0, 0, 0, 0, 0)
 
 /* POPULATION COUNT */
 C(0xb9e1, POPCNT,  RRE,   PC,  0, r2_o, r1, 0, popcnt, nz64)
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index b2e58c5..3ffb304 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -5450,6 +5450,7 @@ enum DisasInsnEnum {
 #define FAC_DAT_ENH S390_FEAT_DAT_ENH
 #define FAC_E2  S390_FEAT_EXTENDED_TRANSLATION_2
 #define FAC_EH  S390_FEAT_STFLE_49 /* execution-hint */
+#define FAC_PPA S390_FEAT_STFLE_49 /* processor-assist */
 #define FAC_LZRBS390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
 
 static const DisasInsn insn_info[] = {
-- 
2.9.4




[Qemu-devel] [PATCH v3 05/18] target/s390x: Mark FPSEH facility as available

2017-06-19 Thread Richard Henderson
This facility bit includes DFP-rounding, FPR-GR-transfer,
FPS-sign-handling, and IEEE-exception-simulation.  We do
support all of these.

Signed-off-by: Richard Henderson 
---
 target/s390x/cpu_models.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 68fa481..703feca 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -687,6 +687,7 @@ static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
 S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
 S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
 S390_FEAT_EXECUTE_EXT,
+S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
 S390_FEAT_STFLE_45,
 };
 int i;
-- 
2.9.4




[Qemu-devel] [PATCH v3 03/18] target/s390x: implement mvcos instruction

2017-06-19 Thread Richard Henderson
From: David Hildenbrand 

This adds support for the MOVE WITH OPTIONAL SPECIFICATIONS (MVCOS)
instruction. Allow to enable it for the qemu cpu model using

qemu-system-s390x ... -cpu qemu,mvcos=on ...

This allows to boot linux kernel that uses it for uacccess.

We are missing (as for most other part) low address protection checks,
PSW key / storage key checks and support for AR-mode.

We fake an ADDRESSING exception when called from problem state (which
seems to rely on PSW key checks to be in place) and if AR-mode is used.
user mode will always see a PRIVILEDGED exception.

This patch is based on an original patch by Miroslav Benes (thanks!).

Signed-off-by: David Hildenbrand 
Message-Id: <20170614133819.18480-3-da...@redhat.com>
Signed-off-by: Richard Henderson 
---
 target/s390x/cpu.h |  22 +-
 target/s390x/cpu_models.c  |   1 +
 target/s390x/helper.h  |   1 +
 target/s390x/insn-data.def |   2 +
 target/s390x/mem_helper.c  | 181 +
 target/s390x/translate.c   |   9 +++
 6 files changed, 201 insertions(+), 15 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 532a4a0..5b94ace 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -304,6 +304,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
 #undef PSW_MASK_WAIT
 #undef PSW_MASK_PSTATE
 #undef PSW_MASK_ASC
+#undef PSW_SHIFT_ASC
 #undef PSW_MASK_CC
 #undef PSW_MASK_PM
 #undef PSW_MASK_64
@@ -320,6 +321,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
 #define PSW_MASK_WAIT   0x0002ULL
 #define PSW_MASK_PSTATE 0x0001ULL
 #define PSW_MASK_ASC0xC000ULL
+#define PSW_SHIFT_ASC   46
 #define PSW_MASK_CC 0x3000ULL
 #define PSW_MASK_PM 0x0F00ULL
 #define PSW_MASK_64 0x0001ULL
@@ -336,6 +338,12 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
 #define PSW_ASC_SECONDARY   0x8000ULL
 #define PSW_ASC_HOME0xC000ULL
 
+/* the address space values shifted */
+#define AS_PRIMARY  0
+#define AS_ACCREG   1
+#define AS_SECONDARY2
+#define AS_HOME 3
+
 /* tb flags */
 
 #define FLAG_MASK_PER   (PSW_MASK_PER>> 32)
@@ -354,6 +362,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
 
 /* Control register 0 bits */
 #define CR0_LOWPROT 0x1000ULL
+#define CR0_SECONDARY   0x0400ULL
 #define CR0_EDAT0x0080ULL
 
 /* MMU */
@@ -361,7 +370,18 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
 #define MMU_SECONDARY_IDX   1
 #define MMU_HOME_IDX2
 
-static inline int cpu_mmu_index (CPUS390XState *env, bool ifetch)
+static inline bool psw_key_valid(CPUS390XState *env, uint8_t psw_key)
+{
+uint16_t pkm = env->cregs[3] >> 16;
+
+if (env->psw.mask & PSW_MASK_PSTATE) {
+/* PSW key has range 0..15, it is valid if the bit is 1 in the PKM */
+return pkm & (0x80 >> psw_key);
+}
+return true;
+}
+
+static inline int cpu_mmu_index(CPUS390XState *env, bool ifetch)
 {
 switch (env->psw.mask & PSW_MASK_ASC) {
 case PSW_ASC_PRIMARY:
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 478bcc6..c3a4ce6 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -682,6 +682,7 @@ static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
 S390_FEAT_LONG_DISPLACEMENT_FAST,
 S390_FEAT_ETF2_ENH,
 S390_FEAT_STORE_CLOCK_FAST,
+S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
 S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
 S390_FEAT_EXECUTE_EXT,
 S390_FEAT_STFLE_45,
diff --git a/target/s390x/helper.h b/target/s390x/helper.h
index 69249a5..b268367 100644
--- a/target/s390x/helper.h
+++ b/target/s390x/helper.h
@@ -105,6 +105,7 @@ DEF_HELPER_FLAGS_1(stfl, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_2(stfle, i32, env, i64)
 DEF_HELPER_FLAGS_2(lpq, TCG_CALL_NO_WG, i64, env, i64)
 DEF_HELPER_FLAGS_4(stpq, TCG_CALL_NO_WG, void, env, i64, i64, i64)
+DEF_HELPER_4(mvcos, i32, env, i64, i64, i64)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(servc, i32, env, i64, i64)
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index d089707..aa4c5b2 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -590,6 +590,8 @@
 C(0xb254, MVPG,RRE,   Z,   r1_o, r2_o, 0, 0, mvpg, 0)
 /* MOVE STRING */
 C(0xb255, MVST,RRE,   Z,   r1_o, r2_o, 0, 0, mvst, 0)
+/* MOVE WITH OPTIONAL SPECIFICATION */
+C(0xc800, MVCOS,   SSF,   MVCOS, la1, a2, 0, 0, mvcos, 0)
 /* MOVE WITH OFFSET */
 /* Really format SS_b, but we pack both lengths into one argument
for the helper call, so we might as well leave one 8-bit field.  */
diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c
index 

[Qemu-devel] [PATCH v3 08/18] target/s390x: Mark STFLE_53 facility as available

2017-06-19 Thread Richard Henderson
This facility bit includes load-on-condition-2 and
load-and-zero-rightmost-byte.

Signed-off-by: Richard Henderson 
---
 target/s390x/cpu_models.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 703feca..1db814b 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -689,6 +689,7 @@ static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
 S390_FEAT_EXECUTE_EXT,
 S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
 S390_FEAT_STFLE_45,
+S390_FEAT_STFLE_53,
 };
 int i;
 
-- 
2.9.4




[Qemu-devel] [PATCH v3 06/18] target/s390x: Implement load-on-condition-2 insns

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/s390x/insn-data.def   |  9 +
 target/s390x/insn-format.def |  1 +
 target/s390x/translate.c | 18 +++---
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index ef02a8e..60d244f 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -516,6 +516,13 @@
 C(0xb9e2, LOCGR,   RRF_c, LOC, r1, r2, r1, 0, loc, 0)
 C(0xebf2, LOC, RSY_b, LOC, r1, m2_32u, new, r1_32, loc, 0)
 C(0xebe2, LOCG,RSY_b, LOC, r1, m2_64, r1, 0, loc, 0)
+/* LOAD HALFWORD IMMEDIATE ON CONDITION */
+C(0xec42, LOCHI,   RIE_g, LOC2, r1, i2, new, r1_32, loc, 0)
+C(0xec46, LOCGHI,  RIE_g, LOC2, r1, i2, r1, 0, loc, 0)
+C(0xec4e, LOCHHI,  RIE_g, LOC2, r1_sr32, i2, new, r1_32h, loc, 0)
+/* LOAD HIGH ON CONDITION */
+C(0xb9e0, LOCFHR,  RRF_c, LOC2, r1_sr32, r2, new, r1_32h, loc, 0)
+C(0xebe0, LOCFH,   RSY_b, LOC2, r1_sr32, m2_32u, new, r1_32h, loc, 0)
 /* LOAD PAIR DISJOINT */
 D(0xc804, LPD, SSF,   ILA, 0, 0, new_P, r3_P32, lpd, 0, MO_TEUL)
 D(0xc805, LPDG,SSF,   ILA, 0, 0, new_P, r3_P64, lpd, 0, MO_TEQ)
@@ -781,6 +788,8 @@
 /* STORE ON CONDITION */
 D(0xebf3, STOC,RSY_b, LOC, 0, 0, 0, 0, soc, 0, 0)
 D(0xebe3, STOCG,   RSY_b, LOC, 0, 0, 0, 0, soc, 0, 1)
+/* STORE HIGH ON CONDITION */
+D(0xebe1, STOCFH,  RSY_b, LOC2, 0, 0, 0, 0, soc, 0, 2)
 /* STORE REVERSED */
 C(0xe33f, STRVH,   RXY_a, Z,   la2, r1_16u, new, m1_16, rev16, 0)
 C(0xe33e, STRV,RXY_a, Z,   la2, r1_32u, new, m1_32, rev32, 0)
diff --git a/target/s390x/insn-format.def b/target/s390x/insn-format.def
index 0e898b9..a412d90 100644
--- a/target/s390x/insn-format.def
+++ b/target/s390x/insn-format.def
@@ -11,6 +11,7 @@ F4(RIE_c, R(1, 8), I(2,32, 8),  M(3,12),   I(4,16,16))
 F3(RIE_d, R(1, 8), I(2,16,16),  R(3,12))
 F3(RIE_e, R(1, 8), I(2,16,16),  R(3,12))
 F5(RIE_f, R(1, 8), R(2,12), I(3,16,8), I(4,24,8),  I(5,32,8))
+F3(RIE_g, R(1, 8), I(2,16,16),  M(3,12))
 F2(RIL_a, R(1, 8), I(2,16,32))
 F2(RIL_b, R(1, 8), I(2,16,32))
 F2(RIL_c, M(1, 8), I(2,16,32))
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 95f2f9d..a3234f7 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -3651,7 +3651,7 @@ static ExitStatus op_sigp(DisasContext *s, DisasOps *o)
 static ExitStatus op_soc(DisasContext *s, DisasOps *o)
 {
 DisasCompare c;
-TCGv_i64 a;
+TCGv_i64 a, h;
 TCGLabel *lab;
 int r1;
 
@@ -3671,10 +3671,21 @@ static ExitStatus op_soc(DisasContext *s, DisasOps *o)
 
 r1 = get_field(s->fields, r1);
 a = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2));
-if (s->insn->data) {
+switch (s->insn->data) {
+case 1: /* STOCG */
 tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s));
-} else {
+break;
+case 0: /* STOC */
 tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s));
+break;
+case 2: /* STOCFH */
+h = tcg_temp_new_i64();
+tcg_gen_shri_i64(h, regs[r1], 32);
+tcg_gen_qemu_st32(h, a, get_mem_index(s));
+tcg_temp_free_i64(h);
+break;
+default:
+g_assert_not_reached();
 }
 tcg_temp_free_i64(a);
 
@@ -5422,6 +5433,7 @@ enum DisasInsnEnum {
 #define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */
 #define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */
 #define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */
+#define FAC_LOC2S390_FEAT_STFLE_53 /* load/store on condition 2 */
 #define FAC_LD  S390_FEAT_LONG_DISPLACEMENT
 #define FAC_PC  S390_FEAT_STFLE_45 /* population count */
 #define FAC_SCF S390_FEAT_STORE_CLOCK_FAST
-- 
2.9.4




[Qemu-devel] [PATCH v3 01/18] target/s390x: Map existing FAC_* names to S390_FEAT_* names

2017-06-19 Thread Richard Henderson
The FAC_ names were placeholders prior to the introduction
of the current facility modeling.

Signed-off-by: Richard Henderson 
---
 target/s390x/translate.c | 59 
 1 file changed, 29 insertions(+), 30 deletions(-)

diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 8c055b7..af18ffb 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -1178,39 +1178,10 @@ typedef enum {
 EXIT_NORETURN,
 } ExitStatus;
 
-typedef enum DisasFacility {
-FAC_Z,  /* zarch (default) */
-FAC_CASS,   /* compare and swap and store */
-FAC_CASS2,  /* compare and swap and store 2*/
-FAC_DFP,/* decimal floating point */
-FAC_DFPR,   /* decimal floating point rounding */
-FAC_DO, /* distinct operands */
-FAC_EE, /* execute extensions */
-FAC_EI, /* extended immediate */
-FAC_FPE,/* floating point extension */
-FAC_FPSSH,  /* floating point support sign handling */
-FAC_FPRGR,  /* FPR-GR transfer */
-FAC_GIE,/* general instructions extension */
-FAC_HFP_MA, /* HFP multiply-and-add/subtract */
-FAC_HW, /* high-word */
-FAC_I_SIM,  /* IEEE exception sumilation */
-FAC_MIE,/* miscellaneous-instruction-extensions */
-FAC_LAT,/* load-and-trap */
-FAC_LOC,/* load/store on condition */
-FAC_LD, /* long displacement */
-FAC_PC, /* population count */
-FAC_SCF,/* store clock fast */
-FAC_SFLE,   /* store facility list extended */
-FAC_ILA,/* interlocked access facility 1 */
-FAC_LPP,/* load-program-parameter */
-FAC_DAT_ENH,/* DAT-enhancement */
-FAC_E2, /* extended-translation facility 2 */
-} DisasFacility;
-
 struct DisasInsn {
 unsigned opc:16;
 DisasFormat fmt:8;
-DisasFacility fac:8;
+unsigned fac:8;
 unsigned spec:8;
 
 const char *name;
@@ -5413,6 +5384,34 @@ enum DisasInsnEnum {
 #define SPEC_prep_0 0
 #define SPEC_wout_0 0
 
+/* Give smaller names to the various facilities.  */
+#define FAC_Z   S390_FEAT_ZARCH
+#define FAC_CASSS390_FEAT_COMPARE_AND_SWAP_AND_STORE
+#define FAC_CASS2   S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2
+#define FAC_DFP S390_FEAT_DFP
+#define FAC_DFPRS390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* DFP-rounding 
*/
+#define FAC_DO  S390_FEAT_STFLE_45 /* distinct-operands */
+#define FAC_EE  S390_FEAT_EXECUTE_EXT
+#define FAC_EI  S390_FEAT_EXTENDED_IMMEDIATE
+#define FAC_FPE S390_FEAT_FLOATING_POINT_EXT
+#define FAC_FPSSH   S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* 
FPS-sign-handling */
+#define FAC_FPRGR   S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* 
FPR-GR-transfer */
+#define FAC_GIE S390_FEAT_GENERAL_INSTRUCTIONS_EXT
+#define FAC_HFP_MA  S390_FEAT_HFP_MADDSUB
+#define FAC_HW  S390_FEAT_STFLE_45 /* high-word */
+#define FAC_I_SIM   S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* 
IEEE-exception-simulation */
+#define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */
+#define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */
+#define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */
+#define FAC_LD  S390_FEAT_LONG_DISPLACEMENT
+#define FAC_PC  S390_FEAT_STFLE_45 /* population count */
+#define FAC_SCF S390_FEAT_STORE_CLOCK_FAST
+#define FAC_SFLES390_FEAT_STFLE
+#define FAC_ILA S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */
+#define FAC_LPP S390_FEAT_SET_PROGRAM_PARAMETERS /* 
load-program-parameter */
+#define FAC_DAT_ENH S390_FEAT_DAT_ENH
+#define FAC_E2  S390_FEAT_EXTENDED_TRANSLATION_2
+
 static const DisasInsn insn_info[] = {
 #include "insn-data.def"
 };
-- 
2.9.4




[Qemu-devel] [PATCH v3 00/18] target/s390x improvements

2017-06-19 Thread Richard Henderson
Changes since v2:
  * Dropped the enforcement of PGM_OPERATION for insns for
which the feature bit is set.  There's no agreement on
exactly how to do this yet.
  * Add implementations of insns for 6 more facilities.

I think we can get to z990 fairly quickly after this.
Ignoring HFP, the ones I see missing are DAT-ENH, MSA.


r~


David Hildenbrand (2):
  target/s390x: change PSW_SHIFT_KEY
  target/s390x: implement mvcos instruction

Richard Henderson (16):
  target/s390x: Map existing FAC_* names to S390_FEAT_* names
  target/s390x: Implement CSST
  target/s390x: Mark FPSEH facility as available
  target/s390x: Implement load-on-condition-2 insns
  target/s390x: Implement load-and-zero-rightmost-byte insns
  target/s390x: Mark STFLE_53 facility as available
  target/s390x: Implement execution-hint insns
  target/s390x: Implement processor-assist insn
  target/s390x: Mark STFLE_49 facility as available
  target/s390x: Finish implementing ETF2-ENH
  target/s390x: Implement CONVERT UNICODE insns
  target/s390x: Tidy SRST
  target/s390x: Implement SRSTU
  target/s390x: Implement TRTR
  target/s390x: Mark ETF3 and ETF3_ENH facilities as available
  target/s390x: Clean up TB flag bits

 target/s390x/cpu.h   |  48 ++-
 target/s390x/cpu_models.c|   8 +
 target/s390x/helper.h|  12 +-
 target/s390x/insn-data.def   |  46 +++
 target/s390x/insn-format.def |   1 +
 target/s390x/mem_helper.c| 765 +--
 target/s390x/translate.c | 196 ---
 7 files changed, 987 insertions(+), 89 deletions(-)

-- 
2.9.4




[Qemu-devel] [PATCH v3 02/18] target/s390x: change PSW_SHIFT_KEY

2017-06-19 Thread Richard Henderson
From: David Hildenbrand 

Such shifts are usually used to easily extract the PSW KEY from the PSW
mask, so let's avoid the confusing offset of 4.

Reviewed-by: Thomas Huth 
Signed-off-by: David Hildenbrand 
Message-Id: <20170614133819.18480-2-da...@redhat.com>
Signed-off-by: Richard Henderson 
---
 target/s390x/cpu.h   | 2 +-
 target/s390x/translate.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index a4028fb..532a4a0 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -315,7 +315,7 @@ void s390x_cpu_debug_excp_handler(CPUState *cs);
 #define PSW_MASK_IO 0x0200ULL
 #define PSW_MASK_EXT0x0100ULL
 #define PSW_MASK_KEY0x00F0ULL
-#define PSW_SHIFT_KEY   56
+#define PSW_SHIFT_KEY   52
 #define PSW_MASK_MCHECK 0x0004ULL
 #define PSW_MASK_WAIT   0x0002ULL
 #define PSW_MASK_PSTATE 0x0001ULL
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index af18ffb..204b52a 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -3751,7 +3751,7 @@ static ExitStatus op_spka(DisasContext *s, DisasOps *o)
 {
 check_privileged(s);
 tcg_gen_shri_i64(o->in2, o->in2, 4);
-tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY - 4, 4);
+tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY, 4);
 return NO_EXIT;
 }
 
-- 
2.9.4




Re: [Qemu-devel] [PATCH] target/s390x: Implement CSST

2017-06-19 Thread Richard Henderson

On 06/19/2017 01:08 AM, Thomas Huth wrote:

+/* Sanity check the function code and storage characteristic.  */
+if (fc > 1 || sc > 3) {
+if (!s390_has_feat(S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2)) {
+goto spec_exception;
+}
+if (fc > 2 || sc > 4 || (fc == 2 && (r3 & 1))) {


I think you could omit the "fc == 2" here. fc has to be bigger than 1
due to the outer if-statement, and if it is not 2, the first "fc > 1"
has already triggered. So "fc" has to be 2 here and the "fc == 2" is a
redundant check.


Not so.  We can also get here with fc == 0 && sc == 4.


r~



[Qemu-devel] [PATCH v5 1/1] 9pfs: local: Add support for custom fmode/dmode in 9ps mapped security modes

2017-06-19 Thread Tobias Schramm
In mapped security modes, files are created with very restrictive
permissions (600 for files and 700 for directories). This makes
file sharing between virtual machines and users on the host rather
complicated. Imagine eg. a group of users that need to access data
produced by processes on a virtual machine. Giving those users access
to the data will be difficult since the group access mode is always 0.

This patch makes the default mode for both files and directories
configurable. Existing setups that don't know about the new parameters
keep using the current secure behavior.

Signed-off-by: Tobias Schramm 
---
 v5: Eliminate expandable variables, check mandatory commandline options
 first
 v4: Use OPT_NUMBER for file mode arguments, fix back to front naming,
 fix resource leak and add sanity checking for fmode/dmode arguments
 v3: Use unsigned types for umask
 v2: Adjust patch to QEMU code style

 fsdev/file-op-9p.h  |  4 
 fsdev/qemu-fsdev-opts.c | 12 
 hw/9pfs/9p-local.c  | 25 +
 hw/9pfs/9p.c|  3 +++
 qemu-options.hx | 20 
 5 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index 0844a403dc..474c79d003 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -76,6 +76,8 @@ typedef struct FsDriverEntry {
 int export_flags;
 FileOperations *ops;
 FsThrottle fst;
+mode_t fmode;
+mode_t dmode;
 } FsDriverEntry;
 
 typedef struct FsContext
@@ -88,6 +90,8 @@ typedef struct FsContext
 FsThrottle *fst;
 /* fs driver specific data */
 void *private;
+mode_t fmode;
+mode_t dmode;
 } FsContext;
 
 typedef struct V9fsPath {
diff --git a/fsdev/qemu-fsdev-opts.c b/fsdev/qemu-fsdev-opts.c
index bf5713008a..7c31af 100644
--- a/fsdev/qemu-fsdev-opts.c
+++ b/fsdev/qemu-fsdev-opts.c
@@ -38,6 +38,12 @@ static QemuOptsList qemu_fsdev_opts = {
 }, {
 .name = "sock_fd",
 .type = QEMU_OPT_NUMBER,
+}, {
+.name = "fmode",
+.type = QEMU_OPT_NUMBER,
+}, {
+.name = "dmode",
+.type = QEMU_OPT_NUMBER,
 },
 
 THROTTLE_OPTS,
@@ -75,6 +81,12 @@ static QemuOptsList qemu_virtfs_opts = {
 }, {
 .name = "sock_fd",
 .type = QEMU_OPT_NUMBER,
+}, {
+.name = "fmode",
+.type = QEMU_OPT_NUMBER,
+}, {
+.name = "dmode",
+.type = QEMU_OPT_NUMBER,
 },
 
 { /*End of list */ }
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 1e78b7c9e9..f1ce03b06a 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -633,7 +633,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath 
*dir_path,
 
 if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
 fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
-err = mknodat(dirfd, name, SM_LOCAL_MODE_BITS | S_IFREG, 0);
+err = mknodat(dirfd, name, fs_ctx->fmode | S_IFREG, 0);
 if (err == -1) {
 goto out;
 }
@@ -685,7 +685,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath 
*dir_path,
 
 if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
 fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
-err = mkdirat(dirfd, name, SM_LOCAL_DIR_MODE_BITS);
+err = mkdirat(dirfd, name, fs_ctx->dmode);
 if (err == -1) {
 goto out;
 }
@@ -786,7 +786,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath 
*dir_path, const char *name,
 /* Determine the security model */
 if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
 fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
-fd = openat_file(dirfd, name, flags, SM_LOCAL_MODE_BITS);
+fd = openat_file(dirfd, name, flags, fs_ctx->fmode);
 if (fd == -1) {
 goto out;
 }
@@ -849,7 +849,7 @@ static int local_symlink(FsContext *fs_ctx, const char 
*oldpath,
 ssize_t oldpath_size, write_size;
 
 fd = openat_file(dirfd, name, O_CREAT | O_EXCL | O_RDWR,
- SM_LOCAL_MODE_BITS);
+ fs_ctx->fmode);
 if (fd == -1) {
 goto out;
 }
@@ -1467,6 +1467,23 @@ static int local_parse_opts(QemuOpts *opts, struct 
FsDriverEntry *fse)
 return -1;
 }
 
+if (fse->export_flags & V9FS_SM_MAPPED ||
+fse->export_flags & V9FS_SM_MAPPED_FILE) {
+fse->fmode =
+qemu_opt_get_number(opts, "fmode", SM_LOCAL_MODE_BITS) & 0777;
+fse->dmode =
+qemu_opt_get_number(opts, "dmode", SM_LOCAL_DIR_MODE_BITS) & 0777;
+} else {
+if (qemu_opt_find(opts, "fmode")) {
+error_report("fmode is only valid for mapped 9p modes");
+return -1;
+}
+if (qemu_opt_find(opts, "dmode")) {
+error_report("dmode is only valid for mapped 9p modes");
+return 

[Qemu-devel] [PATCH v5 0/1] 9pfs: local: Add support for custom fmode/dmode in 9ps mapped security modes

2017-06-19 Thread Tobias Schramm
Hi Greg,

thank you for your hints on improving this patch. I've implemented them all
in this version.

In the last version of the patch I moved the path check down because I moved
the g_strdup and tried to keep all operations performed on path as close
together as possible to increase readability. But I clearly didn't think of
madatory vs optional aguments.

I introduced extra variables for fmode and dmode for clear separation of
fetching and processing of arguments. But I guess that trade off is just
personal preference.

I do agree that unifying the mapped mode checks is a good idea. Considering
that it is used in quite a few places might it be a good idea to write a macro
for that check?

Also I have added a much more descriptive commit message.

Again, thank you for the great help (and patience :)).

Regards,

Tobias Schramm

Tobias Schramm (1):
  9pfs: local: Add support for custom fmode/dmode in 9ps mapped security
modes

 fsdev/file-op-9p.h  |  4 
 fsdev/qemu-fsdev-opts.c | 12 
 hw/9pfs/9p-local.c  | 25 +
 hw/9pfs/9p.c|  3 +++
 qemu-options.hx | 20 
 5 files changed, 56 insertions(+), 8 deletions(-)

-- 
2.13.1




Re: [Qemu-devel] [PATCH v6 2/6] queue: Add macro for incremental traversal

2017-06-19 Thread Richard Henderson

On 06/12/2017 07:54 AM, Lluís Vilanova wrote:

Adds macro QTAILQ_FOREACH_CONTINUE to support incremental list
traversal.

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

diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index 35292c3155..eb2bf9cb1c 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -415,6 +415,18 @@ struct {   
 \
  (var);  \
  (var) = ((var)->field.tqe_next))
  
+/**

+ * QTAILQ_FOREACH_CONTINUE:
+ * @var: Variable to resume iteration from.
+ * @field: Field in @var holding a QTAILQ_ENTRY for this queue.
+ *
+ * Resumes iteration on a queue from the element in @var.
+ */
+#define QTAILQ_FOREACH_CONTINUE(var, field) \
+for ((var) = ((var)->field.tqe_next);   \
+(var);  \
+(var) = ((var)->field.tqe_next))
+
  #define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \
  for ((var) = ((head)->tqh_first);   \
  (var) && ((next_var) = ((var)->field.tqe_next), 1); \




I still say this isn't required if the breakpoint loop is better structured.


r~



Re: [Qemu-devel] Commit 77af8a2b9 breaks (mac)OS X 10.11.6

2017-06-19 Thread BALATON Zoltan

On Mon, 19 Jun 2017, Gabriel L. Somlo wrote:

On Sun, Jun 18, 2017 at 11:25:15PM +0200, BALATON Zoltan wrote:

After 77af8a2b9 (hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to
improve guest OS support.) OS X 10.11.6 hangs during boot near detecting
IOAPIC. (Gabriel's latest v3 applesmc patch series does not fix this.) Maybe
another register needs to be implemented somewhere?


I can (still) boot off my 10.11.0 installer iso image, and
successfully upgraded from 10.11.4 to 10.11.6, with the latter
continuing to boot without problems.


I had Clover with unpatched OVMF which worked before but hangs after 
"AppleKeyStore starting" and before "IOAPIC: Version..." messages since 
the above patch. Maybe it's a problem in Clover and I should try a newer 
version.



This is with qemu master (patched for applesmc with the latest v3
pending series that's also on the mailing list), and OVMF master
(patched for HFS+).


It boots with your patched OVMF so now I'm using that instead. (No boot 
menu but it's faster.)



Zoltan: did reverting 77af8a2b9 actually help in your case ? Leaving
it in doesn't seem to be a problem for me...


I could not test reverting because this patch does not cleanly revert on 
HEAD now but my image with Clover booted with the version before 77af8a2b9 
and hangs starting with that patch. So since OS X 10.11.6 can be booted in 
another way the subject should be this commit breaks Clover (at least the 
old version I had). I can't test with a newer Clover version at the moment 
but my problem is solved for now.


Thank you,
BALATON Zoltan



Re: [Qemu-devel] [PATCH 0/6] spapr: DRC cleanups (part IV)

2017-06-19 Thread Michael Roth
Quoting David Gibson (2017-06-08 00:09:24)
> This fourth isntallment of cleanups to the DRC code introduces the
> first changes to the fundamental state handling.  We change the
> initial states in the reset code and attach code for PCI devices, and
> are able to remove the 'signalled' state variable with those fixes.
> 
> There are also some more mechanical cleanups in preparation for
> further cleanups and fixes to the state management.
> 
> David Gibson (6):
>   spapr: Start hotplugged PCI devices in ISOLATED state
>   spapr: Eliminate DRC 'signalled' state variable
>   spapr: Split DRC release from DRC detach
>   spapr: Make DRC reset force DRC into known state
>   spapr: Clean up DRC set_allocation_state path
>   spapr: Clean up DRC set_isolation_state() path

Series:

Reviewed-by: Michael Roth 

> 
>  hw/ppc/spapr.c |  15 --
>  hw/ppc/spapr_drc.c | 363 
> +++--
>  hw/ppc/spapr_events.c  |  10 --
>  include/hw/ppc/spapr_drc.h |  10 +-
>  4 files changed, 188 insertions(+), 210 deletions(-)
> 
> -- 
> 2.9.4
> 




Re: [Qemu-devel] [PATCH 6/6] spapr: Clean up DRC set_isolation_state() path

2017-06-19 Thread Michael Roth
Quoting David Gibson (2017-06-08 00:09:30)
> There are substantial differences in the various paths through
> set_isolation_state(), both for setting to ISOLATED versus UNISOLATED
> state and for logical versus physical DRCs.
> 
> So, split the set_isolation_state() method into isolate() and unisolate()
> methods, and give it different implementations for the two DRC types.
> 
> Factor some minimal common checks, including for valid indicator values
> (which we weren't previously checking) into rtas_set_isolation_state().
> 
> Signed-off-by: David Gibson 
> ---
>  hw/ppc/spapr_drc.c | 145 
> -
>  include/hw/ppc/spapr_drc.h |   6 +-
>  2 files changed, 105 insertions(+), 46 deletions(-)
> 
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index 9e01d7b..90c0fde 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -46,30 +46,64 @@ uint32_t spapr_drc_index(sPAPRDRConnector *drc)
>  | (drc->id & DRC_INDEX_ID_MASK);
>  }
> 
> -static uint32_t set_isolation_state(sPAPRDRConnector *drc,
> -sPAPRDRIsolationState state)
> +static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
>  {
> -trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
> -
>  /* if the guest is configuring a device attached to this DRC, we
>   * should reset the configuration state at this point since it may
>   * no longer be reliable (guest released device and needs to start
>   * over, or unplug occurred so the FDT is no longer valid)
>   */
> -if (state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
> -g_free(drc->ccs);
> -drc->ccs = NULL;
> -}
> +g_free(drc->ccs);
> +drc->ccs = NULL;
> 
> -if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
> -/* cannot unisolate a non-existent resource, and, or resources
> - * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5)
> - */
> -if (!drc->dev ||
> -drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
> -return RTAS_OUT_NO_SUCH_INDICATOR;
> +drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
> +
> +/* if we're awaiting release, but still in an unconfigured state,
> + * it's likely the guest is still in the process of configuring
> + * the device and is transitioning the devices to an ISOLATED
> + * state as a part of that process. so we only complete the
> + * removal when this transition happens for a device in a
> + * configured state, as suggested by the state diagram from PAPR+
> + * 2.7, 13.4
> + */
> +if (drc->awaiting_release) {
> +uint32_t drc_index = spapr_drc_index(drc);
> +if (drc->configured) {
> +trace_spapr_drc_set_isolation_state_finalizing(drc_index);
> +spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
> +} else {
> +trace_spapr_drc_set_isolation_state_deferring(drc_index);
>  }
>  }
> +drc->configured = false;
> +
> +return RTAS_OUT_SUCCESS;
> +}
> +
> +static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
> +{
> +/* cannot unisolate a non-existent resource, and, or resources
> + * which are in an 'UNUSABLE' allocation state. (PAPR 2.7,
> + * 13.5.3.5)
> + */
> +if (!drc->dev) {
> +return RTAS_OUT_NO_SUCH_INDICATOR;
> +}
> +
> +drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
> +
> +return RTAS_OUT_SUCCESS;
> +}
> +
> +static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
> +{
> +/* if the guest is configuring a device attached to this DRC, we
> + * should reset the configuration state at this point since it may
> + * no longer be reliable (guest released device and needs to start
> + * over, or unplug occurred so the FDT is no longer valid)
> + */
> +g_free(drc->ccs);
> +drc->ccs = NULL;
> 
>  /*
>   * Fail any requests to ISOLATE the LMB DRC if this LMB doesn't
> @@ -81,35 +115,47 @@ static uint32_t set_isolation_state(sPAPRDRConnector 
> *drc,
>   * If the LMB being removed doesn't belong to a DIMM device that is
>   * actually being unplugged, fail the isolation request here.
>   */
> -if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) {
> -if ((state == SPAPR_DR_ISOLATION_STATE_ISOLATED) &&
> - !drc->awaiting_release) {
> -return RTAS_OUT_HW_ERROR;
> -}
> +if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB
> +&& !drc->awaiting_release) {
> +return RTAS_OUT_HW_ERROR;
>  }
> 
> -drc->isolation_state = state;
> +drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
> 
> -if (drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
> -/* if we're awaiting release, but still in an unconfigured state,
> - * it's likely the guest is still in the 

Re: [Qemu-devel] QEMU issues on SPARC hosts due to more-than-page-alignment requirement for MAP_SHARED|MAP_FIXED...

2017-06-19 Thread Richard Henderson

On 06/16/2017 02:18 AM, Peter Maydell wrote:

(As an aside I wonder whether any still-used hardware has
the cache aliasing constraints in question :-))


I strongly doubt it.  Certainly none of the 64-bit chips have this.

Amusingly, while we require a 64-bit chip in TCG, we do allow elf32 via 
sparcv8plus, which still runs afoul of this check.  In hindsight, sparcv8plus 
probably should have relaxed this, but it's 20 years too late for that.



r~



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

2017-06-19 Thread Laszlo Ersek
On 06/19/17 20:49, Mark Cave-Ayland wrote:
> On 19/06/17 18:09, Laszlo Ersek wrote:
> 
>>> What seems to happen is that calling object_property_add_child() only
>>> succeeds for the first instance and so a simple comparison is enough to
>>> determine that the device already exists at FW_CFG_PATH. Or is this a
>>> fairly terrible (ab)use of the QOM APIs?
>>
>> This has jogged my memory about how we ensure "at most one" for the
>> vmgenid device. Please see:
>>
>>   vmgenid_realize()[hw/acpi/vmgenid.c]
>> find_vmgenid_dev() [include/hw/acpi/vmgenid.h]
>>
>> ... I was quite silly not to think of this on my own now, despite having
>> authored commit f92063028a0e ("hw/acpi/vmgenid: prevent more than one
>> vmgenid device", 2017-03-20) :/
> 
> Right that definitely helps - the following code seems to work correctly
> when trying to instantiate a mixture of fw_cfg_io and/or fw_cfg_mem types:
> 
> if (!object_resolve_path_type("", TYPE_FW_CFG, NULL)) {
> error_setg(errp, "at most one %s device is permitted", TYPE_FW_CFG);
> return;
> }
> 
> I've also copied the wording from the above commit to make everything
> consistent. Does that seem okay? If so, I'll fold it into a v7 patchset.

It looks good to me, but please await Eduardo's reply as well.

In particular, it should be confirmed that object_resolve_path_type()
matches instances of *subclasses* as well (as I expect it would). Your
test results confirm that; let's make sure it is intentional behavior.
Eduardo (or someone else on the CC list), can you please comment on that?

Thanks!
Laszlo



Re: [Qemu-devel] Guest unresponsive after Virtqueue size exceeded error

2017-06-19 Thread Fernando Casas Schössow
Hi Ladi,

Today two guests failed again at different times of day.
One of them was the one I switched from virtio_blk to virtio_scsi so this 
change didn't solved the problem.
Now in this guest I also disabled virtio_balloon, continuing with the 
elimination process.

Also this time I found a different error message in the guest console.
In the guest already switched to virtio_scsi:

virtio_scsi virtio2: request:id 44 is not a head!

Followed by the usual "task blocked for more than 120 seconds." error.

On the guest still running on virtio_blk the error was similar:

virtio_blk virtio2: req.0:id 42 is not a head!
blk_update_request: I/O error, dev vda, sector 645657736
Buffer I/O error on dev dm-1, logical block 7413821, lost async page write

Followed by the usual "task blocked for more than 120 seconds." error.

Do you think that the blk_update_request and the buffer I/O error may be a 
consequence of the previous "is not a head!" error or should I be worried for a 
storage level issue here?

Now I will wait to see if disabling virtio_balloon helps or not and report back.

Thanks.

Fer

On vie, jun 16, 2017 at 12:25 , Ladi Prosek  wrote:
On Fri, Jun 16, 2017 at 12:11 PM, Fernando Casas Schössow 
> wrote:
Hi Ladi, Thanks a lot for looking into this and replying. I will do my best to 
rebuild and deploy Alpine's qemu packages with this patch included but not sure 
its feasible yet. In any case, would it be possible to have this patch included 
in the next qemu release?
Yes, I have already added this to my todo list.
The current error message is helpful but knowing which device was involved will 
be much more helpful. Regarding the environment, I'm not doing migrations and 
only managed save is done in case the host needs to be rebooted or shutdown. 
The QEMU process is running the VM since the host is started and this failuire 
is ocurring randomly without any previous manage save done. As part of 
troubleshooting on one of the guests I switched from virtio_blk to virtio_scsi 
for the guest disks but I will need more time to see if that helped. If I have 
this problem again I will follow your advise and remove virtio_balloon.
Thanks, please keep us posted.
Another question: is there any way to monitor the virtqueue size either from 
the guest itself or from the host? Any file in sysfs or proc? This may help to 
understand in which conditions this is happening and to react faster to 
mitigate the problem.
The problem is not in the virtqueue size but in one piece of internal state 
("inuse") which is meant to track the number of buffers "checked out" by QEMU. 
It's being compared to virtqueue size merely as a sanity check. I'm afraid that 
there's no way to expose this variable without rebuilding QEMU. The best you 
could do is attach gdb to the QEMU process and use some clever data access 
breakpoints to catch suspicious writes to the variable. Although it's likely 
that it just creeps up slowly and you won't see anything interesting. It's 
probably beyond reasonable at this point anyway. I would continue with the 
elimination process (virtio_scsi instead of virtio_blk, no balloon, etc.) and 
then maybe once we know which device it is, we can add some instrumentation to 
the code.
Thanks again for your help with this! Fer On vie, jun 16, 2017 at 8:58 , Ladi 
Prosek > wrote: Hi, Would you be 
able to enhance the error message and rebuild QEMU? --- a/hw/virtio/virtio.c 
+++ b/hw/virtio/virtio.c @@ -856,7 +856,7 @@ void *virtqueue_pop(VirtQueue *vq, 
size_t sz) max = vq->vring.num; if (vq->inuse
= vq->vring.num) { - virtio_error(vdev, "Virtqueue size exceeded"); +
virtio_error(vdev, "Virtqueue %u device %s size exceeded", vq->queue_index, 
vdev->name); goto done; } This would at least confirm the theory that it's 
caused by virtio-blk-pci. If rebuilding is not feasible I would start by 
removing other virtio devices -- particularly balloon which has had quite a few 
virtio related bugs fixed recently. Does your environment involve VM migrations 
or saving/resuming, or does the crashing QEMU process always run the VM from 
its boot? Thanks!




Re: [Qemu-devel] [PATCH v4 5/7] target-m68k: use floatx80 internally

2017-06-19 Thread Richard Henderson

On 06/19/2017 02:42 PM, Laurent Vivier wrote:

Le 19/06/2017 à 23:03, Laurent Vivier a écrit :

Le 19/06/2017 à 22:53, Richard Henderson a écrit :


It would also make me happier if we were to adjust the definition of
fl0atx80 to more closely match m68k and those missing zeros.  Shouldn't
real hardware move instructions propagate those middle 2 bytes
regardless of contents?

Perhaps something like

#ifdef TARGET_M68K
   typedef struct {
 uint64_t low;
 union {
   uin32_t high32;
   struct {
#ifdef HOST_WORDS_BIGENDIAN
 uint16_t high, zero;
#else
 uint16_t zero, high;
#endif
   };
 };
   } floatx80;
#else
   ...
#endif

(with a minor fix to make_floatx80 to use named initializers).

Then you can use full 32-bit store insns when copying data here.  Which
also allows you to drop some of the shifts you're needing to add.


OK, I will.


The softfloat is in the target independent code, so we can't adjust the
size of floatx80 by target, TARGET_ are poisoned when used in
softfloat.h.


Ouch.  That means we'd have to add a full set of floatx96.

If you don't want to do that now, I'd understand.  I'd prefer that you issue an 
undefined opcode exception or something for the packed decimals though, rather 
than just silently dropping 2 bytes of data.


I suppose a first go at floatx96 would be just to thunk the data and call to 
the floatx80 routines.  I do seem to recall that a Proper implementation would 
treat m68k un-normals different from x86.


r~



Re: [Qemu-devel] [PATCH 2/4] include/exec/poison: Mark some CONFIG defines as poisoned, too

2017-06-19 Thread Richard Henderson

On 06/14/2017 12:21 PM, Thomas Huth wrote:

+#pragma GCC poison CONFIG_ALPHA_DIS
+#pragma GCC poison CONFIG_ARM_A64_DIS
+#pragma GCC poison CONFIG_ARM_DIS
+#pragma GCC poison CONFIG_CRIS_DIS
+#pragma GCC poison CONFIG_I386_DIS
+#pragma GCC poison CONFIG_LM32_DIS
+#pragma GCC poison CONFIG_M68K_DIS
+#pragma GCC poison CONFIG_MICROBLAZE_DIS
+#pragma GCC poison CONFIG_MIPS_DIS
+#pragma GCC poison CONFIG_MOXIE_DIS
+#pragma GCC poison CONFIG_NIOS2_DIS
+#pragma GCC poison CONFIG_PPC_DIS
+#pragma GCC poison CONFIG_S390_DIS
+#pragma GCC poison CONFIG_SH4_DIS
+#pragma GCC poison CONFIG_SPARC_DIS
+#pragma GCC poison CONFIG_XTENSA_DIS


Also missing a couple.


r~



Re: [Qemu-devel] [PATCH 1/4] include/exec/poison: Add missing TARGET defines

2017-06-19 Thread Richard Henderson

On 06/14/2017 12:21 PM, Thomas Huth wrote:

  #pragma GCC poison TARGET_CRIS
  #pragma GCC poison TARGET_LM32


Missing HPPA and TILEGX.


r~



Re: [Qemu-devel] [PATCH v4 5/7] target-m68k: use floatx80 internally

2017-06-19 Thread Laurent Vivier
Le 19/06/2017 à 23:03, Laurent Vivier a écrit :
> Le 19/06/2017 à 22:53, Richard Henderson a écrit :
>>
>> It would also make me happier if we were to adjust the definition of
>> fl0atx80 to more closely match m68k and those missing zeros.  Shouldn't
>> real hardware move instructions propagate those middle 2 bytes
>> regardless of contents?
>>
>> Perhaps something like
>>
>> #ifdef TARGET_M68K
>>   typedef struct {
>> uint64_t low;
>> union {
>>   uin32_t high32;
>>   struct {
>> #ifdef HOST_WORDS_BIGENDIAN
>> uint16_t high, zero;
>> #else
>> uint16_t zero, high;
>> #endif
>>   };
>> };
>>   } floatx80;
>> #else
>>   ...
>> #endif
>>
>> (with a minor fix to make_floatx80 to use named initializers).
>>
>> Then you can use full 32-bit store insns when copying data here.  Which
>> also allows you to drop some of the shifts you're needing to add.
> 
> OK, I will.

The softfloat is in the target independent code, so we can't adjust the
size of floatx80 by target, TARGET_ are poisoned when used in
softfloat.h.

Laurent



Re: [Qemu-devel] [PATCH] tcg/tci: enable bswap16_i64

2017-06-19 Thread Richard Henderson

On 06/13/2017 12:11 PM, Alex Bennée wrote:


Philippe Mathieu-Daudé  writes:


remove some copy/paste leftover, code seems sane.

while running Alex Bennée's image aarch64-linux-3.15rc2-buildroot.img:

Trace 0x7fa1904b0890 [0: ffc00036cd04]

IN:
0xffc00036cd24:  5ac00694  rev16 w20, w20

OP:
   ffc00036cd24  
  ext32u_i64 tmp3,x20
  ext16u_i64 tmp2,tmp3
  bswap16_i64 x20,tmp2
  movi_i64 tmp4,$0x10
  shr_i64 tmp2,tmp3,tmp4
  ext16u_i64 tmp2,tmp2
  bswap16_i64 tmp2,tmp2
  deposit_i64 x20,x20,tmp2,$0x10,$0x10

Linking TBs 0x7fa1904b0890 [ffc00036cd04] index 0 -> 0x7fa1904b0aa0 
[ffc00036cd24]
Trace 0x7fa1904b0aa0 [0: ffc00036cd24]
TODO qemu/tci.c:1049: tcg_qemu_tb_exec()
qemu/tci.c:1049: tcg fatal error
Aborted

Signed-off-by: Philippe Mathieu-Daudé 


Possibly the only person who has run tci recently ;-)


Is it time to remove it?  I'm pretty sure the only hosts for which it will work 
have proper backends...



r~



Re: [Qemu-devel] [PATCH] nvme: Add support for Read Data and Write Data in CMBs.

2017-06-19 Thread Keith Busch
On Tue, Jun 13, 2017 at 04:08:35AM -0600, sba...@raithlin.com wrote:
> From: Stephen Bates 
> 
> Add the ability for the NVMe model to support both the RDS and WDS
> modes in the Controller Memory Buffer.
> 
> Although not currently supported in the upstreamed Linux kernel a fork
> with support exists [1] and user-space test programs that build on
> this also exist [2].
> 
> Useful for testing CMB functionality in preperation for real CMB
> enabled NVMe devices (coming soon).
> 
> [1] https://github.com/sbates130272/linux-p2pmem
> [2] https://github.com/sbates130272/p2pmem-test
> 
> Signed-off-by: Stephen Bates 
> Reviewed-by: Logan Gunthorpe 

This looks good to me.

Reviewed-by: Keith Busch 



Re: [Qemu-devel] [PATCH v4 7/7] target-m68k: add FPCR and FPSR

2017-06-19 Thread Richard Henderson

On 06/11/2017 04:16 PM, Laurent Vivier wrote:

@@ -95,8 +101,14 @@ static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t 
*mem_buf, int n)
  env->fregs[n].d = float64_to_floatx80(ldfq_p(mem_buf), );
  return 8;
  }
-if (n < 11) {
-/* FP control registers (not implemented)  */
+switch (n) {
+case 8: /* fpcontrol */
+env->fpcr = ldl_p(mem_buf);
+return 4;


Should use cpu_m68k_set_fpcr.



+DEF_HELPER_2(set_fpcr, void, env, i32)


Hmm.  I suppose the write to env->fpcr means you can't indicate 
TCG_CALL_NO_RWG.  I wonder if it's better as


uint32_t HELPER(set_fpcr)(CPUM68KState *env, uint32_t val)
{
   cpu_m68k_set_fpcr(env, val);
   return env->fpcr;
}

DEF_HELPER_FLAGS_2(set_fpcr, i32, env, i32)

gen_helper_set_fpcr(QEMU_FPCR, cpu_env, val);

This skirts the rules of TCG, but it'll work, since we disguise the (incorrect) 
write to env->fpcr with a (correct but redundant) write to QEMU_FPCR.


Any time we can avoid spilling all globals we're better off.

As an alternative, is it really that important to represent FPSR and FPCR as 
tcg registers?  Perhaps it's better to just tcg_gen_ld/st instead?



r~



[Qemu-devel] Tracing guest virtual addresses

2017-06-19 Thread Jayanto Minocha
Hi,

I think there have been a few threads on the mailing list regarding tracing
guest virtual addresses for load and store instructions, but I have been
unable to get it to work. I am trying this for an AArch64 machine, and am
using the softmmu.

The tracing infrastructure provides the following event:

vcpu tcg guest_mem_before(...).

But that is only used to instrument the cpu_ld/cpu_st macros, which is only
called in the case of a tlb miss.

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

Regards,
-Jayanto


Re: [Qemu-devel] [PATCH] Remove restriction that prevents bootimg elf64 images

2017-06-19 Thread Adam Lackorzynski
Hi,

On Tue Jun 13, 2017 at 17:05:41 -0700, Anatol Pomozov wrote:
> Do these arguments sound reasonable to apply the patch?

I'm not really convinced.

> On Thu, Jun 8, 2017 at 2:07 PM, Anatol Pomozov  
> wrote:
> > +reply-all
> >
> > On Thu, Jun 8, 2017 at 1:41 PM, Adam Lackorzynski
> >  wrote:
> >>
> >> On Tue Jun 06, 2017 at 21:41:48 -0700, Anatol Pomozov wrote:
> >>> It is possible to create a 64 bit elf image that has valid multiboot 
> >>> header.
> >>> qemu should be able to boot such images.
> >>
> >> But this 64bit image actually starts with 32bit code, right?
> >
> > Correct. The very first part of the startup code has to be 32bit.
> > After it sets "long mode" it can use 64bit instructions. To make sure
> > that the preamble has only 32bit instructions one have to use asm
> > directive such as ".code32".
> >
> > Here is an example from LitleKernel sturtup code:
> >
> > https://github.com/littlekernel/lk/blob/master/arch/x86/64/start.S#L50
> >
> > .code32 tells assembler to treat following text as 32 bit code. And
> > later when it jumps into "long mode"
> >
> > https://github.com/littlekernel/lk/blob/master/arch/x86/64/start.S#L214
> > one can use 64bit code.
> >
> >> So it's a 32bit program and the check verifies that this is the case.
> >
> > While preamble have to contain 32 only instructions the rest of the
> > image can perfectly contain 64bit code. Right now 64bit binary cannot
> > be run with "qemu-system-x86_64 -kernel". But the same binary runs
> > fine if packed with GRUB as iso.
> >
> > I tried to hack around this restriction by adding
> > "OUTPUT_FORMAT(elf32-i386)" to the linker file and compiling project
> > with 64bit support. But GNU ld program crashed at Ubuntu 14.04. It
> > means not that many people use this code path. GNU ld compiled from
> > HEAD does not have this problem but now GDB is confused by the fact
> > that ELF contains 64bit code while header reports i386.

That's unfortunate.

> > Practically there is no reason for this check as it prevents running
> > 64bit binaries with "qemu-system-x86_64 -kernel".

One reason for the check is that it prevents that one loads a 64bit ELF
binary that then fails strangely because it does not have the magic
32bit code to set up things. At least there needs to be an override
(could also be in the ELF info).

Doing a proper 32bit wrapper is also possible, although that would need
a little ELF loader, or a custom loader, probably. We've done it this
way but that also requires some more lines.

If allowing 64bit binaries it should also be checked that all relevant
values fit into 32bit.



Adam



Re: [Qemu-devel] [PATCH v4 5/7] target-m68k: use floatx80 internally

2017-06-19 Thread Laurent Vivier
Le 19/06/2017 à 22:53, Richard Henderson a écrit :
> On 06/11/2017 04:16 PM, Laurent Vivier wrote:
>> +static void gen_load_fp(DisasContext *s, int opsize, TCGv addr,
>> TCGv_ptr fp)
>> +{
>> +TCGv tmp;
>> +TCGv_i64 t64;
>> +int index = IS_USER(s);
>> +
>> +t64 = tcg_temp_new_i64();
>> +tmp = tcg_temp_new();
>> +switch (opsize) {
>> +case OS_BYTE:
>> +tcg_gen_qemu_ld8s(tmp, addr, index);
>> +gen_helper_exts32(cpu_env, fp, tmp);
>> +break;
>> +case OS_WORD:
>> +tcg_gen_qemu_ld16s(tmp, addr, index);
>> +gen_helper_exts32(cpu_env, fp, tmp);
>> +break;
>> +case OS_LONG:
>> +tcg_gen_qemu_ld32u(tmp, addr, index);
>> +gen_helper_exts32(cpu_env, fp, tmp);
>> +break;
>> +case OS_SINGLE:
>> +tcg_gen_qemu_ld32u(tmp, addr, index);
>> +gen_helper_extf32(cpu_env, fp, tmp);
>> +break;
>> +case OS_DOUBLE:
>> +tcg_gen_qemu_ld64(t64, addr, index);
>> +gen_helper_extf64(cpu_env, fp, t64);
>> +tcg_temp_free_i64(t64);
>> +break;
>> +case OS_EXTENDED:
>> +tcg_gen_qemu_ld32u(tmp, addr, index);
>> +tcg_gen_shri_i32(tmp, tmp, 16);
>> +tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
>> +tcg_gen_addi_i32(tmp, addr, 4);
>> +tcg_gen_qemu_ld64(t64, tmp, index);
>> +tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
>> +break;
>> +case OS_PACKED:
>> +tcg_gen_qemu_ld32u(tmp, addr, index);
>> +tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
>> +tcg_gen_addi_i32(tmp, addr, 4);
>> +tcg_gen_qemu_ld64(t64, tmp, index);
>> +tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
> 
> I don't see how this can be correct.  Doesn't the packed-decimal format
> use all 12 bytes (with two unaligned nibbles unused)?

yes, it's totally wrong.

> 
> It would also make me happier if we were to adjust the definition of
> fl0atx80 to more closely match m68k and those missing zeros.  Shouldn't
> real hardware move instructions propagate those middle 2 bytes
> regardless of contents?
> 
> Perhaps something like
> 
> #ifdef TARGET_M68K
>   typedef struct {
> uint64_t low;
> union {
>   uin32_t high32;
>   struct {
> #ifdef HOST_WORDS_BIGENDIAN
> uint16_t high, zero;
> #else
> uint16_t zero, high;
> #endif
>   };
> };
>   } floatx80;
> #else
>   ...
> #endif
> 
> (with a minor fix to make_floatx80 to use named initializers).
> 
> Then you can use full 32-bit store insns when copying data here.  Which
> also allows you to drop some of the shifts you're needing to add.

OK, I will.

> And, in future, when you actually implement the packed decimal, you'll
> be able to use the high32 field to Do the Right Thing.
> 
> All of the rest of the patch looks good.

Thanks,
Laurent




[Qemu-devel] [PATCH] 9pfs: local: remove: use correct path component

2017-06-19 Thread Bruce Rogers
Commit a0e640a8 introduced a path processing error.
Pass fstatat the dirpath based path component instead
of the entire path.

Signed-off-by: Bruce Rogers 
---
 hw/9pfs/9p-local.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 1e78b7c9e9..83952eff0a 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -1100,7 +1100,7 @@ static int local_remove(FsContext *ctx, const char *path)
 goto out;
 }
 
-if (fstatat(dirfd, path, , AT_SYMLINK_NOFOLLOW) < 0) {
+if (fstatat(dirfd, name, , AT_SYMLINK_NOFOLLOW) < 0) {
 goto err_out;
 }
 
-- 
2.12.2




Re: [Qemu-devel] [PATCH v4 5/7] target-m68k: use floatx80 internally

2017-06-19 Thread Richard Henderson

On 06/11/2017 04:16 PM, Laurent Vivier wrote:

+static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp)
+{
+TCGv tmp;
+TCGv_i64 t64;
+int index = IS_USER(s);
+
+t64 = tcg_temp_new_i64();
+tmp = tcg_temp_new();
+switch (opsize) {
+case OS_BYTE:
+tcg_gen_qemu_ld8s(tmp, addr, index);
+gen_helper_exts32(cpu_env, fp, tmp);
+break;
+case OS_WORD:
+tcg_gen_qemu_ld16s(tmp, addr, index);
+gen_helper_exts32(cpu_env, fp, tmp);
+break;
+case OS_LONG:
+tcg_gen_qemu_ld32u(tmp, addr, index);
+gen_helper_exts32(cpu_env, fp, tmp);
+break;
+case OS_SINGLE:
+tcg_gen_qemu_ld32u(tmp, addr, index);
+gen_helper_extf32(cpu_env, fp, tmp);
+break;
+case OS_DOUBLE:
+tcg_gen_qemu_ld64(t64, addr, index);
+gen_helper_extf64(cpu_env, fp, t64);
+tcg_temp_free_i64(t64);
+break;
+case OS_EXTENDED:
+tcg_gen_qemu_ld32u(tmp, addr, index);
+tcg_gen_shri_i32(tmp, tmp, 16);
+tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
+tcg_gen_addi_i32(tmp, addr, 4);
+tcg_gen_qemu_ld64(t64, tmp, index);
+tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));
+break;
+case OS_PACKED:
+tcg_gen_qemu_ld32u(tmp, addr, index);
+tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper));
+tcg_gen_addi_i32(tmp, addr, 4);
+tcg_gen_qemu_ld64(t64, tmp, index);
+tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower));


I don't see how this can be correct.  Doesn't the packed-decimal format use all 
12 bytes (with two unaligned nibbles unused)?


It would also make me happier if we were to adjust the definition of fl0atx80 
to more closely match m68k and those missing zeros.  Shouldn't real hardware 
move instructions propagate those middle 2 bytes regardless of contents?


Perhaps something like

#ifdef TARGET_M68K
  typedef struct {
uint64_t low;
union {
  uin32_t high32;
  struct {
#ifdef HOST_WORDS_BIGENDIAN
uint16_t high, zero;
#else
uint16_t zero, high;
#endif
  };
};
  } floatx80;
#else
  ...
#endif

(with a minor fix to make_floatx80 to use named initializers).

Then you can use full 32-bit store insns when copying data here.  Which also 
allows you to drop some of the shifts you're needing to add.


And, in future, when you actually implement the packed decimal, you'll be able 
to use the high32 field to Do the Right Thing.


All of the rest of the patch looks good.


r~



[Qemu-devel] [PATCH v3] Add manpage for QEMU Backup Tool

2017-06-19 Thread Ishani Chugh
qemu-backup will be a command-line tool for performing full and incremental 
disk backups on running
VMs.  It is intended as a reference implementation for management stack and 
backup developers to
see QEMU's backup features in action. The following commit is an initial 
implementation of manpage
listing the commands which the backup tool will support.

Signed-off-by: Ishani Chugh 
---
 Makefile|   2 +-
 contrib/backup/qemu-backup.texi | 139 
 2 files changed, 140 insertions(+), 1 deletion(-)
 create mode 100644 contrib/backup/qemu-backup.texi

diff --git a/Makefile b/Makefile
index c830d7a..094f291 100644
--- a/Makefile
+++ b/Makefile
@@ -504,7 +504,7 @@ clean:
 VERSION ?= $(shell cat VERSION)
 
 dist: qemu-$(VERSION).tar.bz2
-
+qemu-backup.8: contrib/backup/qemu-backup.texi
 qemu-%.tar.bz2:
$(SRC_PATH)/scripts/make-release "$(SRC_PATH)" "$(patsubst 
qemu-%.tar.bz2,%,$@)"
 
diff --git a/contrib/backup/qemu-backup.texi b/contrib/backup/qemu-backup.texi
new file mode 100644
index 000..1db63c0
--- /dev/null
+++ b/contrib/backup/qemu-backup.texi
@@ -0,0 +1,139 @@
+@setfilename qemu-backup-tool-manpage
+
+@documentlanguage en
+@documentencoding UTF-8
+
+\input texinfo
+@settitle Manpage_backup_tool 1.0
+@copying
+This is a manpage for qemu_backup_tool, version 1.0.
+
+Copyright @copyright{} 2016 Free Software Foundation, Inc.
+@end copying
+@ifinfo
+@direntry
+* QEMU: (qemu-backup-tool-manpage).Man page for QEMU backup tool.
+@end direntry
+@end ifinfo
+@iftex
+@titlepage
+@sp 7
+@center @titlefont{QEMU_backup_tool}
+@sp 1
+@center @titlefont{Man Page}
+@sp 3
+@end titlepage
+@end iftex
+@ifnottex
+@node Top
+@top Short Sample
+
+@menu
+* Name::
+* Synopsis::
+* list of Commands::
+* Command Parameters::
+* Command Descriptions::
+* License::
+@end menu
+
+@end ifnottex
+
+@node Name
+@chapter Name
+
+QEMU disk backup tool.
+
+@node Synopsis
+@chapter Synopsis
+
+qemu-backup command [ command options].
+
+@node  list of Commands
+@chapter  list of Commands
+@cindex chapter, first dummy
+@itemize
+@item qemu-backup guest add [--id id] [--qmp socketpath]
+@item qemu-backup guest list
+@item qemu-backup drive add [--guest guestname] [--id driveid] [--target 
target]
+@item qemu-backup drive list [--guest guestname]
+@item qemu-backup backup [--guest guestname]
+@item qemu-backup restore [--guest guestname]
+@item qemu-backup drive-remove [--guest guestname] [--id driveid]
+@item qemu-backup remove [--guest guestname]
+@item qemu-backup drive add [--all] [--guest guestname] [--target target]
+@item qemu-backup backup [--inc] [--guest guestname]
+@end itemize
+@node  Command Parameters
+@chapter  Command Parameters
+@cindex chapter, first dummy
+@itemize
+@item --guest: Name of the guest.
+@item --id: id of guest or drive.
+@item --target: Destination on which you want your backup to be made.
+@item --all: Add all the drives present in a guest for backup except cd-rom.
+@item --inc: For incremental backup.
+@item --qmp: Path of qmp socket.
+@end itemize
+
+@node  Command Descriptions
+@chapter  Command Descriptions
+@cindex chapter, first dummy
+@itemize
+@item qemu-backup guest add [--id id] [--qmp socketpath]
+This command adds a guest to the configuration file given its path to qmp 
socket.
+example:
+qemu-backup guest add --id=fedora –qmp=/var/run/qemu/fedora.sock
+
+@item qemu-backup guest list
+This commands lists the names of guests which are added to configuration file.
+
+@item qemu-backup drive add [--guest guestname] [--id driveid] [--target 
target]
+This command adds different drives for backup in a particular guest by giving 
the name of drive to be backed up and target imagefile in which we want to 
store the drive backup.
+example:
+qemu-backup drive add --guest=fedora --id=root
+--target=/backup/fedora/root.img
+qemu-backup drive add --guest=fedora --id=data
+--target=/backup/fedora/data.img
+
+@item qemu-backup drive list [--guest guestname]
+This commands gives the names of the drive present in a guest which are added 
for backup.
+example: qemu-backup drive list --guest=fedora
+
+@item qemu-backup backup [--guest guestname]
+
+This command makes the backup of the drives, in their respective given 
destinations. The ids of drive and their destinations are taken from the 
configuration file.
+example: qemu-backup backup --guest=fedora
+
+@item qemu-backup restore [--guest guestname]
+This command is needed if we want to restore the backup. It will list the 
commands to be run for performing the same but will not perform any action.
+example: qemu-backup restore --guest=fedora
+cp /backup/fedora/root.img /var/run/qemu/fedora/root.img
+cp /backup/fedora/data.img /var/run/qemu/fedora/data.img
+
+@item qemu-backup drive-remove [--guest guestname] [--id driveid]
+This command helps remove a drive which is set for backup in configuration of 
given host.
+example: qemu-backup remove 

Re: [Qemu-devel] [PATCH v4 1/1] 9pfs: local: Add support for custom fmode/dmode in 9ps mapped security modes

2017-06-19 Thread Greg Kurz
On Mon, 19 Jun 2017 16:28:48 +0200
Tobias Schramm  wrote:

I saw you wrote the full story in the cover letter, but I was asking for
something to be written here (so that it appears in git log). Something
concise and clear like:

"In mapped security mode, files get created with restricted file mode (0600 for
regular files and 0700 for directories). This makes file sharing between several
users on the host rather complicated (examples?)

This patch makes the default mode for both files and directories configurable
through the command line. Existing setups that don't know about the new command
line go on with the current secure behavior."

or anything better you can come up with.

> Signed-off-by: Tobias Schramm 
> ---
>  v4: Use OPT_NUMBER for file mode arguments, fix back to front naming,
>  fix resource leak and add sanity checking for fmode/dmode arguments
>  v3: Use unsigned types for umask
>  v2: Adjust patch to QEMU code style
> 
>  fsdev/file-op-9p.h  |  4 
>  fsdev/qemu-fsdev-opts.c | 12 
>  hw/9pfs/9p-local.c  | 34 +-
>  hw/9pfs/9p.c|  3 +++
>  qemu-options.hx | 20 
>  5 files changed, 60 insertions(+), 13 deletions(-)
> 
> diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
> index 0844a403dc..474c79d003 100644
> --- a/fsdev/file-op-9p.h
> +++ b/fsdev/file-op-9p.h
> @@ -76,6 +76,8 @@ typedef struct FsDriverEntry {
>  int export_flags;
>  FileOperations *ops;
>  FsThrottle fst;
> +mode_t fmode;
> +mode_t dmode;
>  } FsDriverEntry;
>  
>  typedef struct FsContext
> @@ -88,6 +90,8 @@ typedef struct FsContext
>  FsThrottle *fst;
>  /* fs driver specific data */
>  void *private;
> +mode_t fmode;
> +mode_t dmode;
>  } FsContext;
>  
>  typedef struct V9fsPath {
> diff --git a/fsdev/qemu-fsdev-opts.c b/fsdev/qemu-fsdev-opts.c
> index bf5713008a..7c31af 100644
> --- a/fsdev/qemu-fsdev-opts.c
> +++ b/fsdev/qemu-fsdev-opts.c
> @@ -38,6 +38,12 @@ static QemuOptsList qemu_fsdev_opts = {
>  }, {
>  .name = "sock_fd",
>  .type = QEMU_OPT_NUMBER,
> +}, {
> +.name = "fmode",
> +.type = QEMU_OPT_NUMBER,
> +}, {
> +.name = "dmode",
> +.type = QEMU_OPT_NUMBER,
>  },
>  
>  THROTTLE_OPTS,
> @@ -75,6 +81,12 @@ static QemuOptsList qemu_virtfs_opts = {
>  }, {
>  .name = "sock_fd",
>  .type = QEMU_OPT_NUMBER,
> +}, {
> +.name = "fmode",
> +.type = QEMU_OPT_NUMBER,
> +}, {
> +.name = "dmode",
> +.type = QEMU_OPT_NUMBER,
>  },
>  
>  { /*End of list */ }
> diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
> index 1e78b7c9e9..696e2b75dc 100644
> --- a/hw/9pfs/9p-local.c
> +++ b/hw/9pfs/9p-local.c
> @@ -633,7 +633,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath 
> *dir_path,
>  
>  if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
>  fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
> -err = mknodat(dirfd, name, SM_LOCAL_MODE_BITS | S_IFREG, 0);
> +err = mknodat(dirfd, name, fs_ctx->fmode | S_IFREG, 0);
>  if (err == -1) {
>  goto out;
>  }
> @@ -685,7 +685,7 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath 
> *dir_path,
>  
>  if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
>  fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
> -err = mkdirat(dirfd, name, SM_LOCAL_DIR_MODE_BITS);
> +err = mkdirat(dirfd, name, fs_ctx->dmode);
>  if (err == -1) {
>  goto out;
>  }
> @@ -786,7 +786,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath 
> *dir_path, const char *name,
>  /* Determine the security model */
>  if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
>  fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
> -fd = openat_file(dirfd, name, flags, SM_LOCAL_MODE_BITS);
> +fd = openat_file(dirfd, name, flags, fs_ctx->fmode);
>  if (fd == -1) {
>  goto out;
>  }
> @@ -849,7 +849,7 @@ static int local_symlink(FsContext *fs_ctx, const char 
> *oldpath,
>  ssize_t oldpath_size, write_size;
>  
>  fd = openat_file(dirfd, name, O_CREAT | O_EXCL | O_RDWR,
> - SM_LOCAL_MODE_BITS);
> + fs_ctx->fmode);
>  if (fd == -1) {
>  goto out;
>  }
> @@ -1431,6 +1431,8 @@ static int local_parse_opts(QemuOpts *opts, struct 
> FsDriverEntry *fse)
>  {
>  const char *sec_model = qemu_opt_get(opts, "security_model");
>  const char *path = qemu_opt_get(opts, "path");
> +uint64_t fmode = qemu_opt_get_number(opts, "fmode", SM_LOCAL_MODE_BITS);
> +uint64_t dmode = qemu_opt_get_number(opts, "dmode", 
> SM_LOCAL_DIR_MODE_BITS);

We don't need to get this options in non-mapped security 

Re: [Qemu-devel] [PATCH v4 0/1] 9pfs: local: Add support for custom fmode/dmode in 9ps mapped security modes

2017-06-19 Thread Greg Kurz
On Mon, 19 Jun 2017 16:28:47 +0200
Tobias Schramm  wrote:

> Hi,
> 
> i've noticed that there is no way to control the permissions of newly created 
> files and
> folders on the host when using 9p in mapped security mode. This can be a big 
> problem when
> configuring permissions for access to such data for groups and via ACLs on 
> the host.
> Thus I added the options fmode and dmode to the fsdev and virtfs options that 
> set the actual
> permissions of newly created files and folders on the host.
> 
> This version of the patch fixes the back to front "mask" naming in the 
> previous patches. I
> always meant "mode" when actually writing "mask".
> 

Indeed, this hasn't the umask semantics.

> Also specifying fmode and dmode only has an effect in mapped security modes. 
> Specifying it
> in any other mode now throws an error.
> 
> Additionally I've switched fmode and dmode to QEMU_OPT_NUMBER because it 
> handels octal input
> just fine.
> 
> Also previous versions leaked a string with g_strdup if an error during 
> parsing of fmode/dmode
> occurred.
> 
> Thanks to Greg Kurz for pointing out most of the above issues to me.
> 
> Tobias Schramm
> 
> Tobias Schramm (1):
>   Add support for custom fmode/dmode in 9ps mapped security modes
> 
>  fsdev/file-op-9p.h  |  4 
>  fsdev/qemu-fsdev-opts.c | 12 
>  hw/9pfs/9p-local.c  | 34 +-
>  hw/9pfs/9p.c|  3 +++
>  qemu-options.hx | 20 
>  5 files changed, 60 insertions(+), 13 deletions(-)
> 



pgp92qxqM4OlK.pgp
Description: OpenPGP digital signature


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

2017-06-19 Thread Mark Cave-Ayland
On 19/06/17 18:09, Laszlo Ersek wrote:

>> What seems to happen is that calling object_property_add_child() only
>> succeeds for the first instance and so a simple comparison is enough to
>> determine that the device already exists at FW_CFG_PATH. Or is this a
>> fairly terrible (ab)use of the QOM APIs?
> 
> This has jogged my memory about how we ensure "at most one" for the
> vmgenid device. Please see:
> 
>   vmgenid_realize()[hw/acpi/vmgenid.c]
> find_vmgenid_dev() [include/hw/acpi/vmgenid.h]
> 
> ... I was quite silly not to think of this on my own now, despite having
> authored commit f92063028a0e ("hw/acpi/vmgenid: prevent more than one
> vmgenid device", 2017-03-20) :/

Right that definitely helps - the following code seems to work correctly
when trying to instantiate a mixture of fw_cfg_io and/or fw_cfg_mem types:

if (!object_resolve_path_type("", TYPE_FW_CFG, NULL)) {
error_setg(errp, "at most one %s device is permitted", TYPE_FW_CFG);
return;
}

I've also copied the wording from the above commit to make everything
consistent. Does that seem okay? If so, I'll fold it into a v7 patchset.


ATB,

Mark.




[Qemu-devel] [PULL 07/12] tcg/arm: Try pc-relative addresses for movi

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 tcg/arm/tcg-target.inc.c | 40 +++-
 1 file changed, 27 insertions(+), 13 deletions(-)

diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index fce382f..42370e5 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -418,23 +418,37 @@ static inline void tcg_out_dat_imm(TCGContext *s,
 
 static void tcg_out_movi32(TCGContext *s, int cond, int rd, uint32_t arg)
 {
-int rot, opc, rn;
-
-/* For armv7, make sure not to use movw+movt when mov/mvn would do.
-   Speed things up by only checking when movt would be required.
-   Prior to armv7, have one go at fully rotated immediates before
-   doing the decomposition thing below.  */
-if (!use_armv7_instructions || (arg & 0x)) {
-rot = encode_imm(arg);
+int rot, opc, rn, diff;
+
+/* Check a single MOV/MVN before anything else.  */
+rot = encode_imm(arg);
+if (rot >= 0) {
+tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0,
+rotl(arg, rot) | (rot << 7));
+return;
+}
+rot = encode_imm(~arg);
+if (rot >= 0) {
+tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0,
+rotl(~arg, rot) | (rot << 7));
+return;
+}
+
+/* Check for a pc-relative address.  This will usually be the TB,
+   or within the TB, which is immediately before the code block.  */
+diff = arg - ((intptr_t)s->code_ptr + 8);
+if (diff >= 0) {
+rot = encode_imm(diff);
 if (rot >= 0) {
-tcg_out_dat_imm(s, cond, ARITH_MOV, rd, 0,
-rotl(arg, rot) | (rot << 7));
+tcg_out_dat_imm(s, cond, ARITH_ADD, rd, TCG_REG_PC,
+rotl(diff, rot) | (rot << 7));
 return;
 }
-rot = encode_imm(~arg);
+} else {
+rot = encode_imm(-diff);
 if (rot >= 0) {
-tcg_out_dat_imm(s, cond, ARITH_MVN, rd, 0,
-rotl(~arg, rot) | (rot << 7));
+tcg_out_dat_imm(s, cond, ARITH_SUB, rd, TCG_REG_PC,
+rotl(-diff, rot) | (rot << 7));
 return;
 }
 }
-- 
2.9.4




[Qemu-devel] [PULL 12/12] target/arm: Exit after clearing aarch64 interrupt mask

2017-06-19 Thread Richard Henderson
Exit to cpu loop so we reevaluate cpu_arm_hw_interrupts.

Tested-by: Emilio G. Cota 
Tested-by: Alex Bennée 
Reviewed-by: Emilio G. Cota 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 860e279..e55547d 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1422,7 +1422,9 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
 gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
 tcg_temp_free_i32(tcg_imm);
 tcg_temp_free_i32(tcg_op);
-s->is_jmp = DISAS_UPDATE;
+/* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs.  */
+gen_a64_set_pc_im(s->pc);
+s->is_jmp = (op == 0x1f ? DISAS_EXIT : DISAS_JUMP);
 break;
 }
 default:
@@ -11369,6 +11371,9 @@ void gen_intermediate_code_a64(ARMCPU *cpu, 
TranslationBlock *tb)
 case DISAS_JUMP:
 tcg_gen_lookup_and_goto_ptr(cpu_pc);
 break;
+case DISAS_EXIT:
+tcg_gen_exit_tb(0);
+break;
 case DISAS_TB_JUMP:
 case DISAS_EXC:
 case DISAS_SWI:
-- 
2.9.4




[Qemu-devel] [PULL 10/12] target/alpha: Use tcg_gen_lookup_and_goto_ptr

2017-06-19 Thread Richard Henderson
Tested-by: Emilio G. Cota 
Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/alpha/translate.c | 27 ++-
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 7c45ae3..232af9e 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -84,6 +84,7 @@ typedef enum {
the PC (for whatever reason), so there's no need to do it again on
exiting the TB.  */
 EXIT_PC_UPDATED,
+EXIT_PC_UPDATED_NOCHAIN,
 
 /* We are exiting the TB, but have neither emitted a goto_tb, nor
updated the PC for the next instruction to be executed.  */
@@ -458,11 +459,17 @@ static bool in_superpage(DisasContext *ctx, int64_t addr)
 #endif
 }
 
+static bool use_exit_tb(DisasContext *ctx)
+{
+return ((ctx->tb->cflags & CF_LAST_IO)
+|| ctx->singlestep_enabled
+|| singlestep);
+}
+
 static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
 {
 /* Suppress goto_tb in the case of single-steping and IO.  */
-if ((ctx->tb->cflags & CF_LAST_IO)
-|| ctx->singlestep_enabled || singlestep) {
+if (unlikely(use_exit_tb(ctx))) {
 return false;
 }
 #ifndef CONFIG_USER_ONLY
@@ -1198,7 +1205,10 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int 
palcode)
 tcg_gen_andi_i64(tmp, ctx->ir[IR_A0], PS_INT_MASK);
 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, ps));
 tcg_temp_free(tmp);
-break;
+
+/* Allow interrupts to be recognized right away.  */
+tcg_gen_movi_i64(cpu_pc, ctx->pc);
+return EXIT_PC_UPDATED_NOCHAIN;
 
 case 0x36:
 /* RDPS */
@@ -1266,7 +1276,7 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int 
palcode)
need the page permissions check.  We'll see the existence of
the page when we create the TB, and we'll flush all TBs if
we change the PAL base register.  */
-if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) {
+if (!use_exit_tb(ctx)) {
 tcg_gen_goto_tb(0);
 tcg_gen_movi_i64(cpu_pc, entry);
 tcg_gen_exit_tb((uintptr_t)ctx->tb);
@@ -2686,7 +2696,8 @@ static ExitStatus translate_one(DisasContext *ctx, 
uint32_t insn)
 tcg_gen_andi_i64(tmp, vb, 1);
 tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, pal_mode));
 tcg_gen_andi_i64(cpu_pc, vb, ~3);
-ret = EXIT_PC_UPDATED;
+/* Allow interrupts to be recognized right away.  */
+ret = EXIT_PC_UPDATED_NOCHAIN;
 break;
 #else
 goto invalid_opc;
@@ -3010,6 +3021,12 @@ void gen_intermediate_code(CPUAlphaState *env, struct 
TranslationBlock *tb)
 tcg_gen_movi_i64(cpu_pc, ctx.pc);
 /* FALLTHRU */
 case EXIT_PC_UPDATED:
+if (!use_exit_tb()) {
+tcg_gen_lookup_and_goto_ptr(cpu_pc);
+break;
+}
+/* FALLTHRU */
+case EXIT_PC_UPDATED_NOCHAIN:
 if (ctx.singlestep_enabled) {
 gen_excp_1(EXCP_DEBUG, 0);
 } else {
-- 
2.9.4




[Qemu-devel] [PULL 09/12] tcg: Increase hit rate of lookup_tb_ptr

2017-06-19 Thread Richard Henderson
We can call tb_htable_lookup even when the tb_jmp_cache is completely
empty.  Therefore, un-nest most of the code dependent on tb != NULL
from the read from the cache.

This improves the hit rate of lookup_tb_ptr; for instance, when booting
and immediately shutting down debian-arm, the hit rate improves from
93.2% to 99.4%.

Reviewed-by: Alex Bennée 
Signed-off-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg-runtime.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/tcg-runtime.c b/tcg-runtime.c
index 7fa90ce..ec3a34e 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -149,23 +149,23 @@ void *HELPER(lookup_tb_ptr)(CPUArchState *env, 
target_ulong addr)
 CPUState *cpu = ENV_GET_CPU(env);
 TranslationBlock *tb;
 target_ulong cs_base, pc;
-uint32_t flags;
-
-tb = atomic_rcu_read(>tb_jmp_cache[tb_jmp_cache_hash_func(addr)]);
-if (likely(tb)) {
-cpu_get_tb_cpu_state(env, , _base, );
-if (likely(tb->pc == addr && tb->cs_base == cs_base &&
-   tb->flags == flags)) {
-goto found;
-}
+uint32_t flags, addr_hash;
+
+addr_hash = tb_jmp_cache_hash_func(addr);
+tb = atomic_rcu_read(>tb_jmp_cache[addr_hash]);
+cpu_get_tb_cpu_state(env, , _base, );
+
+if (unlikely(!(tb
+   && tb->pc == addr
+   && tb->cs_base == cs_base
+   && tb->flags == flags))) {
 tb = tb_htable_lookup(cpu, addr, cs_base, flags);
-if (likely(tb)) {
-atomic_set(>tb_jmp_cache[tb_jmp_cache_hash_func(addr)], tb);
-goto found;
+if (!tb) {
+return tcg_ctx.code_gen_epilogue;
 }
+atomic_set(>tb_jmp_cache[addr_hash], tb);
 }
-return tcg_ctx.code_gen_epilogue;
- found:
+
 qemu_log_mask_and_addr(CPU_LOG_EXEC, addr,
"Chain %p [%d: " TARGET_FMT_lx "] %s\n",
tb->tc_ptr, cpu->cpu_index, addr,
-- 
2.9.4




[Qemu-devel] [PULL 11/12] target/s390x: Exit after changing PSW mask

2017-06-19 Thread Richard Henderson
Exit to cpu loop so we reevaluate cpu_s390x_hw_interrupts.

Reviewed-by: Alex Bennée 
Signed-off-by: Richard Henderson 
---
 target/s390x/translate.c | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 8c055b7..6403542 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -1173,6 +1173,8 @@ typedef enum {
 /* We are exiting the TB, but have neither emitted a goto_tb, nor
updated the PC for the next instruction to be executed.  */
 EXIT_PC_STALE,
+/* We are exiting the TB to the main loop.  */
+EXIT_PC_STALE_NOCHAIN,
 /* We are ending the TB with a noreturn function call, e.g. longjmp.
No following code will be executed.  */
 EXIT_NORETURN,
@@ -3795,7 +3797,8 @@ static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
 {
 check_privileged(s);
 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
-return NO_EXIT;
+/* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
+return EXIT_PC_STALE_NOCHAIN;
 }
 
 static ExitStatus op_stap(DisasContext *s, DisasOps *o)
@@ -4038,7 +4041,9 @@ static ExitStatus op_stnosm(DisasContext *s, DisasOps *o)
 } else {
 tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
 }
-return NO_EXIT;
+
+/* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
+return EXIT_PC_STALE_NOCHAIN;
 }
 
 static ExitStatus op_stura(DisasContext *s, DisasOps *o)
@@ -5788,6 +5793,7 @@ void gen_intermediate_code(CPUS390XState *env, struct 
TranslationBlock *tb)
 case EXIT_NORETURN:
 break;
 case EXIT_PC_STALE:
+case EXIT_PC_STALE_NOCHAIN:
 update_psw_addr();
 /* FALLTHRU */
 case EXIT_PC_UPDATED:
@@ -5799,14 +5805,14 @@ void gen_intermediate_code(CPUS390XState *env, struct 
TranslationBlock *tb)
 /* Exit the TB, either by raising a debug exception or by return.  */
 if (do_debug) {
 gen_exception(EXCP_DEBUG);
-} else if (use_exit_tb()) {
+} else if (use_exit_tb() || status == EXIT_PC_STALE_NOCHAIN) {
 tcg_gen_exit_tb(0);
 } else {
 tcg_gen_lookup_and_goto_ptr(psw_addr);
 }
 break;
 default:
-abort();
+g_assert_not_reached();
 }
 
 gen_tb_end(tb, num_insns);
-- 
2.9.4




[Qemu-devel] [PULL 02/12] tcg: allocate TB structs before the corresponding translated code

2017-06-19 Thread Richard Henderson
From: "Emilio G. Cota" 

Allocating an arbitrarily-sized array of tbs results in either
(a) a lot of memory wasted or (b) unnecessary flushes of the code
cache when we run out of TB structs in the array.

An obvious solution would be to just malloc a TB struct when needed,
and keep the TB array as an array of pointers (recall that tb_find_pc()
needs the TB array to run in O(log n)).

Perhaps a better solution, which is implemented in this patch, is to
allocate TB's right before the translated code they describe. This
results in some memory waste due to padding to have code and TBs in
separate cache lines--for instance, I measured 4.7% of padding in the
used portion of code_gen_buffer when booting aarch64 Linux on a
host with 64-byte cache lines. However, it can allow for optimizations
in some host architectures, since TCG backends could safely assume that
the TB and the corresponding translated code are very close to each
other in memory. See this message by rth for a detailed explanation:

  https://lists.gnu.org/archive/html/qemu-devel/2017-03/msg05172.html
  Subject: Re: GSoC 2017 Proposal: TCG performance enhancements
  Message-ID: <1e67644b-4b30-887e-d329-1848e94c9...@twiddle.net>

Suggested-by: Richard Henderson 
Reviewed-by: Pranith Kumar 
Signed-off-by: Emilio G. Cota 
Message-Id: <1496790745-314-3-git-send-email-c...@braap.org>
[rth: Simplify the arithmetic in tcg_tb_alloc]
Signed-off-by: Richard Henderson 
---
 include/exec/tb-context.h |  3 ++-
 tcg/tcg.c | 20 
 tcg/tcg.h |  2 +-
 translate-all.c   | 39 ---
 4 files changed, 47 insertions(+), 17 deletions(-)

diff --git a/include/exec/tb-context.h b/include/exec/tb-context.h
index c7f17f2..25c2afe 100644
--- a/include/exec/tb-context.h
+++ b/include/exec/tb-context.h
@@ -31,8 +31,9 @@ typedef struct TBContext TBContext;
 
 struct TBContext {
 
-TranslationBlock *tbs;
+TranslationBlock **tbs;
 struct qht htable;
+size_t tbs_size;
 int nb_tbs;
 /* any access to the tbs or the page table must use this lock */
 QemuMutex tb_lock;
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 564292f..3559829 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -383,6 +383,26 @@ void tcg_context_init(TCGContext *s)
 }
 }
 
+/*
+ * Allocate TBs right before their corresponding translated code, making
+ * sure that TBs and code are on different cache lines.
+ */
+TranslationBlock *tcg_tb_alloc(TCGContext *s)
+{
+uintptr_t align = qemu_icache_linesize;
+TranslationBlock *tb;
+void *next;
+
+tb = (void *)ROUND_UP((uintptr_t)s->code_gen_ptr, align);
+next = (void *)ROUND_UP((uintptr_t)(tb + 1), align);
+
+if (unlikely(next > s->code_gen_highwater)) {
+return NULL;
+}
+s->code_gen_ptr = next;
+return tb;
+}
+
 void tcg_prologue_init(TCGContext *s)
 {
 size_t prologue_size, total_size;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 5ec48d1..9e37722 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -697,7 +697,6 @@ struct TCGContext {
here, because there's too much arithmetic throughout that relies
on addition and subtraction working on bytes.  Rely on the GCC
extension that allows arithmetic on void*.  */
-int code_gen_max_blocks;
 void *code_gen_prologue;
 void *code_gen_epilogue;
 void *code_gen_buffer;
@@ -756,6 +755,7 @@ static inline bool tcg_op_buf_full(void)
 /* tb_lock must be held for tcg_malloc_internal. */
 void *tcg_malloc_internal(TCGContext *s, int size);
 void tcg_pool_reset(TCGContext *s);
+TranslationBlock *tcg_tb_alloc(TCGContext *s);
 
 void tb_lock(void);
 void tb_unlock(void);
diff --git a/translate-all.c b/translate-all.c
index b3ee876..bb094ad 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -781,12 +781,13 @@ static inline void code_gen_alloc(size_t tb_size)
 exit(1);
 }
 
-/* Estimate a good size for the number of TBs we can support.  We
-   still haven't deducted the prologue from the buffer size here,
-   but that's minimal and won't affect the estimate much.  */
-tcg_ctx.code_gen_max_blocks
-= tcg_ctx.code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
-tcg_ctx.tb_ctx.tbs = g_new(TranslationBlock, tcg_ctx.code_gen_max_blocks);
+/* size this conservatively -- realloc later if needed */
+tcg_ctx.tb_ctx.tbs_size =
+tcg_ctx.code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE / 8;
+if (unlikely(!tcg_ctx.tb_ctx.tbs_size)) {
+tcg_ctx.tb_ctx.tbs_size = 64 * 1024;
+}
+tcg_ctx.tb_ctx.tbs = g_new(TranslationBlock *, tcg_ctx.tb_ctx.tbs_size);
 
 qemu_mutex_init(_ctx.tb_ctx.tb_lock);
 }
@@ -828,13 +829,20 @@ bool tcg_enabled(void)
 static TranslationBlock *tb_alloc(target_ulong pc)
 {
 TranslationBlock *tb;
+TBContext *ctx;
 
 assert_tb_locked();
 
-if (tcg_ctx.tb_ctx.nb_tbs >= 

[Qemu-devel] [PULL 08/12] tcg/arm: Use ldr (literal) for goto_tb

2017-06-19 Thread Richard Henderson
The new placement of the TB means that we can use one insn
to load the goto_tb destination directly from the TB.

Signed-off-by: Richard Henderson 
---
 tcg/arm/tcg-target.inc.c | 23 ++-
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index 42370e5..d1793ec 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -1669,14 +1669,27 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 }
 break;
 case INDEX_op_goto_tb:
-tcg_debug_assert(s->tb_jmp_insn_offset == 0);
 {
 /* Indirect jump method */
-intptr_t ptr = (intptr_t)(s->tb_jmp_target_addr + args[0]);
-tcg_out_movi32(s, COND_AL, TCG_REG_R0, ptr & ~0xfff);
-tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, ptr & 0xfff);
+intptr_t ptr, dif, dil;
+TCGReg base = TCG_REG_PC;
+
+tcg_debug_assert(s->tb_jmp_insn_offset == 0);
+ptr = (intptr_t)(s->tb_jmp_target_addr + args[0]);
+dif = ptr - ((intptr_t)s->code_ptr + 8);
+dil = sextract32(dif, 0, 12);
+if (dif != dil) {
+/* The TB is close, but outside the 12 bits addressable by
+   the load.  We can extend this to 20 bits with a sub of a
+   shifted immediate from pc.  In the vastly unlikely event
+   the code requires more than 1MB, we'll use 2 insns and
+   be no worse off.  */
+base = TCG_REG_R0;
+tcg_out_movi32(s, COND_AL, base, ptr - dil);
+}
+tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, base, dil);
+s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
 }
-s->tb_jmp_reset_offset[args[0]] = tcg_current_code_size(s);
 break;
 case INDEX_op_goto_ptr:
 tcg_out_bx(s, COND_AL, args[0]);
-- 
2.9.4




[Qemu-devel] [PULL 01/12] util: add cacheinfo

2017-06-19 Thread Richard Henderson
From: "Emilio G. Cota" 

Add helpers to gather cache info from the host at init-time.

For now, only export the host's I/D cache line sizes, which we
will use to improve cache locality to avoid false sharing.

Suggested-by: Richard Henderson 
Suggested-by: Geert Martin Ijewski 
Tested-by:Geert Martin Ijewski 
Signed-off-by: Emilio G. Cota 
Message-Id: <1496794624-4083-1-git-send-email-c...@braap.org>
[rth: Move all implementations from tcg/ppc/]
Signed-off-by: Richard Henderson 
---
 include/qemu/osdep.h |   3 +
 tcg/ppc/tcg-target.inc.c |  71 +-
 util/Makefile.objs   |   1 +
 util/cacheinfo.c | 185 +++
 4 files changed, 191 insertions(+), 69 deletions(-)
 create mode 100644 util/cacheinfo.c

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index fb008a2..8559634 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -483,4 +483,7 @@ char *qemu_get_pid_name(pid_t pid);
  */
 pid_t qemu_fork(Error **errp);
 
+extern int qemu_icache_linesize;
+extern int qemu_dcache_linesize;
+
 #endif
diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
index 8d50f18..1f690df 100644
--- a/tcg/ppc/tcg-target.inc.c
+++ b/tcg/ppc/tcg-target.inc.c
@@ -2820,14 +2820,11 @@ void tcg_register_jit(void *buf, size_t buf_size)
 }
 #endif /* __ELF__ */
 
-static size_t dcache_bsize = 16;
-static size_t icache_bsize = 16;
-
 void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
 uintptr_t p, start1, stop1;
-size_t dsize = dcache_bsize;
-size_t isize = icache_bsize;
+size_t dsize = qemu_dcache_linesize;
+size_t isize = qemu_icache_linesize;
 
 start1 = start & ~(dsize - 1);
 stop1 = (stop + dsize - 1) & ~(dsize - 1);
@@ -2844,67 +2841,3 @@ void flush_icache_range(uintptr_t start, uintptr_t stop)
 asm volatile ("sync" : : : "memory");
 asm volatile ("isync" : : : "memory");
 }
-
-#if defined _AIX
-#include 
-
-static void __attribute__((constructor)) tcg_cache_init(void)
-{
-icache_bsize = _system_configuration.icache_line;
-dcache_bsize = _system_configuration.dcache_line;
-}
-
-#elif defined __linux__
-static void __attribute__((constructor)) tcg_cache_init(void)
-{
-unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
-unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
-
-if (dsize == 0 || isize == 0) {
-if (dsize == 0) {
-fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
-}
-if (isize == 0) {
-fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
-}
-exit(1);
-}
-dcache_bsize = dsize;
-icache_bsize = isize;
-}
-
-#elif defined __APPLE__
-#include 
-
-static void __attribute__((constructor)) tcg_cache_init(void)
-{
-size_t len;
-unsigned cacheline;
-int name[2] = { CTL_HW, HW_CACHELINE };
-
-len = sizeof(cacheline);
-if (sysctl(name, 2, , , NULL, 0)) {
-perror("sysctl CTL_HW HW_CACHELINE failed");
-exit(1);
-}
-dcache_bsize = cacheline;
-icache_bsize = cacheline;
-}
-
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include 
-
-static void __attribute__((constructor)) tcg_cache_init(void)
-{
-size_t len = 4;
-unsigned cacheline;
-
-if (sysctlbyname ("machdep.cacheline_size", , , NULL, 0)) {
-fprintf(stderr, "sysctlbyname machdep.cacheline_size failed: %s\n",
-strerror(errno));
-exit(1);
-}
-dcache_bsize = cacheline;
-icache_bsize = cacheline;
-}
-#endif
diff --git a/util/Makefile.objs b/util/Makefile.objs
index c6205eb..94d9477 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -20,6 +20,7 @@ util-obj-y += host-utils.o
 util-obj-y += bitmap.o bitops.o hbitmap.o
 util-obj-y += fifo8.o
 util-obj-y += acl.o
+util-obj-y += cacheinfo.o
 util-obj-y += error.o qemu-error.o
 util-obj-y += id.o
 util-obj-y += iov.o qemu-config.o qemu-sockets.o uri.o notify.o
diff --git a/util/cacheinfo.c b/util/cacheinfo.c
new file mode 100644
index 000..f987522
--- /dev/null
+++ b/util/cacheinfo.c
@@ -0,0 +1,185 @@
+/*
+ * cacheinfo.c - helpers to query the host about its caches
+ *
+ * Copyright (C) 2017, Emilio G. Cota 
+ * License: GNU GPL, version 2 or later.
+ *   See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+int qemu_icache_linesize = 0;
+int qemu_dcache_linesize = 0;
+
+/*
+ * Operating system specific detection mechanisms.
+ */
+
+#if defined(_AIX)
+# include 
+
+static void sys_cache_info(int *isize, int *dsize)
+{
+*isize = _system_configuration.icache_line;
+*dsize = _system_configuration.dcache_line;
+}
+
+#elif defined(_WIN32)
+
+static void sys_cache_info(int *isize, int *dsize)
+{
+SYSTEM_LOGICAL_PROCESSOR_INFORMATION *buf;
+DWORD size = 0;
+BOOL success;
+size_t i, n;
+
+/* Check 

[Qemu-devel] [PULL 06/12] tcg/arm: Remove limit on code buffer size

2017-06-19 Thread Richard Henderson
Since we're no longer using a direct branch, we have no
limit on the branch distance.

Signed-off-by: Richard Henderson 
---
 translate-all.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/translate-all.c b/translate-all.c
index 46c5592..d4f364d 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -523,8 +523,6 @@ static inline PageDesc *page_find(tb_page_addr_t index)
 # define MAX_CODE_GEN_BUFFER_SIZE  (32u * 1024 * 1024)
 #elif defined(__aarch64__)
 # define MAX_CODE_GEN_BUFFER_SIZE  (128ul * 1024 * 1024)
-#elif defined(__arm__)
-# define MAX_CODE_GEN_BUFFER_SIZE  (16u * 1024 * 1024)
 #elif defined(__s390x__)
   /* We have a +- 4GB range on the branches; leave some slop.  */
 # define MAX_CODE_GEN_BUFFER_SIZE  (3ul * 1024 * 1024 * 1024)
-- 
2.9.4




[Qemu-devel] [PULL 04/12] tcg/aarch64: Use ADR in tcg_out_movi

2017-06-19 Thread Richard Henderson
The new placement of the TB means that we can use one insn
to load the return value for exit_tb returning the TB pointer.

Tested-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 tcg/aarch64/tcg-target.inc.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 5f18545..1fa3bcc 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -616,7 +616,12 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 /* Look for host pointer values within 4G of the PC.  This happens
often when loading pointers to QEMU's own data structures.  */
 if (type == TCG_TYPE_I64) {
-tcg_target_long disp = (value >> 12) - ((intptr_t)s->code_ptr >> 12);
+tcg_target_long disp = value - (intptr_t)s->code_ptr;
+if (disp == sextract64(disp, 0, 21)) {
+tcg_out_insn(s, 3406, ADR, rd, disp);
+return;
+}
+disp = (value >> 12) - ((intptr_t)s->code_ptr >> 12);
 if (disp == sextract64(disp, 0, 21)) {
 tcg_out_insn(s, 3406, ADRP, rd, disp);
 if (value & 0xfff) {
-- 
2.9.4




[Qemu-devel] [PULL 00/12] TCG queued patches

2017-06-19 Thread Richard Henderson
This contains Emilio's moving the TB struct into code_gen_buffer,
my taking advantage of that in the aa64 and aa32 tcg backends,
and the communal fixes for the goto_ptr hangs.

I've droppped the target/mips goto_ptr patch from Paolo, as Aurelien
has said he'd come up with a more complete fix.

I've dropped the "-accel tcg,thread=*" fix as it is apparently also
in Paolo's misc patches tree.


r~


The following changes since commit cef8fd68364ad754d4f0050a215376cdf0ec744a:

  Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20170614-1' into 
staging (2017-06-19 17:54:30 +0100)

are available in the git repository at:

  git://github.com/rth7680/qemu.git tags/pull-tcg-20170619

for you to fetch changes up to 8da54b2507c1cabf60c2de904cf0383b23239231:

  target/arm: Exit after clearing aarch64 interrupt mask (2017-06-19 11:11:26 
-0700)


Queued TCG patches


Emilio G. Cota (3):
  util: add cacheinfo
  tcg: allocate TB structs before the corresponding translated code
  translate-all: consolidate tb init in tb_gen_code

Richard Henderson (9):
  tcg/aarch64: Use ADR in tcg_out_movi
  tcg/arm: Use indirect branch for goto_tb
  tcg/arm: Remove limit on code buffer size
  tcg/arm: Try pc-relative addresses for movi
  tcg/arm: Use ldr (literal) for goto_tb
  tcg: Increase hit rate of lookup_tb_ptr
  target/alpha: Use tcg_gen_lookup_and_goto_ptr
  target/s390x: Exit after changing PSW mask
  target/arm: Exit after clearing aarch64 interrupt mask

 include/exec/exec-all.h  |   5 +-
 include/exec/tb-context.h|   3 +-
 include/qemu/osdep.h |   3 +
 target/alpha/translate.c |  27 +--
 target/arm/translate-a64.c   |   7 +-
 target/s390x/translate.c |  14 +++-
 tcg-runtime.c|  28 +++
 tcg/aarch64/tcg-target.inc.c |   7 +-
 tcg/arm/tcg-target.inc.c |  78 ++
 tcg/ppc/tcg-target.inc.c |  71 +
 tcg/tcg.c|  20 +
 tcg/tcg.h|   2 +-
 translate-all.c  |  46 ++-
 util/Makefile.objs   |   1 +
 util/cacheinfo.c | 185 +++
 15 files changed, 345 insertions(+), 152 deletions(-)
 create mode 100644 util/cacheinfo.c



[Qemu-devel] [PULL 03/12] translate-all: consolidate tb init in tb_gen_code

2017-06-19 Thread Richard Henderson
From: "Emilio G. Cota" 

We are partially initializing tb in tb_alloc. Instead, fully
initialize it in tb_gen_code, which is tb_alloc's only caller.

This saves an unnecessary write to tb->cflags.

Signed-off-by: Emilio G. Cota 
Message-Id: <1497038122-26364-1-git-send-email-c...@braap.org>
Signed-off-by: Richard Henderson 
---
 translate-all.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/translate-all.c b/translate-all.c
index bb094ad..46c5592 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -843,9 +843,6 @@ static TranslationBlock *tb_alloc(target_ulong pc)
 ctx->tbs = g_renew(TranslationBlock *, ctx->tbs, ctx->tbs_size);
 }
 ctx->tbs[ctx->nb_tbs++] = tb;
-tb->pc = pc;
-tb->cflags = 0;
-tb->invalid = false;
 return tb;
 }
 
@@ -1289,9 +1286,11 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 
 gen_code_buf = tcg_ctx.code_gen_ptr;
 tb->tc_ptr = gen_code_buf;
+tb->pc = pc;
 tb->cs_base = cs_base;
 tb->flags = flags;
 tb->cflags = cflags;
+tb->invalid = false;
 
 #ifdef CONFIG_PROFILER
 tcg_ctx.tb_count1++; /* includes aborted translations because of
-- 
2.9.4




[Qemu-devel] [PULL 05/12] tcg/arm: Use indirect branch for goto_tb

2017-06-19 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 include/exec/exec-all.h  |  5 +
 tcg/arm/tcg-target.inc.c | 17 ++---
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 87ae10b..724ec73 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -301,7 +301,7 @@ static inline void 
tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
 #define CODE_GEN_AVG_BLOCK_SIZE 150
 #endif
 
-#if defined(__arm__) || defined(_ARCH_PPC) \
+#if defined(_ARCH_PPC) \
 || defined(__x86_64__) || defined(__i386__) \
 || defined(__sparc__) || defined(__aarch64__) \
 || defined(__s390x__) || defined(__mips__) \
@@ -401,9 +401,6 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, 
uintptr_t addr)
 #elif defined(__aarch64__)
 void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
 #define tb_set_jmp_target1 aarch64_tb_set_jmp_target
-#elif defined(__arm__)
-void arm_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
-#define tb_set_jmp_target1 arm_tb_set_jmp_target
 #elif defined(__sparc__) || defined(__mips__)
 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
 #else
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index 9f5cb66..fce382f 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -1026,16 +1026,6 @@ static void tcg_out_call(TCGContext *s, tcg_insn_unit 
*addr)
 }
 }
 
-void arm_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)
-{
-tcg_insn_unit *code_ptr = (tcg_insn_unit *)jmp_addr;
-tcg_insn_unit *target = (tcg_insn_unit *)addr;
-
-/* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
-reloc_pc24_atomic(code_ptr, target);
-flush_icache_range(jmp_addr, jmp_addr + 4);
-}
-
 static inline void tcg_out_goto_label(TCGContext *s, int cond, TCGLabel *l)
 {
 if (l->has_value) {
@@ -1665,11 +1655,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 }
 break;
 case INDEX_op_goto_tb:
-if (s->tb_jmp_insn_offset) {
-/* Direct jump method */
-s->tb_jmp_insn_offset[args[0]] = tcg_current_code_size(s);
-tcg_out_b_noaddr(s, COND_AL);
-} else {
+tcg_debug_assert(s->tb_jmp_insn_offset == 0);
+{
 /* Indirect jump method */
 intptr_t ptr = (intptr_t)(s->tb_jmp_target_addr + args[0]);
 tcg_out_movi32(s, COND_AL, TCG_REG_R0, ptr & ~0xfff);
-- 
2.9.4




[Qemu-devel] [PATCH] ui: Remove inclusion of "hw/qdev.h"

2017-06-19 Thread Thomas Huth
Looks like #include "hw/qdev.h" is not needed here, so remove it.

Signed-off-by: Thomas Huth 
---
 ui/input.c | 1 -
 ui/vnc.c   | 1 -
 2 files changed, 2 deletions(-)

diff --git a/ui/input.c b/ui/input.c
index 290ca9f..2abd46d 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -1,5 +1,4 @@
 #include "qemu/osdep.h"
-#include "hw/qdev.h"
 #include "sysemu/sysemu.h"
 #include "qapi-types.h"
 #include "qemu/error-report.h"
diff --git a/ui/vnc.c b/ui/vnc.c
index 47b49c7..26136f5 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -28,7 +28,6 @@
 #include "vnc.h"
 #include "vnc-jobs.h"
 #include "trace.h"
-#include "hw/qdev.h"
 #include "sysemu/sysemu.h"
 #include "qemu/error-report.h"
 #include "qemu/sockets.h"
-- 
1.8.3.1




[Qemu-devel] [PATCH v9 13/20] qcow2: add support for LUKS encryption format

2017-06-19 Thread Daniel P. Berrange
This adds support for using LUKS as an encryption format
with the qcow2 file, using the new encrypt.format parameter
to request "luks" format. e.g.

  # qemu-img create --object secret,data=123456,id=sec0 \
   -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec0 \
   test.qcow2 10G

The legacy "encryption=on" parameter still results in
creation of the old qcow2 AES format (and is equivalent
to the new 'encryption-format=aes'). e.g. the following are
equivalent:

  # qemu-img create --object secret,data=123456,id=sec0 \
   -f qcow2 -o encryption=on,encrypt.key-secret=sec0 \
   test.qcow2 10G

 # qemu-img create --object secret,data=123456,id=sec0 \
   -f qcow2 -o encryption-format=aes,encrypt.key-secret=sec0 \
   test.qcow2 10G

With the LUKS format it is necessary to store the LUKS
partition header and key material in the QCow2 file. This
data can be many MB in size, so cannot go into the QCow2
header region directly. Thus the spec defines a FDE
(Full Disk Encryption) header extension that specifies
the offset of a set of clusters to hold the FDE headers,
as well as the length of that region. The LUKS header is
thus stored in these extra allocated clusters before the
main image payload.

Aside from all the cryptographic differences implied by
use of the LUKS format, there is one further key difference
between the use of legacy AES and LUKS encryption in qcow2.
For LUKS, the initialiazation vectors are generated using
the host physical sector as the input, rather than the
guest virtual sector. This guarantees unique initialization
vectors for all sectors when qcow2 internal snapshots are
used, thus giving stronger protection against watermarking
attacks.

Reviewed-by: Eric Blake 
Reviewed-by: Alberto Garcia 
Signed-off-by: Daniel P. Berrange 
---
 block/qcow2-cluster.c  |   4 +-
 block/qcow2-refcount.c |  10 ++
 block/qcow2.c  | 268 ++--
 block/qcow2.h  |   9 ++
 qapi/block-core.json   |   5 +-
 tests/qemu-iotests/082.out | 270 -
 6 files changed, 478 insertions(+), 88 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index c4a256d..edec6a7 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -395,7 +395,9 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
 
 if (bs->encrypted) {
 Error *err = NULL;
-int64_t sector = (src_cluster_offset + offset_in_cluster)
+int64_t sector = (s->crypt_physical_offset ?
+  (cluster_offset + offset_in_cluster) :
+  (src_cluster_offset + offset_in_cluster))
  >> BDRV_SECTOR_BITS;
 assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
 assert((bytes & ~BDRV_SECTOR_MASK) == 0);
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 7c06061..81c22e6 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1856,6 +1856,16 @@ static int calculate_refcounts(BlockDriverState *bs, 
BdrvCheckResult *res,
 return ret;
 }
 
+/* encryption */
+if (s->crypto_header.length) {
+ret = inc_refcounts(bs, res, refcount_table, nb_clusters,
+s->crypto_header.offset,
+s->crypto_header.length);
+if (ret < 0) {
+return ret;
+}
+}
+
 return check_refblocks(bs, res, fix, rebuild, refcount_table, nb_clusters);
 }
 
diff --git a/block/qcow2.c b/block/qcow2.c
index 9edd0a0..bb6e7c1 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -66,6 +66,7 @@ typedef struct {
 #define  QCOW2_EXT_MAGIC_END 0
 #define  QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
 #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
+#define  QCOW2_EXT_MAGIC_CRYPTO_HEADER 0x0537be77
 
 static int qcow2_probe(const uint8_t *buf, int buf_size, const char *filename)
 {
@@ -80,6 +81,86 @@ static int qcow2_probe(const uint8_t *buf, int buf_size, 
const char *filename)
 }
 
 
+static ssize_t qcow2_crypto_hdr_read_func(QCryptoBlock *block, size_t offset,
+  uint8_t *buf, size_t buflen,
+  void *opaque, Error **errp)
+{
+BlockDriverState *bs = opaque;
+BDRVQcow2State *s = bs->opaque;
+ssize_t ret;
+
+if ((offset + buflen) > s->crypto_header.length) {
+error_setg(errp, "Request for data outside of extension header");
+return -1;
+}
+
+ret = bdrv_pread(bs->file,
+ s->crypto_header.offset + offset, buf, buflen);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Could not read encryption header");
+return -1;
+}
+return ret;
+}
+
+
+static ssize_t qcow2_crypto_hdr_init_func(QCryptoBlock *block, size_t 
headerlen,
+  void *opaque, Error **errp)
+{
+  

[Qemu-devel] [PATCH v9 16/20] block: rip out all traces of password prompting

2017-06-19 Thread Daniel P. Berrange
Now that qcow & qcow2 are wired up to get encryption keys
via the QCryptoSecret object, nothing is relying on the
interactive prompting for passwords. All the code related
to password prompting can thus be ripped out.

Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Signed-off-by: Daniel P. Berrange 
---
 hmp.c | 31 -
 include/monitor/monitor.h |  7 -
 include/qemu/osdep.h  |  2 --
 monitor.c | 68 ---
 qapi-schema.json  | 10 +--
 qemu-img.c| 31 -
 qemu-io.c | 20 --
 qmp.c | 12 +
 util/oslib-posix.c| 66 -
 util/oslib-win32.c| 24 -
 10 files changed, 2 insertions(+), 269 deletions(-)

diff --git a/hmp.c b/hmp.c
index 8c72c58..435cb31 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1085,37 +1085,12 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
 g_free(data);
 }
 
-static void hmp_cont_cb(void *opaque, int err)
-{
-if (!err) {
-qmp_cont(NULL);
-}
-}
-
-static bool key_is_missing(const BlockInfo *bdev)
-{
-return (bdev->inserted && bdev->inserted->encryption_key_missing);
-}
-
 void hmp_cont(Monitor *mon, const QDict *qdict)
 {
-BlockInfoList *bdev_list, *bdev;
 Error *err = NULL;
 
-bdev_list = qmp_query_block(NULL);
-for (bdev = bdev_list; bdev; bdev = bdev->next) {
-if (key_is_missing(bdev->value)) {
-monitor_read_block_device_key(mon, bdev->value->device,
-  hmp_cont_cb, NULL);
-goto out;
-}
-}
-
 qmp_cont();
 hmp_handle_error(mon, );
-
-out:
-qapi_free_BlockInfoList(bdev_list);
 }
 
 void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
@@ -1738,12 +1713,6 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 qmp_blockdev_change_medium(true, device, false, NULL, target,
!!arg, arg, !!read_only, read_only_mode,
);
-if (err &&
-error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
-error_free(err);
-monitor_read_block_device_key(mon, device, NULL, NULL);
-return;
-}
 }
 
 hmp_handle_error(mon, );
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index d2b3aaf..83ea4a1 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -23,13 +23,6 @@ void monitor_cleanup(void);
 int monitor_suspend(Monitor *mon);
 void monitor_resume(Monitor *mon);
 
-int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
-BlockCompletionFunc *completion_cb,
-void *opaque);
-int monitor_read_block_device_key(Monitor *mon, const char *device,
-  BlockCompletionFunc *completion_cb,
-  void *opaque);
-
 int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
 int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp);
 
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index fb008a2..a5982ef 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -457,8 +457,6 @@ void qemu_set_tty_echo(int fd, bool echo);
 void os_mem_prealloc(int fd, char *area, size_t sz, int smp_cpus,
  Error **errp);
 
-int qemu_read_password(char *buf, int buf_size);
-
 /**
  * qemu_get_pid_name:
  * @pid: pid of a process
diff --git a/monitor.c b/monitor.c
index fcf4fad..7647291 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4123,74 +4123,6 @@ void monitor_cleanup(void)
 qemu_mutex_unlock(_lock);
 }
 
-static void bdrv_password_cb(void *opaque, const char *password,
- void *readline_opaque)
-{
-Monitor *mon = opaque;
-BlockDriverState *bs = readline_opaque;
-int ret = 0;
-Error *local_err = NULL;
-
-bdrv_add_key(bs, password, _err);
-if (local_err) {
-error_report_err(local_err);
-ret = -EPERM;
-}
-if (mon->password_completion_cb)
-mon->password_completion_cb(mon->password_opaque, ret);
-
-monitor_read_command(mon, 1);
-}
-
-int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
-BlockCompletionFunc *completion_cb,
-void *opaque)
-{
-int err;
-
-monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
-   bdrv_get_encrypted_filename(bs));
-
-mon->password_completion_cb = completion_cb;
-mon->password_opaque = opaque;
-
-err = monitor_read_password(mon, bdrv_password_cb, bs);
-
-if (err && completion_cb)
-completion_cb(opaque, err);
-
-return err;
-}
-
-int 

[Qemu-devel] [PATCH v9 19/20] qcow2: report encryption specific image information

2017-06-19 Thread Daniel P. Berrange
Currently 'qemu-img info' reports a simple "encrypted: yes"
field. This is not very useful now that qcow2 can support
multiple encryption formats. Users want to know which format
is in use and some data related to it.

Wire up usage of the qcrypto_block_get_info() method so that
'qemu-img info' can report about the encryption format
and parameters in use

  $ qemu-img create \
  --object secret,id=sec0,data=123456 \
  -o encrypt.format=luks,encrypt.key-secret=sec0 \
  -f qcow2 demo.qcow2 1G
  Formatting 'demo.qcow2', fmt=qcow2 size=1073741824 \
  encryption=off encrypt.format=luks encrypt.key-secret=sec0 \
  cluster_size=65536 lazy_refcounts=off refcount_bits=16

  $ qemu-img info demo.qcow2
  image: demo.qcow2
  file format: qcow2
  virtual size: 1.0G (1073741824 bytes)
  disk size: 480K
  encrypted: yes
  cluster_size: 65536
  Format specific information:
  compat: 1.1
  lazy refcounts: false
  refcount bits: 16
  encrypt:
  ivgen alg: plain64
  hash alg: sha256
  cipher alg: aes-256
  uuid: 3fa930c4-58c8-4ef7-b3c5-314bb5af21f3
  format: luks
  cipher mode: xts
  slots:
  [0]:
  active: true
  iters: 1839058
  key offset: 4096
  stripes: 4000
  [1]:
  active: false
  key offset: 262144
  [2]:
  active: false
  key offset: 520192
  [3]:
  active: false
  key offset: 778240
  [4]:
  active: false
  key offset: 1036288
  [5]:
  active: false
  key offset: 1294336
  [6]:
  active: false
  key offset: 1552384
  [7]:
  active: false
  key offset: 1810432
  payload offset: 2068480
  master key iters: 438487
  corrupt: false

With the legacy "AES" encryption we just report the format
name

  $ qemu-img create \
  --object secret,id=sec0,data=123456 \
  -o encrypt.format=aes,encrypt.key-secret=sec0 \
  -f qcow2 demo.qcow2 1G
  Formatting 'demo.qcow2', fmt=qcow2 size=1073741824 \
  encryption=off encrypt.format=aes encrypt.key-secret=sec0 \
  cluster_size=65536 lazy_refcounts=off refcount_bits=16

  $ ./qemu-img info demo.qcow2
  image: demo.qcow2
  file format: qcow2
  virtual size: 1.0G (1073741824 bytes)
  disk size: 196K
  encrypted: yes
  cluster_size: 65536
  Format specific information:
  compat: 1.1
  lazy refcounts: false
  refcount bits: 16
  encrypt:
  format: aes
  corrupt: false

Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Reviewed-by: Eric Blake 
Signed-off-by: Daniel P. Berrange 
---
 block/qcow2.c| 32 +++-
 qapi/block-core.json | 27 ++-
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 19bc69c..a9d0b55 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -3199,8 +3199,14 @@ static int qcow2_get_info(BlockDriverState *bs, 
BlockDriverInfo *bdi)
 static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs)
 {
 BDRVQcow2State *s = bs->opaque;
-ImageInfoSpecific *spec_info = g_new(ImageInfoSpecific, 1);
+ImageInfoSpecific *spec_info;
+QCryptoBlockInfo *encrypt_info = NULL;
 
+if (s->crypto != NULL) {
+encrypt_info = qcrypto_block_get_info(s->crypto, _abort);
+}
+
+spec_info = g_new(ImageInfoSpecific, 1);
 *spec_info = (ImageInfoSpecific){
 .type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
 .u.qcow2.data = g_new(ImageInfoSpecificQCow2, 1),
@@ -3227,6 +3233,30 @@ static ImageInfoSpecific 
*qcow2_get_specific_info(BlockDriverState *bs)
 assert(false);
 }
 
+if (encrypt_info) {
+ImageInfoSpecificQCow2Encryption *qencrypt =
+g_new(ImageInfoSpecificQCow2Encryption, 1);
+switch (encrypt_info->format) {
+case Q_CRYPTO_BLOCK_FORMAT_QCOW:
+qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_AES;
+qencrypt->u.aes = encrypt_info->u.qcow;
+break;
+case Q_CRYPTO_BLOCK_FORMAT_LUKS:
+qencrypt->format = BLOCKDEV_QCOW2_ENCRYPTION_FORMAT_LUKS;
+qencrypt->u.luks = encrypt_info->u.luks;
+break;
+default:
+abort();
+}
+/* Since we did shallow copy above, erase any pointers
+ * in the original info */
+memset(_info->u, 0, sizeof(encrypt_info->u));
+qapi_free_QCryptoBlockInfo(encrypt_info);
+
+spec_info->u.qcow2.data->has_encrypt = true;
+spec_info->u.qcow2.data->encrypt = qencrypt;
+}
+
 return spec_info;
 }
 
diff --git a/qapi/block-core.json 

[Qemu-devel] [PATCH v9 14/20] qcow2: add iotests to cover LUKS encryption support

2017-06-19 Thread Daniel P. Berrange
This extends the 087 iotest to cover LUKS encryption when doing
blockdev-add.

Two further tests are added to validate read/write of LUKS
encrypted images with a single file and with a backing file.

Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Signed-off-by: Daniel P. Berrange 
---
 tests/qemu-iotests/087 | 35 ++-
 tests/qemu-iotests/087.out | 14 +++-
 tests/qemu-iotests/188 | 76 
 tests/qemu-iotests/188.out | 18 ++
 tests/qemu-iotests/189 | 86 ++
 tests/qemu-iotests/189.out | 26 ++
 tests/qemu-iotests/group   |  2 ++
 7 files changed, 255 insertions(+), 2 deletions(-)
 create mode 100755 tests/qemu-iotests/188
 create mode 100644 tests/qemu-iotests/188.out
 create mode 100755 tests/qemu-iotests/189
 create mode 100644 tests/qemu-iotests/189.out

diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087
index 1d595b2..f8e4903 100755
--- a/tests/qemu-iotests/087
+++ b/tests/qemu-iotests/087
@@ -119,7 +119,7 @@ run_qemu .
+#
+
+# creator
+owner=berra...@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+
+size=16M
+
+SECRET="secret,id=sec0,data=astrochicken"
+SECRETALT="secret,id=sec0,data=platypus"
+
+_make_test_img --object $SECRET -o 
"encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10" $size
+
+IMGSPEC="driver=$IMGFMT,file.filename=$TEST_IMG,encrypt.key-secret=sec0"
+
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT
+
+echo
+echo "== reading whole image =="
+$QEMU_IO --object $SECRET -c "read -P 0 0 $size" --image-opts $IMGSPEC | 
_filter_qemu_io | _filter_testdir
+
+echo
+echo "== rewriting whole image =="
+$QEMU_IO --object $SECRET -c "write -P 0xa 0 $size" --image-opts $IMGSPEC | 
_filter_qemu_io | _filter_testdir
+
+echo
+echo "== verify pattern =="
+$QEMU_IO --object $SECRET -c "read -P 0xa 0 $size"  --image-opts $IMGSPEC | 
_filter_qemu_io | _filter_testdir
+
+echo
+echo "== verify open failure with wrong password =="
+$QEMU_IO --object $SECRETALT -c "read -P 0xa 0 $size" --image-opts $IMGSPEC | 
_filter_qemu_io | _filter_testdir
+
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/188.out b/tests/qemu-iotests/188.out
new file mode 100644
index 000..8af24e5
--- /dev/null
+++ b/tests/qemu-iotests/188.out
@@ -0,0 +1,18 @@
+QA output created by 188
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=16777216 encrypt.format=luks 
encrypt.key-secret=sec0 encrypt.iter-time=10
+
+== reading whole image ==
+read 16777216/16777216 bytes at offset 0
+16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== rewriting whole image ==
+wrote 16777216/16777216 bytes at offset 0
+16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify pattern ==
+read 16777216/16777216 bytes at offset 0
+16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== verify open failure with wrong password ==
+can't open: Invalid password, cannot unlock any keyslot
+*** done
diff --git a/tests/qemu-iotests/189 b/tests/qemu-iotests/189
new file mode 100755
index 000..54ad980
--- /dev/null
+++ b/tests/qemu-iotests/189
@@ -0,0 +1,86 @@
+#!/bin/bash
+#
+# Test encrypted read/write using backing files
+#
+# Copyright (C) 2017 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+
+# creator
+owner=berra...@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+
+size=16M
+TEST_IMG_BASE=$TEST_IMG.base
+SECRET0="secret,id=sec0,data=astrochicken"
+SECRET1="secret,id=sec1,data=furby"
+
+TEST_IMG_SAVE=$TEST_IMG
+TEST_IMG=$TEST_IMG_BASE
+echo "== create base =="
+_make_test_img --object $SECRET0 -o 

[Qemu-devel] [PATCH v9 12/20] qcow2: extend specification to cover LUKS encryption

2017-06-19 Thread Daniel P. Berrange
Update the qcow2 specification to describe how the LUKS header is
placed inside a qcow2 file, when using LUKS encryption for the
qcow2 payload instead of the legacy AES-CBC encryption

Reviewed-by: Eric Blake 
Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Signed-off-by: Daniel P. Berrange 
---
 docs/specs/qcow2.txt | 103 +++
 1 file changed, 103 insertions(+)

diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index 80cdfd0..886a546 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -45,6 +45,7 @@ The first cluster of a qcow2 image contains the file header:
  32 - 35:   crypt_method
 0 for no encryption
 1 for AES encryption
+2 for LUKS encryption
 
  36 - 39:   l1_size
 Number of entries in the active L1 table
@@ -135,6 +136,7 @@ be stored. Each extension has a structure like the 
following:
 0xE2792ACA - Backing file format name
 0x6803f857 - Feature name table
 0x23852875 - Bitmaps extension
+0x0537be77 - Full disk encryption header pointer
 other  - Unknown header extension, can be safely
  ignored
 
@@ -207,6 +209,107 @@ The fields of the bitmaps extension are:
Offset into the image file at which the bitmap directory
starts. Must be aligned to a cluster boundary.
 
+== Full disk encryption header pointer ==
+
+The full disk encryption header must be present if, and only if, the
+'crypt_method' header requires metadata. Currently this is only true
+of the 'LUKS' crypt method. The header extension must be absent for
+other methods.
+
+This header provides the offset at which the crypt method can store
+its additional data, as well as the length of such data.
+
+Byte  0 -  7:   Offset into the image file at which the encryption
+header starts in bytes. Must be aligned to a cluster
+boundary.
+Byte  8 - 15:   Length of the written encryption header in bytes.
+Note actual space allocated in the qcow2 file may
+be larger than this value, since it will be rounded
+to the nearest multiple of the cluster size. Any
+unused bytes in the allocated space will be initialized
+to 0.
+
+For the LUKS crypt method, the encryption header works as follows.
+
+The first 592 bytes of the header clusters will contain the LUKS
+partition header. This is then followed by the key material data areas.
+The size of the key material data areas is determined by the number of
+stripes in the key slot and key size. Refer to the LUKS format
+specification ('docs/on-disk-format.pdf' in the cryptsetup source
+package) for details of the LUKS partition header format.
+
+In the LUKS partition header, the "payload-offset" field will be
+calculated as normal for the LUKS spec. ie the size of the LUKS
+header, plus key material regions, plus padding, relative to the
+start of the LUKS header. This offset value is not required to be
+qcow2 cluster aligned. Its value is currently never used in the
+context of qcow2, since the qcow2 file format itself defines where
+the real payload offset is, but none the less a valid payload offset
+should always be present.
+
+In the LUKS key slots header, the "key-material-offset" is relative
+to the start of the LUKS header clusters in the qcow2 container,
+not the start of the qcow2 file.
+
+Logically the layout looks like
+
+  +-+
+  | QCow2 header|
+  | QCow2 header extension X|
+  | QCow2 header extension FDE  |
+  | QCow2 header extension ...  |
+  | QCow2 header extension Z|
+  +-+
+  | other QCow2 tables  |
+  . .
+  . .
+  +-+
+  | +-+ |
+  | | LUKS partition header   | |
+  | +-+ |
+  | | LUKS key material 1 | |
+  | +-+ |
+  | | LUKS key material 2 | |
+  | +-+ |
+  | | LUKS key material ...   | |
+  | +-+ |
+  | | LUKS key material 8 | |
+  | +-+ |
+  +-+
+  | QCow2 cluster payload   |
+  . .
+  . .
+  . .
+  | |
+  +-+
+
+== Data encryption ==
+
+When an encryption method is requested in the header, the image payload
+data must be encrypted/decrypted on every write/read. The image headers
+and metadata are never 

[Qemu-devel] [PATCH v9 15/20] iotests: enable tests 134 and 158 to work with qcow (v1)

2017-06-19 Thread Daniel P. Berrange
The 138 and 158 iotests exercise the legacy qcow2 aes encryption
code path and they work fine with qcow v1 too.

Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Signed-off-by: Daniel P. Berrange 
---
 tests/qemu-iotests/134 | 2 +-
 tests/qemu-iotests/158 | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134
index f851d92..9914415 100755
--- a/tests/qemu-iotests/134
+++ b/tests/qemu-iotests/134
@@ -37,7 +37,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.rc
 . ./common.filter
 
-_supported_fmt qcow2
+_supported_fmt qcow qcow2
 _supported_proto generic
 _unsupported_proto vxhs
 _supported_os Linux
diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158
index e280b79..823c120 100755
--- a/tests/qemu-iotests/158
+++ b/tests/qemu-iotests/158
@@ -37,7 +37,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
 . ./common.rc
 . ./common.filter
 
-_supported_fmt qcow2
+_supported_fmt qcow qcow2
 _supported_proto generic
 _unsupported_proto vxhs
 _supported_os Linux
-- 
2.9.3




[Qemu-devel] [PATCH v9 20/20] docs: document encryption options for qcow, qcow2 and luks

2017-06-19 Thread Daniel P. Berrange
Expand the image format docs to cover the new options for
the qcow, qcow2 and luks disk image formats

Reviewed-by: Alberto Garcia 
Reviewed-by: Eric Blake 
Signed-off-by: Daniel P. Berrange 
---
 qemu-doc.texi | 123 ++
 1 file changed, 115 insertions(+), 8 deletions(-)

diff --git a/qemu-doc.texi b/qemu-doc.texi
index 965ba59..3c3081f 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -541,10 +541,20 @@ File name of a base image (see @option{create} subcommand)
 @item backing_fmt
 Image format of the base image
 @item encryption
-If this option is set to @code{on}, the image is encrypted with 128-bit 
AES-CBC.
+This option is deprecated and equivalent to @code{encrypt.format=aes}
 
-The use of encryption in qcow and qcow2 images is considered to be flawed by
-modern cryptography standards, suffering from a number of design problems:
+@item encrypt.format
+
+If this is set to @code{luks}, it requests that the qcow2 payload (not
+qcow2 header) be encrypted using the LUKS format. The passphrase to
+use to unlock the LUKS key slot is given by the @code{encrypt.key-secret}
+parameter. LUKS encryption parameters can be tuned with the other
+@code{encrypt.*} parameters.
+
+If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
+The encryption key is given by the @code{encrypt.key-secret} parameter.
+This encryption format is considered to be flawed by modern cryptography
+standards, suffering from a number of design problems:
 
 @itemize @minus
 @item The AES-CBC cipher is used with predictable initialization vectors based
@@ -559,10 +569,45 @@ original file must then be securely erased using a 
program like shred,
 though even this is ineffective with many modern storage technologies.
 @end itemize
 
-Use of qcow / qcow2 encryption with QEMU is deprecated, and support for
-it will go away in a future release.  Users are recommended to use an
-alternative encryption technology such as the Linux dm-crypt / LUKS
-system.
+The use of this is no longer supported in system emulators. Support only
+remains in the command line utilities, for the purposes of data liberation
+and interoperability with old versions of QEMU. The @code{luks} format
+should be used instead.
+
+@item encrypt.key-secret
+
+Provides the ID of a @code{secret} object that contains the passphrase
+(@code{encrypt.format=luks}) or encryption key (@code{encrypt.format=aes}).
+
+@item encrypt.cipher-alg
+
+Name of the cipher algorithm and key length. Currently defaults
+to @code{aes-256}. Only used when @code{encrypt.format=luks}.
+
+@item encrypt.cipher-mode
+
+Name of the encryption mode to use. Currently defaults to @code{xts}.
+Only used when @code{encrypt.format=luks}.
+
+@item encrypt.ivgen-alg
+
+Name of the initialization vector generator algorithm. Currently defaults
+to @code{plain64}. Only used when @code{encrypt.format=luks}.
+
+@item encrypt.ivgen-hash-alg
+
+Name of the hash algorithm to use with the initialization vector generator
+(if required). Defaults to @code{sha256}. Only used when 
@code{encrypt.format=luks}.
+
+@item encrypt.hash-alg
+
+Name of the hash algorithm to use for PBKDF algorithm
+Defaults to @code{sha256}. Only used when @code{encrypt.format=luks}.
+
+@item encrypt.iter-time
+
+Amount of time, in milliseconds, to use for PBKDF algorithm per key slot.
+Defaults to @code{2000}. Only used when @code{encrypt.format=luks}.
 
 @item cluster_size
 Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster
@@ -637,7 +682,69 @@ Supported options:
 @item backing_file
 File name of a base image (see @option{create} subcommand)
 @item encryption
-If this option is set to @code{on}, the image is encrypted.
+This option is deprecated and equivalent to @code{encrypt.format=aes}
+
+@item encrypt.format
+If this is set to @code{aes}, the image is encrypted with 128-bit AES-CBC.
+The encryption key is given by the @code{encrypt.key-secret} parameter.
+This encryption format is considered to be flawed by modern cryptography
+standards, suffering from a number of design problems enumerated previously
+against the @code{qcow2} image format.
+
+The use of this is no longer supported in system emulators. Support only
+remains in the command line utilities, for the purposes of data liberation
+and interoperability with old versions of QEMU.
+
+Users requiring native encryption should use the @code{qcow2} format
+instead with @code{encrypt.format=luks}.
+
+@item encrypt.key-secret
+
+Provides the ID of a @code{secret} object that contains the encryption
+key (@code{encrypt.format=aes}).
+
+@end table
+
+@item luks
+
+LUKS v1 encryption format, compatible with Linux dm-crypt/cryptsetup
+
+Supported options:
+@table @code
+
+@item key-secret
+
+Provides the ID of a @code{secret} object that contains the passphrase.
+
+@item cipher-alg
+
+Name of the cipher algorithm and key length. Currently 

[Qemu-devel] [PATCH v9 11/20] qcow2: convert QCow2 to use QCryptoBlock for encryption

2017-06-19 Thread Daniel P. Berrange
This converts the qcow2 driver to make use of the QCryptoBlock
APIs for encrypting image content, using the legacy QCow2 AES
scheme.

With this change it is now required to use the QCryptoSecret
object for providing passwords, instead of the current block
password APIs / interactive prompting.

  $QEMU \
-object secret,id=sec0,filename=/home/berrange/encrypted.pw \
-drive file=/home/berrange/encrypted.qcow2,encrypt.key-secret=sec0

The test 087 could be simplified since there is no longer a
difference in behaviour when using blockdev_add with encrypted
images for the running vs stopped CPU state.

Reviewed-by: Alberto Garcia 
Reviewed-by: Eric Blake 
Signed-off-by: Daniel P. Berrange 
---
 block/qcow2-cluster.c  |  47 +-
 block/qcow2.c  | 226 ++---
 block/qcow2.h  |   5 +-
 qapi/block-core.json   |  27 +-
 tests/qemu-iotests/049 |   2 +-
 tests/qemu-iotests/049.out |   4 +-
 tests/qemu-iotests/082.out |  27 ++
 tests/qemu-iotests/087 |  28 +++---
 tests/qemu-iotests/087.out |  12 +--
 tests/qemu-iotests/134 |  18 +++-
 tests/qemu-iotests/134.out |  10 +-
 tests/qemu-iotests/158 |  19 ++--
 tests/qemu-iotests/158.out |  14 +--
 tests/qemu-iotests/common  |  10 +-
 14 files changed, 263 insertions(+), 186 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 6400147..c4a256d 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -357,47 +357,6 @@ static int count_contiguous_clusters_unallocated(int 
nb_clusters,
 return i;
 }
 
-/* The crypt function is compatible with the linux cryptoloop
-   algorithm for < 4 GB images. */
-int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
-  uint8_t *buf, int nb_sectors, bool enc,
-  Error **errp)
-{
-union {
-uint64_t ll[2];
-uint8_t b[16];
-} ivec;
-int i;
-int ret;
-
-for(i = 0; i < nb_sectors; i++) {
-ivec.ll[0] = cpu_to_le64(sector_num);
-ivec.ll[1] = 0;
-if (qcrypto_cipher_setiv(s->cipher,
- ivec.b, G_N_ELEMENTS(ivec.b),
- errp) < 0) {
-return -1;
-}
-if (enc) {
-ret = qcrypto_cipher_encrypt(s->cipher,
- buf, buf,
- 512,
- errp);
-} else {
-ret = qcrypto_cipher_decrypt(s->cipher,
- buf, buf,
- 512,
- errp);
-}
-if (ret < 0) {
-return -1;
-}
-sector_num++;
-buf += 512;
-}
-return 0;
-}
-
 static int coroutine_fn do_perform_cow(BlockDriverState *bs,
uint64_t src_cluster_offset,
uint64_t cluster_offset,
@@ -438,11 +397,11 @@ static int coroutine_fn do_perform_cow(BlockDriverState 
*bs,
 Error *err = NULL;
 int64_t sector = (src_cluster_offset + offset_in_cluster)
  >> BDRV_SECTOR_BITS;
-assert(s->cipher);
 assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
 assert((bytes & ~BDRV_SECTOR_MASK) == 0);
-if (qcow2_encrypt_sectors(s, sector, iov.iov_base,
-  bytes >> BDRV_SECTOR_BITS, true, ) < 0) {
+assert(s->crypto);
+if (qcrypto_block_encrypt(s->crypto, sector, iov.iov_base,
+  bytes, ) < 0) {
 ret = -EIO;
 error_free(err);
 goto out;
diff --git a/block/qcow2.c b/block/qcow2.c
index b985ba7..9edd0a0 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -37,6 +37,9 @@
 #include "qemu/option_int.h"
 #include "qemu/cutils.h"
 #include "qemu/bswap.h"
+#include "qapi/opts-visitor.h"
+#include "qapi-visit.h"
+#include "block/crypto.h"
 
 /*
   Differences with QCOW:
@@ -461,6 +464,7 @@ static QemuOptsList qcow2_runtime_opts = {
 .type = QEMU_OPT_NUMBER,
 .help = "Clean unused cache entries after this time (in seconds)",
 },
+BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET("encrypt."),
 { /* end of list */ }
 },
 };
@@ -585,6 +589,7 @@ typedef struct Qcow2ReopenState {
 int overlap_check;
 bool discard_passthrough[QCOW2_DISCARD_MAX];
 uint64_t cache_clean_interval;
+QCryptoBlockOpenOptions *crypto_opts; /* Disk encryption runtime options */
 } Qcow2ReopenState;
 
 static int qcow2_update_options_prepare(BlockDriverState *bs,
@@ -598,9 +603,14 @@ static int qcow2_update_options_prepare(BlockDriverState 
*bs,
 int overlap_check_template = 0;
 uint64_t l2_cache_size, refcount_cache_size;
 int i;
+const 

[Qemu-devel] [PATCH v9 09/20] qcow: convert QCow to use QCryptoBlock for encryption

2017-06-19 Thread Daniel P. Berrange
This converts the qcow driver to make use of the QCryptoBlock
APIs for encrypting image content. This is only wired up to
permit use of the legacy QCow encryption format. Users who wish
to have the strong LUKS format should switch to qcow2 instead.

With this change it is now required to use the QCryptoSecret
object for providing passwords, instead of the current block
password APIs / interactive prompting.

  $QEMU \
-object secret,id=sec0,filename=/home/berrange/encrypted.pw \
-drive file=/home/berrange/encrypted.qcow,encrypt.format=qcow,\
   encrypt.key-secret=sec0

Though note that running QEMU system emulators with the AES
encryption is no longer supported, so while the above syntax
is valid, QEMU will refuse to actually run the VM in this
particular example.

Likewise when creating images with the legacy AES-CBC format

  qemu-img create -f qcow \
--object secret,id=sec0,filename=/home/berrange/encrypted.pw \
-o encrypt.format=aes,encrypt.key-secret=sec0 \
/home/berrange/encrypted.qcow 64M

Reviewed-by: Alberto Garcia 
Reviewed-by: Eric Blake 
Signed-off-by: Daniel P. Berrange 
---
 block/crypto.c   |  10 +++
 block/crypto.h   |  20 --
 block/qcow.c | 198 +--
 qapi/block-core.json |  38 +-
 4 files changed, 158 insertions(+), 108 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index 9df1e5d..da4be74 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -181,6 +181,11 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
 v, >u.luks, _err);
 break;
 
+case Q_CRYPTO_BLOCK_FORMAT_QCOW:
+visit_type_QCryptoBlockOptionsQCow_members(
+v, >u.qcow, _err);
+break;
+
 default:
 error_setg(_err, "Unsupported block format %d", format);
 break;
@@ -227,6 +232,11 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
 v, >u.luks, _err);
 break;
 
+case Q_CRYPTO_BLOCK_FORMAT_QCOW:
+visit_type_QCryptoBlockOptionsQCow_members(
+v, >u.qcow, _err);
+break;
+
 default:
 error_setg(_err, "Unsupported block format %d", format);
 break;
diff --git a/block/crypto.h b/block/crypto.h
index 3430dcd..0f985ea 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -21,6 +21,19 @@
 #ifndef BLOCK_CRYPTO_H__
 #define BLOCK_CRYPTO_H__
 
+#define BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, helpstr)\
+{   \
+.name = prefix BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET,\
+.type = QEMU_OPT_STRING,\
+.help = helpstr,\
+}
+
+#define BLOCK_CRYPTO_OPT_QCOW_KEY_SECRET "key-secret"
+
+#define BLOCK_CRYPTO_OPT_DEF_QCOW_KEY_SECRET(prefix)\
+BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \
+"ID of the secret that provides the AES encryption key")
+
 #define BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET "key-secret"
 #define BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG "cipher-alg"
 #define BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE "cipher-mode"
@@ -30,11 +43,8 @@
 #define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
 
 #define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix)\
-{   \
-.name = prefix BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,\
-.type = QEMU_OPT_STRING,\
-.help = "ID of the secret that provides the keyslot passphrase", \
-}
+BLOCK_CRYPTO_OPT_DEF_KEY_SECRET(prefix, \
+"ID of the secret that provides the keyslot passphrase")
 
 #define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(prefix)   \
 {  \
diff --git a/block/qcow.c b/block/qcow.c
index 2306e4f..3dca60c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -31,8 +31,10 @@
 #include "qemu/bswap.h"
 #include 
 #include "qapi/qmp/qerror.h"
-#include "crypto/cipher.h"
+#include "qapi/qmp/qstring.h"
+#include "crypto/block.h"
 #include "migration/blocker.h"
+#include "block/crypto.h"
 
 /**/
 /* QEMU COW block driver with compression and encryption support */
@@ -77,7 +79,7 @@ typedef struct BDRVQcowState {
 uint8_t *cluster_cache;
 uint8_t *cluster_data;
 uint64_t cluster_cache_offset;
-QCryptoCipher *cipher; /* NULL if no key yet */
+QCryptoBlock *crypto; /* Disk encryption format driver */
 uint32_t crypt_method_header;
 CoMutex lock;
 Error *migration_blocker;
@@ -97,6 +99,15 @@ static int qcow_probe(const uint8_t *buf, int buf_size, 
const char *filename)
 return 0;
 }
 
+static QemuOptsList qcow_runtime_opts = 

[Qemu-devel] [PATCH v9 17/20] block: remove all encryption handling APIs

2017-06-19 Thread Daniel P. Berrange
Now that all encryption keys must be provided upfront via
the QCryptoSecret API and associated block driver properties
there is no need for any explicit encryption handling APIs
in the block layer. Encryption can be handled transparently
within the block driver. We only retain an API for querying
whether an image is encrypted or not, since that is a
potentially useful piece of metadata to report to the user.

Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Signed-off-by: Daniel P. Berrange 
---
 block.c   | 77 +--
 block/crypto.c|  1 -
 block/qapi.c  |  2 +-
 block/qcow.c  |  8 -
 block/qcow2.c |  1 -
 blockdev.c| 37 ++-
 hmp-commands.hx   |  2 ++
 include/block/block.h |  3 --
 include/block/block_int.h |  1 -
 include/qapi/error.h  |  1 -
 qapi/block-core.json  | 37 ++-
 qapi/common.json  |  5 +--
 12 files changed, 16 insertions(+), 159 deletions(-)

diff --git a/block.c b/block.c
index fa1d06d..440649c 100644
--- a/block.c
+++ b/block.c
@@ -2569,15 +2569,7 @@ static BlockDriverState *bdrv_open_inherit(const char 
*filename,
 goto close_and_fail;
 }
 
-if (!bdrv_key_required(bs)) {
-bdrv_parent_cb_change_media(bs, true);
-} else if (!runstate_check(RUN_STATE_PRELAUNCH)
-   && !runstate_check(RUN_STATE_INMIGRATE)
-   && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
-error_setg(errp,
-   "Guest must be stopped for opening of encrypted image");
-goto close_and_fail;
-}
+bdrv_parent_cb_change_media(bs, true);
 
 QDECREF(options);
 
@@ -3068,7 +3060,6 @@ static void bdrv_close(BlockDriverState *bs)
 bs->backing_format[0] = '\0';
 bs->total_sectors = 0;
 bs->encrypted = false;
-bs->valid_key = false;
 bs->sg = false;
 QDECREF(bs->options);
 QDECREF(bs->explicit_options);
@@ -3498,72 +3489,6 @@ bool bdrv_is_encrypted(BlockDriverState *bs)
 return bs->encrypted;
 }
 
-bool bdrv_key_required(BlockDriverState *bs)
-{
-BdrvChild *backing = bs->backing;
-
-if (backing && backing->bs->encrypted && !backing->bs->valid_key) {
-return true;
-}
-return (bs->encrypted && !bs->valid_key);
-}
-
-int bdrv_set_key(BlockDriverState *bs, const char *key)
-{
-int ret;
-if (bs->backing && bs->backing->bs->encrypted) {
-ret = bdrv_set_key(bs->backing->bs, key);
-if (ret < 0)
-return ret;
-if (!bs->encrypted)
-return 0;
-}
-if (!bs->encrypted) {
-return -EINVAL;
-} else if (!bs->drv || !bs->drv->bdrv_set_key) {
-return -ENOMEDIUM;
-}
-ret = bs->drv->bdrv_set_key(bs, key);
-if (ret < 0) {
-bs->valid_key = false;
-} else if (!bs->valid_key) {
-/* call the change callback now, we skipped it on open */
-bs->valid_key = true;
-bdrv_parent_cb_change_media(bs, true);
-}
-return ret;
-}
-
-/*
- * Provide an encryption key for @bs.
- * If @key is non-null:
- * If @bs is not encrypted, fail.
- * Else if the key is invalid, fail.
- * Else set @bs's key to @key, replacing the existing key, if any.
- * If @key is null:
- * If @bs is encrypted and still lacks a key, fail.
- * Else do nothing.
- * On failure, store an error object through @errp if non-null.
- */
-void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp)
-{
-if (key) {
-if (!bdrv_is_encrypted(bs)) {
-error_setg(errp, "Node '%s' is not encrypted",
-  bdrv_get_device_or_node_name(bs));
-} else if (bdrv_set_key(bs, key) < 0) {
-error_setg(errp, QERR_INVALID_PASSWORD);
-}
-} else {
-if (bdrv_key_required(bs)) {
-error_set(errp, ERROR_CLASS_DEVICE_ENCRYPTED,
-  "'%s' (%s) is encrypted",
-  bdrv_get_device_or_node_name(bs),
-  bdrv_get_encrypted_filename(bs));
-}
-}
-}
-
 const char *bdrv_get_format_name(BlockDriverState *bs)
 {
 return bs->drv ? bs->drv->format_name : NULL;
diff --git a/block/crypto.c b/block/crypto.c
index da4be74..3ad4b20 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -308,7 +308,6 @@ static int block_crypto_open_generic(QCryptoBlockFormat 
format,
 }
 
 bs->encrypted = true;
-bs->valid_key = true;
 
 ret = 0;
  cleanup:
diff --git a/block/qapi.c b/block/qapi.c
index a40922e..9d724c2 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -45,7 +45,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
 info->ro = bs->read_only;
 info->drv= g_strdup(bs->drv->format_name);
 info->encrypted  = bs->encrypted;
-   

[Qemu-devel] [PATCH v9 06/20] iotests: skip 048 with qcow which doesn't support resize

2017-06-19 Thread Daniel P. Berrange
Test 048 is designed to verify data preservation during an
image resize. The qcow (v1) format impl has never supported
resize so always fails.

Reviewed-by: Max Reitz 
Reviewed-by: Alberto Garcia 
Signed-off-by: Daniel P. Berrange 
---
 tests/qemu-iotests/048 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
index 203c04f..9ed04a0 100755
--- a/tests/qemu-iotests/048
+++ b/tests/qemu-iotests/048
@@ -46,7 +46,7 @@ _compare()
 . ./common.filter
 . ./common.pattern
 
-_supported_fmt raw qcow qcow2 qed luks
+_supported_fmt raw qcow2 qed luks
 _supported_proto file
 _supported_os Linux
 
-- 
2.9.3




[Qemu-devel] [PATCH v9 10/20] qcow2: make qcow2_encrypt_sectors encrypt in place

2017-06-19 Thread Daniel P. Berrange
Instead of requiring separate input/output buffers for
encrypting data, change qcow2_encrypt_sectors() to assume
use of a single buffer, encrypting in place. The current
callers all used the same buffer for input/output already.

Reviewed-by: Eric Blake 
Reviewed-by: Fam Zheng 
Reviewed-by: Alberto Garcia 
Signed-off-by: Daniel P. Berrange 
---
 block/qcow2-cluster.c | 17 ++---
 block/qcow2.c |  4 ++--
 block/qcow2.h |  3 +--
 3 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index d779ea1..6400147 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -358,11 +358,9 @@ static int count_contiguous_clusters_unallocated(int 
nb_clusters,
 }
 
 /* The crypt function is compatible with the linux cryptoloop
-   algorithm for < 4 GB images. NOTE: out_buf == in_buf is
-   supported */
+   algorithm for < 4 GB images. */
 int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
-  uint8_t *out_buf, const uint8_t *in_buf,
-  int nb_sectors, bool enc,
+  uint8_t *buf, int nb_sectors, bool enc,
   Error **errp)
 {
 union {
@@ -382,14 +380,12 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t 
sector_num,
 }
 if (enc) {
 ret = qcrypto_cipher_encrypt(s->cipher,
- in_buf,
- out_buf,
+ buf, buf,
  512,
  errp);
 } else {
 ret = qcrypto_cipher_decrypt(s->cipher,
- in_buf,
- out_buf,
+ buf, buf,
  512,
  errp);
 }
@@ -397,8 +393,7 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t 
sector_num,
 return -1;
 }
 sector_num++;
-in_buf += 512;
-out_buf += 512;
+buf += 512;
 }
 return 0;
 }
@@ -446,7 +441,7 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
 assert(s->cipher);
 assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
 assert((bytes & ~BDRV_SECTOR_MASK) == 0);
-if (qcow2_encrypt_sectors(s, sector, iov.iov_base, iov.iov_base,
+if (qcow2_encrypt_sectors(s, sector, iov.iov_base,
   bytes >> BDRV_SECTOR_BITS, true, ) < 0) {
 ret = -EIO;
 error_free(err);
diff --git a/block/qcow2.c b/block/qcow2.c
index 652e6a4..b985ba7 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1543,7 +1543,7 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState 
*bs, uint64_t offset,
 assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
 Error *err = NULL;
 if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
-  cluster_data, cluster_data,
+  cluster_data,
   cur_bytes >> BDRV_SECTOR_BITS,
   false, ) < 0) {
 error_free(err);
@@ -1639,7 +1639,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState 
*bs, uint64_t offset,
 qemu_iovec_to_buf(_qiov, 0, cluster_data, hd_qiov.size);
 
 if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS,
-  cluster_data, cluster_data,
+  cluster_data,
   cur_bytes >>BDRV_SECTOR_BITS,
   true, ) < 0) {
 error_free(err);
diff --git a/block/qcow2.h b/block/qcow2.h
index 1801dc3..6b3d5de 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -538,8 +538,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t 
min_size,
 int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
 int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
 int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
-  uint8_t *out_buf, const uint8_t *in_buf,
-  int nb_sectors, bool enc, Error **errp);
+  uint8_t *buf, int nb_sectors, bool enc, Error 
**errp);
 
 int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
  unsigned int *bytes, uint64_t *cluster_offset);
-- 
2.9.3




[Qemu-devel] [PATCH v9 18/20] block: pass option prefix down to crypto layer

2017-06-19 Thread Daniel P. Berrange
While the crypto layer uses a fixed option name "key-secret",
the upper block layer may have a prefix on the options. e.g.
"encrypt.key-secret", in order to avoid clashes between crypto
option names & other block option names. To ensure the crypto
layer can report accurate error messages, we must tell it what
option name prefix was used.

Reviewed-by: Alberto Garcia 
Reviewed-by: Max Reitz 
Signed-off-by: Daniel P. Berrange 
---
 block/crypto.c| 4 ++--
 block/qcow.c  | 7 ---
 block/qcow2.c | 8 
 crypto/block-luks.c   | 8 ++--
 crypto/block-qcow.c   | 8 ++--
 crypto/block.c| 6 --
 crypto/blockpriv.h| 2 ++
 include/crypto/block.h| 6 +-
 tests/test-crypto-block.c | 8 
 9 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index 3ad4b20..c561cba 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -296,7 +296,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat 
format,
 if (flags & BDRV_O_NO_IO) {
 cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
 }
-crypto->block = qcrypto_block_open(open_opts,
+crypto->block = qcrypto_block_open(open_opts, NULL,
block_crypto_read_func,
bs,
cflags,
@@ -340,7 +340,7 @@ static int block_crypto_create_generic(QCryptoBlockFormat 
format,
 return -1;
 }
 
-crypto = qcrypto_block_create(create_opts,
+crypto = qcrypto_block_create(create_opts, NULL,
   block_crypto_init_func,
   block_crypto_write_func,
   ,
diff --git a/block/qcow.c b/block/qcow.c
index fb5a11f..fcd4715 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -208,8 +208,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, 
int flags,
 if (flags & BDRV_O_NO_IO) {
 cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
 }
-s->crypto = qcrypto_block_open(crypto_opts, NULL, NULL,
-   cflags, errp);
+s->crypto = qcrypto_block_open(crypto_opts, "encrypt.",
+   NULL, NULL, cflags, errp);
 if (!s->crypto) {
 ret = -EINVAL;
 goto fail;
@@ -869,7 +869,8 @@ static int qcow_create(const char *filename, QemuOpts 
*opts, Error **errp)
 goto exit;
 }
 
-crypto = qcrypto_block_create(crypto_opts, NULL, NULL, NULL, errp);
+crypto = qcrypto_block_create(crypto_opts, "encrypt.",
+  NULL, NULL, NULL, errp);
 if (!crypto) {
 ret = -EINVAL;
 goto exit;
diff --git a/block/qcow2.c b/block/qcow2.c
index 9ab361c..19bc69c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -279,7 +279,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, 
uint64_t start_offset,
 if (flags & BDRV_O_NO_IO) {
 cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
 }
-s->crypto = qcrypto_block_open(s->crypto_opts,
+s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
qcow2_crypto_hdr_read_func,
bs, cflags, errp);
 if (!s->crypto) {
@@ -1313,8 +1313,8 @@ static int qcow2_do_open(BlockDriverState *bs, QDict 
*options, int flags,
 if (flags & BDRV_O_NO_IO) {
 cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
 }
-s->crypto = qcrypto_block_open(s->crypto_opts, NULL, NULL,
-   cflags, errp);
+s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
+   NULL, NULL, cflags, errp);
 if (!s->crypto) {
 ret = -EINVAL;
 goto fail;
@@ -2274,7 +2274,7 @@ static int qcow2_set_up_encryption(BlockDriverState *bs, 
const char *encryptfmt,
 }
 s->crypt_method_header = fmt;
 
-crypto = qcrypto_block_create(cryptoopts,
+crypto = qcrypto_block_create(cryptoopts, "encrypt.",
   qcow2_crypto_hdr_init_func,
   qcow2_crypto_hdr_write_func,
   bs, errp);
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index 2b97d89..afb8543 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -638,6 +638,7 @@ qcrypto_block_luks_find_key(QCryptoBlock *block,
 static int
 qcrypto_block_luks_open(QCryptoBlock *block,
 QCryptoBlockOpenOptions *options,
+const char *optprefix,
 QCryptoBlockReadFunc readfunc,
 void *opaque,

[Qemu-devel] [PATCH v9 02/20] block: add ability to set a prefix for opt names

2017-06-19 Thread Daniel P. Berrange
When integrating the crypto support with qcow/qcow2, we don't
want to use the bare LUKS option names "hash-alg", "key-secret",
etc. We need to namespace them to match the nested QAPI schema.

e.g. "encrypt.hash-alg", "encrypt.key-secret"

so that they don't clash with any general qcow options at a later
date.

Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
Reviewed-by: Alberto Garcia 
Signed-off-by: Daniel P. Berrange 
---
 block/crypto.c | 16 
 block/crypto.h | 40 
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index ea40ba4..9df1e5d 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -129,7 +129,7 @@ static QemuOptsList block_crypto_runtime_opts_luks = {
 .name = "crypto",
 .head = QTAILQ_HEAD_INITIALIZER(block_crypto_runtime_opts_luks.head),
 .desc = {
-BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
+BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
 { /* end of list */ }
 },
 };
@@ -144,13 +144,13 @@ static QemuOptsList block_crypto_create_opts_luks = {
 .type = QEMU_OPT_SIZE,
 .help = "Virtual disk size"
 },
-BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET,
-BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG,
-BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE,
-BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG,
-BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG,
-BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG,
-BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME,
+BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(""),
+BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(""),
+BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(""),
+BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(""),
+BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(""),
+BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG(""),
+BLOCK_CRYPTO_OPT_DEF_LUKS_ITER_TIME(""),
 { /* end of list */ }
 },
 };
diff --git a/block/crypto.h b/block/crypto.h
index c0e9b54..3430dcd 100644
--- a/block/crypto.h
+++ b/block/crypto.h
@@ -29,51 +29,51 @@
 #define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
 #define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET\
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_KEY_SECRET(prefix)\
 {   \
-.name = BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,   \
+.name = prefix BLOCK_CRYPTO_OPT_LUKS_KEY_SECRET,\
 .type = QEMU_OPT_STRING,\
 .help = "ID of the secret that provides the keyslot passphrase", \
 }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG   \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_ALG(prefix)   \
 {  \
-.name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG,  \
+.name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_ALG,   \
 .type = QEMU_OPT_STRING,   \
 .help = "Name of encryption cipher algorithm", \
 }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE \
-{ \
-.name = BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE,\
-.type = QEMU_OPT_STRING,  \
-.help = "Name of encryption cipher mode", \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_CIPHER_MODE(prefix)  \
+{  \
+.name = prefix BLOCK_CRYPTO_OPT_LUKS_CIPHER_MODE,  \
+.type = QEMU_OPT_STRING,   \
+.help = "Name of encryption cipher mode",  \
 }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG   \
-{ \
-.name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG,  \
-.type = QEMU_OPT_STRING,  \
-.help = "Name of IV generator algorithm", \
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_ALG(prefix) \
+{   \
+.name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG, \
+.type = QEMU_OPT_STRING,\
+.help = "Name of IV generator algorithm",   \
 }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG\
+#define BLOCK_CRYPTO_OPT_DEF_LUKS_IVGEN_HASH_ALG(prefix)\
 {   \
-.name = BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG,   \
+.name = prefix BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG,\
 .type = QEMU_OPT_STRING,\
 .help = "Name of IV generator hash algorithm",  \
 }
 
-#define BLOCK_CRYPTO_OPT_DEF_LUKS_HASH_ALG   \
+#define 

[Qemu-devel] [PATCH v9 08/20] qcow: make encrypt_sectors encrypt in place

2017-06-19 Thread Daniel P. Berrange
Instead of requiring separate input/output buffers for
encrypting data, change encrypt_sectors() to assume
use of a single buffer, encrypting in place. One current
caller uses the same buffer for input/output already
and the other two callers are easily converted to do so.

Reviewed-by: Alberto Garcia 
Reviewed-by: Eric Blake 
Reviewed-by: Max Reitz 
Reviewed-by: Kevin Wolf 
Signed-off-by: Daniel P. Berrange 
---
 block/qcow.c | 45 +++--
 1 file changed, 15 insertions(+), 30 deletions(-)

diff --git a/block/qcow.c b/block/qcow.c
index 3047a61..2306e4f 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -322,11 +322,10 @@ static int qcow_set_key(BlockDriverState *bs, const char 
*key)
 }
 
 /* The crypt function is compatible with the linux cryptoloop
-   algorithm for < 4 GB images. NOTE: out_buf == in_buf is
-   supported */
+   algorithm for < 4 GB images. */
 static int encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
-   uint8_t *out_buf, const uint8_t *in_buf,
-   int nb_sectors, bool enc, Error **errp)
+   uint8_t *buf, int nb_sectors, bool enc,
+   Error **errp)
 {
 union {
 uint64_t ll[2];
@@ -345,14 +344,12 @@ static int encrypt_sectors(BDRVQcowState *s, int64_t 
sector_num,
 }
 if (enc) {
 ret = qcrypto_cipher_encrypt(s->cipher,
- in_buf,
- out_buf,
+ buf, buf,
  512,
  errp);
 } else {
 ret = qcrypto_cipher_decrypt(s->cipher,
- in_buf,
- out_buf,
+ buf, buf,
  512,
  errp);
 }
@@ -360,8 +357,7 @@ static int encrypt_sectors(BDRVQcowState *s, int64_t 
sector_num,
 return -1;
 }
 sector_num++;
-in_buf += 512;
-out_buf += 512;
+buf += 512;
 }
 return 0;
 }
@@ -481,13 +477,12 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
 uint64_t start_sect;
 assert(s->cipher);
 start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
-memset(s->cluster_data + 512, 0x00, 512);
 for(i = 0; i < s->cluster_sectors; i++) {
 if (i < n_start || i >= n_end) {
 Error *err = NULL;
+memset(s->cluster_data, 0x00, 512);
 if (encrypt_sectors(s, start_sect + i,
-s->cluster_data,
-s->cluster_data + 512, 1,
+s->cluster_data, 1,
 true, ) < 0) {
 error_free(err);
 errno = EIO;
@@ -665,7 +660,7 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, 
int64_t sector_num,
 }
 if (bs->encrypted) {
 assert(s->cipher);
-if (encrypt_sectors(s, sector_num, buf, buf,
+if (encrypt_sectors(s, sector_num, buf,
 n, false, ) < 0) {
 goto fail;
 }
@@ -700,9 +695,7 @@ static coroutine_fn int qcow_co_writev(BlockDriverState 
*bs, int64_t sector_num,
 BDRVQcowState *s = bs->opaque;
 int index_in_cluster;
 uint64_t cluster_offset;
-const uint8_t *src_buf;
 int ret = 0, n;
-uint8_t *cluster_data = NULL;
 struct iovec hd_iov;
 QEMUIOVector hd_qiov;
 uint8_t *buf;
@@ -710,7 +703,9 @@ static coroutine_fn int qcow_co_writev(BlockDriverState 
*bs, int64_t sector_num,
 
 s->cluster_cache_offset = -1; /* disable compressed cache */
 
-if (qiov->niov > 1) {
+/* We must always copy the iov when encrypting, so we
+ * don't modify the original data buffer during encryption */
+if (bs->encrypted || qiov->niov > 1) {
 buf = orig_buf = qemu_try_blockalign(bs, qiov->size);
 if (buf == NULL) {
 return -ENOMEM;
@@ -740,21 +735,14 @@ static coroutine_fn int qcow_co_writev(BlockDriverState 
*bs, int64_t sector_num,
 if (bs->encrypted) {
 Error *err = NULL;
 assert(s->cipher);
-if (!cluster_data) {
-cluster_data = g_malloc0(s->cluster_size);
-}
-if (encrypt_sectors(s, sector_num, cluster_data, buf,
-n, true, ) < 0) {

  1   2   3   >