[Qemu-devel] [PATCH] target/i386: add CPU model "Skylake-Server-clflushopt"

2017-12-11 Thread Haozhong Zhang
The only difference from the existing CPU model "Skylake-Server" is
the add of CPUID_7_0_EBX_CLFLUSHOPT, which is missed in "Skylake-Server".

Signed-off-by: Haozhong Zhang 
---
 target/i386/cpu.c | 49 +
 1 file changed, 49 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 045d66191f..a4370e6393 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1391,6 +1391,55 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .xlevel = 0x8008,
 .model_id = "Intel Xeon Processor (Skylake)",
 },
+{
+/* Add CLFLUSHOPT which is missed in CPU model "Skylake-Server". */
+.name = "Skylake-Server-clflushopt",
+.level = 0xd,
+.vendor = CPUID_VENDOR_INTEL,
+.family = 6,
+.model = 85,
+.stepping = 4,
+.features[FEAT_1_EDX] =
+CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+CPUID_DE | CPUID_FP87,
+.features[FEAT_1_ECX] =
+CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
+CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
+CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+.features[FEAT_8000_0001_EDX] =
+CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
+CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+.features[FEAT_8000_0001_ECX] =
+CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
+.features[FEAT_7_0_EBX] =
+CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
+CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
+CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
+CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_CLWB |
+CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
+CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
+CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
+/* Missing: XSAVES (not supported by some Linux versions,
+ * including v4.1 to v4.12).
+ * KVM doesn't yet expose any XSAVES state save component,
+ * and the only one defined in Skylake (processor tracing)
+ * probably will block migration anyway.
+ */
+.features[FEAT_XSAVE] =
+CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+CPUID_XSAVE_XGETBV1,
+.features[FEAT_6_EAX] =
+CPUID_6_EAX_ARAT,
+.xlevel = 0x8008,
+.model_id = "Intel Xeon Processor (Skylake w/ clflushopt)",
+},
 {
 .name = "Opteron_G1",
 .level = 5,
-- 
2.14.1




Re: [Qemu-devel] [PATCH 00/12] Refactor get_phys_addr() not to return FSR values

2017-12-11 Thread Edgar E. Iglesias
On Tue, Dec 05, 2017 at 07:46:20PM +, Peter Maydell wrote:
> Currently get_phys_addr() and its various subfunctions return a
> hard-coded fault status register value for translation failures. This
> is awkward because FSR values these days may be either long-descriptor
> format or short-descriptor format.  Worse, the right FSR type to use
> doesn't depend only on the translation table being walked -- some
> cases, like fault info reported to AArch32 EL2 for some kinds of ATS
> operation, must be in long-descriptor format even if the translation
> table being walked was short format. We can't get those cases right
> with our current approach. (We put in a bodge fix so we could at
> least run Xen, in commit 50cd71b0d347c7.)
> 
> This series does a refactoring of get_phys_addr() so that instead
> of returning FSR values it puts information in the existing
> ARMMMUFaultInfo structure that is sufficient to construct an
> FSR value, and the callers then do that using the right condition
> for whatever they're doing. I've included Edgar's patch from back
> in June that fixes the handling of ATS instructions, which is most
> of the point of the refactoring.
> 
> Rather than doing it all in one massive unreviewable patch, the
> series is structured as:
>  * patch 1: add fields to ARMMMUFaultInfo, and the utility functions
>that return a long or short format FSR given a fault info struct
>  * patch 2: stop passing an fsr argument to arm_ld*_ptw(), since
>nothing actually looks at the result. (This breaks a cycle
>arm_ldq_ptw()->S1_ptw_translate()->get_phys_addr_lpae()->arm_ldq_ptw()
>which would otherwise make a stepwise refactoring awkward.)
>  * patches 3 to 8: for each of the different subfunctions of
>get_phys_addr(), make them fill in the fault info fields instead
>of an fsr value. Temporarily we add calls to arm_fi_to_sfsc()
>and arm_fi_to_lfsc() at the callsites in get_phys_addr(), since
>the callers of get_phys_addr() still need the fsr values. These
>will go away again in a later patch.
>  * patches 9 and 10: change the callers of get_phys_addr() to use
>the info in the fault info struct and ignore the fsr value.
>  * patch 11: remove the now unused fsr argument (and the temporary
>calls to arm_fi_to_sfsc()/arm_fi_to_lfsc())
>  * patch 12: Edgar's patch for ATS PAR format
> 
> Arguably it would be good to push the "create the FSR value"
> logic further, into the point where the exception is taken.
> (This would let us correct the oddity where for M profile we
> get an A/R profile FSR value in arm_v7m_cpu_do_interrupt()
> which we then have to convert into the appropriate M profile
> fault status bits.) However, migration backcompat makes this
> tricky, because at the moment we migrate env->exception.fsr,
> and so we'd need to have code just to handle inbound migrations
> from old QEMU with an FSR and reconstitute a fault info struct.
> So I've stopped here, at least for now.
> 
> This whole series sits on top of my v8M TT patchset (which also
> had to touch some of the get_phys_addr() code). I've pushed it
> to this git branch if that's more convenient:
> 
>  https://git.linaro.org/people/peter.maydell/qemu-arm.git fsr-in-faultinfo
> 
> I have tested a bit (including a Linux KVM EL2 setup), but more
> testing would definitely be useful. Stefano: in particular it would
> be good to check this hasn't broken Xen again :-)
> 
> Based-on: 1512153879-5291-1-git-send-email-peter.mayd...@linaro.org
> ([PATCH 0/7] armv8m: Implement TT, and other bugfixes)


Hi Peter,

Thans for working on this, the series looks good to me!
Reviewed-by: Edgar E. Iglesias 

Cheers,
Edgar


> 
> thanks
> -- PMM
> 
> 
> Edgar E. Iglesias (1):
>   target/arm: Extend PAR format determination
> 
> Peter Maydell (11):
>   target/arm: Provide fault type enum and FSR conversion functions
>   target/arm: Remove fsr argument from arm_ld*_ptw()
>   target/arm: Convert get_phys_addr_v5() to not return FSC values
>   target/arm: Convert get_phys_addr_v6() to not return FSC values
>   target/arm: Convert get_phys_addr_lpae() to not return FSC values
>   target/arm: Convert get_phys_addr_pmsav5() to not return FSC values
>   target/arm: Convert get_phys_addr_pmsav7() to not return FSC values
>   target/arm: Convert get_phys_addr_pmsav8() to not return FSC values
>   target/arm: Use ARMMMUFaultInfo in deliver_fault()
>   target/arm: Ignore fsr from get_phys_addr() in do_ats_write()
>   target/arm: Remove fsr argument from get_phys_addr() and
> arm_tlb_fill()
> 
>  target/arm/internals.h | 187 +-
>  target/arm/helper.c| 238 
> +++--
>  target/arm/op_helper.c |  82 +
>  3 files changed, 342 insertions(+), 165 deletions(-)
> 
> -- 
> 2.7.4
> 



Re: [Qemu-devel] [PATCH 3/3] ide: abort TRIM operation for invalid range

2017-12-11 Thread Anton Nefedov

On 8/12/2017 10:51 PM, John Snow wrote:


Looks about right, just remember that this flow won't call
block_acct_invalid because you're bypassing the return to ide_dma_cb. I
assume you'll get to that in your next series.



Yes; I meant to keep the trim accounting in ide_issue_trim_cb()


For now, this should properly reject bogus TRIM commands. When you send
your next series, may I ask for a simple test case if possible?



Sure, I'll look into it


1-3:
Reviewed-by: John Snow 





Re: [Qemu-devel] [v22 1/2] virtio-crypto: Add virtio crypto device specification

2017-12-11 Thread Longpeng (Mike)


On 2017/12/6 19:01, Halil Pasic wrote:

> 
> 
> On 12/06/2017 08:37 AM, Longpeng(Mike) wrote:
>> +\field{outcome_len} is the size of struct virtio_crypto_session_input or
>> +ZERO for the session-destroy operation.
> 
> This ain't correct. It should have been something like 
> virtio_crypto_destroy_session_input.
> 

Hi Halil,

I already fixed this just now.
Do you have any other comments on v22 ? I'll send v23 tomorrow if no. :)

-- 
Regards,
Longpeng(Mike)

>> +
>> +
>> +\paragraph{Session operation}\label{sec:Device Types / Crypto Device / 
>> Device
>> +Operation / Control Virtqueue / Session operation}
>> +
>> +The session is a handle which describes the cryptographic parameters to be
>> +applied to a number of buffers.
>> +
>> +The following structure stores the result of session creation set by the 
>> device:
>> +
>> +\begin{lstlisting}
>> +struct virtio_crypto_session_input {
>> +/* Device write only portion */
>> +le64 session_id;
>> +le32 status;
>> +le32 padding;
>> +};
>> +\end{lstlisting}
>> +
>> +A request to destroy a session includes the following information:
>> +
>> +\begin{lstlisting}
>> +struct virtio_crypto_destroy_session_flf {
>> +/* Device read only portion */
>> +le64  session_id;
>> +/* Device write only portion */
> 
> This is the device writable portion and thus what we cal op_outcome above.
> So it should have been
> };
> 
> 
> struct virtio_crypto_destroy_session_input {
>> +le32  status;
>> +le32  padding;
>> +};
> 
> If we aren't consistent about it the dividing into parts (like op specific
> fixed and variable length (output) fields, operation outcome (input))
> isn't really helpful.
> 
> 
> Regards,
> Halil
>> +\end{lstlisting}
> 
> 
> .
> 


-- 
Regards,
Longpeng(Mike)




[Qemu-devel] [PATCH v1 14/19] fpu/softfloat: re-factor round_to_int

2017-12-11 Thread Alex Bennée
We can now add float16_round_to_int and use the common round_decomposed and
canonicalize functions to have a single implementation for
float16/32/64 round_to_int functions.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 304 
 include/fpu/softfloat.h |   1 +
 2 files changed, 130 insertions(+), 175 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index bf37f23f6a..9914ecb783 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1183,6 +1183,135 @@ float64 float64_div(float64 a, float64 b, float_status 
*status)
 return float64_round_pack_canonical(pr, status);
 }
 
+/*
+ * Rounds the floating-point value `a' to an integer, and returns the
+ * result as a floating-point value. The operation is performed
+ * according to the IEC/IEEE Standard for Binary Floating-Point
+ * Arithmetic.
+ */
+
+static decomposed_parts round_decomposed(decomposed_parts a, int rounding_mode,
+ float_status *s)
+{
+
+switch (a.cls) {
+case float_class_snan:
+a.cls = s->default_nan_mode ? float_class_dnan : float_class_msnan;
+s->float_exception_flags |= float_flag_invalid;
+break;
+case float_class_zero:
+case float_class_inf:
+case float_class_qnan:
+/* already "integral" */
+break;
+case float_class_normal:
+if (a.exp >= DECOMPOSED_BINARY_POINT) {
+/* already integral */
+break;
+}
+if (a.exp < 0) {
+bool one;
+/* all fractional */
+s->float_exception_flags |= float_flag_inexact;
+switch (rounding_mode) {
+case float_round_nearest_even:
+one = a.exp == -1 && a.frac > DECOMPOSED_IMPLICIT_BIT;
+break;
+case float_round_ties_away:
+one = a.exp == -1 && a.frac >= DECOMPOSED_IMPLICIT_BIT;
+break;
+case float_round_to_zero:
+one = false;
+break;
+case float_round_up:
+one = !a.sign;
+break;
+case float_round_down:
+one = a.sign;
+break;
+default:
+g_assert_not_reached();
+}
+
+if (one) {
+a.frac = DECOMPOSED_IMPLICIT_BIT;
+a.exp = 0;
+} else {
+a.cls = float_class_zero;
+}
+} else {
+uint64_t frac_lsb, frac_lsbm1, round_mask, roundeven_mask, inc;
+
+frac_lsb = DECOMPOSED_IMPLICIT_BIT >> a.exp;
+frac_lsbm1 = frac_lsb >> 1;
+roundeven_mask = (frac_lsb - 1) | frac_lsb;
+round_mask = roundeven_mask >> 1;
+
+switch (rounding_mode) {
+case float_round_nearest_even:
+inc = ((a.frac & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 
0);
+break;
+case float_round_ties_away:
+inc = frac_lsbm1;
+break;
+case float_round_to_zero:
+inc = 0;
+break;
+case float_round_up:
+inc = a.sign ? 0 : round_mask;
+break;
+case float_round_down:
+inc = a.sign ? round_mask : 0;
+break;
+default:
+g_assert_not_reached();
+}
+
+if (a.frac & round_mask) {
+s->float_exception_flags |= float_flag_inexact;
+a.frac += inc;
+a.frac &= ~round_mask;
+if (a.frac & DECOMPOSED_OVERFLOW_BIT) {
+a.frac >>= 1;
+a.exp++;
+}
+}
+}
+break;
+default:
+g_assert_not_reached();
+}
+return a;
+}
+
+float16 float16_round_to_int(float16 a, float_status *s)
+{
+decomposed_parts pa = float16_unpack_canonical(a, s);
+decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s);
+return float16_round_pack_canonical(pr, s);
+}
+
+float32 float32_round_to_int(float32 a, float_status *s)
+{
+decomposed_parts pa = float32_unpack_canonical(a, s);
+decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s);
+return float32_round_pack_canonical(pr, s);
+}
+
+float64 float64_round_to_int(float64 a, float_status *s)
+{
+decomposed_parts pa = float64_unpack_canonical(a, s);
+decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s);
+return float64_round_pack_canonical(pr, s);
+}
+
+float64 float64_trunc_to_int(float64 a, float_status *s)
+{
+decomposed_parts pa = float64_unpack_canonical(a, s);
+decomposed_parts pr = round_decomposed(pa, float_round_to_zero, s);
+return float64_round_pack_canonical(pr, s);
+}
+
 

[Qemu-devel] [PATCH v1 09/19] fpu/softfloat: define decompose structures

2017-12-11 Thread Alex Bennée
These structures pave the way for generic softfloat helper routines
that will operate on fully decomposed numbers.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 72 -
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 0850a78149..fe443ff234 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -83,7 +83,7 @@ this code that are retained.
  * target-dependent and needs the TARGET_* macros.
  */
 #include "qemu/osdep.h"
-
+#include "qemu/bitops.h"
 #include "fpu/softfloat.h"
 
 /* We only need stdlib for abort() */
@@ -185,6 +185,76 @@ static inline flag extractFloat64Sign(float64 a)
 {
 return float64_val(a) >> 63;
 }
+
+/*
+| Classify a floating point number.
+**/
+
+typedef enum {
+float_class_unclassified,
+float_class_zero,
+float_class_normal,
+float_class_inf,
+float_class_qnan,
+float_class_snan,
+float_class_dnan,
+float_class_msnan, /* maybe silenced */
+} float_class;
+
+/*
+| Structure holding all of the decomposed parts of a float.
+| The exponent is unbiased and the fraction is normalized.
+**/
+
+typedef struct {
+uint64_t frac   : 64;
+int exp : 32;
+float_class cls : 8;
+int : 23;
+bool sign   : 1;
+} decomposed_parts;
+
+#define DECOMPOSED_BINARY_POINT(64 - 2)
+#define DECOMPOSED_IMPLICIT_BIT(1ull << DECOMPOSED_BINARY_POINT)
+#define DECOMPOSED_OVERFLOW_BIT(DECOMPOSED_IMPLICIT_BIT << 1)
+
+/* Structure holding all of the relevant parameters for a format.  */
+typedef struct {
+int exp_bias;
+int exp_max;
+int frac_shift;
+uint64_t frac_lsb;
+uint64_t frac_lsbm1;
+uint64_t round_mask;
+uint64_t roundeven_mask;
+} decomposed_params;
+
+#define FRAC_PARAMS(F) \
+.frac_shift = F,   \
+.frac_lsb   = 1ull << (F), \
+.frac_lsbm1 = 1ull << ((F) - 1),   \
+.round_mask = (1ull << (F)) - 1,   \
+.roundeven_mask = (2ull << (F)) - 1
+
+static const decomposed_params float16_params = {
+.exp_bias   = 0x0f,
+.exp_max= 0x1f,
+FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 10)
+};
+
+static const decomposed_params float32_params = {
+.exp_bias   = 0x7f,
+.exp_max= 0xff,
+FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 23)
+};
+
+static const decomposed_params float64_params = {
+.exp_bias   = 0x3ff,
+.exp_max= 0x7ff,
+FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52)
+};
+
+
 /*
 | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
 | and 7, and returns the properly rounded 32-bit integer corresponding to the
-- 
2.15.1




[Qemu-devel] [PATCH v1 04/19] include/fpu/softfloat: implement float16_set_sign helper

2017-12-11 Thread Alex Bennée
Signed-off-by: Alex Bennée 
---
 include/fpu/softfloat.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 32036382c6..17dfe60dbd 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -390,6 +390,11 @@ static inline float16 float16_chs(float16 a)
 return make_float16(float16_val(a) ^ 0x8000);
 }
 
+static inline float16 float16_set_sign(float16 a, int sign)
+{
+return make_float16((float16_val(a) & 0x7fff) | (sign << 15));
+}
+
 /*
 | The pattern for a default generated half-precision NaN.
 **/
-- 
2.15.1




Re: [Qemu-devel] [PATCH V3] pci: removed the is_express field since a uniform interface was inserted

2017-12-11 Thread Yoni Bettan



On 12/07/2017 10:58 PM, Eduardo Habkost wrote:

On Tue, Dec 05, 2017 at 07:17:06PM +0200, Yoni Bettan wrote:

 * according to Eduardo Habkost's commit
   fd3b02c8896d597dd8b9e053dec579cf0386aee1

 * since all PCIEs now implement INTERFACE_PCIE_DEVICE we
   don't need this field anymore

 * Devices that where only INTERFACE_PCIE_DEVICE (is_express == 1)
   or
   devices that where only INTERFACE_CONVENTIONAL_PCI_DEVICE 
(is_express == 0)
   where not affected by the change

   The only devices that were affected are those that are hybrid and 
also
   had (is_express == 1) - therefor only:
 - hw/vfio/pci.c
 - hw/usb/hcd-xhci.c

   For both I made sure that QEMU_PCI_CAP_EXPRESS is on

Signed-off-by: Yoni Bettan 
---
  docs/pcie_pci_bridge.txt   | 2 +-
  hw/block/nvme.c| 1 -
  hw/net/e1000e.c| 1 -
  hw/pci-bridge/pcie_pci_bridge.c| 1 -
  hw/pci-bridge/pcie_root_port.c | 1 -
  hw/pci-bridge/xio3130_downstream.c | 1 -
  hw/pci-bridge/xio3130_upstream.c   | 1 -
  hw/pci-host/xilinx-pcie.c  | 1 -
  hw/pci/pci.c   | 4 +++-
  hw/scsi/megasas.c  | 4 
  hw/usb/hcd-xhci.c  | 7 ++-
  hw/vfio/pci.c  | 3 ++-
  include/hw/pci/pci.h   | 3 ---
  13 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/docs/pcie_pci_bridge.txt b/docs/pcie_pci_bridge.txt
index 5a4203f97c..ab35ebf3ca 100644
--- a/docs/pcie_pci_bridge.txt
+++ b/docs/pcie_pci_bridge.txt
@@ -110,5 +110,5 @@ To enable device hot-plug into the bridge on Linux there're 
3 ways:
  Implementation
  ==
  The PCIE-PCI bridge is based on PCI-PCI bridge, but also accumulates PCI 
Express
-features as a PCI Express device (is_express=1).
+features as a PCI Express device.
  
diff --git a/hw/block/nvme.c b/hw/block/nvme.c

index 441e21ed1f..9325bc0911 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1087,7 +1087,6 @@ static void nvme_class_init(ObjectClass *oc, void *data)
  pc->vendor_id = PCI_VENDOR_ID_INTEL;
  pc->device_id = 0x5845;
  pc->revision = 2;
-pc->is_express = 1;
  
  set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

  dc->desc = "Non-Volatile Memory Express";
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index f1af279e8d..c360f0d8c9 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -675,7 +675,6 @@ static void e1000e_class_init(ObjectClass *class, void 
*data)
  c->revision = 0;
  c->romfile = "efi-e1000e.rom";
  c->class_id = PCI_CLASS_NETWORK_ETHERNET;
-c->is_express = 1;
  
  dc->desc = "Intel 82574L GbE Controller";

  dc->reset = e1000e_qdev_reset;
diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c
index a4d827c99d..b7d9ebbec2 100644
--- a/hw/pci-bridge/pcie_pci_bridge.c
+++ b/hw/pci-bridge/pcie_pci_bridge.c
@@ -169,7 +169,6 @@ static void pcie_pci_bridge_class_init(ObjectClass *klass, 
void *data)
  DeviceClass *dc = DEVICE_CLASS(klass);
  HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
  
-k->is_express = 1;

  k->is_bridge = 1;
  k->vendor_id = PCI_VENDOR_ID_REDHAT;
  k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_BRIDGE;
diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c
index 9b6e4ce512..45f9e8cd4a 100644
--- a/hw/pci-bridge/pcie_root_port.c
+++ b/hw/pci-bridge/pcie_root_port.c
@@ -145,7 +145,6 @@ static void rp_class_init(ObjectClass *klass, void *data)
  DeviceClass *dc = DEVICE_CLASS(klass);
  PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  
-k->is_express = 1;

  k->is_bridge = 1;
  k->config_write = rp_write_config;
  k->realize = rp_realize;
diff --git a/hw/pci-bridge/xio3130_downstream.c 
b/hw/pci-bridge/xio3130_downstream.c
index 1e09d2afb7..613a0d6bb7 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -177,7 +177,6 @@ static void xio3130_downstream_class_init(ObjectClass 
*klass, void *data)
  DeviceClass *dc = DEVICE_CLASS(klass);
  PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  
-k->is_express = 1;

  k->is_bridge = 1;
  k->config_write = xio3130_downstream_write_config;
  k->realize = xio3130_downstream_realize;
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 227997ce46..d4645bddee 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -148,7 +148,6 @@ static void xio3130_upstream_class_init(ObjectClass *klass, 
void *data)
  DeviceClass *dc = DEVICE_CLASS(klass);
  PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
  
-k->is_express = 1;

  k->is_bridge = 1;
  k->config_write = xio3130_upstream_write_config;
  k->realize = xio3130_upstream_realize;
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c

[Qemu-devel] [PATCH v4 00/46] Windbg supporting

2017-12-11 Thread Mihail Abakumov
An update of:

v1: 
https://lists.nongnu.org/archive/html/qemu-devel/2017-09/msg07092.html

We made the debugger module WinDbg (like GDB) for QEMU. This is the replacement
of the remote stub in Windows kernel. Used for remote Windows kernel debugging
without debugging mode.

WinDbg is a multipurpose debugger for the Microsoft Windows computer operating
system, distributed by Microsoft. Recent versions of WinDbg have been and are
being distributed as part of the free Debugging Tools for Windows suite.

How to start debugging QEMU using WinDbg:
  Run QEMU with next option:
-windbg pipe:
  QEMU will start and pause for waiting WinDbg connection.
  Run WinDbg with next options:
-b -k com:pipe,baud=115200,port=\\.\pipe\,resets=0
  Wait for debugger connect to kernel.

Note: You can add Symbol Search Path in WinDbg such as
srv*c:\tmp*http://msdl.microsoft.com/download/symbols.

How it works:
The WinDbg debugger has the possibility of connecting to a remote debug service
(Kdsrv.exe) in the Windows kernel. Therefore, it is possible to connect to the
guest system running in the QEMU emulator. Kernel debugging is possible only
with the enabled debugging mode, may change at the same time. Our module of
WinDbg debugger for QEMU is an alternative of the remote debugging service in
the kernel. Thus, the debugger connects to the debugging module, not to the
kernel of the operating system. The module obtains all the necessary information
answering debugger requests from the QEMU emulator. At the same time for
debugging there is no need to enable debugging mode in the kernel. This leads to
hidden debugging. Our module supports all features of WinDbg regarding remote
debugging, besides interception of events and exceptions. Only i386 is supported
now.

Changed in v4:

 - Add WinDbg stub to the MAINTAINERS file.
 - Increase size of the search buffer in 'kd_api_search_memory'. (Ladi Prosek)
 - Add sub functions for helper_wrmsr and helper_rdmsr: cpu_x86_write_msr and
   cpu_x86_read_msr. Also they are used in packet handlers, i.e. duplication of
   code is removed. (Ladi Prosek)
 - Add a more user-friendly error when try to use -windbg and -gdb at the same
   time. (Ladi Prosek)
 - Remove macros for SizedBuf. (Ladi Prosek)
 - Add runtime assert to KD_API_NAME and KD_PKT_TYPE_NAME. (Ladi Prosek)
 - Remove 'ifneq ($(TARGET_NAME), x86_64)' from the 'Makefile.target' file.
   (Ladi Prosek)
 - Remove incorrect macro UINT32_P. Replace it by bit shifts. (Ladi Prosek)

Changed in v3:

 - Add a support of the new api functions from the WinDbg v10.

Changed in v2:

 - Move target specific code in the 'target/' directory. (Alistair Francis)
 - Change 'kd_api_fill_memory'. Made a fill of memory by line segments. Before
   that, a full array was immediately collected and written in RAM. (Ladi 
Prosek)
 - Change 'kd_api_search_memory'. Made a search for memory by line segments.
   (Ladi Prosek)
 - Change ld* to st* where it needs. (Ladi Prosek)
 - Add a additional check of input arguments in 'windbg_read_context' and
   'windbg_read_ks_regs'. (Ladi Prosek)
 - Fix typos. (Ladi Prosek)
 - Add a fliping back 'windbg_state->is_loaded' after reset VM.
 - Add a check to disabled kvm. It is supported yet. (Ladi Prosek)
 - Add a check to device in windbg option. Only pipe is supporting now.
   (Alistair Francis)
 - Add a check to 'ifdef' WINDBG_DEBUG_ON before define it. (Alistair Francis)
 - Replace printf to qemu_log. (Alistair Francis)
 - Fix build on s390x host. (patchew)
 - Fix code style error. (patchew)

---

Mihail Abakumov (46):
  windbg: added empty windbgstub files
  windbg: added windbg's KD header file
  windbg: modified windbgkd.h
  windbg: added '-windbg' option
  windbg: added helper features
  windbg: added WindbgState
  windbg: added chardev
  windbg: hook to wrmsr operation
  windbg: handler of fs/gs register
  windbg: structures for parsing data stream
  windbg: parsing data stream
  windbg: send data and control packets
  windbg: handler of parsing context
  windbg: init DBGKD_ANY_WAIT_STATE_CHANGE
  windbg: generate ExceptionStateChange
  windbg: generate LoadSymbolsStateChange
  windbg: windbg_vm_stop
  windbg: implemented windbg_process_control_packet
  windbg: implemented windbg_process_data_packet
  windbg: implemented windbg_process_manipulate_packet
  windbg: implemented kd_api_read_virtual_memory and 
kd_api_write_virtual_memory
  windbg: kernel's structures
  windbg: implemented kd_api_get_context and kd_api_set_context
  windbg: implemented kd_api_read_control_space and 
kd_api_write_control_space
  windbg: implemented windbg_read_context
  windbg: implemented windbg_write_context
  windbg: implemented windbg_read_ks_regs
  windbg: implemented windbg_write_ks_regs
  windbg: implemented windbg_set_sr
  windbg: implemented windbg_set_dr
  windbg: implemented windbg_set_dr7
  

[Qemu-devel] [PATCH v4 06/46] windbg: added WindbgState

2017-12-11 Thread Mihail Abakumov
Added definition of the WindbgState struct and its initialization.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |   28 
 1 file changed, 28 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index 3830446988..0863da73fd 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -10,10 +10,38 @@
  */
 
 #include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "chardev/char.h"
+#include "chardev/char-fe.h"
+#include "qemu/cutils.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
 
+typedef struct WindbgState {
+bool is_loaded;
+
+uint32_t ctrl_packet_id;
+uint32_t data_packet_id;
+} WindbgState;
+
+static WindbgState *windbg_state;
+
+static void windbg_exit(void)
+{
+g_free(windbg_state);
+}
+
 int windbg_server_start(const char *device)
 {
+if (windbg_state) {
+WINDBG_ERROR("Multiple instances of windbg are not supported.");
+exit(1);
+}
+
+windbg_state = g_new0(WindbgState, 1);
+windbg_state->ctrl_packet_id = RESET_PACKET_ID;
+windbg_state->data_packet_id = INITIAL_PACKET_ID;
+
+atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 01/46] windbg: added empty windbgstub files

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 Makefile.target |5 +
 include/exec/windbgstub-utils.h |   18 ++
 include/exec/windbgstub.h   |   17 +
 stubs/Makefile.objs |1 +
 stubs/windbgstub.c  |   18 ++
 target/i386/Makefile.objs   |2 +-
 target/i386/windbgstub.c|   12 
 windbgstub-utils.c  |   12 
 windbgstub.c|   19 +++
 9 files changed, 103 insertions(+), 1 deletion(-)
 create mode 100755 include/exec/windbgstub-utils.h
 create mode 100755 include/exec/windbgstub.h
 create mode 100755 stubs/windbgstub.c
 create mode 100755 target/i386/windbgstub.c
 create mode 100755 windbgstub-utils.c
 create mode 100755 windbgstub.c

diff --git a/Makefile.target b/Makefile.target
index 7f42c45db8..0272b5e0ab 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -148,6 +148,11 @@ obj-y += dump.o
 obj-y += migration/ram.o
 LIBS := $(libs_softmmu) $(LIBS)
 
+# WinDbg support
+ifeq ($(TARGET_NAME), i386)
+obj-y += windbgstub.o windbgstub-utils.o
+endif
+
 # Hardware support
 ifeq ($(TARGET_NAME), sparc64)
 obj-y += hw/sparc64/
diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
new file mode 100755
index 00..67d190bf6c
--- /dev/null
+++ b/include/exec/windbgstub-utils.h
@@ -0,0 +1,18 @@
+/*
+ * windbgstub-utils.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGSTUB_UTILS_H
+#define WINDBGSTUB_UTILS_H
+
+#include "qemu/osdep.h"
+#include "exec/windbgstub.h"
+
+#endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
new file mode 100755
index 00..1a6e1cc6e5
--- /dev/null
+++ b/include/exec/windbgstub.h
@@ -0,0 +1,17 @@
+/*
+ * windbgstub.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGSTUB_H
+#define WINDBGSTUB_H
+
+int windbg_server_start(const char *device);
+
+#endif
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index e69c217aff..5c25a53c15 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -12,6 +12,7 @@ stub-obj-y += dump.o
 stub-obj-y += error-printf.o
 stub-obj-y += fdset.o
 stub-obj-y += gdbstub.o
+stub-obj-y += windbgstub.o
 stub-obj-y += get-vm-name.o
 stub-obj-y += iothread.o
 stub-obj-y += iothread-lock.o
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
new file mode 100755
index 00..4951f59203
--- /dev/null
+++ b/stubs/windbgstub.c
@@ -0,0 +1,18 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "exec/windbgstub.h"
+
+int windbg_server_start(const char *device)
+{
+return 0;
+}
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index 6a26e9d9f0..730ee04e27 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -1,4 +1,4 @@
-obj-y += helper.o cpu.o gdbstub.o xsave_helper.o
+obj-y += helper.o cpu.o gdbstub.o windbgstub.o xsave_helper.o
 obj-$(CONFIG_TCG) += translate.o
 obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
 obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
new file mode 100755
index 00..df89e1edd8
--- /dev/null
+++ b/target/i386/windbgstub.c
@@ -0,0 +1,12 @@
+/*
+ * windbgstub.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
new file mode 100755
index 00..dc5e505c63
--- /dev/null
+++ b/windbgstub-utils.c
@@ -0,0 +1,12 @@
+/*
+ * windbgstub-utils.c
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "exec/windbgstub-utils.h"
diff --git a/windbgstub.c 

[Qemu-devel] [PATCH v4 04/46] windbg: added '-windbg' option

2017-12-11 Thread Mihail Abakumov
This option starts windbg server.

Signed-off-by: Mihail Abakumov 
Acked-by: Alistair Francis 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 qemu-options.hx |8 
 vl.c|8 
 2 files changed, 16 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index 9f6e2adfff..1c84eb56d9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3544,6 +3544,14 @@ Shorthand for -gdb tcp::1234, i.e. open a gdbserver on 
TCP port 1234
 (@pxref{gdb_usage}).
 ETEXI
 
+DEF("windbg", HAS_ARG, QEMU_OPTION_windbg, \
+"-windbg wait for windbg connection\n", QEMU_ARCH_I386)
+STEXI
+@item -windbg
+@findex -windbg
+Wait for windbg connection.
+ETEXI
+
 DEF("d", HAS_ARG, QEMU_OPTION_d, \
 "-d item1,...enable logging of specified items (use '-d help' for a 
list of log items)\n",
 QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index 8e247cc2a2..d6378cf03f 100644
--- a/vl.c
+++ b/vl.c
@@ -80,6 +80,7 @@ int main(int argc, char **argv)
 #include "sysemu/sysemu.h"
 #include "sysemu/numa.h"
 #include "exec/gdbstub.h"
+#include "exec/windbgstub.h"
 #include "qemu/timer.h"
 #include "chardev/char.h"
 #include "qemu/bitmap.h"
@@ -2436,6 +2437,7 @@ struct device_config {
 DEV_VIRTCON,   /* -virtioconsole */
 DEV_DEBUGCON,  /* -debugcon */
 DEV_GDB,   /* -gdb, -s */
+DEV_WINDBG,/* -windbg */
 DEV_SCLP,  /* s390 sclp */
 } type;
 const char *cmdline;
@@ -3445,6 +3447,9 @@ int main(int argc, char **argv, char **envp)
 case QEMU_OPTION_gdb:
 add_device_config(DEV_GDB, optarg);
 break;
+case QEMU_OPTION_windbg:
+add_device_config(DEV_WINDBG, optarg);
+break;
 case QEMU_OPTION_L:
 if (is_help_option(optarg)) {
 list_data_dirs = true;
@@ -4586,6 +4591,9 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
+if (foreach_device_config(DEV_WINDBG, windbg_server_start) < 0) {
+exit(1);
+}
 if (foreach_device_config(DEV_SERIAL, serial_parse) < 0)
 exit(1);
 if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0)




[Qemu-devel] [PATCH v4 13/46] windbg: handler of parsing context

2017-12-11 Thread Mihail Abakumov
Implemented handler of parsing context.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |   36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/windbgstub.c b/windbgstub.c
index 8c33e0de0a..b71449e369 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -11,6 +11,7 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "sysemu/sysemu.h"
 #include "chardev/char.h"
 #include "chardev/char-fe.h"
 #include "qemu/cutils.h"
@@ -97,7 +98,6 @@ static void windbg_send_data_packet(uint8_t *data, uint16_t 
byte_count,
 windbg_state->data_packet_id ^= 1;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void windbg_send_control_packet(uint16_t type)
 {
 KD_PACKET packet = {
@@ -116,9 +116,41 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
-static void windbg_ctx_handler(ParsingContext *ctx)
+static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
+static void windbg_process_control_packet(ParsingContext *ctx)
+{}
+
+static void windbg_ctx_handler(ParsingContext *ctx)
+{
+switch (ctx->result) {
+case RESULT_NONE:
+break;
+
+case RESULT_BREAKIN_BYTE:
+vm_stop(RUN_STATE_PAUSED);
+break;
+
+case RESULT_CONTROL_PACKET:
+windbg_process_control_packet(ctx);
+break;
+
+case RESULT_DATA_PACKET:
+windbg_process_data_packet(ctx);
+break;
+
+case RESULT_UNKNOWN_PACKET:
+case RESULT_ERROR:
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+
+default:
+break;
+}
+}
+
 static void windbg_read_byte(ParsingContext *ctx, uint8_t byte)
 {
 switch (ctx->state) {




[Qemu-devel] [PATCH v4 22/46] windbg: kernel's structures

2017-12-11 Thread Mihail Abakumov
Defined Windows kernel's structures (CPU_CONTEXT and CPU_KSPECIAL_REGISTERS) 
for i386 and x64_86.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |  247 ++
 1 file changed, 247 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 28d4f5bb10..11c35a4207 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -26,6 +26,253 @@
 # define OFFSET_KPRCB_CURRTHREAD 0x4
 #endif
 
+/*
+ * Next code copied from winnt.h
+ */
+#ifdef TARGET_X86_64
+
+#define CPU_CONTEXT_AMD64 0x10
+
+#define CPU_CONTEXT_CONTROL (CPU_CONTEXT_AMD64 | 0x1)
+#define CPU_CONTEXT_INTEGER (CPU_CONTEXT_AMD64 | 0x2)
+#define CPU_CONTEXT_SEGMENTS(CPU_CONTEXT_AMD64 | 0x4)
+#define CPU_CONTEXT_FLOATING_POINT  (CPU_CONTEXT_AMD64 | 0x8)
+#define CPU_CONTEXT_DEBUG_REGISTERS (CPU_CONTEXT_AMD64 | 0x10)
+
+#define CPU_CONTEXT_FULL \
+(CPU_CONTEXT_CONTROL | CPU_CONTEXT_INTEGER | CPU_CONTEXT_FLOATING_POINT)
+#define CPU_CONTEXT_ALL \
+(CPU_CONTEXT_FULL | CPU_CONTEXT_SEGMENTS | CPU_CONTEXT_DEBUG_REGISTERS)
+
+typedef struct _CPU_DESCRIPTOR {
+uint16_t Pad[3];
+uint16_t Limit;
+uint64_t Base;
+} CPU_DESCRIPTOR, *PCPU_DESCRIPTOR;
+
+typedef struct _CPU_KSPECIAL_REGISTERS {
+uint64_t Cr0;
+uint64_t Cr2;
+uint64_t Cr3;
+uint64_t Cr4;
+uint64_t KernelDr0;
+uint64_t KernelDr1;
+uint64_t KernelDr2;
+uint64_t KernelDr3;
+uint64_t KernelDr6;
+uint64_t KernelDr7;
+CPU_DESCRIPTOR Gdtr;
+CPU_DESCRIPTOR Idtr;
+uint16_t Tr;
+uint16_t Ldtr;
+uint32_t MxCsr;
+uint64_t DebugControl;
+uint64_t LastBranchToRip;
+uint64_t LastBranchFromRip;
+uint64_t LastExceptionToRip;
+uint64_t LastExceptionFromRip;
+uint64_t Cr8;
+uint64_t MsrGsBase;
+uint64_t MsrGsSwap;
+uint64_t MsrStar;
+uint64_t MsrLStar;
+uint64_t MsrCStar;
+uint64_t MsrSyscallMask;
+uint64_t Xcr0;
+} CPU_KSPECIAL_REGISTERS, *PCPU_KSPECIAL_REGISTERS;
+
+#pragma pack(push, 2)
+typedef struct _CPU_M128A {
+uint64_t Low;
+int64_t High;
+} CPU_M128A, *PCPU_M128A;
+#pragma pack(pop)
+
+typedef struct _CPU_XMM_SAVE_AREA32 {
+uint16_t ControlWord;
+uint16_t StatusWord;
+uint8_t TagWord;
+uint8_t Reserved1;
+uint16_t ErrorOpcode;
+uint32_t ErrorOffset;
+uint16_t ErrorSelector;
+uint16_t Reserved2;
+uint32_t DataOffset;
+uint16_t DataSelector;
+uint16_t Reserved3;
+uint32_t MxCsr;
+uint32_t MxCsr_Mask;
+CPU_M128A FloatRegisters[8];
+CPU_M128A XmmRegisters[16];
+uint8_t Reserved4[96];
+} CPU_XMM_SAVE_AREA32, *PCPU_XMM_SAVE_AREA32;
+
+#pragma pack(push, 2)
+typedef struct _CPU_CONTEXT { /* sizeof = 1232 */
+uint64_t P1Home;
+uint64_t P2Home;
+uint64_t P3Home;
+uint64_t P4Home;
+uint64_t P5Home;
+uint64_t P6Home;
+uint32_t ContextFlags;
+uint32_t MxCsr;
+uint16_t SegCs;
+uint16_t SegDs;
+uint16_t SegEs;
+uint16_t SegFs;
+uint16_t SegGs;
+uint16_t SegSs;
+uint32_t EFlags;
+uint64_t Dr0;
+uint64_t Dr1;
+uint64_t Dr2;
+uint64_t Dr3;
+uint64_t Dr6;
+uint64_t Dr7;
+uint64_t Rax;
+uint64_t Rcx;
+uint64_t Rdx;
+uint64_t Rbx;
+uint64_t Rsp;
+uint64_t Rbp;
+uint64_t Rsi;
+uint64_t Rdi;
+uint64_t R8;
+uint64_t R9;
+uint64_t R10;
+uint64_t R11;
+uint64_t R12;
+uint64_t R13;
+uint64_t R14;
+uint64_t R15;
+uint64_t Rip;
+union {
+CPU_XMM_SAVE_AREA32 FltSave;
+CPU_XMM_SAVE_AREA32 FloatSave;
+struct {
+CPU_M128A Header[2];
+CPU_M128A Legacy[8];
+CPU_M128A Xmm0;
+CPU_M128A Xmm1;
+CPU_M128A Xmm2;
+CPU_M128A Xmm3;
+CPU_M128A Xmm4;
+CPU_M128A Xmm5;
+CPU_M128A Xmm6;
+CPU_M128A Xmm7;
+CPU_M128A Xmm8;
+CPU_M128A Xmm9;
+CPU_M128A Xmm10;
+CPU_M128A Xmm11;
+CPU_M128A Xmm12;
+CPU_M128A Xmm13;
+CPU_M128A Xmm14;
+CPU_M128A Xmm15;
+};
+};
+CPU_M128A VectorRegister[26];
+uint64_t VectorControl;
+uint64_t DebugControl;
+uint64_t LastBranchToRip;
+uint64_t LastBranchFromRip;
+uint64_t LastExceptionToRip;
+uint64_t LastExceptionFromRip;
+} CPU_CONTEXT, *PCPU_CONTEXT;
+#pragma pack(pop)
+
+#else
+
+#define SIZE_OF_X86_REG 80
+#define MAX_SUP_EXT 512
+
+#define CPU_CONTEXT_i386 0x1
+
+#define CPU_CONTEXT_CONTROL(CPU_CONTEXT_i386 | 0x1)
+#define CPU_CONTEXT_INTEGER(CPU_CONTEXT_i386 | 0x2)
+#define CPU_CONTEXT_SEGMENTS   (CPU_CONTEXT_i386 | 0x4)
+#define CPU_CONTEXT_FLOATING_POINT (CPU_CONTEXT_i386 | 0x8)
+#define 

[Qemu-devel] [PATCH v4 03/46] windbg: modified windbgkd.h

2017-12-11 Thread Mihail Abakumov
Added useful name arrays of some defines. Not used yet. Needs for the future.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgkd.h |   83 +++
 1 file changed, 83 insertions(+)

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
index b8f98925e7..5008cbb729 100755
--- a/include/exec/windbgkd.h
+++ b/include/exec/windbgkd.h
@@ -870,4 +870,87 @@ typedef struct _DBGKD_TRACE_IO {
} u;
 } DBGKD_TRACE_IO, *PDBGKD_TRACE_IO;
 
+__attribute__ ((unused)) /* maybe unused */
+static const char *kd_api_names[] = {
+"DbgKdReadVirtualMemoryApi",
+"DbgKdWriteVirtualMemoryApi",
+"DbgKdGetContextApi",
+"DbgKdSetContextApi",
+"DbgKdWriteBreakPointApi",
+"DbgKdRestoreBreakPointApi",
+"DbgKdContinueApi",
+"DbgKdReadControlSpaceApi",
+"DbgKdWriteControlSpaceApi",
+"DbgKdReadIoSpaceApi",
+"DbgKdWriteIoSpaceApi",
+"DbgKdRebootApi",
+"DbgKdContinueApi2",
+"DbgKdReadPhysicalMemoryApi",
+"DbgKdWritePhysicalMemoryApi",
+"DbgKdQuerySpecialCallsApi",
+"DbgKdSetSpecialCallApi",
+"DbgKdClearSpecialCallsApi",
+"DbgKdSetInternalBreakPointApi",
+"DbgKdGetInternalBreakPointApi",
+"DbgKdReadIoSpaceExtendedApi",
+"DbgKdWriteIoSpaceExtendedApi",
+"DbgKdGetVersionApi",
+"DbgKdWriteBreakPointExApi",
+"DbgKdRestoreBreakPointExApi",
+"DbgKdCauseBugCheckApi",
+"",
+"",
+"",
+"",
+"",
+"",
+"DbgKdSwitchProcessor",
+"DbgKdPageInApi",
+"DbgKdReadMachineSpecificRegister",
+"DbgKdWriteMachineSpecificRegister",
+"OldVlm1",
+"OldVlm2",
+"DbgKdSearchMemoryApi",
+"DbgKdGetBusDataApi",
+"DbgKdSetBusDataApi",
+"DbgKdCheckLowMemoryApi",
+"DbgKdClearAllInternalBreakpointsApi",
+"DbgKdFillMemoryApi",
+"DbgKdQueryMemoryApi",
+"DbgKdSwitchPartition",
+"DbgKdUnknownApi"
+};
+
+__attribute__ ((unused)) /* maybe unused */
+static const char *kd_packet_type_names[] = {
+"PACKET_TYPE_UNUSED",
+"PACKET_TYPE_KD_STATE_CHANGE32",
+"PACKET_TYPE_KD_STATE_MANIPULATE",
+"PACKET_TYPE_KD_DEBUG_IO",
+"PACKET_TYPE_KD_ACKNOWLEDGE",
+"PACKET_TYPE_KD_RESEND",
+"PACKET_TYPE_KD_RESET",
+"PACKET_TYPE_KD_STATE_CHANGE64",
+"PACKET_TYPE_KD_POLL_BREAKIN",
+"PACKET_TYPE_KD_TRACE_IO",
+"PACKET_TYPE_KD_CONTROL_REQUEST",
+"PACKET_TYPE_KD_FILE_IO",
+"PACKET_TYPE_MAX"
+};
+
+#define KD_API_NAME(id) ({  \
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(kd_api_names) ==   \
+  DbgKdMaximumManipulate - DbgKdMinimumManipulate + 2); \
+(id >= DbgKdMinimumManipulate && id < DbgKdMaximumManipulate) ? \
+kd_api_names[id - DbgKdMinimumManipulate] : \
+kd_api_names[DbgKdMaximumManipulate - DbgKdMinimumManipulate];  \
+})
+
+#define KD_PKT_TYPE_NAME(id) ({ \
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(kd_packet_type_names) == PACKET_TYPE_MAX); \
+(id >= 0 && id < PACKET_TYPE_MAX) ? \
+kd_packet_type_names[id] :  \
+kd_packet_type_names[PACKET_TYPE_MAX - 1];  \
+})
+
 #endif




[Qemu-devel] [PATCH v4 10/46] windbg: structures for parsing data stream

2017-12-11 Thread Mihail Abakumov
Added structures for parsing data stream from windbg to packet.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |   11 +++
 windbgstub.c|   30 ++
 2 files changed, 41 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index ced03b0663..b7e65faefe 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -52,6 +52,17 @@ typedef struct InitedAddr {
 bool is_init;
 } InitedAddr;
 
+typedef struct PacketData {
+union {
+struct {
+DBGKD_MANIPULATE_STATE64 m64;
+uint8_t extra[0];
+};
+uint8_t buf[PACKET_MAX_SIZE];
+};
+uint16_t extra_size;
+} PacketData;
+
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
diff --git a/windbgstub.c b/windbgstub.c
index e9aabd807b..395f244d4f 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -19,6 +19,36 @@
 #include "sysemu/kvm.h"
 #include "sysemu/reset.h"
 
+typedef enum ParsingState {
+STATE_LEADER,
+STATE_PACKET_TYPE,
+STATE_PACKET_BYTE_COUNT,
+STATE_PACKET_ID,
+STATE_PACKET_CHECKSUM,
+STATE_PACKET_DATA,
+STATE_TRAILING_BYTE,
+} ParsingState;
+
+typedef enum ParsingResult {
+RESULT_NONE,
+RESULT_BREAKIN_BYTE,
+RESULT_UNKNOWN_PACKET,
+RESULT_CONTROL_PACKET,
+RESULT_DATA_PACKET,
+RESULT_ERROR,
+} ParsingResult;
+
+typedef struct ParsingContext {
+/* index in the current buffer,
+   which depends on the current state */
+int index;
+ParsingState state;
+ParsingResult result;
+KD_PACKET packet;
+PacketData data;
+const char *name;
+} ParsingContext;
+
 typedef struct WindbgState {
 bool is_loaded;
 




[Qemu-devel] [PATCH v4 12/46] windbg: send data and control packets

2017-12-11 Thread Mihail Abakumov
Added functions for send data and control packets to windbg.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |   56 
 1 file changed, 56 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index ace992e2cb..8c33e0de0a 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -60,6 +60,62 @@ typedef struct WindbgState {
 
 static WindbgState *windbg_state;
 
+static uint32_t compute_checksum(uint8_t *data, uint16_t len)
+{
+uint32_t checksum = 0;
+while (len) {
+--len;
+checksum += *data++;
+}
+return checksum;
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_data_packet(uint8_t *data, uint16_t byte_count,
+uint16_t type)
+{
+uint8_t trailing_byte = PACKET_TRAILING_BYTE;
+
+KD_PACKET packet = {
+.PacketLeader = PACKET_LEADER,
+.PacketType = type,
+.ByteCount = byte_count,
+.PacketId = windbg_state->data_packet_id,
+.Checksum = compute_checksum(data, byte_count)
+};
+
+stw_p(, packet.PacketType);
+stw_p(, packet.ByteCount);
+stl_p(, packet.PacketId);
+stl_p(, packet.Checksum);
+
+qemu_chr_fe_write(_state->chr, PTR(packet), sizeof(packet));
+qemu_chr_fe_write(_state->chr, data, byte_count);
+qemu_chr_fe_write(_state->chr, _byte,
+  sizeof(trailing_byte));
+
+windbg_state->data_packet_id ^= 1;
+}
+
+__attribute__ ((unused)) /* unused yet */
+static void windbg_send_control_packet(uint16_t type)
+{
+KD_PACKET packet = {
+.PacketLeader = CONTROL_PACKET_LEADER,
+.PacketType = type,
+.ByteCount = 0,
+.PacketId = windbg_state->ctrl_packet_id,
+.Checksum = 0
+};
+
+stw_p(, packet.PacketType);
+stl_p(, packet.PacketId);
+
+qemu_chr_fe_write(_state->chr, PTR(packet), sizeof(packet));
+
+windbg_state->ctrl_packet_id ^= 1;
+}
+
 static void windbg_ctx_handler(ParsingContext *ctx)
 {}
 




[Qemu-devel] [PATCH v4 28/46] windbg: implemented windbg_write_ks_regs

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |  111 ++
 1 file changed, 111 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index da7d1eae0c..25a0ee8a66 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -645,6 +645,117 @@ static int windbg_read_ks_regs(CPUState *cpu, uint8_t 
*buf, int buf_size,
 static int windbg_write_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
 int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+int mem_size;
+uint8_t *mem_ptr = buf;
+while (len > 0 && offset < sizeof(CPU_KSPECIAL_REGISTERS)) {
+mem_size = 1;
+switch (offset) {
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Cr0):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr0);
+cpu_x86_update_cr0(env, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Cr2):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr2);
+env->cr[2] = ldtul_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Cr3):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr3);
+cpu_x86_update_cr3(env, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Cr4):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Cr4);
+cpu_x86_update_cr4(env, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr0):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr0);
+windbg_set_dr(cpu, 0, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr1):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr1);
+windbg_set_dr(cpu, 1, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr2):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr2);
+windbg_set_dr(cpu, 2, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr3):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr3);
+windbg_set_dr(cpu, 3, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr6):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr6);
+windbg_set_dr(cpu, 6, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, KernelDr7):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, KernelDr7);
+windbg_set_dr(cpu, 7, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Gdtr.Pad):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Gdtr.Pad);
+env->gdt.selector = lduw_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Gdtr.Limit):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Gdtr.Limit);
+env->gdt.limit = lduw_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Gdtr.Base):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Gdtr.Base);
+env->gdt.base = ldtul_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Idtr.Pad):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Idtr.Pad);
+env->idt.selector = lduw_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Idtr.Limit):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Idtr.Limit);
+env->idt.limit = lduw_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Idtr.Base):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Idtr.Base);
+env->idt.base = ldtul_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Tr):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Tr);
+env->tr.selector = lduw_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Ldtr):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Ldtr);
+env->ldt.selector = lduw_p(buf + offset);
+break;
+
+case offsetof(CPU_KSPECIAL_REGISTERS, Reserved):
+mem_size = sizeof_field(CPU_KSPECIAL_REGISTERS, Reserved);
+break;
+
+default:
+WINDBG_ERROR("write_context: Unknown offset %d", offset);
+return -1;
+}
+
+mem_ptr += mem_size;
+offset += mem_size;
+len -= mem_size;
+}
+
 return 0;
 }
 




[Qemu-devel] [PATCH v4 23/46] windbg: implemented kd_api_get_context and kd_api_set_context

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 ++
 target/i386/windbgstub.c|   39 +++
 windbgstub.c|8 
 3 files changed, 49 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 1cee2aed18..d4efabba0b 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -76,6 +76,8 @@ InitedAddr *windbg_get_version(void);
 
 void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_context(CPUState *cpu, PacketData *pd);
+void kd_api_set_context(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 11c35a4207..7558349469 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -273,6 +273,45 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
+static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
+   int offset, int len)
+{
+return 0;
+}
+
+static int windbg_write_context(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len)
+{
+return 0;
+}
+
+void kd_api_get_context(CPUState *cpu, PacketData *pd)
+{
+int err;
+
+pd->extra_size = sizeof(CPU_CONTEXT);
+err = windbg_read_context(cpu, pd->extra, pd->extra_size, 0,
+  pd->extra_size);
+
+if (err) {
+pd->extra_size = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
+void kd_api_set_context(CPUState *cpu, PacketData *pd)
+{
+int err;
+
+err = windbg_write_context(cpu, pd->extra, pd->extra_size, 0,
+   sizeof(CPU_CONTEXT));
+pd->extra_size = 0;
+
+if (err) {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+}
+
 bool windbg_on_load(void)
 {
 CPUState *cpu = qemu_get_cpu(0);
diff --git a/windbgstub.c b/windbgstub.c
index 14caacef81..be40e3e53b 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -148,6 +148,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_virtual_memory(cpu, >data);
 break;
 
+case DbgKdGetContextApi:
+kd_api_get_context(cpu, >data);
+break;
+
+case DbgKdSetContextApi:
+kd_api_set_context(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 36/46] windbg: implemented kd_api_read_io_space and kd_api_write_io_space

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 +
 windbgstub-utils.c  |   62 +++
 windbgstub.c|8 +
 3 files changed, 72 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index b2416d7698..131eb6418a 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -83,6 +83,8 @@ void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_continue(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
+void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
+void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index fe3adb0b88..3f8ce1f8be 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -11,6 +11,7 @@
 
 #include "exec/windbgstub-utils.h"
 #include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
 
 static InitedAddr KPCR;
 static InitedAddr version;
@@ -148,6 +149,67 @@ void kd_api_continue(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_read_io_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_IO64 *io = >m64.u.ReadWriteIo;
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = ldtul_p(>IoAddress);
+uint32_t value = 0;
+
+switch (io->DataSize) {
+case 1:
+value = address_space_ldub(_space_io, addr,
+   cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+case 2:
+value = address_space_lduw(_space_io, addr,
+   cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+case 4:
+value = address_space_ldl(_space_io, addr,
+  cpu_get_mem_attrs(env), NULL);
+stl_p(>DataValue, value);
+break;
+default:
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+}
+
+void kd_api_write_io_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_IO64 *io = >m64.u.ReadWriteIo;
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = ldtul_p(>IoAddress);
+uint32_t value = ldl_p(>DataValue);
+
+switch (io->DataSize) {
+case 1:
+address_space_stb(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+case 2:
+address_space_stw(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+case 4:
+address_space_stl(_space_io, addr, value,
+  cpu_get_mem_attrs(env), NULL);
+break;
+default:
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+return;
+}
+
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index bc59c0903a..a88bfde072 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -168,6 +168,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_restore_breakpoint(cpu, >data);
 break;
 
+case DbgKdReadIoSpaceApi:
+kd_api_read_io_space(cpu, >data);
+break;
+
+case DbgKdWriteIoSpaceApi:
+kd_api_write_io_space(cpu, >data);
+break;
+
 case DbgKdContinueApi:
 case DbgKdContinueApi2:
 kd_api_continue(cpu, >data);




[Qemu-devel] [PATCH v4 43/46] windbg: added new api functions

2017-12-11 Thread Mihail Abakumov
Added some definitions for new windbg.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgkd.h |   21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
index 5008cbb729..aa2b4fdbd9 100755
--- a/include/exec/windbgkd.h
+++ b/include/exec/windbgkd.h
@@ -112,7 +112,10 @@
 #define DbgKdFillMemoryApi  0x315b
 #define DbgKdQueryMemoryApi 0x315c
 #define DbgKdSwitchPartition0x315d
-#define DbgKdMaximumManipulate  0x315e
+#define DbgKdWriteCustomBreakpointApi   0x315e
+#define DbgKdGetContextExApi0x315f
+#define DbgKdSetContextExApi0x3160
+#define DbgKdMaximumManipulate  0x3161
 
 /*
  * Debug I/O Types
@@ -723,6 +726,20 @@ typedef struct _DBGKD_SWITCH_PARTITION {
 uint32_t Partition;
 } DBGKD_SWITCH_PARTITION;
 
+typedef struct _DBGKD_CONTEXT_EX {
+   uint32_t Offset;
+   uint32_t ByteCount;
+   uint32_t BytesCopied;
+} DBGKD_CONTEXT_EX, *PDBGKD_CONTEXT_EX;
+
+typedef struct _DBGKD_WRITE_CUSTOM_BREAKPOINT {
+   uint64_t BreakPointAddress;
+   uint64_t BreakPointInstruction;
+   uint32_t BreakPointHandle;
+   uint16_t BreakPointInstructionSize;
+   uint16_t BreakPointInstructionAlignment;
+} DBGKD_WRITE_CUSTOM_BREAKPOINT, *PDBGKD_WRITE_CUSTOM_BREAKPOINT;
+
 /*
  * DBGKD Structure for Manipulate
  */
@@ -787,6 +804,8 @@ typedef struct _DBGKD_MANIPULATE_STATE64 {
 DBGKD_FILL_MEMORY FillMemory;
 DBGKD_QUERY_MEMORY QueryMemory;
 DBGKD_SWITCH_PARTITION SwitchPartition;
+DBGKD_WRITE_CUSTOM_BREAKPOINT WriteCustomBreakpoint;
+DBGKD_CONTEXT_EX ContextEx;
 } u;
 } DBGKD_MANIPULATE_STATE64, *PDBGKD_MANIPULATE_STATE64;
 




[Qemu-devel] [PATCH v4 39/46] windbg: implemented kd_api_read_msr and kd_api_write_msr

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 
 target/i386/windbgstub.c|  328 +++
 windbgstub.c|8 +
 3 files changed, 338 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 8cdb27..6e73ef973c 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -88,6 +88,8 @@ void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_version(CPUState *cpu, PacketData *pd);
+void kd_api_read_msr(CPUState *cpu, PacketData *pd);
+void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 5e094e81d7..7985dcfaf0 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -1007,6 +1007,334 @@ void kd_api_write_control_space(CPUState *cpu, 
PacketData *pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+#if defined(CONFIG_USER_ONLY)
+void kd_api_read_msr(CPUState *cpu, PacketData *pd)
+{
+}
+
+void kd_api_write_msr(CPUState *cpu, PacketData *pd)
+{
+}
+#else
+void kd_api_read_msr(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_WRITE_MSR *m64c = >m64.u.ReadWriteMsr;
+CPUArchState *env = cpu->env_ptr;
+
+uint64_t val;
+
+cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, 0);
+
+switch ((uint32_t)env->regs[R_ECX]) {
+case MSR_IA32_SYSENTER_CS:
+val = env->sysenter_cs;
+break;
+case MSR_IA32_SYSENTER_ESP:
+val = env->sysenter_esp;
+break;
+case MSR_IA32_SYSENTER_EIP:
+val = env->sysenter_eip;
+break;
+case MSR_IA32_APICBASE:
+val = cpu_get_apic_base(x86_env_get_cpu(env)->apic_state);
+break;
+case MSR_EFER:
+val = env->efer;
+break;
+case MSR_STAR:
+val = env->star;
+break;
+case MSR_PAT:
+val = env->pat;
+break;
+case MSR_VM_HSAVE_PA:
+val = env->vm_hsave;
+break;
+case MSR_IA32_PERF_STATUS:
+/* tsc_increment_by_tick */
+val = 1000ULL;
+/* CPU multiplier */
+val |= (((uint64_t)4ULL) << 40);
+break;
+#ifdef TARGET_X86_64
+case MSR_LSTAR:
+val = env->lstar;
+break;
+case MSR_CSTAR:
+val = env->cstar;
+break;
+case MSR_FMASK:
+val = env->fmask;
+break;
+case MSR_FSBASE:
+val = env->segs[R_FS].base;
+break;
+case MSR_GSBASE:
+val = env->segs[R_GS].base;
+break;
+case MSR_KERNELGSBASE:
+val = env->kernelgsbase;
+break;
+case MSR_TSC_AUX:
+val = env->tsc_aux;
+break;
+#endif
+case MSR_MTRRphysBase(0):
+case MSR_MTRRphysBase(1):
+case MSR_MTRRphysBase(2):
+case MSR_MTRRphysBase(3):
+case MSR_MTRRphysBase(4):
+case MSR_MTRRphysBase(5):
+case MSR_MTRRphysBase(6):
+case MSR_MTRRphysBase(7):
+val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysBase(0)) / 2].base;
+break;
+case MSR_MTRRphysMask(0):
+case MSR_MTRRphysMask(1):
+case MSR_MTRRphysMask(2):
+case MSR_MTRRphysMask(3):
+case MSR_MTRRphysMask(4):
+case MSR_MTRRphysMask(5):
+case MSR_MTRRphysMask(6):
+case MSR_MTRRphysMask(7):
+val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
+ MSR_MTRRphysMask(0)) / 2].mask;
+break;
+case MSR_MTRRfix64K_0:
+val = env->mtrr_fixed[0];
+break;
+case MSR_MTRRfix16K_8:
+case MSR_MTRRfix16K_A:
+val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+  MSR_MTRRfix16K_8 + 1];
+break;
+case MSR_MTRRfix4K_C:
+case MSR_MTRRfix4K_C8000:
+case MSR_MTRRfix4K_D:
+case MSR_MTRRfix4K_D8000:
+case MSR_MTRRfix4K_E:
+case MSR_MTRRfix4K_E8000:
+case MSR_MTRRfix4K_F:
+case MSR_MTRRfix4K_F8000:
+val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
+  MSR_MTRRfix4K_C + 3];
+break;
+case MSR_MTRRdefType:
+val = env->mtrr_deftype;
+break;
+case MSR_MTRRcap:
+if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
+val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
+MSR_MTRRcap_WC_SUPPORTED;
+} else {
+/* XXX: exception? */
+val = 0;
+}
+break;
+case MSR_MCG_CAP:
+val = env->mcg_cap;
+break;
+case MSR_MCG_CTL:
+if 

[Qemu-devel] [PATCH v4 40/46] windbg: implemented kd_api_search_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   33 +
 windbgstub.c|4 
 3 files changed, 38 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 6e73ef973c..a58c47d359 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -90,6 +90,7 @@ void kd_api_write_physical_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_read_msr(CPUState *cpu, PacketData *pd);
 void kd_api_write_msr(CPUState *cpu, PacketData *pd);
+void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 7ef301bac7..79899d3295 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -261,6 +261,39 @@ void kd_api_get_version(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_search_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_SEARCH_MEMORY *m64c = >m64.u.SearchMemory;
+int s_len = MAX(ldq_p(>SearchLength), 1);
+int p_len = MIN(ldl_p(>PatternLength), pd->extra_size);
+target_ulong addr = ldq_p(>SearchAddress);
+int size = MIN(s_len, 1024);
+uint8_t mem[size + p_len];
+int i, err;
+
+pd->extra_size = 0;
+pd->m64.ReturnStatus = STATUS_NO_MORE_ENTRIES;
+
+while (s_len) {
+err = cpu_memory_rw_debug(cpu, addr, mem, size + p_len, 0);
+if (!err) {
+for (i = 0; i < size; ++i) {
+if (memcmp(mem + i, pd->extra, p_len) == 0) {
+stl_p(>FoundAddress, addr + i);
+pd->m64.ReturnStatus = STATUS_SUCCESS;
+return;
+}
+}
+} else {
+WINDBG_DEBUG("search_memory: No physical page mapped: " FMT_ADDR,
+ addr);
+}
+s_len -= size;
+addr += size;
+size = MIN(s_len, 1024);
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 45f61917d9..3dcac03be1 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -212,6 +212,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 
+case DbgKdSearchMemoryApi:
+kd_api_search_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v1 for-2-12 04/15] s390x/flic: simplify flic initialization

2017-12-11 Thread David Hildenbrand
This makes it clearer, which device is used for which accelerator.

Signed-off-by: David Hildenbrand 
---
 hw/intc/s390_flic.c  |  9 +++--
 hw/intc/s390_flic_kvm.c  | 12 
 include/hw/s390x/s390_flic.h |  9 -
 3 files changed, 7 insertions(+), 23 deletions(-)

diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index 6eaf178d79..a78bdf1d90 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -40,11 +40,16 @@ void s390_flic_init(void)
 {
 DeviceState *dev;
 
-dev = s390_flic_kvm_create();
-if (!dev) {
+if (kvm_enabled()) {
+dev = qdev_create(NULL, TYPE_KVM_S390_FLIC);
+object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC,
+  OBJECT(dev), NULL);
+} else if (tcg_enabled()) {
 dev = qdev_create(NULL, TYPE_QEMU_S390_FLIC);
 object_property_add_child(qdev_get_machine(), TYPE_QEMU_S390_FLIC,
   OBJECT(dev), NULL);
+} else {
+g_assert_not_reached();
 }
 qdev_init_nofail(dev);
 }
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index d208cb81c4..0cb5feab0c 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -35,18 +35,6 @@ typedef struct KVMS390FLICState {
 bool clear_io_supported;
 } KVMS390FLICState;
 
-DeviceState *s390_flic_kvm_create(void)
-{
-DeviceState *dev = NULL;
-
-if (kvm_enabled()) {
-dev = qdev_create(NULL, TYPE_KVM_S390_FLIC);
-object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC,
-  OBJECT(dev), NULL);
-}
-return dev;
-}
-
 /**
  * flic_get_all_irqs - store all pending irqs in buffer
  * @buf: pointer to buffer which is passed to kernel
diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h
index 7aab6ef7f0..5b00e936fa 100644
--- a/include/hw/s390x/s390_flic.h
+++ b/include/hw/s390x/s390_flic.h
@@ -91,13 +91,4 @@ void s390_flic_init(void);
 S390FLICState *s390_get_flic(void);
 bool ais_needed(void *opaque);
 
-#ifdef CONFIG_KVM
-DeviceState *s390_flic_kvm_create(void);
-#else
-static inline DeviceState *s390_flic_kvm_create(void)
-{
-return NULL;
-}
-#endif
-
 #endif /* HW_S390_FLIC_H */
-- 
2.14.3




Re: [Qemu-devel] [RFC] vhost: check if ring mapping is still valid when building memmap

2017-12-11 Thread Igor Mammedov
On Mon, 11 Dec 2017 11:03:00 +
"Dr. David Alan Gilbert"  wrote:

> * Igor Mammedov (imamm...@redhat.com) wrote:
> > On Fri, 8 Dec 2017 17:51:56 +
> > "Dr. David Alan Gilbert"  wrote:
> >   
> > > * Igor Mammedov (imamm...@redhat.com) wrote:  
> > > > On Thu, 7 Dec 2017 18:17:51 +
> > > > "Dr. David Alan Gilbert"  wrote:
> > > > 
> > > > > * Igor Mammedov (imamm...@redhat.com) wrote:
> > > > > > vhost_verify_ring_mappings() were used to verify that
> > > > > > rings are still accessible and related memory hasn't
> > > > > > been moved after flatview is updated.
> > > > > > 
> > > > > > It were doing checks by mapping ring's GPA+len and
> > > > > > checking that HVA hasn't changed with new memory map.
> > > > > > To avoid maybe expensive mapping call, we were
> > > > > > identifying address range that changed and were doing
> > > > > > mapping only if ring were in changed range.
> > > > > > 
> > > > > > However it's no neccessary to perform ringi's GPA
> > > > > > mapping as we already have it's current HVA and all
> > > > > > we need is to verify that ring's GPA translates to
> > > > > > the same HVA in updated flatview.
> > > > > > 
> > > > > > That could be done during time when we are building
> > > > > > vhost memmap where vhost_update_mem_cb() already maps
> > > > > > every RAM MemoryRegionSection to get section HVA. This
> > > > > > fact can be used to check that ring belongs to the same
> > > > > > MemoryRegion in the same place, like this:
> > > > > > 
> > > > > >   hva_ring_offset = GPA(ring) - GPA(MemoryRegionSection)
> > > > > >   ring_hva == HVA(MemoryRegionSection) + hva_ring_offset
> > > > > > 
> > > > > > Doing this would allow us to drop ~100LOC of code which
> > > > > > figures out changed memory range and avoid calling not
> > > > > > needed reverse vhost_memory_map(is_write=true) which is
> > > > > > overkill for the task at hand.  
> > > > > 
> > > > > There are a few things about this I don't understand; however if
> > > > > it's right I agree that it means we can kill off my comparison
> > > > > code.
> > > > > 
> > > > > 
> > > > > First, can I check what constraints 'verify_ring' needs to check;
> > > > > if I'm understanding the original code it's checking that :
> > > > > a) If a queue falls within a region, that the whole queue can
> > > > >be mapped
> > > >  see vhost_verify_ring_part_mapping():
> > > > 
> > > >  p = vhost_memory_map(dev, part_addr, , 1);   
> > > >   
> > > >  if (!p || l != part_size) 
> > > >   error_out
> > > >  
> > > >  1st: (!p) requested part_addr must be mapped
> > > >   i.e. be a part of MemorySection in flatview
> > > >  AND
> > > >  2nd: (l != part_size) mapped range size must match what we 
> > > > asked for
> > > >   i.e. mapped as continuous range so that
> > > >  [GPA, GPA + part_size) could directly correspond to 
> > > > [HVA, HVA + part_size)
> > > >   and that's is possible only withing 1 MemorySection && 1 
> > > > MeoryRegion
> > > >   if I read address_space_map() correctly
> > > >  flatview_translate() -> GPA's MemorySection
> > > >  flatview_extend_translation() -> 1:1 GPA->HVA 
> > > > range size
> > > >   
> > > >  So answer in case of RAM memory region that we are interested 
> > > > in, would be:
> > > >  queue falls within a MemorySection and whole queue fits in to 
> > > > it
> > > 
> > > Yes, OK.
> > >   
> > > > > b) And the start of the queue corresponds to where we thought
> > > > >it used to be (in GPA?)
> > > >  that cached at vq->desc queue HVA hasn't changed after 
> > > > flatview change
> > > > if (p != part)
> > > >error_out
> > > 
> > > OK, so it's the HVA that's not changed based on taking the part_addr
> > > which is GPA and checking the map?  
> > Yes, I think so.
> >   
> > > > >so that doesn't have any constraint on the ordering of the regions
> > > > >or whether the region is the same size or anything.
> > > > >   Also I don't think it would spot if there was a qeueue that had no
> > > > >   region associated with it at all.
> > > > > 
> > > > > Now, comments on your code below:
> > > > > 
> > > > > 
> > > > > > Signed-off-by: Igor Mammedov 
> > > > > > ---
> > > > > > PS:
> > > > > >should be applied on top of David's series
> > > > > > 
> > > > > > ---
> > > > > >  include/hw/virtio/vhost.h |   2 -
> > > > > >  hw/virtio/vhost.c | 195 
> > > > > > ++
> > > > > >  2 files changed, 57 insertions(+), 140 deletions(-)
> > > > > > 
> > > > > > diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
> > > > > > index 

Re: [Qemu-devel] [qemu-s390x] [PATCH v3 1/1] s390-ccw-virtio: allow for systems larger that 7.999TB

2017-12-11 Thread David Hildenbrand
On 11.12.2017 13:21, Christian Borntraeger wrote:
> KVM does not allow memory regions > KVM_MEM_MAX_NR_PAGES, basically
> limiting the memory per slot to 8TB-4k. As memory slots on s390/kvm must
> be a multiple of 1MB we need start a new memory region if we cross
> 8TB-1M.
> 
> With that (and optimistic overcommitment in the kernel) I was able to
> start a 24TB guest on a 1TB system.
> 
> Signed-off-by: Christian Borntraeger 
> ---
>  hw/s390x/s390-virtio-ccw.c | 28 +---
>  1 file changed, 25 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 8425534..073f6ed 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -154,14 +154,36 @@ static void virtio_ccw_register_hcalls(void)
> virtio_ccw_hcall_early_printk);
>  }
>  
> +/*
> + * KVM does only support memory slots up to KVM_MEM_MAX_NR_PAGES pages
> + * as the dirty bitmap must be managed by bitops that take an int as
> + * position indicator. If we have a guest beyond that we will split off
> + * new subregions. The split must happen on a segment boundary (1MB).
> + */
> +#define KVM_MEM_MAX_NR_PAGES ((1UL << 31) - 1)
> +#define SEG_MSK (~0xfULL)
> +#define KVM_SLOT_MAX_BYTES ((KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE) & 
> SEG_MSK)

Just wondering if we could get into trouble when calculating

KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE

on a host with sizeof(long) == 4

could it wrap? (e.g. crazy mingw stuff)

>  static void s390_memory_init(ram_addr_t mem_size)
>  {
>  MemoryRegion *sysmem = get_system_memory();
> -MemoryRegion *ram = g_new(MemoryRegion, 1);
> +ram_addr_t chunk, offset = 0;
> +unsigned int number = 0;
> +gchar *name;
>  
>  /* allocate RAM for core */
> -memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
> -memory_region_add_subregion(sysmem, 0, ram);
> +name = g_strdup_printf("s390.ram");
> +while (mem_size) {
> +MemoryRegion *ram = g_new(MemoryRegion, 1);

I'd add an empty line here.

Reviewed-by: David Hildenbrand 

> +/* KVM does not allow memslots >= 8 TB */
> +chunk = MIN(mem_size, KVM_SLOT_MAX_BYTES);
> +memory_region_allocate_system_memory(ram, NULL, name, chunk);
> +memory_region_add_subregion(sysmem, offset, ram);
> +mem_size -= chunk;
> +offset += chunk;
> +g_free(name);
> +name = g_strdup_printf("s390.ram.%u", ++number);
> +}
> +g_free(name);
>  
>  /* Initialize storage key device */
>  s390_skeys_init();
> 


-- 

Thanks,

David / dhildenb



[Qemu-devel] [PATCH v1 for-2-12 02/15] cpu-exec: fix missed CPU kick during interrupt injection

2017-12-11 Thread David Hildenbrand
The conditional memory barrier not only looks strange but actually is
wrong.

On s390x, I can reproduce interrupts via cpu_interrupt() not leading to
a proper kick out of emulation every now and then. cpu_interrupt() is
especially used for inter CPU communication via SIGP (esp. external
calls and emergency interrupts).

With this patch, I was not able to reproduce. (esp. no stalls or hangs
in the guest).

My setup is s390x MTTCG with 16 VCPUs on 8 CPU host, running make -j16.

Signed-off-by: David Hildenbrand 
---
 accel/tcg/cpu-exec.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 9b544d88c8..dfba5ebd29 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -525,19 +525,15 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
 TranslationBlock **last_tb)
 {
 CPUClass *cc = CPU_GET_CLASS(cpu);
-int32_t insns_left;
 
 /* Clear the interrupt flag now since we're processing
  * cpu->interrupt_request and cpu->exit_request.
  */
-insns_left = atomic_read(>icount_decr.u32);
 atomic_set(>icount_decr.u16.high, 0);
-if (unlikely(insns_left < 0)) {
-/* Ensure the zeroing of icount_decr comes before the next read
- * of cpu->exit_request or cpu->interrupt_request.
- */
-smp_mb();
-}
+/* Ensure zeroing happens before reading cpu->exit_request or
+ * cpu->interrupt_request. (also see cpu_exit())
+ */
+smp_mb();
 
 if (unlikely(atomic_read(>interrupt_request))) {
 int interrupt_request;
-- 
2.14.3




Re: [Qemu-devel] [PATCH v6 3/4] contrib/libvhost-user: enable virtio config space messages

2017-12-11 Thread Stefan Hajnoczi
On Tue, Dec 05, 2017 at 02:27:18PM +0800, Changpeng Liu wrote:
> @@ -798,6 +801,70 @@ vu_set_slave_req_fd(VuDev *dev, VhostUserMsg *vmsg)
>  }
>  
>  static bool
> +vu_get_config(VuDev *dev, VhostUserMsg *vmsg)
> +{
> +int ret = -1;
> +
> +if (dev->iface->get_config) {
> +ret = dev->iface->get_config(dev, vmsg->payload.config.region,
> + vmsg->payload.config.size);
> +}
> +
> +if (ret) {
> +/* resize to zero to indicate an error to master */
> +vmsg->size = 0;
> +}

Please document this error case in vhost-user.txt.  I don't remember
reading about it.


signature.asc
Description: PGP signature


Re: [Qemu-devel] [v22 1/2] virtio-crypto: Add virtio crypto device specification

2017-12-11 Thread Michael S. Tsirkin
On Mon, Dec 11, 2017 at 02:54:25PM +0100, Halil Pasic wrote:
> * I assume one request is supposed to correspond to one descriptor chain.
> Right? If yes, could you tell me, where is this expressed in the spec.
> 
> Halil

That's always the default for all virtio devices, exceptions have to
be noted in spec.



Re: [Qemu-devel] [PATCH v6 4/4] contrib/vhost-user-blk: introduce a vhost-user-blk sample application

2017-12-11 Thread Stefan Hajnoczi
> +static int vub_virtio_process_req(VubDev *vdev_blk,
> + VuVirtq *vq)
> +{
> +VugDev *gdev = _blk->parent;
> +VuDev *vu_dev = >parent;
> +VuVirtqElement *elem;
> +uint32_t type;
> +unsigned in_num;
> +unsigned out_num;
> +VubReq *req;
> +
> +elem = vu_queue_pop(vu_dev, vq, sizeof(VuVirtqElement));
> +if (!elem) {
> +return -1;
> +}
> +
> +/* refer to hw/block/virtio_blk.c */
> +if (elem->out_num < 1 || elem->in_num < 1) {
> +fprintf(stderr, "virtio-blk request missing headers\n");
> +free(elem);
> +return -1;
> +}
> +
> +req = g_new0(VubReq, 1);
> +req->vdev_blk = vdev_blk;
> +req->vq = vq;
> +req->elem = elem;
> +
> +in_num = elem->in_num;
> +out_num = elem->out_num;
> +
> +/* don't support VIRTIO_F_ANY_LAYOUT and virtio 1.0 only */
> +if (elem->out_sg[0].iov_len < sizeof(struct virtio_blk_outhdr)) {
> +fprintf(stderr, "Invalid outhdr size\n");
> +goto err;
> +}

QEMU has iov_discard_front() and iov_discard_back().  They make it
pretty easy to support VIRTIO_F_ANY_LAYOUT.  If you have time, please
consider adding it to libvhost-user, but it's not a requirement for this
patch series.

> +req->out = (struct virtio_blk_outhdr *)elem->out_sg[0].iov_base;
> +out_num--;
> +
> +if (elem->in_sg[in_num - 1].iov_len < sizeof(struct virtio_blk_inhdr)) {
> +fprintf(stderr, "Invalid inhdr size\n");
> +goto err;
> +}
> +req->in = (struct virtio_blk_inhdr *)elem->in_sg[in_num - 1].iov_base;
> +in_num--;
> +
> +type = le32toh(req->out->type);

Endianness is more complicated if you want to support both VIRTIO 1.0
and Legacy (0.9.7).  I guess it's okay to make libvhost-user code only
support VIRTIO 1.0.
> +static void vub_queue_set_started(VuDev *vu_dev, int idx, bool started)
> +{
> +VuVirtq *vq;
> +
> +assert(vu_dev);
> +
> +if ((idx < 0) || (idx >= VHOST_MAX_NR_VIRTQUEUE)) {
> +fprintf(stderr, "VQ Index out of range: %d\n", idx);
> +vub_panic_cb(vu_dev, NULL);
> +return;
> +}

Is it necessary to check num_queues?  The vhost-user master should not
be able to enable idx >= num_queues.


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v1 00/19] re-factor softfloat and add fp16 functions

2017-12-11 Thread Alex Bennée
Hi,

In my previous run at this I'd simply taken the existing float32
functions and attempted to copy and paste the code changing the
relevant constants. Apart from the usual typos and missed bits there
were sections where softfloat pulls tricks because it knows the exact
bit positions of things. While I'm sure it's marginally faster it does
make the code rather impenetrable to someone not familiar with how
SoftFloat does things. One thing the last few months have taught me is
the world is not awash with experts on the finer implementation
details of floating point maths. After reviewing the last series
Richard Henderson suggested a different approach which pushed most of
the code into common shared functions. The majority of the work on the
fractional bits is done in 64 bit resolution which leaves plenty of
spare bits for rounding for everything from float16 to float64. This
series is a result of that work and a coding sprint we did 2 weeks ago
in Cambridge.

We've not touched anything that needs higher precision which at the
moment is float80 and 128 bit quad precision operations. They would
need similar decomposed routines to operate on the higher precision
fractional parts. I suspect we'd need to beef up our Int128 wrapper in
the process so it can be done efficiently with 128 bit maths.

This work is part of the larger chunk of adding half-precision ops to
the ARM front-end. However I've split the series up to make for a less
messy review. This tree can be found at:

  https://github.com/stsquad/qemu/tree/softfloat-refactor-and-fp16-v1

While I have been testing the half-precision stuff in the ARM
specific tree this series is all common code. It has however been
tested with ARM RISU which exercises the float32/64 code paths quite
nicely.

Any additional testing appreciated.

Series Breakdown


The first five patches are simple helper functions that are mostly
inline and there for the benefit of architecture helper functions.
This includes the float16 constants in the final patch.

The next two patches fixed a bug in NaN propagation which only showed
up when doing ARM "Reduction" operations in float16. Although the
minmax code is totally replaced later on I wanted to fix it in place
first rather than add the fix when it was re-written.

The next two patches start preparing the ground for the new decomposed
functions and their public APIs. I've used macro expansion in a few
places just to avoid the amount of repeated boiler-plate for these
APIs. Most of the work is done in the static decompose_foo functions.

As you can see in the diffstat there is an overall code reduction even
though we have also added float16 support. For reference the previous
attempt added 1258 lines of code to implement a subset of the float16
functions. I think the code is also a lot easier to follow and reason
about.

Alex Bennée (19):
  fpu/softfloat: implement float16_squash_input_denormal
  include/fpu/softfloat: implement float16_abs helper
  include/fpu/softfloat: implement float16_chs helper
  include/fpu/softfloat: implement float16_set_sign helper
  include/fpu/softfloat: add some float16 contants
  fpu/softfloat: propagate signalling NaNs in MINMAX
  fpu/softfloat: improve comments on ARM NaN propagation
  fpu/softfloat: move the extract functions to the top of the file
  fpu/softfloat: define decompose structures
  fpu/softfloat: re-factor add/sub
  fpu/softfloat: re-factor mul
  fpu/softfloat: re-factor div
  fpu/softfloat: re-factor muladd
  fpu/softfloat: re-factor round_to_int
  fpu/softfloat: re-factor float to int/uint
  fpu/softfloat: re-factor int/uint to float
  fpu/softfloat: re-factor scalbn
  fpu/softfloat: re-factor minmax
  fpu/softfloat: re-factor compare

 fpu/softfloat-macros.h |   44 +
 fpu/softfloat-specialize.h |  115 +-
 fpu/softfloat.c| 6668 
 include/fpu/softfloat.h|   89 +-
 4 files changed, 3066 insertions(+), 3850 deletions(-)

-- 
2.15.1




[Qemu-devel] [PATCH v1 02/19] include/fpu/softfloat: implement float16_abs helper

2017-12-11 Thread Alex Bennée
This will be required when expanding the MINMAX() macro for 16
bit/half-precision operations.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
---
 include/fpu/softfloat.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index d5e99667b6..edf402d422 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -374,6 +374,13 @@ static inline int float16_is_zero_or_denormal(float16 a)
 return (float16_val(a) & 0x7c00) == 0;
 }
 
+static inline float16 float16_abs(float16 a)
+{
+/* Note that abs does *not* handle NaN specially, nor does
+ * it flush denormal inputs to zero.
+ */
+return make_float16(float16_val(a) & 0x7fff);
+}
 /*
 | The pattern for a default generated half-precision NaN.
 **/
-- 
2.15.1




[Qemu-devel] [PATCH v1 03/19] include/fpu/softfloat: implement float16_chs helper

2017-12-11 Thread Alex Bennée
Signed-off-by: Alex Bennée 
---
 include/fpu/softfloat.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index edf402d422..32036382c6 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -381,6 +381,15 @@ static inline float16 float16_abs(float16 a)
  */
 return make_float16(float16_val(a) & 0x7fff);
 }
+
+static inline float16 float16_chs(float16 a)
+{
+/* Note that chs does *not* handle NaN specially, nor does
+ * it flush denormal inputs to zero.
+ */
+return make_float16(float16_val(a) ^ 0x8000);
+}
+
 /*
 | The pattern for a default generated half-precision NaN.
 **/
-- 
2.15.1




[Qemu-devel] [PATCH v1 15/19] fpu/softfloat: re-factor float to int/uint

2017-12-11 Thread Alex Bennée
We share the common int64/uint64_pack_decomposed function across all
the helpers and simply limit the final result depending on the final
size.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 1000 ++-
 include/fpu/softfloat.h |   13 +
 2 files changed, 224 insertions(+), 789 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9914ecb783..d7858bdae5 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1312,6 +1312,183 @@ float64 float64_trunc_to_int(float64 a, float_status *s)
 return float64_round_pack_canonical(pr, s);
 }
 
+/*
+| Returns the result of converting the floating-point value
+| `a' to the two's complement integer format.  The conversion is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic---which means in particular that the conversion is rounded
+| according to the current rounding mode.  If `a' is a NaN, the largest
+| positive integer is returned.  Otherwise, if the conversion overflows, the
+| largest integer with the same sign as `a' is returned.
+**/
+
+static int64_t int64_pack_decomposed(decomposed_parts p, float_status *s)
+{
+uint64_t r;
+
+switch (p.cls) {
+case float_class_snan:
+case float_class_qnan:
+return INT64_MAX;
+case float_class_inf:
+return p.sign ? INT64_MIN : INT64_MAX;
+case float_class_zero:
+return 0;
+case float_class_normal:
+if (p.exp < DECOMPOSED_BINARY_POINT) {
+r = p.frac >> (DECOMPOSED_BINARY_POINT - p.exp);
+} else if (p.exp < 64) {
+r = p.frac << (p.exp - DECOMPOSED_BINARY_POINT);
+} else {
+s->float_exception_flags |= float_flag_invalid;
+r = UINT64_MAX;
+}
+if (p.sign) {
+return r < - (uint64_t) INT64_MIN ? -r : INT64_MIN;
+} else {
+return r < INT64_MAX ? r : INT64_MAX;
+}
+default:
+g_assert_not_reached();
+}
+}
+
+static int16_t int16_pack_decomposed(decomposed_parts p, float_status *s)
+{
+int64_t r = int64_pack_decomposed(p, s);
+if (r < INT16_MIN) {
+s->float_exception_flags |= float_flag_invalid;
+return INT16_MIN;
+} else if (r > INT16_MAX) {
+s->float_exception_flags |= float_flag_invalid;
+return INT16_MAX;
+}
+return r;
+}
+
+static int32_t int32_pack_decomposed(decomposed_parts p, float_status *s)
+{
+int64_t r = int64_pack_decomposed(p, s);
+if (r < INT32_MIN) {
+s->float_exception_flags |= float_flag_invalid;
+return INT32_MIN;
+} else if (r > INT32_MAX) {
+s->float_exception_flags |= float_flag_invalid;
+return INT32_MAX;
+}
+return r;
+}
+
+#define FLOAT_TO_INT(fsz, isz) \
+int ## isz ## _t float ## fsz ## _to_int ## isz(float ## fsz a, float_status 
*s) \
+{   \
+decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s);  \
+decomposed_parts pr = round_decomposed(pa, s->float_rounding_mode, s); \
+return int ## isz ## _pack_decomposed(pr, s);   \
+}   \
+\
+int ## isz ## _t float ## fsz ## _to_int ## isz ## _round_to_zero   \
+ (float ## fsz a, float_status *s)  \
+{   \
+decomposed_parts pa = float ## fsz ## _unpack_canonical(a, s);  \
+decomposed_parts pr = round_decomposed(pa, float_round_to_zero, s); \
+return int ## isz ## _pack_decomposed(pr, s);   \
+}
+
+FLOAT_TO_INT(16, 16)
+FLOAT_TO_INT(16, 32)
+FLOAT_TO_INT(16, 64)
+
+FLOAT_TO_INT(32, 16)
+FLOAT_TO_INT(32, 32)
+FLOAT_TO_INT(32, 64)
+
+FLOAT_TO_INT(64, 16)
+FLOAT_TO_INT(64, 32)
+FLOAT_TO_INT(64, 64)
+
+#undef FLOAT_TO_INT
+
+/*
+| Returns the result of converting the  floating-point value
+| `a' to the unsigned integer format.  The conversion is
+| performed according to the IEC/IEEE Standard for Binary Floating-Point
+| Arithmetic---which means in particular that the conversion is rounded
+| according to the current rounding mode.  If `a' is a NaN, the largest
+| unsigned integer is returned.  Otherwise, if the conversion overflows, the
+| largest unsigned integer is returned.  If the 'a' is negative, the result
+| is rounded and zero is returned; values that do not round to zero will
+| raise the inexact exception flag.
+**/
+
+static uint64_t 

[Qemu-devel] [PATCH v1 10/19] fpu/softfloat: re-factor add/sub

2017-12-11 Thread Alex Bennée
We can now add float16_add/sub and use the common decompose and
canonicalize functions to have a single implementation for
float16/32/64 add and sub functions.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 903 +---
 include/fpu/softfloat.h |   4 +
 2 files changed, 480 insertions(+), 427 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index fe443ff234..f89e47e3ef 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -195,7 +195,7 @@ typedef enum {
 float_class_zero,
 float_class_normal,
 float_class_inf,
-float_class_qnan,
+float_class_qnan,  /* all NaNs from here */
 float_class_snan,
 float_class_dnan,
 float_class_msnan, /* maybe silenced */
@@ -254,6 +254,481 @@ static const decomposed_params float64_params = {
 FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52)
 };
 
+/* Unpack a float16 to parts, but do not canonicalize.  */
+static inline decomposed_parts float16_unpack_raw(float16 f)
+{
+return (decomposed_parts){
+.cls = float_class_unclassified,
+.sign = extract32(f, 15, 1),
+.exp = extract32(f, 10, 5),
+.frac = extract32(f, 0, 10)
+};
+}
+
+/* Unpack a float32 to parts, but do not canonicalize.  */
+static inline decomposed_parts float32_unpack_raw(float32 f)
+{
+return (decomposed_parts){
+.cls = float_class_unclassified,
+.sign = extract32(f, 31, 1),
+.exp = extract32(f, 23, 8),
+.frac = extract32(f, 0, 23)
+};
+}
+
+/* Unpack a float64 to parts, but do not canonicalize.  */
+static inline decomposed_parts float64_unpack_raw(float64 f)
+{
+return (decomposed_parts){
+.cls = float_class_unclassified,
+.sign = extract64(f, 63, 1),
+.exp = extract64(f, 52, 11),
+.frac = extract64(f, 0, 52),
+};
+}
+
+/* Pack a float32 from parts, but do not canonicalize.  */
+static inline float16 float16_pack_raw(decomposed_parts p)
+{
+uint32_t ret = p.frac;
+ret = deposit32(ret, 10, 5, p.exp);
+ret = deposit32(ret, 15, 1, p.sign);
+return make_float16(ret);
+}
+
+/* Pack a float32 from parts, but do not canonicalize.  */
+static inline float32 float32_pack_raw(decomposed_parts p)
+{
+uint32_t ret = p.frac;
+ret = deposit32(ret, 23, 8, p.exp);
+ret = deposit32(ret, 31, 1, p.sign);
+return make_float32(ret);
+}
+
+/* Pack a float64 from parts, but do not canonicalize.  */
+static inline float64 float64_pack_raw(decomposed_parts p)
+{
+uint64_t ret = p.frac;
+ret = deposit64(ret, 52, 11, p.exp);
+ret = deposit64(ret, 63, 1, p.sign);
+return make_float64(ret);
+}
+
+/* Canonicalize EXP and FRAC, setting CLS.  */
+static decomposed_parts decomposed_canonicalize(decomposed_parts part,
+const decomposed_params *parm,
+float_status *status)
+{
+if (part.exp == parm->exp_max) {
+if (part.frac == 0) {
+part.cls = float_class_inf;
+} else {
+#ifdef NO_SIGNALING_NANS
+part.cls = float_class_qnan;
+#else
+int64_t msb = part.frac << (parm->frac_shift + 2);
+if ((msb < 0) == status->snan_bit_is_one) {
+part.cls = float_class_snan;
+} else {
+part.cls = float_class_qnan;
+}
+#endif
+}
+} else if (part.exp == 0) {
+if (likely(part.frac == 0)) {
+part.cls = float_class_zero;
+} else if (status->flush_inputs_to_zero) {
+float_raise(float_flag_input_denormal, status);
+part.cls = float_class_zero;
+part.frac = 0;
+} else {
+int shift = clz64(part.frac) - 1;
+part.cls = float_class_normal;
+part.exp = parm->frac_shift - parm->exp_bias - shift + 1;
+part.frac <<= shift;
+}
+} else {
+part.cls = float_class_normal;
+part.exp -= parm->exp_bias;
+part.frac = DECOMPOSED_IMPLICIT_BIT + (part.frac << parm->frac_shift);
+}
+return part;
+}
+
+/* Round and uncanonicalize a floating-point number by parts.
+   There are FRAC_SHIFT bits that may require rounding at the bottom
+   of the fraction; these bits will be removed.  The exponent will be
+   biased by EXP_BIAS and must be bounded by [EXP_MAX-1, 0].  */
+static decomposed_parts decomposed_round_canonical(decomposed_parts p,
+   float_status *s,
+   const decomposed_params 
*parm)
+{
+const uint64_t frac_lsbm1 = parm->frac_lsbm1;
+const uint64_t round_mask = parm->round_mask;
+const uint64_t roundeven_mask = parm->roundeven_mask;
+const int exp_max = parm->exp_max;
+const int frac_shift = parm->frac_shift;
+uint64_t frac, inc;
+int exp, flags = 0;
+bool overflow_norm;
+
+frac = p.frac;
+exp = 

[Qemu-devel] [PATCH v1 19/19] fpu/softfloat: re-factor compare

2017-12-11 Thread Alex Bennée
Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 135 +---
 include/fpu/softfloat.h |   2 +
 2 files changed, 83 insertions(+), 54 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 5eba996932..31b437e000 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1793,6 +1793,87 @@ MINMAX(64, maxnummag, false, true, true)
 
 #undef MINMAX
 
+/* Floating point compare */
+static int compare_decomposed(decomposed_parts a, decomposed_parts b,
+  bool is_quiet, float_status *s)
+{
+if (a.cls >= float_class_qnan
+||
+b.cls >= float_class_qnan) {
+if (!is_quiet ||
+a.cls == float_class_snan ||
+b.cls == float_class_snan) {
+s->float_exception_flags |= float_flag_invalid;
+}
+return float_relation_unordered;
+}
+
+if (a.cls == float_class_zero || b.cls == float_class_zero) {
+if (a.cls == float_class_normal) {
+return a.sign ? float_relation_less : float_relation_greater;
+} else if (b.cls == float_class_normal) {
+return b.sign ? float_relation_greater : float_relation_less;
+} else if (a.cls == b.cls) {
+return float_relation_equal;
+}
+}
+
+/* The only infinity we need to explicitly worry about is
+ * comparing two together, otherwise the max_exp/sign details are
+ * enough to compare to normal numbers
+ */
+if (a.cls == float_class_inf && b.cls == float_class_inf) {
+if (a.sign != b.sign) {
+return a.sign ? float_relation_less : float_relation_greater;
+} else {
+return float_relation_equal;
+}
+}
+
+if (a.sign != b.sign) {
+return a.sign ? float_relation_less : float_relation_greater;
+}
+
+if (a.exp == b.exp) {
+if (a.frac == b.frac) {
+return float_relation_equal;
+}
+if (a.sign) {
+return a.frac > b.frac ?
+float_relation_less : float_relation_greater;
+} else {
+return a.frac > b.frac ?
+float_relation_greater : float_relation_less;
+}
+} else {
+if (a.sign) {
+return a.exp > b.exp ? float_relation_less : 
float_relation_greater;
+} else {
+return a.exp > b.exp ? float_relation_greater : 
float_relation_less;
+}
+}
+}
+
+#define COMPARE(sz) \
+int float ## sz ## _compare(float ## sz a, float ## sz b, float_status *s) \
+{   \
+decomposed_parts pa = float ## sz ## _unpack_canonical(a, s);   \
+decomposed_parts pb = float ## sz ## _unpack_canonical(b, s);   \
+return compare_decomposed(pa, pb, false, s);\
+}   \
+int float ## sz ## _compare_quiet(float ## sz a, float ## sz b, float_status 
*s) \
+{   \
+decomposed_parts pa = float ## sz ## _unpack_canonical(a, s);   \
+decomposed_parts pb = float ## sz ## _unpack_canonical(b, s);   \
+return compare_decomposed(pa, pb, true, s); \
+}
+
+COMPARE(16)
+COMPARE(32)
+COMPARE(64)
+
+#undef COMPARE
+
 /* Multiply A by 2 raised to the power N.  */
 static decomposed_parts scalbn_decomposed(decomposed_parts a, int n,
   float_status *s)
@@ -6894,60 +6975,6 @@ int float128_unordered_quiet(float128 a, float128 b, 
float_status *status)
 return 0;
 }
 
-#define COMPARE(s, nan_exp)  \
-static inline int float ## s ## _compare_internal(float ## s a, float ## s b,\
-  int is_quiet, float_status *status)\
-{\
-flag aSign, bSign;   \
-uint ## s ## _t av, bv;  \
-a = float ## s ## _squash_input_denormal(a, status); \
-b = float ## s ## _squash_input_denormal(b, status); \
- \
-if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) &&\
- extractFloat ## s ## Frac( a ) ) || \
-( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&\
-  extractFloat ## s ## Frac( b ) )) {\
-if (!is_quiet || \
-float ## s ## _is_signaling_nan(a, status) ||  \
-float ## s ## 

[Qemu-devel] [PATCH v4 05/46] windbg: added helper features

2017-12-11 Thread Mihail Abakumov
Added some helper features for windbgstub.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |   31 +++
 include/exec/windbgstub.h   |6 ++
 2 files changed, 37 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 2390597f1f..4c747fa23e 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -13,7 +13,38 @@
 #define WINDBGSTUB_UTILS_H
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "log.h"
+#include "cpu.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgkd.h"
 
+#define WINDBG_DEBUG(...) do { \
+if (WINDBG_DEBUG_ON) { \
+qemu_log(WINDBG ": " __VA_ARGS__); \
+qemu_log("\n");\
+}  \
+} while (false)
+
+#define WINDBG_ERROR(...) error_report(WINDBG ": " __VA_ARGS__)
+
+#define FMT_ADDR "addr:0x" TARGET_FMT_lx
+#define FMT_ERR  "Error:%d"
+
+#define UINT8_P(ptr) ((uint8_t *) (ptr))
+#define PTR(var) UINT8_P()
+
+#define sizeof_field(type, field) sizeof(((type *) NULL)->field)
+
+#define READ_VMEM(cpu, addr, type) ({ \
+type _t;  \
+cpu_memory_rw_debug(cpu, addr, PTR(_t), sizeof(type), 0); \
+_t;   \
+})
+
+typedef struct SizedBuf {
+uint8_t *data;
+size_t size;
+} SizedBuf;
+
 #endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 1a6e1cc6e5..21bc552e58 100755
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -12,6 +12,12 @@
 #ifndef WINDBGSTUB_H
 #define WINDBGSTUB_H
 
+#define WINDBG "windbg"
+
+#ifndef WINDBG_DEBUG_ON
+#define WINDBG_DEBUG_ON false
+#endif
+
 int windbg_server_start(const char *device);
 
 #endif




[Qemu-devel] [PATCH v4 02/46] windbg: added windbg's KD header file

2017-12-11 Thread Mihail Abakumov
Header file from windbg's source code describing the main structures.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgkd.h |  873 +++
 include/exec/windbgstub-utils.h |1 
 2 files changed, 874 insertions(+)
 create mode 100755 include/exec/windbgkd.h

diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
new file mode 100755
index 00..b8f98925e7
--- /dev/null
+++ b/include/exec/windbgkd.h
@@ -0,0 +1,873 @@
+/*
+ * windbgkd.h
+ *
+ * Copyright (c) 2010-2017 Institute for System Programming
+ * of the Russian Academy of Sciences.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef WINDBGKD_H
+#define WINDBGKD_H
+
+/*
+ * Packet Size and Control Stream Size
+ */
+#define PACKET_MAX_SIZE 4096
+#define DBGKD_MAXSTREAM 16
+
+/*
+ * Magic Packet IDs
+ */
+#define INITIAL_PACKET_ID   0x8080
+#define SYNC_PACKET_ID  0x0800
+#define RESET_PACKET_ID 0x0018359b
+
+/*
+ * Magic Packet bytes
+ */
+#define BREAKIN_PACKET  0x62626262
+#define BREAKIN_PACKET_BYTE 0x62
+#define PACKET_LEADER   0x30303030
+#define PACKET_LEADER_BYTE  0x30
+#define CONTROL_PACKET_LEADER   0x69696969
+#define CONTROL_PACKET_LEADER_BYTE  0x69
+#define PACKET_TRAILING_BYTE0xaa
+
+/*
+ * Packet Types
+ */
+#define PACKET_TYPE_UNUSED  0
+#define PACKET_TYPE_KD_STATE_CHANGE32   1
+#define PACKET_TYPE_KD_STATE_MANIPULATE 2
+#define PACKET_TYPE_KD_DEBUG_IO 3
+#define PACKET_TYPE_KD_ACKNOWLEDGE  4
+#define PACKET_TYPE_KD_RESEND   5
+#define PACKET_TYPE_KD_RESET6
+#define PACKET_TYPE_KD_STATE_CHANGE64   7
+#define PACKET_TYPE_KD_POLL_BREAKIN 8
+#define PACKET_TYPE_KD_TRACE_IO 9
+#define PACKET_TYPE_KD_CONTROL_REQUEST  10
+#define PACKET_TYPE_KD_FILE_IO  11
+#define PACKET_TYPE_MAX 12
+
+/*
+ * Wait State Change Types
+ */
+#define DbgKdMinimumStateChange 0x3030
+#define DbgKdExceptionStateChange   0x3030
+#define DbgKdLoadSymbolsStateChange 0x3031
+#define DbgKdCommandStringStateChange   0x3032
+#define DbgKdMaximumStateChange 0x3033
+
+/*
+ * This is combined with the basic state change code
+ * if the state is from an alternate source
+ */
+#define DbgKdAlternateStateChange   0x0001
+
+/*
+ * Manipulate Types
+ */
+#define DbgKdMinimumManipulate  0x3130
+#define DbgKdReadVirtualMemoryApi   0x3130
+#define DbgKdWriteVirtualMemoryApi  0x3131
+#define DbgKdGetContextApi  0x3132
+#define DbgKdSetContextApi  0x3133
+#define DbgKdWriteBreakPointApi 0x3134
+#define DbgKdRestoreBreakPointApi   0x3135
+#define DbgKdContinueApi0x3136
+#define DbgKdReadControlSpaceApi0x3137
+#define DbgKdWriteControlSpaceApi   0x3138
+#define DbgKdReadIoSpaceApi 0x3139
+#define DbgKdWriteIoSpaceApi0x313a
+#define DbgKdRebootApi  0x313b
+#define DbgKdContinueApi2   0x313c
+#define DbgKdReadPhysicalMemoryApi  0x313d
+#define DbgKdWritePhysicalMemoryApi 0x313e
+#define DbgKdQuerySpecialCallsApi   0x313f
+#define DbgKdSetSpecialCallApi  0x3140
+#define DbgKdClearSpecialCallsApi   0x3141
+#define DbgKdSetInternalBreakPointApi   0x3142
+#define DbgKdGetInternalBreakPointApi   0x3143
+#define DbgKdReadIoSpaceExtendedApi 0x3144
+#define DbgKdWriteIoSpaceExtendedApi0x3145
+#define DbgKdGetVersionApi  0x3146
+#define DbgKdWriteBreakPointExApi   0x3147
+#define DbgKdRestoreBreakPointExApi 0x3148
+#define DbgKdCauseBugCheckApi   0x3149
+#define DbgKdSwitchProcessor0x3150
+#define DbgKdPageInApi  0x3151
+#define DbgKdReadMachineSpecificRegister0x3152
+#define DbgKdWriteMachineSpecificRegister   0x3153
+#define OldVlm1 0x3154
+#define OldVlm2 0x3155
+#define DbgKdSearchMemoryApi0x3156
+#define DbgKdGetBusDataApi  0x3157
+#define DbgKdSetBusDataApi  0x3158
+#define DbgKdCheckLowMemoryApi  0x3159
+#define DbgKdClearAllInternalBreakpointsApi 0x315a
+#define 

[Qemu-devel] [PATCH v4 09/46] windbg: handler of fs/gs register

2017-12-11 Thread Mihail Abakumov
Added handler of fs/gs register. It tries to find and check KPCR and version 
address.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |8 ++
 target/i386/windbgstub.c|   49 ++-
 windbgstub-utils.c  |   13 ++
 windbgstub.c|   10 
 4 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a181e172e9..ced03b0663 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -47,6 +47,14 @@ typedef struct SizedBuf {
 size_t size;
 } SizedBuf;
 
+typedef struct InitedAddr {
+target_ulong addr;
+bool is_init;
+} InitedAddr;
+
+InitedAddr *windbg_get_KPCR(void);
+InitedAddr *windbg_get_version(void);
+
 bool windbg_on_load(void);
 
 #endif
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 0938f738e6..47ee5840ef 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -14,9 +14,56 @@
 #ifndef TARGET_X86_64
 #include "exec/windbgstub-utils.h"
 
+#ifdef TARGET_X86_64
+# define OFFSET_SELF_PCR 0x18
+# define OFFSET_VERS 0x108
+#else
+# define OFFSET_SELF_PCR 0x1C
+# define OFFSET_VERS 0x34
+#endif
+
 bool windbg_on_load(void)
 {
-return false;
+CPUState *cpu = qemu_get_cpu(0);
+CPUArchState *env = cpu->env_ptr;
+InitedAddr *KPCR = windbg_get_KPCR();
+InitedAddr *version = windbg_get_version();
+
+if (!KPCR->is_init) {
+
+ #ifdef TARGET_X86_64
+KPCR->addr = env->segs[R_GS].base;
+ #else
+KPCR->addr = env->segs[R_FS].base;
+ #endif
+
+static target_ulong prev_KPCR;
+if (!KPCR->addr || prev_KPCR == KPCR->addr) {
+return false;
+}
+prev_KPCR = KPCR->addr;
+
+if (KPCR->addr != READ_VMEM(cpu, KPCR->addr + OFFSET_SELF_PCR,
+target_ulong)) {
+return false;
+}
+
+KPCR->is_init = true;
+}
+
+if (!version->is_init && KPCR->is_init) {
+version->addr = READ_VMEM(cpu, KPCR->addr + OFFSET_VERS,
+  target_ulong);
+if (!version->addr) {
+return false;
+}
+version->is_init = true;
+}
+
+WINDBG_DEBUG("windbg_on_load: KPCR " FMT_ADDR, KPCR->addr);
+WINDBG_DEBUG("windbg_on_load: version " FMT_ADDR, version->addr);
+
+return true;
 }
 
 #endif
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index dc5e505c63..347c61553a 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,3 +10,16 @@
  */
 
 #include "exec/windbgstub-utils.h"
+
+static InitedAddr KPCR;
+static InitedAddr version;
+
+InitedAddr *windbg_get_KPCR(void)
+{
+return 
+}
+
+InitedAddr *windbg_get_version(void)
+{
+return 
+}
diff --git a/windbgstub.c b/windbgstub.c
index a2a6eb81b4..e9aabd807b 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -17,6 +17,7 @@
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
 #include "sysemu/kvm.h"
+#include "sysemu/reset.h"
 
 typedef struct WindbgState {
 bool is_loaded;
@@ -46,6 +47,13 @@ static void windbg_exit(void)
 g_free(windbg_state);
 }
 
+static void windbg_handle_reset(void *opaque)
+{
+windbg_state->is_loaded = false;
+windbg_get_KPCR()->is_init = false;
+windbg_get_version()->is_init = false;
+}
+
 void windbg_try_load(void)
 {
 if (windbg_state && !windbg_state->is_loaded) {
@@ -85,6 +93,8 @@ int windbg_server_start(const char *device)
 qemu_chr_fe_set_handlers(_state->chr, windbg_chr_can_receive,
  windbg_chr_receive, NULL, NULL, NULL, NULL, true);
 
+qemu_register_reset(windbg_handle_reset, NULL);
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 24/46] windbg: implemented kd_api_read_control_space and kd_api_write_control_space

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 +
 target/i386/windbgstub.c|   89 +++
 windbgstub.c|8 
 3 files changed, 99 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index d4efabba0b..e04bd59d46 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -78,6 +78,8 @@ void kd_api_read_virtual_memory(CPUState *cpu, PacketData 
*pd);
 void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
+void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
+void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 7558349469..f72d164bb5 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -285,6 +285,18 @@ static int windbg_write_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 return 0;
 }
 
+static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
+   int offset, int len)
+{
+return 0;
+}
+
+static int windbg_write_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len)
+{
+return 0;
+}
+
 void kd_api_get_context(CPUState *cpu, PacketData *pd)
 {
 int err;
@@ -312,6 +324,83 @@ void kd_api_set_context(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_read_control_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+uint32_t context_len;
+uint32_t ks_regs_len;
+target_ulong addr;
+int err = -1;
+
+len = MIN(ldl_p(>TransferCount),
+  PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+
+if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+err = windbg_read_context(cpu, pd->extra, context_len, addr,
+  context_len);
+}
+if (ks_regs_len > 0) {
+addr = addr - sizeof(CPU_CONTEXT) + context_len;
+err = windbg_read_ks_regs(cpu, pd->extra + context_len,
+  ks_regs_len, addr, ks_regs_len);
+}
+}
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_control_space(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+uint32_t context_len;
+uint32_t ks_regs_len;
+target_ulong addr;
+int err = -1;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+
+if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+err = windbg_write_context(cpu, pd->extra, context_len, addr,
+   context_len);
+}
+if (ks_regs_len > 0) {
+addr = addr - sizeof(CPU_CONTEXT) + context_len;
+err = windbg_write_ks_regs(cpu, pd->extra + context_len,
+   ks_regs_len, addr, ks_regs_len);
+}
+}
+
+if (err) {
+mem->ActualBytesWritten = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
+
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 bool windbg_on_load(void)
 {
 CPUState *cpu = qemu_get_cpu(0);
diff --git a/windbgstub.c b/windbgstub.c
index be40e3e53b..53a7e75683 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -156,6 +156,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_set_context(cpu, >data);
 break;
 
+case DbgKdReadControlSpaceApi:
+kd_api_read_control_space(cpu, >data);
+break;
+
+case DbgKdWriteControlSpaceApi:
+kd_api_write_control_space(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 15/46] windbg: generate ExceptionStateChange

2017-12-11 Thread Mihail Abakumov
Added function for generate ExceptionStateChange packet.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 ++
 target/i386/windbgstub.c|   21 -
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 830d01314e..d9dae4e902 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -74,6 +74,8 @@ typedef struct PacketData {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+SizedBuf kd_gen_exception_sc(CPUState *cpu);
+
 bool windbg_on_load(void);
 
 #endif
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index a3c433f756..5db6a5e3bc 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -70,7 +70,6 @@ bool windbg_on_load(void)
 return true;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void kd_init_state_change(CPUState *cpu,
  DBGKD_ANY_WAIT_STATE_CHANGE *sc)
 {
@@ -115,4 +114,24 @@ static void kd_init_state_change(CPUState *cpu,
 }
 }
 
+SizedBuf kd_gen_exception_sc(CPUState *cpu)
+{
+CPUArchState *env = cpu->env_ptr;
+DBGKD_ANY_WAIT_STATE_CHANGE *sc;
+DBGKM_EXCEPTION_RECORD64 *exc;
+SizedBuf buf;
+
+buf.size = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE) + sizeof(int);
+buf.data = g_malloc0(buf.size);
+sc = (DBGKD_ANY_WAIT_STATE_CHANGE *) buf.data;
+exc = >u.Exception.ExceptionRecord;
+kd_init_state_change(cpu, sc);
+
+stl_p(>NewState, DbgKdExceptionStateChange);
+stl_p(>ExceptionCode, 0x8003);
+sttul_p(>ExceptionAddress, env->eip);
+
+return buf;
+}
+
 #endif




[Qemu-devel] [PATCH v4 29/46] windbg: implemented windbg_set_sr

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |   17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 25a0ee8a66..2a09cec9d8 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -277,7 +277,22 @@ static void windbg_set_dr(CPUState *cpu, int index, 
target_ulong value)
 {}
 
 static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
-{}
+{
+CPUArchState *env = cpu->env_ptr;
+
+if (selector != env->segs[sr].selector &&
+(!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK))) {
+unsigned int limit, flags;
+target_ulong base;
+
+int dpl = (env->eflags & VM_MASK) ? 3 : 0;
+base = selector << 4;
+limit = 0x;
+flags = DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+DESC_A_MASK | (dpl << DESC_DPL_SHIFT);
+cpu_x86_load_seg_cache(env, sr, selector, base, limit, flags);
+}
+}
 
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)




Re: [Qemu-devel] [PATCH v18 10/10] virtio-balloon: don't report free pages when page poisoning is enabled

2017-12-11 Thread Michael S. Tsirkin
On Mon, Dec 11, 2017 at 02:38:45PM +0800, Wei Wang wrote:
> On 12/01/2017 11:49 PM, Michael S. Tsirkin wrote:
> > On Wed, Nov 29, 2017 at 09:55:26PM +0800, Wei Wang wrote:
> > > The guest free pages should not be discarded by the live migration thread
> > > when page poisoning is enabled with PAGE_POISONING_NO_SANITY=n, because
> > > skipping the transfer of such poisoned free pages will trigger false
> > > positive when new pages are allocated and checked on the destination.
> > > This patch skips the reporting of free pages in the above case.
> > > 
> > > Reported-by: Michael S. Tsirkin 
> > > Signed-off-by: Wei Wang 
> > > Cc: Michal Hocko 
> > > ---
> > >   drivers/virtio/virtio_balloon.c | 4 +++-
> > >   1 file changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/virtio/virtio_balloon.c 
> > > b/drivers/virtio/virtio_balloon.c
> > > index 035bd3a..6ac4cff 100644
> > > --- a/drivers/virtio/virtio_balloon.c
> > > +++ b/drivers/virtio/virtio_balloon.c
> > > @@ -652,7 +652,9 @@ static void report_free_page(struct work_struct *work)
> > >   /* Start by sending the obtained cmd id to the host with an 
> > > outbuf */
> > >   send_one_desc(vb, vb->free_page_vq, 
> > > virt_to_phys(>start_cmd_id),
> > > sizeof(uint32_t), false, true, false);
> > > - walk_free_mem_block(vb, 0, _balloon_send_free_pages);
> > > + if (!(page_poisoning_enabled() &&
> > > + !IS_ENABLED(CONFIG_PAGE_POISONING_NO_SANITY)))
> > > + walk_free_mem_block(vb, 0, _balloon_send_free_pages);
> > >   /*
> > >* End by sending the stop id to the host with an outbuf. Use 
> > > the
> > >* non-batching mode here to trigger a kick after adding the 
> > > stop id.
> > PAGE_POISONING_ZERO is actually OK.
> > 
> > But I really would prefer it that we still send pages to host,
> > otherwise debugging becomes much harder.
> > 
> > And it does not have to be completely useless, even though
> > you can not discard them as they would be zero-filled then.
> > 
> > How about a config field telling host what should be there in the free
> > pages? This way even though host can not discard them, host can send
> > them out without reading them, still a win.
> > 
> > 
> 
> Since this poison value comes with the free page reporting feature, how
> about sending the poison value via the free_page_vq, along with the cmd id
> in the outbuf? That is, use the following interface:
> 
> struct virtio_balloon_free_page_vq_hdr {
> bool page_poisoning;
> __virtio32 poison_value;
> __virtio32 cmd_id;
> }

Can we put the value in config space instead?

> We need "bool page_poisoning" because "poison_value=0" doesn't tell whether
> page poising is in use by the guest.

Can we use a feature bit for this?

> PAGE_POISONING_ZERO sets
> "page_poisoning=true, poisoning_value=0", and the host will send the
> 0-filled pages to the destination (if not sending 0-filled pages, the
> destination host would offer non-zero pages to the guest)

Why would it? Linux zeroes all pages on alloc.

> The host can discard free pages only when "page_poisoning=false".
> 
> Best,
> Wei





[Qemu-devel] [PATCH v4 30/46] windbg: implemented windbg_set_dr

2017-12-11 Thread Mihail Abakumov
Defined useful macros for breakpoints.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |   50 +-
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 2a09cec9d8..cae827df50 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -14,6 +14,21 @@
 #ifndef TARGET_X86_64
 #include "exec/windbgstub-utils.h"
 
+#define IS_LOCAL_BP_ENABLED(dr7, index) (((dr7) >> ((index) * 2)) & 1)
+
+#define IS_GLOBAL_BP_ENABLED(dr7, index) (((dr7) >> ((index) * 2)) & 2)
+
+#define IS_BP_ENABLED(dr7, index) \
+(IS_LOCAL_BP_ENABLED(dr7, index) | IS_GLOBAL_BP_ENABLED(dr7, index))
+
+#define BP_TYPE(dr7, index) \
+((int) ((dr7) >> (DR7_TYPE_SHIFT + ((index) * 4))) & 3)
+
+#define BP_LEN(dr7, index) ({\
+int _len = (((dr7) >> (DR7_LEN_SHIFT + ((index) * 4))) & 3); \
+(_len == 2) ? 8 : _len + 1;  \
+})
+
 #ifdef TARGET_X86_64
 # define OFFSET_SELF_PCR 0x18
 # define OFFSET_VERS 0x108
@@ -273,9 +288,42 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
-static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+static int windbg_hw_breakpoint_insert(CPUState *cpu, int index)
+{
+return 0;
+}
+
+static int windbg_hw_breakpoint_remove(CPUState *cpu, int index)
+{
+return 0;
+}
+
+static void windbg_set_dr7(CPUState *cpu, target_ulong new_dr7)
 {}
 
+static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+{
+CPUArchState *env = cpu->env_ptr;
+
+switch (index) {
+case 0 ... 3:
+if (IS_BP_ENABLED(env->dr[7], index) && env->dr[index] != value) {
+windbg_hw_breakpoint_remove(cpu, index);
+env->dr[index] = value;
+windbg_hw_breakpoint_insert(cpu, index);
+} else {
+env->dr[index] = value;
+}
+return;
+case 6:
+env->dr[6] = value | DR6_FIXED_1;
+return;
+case 7:
+windbg_set_dr7(cpu, value);
+return;
+}
+}
+
 static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
 {
 CPUArchState *env = cpu->env_ptr;




[Qemu-devel] [PATCH v4 27/46] windbg: implemented windbg_read_ks_regs

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |   39 +++
 1 file changed, 39 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 6272a1341d..da7d1eae0c 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -600,6 +600,45 @@ static int windbg_write_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+CPU_KSPECIAL_REGISTERS *ckr;
+bool new_mem;
+
+new_mem = (len != sizeof(CPU_KSPECIAL_REGISTERS) || offset != 0);
+if (new_mem) {
+ckr = g_new(CPU_KSPECIAL_REGISTERS, 1);
+} else {
+ckr = (CPU_KSPECIAL_REGISTERS *) buf;
+}
+
+memset(ckr, 0, len);
+
+ckr->Cr0 = ldl_p(>cr[0]);
+ckr->Cr2 = ldl_p(>cr[2]);
+ckr->Cr3 = ldl_p(>cr[3]);
+ckr->Cr4 = ldl_p(>cr[4]);
+
+ckr->KernelDr0 = ldtul_p(>dr[0]);
+ckr->KernelDr1 = ldtul_p(>dr[1]);
+ckr->KernelDr2 = ldtul_p(>dr[2]);
+ckr->KernelDr3 = ldtul_p(>dr[3]);
+ckr->KernelDr6 = ldtul_p(>dr[6]);
+ckr->KernelDr7 = ldtul_p(>dr[7]);
+
+ckr->Gdtr.Pad = lduw_p(>gdt.selector);
+ckr->Idtr.Pad = lduw_p(>idt.selector);
+
+ckr->Gdtr.Limit = lduw_p(>gdt.limit);
+ckr->Gdtr.Base  = ldtul_p(>gdt.base);
+ckr->Idtr.Limit = lduw_p(>idt.limit);
+ckr->Idtr.Base  = ldtul_p(>idt.base);
+ckr->Tr = lduw_p(>tr.selector);
+ckr->Ldtr   = lduw_p(>ldt.selector);
+
+if (new_mem) {
+memcpy(buf, (uint8_t *) ckr + offset, len);
+g_free(ckr);
+}
 return 0;
 }
 




[Qemu-devel] [PATCH v4 38/46] windbg: implemented kd_api_get_version

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   22 ++
 windbgstub.c|4 
 3 files changed, 27 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a40253f18a..8cdb27 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -87,6 +87,7 @@ void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_version(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 6708e62798..7ef301bac7 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -239,6 +239,28 @@ void kd_api_write_physical_memory(CPUState *cpu, 
PacketData *pd)
 stl_p(>ActualBytesWritten, len);
 }
 
+void kd_api_get_version(CPUState *cpu, PacketData *pd)
+{
+DBGKD_GET_VERSION64 *kdver;
+int err = cpu_memory_rw_debug(cpu, version.addr, PTR(pd->m64) + 0x10,
+  sizeof(DBGKD_MANIPULATE_STATE64) - 0x10, 0);
+if (!err) {
+kdver = (DBGKD_GET_VERSION64 *) (PTR(pd->m64) + 0x10);
+
+stw_p(>MajorVersion, kdver->MajorVersion);
+stw_p(>MinorVersion, kdver->MinorVersion);
+stw_p(>Flags, kdver->Flags);
+stw_p(>MachineType, kdver->MachineType);
+stw_p(>Unused[0], kdver->Unused[0]);
+sttul_p(>KernBase, kdver->KernBase);
+sttul_p(>PsLoadedModuleList, kdver->PsLoadedModuleList);
+sttul_p(>DebuggerDataList, kdver->DebuggerDataList);
+} else {
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+WINDBG_ERROR("get_version: " FMT_ERR, err);
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index 9cf25bc6dd..06e99199b6 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -197,6 +197,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_physical_memory(cpu, >data);
 break;
 
+case DbgKdGetVersionApi:
+kd_api_get_version(cpu, >data);
+break;
+
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 




[Qemu-devel] [PATCH v4 45/46] windbg: changed kd_api_read_msr and kd_api_write_msr

2017-12-11 Thread Mihail Abakumov
Added sub functions for helper_wrmsr and helper_rdmsr: cpu_x86_write_msr and 
cpu_x86_read_msr. Also they are used in packet handlers, i.e. duplication of 
code is removed.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/cpu.h |3 
 target/i386/misc_helper.c |   49 +--
 target/i386/windbgstub.c  |  303 +
 3 files changed, 43 insertions(+), 312 deletions(-)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 051867399b..04c5aac795 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1481,6 +1481,9 @@ void cpu_x86_update_cr3(CPUX86State *env, target_ulong 
new_cr3);
 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4);
 void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7);
 
+void cpu_x86_write_msr(CPUX86State *env, uint64_t val);
+uint64_t cpu_x86_read_msr(CPUX86State *env);
+
 /* hw/pc.c */
 uint64_t cpu_get_tsc(CPUX86State *env);
 
diff --git a/target/i386/misc_helper.c b/target/i386/misc_helper.c
index ec1fcd2899..5d74c31998 100644
--- a/target/i386/misc_helper.c
+++ b/target/i386/misc_helper.c
@@ -220,6 +220,14 @@ void helper_rdpmc(CPUX86State *env)
 }
 
 #if defined(CONFIG_USER_ONLY)
+void cpu_x86_write_msr(CPUX86State *env, uint64_t val)
+{
+}
+
+uint64_t cpu_x86_read_msr(CPUX86State *env)
+{
+}
+
 void helper_wrmsr(CPUX86State *env)
 {
 }
@@ -228,15 +236,8 @@ void helper_rdmsr(CPUX86State *env)
 {
 }
 #else
-void helper_wrmsr(CPUX86State *env)
+void cpu_x86_write_msr(CPUX86State *env, uint64_t val)
 {
-uint64_t val;
-
-cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
-
-val = ((uint32_t)env->regs[R_EAX]) |
-((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
-
 switch ((uint32_t)env->regs[R_ECX]) {
 case MSR_IA32_SYSENTER_CS:
 env->sysenter_cs = val & 0x;
@@ -386,16 +387,12 @@ void helper_wrmsr(CPUX86State *env)
 /* XXX: exception? */
 break;
 }
-
-windbg_try_load();
 }
 
-void helper_rdmsr(CPUX86State *env)
+uint64_t cpu_x86_read_msr(CPUX86State *env)
 {
 uint64_t val;
 
-cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC());
-
 switch ((uint32_t)env->regs[R_ECX]) {
 case MSR_IA32_SYSENTER_CS:
 val = env->sysenter_cs;
@@ -534,6 +531,32 @@ void helper_rdmsr(CPUX86State *env)
 val = 0;
 break;
 }
+
+return val;
+}
+
+void helper_wrmsr(CPUX86State *env)
+{
+uint64_t val;
+
+cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
+
+val = ((uint32_t)env->regs[R_EAX]) |
+((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
+
+cpu_x86_write_msr(env, val);
+
+windbg_try_load();
+}
+
+void helper_rdmsr(CPUX86State *env)
+{
+uint64_t val;
+
+cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC());
+
+val = cpu_x86_read_msr(env);
+
 env->regs[R_EAX] = (uint32_t)(val);
 env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 96cb015752..c38bfa7448 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -1076,150 +1076,9 @@ void kd_api_read_msr(CPUState *cpu, PacketData *pd)
 DBGKD_READ_WRITE_MSR *m64c = >m64.u.ReadWriteMsr;
 CPUArchState *env = cpu->env_ptr;
 
-uint64_t val;
-
-cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, 0);
-
-switch ((uint32_t)env->regs[R_ECX]) {
-case MSR_IA32_SYSENTER_CS:
-val = env->sysenter_cs;
-break;
-case MSR_IA32_SYSENTER_ESP:
-val = env->sysenter_esp;
-break;
-case MSR_IA32_SYSENTER_EIP:
-val = env->sysenter_eip;
-break;
-case MSR_IA32_APICBASE:
-val = cpu_get_apic_base(x86_env_get_cpu(env)->apic_state);
-break;
-case MSR_EFER:
-val = env->efer;
-break;
-case MSR_STAR:
-val = env->star;
-break;
-case MSR_PAT:
-val = env->pat;
-break;
-case MSR_VM_HSAVE_PA:
-val = env->vm_hsave;
-break;
-case MSR_IA32_PERF_STATUS:
-/* tsc_increment_by_tick */
-val = 1000ULL;
-/* CPU multiplier */
-val |= (((uint64_t)4ULL) << 40);
-break;
-#ifdef TARGET_X86_64
-case MSR_LSTAR:
-val = env->lstar;
-break;
-case MSR_CSTAR:
-val = env->cstar;
-break;
-case MSR_FMASK:
-val = env->fmask;
-break;
-case MSR_FSBASE:
-val = env->segs[R_FS].base;
-break;
-case MSR_GSBASE:
-val = env->segs[R_GS].base;
-break;
-case MSR_KERNELGSBASE:
-val = env->kernelgsbase;
-break;
-case MSR_TSC_AUX:
-val = env->tsc_aux;
-break;
-#endif
-case MSR_MTRRphysBase(0):
-case MSR_MTRRphysBase(1):
-case MSR_MTRRphysBase(2):
-case MSR_MTRRphysBase(3):
-case MSR_MTRRphysBase(4):
-

[Qemu-devel] [PATCH v4 42/46] windbg: implemented kd_api_query_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |9 +
 windbgstub.c|4 
 3 files changed, 14 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index f4adfe44dd..8d36354b7c 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -93,6 +93,7 @@ void kd_api_write_msr(CPUState *cpu, PacketData *pd);
 void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
+void kd_api_query_memory(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index a34f5ae8bd..e3b1276dab 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -333,6 +333,15 @@ void kd_api_fill_memory(CPUState *cpu, PacketData *pd)
 }
 }
 
+void kd_api_query_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_QUERY_MEMORY *mem = >m64.u.QueryMemory;
+
+stl_p(>AddressSpace, DBGKD_QUERY_MEMORY_PROCESS);
+stl_p(>Flags, DBGKD_QUERY_MEMORY_READ |
+   DBGKD_QUERY_MEMORY_WRITE | DBGKD_QUERY_MEMORY_EXECUTE);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index f0b3ca3390..f0930f20a8 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -220,6 +220,10 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_fill_memory(cpu, >data);
 break;
 
+case DbgKdQueryMemoryApi:
+kd_api_query_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v1 for-2-12 05/15] s390x/tcg: simplify machine check handling

2017-12-11 Thread David Hildenbrand
We currently only support CRW machine checks. This is a preparation for
real floating interrupt support.

Get rid of the queue and handle it via the bit INTERRUPT_MCHK. We don't
rename it for now, as it will be soon gone (when moving crw machine checks
into the flic).

Please note that this is the same way also KVM handles it: only one
instance of a machine check can be pending at a time. So no need for a
queue.

While at it, make sure we try to deliver only if env->cregs[14]
actually indicates that CRWs are accepted.

Drop two unused defines on the way (we already have PSW_MASK_...).

Signed-off-by: David Hildenbrand 
---
 target/s390x/cpu.c |  2 --
 target/s390x/cpu.h | 10 --
 target/s390x/excp_helper.c | 29 +
 target/s390x/interrupt.c   | 18 +++---
 4 files changed, 12 insertions(+), 47 deletions(-)

diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index ae3cee91a2..bb4fc0f879 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -118,7 +118,6 @@ static void s390_cpu_initial_reset(CPUState *s)
 for (i = 0; i < ARRAY_SIZE(env->io_index); i++) {
 env->io_index[i] = -1;
 }
-env->mchk_index = -1;
 
 /* tininess for underflow is detected before rounding */
 set_float_detect_tininess(float_tininess_before_rounding,
@@ -155,7 +154,6 @@ static void s390_cpu_full_reset(CPUState *s)
 for (i = 0; i < ARRAY_SIZE(env->io_index); i++) {
 env->io_index[i] = -1;
 }
-env->mchk_index = -1;
 
 /* tininess for underflow is detected before rounding */
 set_float_detect_tininess(float_tininess_before_rounding,
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 1a8b6b9ae9..85f4e6b758 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -54,10 +54,6 @@
 #define MMU_USER_IDX 0
 
 #define MAX_IO_QUEUE 16
-#define MAX_MCHK_QUEUE 16
-
-#define PSW_MCHK_MASK 0x0004
-#define PSW_IO_MASK 0x0200
 
 #define S390_MAX_CPUS 248
 
@@ -73,10 +69,6 @@ typedef struct IOIntQueue {
 uint32_t word;
 } IOIntQueue;
 
-typedef struct MchkQueue {
-uint16_t type;
-} MchkQueue;
-
 struct CPUS390XState {
 uint64_t regs[16]; /* GP registers */
 /*
@@ -122,14 +114,12 @@ struct CPUS390XState {
 uint64_t cregs[16]; /* control registers */
 
 IOIntQueue io_queue[MAX_IO_QUEUE][8];
-MchkQueue mchk_queue[MAX_MCHK_QUEUE];
 
 int pending_int;
 uint32_t service_param;
 uint16_t external_call_addr;
 DECLARE_BITMAP(emergency_signals, S390_MAX_CPUS);
 int io_index[8];
-int mchk_index;
 
 uint64_t ckc;
 uint64_t cputm;
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index d024ac5fef..a18842ccbd 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -368,30 +368,16 @@ static void do_io_interrupt(CPUS390XState *env)
 
 static void do_mchk_interrupt(CPUS390XState *env)
 {
-S390CPU *cpu = s390_env_get_cpu(env);
 uint64_t mask, addr;
 LowCore *lowcore;
-MchkQueue *q;
 int i;
 
-if (!(env->psw.mask & PSW_MASK_MCHECK)) {
-cpu_abort(CPU(cpu), "Machine check w/o mchk mask\n");
-}
+/* for now we only support channel report machine checks (floating) */
+g_assert(env->psw.mask & PSW_MASK_MCHECK);
+g_assert(env->cregs[14] & CR0_SERVICE_SC);
 
-if (env->mchk_index < 0 || env->mchk_index >= MAX_MCHK_QUEUE) {
-cpu_abort(CPU(cpu), "Mchk queue overrun: %d\n", env->mchk_index);
-}
-
-q = >mchk_queue[env->mchk_index];
-
-if (q->type != 1) {
-/* Don't know how to handle this... */
-cpu_abort(CPU(cpu), "Unknown machine check type %d\n", q->type);
-}
-if (!(env->cregs[14] & (1 << 28))) {
-/* CRW machine checks disabled */
-return;
-}
+g_assert(env->pending_int & INTERRUPT_MCHK);
+env->pending_int &= ~INTERRUPT_MCHK;
 
 lowcore = cpu_map_lowcore(env);
 
@@ -418,11 +404,6 @@ static void do_mchk_interrupt(CPUS390XState *env)
 
 cpu_unmap_lowcore(lowcore);
 
-env->mchk_index--;
-if (env->mchk_index == -1) {
-env->pending_int &= ~INTERRUPT_MCHK;
-}
-
 DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
 env->psw.mask, env->psw.addr);
 
diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
index 39c026b8b5..380222b394 100644
--- a/target/s390x/interrupt.c
+++ b/target/s390x/interrupt.c
@@ -162,16 +162,6 @@ static void cpu_inject_crw_mchk(S390CPU *cpu)
 {
 CPUS390XState *env = >env;
 
-if (env->mchk_index == MAX_MCHK_QUEUE - 1) {
-/* ugh - can't queue anymore. Let's drop. */
-return;
-}
-
-env->mchk_index++;
-assert(env->mchk_index < MAX_MCHK_QUEUE);
-
-env->mchk_queue[env->mchk_index].type = 1;
-
 env->pending_int |= INTERRUPT_MCHK;
 cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
 }
@@ -225,7 +215,13 @@ bool s390_cpu_has_mcck_int(S390CPU *cpu)
 return false;
 }
 
-return 

[Qemu-devel] [PATCH v1 for-2-12 00/15] s390x: flic rework, tcg flic support and tcg

2017-12-11 Thread David Hildenbrand
This patch series implements floating interrupt support for TCG and fixes
STSI so we can remove warnings related to s390x SMP and MTTCG.

KVM code has to be touched in order to factor out the injection routines
into the flic ("s390x/flic: factor out injection of floating interrupts").
Basic testing didn't reveal any problems so far.

With this series I am now able to run fedora 26/27 and Ubuntu 17.10+ with
16 VCPUs (MTTCG) on a 8CPU host, doing a make -j16 in the guest. I got
nasty stalls in the guest beforehand.

I already sent the patches
 - "cpus: make pause_all_cpus() play with SMP on single threaded TCG"
 - "cpu-exec: fix missed CPU kick during interrupt injection"
separately, but as nobody commented so far (e.g. due to 2.11) I am including
them here as they are required to make SMP work reliably.

Based on: https://github.com/cohuck/qemu.git s390x-next
Available at: https://github.com/davidhildenbrand/qemu.git s390x-queue

David Hildenbrand (15):
  cpus: make pause_all_cpus() play with SMP on single threaded TCG
  cpu-exec: fix missed CPU kick during interrupt injection
  s390x/tcg: deliver multiple interrupts in a row
  s390x/flic: simplify flic initialization
  s390x/tcg: simplify machine check handling
  s390x/flic: factor out injection of floating interrupts
  s390x/tcg: tolerate wrong wakeups due to floating interrupts
  s390x/flic: make floating interrupts on TCG actually floating
  s390x/tcg: implement TEST PENDING INTERRUPTION
  s390x/flic: implement qemu_s390_clear_io_flic()
  s390x/flic: optimize CPU wakeup for TCG
  s390x/tcg: fix size + content of STSI blocks
  s390x/tcg: STSI overhaul
  s390x/tcg: remove SMP warning
  configure: s390x supports mttcg now

 accel/tcg/cpu-exec.c |  12 +-
 configure|   1 +
 cpus.c   |  32 +++---
 hw/intc/s390_flic.c  | 222 +++-
 hw/intc/s390_flic_kvm.c  |  75 +---
 hw/s390x/s390-virtio-ccw.c   |   4 -
 include/hw/s390x/s390_flic.h |  55 +++--
 target/s390x/cpu.c   |  10 --
 target/s390x/cpu.h   |  75 ++--
 target/s390x/excp_helper.c   | 147 +---
 target/s390x/helper.h|   1 +
 target/s390x/insn-data.def   |   1 +
 target/s390x/internal.h  |   5 -
 target/s390x/interrupt.c | 100 
 target/s390x/kvm-stub.c  |  13 ---
 target/s390x/kvm.c   |  68 +--
 target/s390x/kvm_s390x.h |  10 +-
 target/s390x/misc_helper.c   | 266 +++
 target/s390x/translate.c |   8 ++
 19 files changed, 644 insertions(+), 461 deletions(-)

-- 
2.14.3




[Qemu-devel] [PATCH v1 for-2-12 01/15] cpus: make pause_all_cpus() play with SMP on single threaded TCG

2017-12-11 Thread David Hildenbrand
pause_all_cpus() is sometimes called from a VCPU thread (e.g. s390x
during special reset). It cannot deal with multiple VCPUs per Thread
(single threaded TCG) yet.

Booting an s390x guest with -smp 2 and single threaded TCG from disk
currently fails. The DIAG 308 will issue a pause_all_cpus() and wait
forever for the CPUs to actually stop. But it is waiting for itself.

So let's stop all VCPUs belonging to the current thread. Factor out
stopping of a VCPU.

Signed-off-by: David Hildenbrand 
---
 cpus.c | 32 +++-
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/cpus.c b/cpus.c
index 114c29b6a0..3740c4db62 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1057,13 +1057,22 @@ static void qemu_tcg_destroy_vcpu(CPUState *cpu)
 {
 }
 
+static void qemu_cpu_stop(CPUState *cpu, bool exit)
+{
+g_assert(qemu_cpu_is_self(cpu));
+cpu->stop = false;
+cpu->stopped = true;
+if (exit) {
+cpu_exit(cpu);
+}
+qemu_cond_broadcast(_pause_cond);
+}
+
 static void qemu_wait_io_event_common(CPUState *cpu)
 {
 atomic_mb_set(>thread_kicked, false);
 if (cpu->stop) {
-cpu->stop = false;
-cpu->stopped = true;
-qemu_cond_broadcast(_pause_cond);
+qemu_cpu_stop(cpu, false);
 }
 process_queued_cpu_work(cpu);
 }
@@ -1610,12 +1619,12 @@ void pause_all_vcpus(void)
 
 qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
 CPU_FOREACH(cpu) {
-cpu->stop = true;
-qemu_cpu_kick(cpu);
-}
-
-if (qemu_in_vcpu_thread()) {
-cpu_stop_current();
+if (qemu_cpu_is_self(cpu)) {
+qemu_cpu_stop(cpu, true);
+} else {
+cpu->stop = true;
+qemu_cpu_kick(cpu);
+}
 }
 
 while (!all_vcpus_paused()) {
@@ -1799,10 +1808,7 @@ void qemu_init_vcpu(CPUState *cpu)
 void cpu_stop_current(void)
 {
 if (current_cpu) {
-current_cpu->stop = false;
-current_cpu->stopped = true;
-cpu_exit(current_cpu);
-qemu_cond_broadcast(_pause_cond);
+qemu_cpu_stop(current_cpu, true);
 }
 }
 
-- 
2.14.3




[Qemu-devel] [PATCH v1 for-2-12 14/15] s390x/tcg: remove SMP warning

2017-12-11 Thread David Hildenbrand
We should be pretty good in shape now. Floating interrupts are working
and atomic instructions should be atomic.

Signed-off-by: David Hildenbrand 
---
 hw/s390x/s390-virtio-ccw.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index c1f96418fa..6e286711e3 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -78,10 +78,6 @@ static void s390_init_cpus(MachineState *machine)
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 int i;
 
-if (tcg_enabled() && max_cpus > 1) {
-error_report("WARNING: SMP support on s390x is experimental!");
-}
-
 /* initialize possible_cpus */
 mc->possible_cpu_arch_ids(machine);
 
-- 
2.14.3




[Qemu-devel] [PATCH v1 for-2-12 12/15] s390x/tcg: fix size + content of STSI blocks

2017-12-11 Thread David Hildenbrand
All blocks are 4k in size, which is only true for two of them right now.
Also some reserved fields were wrong, fix it and convert all reserved
fields to u8.

This also fixes the LPAR part output in /proc/sysinfo under TCG. (for
now, everything was indicated as 0)

Signed-off-by: David Hildenbrand 
---
 target/s390x/cpu.h | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index b4a88830de..bfe650c46e 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -437,25 +437,27 @@ static inline void setcc(S390CPU *cpu, uint64_t cc)
 
 /* Basic Machine Configuration */
 struct sysib_111 {
-uint32_t res1[8];
+uint8_t  res1[32];
 uint8_t  manuf[16];
 uint8_t  type[4];
 uint8_t  res2[12];
 uint8_t  model[16];
 uint8_t  sequence[16];
 uint8_t  plant[4];
-uint8_t  res3[156];
+uint8_t  res3[3996];
 };
+QEMU_BUILD_BUG_ON(sizeof(struct sysib_111) != 4096);
 
 /* Basic Machine CPU */
 struct sysib_121 {
-uint32_t res1[80];
+uint8_t  res1[80];
 uint8_t  sequence[16];
 uint8_t  plant[4];
 uint8_t  res2[2];
 uint16_t cpu_addr;
-uint8_t  res3[152];
+uint8_t  res3[3992];
 };
+QEMU_BUILD_BUG_ON(sizeof(struct sysib_121) != 4096);
 
 /* Basic Machine CPUs */
 struct sysib_122 {
@@ -467,20 +469,22 @@ struct sysib_122 {
 uint16_t reserved_cpus;
 uint16_t adjustments[2026];
 };
+QEMU_BUILD_BUG_ON(sizeof(struct sysib_122) != 4096);
 
 /* LPAR CPU */
 struct sysib_221 {
-uint32_t res1[80];
+uint8_t  res1[80];
 uint8_t  sequence[16];
 uint8_t  plant[4];
 uint16_t cpu_id;
 uint16_t cpu_addr;
-uint8_t  res3[152];
+uint8_t  res3[3992];
 };
+QEMU_BUILD_BUG_ON(sizeof(struct sysib_221) != 4096);
 
 /* LPAR CPUs */
 struct sysib_222 {
-uint32_t res1[32];
+uint8_t  res1[32];
 uint16_t lpar_num;
 uint8_t  res2;
 uint8_t  lcpuc;
@@ -493,8 +497,9 @@ struct sysib_222 {
 uint8_t  res3[16];
 uint16_t dedicated_cpus;
 uint16_t shared_cpus;
-uint8_t  res4[180];
+uint8_t  res4[4020];
 };
+QEMU_BUILD_BUG_ON(sizeof(struct sysib_222) != 4096);
 
 /* VM CPUs */
 struct sysib_322 {
@@ -517,6 +522,7 @@ struct sysib_322 {
 uint8_t res4[1504];
 uint8_t ext_names[8][256];
 };
+QEMU_BUILD_BUG_ON(sizeof(struct sysib_322) != 4096);
 
 /* MMU defines */
 #define _ASCE_ORIGIN~0xfffULL /* segment table origin 
*/
-- 
2.14.3




Re: [Qemu-devel] [PATCH v6 2/4] vhost-user-blk: introduce a new vhost-user-blk host device

2017-12-11 Thread Stefan Hajnoczi
On Tue, Dec 05, 2017 at 02:27:17PM +0800, Changpeng Liu wrote:
> This commit introduces a new vhost-user device for block, it uses a
> chardev to connect with the backend, same with Qemu virito-blk device,
> Guest OS still uses the virtio-blk frontend driver.
> 
> To use it, start QEMU with command line like this:
> 
> qemu-system-x86_64 \
> -chardev socket,id=char0,path=/path/vhost.socket \
> -device vhost-user-blk-pci,chardev=char0,num-queues=2, \
> bootindex=2... \
> 
> Users can use different parameters for `num-queues` and `bootindex`.
> 
> Different with exist Qemu virtio-blk host device, it makes more easy
> for users to implement their own I/O processing logic, such as all
> user space I/O stack against hardware block device. It uses the new
> vhost messages(VHOST_USER_GET_CONFIG) to get block virtio config
> information from backend process.
> 
> Signed-off-by: Changpeng Liu 
> ---
>  default-configs/pci.mak|   1 +
>  hw/block/Makefile.objs |   3 +
>  hw/block/vhost-user-blk.c  | 357 
> +
>  hw/virtio/virtio-pci.c |  55 ++
>  hw/virtio/virtio-pci.h |  18 ++
>  include/hw/virtio/vhost-user-blk.h |  41 +
>  6 files changed, 475 insertions(+)
>  create mode 100644 hw/block/vhost-user-blk.c
>  create mode 100644 include/hw/virtio/vhost-user-blk.h

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [Qemu-devel] [v22 1/2] virtio-crypto: Add virtio crypto device specification

2017-12-11 Thread Halil Pasic


On 12/11/2017 01:56 PM, Longpeng (Mike) wrote:
> 
> 
> On 2017/12/6 19:01, Halil Pasic wrote:
> 
>>
>>
>> On 12/06/2017 08:37 AM, Longpeng(Mike) wrote:
>>> +\field{outcome_len} is the size of struct virtio_crypto_session_input or
>>> +ZERO for the session-destroy operation.
>>
>> This ain't correct. It should have been something like 
>> virtio_crypto_destroy_session_input.
>>
> 
> Hi Halil,
> 
> I already fixed this just now.
> Do you have any other comments on v22 ? I'll send v23 tomorrow if no. :)
> 

Did not read the rest of the document. I'm not in the middle of something,
but I wanted to read the operation part these days. I guess, you prefer
sending out v23 over waiting, so I guess I will wait for v23 then.

Some general questions/remarks before you spin v23:

* I'm not convinced about this 'header' and 'extra parameters' terminology.
Please see https://en.wikipedia.org/wiki/Header_(computing) for header.
I don't think it's fitting for the _flf structs. 
Same about the 'extra'. Please see  
https://www.merriam-webster.com/dictionary/extra
(a : more than is due, usual, or necessary : additional) the things in
_vlf aren't extra at all. Do you intend to stick with is terminology?
If yes why? Please explain how should I read/understand it so that it makes
sense!

* Do we want/need to specify any alignment requirement for the
stuff in guest storage (for instance the _flf fields) or be explicit
about no alignment should be assumed (e.g 
virtio_crypto_mac_create_session_flf.algo
ain't necessarily aligned (in guest memory) as required by uint32_t)?

* I assume one request is supposed to correspond to one descriptor chain.
Right? If yes, could you tell me, where is this expressed in the spec.

Halil




[Qemu-devel] [PATCH v1 13/19] fpu/softfloat: re-factor muladd

2017-12-11 Thread Alex Bennée
We can now add float16_muladd and use the common decompose and
canonicalize functions to have a single implementation for
float16/32/64 muladd functions.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat-specialize.h | 104 ---
 fpu/softfloat.c| 756 +
 include/fpu/softfloat.h|   1 +
 3 files changed, 286 insertions(+), 575 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 3d507d8c77..98fb0e7001 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -729,58 +729,6 @@ static float32 propagateFloat32NaN(float32 a, float32 b, 
float_status *status)
 }
 }
 
-/*
-| Takes three single-precision floating-point values `a', `b' and `c', one of
-| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
-| `b' or `c' is a signaling NaN, the invalid exception is raised.
-| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
-| obviously c is a NaN, and whether to propagate c or some other NaN is
-| implementation defined).
-**/
-
-static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
- float32 c, flag infzero,
- float_status *status)
-{
-flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
-cIsQuietNaN, cIsSignalingNaN;
-int which;
-
-aIsQuietNaN = float32_is_quiet_nan(a, status);
-aIsSignalingNaN = float32_is_signaling_nan(a, status);
-bIsQuietNaN = float32_is_quiet_nan(b, status);
-bIsSignalingNaN = float32_is_signaling_nan(b, status);
-cIsQuietNaN = float32_is_quiet_nan(c, status);
-cIsSignalingNaN = float32_is_signaling_nan(c, status);
-
-if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
-float_raise(float_flag_invalid, status);
-}
-
-which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
-  bIsQuietNaN, bIsSignalingNaN,
-  cIsQuietNaN, cIsSignalingNaN, infzero, status);
-
-if (status->default_nan_mode) {
-/* Note that this check is after pickNaNMulAdd so that function
- * has an opportunity to set the Invalid flag.
- */
-return float32_default_nan(status);
-}
-
-switch (which) {
-case 0:
-return float32_maybe_silence_nan(a, status);
-case 1:
-return float32_maybe_silence_nan(b, status);
-case 2:
-return float32_maybe_silence_nan(c, status);
-case 3:
-default:
-return float32_default_nan(status);
-}
-}
-
 #ifdef NO_SIGNALING_NANS
 int float64_is_quiet_nan(float64 a_, float_status *status)
 {
@@ -936,58 +884,6 @@ static float64 propagateFloat64NaN(float64 a, float64 b, 
float_status *status)
 }
 }
 
-/*
-| Takes three double-precision floating-point values `a', `b' and `c', one of
-| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
-| `b' or `c' is a signaling NaN, the invalid exception is raised.
-| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
-| obviously c is a NaN, and whether to propagate c or some other NaN is
-| implementation defined).
-**/
-
-static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
- float64 c, flag infzero,
- float_status *status)
-{
-flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
-cIsQuietNaN, cIsSignalingNaN;
-int which;
-
-aIsQuietNaN = float64_is_quiet_nan(a, status);
-aIsSignalingNaN = float64_is_signaling_nan(a, status);
-bIsQuietNaN = float64_is_quiet_nan(b, status);
-bIsSignalingNaN = float64_is_signaling_nan(b, status);
-cIsQuietNaN = float64_is_quiet_nan(c, status);
-cIsSignalingNaN = float64_is_signaling_nan(c, status);
-
-if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
-float_raise(float_flag_invalid, status);
-}
-
-which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
-  bIsQuietNaN, bIsSignalingNaN,
-  cIsQuietNaN, cIsSignalingNaN, infzero, status);
-
-if (status->default_nan_mode) {
-/* Note that this check is after pickNaNMulAdd so that function
- * has an opportunity to set the Invalid flag.
- */
-return float64_default_nan(status);
-}
-
-switch (which) {
-case 0:
-return float64_maybe_silence_nan(a, status);
-case 1:
-return float64_maybe_silence_nan(b, status);
-case 2:
-return float64_maybe_silence_nan(c, status);
-case 3:

[Qemu-devel] [PATCH v1 11/19] fpu/softfloat: re-factor mul

2017-12-11 Thread Alex Bennée
We can now add float16_mul and use the common decompose and
canonicalize functions to have a single implementation for
float16/32/64 versions.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 207 ++--
 include/fpu/softfloat.h |   1 +
 2 files changed, 80 insertions(+), 128 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index f89e47e3ef..6e9d4c172c 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -730,6 +730,85 @@ float64 float64_sub(float64 a, float64 b, float_status 
*status)
 return float64_round_pack_canonical(pr, status);
 }
 
+/*
+ * Returns the result of multiplying the floating-point values `a' and
+ * `b'. The operation is performed according to the IEC/IEEE Standard
+ * for Binary Floating-Point Arithmetic.
+ */
+
+static decomposed_parts mul_decomposed(decomposed_parts a, decomposed_parts b,
+   float_status *s)
+{
+bool sign = a.sign ^ b.sign;
+
+if (a.cls == float_class_normal && b.cls == float_class_normal) {
+uint64_t hi, lo;
+int exp = a.exp + b.exp;
+
+mul64To128(a.frac, b.frac, , );
+shift128RightJamming(hi, lo, DECOMPOSED_BINARY_POINT, , );
+if (lo & DECOMPOSED_OVERFLOW_BIT) {
+shift64RightJamming(lo, 1, );
+exp += 1;
+}
+
+/* Re-use a */
+a.exp = exp;
+a.sign = sign;
+a.frac = lo;
+return a;
+}
+/* handle all the NaN cases */
+if (a.cls >= float_class_qnan || b.cls >= float_class_qnan) {
+return pick_nan_parts(a, b, s);
+}
+/* Inf * Zero == NaN */
+if (((1 << a.cls) | (1 << b.cls)) ==
+((1 << float_class_inf) | (1 << float_class_zero))) {
+s->float_exception_flags |= float_flag_invalid;
+a.cls = float_class_dnan;
+a.sign = sign;
+return a;
+}
+/* Multiply by 0 or Inf */
+if (a.cls == float_class_inf || a.cls == float_class_zero) {
+a.sign = sign;
+return a;
+}
+if (b.cls == float_class_inf || b.cls == float_class_zero) {
+b.sign = sign;
+return b;
+}
+g_assert_not_reached();
+}
+
+float16 float16_mul(float16 a, float16 b, float_status *status)
+{
+decomposed_parts pa = float16_unpack_canonical(a, status);
+decomposed_parts pb = float16_unpack_canonical(b, status);
+decomposed_parts pr = mul_decomposed(pa, pb, status);
+
+return float16_round_pack_canonical(pr, status);
+}
+
+float32 float32_mul(float32 a, float32 b, float_status *status)
+{
+decomposed_parts pa = float32_unpack_canonical(a, status);
+decomposed_parts pb = float32_unpack_canonical(b, status);
+decomposed_parts pr = mul_decomposed(pa, pb, status);
+
+return float32_round_pack_canonical(pr, status);
+}
+
+float64 float64_mul(float64 a, float64 b, float_status *status)
+{
+decomposed_parts pa = float64_unpack_canonical(a, status);
+decomposed_parts pb = float64_unpack_canonical(b, status);
+decomposed_parts pr = mul_decomposed(pa, pb, status);
+
+return float64_round_pack_canonical(pr, status);
+}
+
 /*
 | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
 | and 7, and returns the properly rounded 32-bit integer corresponding to the
@@ -2542,70 +2621,6 @@ float32 float32_round_to_int(float32 a, float_status 
*status)
 }
 
 
-/*
-| Returns the result of multiplying the single-precision floating-point values
-| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
-| for Binary Floating-Point Arithmetic.
-**/
-
-float32 float32_mul(float32 a, float32 b, float_status *status)
-{
-flag aSign, bSign, zSign;
-int aExp, bExp, zExp;
-uint32_t aSig, bSig;
-uint64_t zSig64;
-uint32_t zSig;
-
-a = float32_squash_input_denormal(a, status);
-b = float32_squash_input_denormal(b, status);
-
-aSig = extractFloat32Frac( a );
-aExp = extractFloat32Exp( a );
-aSign = extractFloat32Sign( a );
-bSig = extractFloat32Frac( b );
-bExp = extractFloat32Exp( b );
-bSign = extractFloat32Sign( b );
-zSign = aSign ^ bSign;
-if ( aExp == 0xFF ) {
-if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
-return propagateFloat32NaN(a, b, status);
-}
-if ( ( bExp | bSig ) == 0 ) {
-float_raise(float_flag_invalid, status);
-return float32_default_nan(status);
-}
-return packFloat32( zSign, 0xFF, 0 );
-}
-if ( bExp == 0xFF ) {
-if (bSig) {
-return propagateFloat32NaN(a, b, status);
-}
-if ( ( aExp | aSig ) == 0 ) {
-float_raise(float_flag_invalid, status);
-return 

[Qemu-devel] [PATCH v4 19/46] windbg: implemented windbg_process_data_packet

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |   20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index 07a1815b79..cd46649278 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -125,9 +125,27 @@ static void windbg_vm_stop(void)
 g_free(buf.data);
 }
 
-static void windbg_process_data_packet(ParsingContext *ctx)
+static void windbg_process_manipulate_packet(ParsingContext *ctx)
 {}
 
+static void windbg_process_data_packet(ParsingContext *ctx)
+{
+switch (ctx->packet.PacketType) {
+case PACKET_TYPE_KD_STATE_MANIPULATE:
+windbg_send_control_packet(PACKET_TYPE_KD_ACKNOWLEDGE);
+windbg_process_manipulate_packet(ctx);
+break;
+
+default:
+WINDBG_ERROR("Caught unsupported data packet 0x%x",
+ ctx->packet.PacketType);
+
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+}
+}
+
 static void windbg_process_control_packet(ParsingContext *ctx)
 {
 switch (ctx->packet.PacketType) {




[Qemu-devel] [PATCH v4 14/46] windbg: init DBGKD_ANY_WAIT_STATE_CHANGE

2017-12-11 Thread Mihail Abakumov
Added function for init DBGKD_ANY_WAIT_STATE_CHANGE. It is a header of 'state 
change' packets.


Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |8 ++
 target/i386/windbgstub.c|   49 +++
 2 files changed, 57 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index b7e65faefe..830d01314e 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -42,6 +42,14 @@
 _t;   \
 })
 
+#if TARGET_LONG_BITS == 64
+# define sttul_p(p, v) stq_p(p, v)
+# define ldtul_p(p) ldq_p(p)
+#else
+# define sttul_p(p, v) stl_p(p, v)
+# define ldtul_p(p) ldl_p(p)
+#endif
+
 typedef struct SizedBuf {
 uint8_t *data;
 size_t size;
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 47ee5840ef..a3c433f756 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -17,9 +17,13 @@
 #ifdef TARGET_X86_64
 # define OFFSET_SELF_PCR 0x18
 # define OFFSET_VERS 0x108
+# define OFFSET_KPRCB0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x8
 #else
 # define OFFSET_SELF_PCR 0x1C
 # define OFFSET_VERS 0x34
+# define OFFSET_KPRCB0x20
+# define OFFSET_KPRCB_CURRTHREAD 0x4
 #endif
 
 bool windbg_on_load(void)
@@ -66,4 +70,49 @@ bool windbg_on_load(void)
 return true;
 }
 
+__attribute__ ((unused)) /* unused yet */
+static void kd_init_state_change(CPUState *cpu,
+ DBGKD_ANY_WAIT_STATE_CHANGE *sc)
+{
+CPUArchState *env = cpu->env_ptr;
+DBGKD_CONTROL_REPORT *cr = >ControlReport;
+InitedAddr *KPCR = windbg_get_KPCR();
+target_ulong KPRCB;
+int err = 0;
+
+/* T0D0: HEADER */
+
+sc->Processor = 0;
+
+sc->NumberProcessors = 0;
+CPUState *cpu_tmp;
+CPU_FOREACH(cpu_tmp) {
+sc->NumberProcessors++;
+}
+stl_p(>NumberProcessors, sc->NumberProcessors);
+
+KPRCB = READ_VMEM(cpu, KPCR->addr + OFFSET_KPRCB, target_ulong);
+sc->Thread = READ_VMEM(cpu, KPRCB + OFFSET_KPRCB_CURRTHREAD, target_ulong);
+sttul_p(>Thread, sc->Thread);
+sttul_p(>ProgramCounter, env->eip);
+
+/* T0D0: CONTROL REPORT */
+
+sttul_p(>Dr6, env->dr[6]);
+sttul_p(>Dr7, env->dr[7]);
+stw_p(>ReportFlags, REPORT_INCLUDES_SEGS | REPORT_STANDARD_CS);
+stw_p(>SegCs, env->segs[R_CS].selector);
+stw_p(>SegDs, env->segs[R_DS].selector);
+stw_p(>SegEs, env->segs[R_ES].selector);
+stw_p(>SegFs, env->segs[R_FS].selector);
+stl_p(>EFlags, env->eflags);
+
+err = cpu_memory_rw_debug(cpu, sc->ProgramCounter,
+  PTR(cr->InstructionStream[0]),
+  DBGKD_MAXSTREAM, 0);
+if (!err) {
+stw_p(>InstructionCount, DBGKD_MAXSTREAM);
+}
+}
+
 #endif




[Qemu-devel] [PATCH v4 31/46] windbg: implemented windbg_set_dr7

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |   27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index cae827df50..6e167a7473 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -299,7 +299,32 @@ static int windbg_hw_breakpoint_remove(CPUState *cpu, int 
index)
 }
 
 static void windbg_set_dr7(CPUState *cpu, target_ulong new_dr7)
-{}
+{
+CPUArchState *env = cpu->env_ptr;
+target_ulong old_dr7 = env->dr[7];
+int iobpt = 0;
+int i;
+
+new_dr7 |= DR7_FIXED_1;
+if (new_dr7 == old_dr7) {
+return;
+}
+
+for (i = 0; i < DR7_MAX_BP; i++) {
+if (IS_BP_ENABLED(old_dr7, i) && !IS_BP_ENABLED(new_dr7, i)) {
+windbg_hw_breakpoint_remove(cpu, i);
+}
+}
+
+env->dr[7] = new_dr7;
+for (i = 0; i < DR7_MAX_BP; i++) {
+if (IS_BP_ENABLED(env->dr[7], i)) {
+iobpt |= windbg_hw_breakpoint_insert(cpu, i);
+}
+}
+
+env->hflags = (env->hflags & ~HF_IOBPT_MASK) | iobpt;
+}
 
 static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
 {




[Qemu-devel] [PATCH v4 18/46] windbg: implemented windbg_process_control_packet

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |   26 +-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index 6eb9517e24..07a1815b79 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -129,7 +129,31 @@ static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
 static void windbg_process_control_packet(ParsingContext *ctx)
-{}
+{
+switch (ctx->packet.PacketType) {
+case PACKET_TYPE_KD_ACKNOWLEDGE:
+break;
+
+case PACKET_TYPE_KD_RESET:
+{
+SizedBuf buf = kd_gen_load_symbols_sc(qemu_get_cpu(0));
+windbg_send_data_packet(buf.data, buf.size,
+PACKET_TYPE_KD_STATE_CHANGE64);
+g_free(buf.data);
+
+windbg_send_control_packet(ctx->packet.PacketType);
+windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;
+break;
+}
+default:
+WINDBG_ERROR("Caught unsupported control packet 0x%x",
+ ctx->packet.PacketType);
+
+windbg_state->ctrl_packet_id = 0;
+windbg_send_control_packet(PACKET_TYPE_KD_RESEND);
+break;
+}
+}
 
 static void windbg_ctx_handler(ParsingContext *ctx)
 {




[Qemu-devel] [PATCH v4 26/46] windbg: implemented windbg_write_context

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |  216 ++
 1 file changed, 216 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index de3ffd78b0..6272a1341d 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -273,6 +273,12 @@ typedef struct _CPU_KPROCESSOR_STATE {
 CPU_KSPECIAL_REGISTERS SpecialRegisters;
 } CPU_KPROCESSOR_STATE, *PCPU_KPROCESSOR_STATE;
 
+static void windbg_set_dr(CPUState *cpu, int index, target_ulong value)
+{}
+
+static void windbg_set_sr(CPUState *cpu, int sr, uint16_t selector)
+{}
+
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
@@ -378,6 +384,216 @@ static int windbg_read_context(CPUState *cpu, uint8_t 
*buf, int buf_size,
 static int windbg_write_context(CPUState *cpu, uint8_t *buf, int buf_size,
 int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+int mem_size, i, tmp;
+uint8_t *mem_ptr = buf;
+
+if (len < 0 || len > buf_size) {
+WINDBG_ERROR("windbg_write_context: incorrect length %d", len);
+return 1;
+}
+
+if (offset < 0 || offset + len > sizeof(CPU_CONTEXT)) {
+WINDBG_ERROR("windbg_write_context: incorrect offset %d", offset);
+return 2;
+}
+
+while (len > 0 && offset < sizeof(CPU_CONTEXT)) {
+mem_size = 1;
+switch (offset) {
+
+case offsetof(CPU_CONTEXT, ContextFlags):
+mem_size = sizeof_field(CPU_CONTEXT, ContextFlags);
+break;
+
+case offsetof(CPU_CONTEXT, Dr0):
+mem_size = sizeof_field(CPU_CONTEXT, Dr0);
+windbg_set_dr(cpu, 0, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr1):
+mem_size = sizeof_field(CPU_CONTEXT, Dr1);
+windbg_set_dr(cpu, 1, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr2):
+mem_size = sizeof_field(CPU_CONTEXT, Dr2);
+windbg_set_dr(cpu, 2, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr3):
+mem_size = sizeof_field(CPU_CONTEXT, Dr3);
+windbg_set_dr(cpu, 3, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr6):
+mem_size = sizeof_field(CPU_CONTEXT, Dr6);
+windbg_set_dr(cpu, 6, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, Dr7):
+mem_size = sizeof_field(CPU_CONTEXT, Dr7);
+windbg_set_dr(cpu, 7, ldtul_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ControlWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ControlWord);
+cpu_set_fpuc(env, ldl_p(buf + offset));
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.StatusWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.StatusWord);
+tmp = ldl_p(buf + offset);
+env->fpstt = (tmp >> 11) & 7;
+env->fpus = tmp & ~0x3800;
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.TagWord):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.TagWord);
+tmp = ldl_p(buf + offset);
+for (i = 0; i < 8; ++i) {
+env->fptags[i] = !((tmp >> i) & 1);
+}
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ErrorOffset):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ErrorOffset);
+env->fpip &= ~0xL;
+env->fpip |= ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.ErrorSelector):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.ErrorSelector);
+env->fpip &= 0xL;
+env->fpip |= ((uint64_t) ldl_p(buf + offset)) << 32;
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.DataOffset):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.DataOffset);
+env->fpdp &= ~0xL;
+env->fpdp |= ldl_p(buf + offset);
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.DataSelector):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.DataSelector);
+env->fpdp &= 0xL;
+env->fpdp |= ((uint64_t) ldl_p(buf + offset)) << 32;
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.RegisterArea):
+mem_size = sizeof_field(CPU_CONTEXT, FloatSave.RegisterArea);
+for (i = 0; i < 8; ++i) {
+memcpy(PTR(env->fpregs[i]), mem_ptr + i * 10, 10);
+}
+break;
+
+case offsetof(CPU_CONTEXT, FloatSave.Cr0NpxState):
+mem_size = 

Re: [Qemu-devel] qemu process crash: Assertion failed: QLIST_EMPTY(>tracked_requests)

2017-12-11 Thread Fernando Casas Schössow
Hello Stefan,

Thanks for your reply.
Fortunately I didn’t have the problem again and it’s not clear how it can be 
consistently reproduced. Daily backups are running as usual at the moment.

If there is anything I can do from my side or if you have any ideas to try to 
reproduce it let me know.

Thanks.

Fer

Sent from my iPhone

On 11 Dec 2017, at 12:56, Stefan Hajnoczi 
> wrote:

On Thu, Dec 07, 2017 at 10:18:52AM +, Fernando Casas Schössow wrote:
Hi there,


Last night while doing a backup of a guest using the live snapshot mechanism 
the qemu process for the guest seem to had crashed.

The snapshot succeeded then the backup of the VM disk had place and also 
succeeded but the commit to the original disk after the backup seem to have 
failed.

The command I use in the script to take the snapshot is:


virsh snapshot-create-as --domain $VM backup-job.qcow2 --disk-only --atomic 
--quiesce --no-metadata


And then to commit back is:


virsh blockcommit $VM $TARGETDISK --base $DISKFILE --top $SNAPFILE --active 
--pivot


In the qemu log for the guest I found the following while the commit back was 
having place:


Assertion failed: QLIST_EMPTY(>tracked_requests) 
(/home/buildozer/aports/main/qemu/src/qemu-2.10.1/block/mirror.c: mirror_run: 
884)

I'm running qemu 2.10.1 with libvirt 3.9.0 and kernel 4.9.65 on Alpine Linux 
3.7.

This is the complete guest info from the logs:


LC_ALL=C 
PATH=/bin:/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
 HOME=/root USER=root QEMU_AUDIO_DRV=spice /usr/bin/qemu-system-x86_64 -name 
guest=DOCKER01,debug-threads=on -S -object 
secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-6-DOCKER01/master-key.aes
 -machine pc-i440fx-2.8,accel=kvm,usb=off,dump-guest-core=off -cpu 
IvyBridge,ss=on,vmx=on,pcid=on,hypervisor=on,arat=on,tsc_adjust=on,xsaveopt=on 
-drive 
file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd,if=pflash,format=raw,unit=0,readonly=on
 -drive 
file=/var/lib/libvirt/qemu/nvram/DOCKER01_VARS.fd,if=pflash,format=raw,unit=1 
-m 2048 -realtime mlock=off -smp 2,sockets=2,cores=1,threads=1 -uuid 
4705b146-3b14-4c20-923c-42105d47e7fc -no-user-config -nodefaults -chardev 
socket,id=charmonitor,path=/var/lib/libvirt/qemu/domain-6-DOCKER01/monitor.sock,server,nowait
 -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew 
-global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global 
PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot strict=on -device 
ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 -device 
ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x4.0x1 
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 
-device ahci,id=sata0,bus=pci.0,addr=0x9 -device 
virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x5 -drive 
file=/storage/storage-ssd-vms/virtual_machines_ssd/docker01.qcow2,format=qcow2,if=none,id=drive-sata0-0-0,cache=none,aio=threads
 -device ide-hd,bus=sata0.0,drive=drive-sata0-0-0,id=sata0-0-0,bootindex=1 
-netdev tap,fd=33,id=hostnet0,vhost=on,vhostfd=35 -device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:1c:af:ce,bus=pci.0,addr=0x3 
-chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 
-chardev 
socket,id=charchannel0,path=/var/lib/libvirt/qemu/channel/target/domain-6-DOCKER01/org.qemu.guest_agent.0,server,nowait
 -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0
 -chardev spicevmc,id=charchannel1,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=com.redhat.spice.0
 -spice port=5905,addr=127.0.0.1,disable-ticketing,seamless-migration=on 
-device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,vram64_size_mb=0,vgamem_mb=16,max_outputs=1,bus=pci.0,addr=0x2
 -chardev spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 -object 
rng-random,id=objrng0,filename=/dev/random -device 
virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x8 -msg timestamp=on



I was running on qemu 2.8.1 for months and didn't have any problems with the 
backups but yesterday I updated to qemu 2.10.1 and I hit this problem last 
night.


Is this a bug? Any ideas will be appreciated.

Thanks for reporting this bug.  Can you reproduce it reliably?

Stefan


[Qemu-devel] [PATCH v4 44/46] windbg: implemented kd_api_get_context_ex and kd_api_set_context_ex

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 +
 target/i386/windbgstub.c|  130 ---
 windbgstub.c|   14 +++-
 3 files changed, 106 insertions(+), 40 deletions(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 8d36354b7c..d3e737e031 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -94,6 +94,8 @@ void kd_api_search_memory(CPUState *cpu, PacketData *pd);
 void kd_api_fill_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 void kd_api_query_memory(CPUState *cpu, PacketData *pd);
+void kd_api_get_context_ex(CPUState *cpu, PacketData *pd);
+void kd_api_set_context_ex(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 7985dcfaf0..96cb015752 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -903,6 +903,52 @@ static int windbg_write_ks_regs(CPUState *cpu, uint8_t 
*buf, int buf_size,
 return 0;
 }
 
+static int windbg_rw_context_ex(CPUState *cpu, uint8_t *buf, int buf_size,
+int offset, int len, bool is_read)
+{
+uint32_t context_len;
+uint32_t ks_regs_len;
+int err = -1;
+
+if (offset < sizeof(CPU_KPROCESSOR_STATE)) {
+len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - offset);
+
+context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - offset));
+ks_regs_len = len - context_len;
+
+if (context_len > 0) {
+if (is_read) {
+err = windbg_read_context(cpu, buf, context_len, offset,
+  context_len);
+} else {
+err = windbg_write_context(cpu, buf, context_len, offset,
+   context_len);
+}
+
+if (err) {
+return err;
+}
+}
+
+if (ks_regs_len > 0) {
+offset += context_len - sizeof(CPU_CONTEXT);
+if (is_read) {
+err = windbg_read_ks_regs(cpu, buf + context_len, ks_regs_len,
+  offset, ks_regs_len);
+} else {
+err = windbg_write_ks_regs(cpu, buf + context_len, ks_regs_len,
+   offset, ks_regs_len);
+}
+
+if (err) {
+return err;
+}
+}
+}
+
+return err;
+}
+
 void kd_api_get_context(CPUState *cpu, PacketData *pd)
 {
 int err;
@@ -934,31 +980,14 @@ void kd_api_read_control_space(CPUState *cpu, PacketData 
*pd)
 {
 DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
 uint32_t len;
-uint32_t context_len;
-uint32_t ks_regs_len;
 target_ulong addr;
-int err = -1;
+int err;
 
 len = MIN(ldl_p(>TransferCount),
   PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
 addr = ldtul_p(>TargetBaseAddress);
 
-if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
-len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
-
-context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
-ks_regs_len = len - context_len;
-
-if (context_len > 0) {
-err = windbg_read_context(cpu, pd->extra, context_len, addr,
-  context_len);
-}
-if (ks_regs_len > 0) {
-addr = addr - sizeof(CPU_CONTEXT) + context_len;
-err = windbg_read_ks_regs(cpu, pd->extra + context_len,
-  ks_regs_len, addr, ks_regs_len);
-}
-}
+err = windbg_rw_context_ex(cpu, pd->extra, len, addr, len, true);
 
 if (err) {
 len = 0;
@@ -973,38 +1002,64 @@ void kd_api_write_control_space(CPUState *cpu, 
PacketData *pd)
 {
 DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
 uint32_t len;
-uint32_t context_len;
-uint32_t ks_regs_len;
 target_ulong addr;
-int err = -1;
+int err;
 
 len = MIN(ldl_p(>TransferCount), pd->extra_size);
 addr = ldtul_p(>TargetBaseAddress);
 
-if (addr < sizeof(CPU_KPROCESSOR_STATE)) {
-len = MIN(len, sizeof(CPU_KPROCESSOR_STATE) - addr);
+err = windbg_rw_context_ex(cpu, pd->extra, len, addr, len, false);
 
-context_len = MAX(0, (int) (sizeof(CPU_CONTEXT) - addr));
-ks_regs_len = len - context_len;
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+}
 
-if (context_len > 0) {
-err = windbg_write_context(cpu, pd->extra, context_len, addr,
-   context_len);
-}
-if (ks_regs_len > 0) {
-  

[Qemu-devel] [PATCH v1 for-2-12 10/15] s390x/flic: implement qemu_s390_clear_io_flic()

2017-12-11 Thread David Hildenbrand
Now that we have access to the io interrupts, we can implement
clear_io_irq() for TCG.

Signed-off-by: David Hildenbrand 
---
 hw/intc/s390_flic.c | 31 +--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index 3a28bee90c..fe6ad02f29 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -83,8 +83,35 @@ static void qemu_s390_release_adapter_routes(S390FLICState 
*fs,
 static int qemu_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,
uint16_t subchannel_nr)
 {
-/* Fixme TCG */
-return -ENOSYS;
+QEMUS390FLICState *flic  = QEMU_S390_FLIC(fs);
+QEMUS390FlicIO *cur, *next;
+uint8_t isc;
+
+g_assert(qemu_mutex_iothread_locked());
+if (!(flic->pending & FLIC_PENDING_IO)) {
+return 0;
+}
+
+/* check all iscs */
+for (isc = 0; isc < 8; isc++) {
+if (QLIST_EMPTY(>io[isc])) {
+continue;
+}
+
+/* search and delete any matching one */
+QLIST_FOREACH_SAFE(cur, >io[isc], next, next) {
+if (cur->id == subchannel_id && cur->nr == subchannel_nr) {
+QLIST_REMOVE(cur, next);
+g_free(cur);
+}
+}
+
+/* update our indicator bit */
+if (QLIST_EMPTY(>io[isc])) {
+flic->pending &= ~ISC_TO_PENDING_IO(isc);
+}
+}
+return 0;
 }
 
 static int qemu_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,
-- 
2.14.3




Re: [Qemu-devel] [PATCH v6 1/4] vhost-user: add new vhost user messages to support virtio config space

2017-12-11 Thread Stefan Hajnoczi
On Tue, Dec 05, 2017 at 02:27:16PM +0800, Changpeng Liu wrote:
> +* VHOST_USER_SET_CONFIG
> +  Id: 25
> +  Equivalent ioctl: N/A
> +  Master payload: virtio device config space
> +
> +  Submitted by the vhost-user master when the Guest changes the virtio
> +  device configuration space and also can be used for live migration
> +  on the destination host. The vhost-user slave must check the flags
> +  filed, and slaves MUST NOT accept SET_CONFIG for read-only

s/filed/field/

> +static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t 
> *config,
> + uint32_t offset, uint32_t size, uint32_t 
> flags)
> +{
> +uint8_t *p;
> +bool reply_supported = virtio_has_feature(dev->protocol_features,
> +  
> VHOST_USER_PROTOCOL_F_REPLY_ACK);
> +
> +VhostUserMsg msg = {
> +msg.request = VHOST_USER_SET_CONFIG,
> +msg.flags = VHOST_USER_VERSION,
> +msg.size = VHOST_USER_CONFIG_HDR_SIZE + size,
> +};
> +
> +if (reply_supported) {
> +msg.flags |= VHOST_USER_NEED_REPLY_MASK;
> +}
> +
> +msg.payload.config.offset = offset,
> +msg.payload.config.size = size,
> +msg.payload.config.flags = flags,
> +p = msg.payload.config.region;
> +memcpy(p, config + offset, size);

This function can be made more general by changing the semantics of the
config argument:

  memcpy(p, config, size);

Now the caller can pass just a single field instead of a whole 256-byte
config buffer.  It might be clearer to name the argument "data" or
"region" instead of "config" though.

> @@ -1505,6 +1508,67 @@ void vhost_ack_features(struct vhost_dev *hdev, const 
> int *feature_bits,
>  }
>  }
>  
> +int vhost_dev_get_config(struct vhost_dev *hdev, uint8_t *config,
> + uint32_t config_len)
> +{
> +assert(hdev->vhost_ops);
> +
> +if (hdev->vhost_ops->vhost_get_config) {
> +return hdev->vhost_ops->vhost_get_config(hdev, config, config_len);
> +}
> +
> +return 0;
> +}
> +
> +int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *config,
> + uint32_t offset, uint32_t size, uint32_t flags)
> +{
> +assert(hdev->vhost_ops);
> +
> +if (hdev->vhost_ops->vhost_set_config) {
> +return hdev->vhost_ops->vhost_set_config(hdev, config, offset,
> + size, flags);
> +}
> +
> +return 0;
> +}

Both vhost_dev_get_config() and vhost_dev_set_config() cannot fail
silently.  The device will not work properly if the configuration space
feature is not supported.

Please make these functions return an error if the callback is NULL.

The vhost-blk code should also check that
hdev->vhost_ops->vhost_set_config != NULL during realize.  This way
users see the error when adding the device instead of at runtime when
the function gets called.


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v13 00/12] Add ARMv8 RAS virtualization support in QEMU

2017-12-11 Thread Igor Mammedov
On Mon, 11 Dec 2017 19:31:14 +0800
gengdongjiu  wrote:

> Hi maintainer,
> 
>   This patch set seems pending about one month, could you help review for 
> them?  Thanks.
I'm going to look at ACPI side of it this week.


> In this series, except the three patches in [1] are dependent on KVM 
> implementation. Other patches does not depend on KVM/host,
> because KVM/host has already supported them,  According to James Morse 
> 's agreement, when Qemu receives SIGBUS with 
> MCE_MCEERR_AR, Qemu record
> the CPER and inject a Synchronous-External-Abort; when Qemu receives SIGBUS 
> with MCE_MCEERR_AO, Qemu record CPER and inject a GPIO IRQ. In my
> current patch set, I already do that.
> 
> I plan to move the three patches in [1] out of this patch set, because it was 
> a separate case, the three patches are used to set guest SError ESR,
> which depend on KVM "return a Error" to Qemu, James has some concern about 
> "KVM return error", so I plan to remove them from this patch set so that it 
> does not block the whole patches review.
> Thanks!
> 
> [1]:
> [v13,05/12] linux-headers: sync against Linux v4.14-rc8
> [v13,06/12] target-arm: kvm64: detect whether can set vsesr_el2
> [v13,07/12] target-arm: handle SError interrupt exception from the guest OS
> 
> 
> On 2017/11/28 2:39, Dongjiu Geng wrote:
> > From: gengdongjiu 
> >
> > In the ARMv8 platform, the CPU error type are synchronous external
> > abort(SEA) and SError Interrupt (SEI). If guest happen exception,
> > sometimes  guest itself do the recovery is better, because host
> > does not know guest's detailed info. For example, if a guest
> > user-space application happen exception, guest can kill this
> > application, but host can not do that.
> >
> > For the ARMv8 SEA/SEI, KVM or host kernel will deliver SIGBUS or
> > use other interface to notify user space. After user space gets
> > the notification, it will record the CPER to guest GHES buffer
> > for guest and inject a exception or IRQ to KVM.
> >
> > In the current implement, if the SIGBUS is BUS_MCEERR_AR, we will
> > treat it as synchronous exception, and use ARMv8 SEA notification type
> > to notify guest after recording CPER for guest; If the SIGBUS is
> > BUS_MCEERR_AO, we will treat it as asynchronous exception, and use
> > GPIO-Signal to notify guest after recording CPER for guest.
> >
> > If KVM wants userspace to do the recovery for the SError, it will return a 
> > error
> > status to Qemu. Then Qemu will specify the guest ESR value and inject a 
> > virtual
> > SError.
> >
> > This series patches have three parts:
> > 1. Generate APEI/GHES table and record CPER for guest in runtime.
> > 2. Handle the SIGBUS signal, record the CPER and fill into guest memory,
> >then according to SIGBUS type(BUS_MCEERR_AR or BUS_MCEERR_AO), using
> >different ACPI notification type to notify guest.
> > 3. Specify guest SError ESR value and inject a virtual SError
> >
> > Whole solution was suggested by James(james.mo...@arm.com); inject RAS SEA 
> > abort and specify guest ESR
> > in user space are suggested by Marc(marc.zyng...@arm.com), APEI part 
> > solution is suggested by
> > Laszlo(ler...@redhat.com). Shown some discussion in [1].
> >
> >
> > This series patches have already tested on ARM64 platform with RAS feature 
> > enabled:
> > Show the APEI part verification result in [2]
> > Show the BUS_MCEERR_AR and BUS_MCEERR_AO SIGBUS handling verification 
> > result in [3]
> > Show Qemu set guest ESR and inject virtual SError verification result in [4]
> >
> > ---
> > Change since v12:
> > 1. Address Paolo's comments to move HWPoisonPage definition to 
> > accel/kvm/kvm-all.c
> > 2. Only call kvm_cpu_synchronize_state() when get the BUS_MCEERR_AR signal
> > 3. Only add and enable GPIO-Signal and ARMv8 SEA two hardware error sources
> > 4. Address Michael's comments to not sync SPDX from Linux kernel header file
> >
> > Change since v11:
> > Address James's comments(james.mo...@arm.com)
> > 1. Check whether KVM has the capability to to set ESR instead of detecting 
> > host CPU RAS capability
> > 2. For SIGBUS_MCEERR_AR SIGBUS, use Synchronous-External-Abort(SEA) 
> > notification type
> >for SIGBUS_MCEERR_AO SIGBUS, use GPIO-Signal notification
> >
> >
> > Address Shannon's comments(for ACPI part):
> > 1. Unify hest_ghes.c and hest_ghes.h license declaration
> > 2. Remove unnecessary including "qmp-commands.h" in hest_ghes.c
> > 3. Unconditionally add guest APEI table based on James's 
> > comments(james.mo...@arm.com)
> > 4. Add a option to virt machine for migration compatibility. On new virt 
> > machine it's on
> >by default while off for old ones, we enabled it since 2.10
> > 5. Refer to the ACPI spec version which introduces Hardware Error 
> > Notification first time
> > 6. Add ACPI_HEST_NOTIFY_RESERVED notification type
> >
> > Address Igor's comments(for ACPI part):
> > 1. Add doc patch first which will 

[Qemu-devel] [PATCH v1 for-2-12 06/15] s390x/flic: factor out injection of floating interrupts

2017-12-11 Thread David Hildenbrand
Let the flic device handle it internally. This will allow us to later
on store floating interrupts in the flic for the TCG case.

This now also simplifies kvm.c. All that's left is the fallback
interface for floating interrupts, which is no triggered directly via
the flic in case anything goes wrong.

Signed-off-by: David Hildenbrand 
---
 hw/intc/s390_flic.c  | 31 
 hw/intc/s390_flic_kvm.c  | 63 
 include/hw/s390x/s390_flic.h |  5 
 target/s390x/cpu.h   |  7 -
 target/s390x/interrupt.c | 42 +++
 target/s390x/kvm-stub.c  | 13 -
 target/s390x/kvm.c   | 68 
 target/s390x/kvm_s390x.h | 10 +--
 8 files changed, 123 insertions(+), 116 deletions(-)

diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index a78bdf1d90..8d521c415a 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -131,6 +131,34 @@ static int qemu_s390_inject_airq(S390FLICState *fs, 
uint8_t type,
 return 0;
 }
 
+static void qemu_s390_inject_service(S390FLICState *fs, uint32_t parm)
+{
+
+S390CPU *dummy_cpu = s390_cpu_addr2state(0);
+
+/* FIXME: don't inject into dummy CPU */
+cpu_inject_service(dummy_cpu, parm);
+}
+
+static void qemu_s390_inject_io(S390FLICState *fs, uint16_t subchannel_id,
+uint16_t subchannel_nr, uint32_t io_int_parm,
+uint32_t io_int_word)
+{
+S390CPU *dummy_cpu = s390_cpu_addr2state(0);
+
+/* FIXME: don't inject into dummy CPU */
+cpu_inject_io(dummy_cpu, subchannel_id, subchannel_nr, io_int_parm,
+  io_int_word);
+}
+
+static void qemu_s390_inject_crw_mchk(S390FLICState *fs)
+{
+S390CPU *dummy_cpu = s390_cpu_addr2state(0);
+
+/* FIXME: don't inject into dummy CPU */
+cpu_inject_crw_mchk(dummy_cpu);
+}
+
 static void qemu_s390_flic_reset(DeviceState *dev)
 {
 QEMUS390FLICState *flic = QEMU_S390_FLIC(dev);
@@ -172,6 +200,9 @@ static void qemu_s390_flic_class_init(ObjectClass *oc, void 
*data)
 fsc->clear_io_irq = qemu_s390_clear_io_flic;
 fsc->modify_ais_mode = qemu_s390_modify_ais_mode;
 fsc->inject_airq = qemu_s390_inject_airq;
+fsc->inject_service = qemu_s390_inject_service;
+fsc->inject_io = qemu_s390_inject_io;
+fsc->inject_crw_mchk = qemu_s390_inject_crw_mchk;
 }
 
 static Property s390_flic_common_properties[] = {
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index 0cb5feab0c..d277ffdd2e 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -111,14 +111,64 @@ static int flic_enqueue_irqs(void *buf, uint64_t len,
 return rc ? -errno : 0;
 }
 
-int kvm_s390_inject_flic(struct kvm_s390_irq *irq)
+static void kvm_s390_inject_flic(S390FLICState *fs, struct kvm_s390_irq *irq)
 {
-static KVMS390FLICState *flic;
+static bool use_flic = true;
+int r;
+
+if (use_flic) {
+r = flic_enqueue_irqs(irq, sizeof(*irq), KVM_S390_FLIC(fs));
+if (r == -ENOSYS) {
+use_flic = false;
+}
+if (!r) {
+return;
+}
+}
+/* fallback to legacy KVM IOCTL in case FLIC fails */
+kvm_s390_floating_interrupt_legacy(irq);
+}
+
+static void kvm_s390_inject_service(S390FLICState *fs, uint32_t parm)
+{
+struct kvm_s390_irq irq = {
+.type = KVM_S390_INT_SERVICE,
+.u.ext.ext_params = parm,
+};
+
+kvm_s390_inject_flic(fs, );
+}
 
-if (unlikely(!flic)) {
-flic = KVM_S390_FLIC(s390_get_flic());
+static void kvm_s390_inject_io(S390FLICState *fs, uint16_t subchannel_id,
+   uint16_t subchannel_nr, uint32_t io_int_parm,
+   uint32_t io_int_word)
+{
+struct kvm_s390_irq irq = {
+.u.io.subchannel_id = subchannel_id,
+.u.io.subchannel_nr = subchannel_nr,
+.u.io.io_int_parm = io_int_parm,
+.u.io.io_int_word = io_int_word,
+};
+
+if (io_int_word & IO_INT_WORD_AI) {
+irq.type = KVM_S390_INT_IO(1, 0, 0, 0);
+} else {
+irq.type = KVM_S390_INT_IO(0, (subchannel_id & 0xff00) >> 8,
+  (subchannel_id & 0x0006),
+  subchannel_nr);
 }
-return flic_enqueue_irqs(irq, sizeof(*irq), flic);
+kvm_s390_inject_flic(fs, );
+}
+
+static void kvm_s390_inject_crw_mchk(S390FLICState *fs)
+{
+struct kvm_s390_irq irq = {
+.type = KVM_S390_MCHK,
+.u.mchk.cr14 = CR14_CHANNEL_REPORT_SC,
+.u.mchk.mcic = s390_build_validity_mcic() | MCIC_SC_CP,
+};
+
+kvm_s390_inject_flic(fs, );
 }
 
 static int kvm_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,
@@ -602,6 +652,9 @@ static void kvm_s390_flic_class_init(ObjectClass *oc, void 
*data)
 fsc->clear_io_irq = kvm_s390_clear_io_flic;
 fsc->modify_ais_mode = 

[Qemu-devel] [PATCH v1 for-2-12 11/15] s390x/flic: optimize CPU wakeup for TCG

2017-12-11 Thread David Hildenbrand
Kicking all CPUs on every floating interrupt is far from efficient.
Let's optimize it at least a little bit.

Signed-off-by: David Hildenbrand 
---
 hw/intc/s390_flic.c | 31 +--
 target/s390x/cpu.h  |  4 
 target/s390x/internal.h |  5 -
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index fe6ad02f29..c2cdaf90c1 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -164,10 +164,37 @@ static void qemu_s390_flic_notify(uint32_t type)
 
 /*
  * We have to make all CPUs see CPU_INTERRUPT_HARD, so they might
- * consider it. TODO: don't kick/wakeup all VCPUs but try to be
- * smarter (using the interrupt type).
+ * consider it. We will kick all running CPUs and only relevant
+ * sleeping ones.
  */
 CPU_FOREACH(cs) {
+S390CPU *cpu = S390_CPU(cs);
+
+cs->interrupt_request |= CPU_INTERRUPT_HARD;
+
+/* ignore CPUs that are not sleeping */
+if (s390_cpu_get_state(cpu) != CPU_STATE_OPERATING &&
+s390_cpu_get_state(cpu) != CPU_STATE_LOAD) {
+continue;
+}
+
+/* we always kick running CPUs for now, this is tricky */
+if (cs->halted) {
+/* don't check for subclasses, CPUs double check when waking up */
+if (type & FLIC_PENDING_SERVICE) {
+if (!(cpu->env.psw.mask & PSW_MASK_EXT)) {
+continue;
+}
+} else if (type & FLIC_PENDING_IO) {
+if (!(cpu->env.psw.mask & PSW_MASK_IO)) {
+continue;
+}
+} else if (type & FLIC_PENDING_MCHK_CR) {
+if (!(cpu->env.psw.mask & PSW_MASK_MCHECK)) {
+continue;
+}
+}
+}
 cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 }
 }
diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index 2a37ef5050..b4a88830de 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -691,6 +691,10 @@ static inline unsigned int s390_cpu_set_state(uint8_t 
cpu_state, S390CPU *cpu)
 return 0;
 }
 #endif /* CONFIG_USER_ONLY */
+static inline uint8_t s390_cpu_get_state(S390CPU *cpu)
+{
+return cpu->env.cpu_state;
+}
 
 
 /* cpu_models.c */
diff --git a/target/s390x/internal.h b/target/s390x/internal.h
index 1a88e4beb4..dbac3f7cbb 100644
--- a/target/s390x/internal.h
+++ b/target/s390x/internal.h
@@ -278,11 +278,6 @@ static inline void s390_do_cpu_full_reset(CPUState *cs, 
run_on_cpu_data arg)
 cpu_reset(cs);
 }
 
-static inline uint8_t s390_cpu_get_state(S390CPU *cpu)
-{
-return cpu->env.cpu_state;
-}
-
 
 /* arch_dump.c */
 int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
-- 
2.14.3




[Qemu-devel] [PATCH v1 for-2-12 13/15] s390x/tcg: STSI overhaul

2017-12-11 Thread David Hildenbrand
Current STSI implementation is a mess, so let's rewrite it.

Problems fixed by this patch:
1) The order of exceptions/when recognized is wrong.
2) We have to store to virtual address space, not absolute.
3) Alignment check of the block is missing.
3) The SMP information is not indicated.

While at it:
a) Make the code look nicer
- get rid of nesting levels
- use struct initialization instead of initializing to zero
- rename a misspelled field and rename function code defines
- use a union and have only one write statement
- use cpu_to_beX()
b) Indicate the VM name/extended name + UUID just like KVM does
c) Indicate that all LPAR CPUs we fake are dedicated
d) Add a comment why we fake being a KVM guest
e) Give our guest as default the name "TCGguest"
f) Fake the same CPU information we have in our Guest for all layers

While at it, get rid of "potential_page_fault()" by forwarding the
retaddr properly.

The result is best verified by looking at "/proc/sysinfo" in the guest
when specifying on the qemu command line
-uuid "74738ff5-5367-5958-9aee-98fffdcd1876" \
-name "extra long guest name"

Signed-off-by: David Hildenbrand 
---
 target/s390x/cpu.h |  22 +++--
 target/s390x/misc_helper.c | 213 -
 2 files changed, 132 insertions(+), 103 deletions(-)

diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
index bfe650c46e..aded28d390 100644
--- a/target/s390x/cpu.h
+++ b/target/s390x/cpu.h
@@ -425,11 +425,11 @@ static inline void setcc(S390CPU *cpu, uint64_t cc)
 }
 
 /* STSI */
-#define STSI_LEVEL_MASK 0xf000ULL
-#define STSI_LEVEL_CURRENT  0xULL
-#define STSI_LEVEL_10x1000ULL
-#define STSI_LEVEL_20x2000ULL
-#define STSI_LEVEL_30x3000ULL
+#define STSI_R0_FC_MASK 0xf000ULL
+#define STSI_R0_FC_CURRENT  0xULL
+#define STSI_R0_FC_LEVEL_1  0x1000ULL
+#define STSI_R0_FC_LEVEL_2  0x2000ULL
+#define STSI_R0_FC_LEVEL_3  0x3000ULL
 #define STSI_R0_RESERVED_MASK   0x0f00ULL
 #define STSI_R0_SEL1_MASK   0x00ffULL
 #define STSI_R1_RESERVED_MASK   0xULL
@@ -464,7 +464,7 @@ struct sysib_122 {
 uint8_t res1[32];
 uint32_t capability;
 uint16_t total_cpus;
-uint16_t active_cpus;
+uint16_t conf_cpus;
 uint16_t standby_cpus;
 uint16_t reserved_cpus;
 uint16_t adjustments[2026];
@@ -524,6 +524,16 @@ struct sysib_322 {
 };
 QEMU_BUILD_BUG_ON(sizeof(struct sysib_322) != 4096);
 
+union sysib {
+struct sysib_111 sysib_111;
+struct sysib_121 sysib_121;
+struct sysib_122 sysib_122;
+struct sysib_221 sysib_221;
+struct sysib_222 sysib_222;
+struct sysib_322 sysib_322;
+};
+QEMU_BUILD_BUG_ON(sizeof(union sysib) != 4096);
+
 /* MMU defines */
 #define _ASCE_ORIGIN~0xfffULL /* segment table origin 
*/
 #define _ASCE_SUBSPACE  0x200 /* subspace group control   
*/
diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index 8483abeda6..b9dbe01a62 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -36,6 +36,9 @@
 #include "hw/s390x/ebcdic.h"
 #include "hw/s390x/s390-virtio-hcall.h"
 #include "hw/s390x/sclp.h"
+#include "hw/s390x/ioinst.h"
+#include "hw/s390x/s390_flic.h"
+#include "hw/boards.h"
 #endif
 
 /* #define DEBUG_HELPER */
@@ -194,132 +197,148 @@ void HELPER(spt)(CPUS390XState *env, uint64_t time)
 }
 
 /* Store System Information */
-uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
-  uint64_t r0, uint64_t r1)
+uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint64_t r0, uint64_t 
r1)
 {
+const uintptr_t ra = GETPC();
+const uint32_t sel1 = r0 & STSI_R0_SEL1_MASK;
+const uint32_t sel2 = r1 & STSI_R1_SEL2_MASK;
+const MachineState *ms = MACHINE(qdev_get_machine());
+uint16_t total_cpus = 0, conf_cpus = 0, reserved_cpus = 0;
 S390CPU *cpu = s390_env_get_cpu(env);
-int cc = 0;
-int sel1, sel2;
+union sysib sysib = { 0 };
+int i, cc = 0;
+
+if ((r0 & STSI_R0_FC_MASK) > STSI_R0_FC_LEVEL_3) {
+/* invalid function code: no other checks are performed */
+return 3;
+}
 
-if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
-((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
-/* valid function code, invalid reserved bits */
-s390_program_interrupt(env, PGM_SPECIFICATION, 4, GETPC());
+if ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK)) {
+s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
 }
 
-sel1 = r0 & STSI_R0_SEL1_MASK;
-sel2 = r1 & STSI_R1_SEL2_MASK;
+if ((r0 & STSI_R0_FC_MASK) == STSI_R0_FC_CURRENT) {
+/* query the current level: no further checks are performed */
+

Re: [Qemu-devel] [PATCH v1 for-2-12 04/15] s390x/flic: simplify flic initialization

2017-12-11 Thread Christian Borntraeger
On 12/11/2017 02:47 PM, David Hildenbrand wrote:
> This makes it clearer, which device is used for which accelerator.
> 
> Signed-off-by: David Hildenbrand 
nice.

Reviewed-by: Christian Borntraeger 


> ---
>  hw/intc/s390_flic.c  |  9 +++--
>  hw/intc/s390_flic_kvm.c  | 12 
>  include/hw/s390x/s390_flic.h |  9 -
>  3 files changed, 7 insertions(+), 23 deletions(-)
> 
> diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
> index 6eaf178d79..a78bdf1d90 100644
> --- a/hw/intc/s390_flic.c
> +++ b/hw/intc/s390_flic.c
> @@ -40,11 +40,16 @@ void s390_flic_init(void)
>  {
>  DeviceState *dev;
> 
> -dev = s390_flic_kvm_create();
> -if (!dev) {
> +if (kvm_enabled()) {
> +dev = qdev_create(NULL, TYPE_KVM_S390_FLIC);
> +object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC,
> +  OBJECT(dev), NULL);
> +} else if (tcg_enabled()) {
>  dev = qdev_create(NULL, TYPE_QEMU_S390_FLIC);
>  object_property_add_child(qdev_get_machine(), TYPE_QEMU_S390_FLIC,
>OBJECT(dev), NULL);
> +} else {
> +g_assert_not_reached();
>  }
>  qdev_init_nofail(dev);
>  }
> diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
> index d208cb81c4..0cb5feab0c 100644
> --- a/hw/intc/s390_flic_kvm.c
> +++ b/hw/intc/s390_flic_kvm.c
> @@ -35,18 +35,6 @@ typedef struct KVMS390FLICState {
>  bool clear_io_supported;
>  } KVMS390FLICState;
> 
> -DeviceState *s390_flic_kvm_create(void)
> -{
> -DeviceState *dev = NULL;
> -
> -if (kvm_enabled()) {
> -dev = qdev_create(NULL, TYPE_KVM_S390_FLIC);
> -object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC,
> -  OBJECT(dev), NULL);
> -}
> -return dev;
> -}
> -
>  /**
>   * flic_get_all_irqs - store all pending irqs in buffer
>   * @buf: pointer to buffer which is passed to kernel
> diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h
> index 7aab6ef7f0..5b00e936fa 100644
> --- a/include/hw/s390x/s390_flic.h
> +++ b/include/hw/s390x/s390_flic.h
> @@ -91,13 +91,4 @@ void s390_flic_init(void);
>  S390FLICState *s390_get_flic(void);
>  bool ais_needed(void *opaque);
> 
> -#ifdef CONFIG_KVM
> -DeviceState *s390_flic_kvm_create(void);
> -#else
> -static inline DeviceState *s390_flic_kvm_create(void)
> -{
> -return NULL;
> -}
> -#endif
> -
>  #endif /* HW_S390_FLIC_H */
> 




Re: [Qemu-devel] [PATCH 2/5] lock-guard: add scoped lock implementation

2017-12-11 Thread Eric Blake
On 12/11/2017 04:16 AM, Stefan Hajnoczi wrote:

>>> I don't understand the need for the qemu_lock_guard_is_taken()
>>> condition, why not do the following?
>>>
>>>   for (QEMU_LOCK_GUARD(type, name, lock);
>>>;
>>>qemu_lock_guard_unlock())
>>
>> Because that would be an infinite loop. :)
> 
> Sorry, I mean for (...; false; ...).  Is there any reason to do
> qemu_lock_guard_is_taken()?

You need the loop to execute at least once ;)

But I proposed an alternative that doesn't need is_taken, by:

for (bool name##done = false, QEMU_LOCK_GUARD(type, name, lock);
 ! name##done; name##done = true)

if we still like the form that declares a for-loop scope.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] baum: Truncate braille device size to 84x1

2017-12-11 Thread Eric Blake
On 12/10/2017 06:19 PM, Samuel Thibault wrote:
> Baum device bigger than 84 do not actually exist, some guest drivers
> would be upset by such sizes.
> 
> Signed-off-by: Samuel Thibault 
> ---
>  chardev/baum.c | 8 +++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 

> @@ -239,6 +239,12 @@ static int baum_deferred_init(BaumChardev *baum)
>  brlapi_perror("baum: brlapi__getDisplaySize");
>  return 0;
>  }
> +if (baum->y > 1) {
> +baum->y = 1;
> +}
> +if (baum->x > 84) {
> +baum->x = 84;
> +}

Is magic clamping desirable, or is it better to make it a hard error if
the user configured a size that is not possible?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] baum: Truncate braille device size to 84x1

2017-12-11 Thread Samuel Thibault
Eric Blake, on lun. 11 déc. 2017 08:30:39 -0600, wrote:
> On 12/10/2017 06:19 PM, Samuel Thibault wrote:
> > Baum device bigger than 84 do not actually exist, some guest drivers
> > would be upset by such sizes.
> > 
> > Signed-off-by: Samuel Thibault 
> > ---
> >  chardev/baum.c | 8 +++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> 
> > @@ -239,6 +239,12 @@ static int baum_deferred_init(BaumChardev *baum)
> >  brlapi_perror("baum: brlapi__getDisplaySize");
> >  return 0;
> >  }
> > +if (baum->y > 1) {
> > +baum->y = 1;
> > +}
> > +if (baum->x > 84) {
> > +baum->x = 84;
> > +}
> 
> Is magic clamping desirable, or is it better to make it a hard error if
> the user configured a size that is not possible?

The thing is: the user didn't configure something, she just happened to
use a braille device bigger than 84 to display qemu's braille output.

This is the same situation as for the virtual video card: qemu could
expose resolutions as big as the size of the X display where qemu is
running on, but it's not a good idea to expose them all because some
drivers could go crazy with sizes bigger than what is supposed to be
supported by the hardware (or just assume the device is bogus and refuse
to drive it), and one should thus rather clamp them to what an actual
video device would support.

Samuel



[Qemu-devel] [PATCH v1 01/19] fpu/softfloat: implement float16_squash_input_denormal

2017-12-11 Thread Alex Bennée
This will be required when expanding the MINMAX() macro for 16
bit/half-precision operations.

Signed-off-by: Alex Bennée 
Reviewed-by: Richard Henderson 
---
 fpu/softfloat.c | 15 +++
 include/fpu/softfloat.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 433c5dad2d..3a4ab1355f 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3488,6 +3488,21 @@ static float16 roundAndPackFloat16(flag zSign, int zExp,
 return packFloat16(zSign, zExp, zSig >> 13);
 }
 
+/*
+| If `a' is denormal and we are in flush-to-zero mode then set the
+| input-denormal exception and return zero. Otherwise just return the value.
+**/
+float16 float16_squash_input_denormal(float16 a, float_status *status)
+{
+if (status->flush_inputs_to_zero) {
+if (extractFloat16Exp(a) == 0 && extractFloat16Frac(a) != 0) {
+float_raise(float_flag_input_denormal, status);
+return make_float16(float16_val(a) & 0x8000);
+}
+}
+return a;
+}
+
 static void normalizeFloat16Subnormal(uint32_t aSig, int *zExpPtr,
   uint32_t *zSigPtr)
 {
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 0f96a0edd1..d5e99667b6 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -277,6 +277,7 @@ void float_raise(uint8_t flags, float_status *status);
 | If `a' is denormal and we are in flush-to-zero mode then set the
 | input-denormal exception and return zero. Otherwise just return the value.
 **/
+float16 float16_squash_input_denormal(float16 a, float_status *status);
 float32 float32_squash_input_denormal(float32 a, float_status *status);
 float64 float64_squash_input_denormal(float64 a, float_status *status);
 
-- 
2.15.1




[Qemu-devel] [PATCH v1 07/19] fpu/softfloat: improve comments on ARM NaN propagation

2017-12-11 Thread Alex Bennée
Mention the pseudo-code fragment from which this is based and correct
the spelling of signalling.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat-specialize.h | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index de2c5d5702..3d507d8c77 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -445,14 +445,15 @@ static float32 commonNaNToFloat32(commonNaNT a, 
float_status *status)
 
 #if defined(TARGET_ARM)
 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
-flag aIsLargerSignificand)
+   flag aIsLargerSignificand)
 {
-/* ARM mandated NaN propagation rules: take the first of:
- *  1. A if it is signaling
- *  2. B if it is signaling
+/* ARM mandated NaN propagation rules (see FPProcessNaNs()), take
+ * the first of:
+ *  1. A if it is signalling
+ *  2. B if it is signalling
  *  3. A (quiet)
  *  4. B (quiet)
- * A signaling NaN is always quietened before returning it.
+ * A signalling NaN is always quietened before returning it.
  */
 if (aIsSNaN) {
 return 0;
-- 
2.15.1




[Qemu-devel] [PATCH v1 05/19] include/fpu/softfloat: add some float16 contants

2017-12-11 Thread Alex Bennée
This defines the same set of common constants for float 16 as defined
for 32 and 64 bit floats. These are often used by target helper
functions.

Signed-off-by: Alex Bennée 
---
 include/fpu/softfloat.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 17dfe60dbd..5a9258c57c 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -395,6 +395,13 @@ static inline float16 float16_set_sign(float16 a, int sign)
 return make_float16((float16_val(a) & 0x7fff) | (sign << 15));
 }
 
+#define float16_zero make_float16(0)
+#define float16_one make_float16(0x3a00)
+#define float16_ln2 make_float16(0x34d1)
+#define float16_pi make_float16(0x4448)
+#define float16_half make_float16(0x3800)
+#define float16_infinity make_float16(0x7a00)
+
 /*
 | The pattern for a default generated half-precision NaN.
 **/
-- 
2.15.1




[Qemu-devel] [PATCH v1 08/19] fpu/softfloat: move the extract functions to the top of the file

2017-12-11 Thread Alex Bennée
This is pure code-motion during re-factoring as the helpers will be
needed earlier.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 119 +---
 1 file changed, 53 insertions(+), 66 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 44c043924e..0850a78149 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -132,6 +132,59 @@ static inline flag extractFloat16Sign(float16 a)
 return float16_val(a)>>15;
 }
 
+/*
+| Returns the fraction bits of the single-precision floating-point value `a'.
+**/
+
+static inline uint32_t extractFloat32Frac(float32 a)
+{
+return float32_val(a) & 0x007F;
+}
+
+/*
+| Returns the exponent bits of the single-precision floating-point value `a'.
+**/
+
+static inline int extractFloat32Exp(float32 a)
+{
+return (float32_val(a) >> 23) & 0xFF;
+}
+
+/*
+| Returns the sign bit of the single-precision floating-point value `a'.
+**/
+
+static inline flag extractFloat32Sign(float32 a)
+{
+return float32_val(a) >> 31;
+}
+
+/*
+| Returns the fraction bits of the double-precision floating-point value `a'.
+**/
+
+static inline uint64_t extractFloat64Frac(float64 a)
+{
+return float64_val(a) & LIT64(0x000F);
+}
+
+/*
+| Returns the exponent bits of the double-precision floating-point value `a'.
+**/
+
+static inline int extractFloat64Exp(float64 a)
+{
+return (float64_val(a) >> 52) & 0x7FF;
+}
+
+/*
+| Returns the sign bit of the double-precision floating-point value `a'.
+**/
+
+static inline flag extractFloat64Sign(float64 a)
+{
+return float64_val(a) >> 63;
+}
 /*
 | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
 | and 7, and returns the properly rounded 32-bit integer corresponding to the
@@ -299,39 +352,6 @@ static int64_t roundAndPackUint64(flag zSign, uint64_t 
absZ0,
 return absZ0;
 }
 
-/*
-| Returns the fraction bits of the single-precision floating-point value `a'.
-**/
-
-static inline uint32_t extractFloat32Frac( float32 a )
-{
-
-return float32_val(a) & 0x007F;
-
-}
-
-/*
-| Returns the exponent bits of the single-precision floating-point value `a'.
-**/
-
-static inline int extractFloat32Exp(float32 a)
-{
-
-return ( float32_val(a)>>23 ) & 0xFF;
-
-}
-
-/*
-| Returns the sign bit of the single-precision floating-point value `a'.
-**/
-
-static inline flag extractFloat32Sign( float32 a )
-{
-
-return float32_val(a)>>31;
-
-}
-
 /*
 | If `a' is denormal and we are in flush-to-zero mode then set the
 | input-denormal exception and return zero. Otherwise just return the value.
@@ -492,39 +512,6 @@ static float32
 
 }
 
-/*
-| Returns the fraction bits of the double-precision floating-point value `a'.
-**/
-
-static inline uint64_t extractFloat64Frac( float64 a )
-{
-
-return float64_val(a) & LIT64( 0x000F );
-
-}
-
-/*
-| Returns the exponent bits of the double-precision floating-point value `a'.
-**/
-
-static inline int extractFloat64Exp(float64 a)
-{
-
-return ( float64_val(a)>>52 ) & 0x7FF;
-
-}
-
-/*
-| Returns 

[Qemu-devel] [PATCH v1 18/19] fpu/softfloat: re-factor minmax

2017-12-11 Thread Alex Bennée
Let's do the same re-factor treatment for minmax functions. I still
use the MACRO trick to expand but now all the checking code is common.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 242 ++--
 include/fpu/softfloat.h |   6 ++
 2 files changed, 137 insertions(+), 111 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index b7ea56dfa5..5eba996932 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1662,6 +1662,137 @@ float64 uint16_to_float64(uint16_t a, float_status 
*status)
 return uint64_to_float64((uint64_t) a, status);
 }
 
+/* Float Min/Max */
+/* min() and max() functions. These can't be implemented as
+ * 'compare and pick one input' because that would mishandle
+ * NaNs and +0 vs -0.
+ *
+ * minnum() and maxnum() functions. These are similar to the min()
+ * and max() functions but if one of the arguments is a QNaN and
+ * the other is numerical then the numerical argument is returned.
+ * SNaNs will get quietened before being returned.
+ * minnum() and maxnum correspond to the IEEE 754-2008 minNum()
+ * and maxNum() operations. min() and max() are the typical min/max
+ * semantics provided by many CPUs which predate that specification.
+ *
+ * minnummag() and maxnummag() functions correspond to minNumMag()
+ * and minNumMag() from the IEEE-754 2008.
+ */
+static decomposed_parts minmax_decomposed(decomposed_parts a,
+  decomposed_parts b,
+  bool ismin, bool ieee, bool ismag,
+  float_status *s)
+{
+if (a.cls >= float_class_qnan
+||
+b.cls >= float_class_qnan)
+{
+if (ieee) {
+/* Takes two floating-point values `a' and `b', one of
+ * which is a NaN, and returns the appropriate NaN
+ * result. If either `a' or `b' is a signaling NaN,
+ * the invalid exception is raised.
+ */
+if (a.cls == float_class_snan || b.cls == float_class_snan) {
+s->float_exception_flags |= float_flag_invalid;
+if (s->default_nan_mode) {
+a.cls = float_class_msnan;
+return a;
+}
+} else if (a.cls >= float_class_qnan
+   &&
+   b.cls < float_class_qnan) {
+return b;
+} else if (b.cls >= float_class_qnan
+   &&
+   a.cls < float_class_qnan) {
+return a;
+}
+}
+return pick_nan_parts(a, b, s);
+}
+
+/* Handle zero cases */
+if (a.cls == float_class_zero || b.cls == float_class_zero) {
+if (a.cls == float_class_normal) {
+if (a.sign) {
+return ismin ? a : b;
+} else {
+return ismin ? b : a;
+}
+} else if (b.cls == float_class_normal) {
+if (b.sign) {
+return ismin ? b : a;
+} else {
+return ismin ? a : b;
+}
+}
+}
+
+if (ismag) {
+/* Magnitude, ignore sign */
+bool a_less;
+if (a.exp == b.exp) {
+a_less = a.frac < b.frac;
+} else {
+a_less = a.exp < b.exp;
+}
+return a_less == ismin ? a : b;
+}
+if (a.sign != b.sign) {
+if (ismin) {
+return a.sign ? a : b;
+} else {
+return a.sign ? b : a;
+}
+} else {
+bool a_less;
+if (a.exp == b.exp) {
+a_less = a.frac < b.frac;
+} else {
+a_less = a.exp < b.exp;
+}
+if (ismin) {
+return a.sign ^ a_less ? a : b;
+} else {
+return a.sign ^ a_less ? b : a;
+}
+}
+}
+
+#define MINMAX(sz, name, ismin, isiee, ismag)   \
+float ## sz float ## sz ## _ ## name(float ## sz a, float ## sz b, 
float_status *s) \
+{   \
+decomposed_parts pa = float ## sz ## _unpack_canonical(a, s);   \
+decomposed_parts pb = float ## sz ## _unpack_canonical(b, s);   \
+decomposed_parts pr = minmax_decomposed(pa, pb, ismin, isiee, ismag, s); \
+\
+return float ## sz ## _round_pack_canonical(pr, s);\
+}
+
+MINMAX(16, min, true, false, false)
+MINMAX(16, minnum, true, true, false)
+MINMAX(16, minnummag, true, true, true)
+MINMAX(16, max, false, false, false)

[Qemu-devel] [PATCH v1 12/19] fpu/softfloat: re-factor div

2017-12-11 Thread Alex Bennée
We can now add float16_div and use the common decompose and
canonicalize functions to have a single implementation for
float16/32/64 versions.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat-macros.h  |  44 +
 fpu/softfloat.c | 235 ++--
 include/fpu/softfloat.h |   1 +
 3 files changed, 134 insertions(+), 146 deletions(-)

diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h
index 9cc6158cb4..980be2c051 100644
--- a/fpu/softfloat-macros.h
+++ b/fpu/softfloat-macros.h
@@ -625,6 +625,50 @@ static uint64_t estimateDiv128To64( uint64_t a0, uint64_t 
a1, uint64_t b )
 
 }
 
+/* Nicked from gmp longlong.h __udiv_qrnnd */
+static uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d)
+{
+uint64_t d0, d1, q0, q1, r1, r0, m;
+
+d0 = (uint32_t)d;
+d1 = d >> 32;
+
+r1 = n1 % d1;
+q1 = n1 / d1;
+m = q1 * d0;
+r1 = (r1 << 32) | (n0 >> 32);
+if (r1 < m) {
+q1 -= 1;
+r1 += d;
+if (r1 >= d) {
+if (r1 < m) {
+q1 -= 1;
+r1 += d;
+}
+}
+}
+r1 -= m;
+
+r0 = r1 % d1;
+q0 = r1 / d1;
+m = q0 * d0;
+r0 = (r0 << 32) | (uint32_t)n0;
+if (r0 < m) {
+q0 -= 1;
+r0 += d;
+if (r0 >= d) {
+if (r0 < m) {
+q0 -= 1;
+r0 += d;
+}
+}
+}
+r0 -= m;
+
+/* Return remainder in LSB */
+return (q1 << 32) | q0 | (r0 != 0);
+}
+
 /*
 | Returns an approximation to the square root of the 32-bit significand given
 | by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6e9d4c172c..2b703c12ed 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -809,6 +809,95 @@ float64 float64_mul(float64 a, float64 b, float_status 
*status)
 return float64_round_pack_canonical(pr, status);
 }
 
+/*
+ * Returns the result of dividing the floating-point value `a' by the
+ * corresponding value `b'. The operation is performed according to
+ * the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+ */
+
+static decomposed_parts div_decomposed(decomposed_parts a, decomposed_parts b,
+   float_status *s)
+{
+bool sign = a.sign ^ b.sign;
+
+if (a.cls == float_class_normal && b.cls == float_class_normal) {
+uint64_t temp_lo, temp_hi;
+int exp = a.exp - b.exp;
+if (a.frac < b.frac) {
+exp -= 1;
+shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1,
+  _hi, _lo);
+} else {
+shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT,
+  _hi, _lo);
+}
+/* LSB of quot is set if inexact which roundandpack will use
+ * to set flags. Yet again we re-use a for the result */
+a.frac = div128To64(temp_lo, temp_hi, b.frac);
+a.sign = sign;
+a.exp = exp;
+return a;
+}
+/* handle all the NaN cases */
+if (a.cls >= float_class_qnan || b.cls >= float_class_qnan) {
+return pick_nan_parts(a, b, s);
+}
+/* 0/0 or Inf/Inf */
+if (a.cls == b.cls
+&&
+(a.cls == float_class_inf || a.cls == float_class_zero)) {
+s->float_exception_flags |= float_flag_invalid;
+a.cls = float_class_dnan;
+return a;
+}
+/* Div 0 => Inf */
+if (b.cls == float_class_zero) {
+s->float_exception_flags |= float_flag_divbyzero;
+a.cls = float_class_inf;
+a.sign = sign;
+return a;
+}
+/* Inf / x or 0 / x */
+if (a.cls == float_class_inf || a.cls == float_class_zero) {
+a.sign = sign;
+return a;
+}
+/* Div by Inf */
+if (b.cls == float_class_inf) {
+a.cls = float_class_zero;
+a.sign = sign;
+return a;
+}
+g_assert_not_reached();
+}
+
+float16 float16_div(float16 a, float16 b, float_status *status)
+{
+decomposed_parts pa = float16_unpack_canonical(a, status);
+decomposed_parts pb = float16_unpack_canonical(b, status);
+decomposed_parts pr = div_decomposed(pa, pb, status);
+
+return float16_round_pack_canonical(pr, status);
+}
+
+float32 float32_div(float32 a, float32 b, float_status *status)
+{
+decomposed_parts pa = float32_unpack_canonical(a, status);
+decomposed_parts pb = float32_unpack_canonical(b, status);
+decomposed_parts pr = div_decomposed(pa, pb, status);
+
+return float32_round_pack_canonical(pr, status);
+}
+
+float64 float64_div(float64 a, float64 b, float_status *status)
+{
+decomposed_parts pa = float64_unpack_canonical(a, status);
+decomposed_parts pb = float64_unpack_canonical(b, status);
+decomposed_parts pr = div_decomposed(pa, pb, status);
+
+return 

[Qemu-devel] [PATCH v4 07/46] windbg: added chardev

2017-12-11 Thread Mihail Abakumov
Added chardev for listening to windbg. Target device is a parameter in the 
'-windbg' option.

Signed-off-by: Mihail Abakumov 
Acked-by: Alistair Francis 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |   30 ++
 1 file changed, 30 insertions(+)

diff --git a/windbgstub.c b/windbgstub.c
index 0863da73fd..e30b8500e0 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -20,12 +20,26 @@
 typedef struct WindbgState {
 bool is_loaded;
 
+CharBackend chr;
+
 uint32_t ctrl_packet_id;
 uint32_t data_packet_id;
 } WindbgState;
 
 static WindbgState *windbg_state;
 
+static int windbg_chr_can_receive(void *opaque)
+{
+return PACKET_MAX_SIZE;
+}
+
+static void windbg_chr_receive(void *opaque, const uint8_t *buf, int size)
+{
+if (windbg_state->is_loaded) {
+/* T0D0: parse data */
+}
+}
+
 static void windbg_exit(void)
 {
 g_free(windbg_state);
@@ -33,15 +47,31 @@ static void windbg_exit(void)
 
 int windbg_server_start(const char *device)
 {
+Chardev *chr = NULL;
+
 if (windbg_state) {
 WINDBG_ERROR("Multiple instances of windbg are not supported.");
 exit(1);
 }
 
+if (!strstart(device, "pipe:", NULL)) {
+WINDBG_ERROR("Unsupported device. Supported only pipe.");
+exit(1);
+}
+
 windbg_state = g_new0(WindbgState, 1);
 windbg_state->ctrl_packet_id = RESET_PACKET_ID;
 windbg_state->data_packet_id = INITIAL_PACKET_ID;
 
+chr = qemu_chr_new_noreplay(WINDBG, device);
+if (!chr) {
+return -1;
+}
+
+qemu_chr_fe_init(_state->chr, chr, _abort);
+qemu_chr_fe_set_handlers(_state->chr, windbg_chr_can_receive,
+ windbg_chr_receive, NULL, NULL, NULL, NULL, true);
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 17/46] windbg: windbg_vm_stop

2017-12-11 Thread Mihail Abakumov
Added function for stop vm. Also, ExceptionStateChange data is generated and 
sent here.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |   13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/windbgstub.c b/windbgstub.c
index b71449e369..6eb9517e24 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -71,7 +71,6 @@ static uint32_t compute_checksum(uint8_t *data, uint16_t len)
 return checksum;
 }
 
-__attribute__ ((unused)) /* unused yet */
 static void windbg_send_data_packet(uint8_t *data, uint16_t byte_count,
 uint16_t type)
 {
@@ -116,6 +115,16 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
+static void windbg_vm_stop(void)
+{
+CPUState *cpu = qemu_get_cpu(0);
+vm_stop(RUN_STATE_PAUSED);
+
+SizedBuf buf = kd_gen_exception_sc(cpu);
+windbg_send_data_packet(buf.data, buf.size, PACKET_TYPE_KD_STATE_CHANGE64);
+g_free(buf.data);
+}
+
 static void windbg_process_data_packet(ParsingContext *ctx)
 {}
 
@@ -129,7 +138,7 @@ static void windbg_ctx_handler(ParsingContext *ctx)
 break;
 
 case RESULT_BREAKIN_BYTE:
-vm_stop(RUN_STATE_PAUSED);
+windbg_vm_stop();
 break;
 
 case RESULT_CONTROL_PACKET:




[Qemu-devel] [PATCH v4 21/46] windbg: implemented kd_api_read_virtual_memory and kd_api_write_virtual_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |   47 +++
 windbgstub.c|8 +++
 3 files changed, 57 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 51977b46c7..1cee2aed18 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -74,6 +74,8 @@ typedef struct PacketData {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd);
+void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 04a7e1cc7b..1e81c37501 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -24,6 +24,53 @@ InitedAddr *windbg_get_version(void)
 return 
 }
 
+void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+target_ulong addr;
+int err;
+
+len = MIN(ldl_p(>TransferCount),
+PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 0);
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+WINDBG_DEBUG("read_virtual_memory: No physical page mapped: " FMT_ADDR,
+ (target_ulong) mem->TargetBaseAddress);
+}
+
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+target_ulong addr;
+int err;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 1);
+
+if (err) {
+len = 0;
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+
+WINDBG_DEBUG("read_write_memory: No physical page mapped: " FMT_ADDR,
+ (target_ulong) mem->TargetBaseAddress);
+}
+
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index a798186930..14caacef81 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -140,6 +140,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 
 switch (ctx->data.m64.ApiNumber) {
 
+case DbgKdReadVirtualMemoryApi:
+kd_api_read_virtual_memory(cpu, >data);
+break;
+
+case DbgKdWriteVirtualMemoryApi:
+kd_api_write_virtual_memory(cpu, >data);
+break;
+
 default:
 kd_api_unsupported(cpu, >data);
 break;




[Qemu-devel] [PATCH v4 34/46] windbg: debug exception subscribing

2017-12-11 Thread Mihail Abakumov
Added handler registration of gdb debug exception. Its exception also can be 
used for windbg.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 cpus.c  |   19 ++-
 gdbstub.c   |4 
 include/sysemu/sysemu.h |2 ++
 windbgstub.c|   16 
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/cpus.c b/cpus.c
index 9bed61eefc..498b7e1dd9 100644
--- a/cpus.c
+++ b/cpus.c
@@ -77,6 +77,8 @@ int64_t max_advance;
 static QEMUTimer *throttle_timer;
 static unsigned int throttle_percentage;
 
+static void (*excp_debug_handler)(CPUState *cpu);
+
 #define CPU_THROTTLE_PCT_MIN 1
 #define CPU_THROTTLE_PCT_MAX 99
 #define CPU_THROTTLE_TIMESLICE_NS 1000
@@ -960,9 +962,24 @@ static bool cpu_can_run(CPUState *cpu)
 return true;
 }
 
+bool register_excp_debug_handler(void (*handler)(CPUState *cpu))
+{
+if (excp_debug_handler == NULL) {
+excp_debug_handler = handler;
+return true;
+} else {
+error_report("Something debugger is already in use. '-gdb' and "
+ "'-windbg' cannot be used at the same time");
+return false;
+}
+}
+
 static void cpu_handle_guest_debug(CPUState *cpu)
 {
-gdb_set_stop_cpu(cpu);
+if (excp_debug_handler != NULL) {
+excp_debug_handler(cpu);
+}
+
 qemu_system_debug_request();
 cpu->stopped = true;
 }
diff --git a/gdbstub.c b/gdbstub.c
index 2a94030d3b..8c76f54117 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2006,6 +2006,10 @@ int gdbserver_start(const char *device)
 s->mon_chr = mon_chr;
 s->current_syscall_cb = NULL;
 
+if (!register_excp_debug_handler(gdb_set_stop_cpu)) {
+exit(1);
+}
+
 return 0;
 }
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index b21369672a..34588c99b4 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -193,6 +193,8 @@ QemuOpts *qemu_get_machine_opts(void);
 
 bool defaults_enabled(void);
 
+bool register_excp_debug_handler(void (*handler)(CPUState *cpu));
+
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
 extern QemuOptsList qemu_drive_opts;
diff --git a/windbgstub.c b/windbgstub.c
index a534fe170b..d3c1317255 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -115,16 +115,20 @@ static void windbg_send_control_packet(uint16_t type)
 windbg_state->ctrl_packet_id ^= 1;
 }
 
-static void windbg_vm_stop(void)
+static void windbg_bp_handler(CPUState *cpu)
 {
-CPUState *cpu = qemu_get_cpu(0);
-vm_stop(RUN_STATE_PAUSED);
-
 SizedBuf buf = kd_gen_exception_sc(cpu);
 windbg_send_data_packet(buf.data, buf.size, PACKET_TYPE_KD_STATE_CHANGE64);
 g_free(buf.data);
 }
 
+static void windbg_vm_stop(void)
+{
+CPUState *cpu = qemu_get_cpu(0);
+vm_stop(RUN_STATE_PAUSED);
+windbg_bp_handler(cpu);
+}
+
 static void windbg_process_manipulate_packet(ParsingContext *ctx)
 {
 CPUState *cpu;
@@ -432,6 +436,10 @@ int windbg_server_start(const char *device)
 
 qemu_register_reset(windbg_handle_reset, NULL);
 
+if (!register_excp_debug_handler(windbg_bp_handler)) {
+exit(1);
+}
+
 atexit(windbg_exit);
 return 0;
 }




[Qemu-devel] [PATCH v4 46/46] windbg: maintainers

2017-12-11 Thread Mihail Abakumov
Added WinDbg stub to the MAINTAINERS.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 MAINTAINERS |   12 
 1 file changed, 12 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ccee28b12d..8ee2c780e3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1300,6 +1300,18 @@ S: Odd Fixes
 F: gdbstub*
 F: gdb-xml/
 
+WinDbg stub
+M: Mihail Abakumov 
+R: Pavel Dovgalyuk 
+S: Supported
+F: include/exec/windbgstub.h
+F: include/exec/windbgstub-utils.h
+F: include/exec/windbgkd.h
+F: windbgstub.c
+F: windbgstub-utils.c
+F: stubs/windbgstub.c
+F: target/i386/windbgstub.c
+
 Memory API
 M: Paolo Bonzini 
 S: Supported




[Qemu-devel] [PATCH v1 for-2-12 03/15] s390x/tcg: deliver multiple interrupts in a row

2017-12-11 Thread David Hildenbrand
We have to consider all deliverable interrupts.

We now have to take care of the special scenario, where we first
inject an interrupt with a WAIT PSW, followed by a !WAIT PSW. (very
unlikely but possible)

Signed-off-by: David Hildenbrand 
---
 target/s390x/excp_helper.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
index f4697a884d..d024ac5fef 100644
--- a/target/s390x/excp_helper.c
+++ b/target/s390x/excp_helper.c
@@ -433,10 +433,12 @@ void s390_cpu_do_interrupt(CPUState *cs)
 {
 S390CPU *cpu = S390_CPU(cs);
 CPUS390XState *env = >env;
+bool stopped = false;
 
 qemu_log_mask(CPU_LOG_INT, "%s: %d at pc=%" PRIx64 "\n",
   __func__, cs->exception_index, env->psw.addr);
 
+try_deliver:
 /* handle machine checks */
 if (cs->exception_index == -1 && s390_cpu_has_mcck_int(cpu)) {
 cs->exception_index = EXCP_MCHK;
@@ -479,13 +481,14 @@ void s390_cpu_do_interrupt(CPUState *cs)
 break;
 case EXCP_STOP:
 do_stop_interrupt(env);
+stopped = true;
 break;
 }
 
-/* WAIT PSW during interrupt injection or STOP interrupt */
-if (cs->exception_index == EXCP_HLT) {
-/* don't trigger a cpu_loop_exit(), use an interrupt instead */
-cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT);
+if (cs->exception_index != -1 && !stopped) {
+/* check if there are more pending interrupts to deliver */
+cs->exception_index = -1;
+goto try_deliver;
 }
 cs->exception_index = -1;
 
@@ -493,6 +496,15 @@ void s390_cpu_do_interrupt(CPUState *cs)
 if (!env->pending_int) {
 cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
 }
+
+/* WAIT PSW during interrupt injection or STOP interrupt */
+if ((env->psw.mask & PSW_MASK_WAIT) || stopped) {
+/* don't trigger a cpu_loop_exit(), use an interrupt instead */
+cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HALT);
+} else if (cs->halted) {
+/* unhalt if we had a WAIT PSW somehwere in our injection chain */
+s390_cpu_unhalt(cpu);
+}
 }
 
 bool s390_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-- 
2.14.3




Re: [Qemu-devel] [RFC PATCH 0/5] Scoped locks using attribute((cleanup))

2017-12-11 Thread Eric Blake
On 12/11/2017 03:38 AM, Peter Maydell wrote:
> On 8 December 2017 at 19:40, Eric Blake  wrote:
>> On 12/08/2017 04:55 AM, Paolo Bonzini wrote:
>>> Likewise,
>>>
>>> QEMU_WITH_LOCK(QemuMutex, guard_name, _mutex) {
>>> ...
>>> }
>>>
>>> is the same as
>>>
>>> qemu_mutex_lock(_mutex);
>>> ...
>>> qemu_mutex_unlock(_mutex);
>>>
>>> except that any returns within the region will unlock the mutex.
>>
>> Not just returns, but ANY manner that you leave the scope, including a
>> goto or just falling out of the end of the scope.
> 
> How about longjmp()ing out of it?

Easy to test:

==
#include 
#include 
#include 

void my_cleanup (int *ptr) {
  int *i = ptr;
  printf("in my_cleanup(%d)\n", *i);
}

jmp_buf jmp;

void foo(int i) {
  while (1) {
__attribute__((cleanup(my_cleanup))) int j = i;
if (i == 0) {
  printf("before leaving scope by return\n");
  return;
}
if (i == 1) {
  goto label;
}
if (i == 3) {
  longjmp(jmp, 1);
}
if (i == 4) {
  printf("before leaving scope by exit\n");
  exit(0);
}
break;
  }
  printf("after leaving scope by break\n");
  return;
 label:
  printf("after leaving scope by return\n");
}

int main(void) {
  foo(0);
  foo(1);
  foo(2);
  if (!setjmp(jmp)) {
foo(3);
  }
  printf("after leaving scope by longjmp\n");
  foo(4);
}


But the results aren't necessarily nice, depending on how we currently
(ab)use longjmp. Under Fedora 27
gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2)

I get

$ ./foo
before leaving scope by return
in my_cleanup(0)
in my_cleanup(1)
after leaving scope by return
in my_cleanup(2)
after leaving scope by break
after leaving scope by longjmp
before leaving scope by exit

I don't know if there is a way to make gcc insert stack-unwind
directives that are honored across longjmp (I know C++ does it for
exceptions; so there may be a way, and I just don't know it).
Conversely, I do know that pthread_cleanup_push/pop, which does
something similar, is permitted by POSIX to NOT work across longjmp:

   Calling longjmp(3) (siglongjmp(3)) produces undefined  results
if  any
   call  has  been made to pthread_cleanup_push() or
pthread_cleanup_pop()
   without the matching call of the pair since the jump buffer was
filled
   by   setjmp(3)  (sigsetjmp(3)).   Likewise,  calling  longjmp(3)
(sig‐
   longjmp(3)) from inside a clean-up handler produces  undefined
results
   unless  the  jump  buffer  was  also filled by setjmp(3)
(sigsetjmp(3))
   inside the handler.


-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v1 for-2-12 15/15] configure: s390x supports mttcg now

2017-12-11 Thread David Hildenbrand
s390x is ready. Most likely we are missing some pieces, but it should
already be in pretty good shape now.

Signed-off-by: David Hildenbrand 
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 0c6e7572db..1e593b6fab 100755
--- a/configure
+++ b/configure
@@ -6508,6 +6508,7 @@ case "$target_name" in
 echo "TARGET_ABI32=y" >> $config_target_mak
   ;;
   s390x)
+mttcg=yes
 gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml s390-vx.xml 
s390-cr.xml s390-virt.xml s390-gs.xml"
   ;;
   tilegx)
-- 
2.14.3




Re: [Qemu-devel] [qemu-s390x] [PATCH v3 1/1] s390-ccw-virtio: allow for systems larger that 7.999TB

2017-12-11 Thread Christian Borntraeger


On 12/11/2017 02:55 PM, David Hildenbrand wrote:
> On 11.12.2017 13:21, Christian Borntraeger wrote:
>> KVM does not allow memory regions > KVM_MEM_MAX_NR_PAGES, basically
>> limiting the memory per slot to 8TB-4k. As memory slots on s390/kvm must
>> be a multiple of 1MB we need start a new memory region if we cross
>> 8TB-1M.
>>
>> With that (and optimistic overcommitment in the kernel) I was able to
>> start a 24TB guest on a 1TB system.
>>
>> Signed-off-by: Christian Borntraeger 
>> ---
>>  hw/s390x/s390-virtio-ccw.c | 28 +---
>>  1 file changed, 25 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
>> index 8425534..073f6ed 100644
>> --- a/hw/s390x/s390-virtio-ccw.c
>> +++ b/hw/s390x/s390-virtio-ccw.c
>> @@ -154,14 +154,36 @@ static void virtio_ccw_register_hcalls(void)
>> virtio_ccw_hcall_early_printk);
>>  }
>>  
>> +/*
>> + * KVM does only support memory slots up to KVM_MEM_MAX_NR_PAGES pages
>> + * as the dirty bitmap must be managed by bitops that take an int as
>> + * position indicator. If we have a guest beyond that we will split off
>> + * new subregions. The split must happen on a segment boundary (1MB).
>> + */
>> +#define KVM_MEM_MAX_NR_PAGES ((1UL << 31) - 1)
>> +#define SEG_MSK (~0xfULL)
>> +#define KVM_SLOT_MAX_BYTES ((KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE) & 
>> SEG_MSK)
> 
> Just wondering if we could get into trouble when calculating
> 
> KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE

maybe just using 1ULL instead of 1UL?


> 
> on a host with sizeof(long) == 4
> 
> could it wrap? (e.g. crazy mingw stuff)
> 
>>  static void s390_memory_init(ram_addr_t mem_size)
>>  {
>>  MemoryRegion *sysmem = get_system_memory();
>> -MemoryRegion *ram = g_new(MemoryRegion, 1);
>> +ram_addr_t chunk, offset = 0;
>> +unsigned int number = 0;
>> +gchar *name;
>>  
>>  /* allocate RAM for core */
>> -memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
>> -memory_region_add_subregion(sysmem, 0, ram);
>> +name = g_strdup_printf("s390.ram");
>> +while (mem_size) {
>> +MemoryRegion *ram = g_new(MemoryRegion, 1);
> 
> I'd add an empty line here.
> 
> Reviewed-by: David Hildenbrand 
> 
>> +/* KVM does not allow memslots >= 8 TB */
>> +chunk = MIN(mem_size, KVM_SLOT_MAX_BYTES);
>> +memory_region_allocate_system_memory(ram, NULL, name, chunk);
>> +memory_region_add_subregion(sysmem, offset, ram);
>> +mem_size -= chunk;
>> +offset += chunk;
>> +g_free(name);
>> +name = g_strdup_printf("s390.ram.%u", ++number);
>> +}
>> +g_free(name);
>>  
>>  /* Initialize storage key device */
>>  s390_skeys_init();
>>
> 
> 




[Qemu-devel] [PATCH v1 06/19] fpu/softfloat: propagate signalling NaNs in MINMAX

2017-12-11 Thread Alex Bennée
While a comparison between a QNaN and a number will return the number
it is not the same with a signaling NaN. In this case the SNaN will
"win" and after potentially raising an exception it will be quietened.

Signed-off-by: Alex Bennée 

---
v2
  - added return for propageFloat
---
 fpu/softfloat.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 3a4ab1355f..44c043924e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -7683,6 +7683,7 @@ int float128_compare_quiet(float128 a, float128 b, 
float_status *status)
  * minnum() and maxnum() functions. These are similar to the min()
  * and max() functions but if one of the arguments is a QNaN and
  * the other is numerical then the numerical argument is returned.
+ * SNaNs will get quietened before being returned.
  * minnum() and maxnum correspond to the IEEE 754-2008 minNum()
  * and maxNum() operations. min() and max() are the typical min/max
  * semantics provided by many CPUs which predate that specification.
@@ -7703,11 +7704,14 @@ static inline float ## s float ## s ## _minmax(float ## 
s a, float ## s b, \
 if (float ## s ## _is_any_nan(a) || \
 float ## s ## _is_any_nan(b)) { \
 if (isieee) {   \
-if (float ## s ## _is_quiet_nan(a, status) &&   \
+if (float ## s ## _is_signaling_nan(a, status) ||   \
+float ## s ## _is_signaling_nan(b, status)) {   \
+return propagateFloat ## s ## NaN(a, b, status);\
+} else  if (float ## s ## _is_quiet_nan(a, status) &&   \
 !float ## s ##_is_any_nan(b)) { \
 return b;   \
 } else if (float ## s ## _is_quiet_nan(b, status) &&\
-   !float ## s ## _is_any_nan(a)) {\
+   !float ## s ## _is_any_nan(a)) { \
 return a;   \
 }   \
 }   \
-- 
2.15.1




[Qemu-devel] [PATCH v1 17/19] fpu/softfloat: re-factor scalbn

2017-12-11 Thread Alex Bennée
This is one of the simpler manipulations you could make to a floating
point number.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 104 +++-
 include/fpu/softfloat.h |   1 +
 2 files changed, 32 insertions(+), 73 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 1a7f1cab10..b7ea56dfa5 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1662,6 +1662,37 @@ float64 uint16_to_float64(uint16_t a, float_status 
*status)
 return uint64_to_float64((uint64_t) a, status);
 }
 
+/* Multiply A by 2 raised to the power N.  */
+static decomposed_parts scalbn_decomposed(decomposed_parts a, int n,
+  float_status *s)
+{
+if (a.cls == float_class_normal) {
+a.exp += n;
+}
+return a;
+}
+
+float16 float16_scalbn(float16 a, int n, float_status *status)
+{
+decomposed_parts pa = float16_unpack_canonical(a, status);
+decomposed_parts pr = scalbn_decomposed(pa, n, status);
+return float16_round_pack_canonical(pr, status);
+}
+
+float32 float32_scalbn(float32 a, int n, float_status *status)
+{
+decomposed_parts pa = float32_unpack_canonical(a, status);
+decomposed_parts pr = scalbn_decomposed(pa, n, status);
+return float32_round_pack_canonical(pr, status);
+}
+
+float64 float64_scalbn(float64 a, int n, float_status *status)
+{
+decomposed_parts pa = float64_unpack_canonical(a, status);
+decomposed_parts pr = scalbn_decomposed(pa, n, status);
+return float64_round_pack_canonical(pr, status);
+}
+
 /*
 | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
 | and 7, and returns the properly rounded 32-bit integer corresponding to the
@@ -6991,79 +7022,6 @@ MINMAX(32)
 MINMAX(64)
 
 
-/* Multiply A by 2 raised to the power N.  */
-float32 float32_scalbn(float32 a, int n, float_status *status)
-{
-flag aSign;
-int16_t aExp;
-uint32_t aSig;
-
-a = float32_squash_input_denormal(a, status);
-aSig = extractFloat32Frac( a );
-aExp = extractFloat32Exp( a );
-aSign = extractFloat32Sign( a );
-
-if ( aExp == 0xFF ) {
-if ( aSig ) {
-return propagateFloat32NaN(a, a, status);
-}
-return a;
-}
-if (aExp != 0) {
-aSig |= 0x0080;
-} else if (aSig == 0) {
-return a;
-} else {
-aExp++;
-}
-
-if (n > 0x200) {
-n = 0x200;
-} else if (n < -0x200) {
-n = -0x200;
-}
-
-aExp += n - 1;
-aSig <<= 7;
-return normalizeRoundAndPackFloat32(aSign, aExp, aSig, status);
-}
-
-float64 float64_scalbn(float64 a, int n, float_status *status)
-{
-flag aSign;
-int16_t aExp;
-uint64_t aSig;
-
-a = float64_squash_input_denormal(a, status);
-aSig = extractFloat64Frac( a );
-aExp = extractFloat64Exp( a );
-aSign = extractFloat64Sign( a );
-
-if ( aExp == 0x7FF ) {
-if ( aSig ) {
-return propagateFloat64NaN(a, a, status);
-}
-return a;
-}
-if (aExp != 0) {
-aSig |= LIT64( 0x0010 );
-} else if (aSig == 0) {
-return a;
-} else {
-aExp++;
-}
-
-if (n > 0x1000) {
-n = 0x1000;
-} else if (n < -0x1000) {
-n = -0x1000;
-}
-
-aExp += n - 1;
-aSig <<= 10;
-return normalizeRoundAndPackFloat64(aSign, aExp, aSig, status);
-}
-
 floatx80 floatx80_scalbn(floatx80 a, int n, float_status *status)
 {
 flag aSign;
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 8ebde83251..c1224aab8c 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -353,6 +353,7 @@ float16 float16_sub(float16, float16, float_status *status);
 float16 float16_mul(float16, float16, float_status *status);
 float16 float16_muladd(float16, float16, float16, int, float_status *status);
 float16 float16_div(float16, float16, float_status *status);
+float16 float16_scalbn(float16, int, float_status *status);
 
 int float16_is_quiet_nan(float16, float_status *status);
 int float16_is_signaling_nan(float16, float_status *status);
-- 
2.15.1




[Qemu-devel] [PATCH v1 16/19] fpu/softfloat: re-factor int/uint to float

2017-12-11 Thread Alex Bennée
These are considerably simpler as the lower order integers can just
use the higher order conversion function. As the decomposed fractional
part is a full 64 bit rounding and inexact handling comes from the
pack functions.

Signed-off-by: Alex Bennée 
---
 fpu/softfloat.c | 358 +---
 include/fpu/softfloat.h |  30 ++--
 2 files changed, 195 insertions(+), 193 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index d7858bdae5..1a7f1cab10 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1409,17 +1409,18 @@ FLOAT_TO_INT(64, 64)
 
 #undef FLOAT_TO_INT
 
-/*
-| Returns the result of converting the  floating-point value
-| `a' to the unsigned integer format.  The conversion is
-| performed according to the IEC/IEEE Standard for Binary Floating-Point
-| Arithmetic---which means in particular that the conversion is rounded
-| according to the current rounding mode.  If `a' is a NaN, the largest
-| unsigned integer is returned.  Otherwise, if the conversion overflows, the
-| largest unsigned integer is returned.  If the 'a' is negative, the result
-| is rounded and zero is returned; values that do not round to zero will
-| raise the inexact exception flag.
-**/
+/*
+ *  Returns the result of converting the floating-point value `a' to
+ *  the unsigned integer format. The conversion is performed according
+ *  to the IEC/IEEE Standard for Binary Floating-Point
+ *  Arithmetic---which means in particular that the conversion is
+ *  rounded according to the current rounding mode. If `a' is a NaN,
+ *  the largest unsigned integer is returned. Otherwise, if the
+ *  conversion overflows, the largest unsigned integer is returned. If
+ *  the 'a' is negative, the result is rounded and zero is returned;
+ *  values that do not round to zero will raise the inexact exception
+ *  flag.
+ */
 
 static uint64_t uint64_pack_decomposed(decomposed_parts p, float_status *s)
 {
@@ -1433,6 +1434,7 @@ static uint64_t uint64_pack_decomposed(decomposed_parts 
p, float_status *s)
 return 0;
 case float_class_normal:
 if (p.sign) {
+s->float_exception_flags |= float_flag_invalid;
 return 0;
 }
 if (p.exp < DECOMPOSED_BINARY_POINT) {
@@ -1440,6 +1442,7 @@ static uint64_t uint64_pack_decomposed(decomposed_parts 
p, float_status *s)
 } else if (p.exp < 64) {
 return p.frac << (p.exp - DECOMPOSED_BINARY_POINT);
 } else {
+s->float_exception_flags |= float_flag_invalid;
 return UINT64_MAX;
 }
 default:
@@ -1450,13 +1453,21 @@ static uint64_t uint64_pack_decomposed(decomposed_parts 
p, float_status *s)
 static uint16_t uint16_pack_decomposed(decomposed_parts p, float_status *s)
 {
 uint64_t r = uint64_pack_decomposed(p, s);
-return r > UINT16_MAX ? UINT16_MAX : r;
+if (r > UINT16_MAX) {
+s->float_exception_flags |= float_flag_invalid;
+r = UINT16_MAX;
+}
+return r;
 }
 
 static uint32_t uint32_pack_decomposed(decomposed_parts p, float_status *s)
 {
 uint64_t r = uint64_pack_decomposed(p, s);
-return r > UINT32_MAX ? UINT32_MAX : r;
+if (r > UINT32_MAX) {
+s->float_exception_flags |= float_flag_invalid;
+r = UINT32_MAX;
+}
+return r;
 }
 
 #define FLOAT_TO_UINT(fsz, isz) \
@@ -1489,6 +1500,168 @@ FLOAT_TO_UINT(64, 64)
 
 #undef FLOAT_TO_UINT
 
+/*
+ * Integer to float conversions
+ *
+ * Returns the result of converting the two's complement integer `a'
+ * to the floating-point format. The conversion is performed according
+ * to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+ */
+
+static decomposed_parts int_to_float(int64_t a, float_status *status)
+{
+decomposed_parts r;
+if (a == 0) {
+r.cls = float_class_zero;
+} else if (a == (1ULL << 63)) {
+r.cls = float_class_normal;
+r.sign = true;
+r.frac = DECOMPOSED_IMPLICIT_BIT;
+r.exp = 63;
+} else {
+uint64_t f;
+if (a < 0) {
+f = -a;
+r.sign = true;
+} else {
+f = a;
+r.sign = false;
+}
+int shift = clz64(f) - 1;
+r.cls = float_class_normal;
+r.exp = (DECOMPOSED_BINARY_POINT - shift);
+r.frac = f << shift;
+}
+
+return r;
+}
+
+float16 int64_to_float16(int64_t a, float_status *status)
+{
+decomposed_parts pa = int_to_float(a, status);
+return float16_round_pack_canonical(pa, status);
+}
+
+float16 int32_to_float16(int32_t a, float_status *status)
+{
+return int64_to_float16((int64_t) a, status);
+}
+
+float16 int16_to_float16(int16_t a, float_status *status)
+{
+return int64_to_float16((int64_t) a, status);
+}
+
+float32 int64_to_float32(int64_t a, 

[Qemu-devel] [PATCH v4 11/46] windbg: parsing data stream

2017-12-11 Thread Mihail Abakumov
Added function of parsing data stream from windbg to packet.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 windbgstub.c |  111 +-
 1 file changed, 110 insertions(+), 1 deletion(-)

diff --git a/windbgstub.c b/windbgstub.c
index 395f244d4f..ace992e2cb 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -60,6 +60,105 @@ typedef struct WindbgState {
 
 static WindbgState *windbg_state;
 
+static void windbg_ctx_handler(ParsingContext *ctx)
+{}
+
+static void windbg_read_byte(ParsingContext *ctx, uint8_t byte)
+{
+switch (ctx->state) {
+case STATE_LEADER:
+ctx->result = RESULT_NONE;
+if (byte == PACKET_LEADER_BYTE || byte == CONTROL_PACKET_LEADER_BYTE) {
+if (ctx->index > 0 && byte != PTR(ctx->packet.PacketLeader)[0]) {
+ctx->index = 0;
+}
+PTR(ctx->packet.PacketLeader)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketLeader)) {
+ctx->state = STATE_PACKET_TYPE;
+ctx->index = 0;
+}
+} else if (byte == BREAKIN_PACKET_BYTE) {
+ctx->result = RESULT_BREAKIN_BYTE;
+ctx->index = 0;
+} else {
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_TYPE:
+PTR(ctx->packet.PacketType)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketType)) {
+ctx->packet.PacketType = lduw_p(>packet.PacketType);
+if (ctx->packet.PacketType >= PACKET_TYPE_MAX) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_UNKNOWN_PACKET;
+} else {
+ctx->state = STATE_PACKET_BYTE_COUNT;
+}
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_BYTE_COUNT:
+PTR(ctx->packet.ByteCount)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.ByteCount)) {
+ctx->packet.ByteCount = lduw_p(>packet.ByteCount);
+ctx->state = STATE_PACKET_ID;
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_ID:
+PTR(ctx->packet.PacketId)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.PacketId)) {
+ctx->packet.PacketId = ldl_p(>packet.PacketId);
+ctx->state = STATE_PACKET_CHECKSUM;
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_CHECKSUM:
+PTR(ctx->packet.Checksum)[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == sizeof(ctx->packet.Checksum)) {
+ctx->packet.Checksum = ldl_p(>packet.Checksum);
+if (ctx->packet.PacketLeader == CONTROL_PACKET_LEADER) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_CONTROL_PACKET;
+} else if (ctx->packet.ByteCount > PACKET_MAX_SIZE) {
+ctx->state = STATE_LEADER;
+ctx->result = RESULT_ERROR;
+} else {
+ctx->state = STATE_PACKET_DATA;
+}
+ctx->index = 0;
+}
+break;
+
+case STATE_PACKET_DATA:
+ctx->data.buf[ctx->index] = byte;
+++ctx->index;
+if (ctx->index == ctx->packet.ByteCount) {
+ctx->state = STATE_TRAILING_BYTE;
+ctx->index = 0;
+}
+break;
+
+case STATE_TRAILING_BYTE:
+if (byte == PACKET_TRAILING_BYTE) {
+ctx->result = RESULT_DATA_PACKET;
+} else {
+ctx->result = RESULT_ERROR;
+}
+ctx->state = STATE_LEADER;
+break;
+}
+}
+
 static int windbg_chr_can_receive(void *opaque)
 {
 return PACKET_MAX_SIZE;
@@ -67,8 +166,18 @@ static int windbg_chr_can_receive(void *opaque)
 
 static void windbg_chr_receive(void *opaque, const uint8_t *buf, int size)
 {
+static ParsingContext ctx = {
+.state = STATE_LEADER,
+.result = RESULT_NONE,
+.name = ""
+};
+
 if (windbg_state->is_loaded) {
-/* T0D0: parse data */
+int i;
+for (i = 0; i < size; i++) {
+windbg_read_byte(, buf[i]);
+windbg_ctx_handler();
+}
 }
 }
 




[Qemu-devel] [PATCH v4 08/46] windbg: hook to wrmsr operation

2017-12-11 Thread Mihail Abakumov
Inserted hook to wrmsr operation. Windows Kernel put address on KPCR struct to 
fs/gs (x32/x64) register. Needs catch this moment and allow windbg server 
handle packets.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 ++
 include/exec/windbgstub.h   |1 +
 stubs/windbgstub.c  |3 +++
 target/i386/misc_helper.c   |3 +++
 target/i386/windbgstub.c|   10 ++
 windbgstub.c|   13 +
 6 files changed, 32 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 4c747fa23e..a181e172e9 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -47,4 +47,6 @@ typedef struct SizedBuf {
 size_t size;
 } SizedBuf;
 
+bool windbg_on_load(void);
+
 #endif
diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
index 21bc552e58..309f692383 100755
--- a/include/exec/windbgstub.h
+++ b/include/exec/windbgstub.h
@@ -18,6 +18,7 @@
 #define WINDBG_DEBUG_ON false
 #endif
 
+void windbg_try_load(void);
 int windbg_server_start(const char *device);
 
 #endif
diff --git a/stubs/windbgstub.c b/stubs/windbgstub.c
index 4951f59203..bd7e2dccd1 100755
--- a/stubs/windbgstub.c
+++ b/stubs/windbgstub.c
@@ -12,6 +12,9 @@
 #include "qemu/osdep.h"
 #include "exec/windbgstub.h"
 
+void windbg_try_load(void)
+{}
+
 int windbg_server_start(const char *device)
 {
 return 0;
diff --git a/target/i386/misc_helper.c b/target/i386/misc_helper.c
index 628f64aad5..ec1fcd2899 100644
--- a/target/i386/misc_helper.c
+++ b/target/i386/misc_helper.c
@@ -24,6 +24,7 @@
 #include "exec/exec-all.h"
 #include "exec/cpu_ldst.h"
 #include "exec/address-spaces.h"
+#include "exec/windbgstub.h"
 
 void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
 {
@@ -385,6 +386,8 @@ void helper_wrmsr(CPUX86State *env)
 /* XXX: exception? */
 break;
 }
+
+windbg_try_load();
 }
 
 void helper_rdmsr(CPUX86State *env)
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index df89e1edd8..0938f738e6 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -10,3 +10,13 @@
  */
 
 #include "qemu/osdep.h"
+
+#ifndef TARGET_X86_64
+#include "exec/windbgstub-utils.h"
+
+bool windbg_on_load(void)
+{
+return false;
+}
+
+#endif
diff --git a/windbgstub.c b/windbgstub.c
index e30b8500e0..a2a6eb81b4 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -16,6 +16,7 @@
 #include "qemu/cutils.h"
 #include "exec/windbgstub.h"
 #include "exec/windbgstub-utils.h"
+#include "sysemu/kvm.h"
 
 typedef struct WindbgState {
 bool is_loaded;
@@ -45,6 +46,13 @@ static void windbg_exit(void)
 g_free(windbg_state);
 }
 
+void windbg_try_load(void)
+{
+if (windbg_state && !windbg_state->is_loaded) {
+windbg_state->is_loaded = windbg_on_load();
+}
+}
+
 int windbg_server_start(const char *device)
 {
 Chardev *chr = NULL;
@@ -54,6 +62,11 @@ int windbg_server_start(const char *device)
 exit(1);
 }
 
+if (kvm_enabled()) {
+WINDBG_ERROR("KVM is not supported.");
+exit(1);
+}
+
 if (!strstart(device, "pipe:", NULL)) {
 WINDBG_ERROR("Unsupported device. Supported only pipe.");
 exit(1);




[Qemu-devel] [PATCH v4 16/46] windbg: generate LoadSymbolsStateChange

2017-12-11 Thread Mihail Abakumov
Added function for generate LoadSymbolsStateChange packet.

Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |1 +
 target/i386/windbgstub.c|   16 
 2 files changed, 17 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index d9dae4e902..a7ec53555b 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -75,6 +75,7 @@ InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
+SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
 
 bool windbg_on_load(void);
 
diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 5db6a5e3bc..28d4f5bb10 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -134,4 +134,20 @@ SizedBuf kd_gen_exception_sc(CPUState *cpu)
 return buf;
 }
 
+SizedBuf kd_gen_load_symbols_sc(CPUState *cpu)
+{
+DBGKD_ANY_WAIT_STATE_CHANGE *sc;
+SizedBuf buf;
+
+buf.size = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
+buf.data = g_malloc0(buf.size);
+sc = (DBGKD_ANY_WAIT_STATE_CHANGE *) buf.data;
+kd_init_state_change(cpu, sc);
+
+stl_p(>NewState, DbgKdLoadSymbolsStateChange);
+stl_p(>u.LoadSymbols.PathNameLength, 0);
+
+return buf;
+}
+
 #endif




[Qemu-devel] [PATCH v4 25/46] windbg: implemented windbg_read_context

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |   96 ++
 1 file changed, 96 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index f72d164bb5..de3ffd78b0 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -276,6 +276,102 @@ typedef struct _CPU_KPROCESSOR_STATE {
 static int windbg_read_context(CPUState *cpu, uint8_t *buf, int buf_size,
int offset, int len)
 {
+CPUArchState *env = cpu->env_ptr;
+CPU_CONTEXT *cc;
+bool new_mem;
+
+if (len < 0 || len > buf_size) {
+WINDBG_ERROR("windbg_read_context: incorrect length %d", len);
+return 1;
+}
+
+if (offset < 0 || offset + len > sizeof(CPU_CONTEXT)) {
+WINDBG_ERROR("windbg_read_context: incorrect offset %d", offset);
+return 2;
+}
+
+new_mem = len != sizeof(CPU_CONTEXT) || offset != 0;
+if (new_mem) {
+cc = g_new0(CPU_CONTEXT, 1);
+} else {
+cc = (CPU_CONTEXT *) buf;
+memset(cc, 0, sizeof(CPU_CONTEXT));
+}
+
+cc->ContextFlags = CPU_CONTEXT_ALL;
+
+if (cc->ContextFlags & CPU_CONTEXT_SEGMENTS) {
+stw_p(>SegCs, env->segs[R_CS].selector);
+stw_p(>SegDs, env->segs[R_DS].selector);
+stw_p(>SegEs, env->segs[R_ES].selector);
+stw_p(>SegFs, env->segs[R_FS].selector);
+stw_p(>SegGs, env->segs[R_GS].selector);
+stw_p(>SegSs, env->segs[R_SS].selector);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_DEBUG_REGISTERS) {
+sttul_p(>Dr0, env->dr[0]);
+sttul_p(>Dr1, env->dr[1]);
+sttul_p(>Dr2, env->dr[2]);
+sttul_p(>Dr3, env->dr[3]);
+sttul_p(>Dr6, env->dr[6]);
+sttul_p(>Dr7, env->dr[7]);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_INTEGER) {
+stl_p(>Edi, env->regs[R_EDI]);
+stl_p(>Esi, env->regs[R_ESI]);
+stl_p(>Ebx, env->regs[R_EBX]);
+stl_p(>Edx, env->regs[R_EDX]);
+stl_p(>Ecx, env->regs[R_ECX]);
+stl_p(>Eax, env->regs[R_EAX]);
+stl_p(>Ebp, env->regs[R_EBP]);
+stl_p(>Esp, env->regs[R_ESP]);
+stl_p(>Eip, env->eip);
+stl_p(>EFlags, env->eflags);
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_FLOATING_POINT) {
+uint32_t swd = 0, twd = 0;
+swd = env->fpus & ~(7 << 11);
+swd |= (env->fpstt & 7) << 11;
+int i;
+for (i = 0; i < 8; ++i) {
+twd |= (!env->fptags[i]) << i;
+}
+
+stl_p(>FloatSave.ControlWord, env->fpuc);
+stl_p(>FloatSave.StatusWord, swd);
+stl_p(>FloatSave.TagWord, twd);
+stl_p(>FloatSave.ErrorOffset, env->fpip & 0x);
+stl_p(>FloatSave.ErrorSelector, (env->fpip >> 32) & 0x);
+stl_p(>FloatSave.DataOffset, env->fpdp & 0x);
+stl_p(>FloatSave.DataSelector, (env->fpdp >> 32) & 0x);
+stl_p(>FloatSave.Cr0NpxState, env->xcr0);
+
+for (i = 0; i < 8; ++i) {
+memcpy(PTR(cc->FloatSave.RegisterArea[i * 10]),
+   PTR(env->fpregs[i]), 10);
+}
+}
+
+if (cc->ContextFlags & CPU_CONTEXT_EXTENDED_REGISTERS) {
+uint8_t *ptr = cc->ExtendedRegisters + 160;
+int i;
+for (i = 0; i < 8; ++i, ptr += 16) {
+stq_p(ptr, env->xmm_regs[i].ZMM_Q(0));
+stq_p(ptr + 8, env->xmm_regs[i].ZMM_Q(1));
+}
+
+stl_p(cc->ExtendedRegisters + 24, env->mxcsr);
+}
+
+stl_p(>ContextFlags, cc->ContextFlags);
+
+if (new_mem) {
+memcpy(buf, (uint8_t *) cc + offset, len);
+g_free(cc);
+}
 return 0;
 }
 




[Qemu-devel] [PATCH v4 20/46] windbg: implemented windbg_process_manipulate_packet

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |8 
 windbgstub.c|   26 +-
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index a7ec53555b..51977b46c7 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -74,6 +74,8 @@ typedef struct PacketData {
 InitedAddr *windbg_get_KPCR(void);
 InitedAddr *windbg_get_version(void);
 
+void kd_api_unsupported(CPUState *cpu, PacketData *pd);
+
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
 SizedBuf kd_gen_load_symbols_sc(CPUState *cpu);
 
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 347c61553a..04a7e1cc7b 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -23,3 +23,11 @@ InitedAddr *windbg_get_version(void)
 {
 return 
 }
+
+void kd_api_unsupported(CPUState *cpu, PacketData *pd)
+{
+WINDBG_ERROR("Caught unimplemented api %s",
+ KD_API_NAME(pd->m64.ApiNumber));
+pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
+pd->extra_size = 0;
+}
diff --git a/windbgstub.c b/windbgstub.c
index cd46649278..a798186930 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -126,7 +126,31 @@ static void windbg_vm_stop(void)
 }
 
 static void windbg_process_manipulate_packet(ParsingContext *ctx)
-{}
+{
+CPUState *cpu;
+
+ctx->data.extra_size = ctx->packet.ByteCount -
+   sizeof(DBGKD_MANIPULATE_STATE64);
+ctx->data.m64.ReturnStatus = STATUS_SUCCESS;
+
+cpu = qemu_get_cpu(ctx->data.m64.Processor);
+if (cpu == NULL) {
+cpu = qemu_get_cpu(0);
+}
+
+switch (ctx->data.m64.ApiNumber) {
+
+default:
+kd_api_unsupported(cpu, >data);
+break;
+}
+
+stl_p(>data.m64.ReturnStatus, ctx->data.m64.ReturnStatus);
+
+windbg_send_data_packet(ctx->data.buf, ctx->data.extra_size +
+sizeof(DBGKD_MANIPULATE_STATE64),
+ctx->packet.PacketType);
+}
 
 static void windbg_process_data_packet(ParsingContext *ctx)
 {




[Qemu-devel] [PATCH v4 32/46] windbg: implemented windbg_hw_breakpoint_insert and windbg_hw_breakpoint_remove

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 target/i386/windbgstub.c |   56 ++
 1 file changed, 56 insertions(+)

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index 6e167a7473..5e094e81d7 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -290,11 +290,67 @@ typedef struct _CPU_KPROCESSOR_STATE {
 
 static int windbg_hw_breakpoint_insert(CPUState *cpu, int index)
 {
+CPUArchState *env = cpu->env_ptr;
+
+target_ulong addr = env->dr[index];
+int type = BP_TYPE(env->dr[7], index);
+int len = BP_LEN(env->dr[7], index);
+int err = 0;
+
+switch (type) {
+case DR7_TYPE_DATA_WR:
+err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_WRITE | BP_GDB,
+>cpu_watchpoint[index]);
+break;
+case DR7_TYPE_DATA_RW:
+err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_ACCESS | BP_GDB,
+>cpu_watchpoint[index]);
+break;
+case DR7_TYPE_BP_INST:
+err = cpu_breakpoint_insert(cpu, addr, BP_GDB,
+>cpu_breakpoint[index]);
+break;
+case DR7_TYPE_IO_RW:
+return HF_IOBPT_MASK;
+default:
+return 0;
+}
+
+if (!err) {
+WINDBG_DEBUG("hw_breakpoint_insert: index(%d), " FMT_ADDR,
+ index, addr);
+} else {
+env->cpu_breakpoint[index] = NULL;
+WINDBG_ERROR("hw_breakpoint_insert: index(%d), " FMT_ADDR ", " FMT_ERR,
+ index, addr, err);
+}
 return 0;
 }
 
 static int windbg_hw_breakpoint_remove(CPUState *cpu, int index)
 {
+CPUArchState *env = cpu->env_ptr;
+int type = BP_TYPE(env->dr[7], index);
+
+switch (type) {
+case DR7_TYPE_BP_INST:
+if (env->cpu_breakpoint[index]) {
+cpu_breakpoint_remove_by_ref(cpu, env->cpu_breakpoint[index]);
+}
+break;
+case DR7_TYPE_DATA_WR:
+case DR7_TYPE_DATA_RW:
+if (env->cpu_watchpoint[index]) {
+cpu_watchpoint_remove_by_ref(cpu, env->cpu_watchpoint[index]);
+}
+break;
+default:
+return 0;
+}
+
+env->cpu_breakpoint[index] = NULL;
+WINDBG_DEBUG("hw_breakpoint_remove: index(%d), " FMT_ADDR,
+ index, env->dr[index]);
 return 0;
 }
 




[Qemu-devel] [PATCH v4 37/46] windbg: implemented kd_api_read_physical_memory and kd_api_write_physical_memory

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |2 ++
 windbgstub-utils.c  |   29 +
 windbgstub.c|8 
 3 files changed, 39 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index 131eb6418a..a40253f18a 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -85,6 +85,8 @@ void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_read_io_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
+void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
+void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
 
 SizedBuf kd_gen_exception_sc(CPUState *cpu);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index 3f8ce1f8be..6708e62798 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -210,6 +210,35 @@ void kd_api_write_io_space(CPUState *cpu, PacketData *pd)
 pd->m64.ReturnStatus = STATUS_SUCCESS;
 }
 
+void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_READ_MEMORY64 *mem = >m64.u.ReadMemory;
+uint32_t len;
+target_ulong addr;
+
+len = MIN(ldl_p(>TransferCount),
+  PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64));
+addr = ldtul_p(>TargetBaseAddress);
+
+cpu_physical_memory_rw(addr, pd->extra, len, 0);
+pd->extra_size = len;
+stl_p(>ActualBytesRead, len);
+}
+
+void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd)
+{
+DBGKD_WRITE_MEMORY64 *mem = >m64.u.WriteMemory;
+uint32_t len;
+target_ulong addr;
+
+len = MIN(ldl_p(>TransferCount), pd->extra_size);
+addr = ldtul_p(>TargetBaseAddress);
+
+cpu_physical_memory_rw(addr, pd->extra, len, 1);
+pd->extra_size = 0;
+stl_p(>ActualBytesWritten, len);
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index a88bfde072..9cf25bc6dd 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -189,6 +189,14 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_write_control_space(cpu, >data);
 break;
 
+case DbgKdReadPhysicalMemoryApi:
+kd_api_read_physical_memory(cpu, >data);
+break;
+
+case DbgKdWritePhysicalMemoryApi:
+kd_api_write_physical_memory(cpu, >data);
+break;
+
 case DbgKdClearAllInternalBreakpointsApi:
 return;
 




[Qemu-devel] [PATCH v4 35/46] windbg: implemented kd_api_continue

2017-12-11 Thread Mihail Abakumov
Signed-off-by: Mihail Abakumov 
Signed-off-by: Pavel Dovgalyuk 
Signed-off-by: Dmitriy Koltunov 
---
 include/exec/windbgstub-utils.h |1 +
 windbgstub-utils.c  |   15 +++
 windbgstub.c|5 +
 3 files changed, 21 insertions(+)

diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
index cc4809de0d..b2416d7698 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -80,6 +80,7 @@ void kd_api_get_context(CPUState *cpu, PacketData *pd);
 void kd_api_set_context(CPUState *cpu, PacketData *pd);
 void kd_api_write_breakpoint(CPUState *cpu, PacketData *pd);
 void kd_api_restore_breakpoint(CPUState *cpu, PacketData *pd);
+void kd_api_continue(CPUState *cpu, PacketData *pd);
 void kd_api_read_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_write_control_space(CPUState *cpu, PacketData *pd);
 void kd_api_unsupported(CPUState *cpu, PacketData *pd);
diff --git a/windbgstub-utils.c b/windbgstub-utils.c
index f00dab2a9d..fe3adb0b88 100755
--- a/windbgstub-utils.c
+++ b/windbgstub-utils.c
@@ -10,6 +10,7 @@
  */
 
 #include "exec/windbgstub-utils.h"
+#include "sysemu/sysemu.h"
 
 static InitedAddr KPCR;
 static InitedAddr version;
@@ -133,6 +134,20 @@ void kd_api_restore_breakpoint(CPUState *cpu, PacketData 
*pd)
 }
 }
 
+void kd_api_continue(CPUState *cpu, PacketData *pd)
+{
+uint32_t status = ldl_p(>m64.u.Continue2.ContinueStatus);
+uint32_t trace = ldl_p(>m64.u.Continue2.ControlSet.TraceFlag);
+int ssFlag = trace ? SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER : 0;
+
+if (NT_SUCCESS(status)) {
+cpu_single_step(cpu, ssFlag);
+if (!runstate_needs_reset()) {
+vm_start();
+}
+}
+}
+
 void kd_api_unsupported(CPUState *cpu, PacketData *pd)
 {
 WINDBG_ERROR("Caught unimplemented api %s",
diff --git a/windbgstub.c b/windbgstub.c
index d3c1317255..bc59c0903a 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -168,6 +168,11 @@ static void 
windbg_process_manipulate_packet(ParsingContext *ctx)
 kd_api_restore_breakpoint(cpu, >data);
 break;
 
+case DbgKdContinueApi:
+case DbgKdContinueApi2:
+kd_api_continue(cpu, >data);
+return;
+
 case DbgKdReadControlSpaceApi:
 kd_api_read_control_space(cpu, >data);
 break;




  1   2   3   >