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

2017-12-14 Thread Ladi Prosek
On Mon, Dec 11, 2017 at 2:21 PM, Mihail Abakumov
 wrote:
> 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_p

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

2017-12-14 Thread Ladi Prosek
On Mon, Dec 11, 2017 at 2:21 PM, Mihail Abakumov
 wrote:
> 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(&var)
> +
> +#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;
> +

Ah, I thought you'd remove it completely. I was thinking about
something like this (patch on top of your series):

diff --git a/include/exec/windbgstub-utils.h
b/include/exec/windbgstub-utils.h
index d3e737e031..ece1c8ce60 100755
--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -50,11 +50,6 @@
 # define ldtul_p(p) ldl_p(p)
 #endif

-typedef struct SizedBuf {
-uint8_t *data;
-size_t size;
-} SizedBuf;
-
 typedef struct InitedAddr {
 target_ulong addr;
 bool is_init;
@@ -97,8 +92,8 @@ 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);
+void kd_gen_exception_sc(CPUState *cpu, DBGKD_ANY_WAIT_STATE_CHANGE
*sc);
+void kd_gen_load_symbols_sc(CPUState *cpu,
DBGKD_ANY_WAIT_STATE_CHANGE *sc);

 bool windbg_on_load(void);

diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
index c38bfa7448..6c42b95fe9 100755
--- a/target/i386/windbgstub.c
+++ b/target/i386/windbgstub.c
@@ -1184,40 +1184,25 @@ static void kd_init_state_change(CPUState
*cpu,
 }
 }

-SizedBuf kd_gen_exception_sc(CPUState *cpu)
+void kd_gen_exception_sc(CPUState *cpu, DBGKD_ANY_WAIT_STATE_CHANGE
*sc)
 {
 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 = &sc->u.Exception.ExceptionRecord;
 kd_init_state_change(cpu, sc);

 stl_p(&sc->NewState, DbgKdExceptionStateChange);
 stl_p(&exc->ExceptionCode, 0x8003);
 sttul_p(&exc->ExceptionAddress, env->eip);
-
-return buf;
 }

-SizedBuf kd_gen_load_symbols_sc(CPUState *cpu)
+void kd_gen_load_symbols_sc(CPUState *cpu,
DBGKD_ANY_WAIT_STATE_CHANGE *sc)
 {
-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(&sc->NewState, DbgKdLoadSymbolsStateChange);
 stl_p(&sc->u.LoadSymbols.PathNameLength, 0);
-
-return buf;
 }

 #endif
diff --git a/windbgstub.c b/windbgstub.c
index a458b962de..d8712af103 100755
--- a/windbgstub.c
+++ b/windbgstub.c
@@ -117,9 +117,15 @@ static void windbg_send_control_packet(uint16_t
type)

 static void windbg_bp_handler(CPUState *cpu)
 {
-SizedBuf buf = kd_gen_exception_sc(cpu);
-windbg_send_data_packet(buf.data, buf.size,
PACKET_TYPE_KD_STATE_CHANGE64);
-g_free(buf.data);
+struct {
+DBGKD_ANY_WAIT_STATE_CHANGE sc;
+int extra;
+} sc_with_extra;
+
+memset(&sc_with_extra, 0, sizeof(sc_with_extra));
+kd_gen_exception_sc(cpu, &sc_with_extra.sc);
+windbg_send_data_packet((uint8_t *)&sc_with_extra,
sizeof(sc_with_extra),
+PACKET_TYPE_KD_STATE_CHANGE64);
 }

 static void windbg_vm_stop(void)
@@ -264,6 +270,8 @@ static void
windbg_process_data_packet(ParsingContext *ctx)

 static void win

[Qemu-devel] [PATCH v4 0/4] ivshmem: MSI bug fixes

2017-12-10 Thread Ladi Prosek
Fixes bugs in the ivshmem device implementation uncovered with the new
Windows ivshmem driver:
https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

v1->v2:
* Patch 1 - added reproducer info to commit message (Markus)
* Patch 2 - restructured conditionals, fixed comment formatting (Markus)
* Patch 3 - added reproducer info to commit message (Markus)

v2->v3:
* Added patch 4

v3->v4:
* Added forward decl of ivshmem_disable_irqfd() instead of moving
  ivshmem_reset() (Eric, Markus)

Ladi Prosek (4):
  ivshmem: Don't update non-existent MSI routes
  ivshmem: Always remove irqfd notifiers
  ivshmem: Improve MSI irqfd error handling
  ivshmem: Disable irqfd on device reset

 hw/misc/ivshmem.c | 81 ++-
 1 file changed, 62 insertions(+), 19 deletions(-)

-- 
2.13.6




[Qemu-devel] [PATCH v4 4/4] ivshmem: Disable irqfd on device reset

2017-12-10 Thread Ladi Prosek
The effects of ivshmem_enable_irqfd() was not undone on device reset.

This manifested as:
ivshmem_add_kvm_msi_virq: Assertion `!s->msi_vectors[vector].pdev' failed.

when irqfd was enabled before reset and then enabled again after reset, making
ivshmem_enable_irqfd() run for the second time.

To reproduce, run:

  ivshmem-server

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then install the Windows driver, at the time of writing available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

and crash-reboot the guest by inducing a BSOD.

Signed-off-by: Ladi Prosek 
---
 hw/misc/ivshmem.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index d1bb246d12..9c7e74ef12 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -758,10 +758,14 @@ static void ivshmem_msix_vector_use(IVShmemState *s)
 }
 }
 
+static void ivshmem_disable_irqfd(IVShmemState *s);
+
 static void ivshmem_reset(DeviceState *d)
 {
 IVShmemState *s = IVSHMEM_COMMON(d);
 
+ivshmem_disable_irqfd(s);
+
 s->intrstatus = 0;
 s->intrmask = 0;
 if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
-- 
2.13.6




[Qemu-devel] [PATCH v4 3/4] ivshmem: Improve MSI irqfd error handling

2017-12-10 Thread Ladi Prosek
Adds a rollback path to ivshmem_enable_irqfd() and fixes
ivshmem_disable_irqfd() to bail if irqfd has not been enabled.

To reproduce, run:

  ivshmem-server -n 0

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then load, unload, and load again the Windows driver, at the time of writing
available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

The issue is believed to have been masked by other guest drivers, notably
Linux ones, not enabling MSI-X on the device.

Signed-off-by: Ladi Prosek 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 37 -
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 91364d8364..d1bb246d12 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -786,6 +786,20 @@ static int ivshmem_setup_interrupts(IVShmemState *s, Error 
**errp)
 return 0;
 }
 
+static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
+{
+IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
+
+if (s->msi_vectors[vector].pdev == NULL) {
+return;
+}
+
+/* it was cleaned when masked in the frontend. */
+kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
+
+s->msi_vectors[vector].pdev = NULL;
+}
+
 static void ivshmem_enable_irqfd(IVShmemState *s)
 {
 PCIDevice *pdev = PCI_DEVICE(s);
@@ -797,7 +811,7 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
 ivshmem_add_kvm_msi_virq(s, i, &err);
 if (err) {
 error_report_err(err);
-/* TODO do we need to handle the error? */
+goto undo;
 }
 }
 
@@ -806,21 +820,14 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
   ivshmem_vector_mask,
   ivshmem_vector_poll)) {
 error_report("ivshmem: msix_set_vector_notifiers failed");
+goto undo;
 }
-}
+return;
 
-static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
-{
-IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
-
-if (s->msi_vectors[vector].pdev == NULL) {
-return;
+undo:
+while (--i >= 0) {
+ivshmem_remove_kvm_msi_virq(s, i);
 }
-
-/* it was cleaned when masked in the frontend. */
-kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
-
-s->msi_vectors[vector].pdev = NULL;
 }
 
 static void ivshmem_disable_irqfd(IVShmemState *s)
@@ -828,6 +835,10 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
+if (!pdev->msix_vector_use_notifier) {
+return;
+}
+
 msix_unset_vector_notifiers(pdev);
 
 for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-- 
2.13.6




[Qemu-devel] [PATCH v4 1/4] ivshmem: Don't update non-existent MSI routes

2017-12-10 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

  kvm_irqchip_commit_routes: Assertion `ret == 0' failed.

if the ivshmem device is configured with more vectors than what the server
supports. This is caused by the ivshmem_vector_unmask() being called on
vectors that have not been initialized by ivshmem_add_kvm_msi_virq().

This commit fixes it by adding a simple check to the mask and unmask
callbacks.

Note that the opposite mismatch, if the server supplies more vectors than
what the device is configured for, is already handled and leads to output
like:

  Too many eventfd received, device has 1 vectors

To reproduce the assert, run:

  ivshmem-server -n 0

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then load the Windows driver, at the time of writing available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

The issue is believed to have been masked by other guest drivers, notably
Linux ones, not enabling MSI-X on the device.

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index a5a46827fe..6e46669744 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -317,6 +317,10 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 int ret;
 
 IVSHMEM_DPRINTF("vector unmask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return -EINVAL;
+}
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -331,12 +335,16 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 {
 IVShmemState *s = IVSHMEM_COMMON(dev);
 EventNotifier *n = &s->peers[s->vm_id].eventfds[vector];
+MSIVector *v = &s->msi_vectors[vector];
 int ret;
 
 IVSHMEM_DPRINTF("vector mask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return;
+}
 
-ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n,
-s->msi_vectors[vector].virq);
+ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
 if (ret != 0) {
 error_report("remove_irqfd_notifier_gsi failed");
 }
-- 
2.13.6




[Qemu-devel] [PATCH v4 2/4] ivshmem: Always remove irqfd notifiers

2017-12-10 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

ivshmem: msix_set_vector_notifiers failed
msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && 
dev->msix_vector_release_notifier' failed.

if MSI-X is repeatedly enabled and disabled on the ivshmem device, for example
by loading and unloading the Windows ivshmem driver. This is because
msix_unset_vector_notifiers() doesn't call any of the release notifier callbacks
since MSI-X is already disabled at that point (msix_enabled() returning false
is how this transition is detected in the first place). Thus 
ivshmem_vector_mask()
doesn't run and when MSI-X is subsequently enabled again ivshmem_vector_unmask()
fails.

This is fixed by keeping track of unmasked vectors and making sure that
ivshmem_vector_mask() always runs on MSI-X disable.

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 6e46669744..91364d8364 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -77,6 +77,7 @@ typedef struct Peer {
 typedef struct MSIVector {
 PCIDevice *pdev;
 int virq;
+bool unmasked;
 } MSIVector;
 
 typedef struct IVShmemState {
@@ -321,6 +322,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 error_report("ivshmem: vector %d route does not exist", vector);
 return -EINVAL;
 }
+assert(!v->unmasked);
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -328,7 +330,13 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 }
 kvm_irqchip_commit_routes(kvm_state);
 
-return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+if (ret < 0) {
+return ret;
+}
+v->unmasked = true;
+
+return 0;
 }
 
 static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector)
@@ -343,11 +351,14 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 error_report("ivshmem: vector %d route does not exist", vector);
 return;
 }
+assert(v->unmasked);
 
 ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
-if (ret != 0) {
+if (ret < 0) {
 error_report("remove_irqfd_notifier_gsi failed");
+return;
 }
+v->unmasked = false;
 }
 
 static void ivshmem_vector_poll(PCIDevice *dev,
@@ -817,11 +828,20 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
-for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-ivshmem_remove_kvm_msi_virq(s, i);
-}
-
 msix_unset_vector_notifiers(pdev);
+
+for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
+/*
+ * MSI-X is already disabled here so msix_unset_vector_notifiers()
+ * didn't call our release notifier.  Do it now to keep our masks and
+ * unmasks balanced.
+ */
+if (s->msi_vectors[i].unmasked) {
+ivshmem_vector_mask(pdev, i);
+}
+ivshmem_remove_kvm_msi_virq(s, i);
+}
+
 }
 
 static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
-- 
2.13.6




Re: [Qemu-devel] [PATCH v3 4/4] ivshmem: Disable irqfd on device reset

2017-12-08 Thread Ladi Prosek
On Fri, Dec 8, 2017 at 6:28 PM, Markus Armbruster  wrote:
> Ladi Prosek  writes:
>
>> On Fri, Dec 8, 2017 at 2:36 PM, Markus Armbruster  wrote:
>>> Ladi Prosek  writes:
>>>
>>>> The effects of ivshmem_enable_irqfd() was not undone on device reset.
>>>>
>>>> This manifested as:
>>>> ivshmem_add_kvm_msi_virq: Assertion `!s->msi_vectors[vector].pdev' failed.
>>>>
>>>> when irqfd was enabled before reset and then enabled again after reset, 
>>>> making
>>>> ivshmem_enable_irqfd() run for the second time.
>>>>
>>>> To reproduce, run:
>>>>
>>>>   ivshmem-server
>>>>
>>>> and QEMU with:
>>>>
>>>>   -device ivshmem-doorbell,chardev=iv
>>>>   -chardev socket,path=/tmp/ivshmem_socket,id=iv
>>>>
>>>> then install the Windows driver, at the time of writing available at:
>>>>
>>>> https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem
>>>>
>>>> and crash-reboot the guest by inducing a BSOD.
>>>>
>>>> Signed-off-by: Ladi Prosek 
>>>> ---
>>>>  hw/misc/ivshmem.c | 24 +---
>>>>  1 file changed, 13 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
>>>> index d1bb246d12..4be0d2627b 100644
>>>> --- a/hw/misc/ivshmem.c
>>>> +++ b/hw/misc/ivshmem.c
>>>> @@ -758,17 +758,6 @@ static void ivshmem_msix_vector_use(IVShmemState *s)
>>>>  }
>>>>  }
>>>>
>>>> -static void ivshmem_reset(DeviceState *d)
>>>> -{
>>>> -IVShmemState *s = IVSHMEM_COMMON(d);
>>>> -
>>>> -s->intrstatus = 0;
>>>> -s->intrmask = 0;
>>>> -if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
>>>> -ivshmem_msix_vector_use(s);
>>>> -}
>>>> -}
>>>> -
>>>>  static int ivshmem_setup_interrupts(IVShmemState *s, Error **errp)
>>>>  {
>>>>  /* allocate QEMU callback data for receiving interrupts */
>>>> @@ -855,6 +844,19 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
>>>>
>>>>  }
>>>>
>>>> +static void ivshmem_reset(DeviceState *d)
>>>> +{
>>>> +IVShmemState *s = IVSHMEM_COMMON(d);
>>>> +
>>>> +ivshmem_disable_irqfd(s);
>>>> +
>>>> +s->intrstatus = 0;
>>>> +s->intrmask = 0;
>>>> +if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
>>>> +ivshmem_msix_vector_use(s);
>>>> +}
>>>> +}
>>>> +
>>>>  static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
>>>>   uint32_t val, int len)
>>>>  {
>>>
>>> Why are you moving ivshmem_reset()?  Makes the actual change harder to
>>> see than necessary.
>>
>> ivshmem_disable_irqfd() is declared after ivshmem_reset() in the
>> source file. I generally prefer to order static functions
>> topologically if possible. If you'd prefer adding a forward decl
>> instead (fewer lines touched, easier to bisect?) I can certainly do
>> that. Thanks!
>
> Well, it compiles before your patch, your patch doesn't add any calls,
> so I can't quite see why a forward declaration would be needed.

It adds a call to ivshmem_disable_irqfd().



Re: [Qemu-devel] [PATCH v3 4/4] ivshmem: Disable irqfd on device reset

2017-12-08 Thread Ladi Prosek
On Fri, Dec 8, 2017 at 2:36 PM, Markus Armbruster  wrote:
> Ladi Prosek  writes:
>
>> The effects of ivshmem_enable_irqfd() was not undone on device reset.
>>
>> This manifested as:
>> ivshmem_add_kvm_msi_virq: Assertion `!s->msi_vectors[vector].pdev' failed.
>>
>> when irqfd was enabled before reset and then enabled again after reset, 
>> making
>> ivshmem_enable_irqfd() run for the second time.
>>
>> To reproduce, run:
>>
>>   ivshmem-server
>>
>> and QEMU with:
>>
>>   -device ivshmem-doorbell,chardev=iv
>>   -chardev socket,path=/tmp/ivshmem_socket,id=iv
>>
>> then install the Windows driver, at the time of writing available at:
>>
>> https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem
>>
>> and crash-reboot the guest by inducing a BSOD.
>>
>> Signed-off-by: Ladi Prosek 
>> ---
>>  hw/misc/ivshmem.c | 24 +---
>>  1 file changed, 13 insertions(+), 11 deletions(-)
>>
>> diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
>> index d1bb246d12..4be0d2627b 100644
>> --- a/hw/misc/ivshmem.c
>> +++ b/hw/misc/ivshmem.c
>> @@ -758,17 +758,6 @@ static void ivshmem_msix_vector_use(IVShmemState *s)
>>  }
>>  }
>>
>> -static void ivshmem_reset(DeviceState *d)
>> -{
>> -IVShmemState *s = IVSHMEM_COMMON(d);
>> -
>> -s->intrstatus = 0;
>> -s->intrmask = 0;
>> -if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
>> -ivshmem_msix_vector_use(s);
>> -}
>> -}
>> -
>>  static int ivshmem_setup_interrupts(IVShmemState *s, Error **errp)
>>  {
>>  /* allocate QEMU callback data for receiving interrupts */
>> @@ -855,6 +844,19 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
>>
>>  }
>>
>> +static void ivshmem_reset(DeviceState *d)
>> +{
>> +IVShmemState *s = IVSHMEM_COMMON(d);
>> +
>> +ivshmem_disable_irqfd(s);
>> +
>> +s->intrstatus = 0;
>> +s->intrmask = 0;
>> +if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
>> +ivshmem_msix_vector_use(s);
>> +}
>> +}
>> +
>>  static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
>>   uint32_t val, int len)
>>  {
>
> Why are you moving ivshmem_reset()?  Makes the actual change harder to
> see than necessary.

ivshmem_disable_irqfd() is declared after ivshmem_reset() in the
source file. I generally prefer to order static functions
topologically if possible. If you'd prefer adding a forward decl
instead (fewer lines touched, easier to bisect?) I can certainly do
that. Thanks!



Re: [Qemu-devel] [PATCH v2 0/3] ivshmem: MSI bug fixes

2017-12-07 Thread Ladi Prosek
On Mon, Nov 20, 2017 at 1:49 PM, Ladi Prosek  wrote:
> On Mon, Nov 20, 2017 at 10:07 AM, Ladi Prosek  wrote:
>> On Sun, Nov 19, 2017 at 9:39 PM,   wrote:
>>> I just updated to the latest build and applied this patch set, now on VM
>>> reset the qemu crashes with the following assert:
>>>
>>> ivshmem.c:467: ivshmem_add_kvm_msi_virq: Assertion
>>> `!s->msi_vectors[vector].pdev' failed.
>>
>> I see asserts too. Even with v1 on top of QEMU v2.10.0 so I must have
>> missed something.
>>
>> Looking. And, needless to say, these patches should not be applied just yet 
>> :)
>
> Ok, here goes it.
>
> 1)
> ivshmem.c:467: ivshmem_add_kvm_msi_virq: Assertion
> `!s->msi_vectors[vector].pdev' failed.
>
> Is caused by the ivshmem device not undoing the effects of
> ivshmem_enable_irqfd() on reset.
>
> This fix works for me:
>
> --- a/hw/misc/ivshmem.c
> +++ b/hw/misc/ivshmem.c
> @@ -758,10 +758,15 @@ static void ivshmem_msix_vector_use(IVShmemState *s)
>  }
>  }
>
> +
> +static void ivshmem_disable_irqfd(IVShmemState *s);
> +
>  static void ivshmem_reset(DeviceState *d)
>  {
>  IVShmemState *s = IVSHMEM_COMMON(d);
>
> +ivshmem_disable_irqfd(s);
> +
>  s->intrstatus = 0;
>  s->intrmask = 0;
>  if (ivshmem_has_feature(s, IVSHMEM_MSI)) {

I have added this to v3 as patch 4.

> 2)
> ivshmem.c:354: ivshmem_vector_mask: Assertion `v->unmasked' failed.
>
> which I've been also getting after I enabled Driver Verifier and
> Windows started crashing
> (https://github.com/virtio-win/kvm-guest-drivers-windows/pull/199), is
> caused by the MSI-X code masking already masked vectors on reset. I'm
> going to post a patch similar to this:
>
> --- a/hw/pci/msix.c
> +++ b/hw/pci/msix.c
> @@ -500,11 +500,12 @@ void msix_reset(PCIDevice *dev)
>  return;
>  }
>  msix_clear_all_vectors(dev);
> +msix_mask_all(dev, dev->msix_entries_nr);
>  dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
> ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
>  memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
>  memset(dev->msix_pba, 0, QEMU_ALIGN_UP(dev->msix_entries_nr, 64) / 8);
> -msix_mask_all(dev, dev->msix_entries_nr);
> +msix_update_function_masked(dev);
>  }
>
>
> Then either no further changes to this patchset are necessary. Or, if
> relying on unmasks/masks (or
> msix_vector_use_notifier/msix_vector_release_notifier as it's called
> in msix.c) always being balanced is not recommended, the assert will
> simply change into an if.

This is fixed in "msix: don't mask already masked vectors on reset":
https://lists.gnu.org/archive/html/qemu-devel/2017-12/msg01362.html



[Qemu-devel] [PATCH v3 4/4] ivshmem: Disable irqfd on device reset

2017-12-07 Thread Ladi Prosek
The effects of ivshmem_enable_irqfd() was not undone on device reset.

This manifested as:
ivshmem_add_kvm_msi_virq: Assertion `!s->msi_vectors[vector].pdev' failed.

when irqfd was enabled before reset and then enabled again after reset, making
ivshmem_enable_irqfd() run for the second time.

To reproduce, run:

  ivshmem-server

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then install the Windows driver, at the time of writing available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

and crash-reboot the guest by inducing a BSOD.

Signed-off-by: Ladi Prosek 
---
 hw/misc/ivshmem.c | 24 +---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index d1bb246d12..4be0d2627b 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -758,17 +758,6 @@ static void ivshmem_msix_vector_use(IVShmemState *s)
 }
 }
 
-static void ivshmem_reset(DeviceState *d)
-{
-IVShmemState *s = IVSHMEM_COMMON(d);
-
-s->intrstatus = 0;
-s->intrmask = 0;
-if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
-ivshmem_msix_vector_use(s);
-}
-}
-
 static int ivshmem_setup_interrupts(IVShmemState *s, Error **errp)
 {
 /* allocate QEMU callback data for receiving interrupts */
@@ -855,6 +844,19 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 
 }
 
+static void ivshmem_reset(DeviceState *d)
+{
+IVShmemState *s = IVSHMEM_COMMON(d);
+
+ivshmem_disable_irqfd(s);
+
+s->intrstatus = 0;
+s->intrmask = 0;
+if (ivshmem_has_feature(s, IVSHMEM_MSI)) {
+ivshmem_msix_vector_use(s);
+}
+}
+
 static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
  uint32_t val, int len)
 {
-- 
2.13.6




[Qemu-devel] [PATCH v3 0/4] ivshmem: MSI bug fixes

2017-12-07 Thread Ladi Prosek
Fixes bugs in the ivshmem device implementation uncovered with the new
Windows ivshmem driver:
https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

v1->v2:
* Patch 1 - added reproducer info to commit message (Markus)
* Patch 2 - restructured conditionals, fixed comment formatting (Markus)
* Patch 3 - added reproducer info to commit message (Markus)

v2->v3:
* Added patch 4

Ladi Prosek (4):
  ivshmem: Don't update non-existent MSI routes
  ivshmem: Always remove irqfd notifiers
  ivshmem: Improve MSI irqfd error handling
  ivshmem: Disable irqfd on device reset

 hw/misc/ivshmem.c | 101 ++
 1 file changed, 71 insertions(+), 30 deletions(-)

-- 
2.13.6




[Qemu-devel] [PATCH v3 2/4] ivshmem: Always remove irqfd notifiers

2017-12-07 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

ivshmem: msix_set_vector_notifiers failed
msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && 
dev->msix_vector_release_notifier' failed.

if MSI-X is repeatedly enabled and disabled on the ivshmem device, for example
by loading and unloading the Windows ivshmem driver. This is because
msix_unset_vector_notifiers() doesn't call any of the release notifier callbacks
since MSI-X is already disabled at that point (msix_enabled() returning false
is how this transition is detected in the first place). Thus 
ivshmem_vector_mask()
doesn't run and when MSI-X is subsequently enabled again ivshmem_vector_unmask()
fails.

This is fixed by keeping track of unmasked vectors and making sure that
ivshmem_vector_mask() always runs on MSI-X disable.

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 6e46669744..91364d8364 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -77,6 +77,7 @@ typedef struct Peer {
 typedef struct MSIVector {
 PCIDevice *pdev;
 int virq;
+bool unmasked;
 } MSIVector;
 
 typedef struct IVShmemState {
@@ -321,6 +322,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 error_report("ivshmem: vector %d route does not exist", vector);
 return -EINVAL;
 }
+assert(!v->unmasked);
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -328,7 +330,13 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 }
 kvm_irqchip_commit_routes(kvm_state);
 
-return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+if (ret < 0) {
+return ret;
+}
+v->unmasked = true;
+
+return 0;
 }
 
 static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector)
@@ -343,11 +351,14 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 error_report("ivshmem: vector %d route does not exist", vector);
 return;
 }
+assert(v->unmasked);
 
 ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
-if (ret != 0) {
+if (ret < 0) {
 error_report("remove_irqfd_notifier_gsi failed");
+return;
 }
+v->unmasked = false;
 }
 
 static void ivshmem_vector_poll(PCIDevice *dev,
@@ -817,11 +828,20 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
-for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-ivshmem_remove_kvm_msi_virq(s, i);
-}
-
 msix_unset_vector_notifiers(pdev);
+
+for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
+/*
+ * MSI-X is already disabled here so msix_unset_vector_notifiers()
+ * didn't call our release notifier.  Do it now to keep our masks and
+ * unmasks balanced.
+ */
+if (s->msi_vectors[i].unmasked) {
+ivshmem_vector_mask(pdev, i);
+}
+ivshmem_remove_kvm_msi_virq(s, i);
+}
+
 }
 
 static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
-- 
2.13.6




[Qemu-devel] [PATCH v3 3/4] ivshmem: Improve MSI irqfd error handling

2017-12-07 Thread Ladi Prosek
Adds a rollback path to ivshmem_enable_irqfd() and fixes
ivshmem_disable_irqfd() to bail if irqfd has not been enabled.

To reproduce, run:

  ivshmem-server -n 0

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then load, unload, and load again the Windows driver, at the time of writing
available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

The issue is believed to have been masked by other guest drivers, notably
Linux ones, not enabling MSI-X on the device.

Signed-off-by: Ladi Prosek 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 37 -
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 91364d8364..d1bb246d12 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -786,6 +786,20 @@ static int ivshmem_setup_interrupts(IVShmemState *s, Error 
**errp)
 return 0;
 }
 
+static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
+{
+IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
+
+if (s->msi_vectors[vector].pdev == NULL) {
+return;
+}
+
+/* it was cleaned when masked in the frontend. */
+kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
+
+s->msi_vectors[vector].pdev = NULL;
+}
+
 static void ivshmem_enable_irqfd(IVShmemState *s)
 {
 PCIDevice *pdev = PCI_DEVICE(s);
@@ -797,7 +811,7 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
 ivshmem_add_kvm_msi_virq(s, i, &err);
 if (err) {
 error_report_err(err);
-/* TODO do we need to handle the error? */
+goto undo;
 }
 }
 
@@ -806,21 +820,14 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
   ivshmem_vector_mask,
   ivshmem_vector_poll)) {
 error_report("ivshmem: msix_set_vector_notifiers failed");
+goto undo;
 }
-}
+return;
 
-static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
-{
-IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
-
-if (s->msi_vectors[vector].pdev == NULL) {
-return;
+undo:
+while (--i >= 0) {
+ivshmem_remove_kvm_msi_virq(s, i);
 }
-
-/* it was cleaned when masked in the frontend. */
-kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
-
-s->msi_vectors[vector].pdev = NULL;
 }
 
 static void ivshmem_disable_irqfd(IVShmemState *s)
@@ -828,6 +835,10 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
+if (!pdev->msix_vector_use_notifier) {
+return;
+}
+
 msix_unset_vector_notifiers(pdev);
 
 for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-- 
2.13.6




[Qemu-devel] [PATCH v3 1/4] ivshmem: Don't update non-existent MSI routes

2017-12-07 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

  kvm_irqchip_commit_routes: Assertion `ret == 0' failed.

if the ivshmem device is configured with more vectors than what the server
supports. This is caused by the ivshmem_vector_unmask() being called on
vectors that have not been initialized by ivshmem_add_kvm_msi_virq().

This commit fixes it by adding a simple check to the mask and unmask
callbacks.

Note that the opposite mismatch, if the server supplies more vectors than
what the device is configured for, is already handled and leads to output
like:

  Too many eventfd received, device has 1 vectors

To reproduce the assert, run:

  ivshmem-server -n 0

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then load the Windows driver, at the time of writing available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

The issue is believed to have been masked by other guest drivers, notably
Linux ones, not enabling MSI-X on the device.

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index a5a46827fe..6e46669744 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -317,6 +317,10 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 int ret;
 
 IVSHMEM_DPRINTF("vector unmask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return -EINVAL;
+}
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -331,12 +335,16 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 {
 IVShmemState *s = IVSHMEM_COMMON(dev);
 EventNotifier *n = &s->peers[s->vm_id].eventfds[vector];
+MSIVector *v = &s->msi_vectors[vector];
 int ret;
 
 IVSHMEM_DPRINTF("vector mask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return;
+}
 
-ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n,
-s->msi_vectors[vector].virq);
+ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
 if (ret != 0) {
 error_report("remove_irqfd_notifier_gsi failed");
 }
-- 
2.13.6




[Qemu-devel] [PATCH v2] msix: don't mask already masked vectors on reset

2017-12-07 Thread Ladi Prosek
msix_mask_all() is supposed to invoke the release vector notifier if the state 
of the
respective vector changed from unmasked to masked. The way it's currently 
called from
msix_reset(), though, may result in calling the release notifier even if the 
vector
is already masked.

1) msix_reset() clears out the msix_cap field and the msix_table.
2) msix_mask_all() runs with was_masked=false for all vectors because of 1), 
which
   results in calling the release notifier on all vectors.
3) if msix_reset() is subsequently called again, it goes through the same steps 
and
   calls the release notifier on all vectors again.

This commit moves msix_mask_all() up so it runs before the device state is 
lost. And
it adds an assignment to msix_function_masked so that the device remembers that
MSI-X is masked.

This is likely a low impact issue, found while debugging an already broken 
device. It
is however easy to fix and the expectation that the use and release notifier 
invocations
are always balanced is very natural.

Signed-off-by: Ladi Prosek 
---

v1->v2:
* fixed typo in commit message "or" -> "to" (Marcel)
* directly set msix_function_masked to true instead of calling
  msix_update_function_masked() (Marcel)


 hw/pci/msix.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index c944c02135..d6a4dbdb6b 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -500,11 +500,12 @@ void msix_reset(PCIDevice *dev)
 return;
 }
 msix_clear_all_vectors(dev);
+msix_mask_all(dev, dev->msix_entries_nr);
 dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
 memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
 memset(dev->msix_pba, 0, QEMU_ALIGN_UP(dev->msix_entries_nr, 64) / 8);
-msix_mask_all(dev, dev->msix_entries_nr);
+dev->msix_function_masked = true;
 }
 
 /* PCI spec suggests that devices make it possible for software to configure
-- 
2.13.6




Re: [Qemu-devel] [PATCH] msix: don't mask already masked vectors on reset

2017-12-07 Thread Ladi Prosek
On Thu, Dec 7, 2017 at 7:27 PM, Michael S. Tsirkin  wrote:
> On Wed, Nov 22, 2017 at 03:22:50PM +0200, Marcel Apfelbaum wrote:
>> On 22/11/2017 14:32, Ladi Prosek wrote:
>> > On Wed, Nov 22, 2017 at 11:46 AM, Marcel Apfelbaum  
>> > wrote:
>> > > Hi Ladi,
>> > >
>> > > On 20/11/2017 16:22, Ladi Prosek wrote:
>> > > >
>> > > > msix_mask_all() is supposed to invoke the release vector notifier if 
>> > > > the
>> > > > state of the
>> > > > respective vector changed from unmasked or masked.
>> > >
>> > >
>> > > You mean from unmasked "to" masked right?
>> >
>> > Yes, that's a typo.
>> >
>> > > The way it's currently called from
>> > > >
>> > > > msix_reset(), though, may result in calling the release notifier even 
>> > > > if
>> > > > the vector
>> > > > is already masked.
>> > > >
>> > > > 1) msix_reset() clears out the msix_cap field and the msix_table.
>> > > > 2) msix_mask_all() runs with was_masked=false for all vectors because 
>> > > > of
>> > > > 1), which
>> > > >  results in calling the release notifier on all vectors.
>> > > > 3) if msix_reset() is subsequently called again, it goes through the 
>> > > > same
>> > > > steps and
>> > > >  calls the release notifier on all vectors again.
>> > > >
>> > >
>> > > As far as I can see in the code you are right.(very reset will trigger 
>> > > the
>> > > release notifiers
>> > > again)
>> > >
>> > > > This commit moves msix_mask_all() up so it runs before the device 
>> > > > state is
>> > > > lost.
>> > >
>> > >
>> > > OK
>> > >
>> > > > And
>> > > > it adds a call to msix_update_function_masked() so that the device
>> > > > remembers that
>> > > > MSI-X is masked.
>> > > >
>> > >
>> > > msix_update_function_masked checks the msix is enabled or masked-off.
>> > > You are building on the fact the msix will not be enabled to set
>> > > "msix_function_masked" to "true", right?
>> > > (I just want to be sure I understand the patch)
>> >
>> > Correct. msix_enabled() will return false because we've just reset
>> >
>> >dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET]
>> >
>> > I guess we could also simply assign true to it:
>> >
>> >dev->msix_function_masked = true;
>> >
>> > just like msix_init() does.
>>
>> Yes, is preferable - I think.
>> If you intend to send V2, please wait first for Alex's remarks if he has any.
>>
>> Thanks,
>> Marcel
>>
>> >
>> > > > This is likely a low impact issue, found while debugging an already 
>> > > > broken
>> > > > device. It
>> > > > is however easy to fix and the expectation that the use and release
>> > > > notifier invocations
>> > > > are always balanced is very natural.
>> > > >
>> > >
>> > > I would leave it (maybe) out of 2.11 because it may expose other bugs
>> > > and we are after rc2 already.
>> > >
>> > > Adding Alex Williamson to see it does not affect device assignment,
>> > > other than that the patch looks OK to me.
>> > >
>> > >
>> > > Thanks,
>> > > Marcel
>> > >
>> > >
>> > > > Signed-off-by: Ladi Prosek 
>> > > > ---
>> > > >hw/pci/msix.c | 3 ++-
>> > > >1 file changed, 2 insertions(+), 1 deletion(-)
>> > > >
>> > > > diff --git a/hw/pci/msix.c b/hw/pci/msix.c
>> > > > index c944c02135..34656de9b0 100644
>> > > > --- a/hw/pci/msix.c
>> > > > +++ b/hw/pci/msix.c
>> > > > @@ -500,11 +500,12 @@ void msix_reset(PCIDevice *dev)
>> > > >return;
>> > > >}
>> > > >msix_clear_all_vectors(dev);
>> > > > +msix_mask_all(dev, dev->msix_entries_nr);
>> > > >dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
>> > > >  ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
>> > > >memset(dev->msix_table, 0, dev->msix_entries_nr *
>> > > > PCI_MSIX_ENTRY_SIZE);
>> > > >memset(dev->msix_pba, 0, QEMU_ALIGN_UP(dev->msix_entries_nr, 
>> > > > 64) /
>> > > > 8);
>> > > > -msix_mask_all(dev, dev->msix_entries_nr);
>> > > > +msix_update_function_masked(dev);
>> > > >}
>> > > >  /* PCI spec suggests that devices make it possible for software to
>> > > > configure
>> > > >
>> > >
>
> Do you intend to post v2 or need Marcel to?

I'll post v2 tomorrow.



Re: [Qemu-devel] [PATCH v3 39/45] windbg: implemented kd_api_get_version

2017-12-06 Thread Ladi Prosek
On Wed, Dec 6, 2017 at 10:00 AM, Mihail Abakumov
 wrote:
> Ladi Prosek писал 2017-11-29 11:14:
>
>> On Tue, Nov 21, 2017 at 3:10 PM, Mihail Abakumov
>>  wrote:
>>>
>>> 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 be48f69f40..bc5b6a8468 100755
>>> --- a/include/exec/windbgstub-utils.h
>>> +++ b/include/exec/windbgstub-utils.h
>>> @@ -99,6 +99,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(&mem->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(&kdver->MajorVersion, kdver->MajorVersion);
>>> +stw_p(&kdver->MinorVersion, kdver->MinorVersion);
>>> +stw_p(&kdver->Flags, kdver->Flags);
>>> +stw_p(&kdver->MachineType, kdver->MachineType);
>>> +stw_p(&kdver->Unused[0], kdver->Unused[0]);
>>> +sttul_p(&kdver->KernBase, kdver->KernBase);
>>> +sttul_p(&kdver->PsLoadedModuleList, kdver->PsLoadedModuleList);
>>> +sttul_p(&kdver->DebuggerDataList, kdver->DebuggerDataList);
>>> +} else {
>>> +pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
>>
>>
>> The ReturnStatus field must be written using st* as well. You have
>> this direct write in many functions.
>>
>
> I'm doing stl_p for status before sending of packet in the
> 'windbg_process_manipulate_packet',
> because this is a global field of structure. Is that bad?

I see. Technically it's probably ok, as long as you make sure that the
field is always aligned. But having the field hold two representations
of the value depending on where exactly in the program you are is not
good style. Imagine debugging it, looking at the contents of the
structure, and not being sure if you're looking at the host or guest
byte order. Plus everybody reading the code will be confused just like
me :)

>>> +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 72324ae53d..ddca290694 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, &ctx->data);
>>>  break;
>>>
>>> +case DbgKdGetVersionApi:
>>> +kd_api_get_version(cpu, &ctx->data);
>>> +break;
>>> +
>>>  case DbgKdClearAllInternalBreakpointsApi:
>>>  return;
>>>
>>>
>



Re: [Qemu-devel] [PATCH v3 35/45] windbg: debug exception subscribing

2017-12-06 Thread Ladi Prosek
On Wed, Dec 6, 2017 at 8:29 AM, Mihail Abakumov
 wrote:
> Ladi Prosek писал 2017-11-29 10:13:
>
>> On Tue, Nov 21, 2017 at 3:10 PM, Mihail Abakumov
>>  wrote:
>>>
>>> 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  |   18 +-
>>>  gdbstub.c   |4 
>>>  include/sysemu/sysemu.h |2 ++
>>>  windbgstub.c|   16 
>>>  4 files changed, 35 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/cpus.c b/cpus.c
>>> index 9bed61eefc..212553b7e3 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,23 @@ 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("ERROR: Something debugger already using");
>>
>>
>> So I take it that -windbg and -gdb cannot be used at the same time.
>> Should it be handled in a more explicit way with a more user-friendly
>> error?
>>
>> Right now I get this error, which is more like an implementation
>> detail (could the debug handler be refactored into a multicast event
>> in the future?) and does not even make sense as a sentence.
>
>
> Yes. I have added a more user-friendly error. "Something debugger is
> already in use. '-gdb' and '-windbg' cannot be used at the same time".
> Or what do you mean under the explicit way? How to do it better?

Yes, "'-gdb' and '-windbg' cannot be used at the same time" would be
nicer. By being more explicit I mean issuing the error from the code
that parses the options.

In other words, I can imagine an implementation of
register_excp_debug_handler() that allows registering multiple
handlers. But running windbg and gdb at the same would probably still
not be a good idea.

Maybe I'm nit-picking and it's ok for the error to stay here.
Wondering what other reviewers think.

>>
>>> +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 489abe6d6c..b33f412659 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);
>>>  SBUF_FREE(buf);
>>>  }
>>>
>>> +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] virtio-input: add missing KEY_COMPOSE mapping

2017-12-01 Thread Ladi Prosek
This key tends to be located somewhere between right Alt and right
Ctrl and is usually used for opening context menus.

Signed-off-by: Ladi Prosek 
---
 hw/input/virtio-input-hid.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c
index e78faec0b1..387a026e10 100644
--- a/hw/input/virtio-input-hid.c
+++ b/hw/input/virtio-input-hid.c
@@ -139,6 +139,7 @@ static const unsigned int keymap_qcode[Q_KEY_CODE__MAX] = {
 [Q_KEY_CODE_META_L]  = KEY_LEFTMETA,
 [Q_KEY_CODE_META_R]  = KEY_RIGHTMETA,
 [Q_KEY_CODE_MENU]= KEY_MENU,
+[Q_KEY_CODE_COMPOSE] = KEY_COMPOSE,
 };
 
 static const unsigned int keymap_button[INPUT_BUTTON__MAX] = {
-- 
2.13.6




Re: [Qemu-devel] [PATCH v3 00/45] Windbg supporting

2017-11-29 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:07 PM, Mihail Abakumov
 wrote:
> 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 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)


Thanks, v3 is working with a Win10 windbg for me!

A few things I noticed during my testing (Win7 32-bit guest):

* Windbg prints:

  ReadVirtual: 827403d0 not properly sign extended

after connecting. That's likely a bug hiding somewhere.

* lm prints only nt and a bunch of unloaded crash dump modules. This
doesn't look expected and blocks what I believe is the most common way
of initiating debugging which is setting a breakpoint on a specific
driver function. Additionally, after rebooting the guest, lm prints
only nt, nothing else. Do you see the same thing?

  kd> lm
  startendmodule name
  8260b000 82a1d000   nt (pdb symbols)  C:\Program
Files (x86)\Windows
Kits\10\Debuggers\x64\sym\ntkrpamp.pdb\684DA42A30CC450F81C535B4D18944B12\ntkrpamp.pdb

  Unloaded modules:
  869da000 869e7000   crashdmp.sys
  869e7000 869f2000   dump_ataport.sys
  869f2000 869fb000   dump_atapi.sys
  8680 86811000   dump_dumpfve.sys

* It seems to work on a Linux host as well! Still ok to keep it
limited to pipe: for now, especially if you don't test on Linux.

* Wondering about the legal aspects of copying code from winnt.h. I'll
let others confirm that it's ok.

I have replied to some of the patches with comments.

Thank you!
Ladi



Re: [Qemu-devel] [PATCH v3 39/45] windbg: implemented kd_api_get_version

2017-11-29 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:10 PM, Mihail Abakumov
 wrote:
> 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 be48f69f40..bc5b6a8468 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -99,6 +99,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(&mem->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(&kdver->MajorVersion, kdver->MajorVersion);
> +stw_p(&kdver->MinorVersion, kdver->MinorVersion);
> +stw_p(&kdver->Flags, kdver->Flags);
> +stw_p(&kdver->MachineType, kdver->MachineType);
> +stw_p(&kdver->Unused[0], kdver->Unused[0]);
> +sttul_p(&kdver->KernBase, kdver->KernBase);
> +sttul_p(&kdver->PsLoadedModuleList, kdver->PsLoadedModuleList);
> +sttul_p(&kdver->DebuggerDataList, kdver->DebuggerDataList);
> +} else {
> +pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;

The ReturnStatus field must be written using st* as well. You have
this direct write in many functions.

> +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 72324ae53d..ddca290694 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, &ctx->data);
>  break;
>
> +case DbgKdGetVersionApi:
> +kd_api_get_version(cpu, &ctx->data);
> +break;
> +
>  case DbgKdClearAllInternalBreakpointsApi:
>  return;
>
>



Re: [Qemu-devel] [PATCH v3 43/45] windbg: implemented kd_api_query_memory

2017-11-29 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:11 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  include/exec/windbgstub-utils.h |1 +
>  windbgstub-utils.c  |   12 
>  windbgstub.c|4 
>  3 files changed, 17 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index e144294b51..fa1ebbb6d2 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -105,6 +105,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 fb2c378460..edd23c1971 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -333,6 +333,18 @@ void kd_api_fill_memory(CPUState *cpu, PacketData *pd)
>  }
>  }
>
> +void kd_api_query_memory(CPUState *cpu, PacketData *pd)
> +{
> +DBGKD_QUERY_MEMORY *mem = &pd->m64.u.QueryMemory;
> +
> +mem->AddressSpace = DBGKD_QUERY_MEMORY_PROCESS;
> +mem->Flags = DBGKD_QUERY_MEMORY_READ |
> + DBGKD_QUERY_MEMORY_WRITE |
> + DBGKD_QUERY_MEMORY_EXECUTE;
> +mem->AddressSpace = ldl_p(&mem->AddressSpace);
> +mem->Flags = ldl_p(&mem->Flags);

This should be:

void kd_api_query_memory(CPUState *cpu, PacketData *pd)
{
DBGKD_QUERY_MEMORY *mem = &pd->m64.u.QueryMemory;

stl_p(&mem->AddressSpace, DBGKD_QUERY_MEMORY_PROCESS);
stl_p(&mem->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 b348028dfd..36372c0ea5 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -220,6 +220,10 @@ static void 
> windbg_process_manipulate_packet(ParsingContext *ctx)
>  kd_api_fill_memory(cpu, &ctx->data);
>  break;
>
> +case DbgKdQueryMemoryApi:
> +kd_api_query_memory(cpu, &ctx->data);
> +break;
> +
>  default:
>  kd_api_unsupported(cpu, &ctx->data);
>  break;
>



Re: [Qemu-devel] [PATCH v3 41/45] windbg: implemented kd_api_search_memory

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:11 PM, Mihail Abakumov
 wrote:
> 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 73d49b774d..c2eb8a75a7 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -102,6 +102,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..1f4590f338 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 = &pd->m64.u.SearchMemory;
> +int s_len = MAX(ldq_p(&m64c->SearchLength), 1);
> +int p_len = MIN(ldl_p(&m64c->PatternLength), pd->extra_size);
> +target_ulong addr = ldq_p(&m64c->SearchAddress);
> +int size = MIN(s_len, 10);
> +uint8_t mem[size + p_len];

Is this allocation bounded by a reasonably small number? What's the
maximum PatternLength?

> +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(&m64c->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, 10);
> +}
> +}
> +

Too bad that you can't use memmem(). This implementation screams
O(N^2) to me. One of the things that can be improved later I guess.

I would at least up the step from 10 to 1024 so we don't call
cpu_memory_rw_debug() that often.

>  void kd_api_unsupported(CPUState *cpu, PacketData *pd)
>  {
>  WINDBG_ERROR("Caught unimplemented api %s",
> diff --git a/windbgstub.c b/windbgstub.c
> index 0268d0818e..d35ff6ba96 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, &ctx->data);
> +break;
> +
>  default:
>  kd_api_unsupported(cpu, &ctx->data);
>  break;
>



Re: [Qemu-devel] [PATCH v3 40/45] windbg: implemented kd_api_read_msr and kd_api_write_msr

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:11 PM, Mihail Abakumov
 wrote:
> 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|  319 
> +++
>  windbgstub.c|8 +
>  3 files changed, 329 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index bc5b6a8468..73d49b774d 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -100,6 +100,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 43e6d45df9..735b2edd5f 100755
> --- a/target/i386/windbgstub.c
> +++ b/target/i386/windbgstub.c
> @@ -1003,6 +1003,325 @@ void kd_api_write_control_space(CPUState *cpu, 
> PacketData *pd)
>  stl_p(&mem->ActualBytesWritten, len);
>  }
>
> +void kd_api_read_msr(CPUState *cpu, PacketData *pd)
> +{
> +DBGKD_READ_WRITE_MSR *m64c = &pd->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;
> + 

Re: [Qemu-devel] [PATCH v3 35/45] windbg: debug exception subscribing

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:10 PM, Mihail Abakumov
 wrote:
> 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  |   18 +-
>  gdbstub.c   |4 
>  include/sysemu/sysemu.h |2 ++
>  windbgstub.c|   16 
>  4 files changed, 35 insertions(+), 5 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index 9bed61eefc..212553b7e3 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,23 @@ 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("ERROR: Something debugger already using");

So I take it that -windbg and -gdb cannot be used at the same time.
Should it be handled in a more explicit way with a more user-friendly
error?

Right now I get this error, which is more like an implementation
detail (could the debug handler be refactored into a multicast event
in the future?) and does not even make sense as a sentence.

> +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 489abe6d6c..b33f412659 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);
>  SBUF_FREE(buf);
>  }
>
> +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;
>  }
>



Re: [Qemu-devel] [PATCH v3 26/45] windbg: implemented windbg_read_context

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:09 PM, Mihail Abakumov
 wrote:
> 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 bf1afab1f8..1fccd8eee7 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;

This deserves at least a comment. Was it maybe for debugging and
accidentally left in the code or is it really intentional?

Also, I believe that cc->ContextFlags should not be accessed directly
in this function but with stl_p / ldl_p.

> +if (cc->ContextFlags & CPU_CONTEXT_SEGMENTS) {
> +stw_p(&cc->SegCs, env->segs[R_CS].selector);
> +stw_p(&cc->SegDs, env->segs[R_DS].selector);
> +stw_p(&cc->SegEs, env->segs[R_ES].selector);
> +stw_p(&cc->SegFs, env->segs[R_FS].selector);
> +stw_p(&cc->SegGs, env->segs[R_GS].selector);
> +stw_p(&cc->SegSs, env->segs[R_SS].selector);
> +}
> +
> +if (cc->ContextFlags & CPU_CONTEXT_DEBUG_REGISTERS) {
> +sttul_p(&cc->Dr0, env->dr[0]);
> +sttul_p(&cc->Dr1, env->dr[1]);
> +sttul_p(&cc->Dr2, env->dr[2]);
> +sttul_p(&cc->Dr3, env->dr[3]);
> +sttul_p(&cc->Dr6, env->dr[6]);
> +sttul_p(&cc->Dr7, env->dr[7]);
> +}
> +
> +if (cc->ContextFlags & CPU_CONTEXT_INTEGER) {
> +stl_p(&cc->Edi, env->regs[R_EDI]);
> +stl_p(&cc->Esi, env->regs[R_ESI]);
> +stl_p(&cc->Ebx, env->regs[R_EBX]);
> +stl_p(&cc->Edx, env->regs[R_EDX]);
> +stl_p(&cc->Ecx, env->regs[R_ECX]);
> +stl_p(&cc->Eax, env->regs[R_EAX]);
> +stl_p(&cc->Ebp, env->regs[R_EBP]);
> +stl_p(&cc->Esp, env->regs[R_ESP]);
> +stl_p(&cc->Eip, env->eip);
> +stl_p(&cc->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(&cc->FloatSave.ControlWord, env->fpuc);
> +stl_p(&cc->FloatSave.StatusWord, swd);
> +stl_p(&cc->FloatSave.TagWord, twd);
> +stl_p(&cc->FloatSave.ErrorOffset, UINT32_P(&env->fpip)[0]);
> +stl_p(&cc->FloatSave.ErrorSelector, UINT32_P(&env->fpip)[1]);
> +stl_p(&cc->FloatSave.DataOffset, UINT32_P(&env->fpdp)[0]);
> +stl_p(&cc->FloatSave.DataSelector, UINT32_P(&env->fpdp)[1]);
> +stl_p(&cc->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(&cc->ContextFlags, cc->ContextFlags);
> +
> +if (new_mem) {
> +memcpy(buf, (uint8_t *) cc + offset, len);
> +g_free(cc);
> +}
>  return 0;
>  }
>
>



Re: [Qemu-devel] [PATCH v3 15/45] windbg: sized data buffer

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:08 PM, Mihail Abakumov
 wrote:
> Defined useful sized data buffer. It contains pointer to data and size of 
> this data. Also, defined some macros for init and free.
>
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  include/exec/windbgstub-utils.h |   16 
>  1 file changed, 16 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index 6ce870beb1..b729cd604e 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -67,6 +67,22 @@ typedef struct PacketData {
>  uint16_t extra_size;
>  } PacketData;
>
> +typedef struct SizedBuf {
> +uint8_t *data;
> +size_t size;
> +} SizedBuf;
> +
> +#define SBUF_INIT(buf, mem_ptr, len) do { \
> +buf.data = mem_ptr;   \
> +buf.size = len;   \
> +} while (false)
> +#define SBUF_MALLOC(buf, size) SBUF_INIT(buf, g_malloc0(size), size)
> +#define SBUF_FREE(buf) do { \
> +g_free(buf.data);   \
> +buf.data = NULL;\
> +buf.size = 0;   \
> +} while (false)
> +

I don't think that this is necessary. These macros are used for ~240
byte data structures and the points where they are allocated and freed
are super close together.

I'd just put them on the stack in the callers of kd_gen_exception_sc()
and kd_gen_load_symbols_sc() (only one caller each) and remove this
patch.

>  InitedAddr *windbg_get_KPCR(void);
>  InitedAddr *windbg_get_version(void);
>
>



Re: [Qemu-devel] [PATCH v3 10/45] windbg: structures for parsing data stream

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:08 PM, Mihail Abakumov
 wrote:
> 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 42dbca1e22..2d74fb847a 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -48,6 +48,17 @@ typedef struct InitedAddr {
>  bool is_init;
>  } InitedAddr;
>
> +typedef struct PacketData {
> +union {
> +struct {
> +DBGKD_MANIPULATE_STATE64 m64;
> +uint8_t extra[PACKET_MAX_SIZE - 
> sizeof(DBGKD_MANIPULATE_STATE64)];

nit:
  uint8_t extra[0];

The buf field below already defines the size and in a more readable way.

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



Re: [Qemu-devel] [PATCH v3 03/45] windbg: modified windbgkd.h

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:07 PM, Mihail Abakumov
 wrote:
> 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 |   75 
> +++
>  1 file changed, 75 insertions(+)
>
> diff --git a/include/exec/windbgkd.h b/include/exec/windbgkd.h
> index b8f98925e7..40a23f8cd0 100755
> --- a/include/exec/windbgkd.h
> +++ b/include/exec/windbgkd.h
> @@ -870,4 +870,79 @@ 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) \
> +(id >= DbgKdMinimumManipulate && id < DbgKdMaximumManipulate) ? \
> +kd_api_names[id - DbgKdMinimumManipulate] : \
> +kd_api_names[DbgKdMaximumManipulate - DbgKdMinimumManipulate] \

nice-to-have: Build-time assert that kd_api_names has
(DbgKdMaximumManipulate - DbgKdMinimumManipulate + 1) elements.

> +#define KD_PKT_TYPE_NAME(id) kd_packet_type_names[id]

nice-to-have: A ternary similar to what KD_API_NAME has for extra safety.

>  #endif
>



Re: [Qemu-devel] [PATCH v3 45/45] windbg: implemented kd_api_get_context_ex and kd_api_set_context_ex

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:11 PM, Mihail Abakumov
 wrote:
[...]
> diff --git a/windbgstub.c b/windbgstub.c
> index 36372c0ea5..3bcf6a8cbb 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -224,6 +224,14 @@ static void 
> windbg_process_manipulate_packet(ParsingContext *ctx)
>  kd_api_query_memory(cpu, &ctx->data);
>  break;
>
> +case DbgKdGetContextExApi:
> +kd_api_get_context_ex(cpu, &ctx->data);
> +break;
> +
> +case DbgKdSetContextExApi:
> +kd_api_set_context_ex(cpu, &ctx->data);
> +break;
> +
>  default:
>  kd_api_unsupported(cpu, &ctx->data);
>  break;
> @@ -262,12 +270,12 @@ static void 
> windbg_process_control_packet(ParsingContext *ctx)
>
>  case PACKET_TYPE_KD_RESET:
>  {
> -SizedBuf buf = kd_gen_load_symbols_sc(qemu_get_cpu(0));
> +windbg_send_control_packet(ctx->packet.PacketType);
> +windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;

You didn't mention it in the cover email so I'd like to be sure. This
is what fixed the initial handshake so it works without -b now, is
that correct? Thanks!

> +SizedBuf buf = kd_gen_load_symbols_sc(qemu_get_cpu(0));
>  windbg_send_data_packet(buf.data, buf.size,
>  PACKET_TYPE_KD_STATE_CHANGE64);
> -windbg_send_control_packet(ctx->packet.PacketType);
> -windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;
>  SBUF_FREE(buf);
>  break;
>  }
>



Re: [Qemu-devel] [PATCH v3 01/45] windbg: added empty windbgstub files

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:07 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  Makefile.target |7 +++
>  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, 105 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..6df0836509 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -148,6 +148,13 @@ obj-y += dump.o
>  obj-y += migration/ram.o
>  LIBS := $(libs_softmmu) $(LIBS)
>
> +# WinDbg support
> +ifeq ($(TARGET_NAME), i386)
> +ifneq ($(TARGET_NAME), x86_64)

This is odd. Did you add the second by mistake? Thanks!



Re: [Qemu-devel] [PATCH v3 05/45] windbg: added helper features

2017-11-28 Thread Ladi Prosek
On Tue, Nov 21, 2017 at 3:07 PM, Mihail Abakumov
 wrote:
> 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 |   27 +++
>  include/exec/windbgstub.h   |6 ++
>  2 files changed, 33 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index 2390597f1f..e9f5223e94 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -13,7 +13,34 @@
>  #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 UINT32_P(ptr) ((uint32_t *) (ptr))

This doesn't cross-compile on Linux:

In file included from
/home/lprosek/qemu/target/i386/windbgstub.c:15:0:
/home/lprosek/qemu/target/i386/windbgstub.c: In function
'kd_api_read_msr':
/home/lprosek/qemu/include/exec/windbgstub-utils.h:35:24: error: cast
to pointer from integer of different size
[-Werror=int-to-pointer-cast]
 #define UINT32_P(ptr) ((uint32_t *) (ptr))
^
/home/lprosek/qemu/target/i386/windbgstub.c:1210:27: note: in
expansion of macro 'UINT32_P'
 m64c->DataValueLow  = UINT32_P(val)[0];
   ^~~~
/home/lprosek/qemu/include/exec/windbgstub-utils.h:35:24: error: cast
to pointer from integer of different size
[-Werror=int-to-pointer-cast]
 #define UINT32_P(ptr) ((uint32_t *) (ptr))
^
/home/lprosek/qemu/target/i386/windbgstub.c:1211:27: note: in
expansion of macro 'UINT32_P'
 m64c->DataValueHigh = UINT32_P(val)[1];
   ^~~~


The macro or the places where it's used need to make sure that the
argument is of the right size. I hacked around it by doing:

--- a/include/exec/windbgstub-utils.h
+++ b/include/exec/windbgstub-utils.h
@@ -32,7 +32,7 @@
 #define FMT_ERR  "Error:%d"

 #define UINT8_P(ptr) ((uint8_t *) (ptr))
-#define UINT32_P(ptr) ((uint32_t *) (ptr))
+#define UINT32_P(ptr) ((uint32_t *) (size_t) (ptr))
 #define PTR(var) UINT8_P(&var)


> +#define PTR(var) UINT8_P(&var)
> +
> +#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;   \
> +})
> +
>  #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
>



Re: [Qemu-devel] [PATCH] msix: don't mask already masked vectors on reset

2017-11-22 Thread Ladi Prosek
On Wed, Nov 22, 2017 at 11:46 AM, Marcel Apfelbaum  wrote:
> Hi Ladi,
>
> On 20/11/2017 16:22, Ladi Prosek wrote:
>>
>> msix_mask_all() is supposed to invoke the release vector notifier if the
>> state of the
>> respective vector changed from unmasked or masked.
>
>
> You mean from unmasked "to" masked right?

Yes, that's a typo.

> The way it's currently called from
>>
>> msix_reset(), though, may result in calling the release notifier even if
>> the vector
>> is already masked.
>>
>> 1) msix_reset() clears out the msix_cap field and the msix_table.
>> 2) msix_mask_all() runs with was_masked=false for all vectors because of
>> 1), which
>> results in calling the release notifier on all vectors.
>> 3) if msix_reset() is subsequently called again, it goes through the same
>> steps and
>> calls the release notifier on all vectors again.
>>
>
> As far as I can see in the code you are right.(very reset will trigger the
> release notifiers
> again)
>
>> This commit moves msix_mask_all() up so it runs before the device state is
>> lost.
>
>
> OK
>
>> And
>> it adds a call to msix_update_function_masked() so that the device
>> remembers that
>> MSI-X is masked.
>>
>
> msix_update_function_masked checks the msix is enabled or masked-off.
> You are building on the fact the msix will not be enabled to set
> "msix_function_masked" to "true", right?
> (I just want to be sure I understand the patch)

Correct. msix_enabled() will return false because we've just reset

  dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET]

I guess we could also simply assign true to it:

  dev->msix_function_masked = true;

just like msix_init() does.

>> This is likely a low impact issue, found while debugging an already broken
>> device. It
>> is however easy to fix and the expectation that the use and release
>> notifier invocations
>> are always balanced is very natural.
>>
>
> I would leave it (maybe) out of 2.11 because it may expose other bugs
> and we are after rc2 already.
>
> Adding Alex Williamson to see it does not affect device assignment,
> other than that the patch looks OK to me.
>
>
> Thanks,
> Marcel
>
>
>> Signed-off-by: Ladi Prosek 
>> ---
>>   hw/pci/msix.c | 3 ++-
>>   1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/pci/msix.c b/hw/pci/msix.c
>> index c944c02135..34656de9b0 100644
>> --- a/hw/pci/msix.c
>> +++ b/hw/pci/msix.c
>> @@ -500,11 +500,12 @@ void msix_reset(PCIDevice *dev)
>>   return;
>>   }
>>   msix_clear_all_vectors(dev);
>> +msix_mask_all(dev, dev->msix_entries_nr);
>>   dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
>> ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
>>   memset(dev->msix_table, 0, dev->msix_entries_nr *
>> PCI_MSIX_ENTRY_SIZE);
>>   memset(dev->msix_pba, 0, QEMU_ALIGN_UP(dev->msix_entries_nr, 64) /
>> 8);
>> -msix_mask_all(dev, dev->msix_entries_nr);
>> +msix_update_function_masked(dev);
>>   }
>> /* PCI spec suggests that devices make it possible for software to
>> configure
>>
>



[Qemu-devel] [PATCH] msix: don't mask already masked vectors on reset

2017-11-20 Thread Ladi Prosek
msix_mask_all() is supposed to invoke the release vector notifier if the state 
of the
respective vector changed from unmasked or masked. The way it's currently 
called from
msix_reset(), though, may result in calling the release notifier even if the 
vector
is already masked.

1) msix_reset() clears out the msix_cap field and the msix_table.
2) msix_mask_all() runs with was_masked=false for all vectors because of 1), 
which
   results in calling the release notifier on all vectors.
3) if msix_reset() is subsequently called again, it goes through the same steps 
and
   calls the release notifier on all vectors again.

This commit moves msix_mask_all() up so it runs before the device state is 
lost. And
it adds a call to msix_update_function_masked() so that the device remembers 
that
MSI-X is masked.

This is likely a low impact issue, found while debugging an already broken 
device. It
is however easy to fix and the expectation that the use and release notifier 
invocations
are always balanced is very natural.

Signed-off-by: Ladi Prosek 
---
 hw/pci/msix.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index c944c02135..34656de9b0 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -500,11 +500,12 @@ void msix_reset(PCIDevice *dev)
 return;
 }
 msix_clear_all_vectors(dev);
+msix_mask_all(dev, dev->msix_entries_nr);
 dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
 memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
 memset(dev->msix_pba, 0, QEMU_ALIGN_UP(dev->msix_entries_nr, 64) / 8);
-msix_mask_all(dev, dev->msix_entries_nr);
+msix_update_function_masked(dev);
 }
 
 /* PCI spec suggests that devices make it possible for software to configure
-- 
2.13.5




Re: [Qemu-devel] [PATCH v2 0/3] ivshmem: MSI bug fixes

2017-11-20 Thread Ladi Prosek
On Mon, Nov 20, 2017 at 10:07 AM, Ladi Prosek  wrote:
> On Sun, Nov 19, 2017 at 9:39 PM,   wrote:
>> I just updated to the latest build and applied this patch set, now on VM
>> reset the qemu crashes with the following assert:
>>
>> ivshmem.c:467: ivshmem_add_kvm_msi_virq: Assertion
>> `!s->msi_vectors[vector].pdev' failed.
>
> I see asserts too. Even with v1 on top of QEMU v2.10.0 so I must have
> missed something.
>
> Looking. And, needless to say, these patches should not be applied just yet :)

Ok, here goes it.

1)
ivshmem.c:467: ivshmem_add_kvm_msi_virq: Assertion
`!s->msi_vectors[vector].pdev' failed.

Is caused by the ivshmem device not undoing the effects of
ivshmem_enable_irqfd() on reset.

This fix works for me:

--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -758,10 +758,15 @@ static void ivshmem_msix_vector_use(IVShmemState *s)
 }
 }

+
+static void ivshmem_disable_irqfd(IVShmemState *s);
+
 static void ivshmem_reset(DeviceState *d)
 {
 IVShmemState *s = IVSHMEM_COMMON(d);

+ivshmem_disable_irqfd(s);
+
 s->intrstatus = 0;
 s->intrmask = 0;
 if (ivshmem_has_feature(s, IVSHMEM_MSI)) {


2)
ivshmem.c:354: ivshmem_vector_mask: Assertion `v->unmasked' failed.

which I've been also getting after I enabled Driver Verifier and
Windows started crashing
(https://github.com/virtio-win/kvm-guest-drivers-windows/pull/199), is
caused by the MSI-X code masking already masked vectors on reset. I'm
going to post a patch similar to this:

--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -500,11 +500,12 @@ void msix_reset(PCIDevice *dev)
 return;
 }
 msix_clear_all_vectors(dev);
+msix_mask_all(dev, dev->msix_entries_nr);
 dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
 memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
 memset(dev->msix_pba, 0, QEMU_ALIGN_UP(dev->msix_entries_nr, 64) / 8);
-msix_mask_all(dev, dev->msix_entries_nr);
+msix_update_function_masked(dev);
 }


Then either no further changes to this patchset are necessary. Or, if
relying on unmasks/masks (or
msix_vector_use_notifier/msix_vector_release_notifier as it's called
in msix.c) always being balanced is not recommended, the assert will
simply change into an if.

> Thanks!
> Ladi
>
>> On 2017-11-15 18:31, Ladi Prosek wrote:
>>>
>>> Fixes bugs in the ivshmem device implementation uncovered with the new
>>> Windows ivshmem driver:
>>>
>>> https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem
>>>
>>> v1->v2:
>>> * Patch 1 - added reproducer info to commit message (Markus)
>>> * Patch 2 - restructured conditionals, fixed comment formatting (Markus)
>>> * Patch 3 - added reproducer info to commit message (Markus)
>>>
>>> Ladi Prosek (3):
>>>   ivshmem: Don't update non-existent MSI routes
>>>   ivshmem: Always remove irqfd notifiers
>>>   ivshmem: Improve MSI irqfd error handling
>>>
>>>  hw/misc/ivshmem.c | 77
>>> +--
>>>  1 file changed, 58 insertions(+), 19 deletions(-)
>>
>>



Re: [Qemu-devel] [PATCH v2 0/3] ivshmem: MSI bug fixes

2017-11-20 Thread Ladi Prosek
On Sun, Nov 19, 2017 at 9:39 PM,   wrote:
> I just updated to the latest build and applied this patch set, now on VM
> reset the qemu crashes with the following assert:
>
> ivshmem.c:467: ivshmem_add_kvm_msi_virq: Assertion
> `!s->msi_vectors[vector].pdev' failed.

I see asserts too. Even with v1 on top of QEMU v2.10.0 so I must have
missed something.

Looking. And, needless to say, these patches should not be applied just yet :)

Thanks!
Ladi

> On 2017-11-15 18:31, Ladi Prosek wrote:
>>
>> Fixes bugs in the ivshmem device implementation uncovered with the new
>> Windows ivshmem driver:
>>
>> https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem
>>
>> v1->v2:
>> * Patch 1 - added reproducer info to commit message (Markus)
>> * Patch 2 - restructured conditionals, fixed comment formatting (Markus)
>> * Patch 3 - added reproducer info to commit message (Markus)
>>
>> Ladi Prosek (3):
>>   ivshmem: Don't update non-existent MSI routes
>>   ivshmem: Always remove irqfd notifiers
>>   ivshmem: Improve MSI irqfd error handling
>>
>>  hw/misc/ivshmem.c | 77
>> +--
>>  1 file changed, 58 insertions(+), 19 deletions(-)
>
>



[Qemu-devel] [PATCH v2 1/3] ivshmem: Don't update non-existent MSI routes

2017-11-14 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

  kvm_irqchip_commit_routes: Assertion `ret == 0' failed.

if the ivshmem device is configured with more vectors than what the server
supports. This is caused by the ivshmem_vector_unmask() being called on
vectors that have not been initialized by ivshmem_add_kvm_msi_virq().

This commit fixes it by adding a simple check to the mask and unmask
callbacks.

Note that the opposite mismatch, if the server supplies more vectors than
what the device is configured for, is already handled and leads to output
like:

  Too many eventfd received, device has 1 vectors

To reproduce the assert, run:

  ivshmem-server -n 0

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then load the Windows driver, at the time of writing available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

The issue is believed to have been masked by other guest drivers, notably
Linux ones, not enabling MSI-X on the device.

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
Reviewed-by: Marc-André Lureau 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index a5a46827fe..6e46669744 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -317,6 +317,10 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 int ret;
 
 IVSHMEM_DPRINTF("vector unmask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return -EINVAL;
+}
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -331,12 +335,16 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 {
 IVShmemState *s = IVSHMEM_COMMON(dev);
 EventNotifier *n = &s->peers[s->vm_id].eventfds[vector];
+MSIVector *v = &s->msi_vectors[vector];
 int ret;
 
 IVSHMEM_DPRINTF("vector mask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return;
+}
 
-ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n,
-s->msi_vectors[vector].virq);
+ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
 if (ret != 0) {
 error_report("remove_irqfd_notifier_gsi failed");
 }
-- 
2.13.5




[Qemu-devel] [PATCH v2 3/3] ivshmem: Improve MSI irqfd error handling

2017-11-14 Thread Ladi Prosek
Adds a rollback path to ivshmem_enable_irqfd() and fixes
ivshmem_disable_irqfd() to bail if irqfd has not been enabled.

To reproduce, run:

  ivshmem-server -n 0

and QEMU with:

  -device ivshmem-doorbell,chardev=iv
  -chardev socket,path=/tmp/ivshmem_socket,id=iv

then load, unload, and load again the Windows driver, at the time of writing
available at:

https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

The issue is believed to have been masked by other guest drivers, notably
Linux ones, not enabling MSI-X on the device.

Signed-off-by: Ladi Prosek 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 37 -
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 91364d8364..d1bb246d12 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -786,6 +786,20 @@ static int ivshmem_setup_interrupts(IVShmemState *s, Error 
**errp)
 return 0;
 }
 
+static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
+{
+IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
+
+if (s->msi_vectors[vector].pdev == NULL) {
+return;
+}
+
+/* it was cleaned when masked in the frontend. */
+kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
+
+s->msi_vectors[vector].pdev = NULL;
+}
+
 static void ivshmem_enable_irqfd(IVShmemState *s)
 {
 PCIDevice *pdev = PCI_DEVICE(s);
@@ -797,7 +811,7 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
 ivshmem_add_kvm_msi_virq(s, i, &err);
 if (err) {
 error_report_err(err);
-/* TODO do we need to handle the error? */
+goto undo;
 }
 }
 
@@ -806,21 +820,14 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
   ivshmem_vector_mask,
   ivshmem_vector_poll)) {
 error_report("ivshmem: msix_set_vector_notifiers failed");
+goto undo;
 }
-}
+return;
 
-static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
-{
-IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
-
-if (s->msi_vectors[vector].pdev == NULL) {
-return;
+undo:
+while (--i >= 0) {
+ivshmem_remove_kvm_msi_virq(s, i);
 }
-
-/* it was cleaned when masked in the frontend. */
-kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
-
-s->msi_vectors[vector].pdev = NULL;
 }
 
 static void ivshmem_disable_irqfd(IVShmemState *s)
@@ -828,6 +835,10 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
+if (!pdev->msix_vector_use_notifier) {
+return;
+}
+
 msix_unset_vector_notifiers(pdev);
 
 for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-- 
2.13.5




[Qemu-devel] [PATCH v2 0/3] ivshmem: MSI bug fixes

2017-11-14 Thread Ladi Prosek
Fixes bugs in the ivshmem device implementation uncovered with the new
Windows ivshmem driver:
https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

v1->v2:
* Patch 1 - added reproducer info to commit message (Markus)
* Patch 2 - restructured conditionals, fixed comment formatting (Markus)
* Patch 3 - added reproducer info to commit message (Markus)

Ladi Prosek (3):
  ivshmem: Don't update non-existent MSI routes
  ivshmem: Always remove irqfd notifiers
  ivshmem: Improve MSI irqfd error handling

 hw/misc/ivshmem.c | 77 +--
 1 file changed, 58 insertions(+), 19 deletions(-)

-- 
2.13.5




[Qemu-devel] [PATCH v2 2/3] ivshmem: Always remove irqfd notifiers

2017-11-14 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

ivshmem: msix_set_vector_notifiers failed
msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && 
dev->msix_vector_release_notifier' failed.

if MSI-X is repeatedly enabled and disabled on the ivshmem device, for example
by loading and unloading the Windows ivshmem driver. This is because
msix_unset_vector_notifiers() doesn't call any of the release notifier callbacks
since MSI-X is already disabled at that point (msix_enabled() returning false
is how this transition is detected in the first place). Thus 
ivshmem_vector_mask()
doesn't run and when MSI-X is subsequently enabled again ivshmem_vector_unmask()
fails.

This is fixed by keeping track of unmasked vectors and making sure that
ivshmem_vector_mask() always runs on MSI-X disable.

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
Reviewed-by: Markus Armbruster 
---
 hw/misc/ivshmem.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 6e46669744..91364d8364 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -77,6 +77,7 @@ typedef struct Peer {
 typedef struct MSIVector {
 PCIDevice *pdev;
 int virq;
+bool unmasked;
 } MSIVector;
 
 typedef struct IVShmemState {
@@ -321,6 +322,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 error_report("ivshmem: vector %d route does not exist", vector);
 return -EINVAL;
 }
+assert(!v->unmasked);
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -328,7 +330,13 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 }
 kvm_irqchip_commit_routes(kvm_state);
 
-return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+if (ret < 0) {
+return ret;
+}
+v->unmasked = true;
+
+return 0;
 }
 
 static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector)
@@ -343,11 +351,14 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 error_report("ivshmem: vector %d route does not exist", vector);
 return;
 }
+assert(v->unmasked);
 
 ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
-if (ret != 0) {
+if (ret < 0) {
 error_report("remove_irqfd_notifier_gsi failed");
+return;
 }
+v->unmasked = false;
 }
 
 static void ivshmem_vector_poll(PCIDevice *dev,
@@ -817,11 +828,20 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
-for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-ivshmem_remove_kvm_msi_virq(s, i);
-}
-
 msix_unset_vector_notifiers(pdev);
+
+for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
+/*
+ * MSI-X is already disabled here so msix_unset_vector_notifiers()
+ * didn't call our release notifier.  Do it now to keep our masks and
+ * unmasks balanced.
+ */
+if (s->msi_vectors[i].unmasked) {
+ivshmem_vector_mask(pdev, i);
+}
+ivshmem_remove_kvm_msi_virq(s, i);
+}
+
 }
 
 static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
-- 
2.13.5




Re: [Qemu-devel] [PATCH 2/3] ivshmem: Always remove irqfd notifiers

2017-11-13 Thread Ladi Prosek
On Mon, Nov 13, 2017 at 3:36 PM, Markus Armbruster  wrote:
> Ladi Prosek  writes:
>
>> As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
>> QEMU crashes with:
>>
>> ivshmem: msix_set_vector_notifiers failed
>> msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && 
>> dev->msix_vector_release_notifier' failed.
>>
>> if MSI-X is repeatedly enabled and disabled on the ivshmem device, for 
>> example
>> by loading and unloading the Windows ivshmem driver. This is because
>> msix_unset_vector_notifiers() doesn't call any of the release notifier 
>> callbacks
>> since MSI-X is already disabled at that point (msix_enabled() returning false
>> is how this transition is detected in the first place). Thus 
>> ivshmem_vector_mask()
>> doesn't run and when MSI-X is subsequently enabled again 
>> ivshmem_vector_unmask()
>> fails.
>>
>> This is fixed by keeping track of unmasked vectors and making sure that
>> ivshmem_vector_mask() always runs on MSI-X disable.
>>
>> Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
>> Signed-off-by: Ladi Prosek 
>> ---
>>  hw/misc/ivshmem.c | 30 --
>>  1 file changed, 24 insertions(+), 6 deletions(-)
>>
>> diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
>> index 6e46669744..493a5030a1 100644
>> --- a/hw/misc/ivshmem.c
>> +++ b/hw/misc/ivshmem.c
>> @@ -77,6 +77,7 @@ typedef struct Peer {
>>  typedef struct MSIVector {
>>  PCIDevice *pdev;
>>  int virq;
>> +bool unmasked;
>>  } MSIVector;
>>
>>  typedef struct IVShmemState {
>> @@ -321,6 +322,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, 
>> unsigned vector,
>>  error_report("ivshmem: vector %d route does not exist", vector);
>>  return -EINVAL;
>>  }
>> +assert(!v->unmasked);
>>
>>  ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
>>  if (ret < 0) {
>> @@ -328,7 +330,11 @@ static int ivshmem_vector_unmask(PCIDevice *dev, 
>> unsigned vector,
>>  }
>>  kvm_irqchip_commit_routes(kvm_state);
>>
>> -return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
>> +ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
>> +if (ret == 0) {
>> +v->unmasked = true;
>> +}
>> +return ret;
>>  }
>>
>>  static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector)
>> @@ -343,9 +349,12 @@ static void ivshmem_vector_mask(PCIDevice *dev, 
>> unsigned vector)
>>  error_report("ivshmem: vector %d route does not exist", vector);
>>  return;
>>  }
>> +assert(v->unmasked);
>>
>>  ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
>> -if (ret != 0) {
>> +if (ret == 0) {
>> +v->unmasked = false;
>> +} else {
>>  error_report("remove_irqfd_notifier_gsi failed");
>>  }
>>  }
>
> I generally prefer to put the error case in the conditional, and keep
> the normal case out of it, like this:
>
>ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
>if (ret < 0) {
>error_report("remove_irqfd_notifier_gsi failed");
>}
>v->unmasked = false;
>
> However, that makes ivshmem_vector_mask() and ivshmem_vector_unmask()
> even more asymmetric.  Hmm.
>
>> @@ -817,11 +826,20 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
>>  PCIDevice *pdev = PCI_DEVICE(s);
>>  int i;
>>
>> -for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
>> -ivshmem_remove_kvm_msi_virq(s, i);
>> -}
>> -
>>  msix_unset_vector_notifiers(pdev);
>> +
>> +for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
>> +/*
>> + * MSI-X is already disabled here so msix_unset_vector_notifiers
>> + * didn't call our release notifier. Do it now to keep our masks and
>> + * unmasks balanced.
>> + */
>
> For consistency with other comments in this file, put () after the
> function name, and two spaces after the sentence-ending period.
>
>> +if (s->msi_vectors[i].unmasked) {
>> +ivshmem_vector_mask(pdev, i);
>> +}
>> +ivshmem_remove_kvm_msi_virq(s, i);
>> +}
>> +
>>  }
>>
>>  static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
>
> Only nit-picking, so:
> Reviewed-by: Markus Armbruster 

Thank you, I'll address your comments in v2.



Re: [Qemu-devel] [PATCH 1/3] ivshmem: Don't update non-existent MSI routes

2017-11-13 Thread Ladi Prosek
On Mon, Nov 13, 2017 at 3:22 PM, Markus Armbruster  wrote:
> Ladi Prosek  writes:
>
>> As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
>> QEMU crashes with:
>>
>>   kvm_irqchip_commit_routes: Assertion `ret == 0' failed.
>>
>> if the ivshmem device is configured with more vectors than what the server
>> supports. This is caused by the ivshmem_vector_unmask() being called on
>> vectors that have not been initialized by ivshmem_add_kvm_msi_virq().
>>
>> This commit fixes it by adding a simple check to the mask and unmask
>> callbacks.
>>
>> Note that the opposite mismatch, if the server supplies more vectors than
>> what the device is configured for, is already handled and leads to output
>> like:
>>
>>   Too many eventfd received, device has 1 vectors
>>
>> Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
>> Signed-off-by: Ladi Prosek 
>
> I think I understand your description of what's wrong.  Not obvious to
> me is how it can happen.  The cover letter mentions a Windows ivshmem
> driver.  Is this a device bug a driver can trigger?  If yes, how?

I don't have a Linux guest handy but this code has existed for quite a
long time so yes, I think it's safe to assume that it can't be
(easily) triggered by the Linux driver.

The reproducer is as simple as:

ivshmem-server -n 0
qemu ... -device ivshmem-doorbell,chardev=iv -chardev
socket,path=/tmp/ivshmem_socket,id=iv

and load the Windows driver in the guest.

Maybe Linux won't enable MSI-X on the device?

Thanks!
Ladi



Re: [Qemu-devel] [PATCH v2 00/43] Windbg supporting

2017-11-13 Thread Ladi Prosek
On Wed, Nov 8, 2017 at 3:28 PM, Mihail Abakumov
 wrote:
> Ladi Prosek писал 2017-11-08 16:43:
>
>> On Wed, Nov 8, 2017 at 12:54 PM, Mihail Abakumov
>>  wrote:
>>>
>>> Ladi Prosek писал 2017-11-06 18:15:
>>>
>>> In your case windbg does not send packets, more specifically, does not
>>> continue to do it. What is your version of windbg. Also, windbg stub has
>>> been supported only for windbg x64, yet.
>>
>>
>> Ah, so that's a pretty important piece of information and not very
>> intuitive given the "Only i386 is supported now." sentence in the
>> cover email.
>>
>> Microsoft (R) Windows Debugger Version 10.0.15063.468 X86
>> Microsoft (R) Windows Debugger Version 10.0.15063.468 AMD64
>> Microsoft (R) Windows Debugger Version 10.0.16299.15 X86
>> Microsoft (R) Windows Debugger Version 10.0.16299.15 AMD64
>>
>> are the versions I have tried. I don't see any difference between x86
>> and amd64, all versions never connect and crash after the second
>> break.
>>
>> What guest OS are you running? Can you maybe zip up your QEMU binaries
>> and share them with me?
>>
>> Thanks,
>> Ladi
>
>
> Oh, it looks like a problem in the versions. I use the Windbg from Windows
> 7.
> Windbg version: 6.12.0002.633 AMD64. I will try to test with your version.

Looks like it's the -b switch making the difference here. It was
removed in later versions of windbg.


Windbg docs (older):

-b
(Kernel mode only) This option has two effects:
1. The debugger will break into the target computer immediately upon connection.

2. After a reboot, the debugger will break into the target computer
once the kernel is initialized. See Crashing and Rebooting the Target
Computer for details and for other methods of changing this status.


Windbg docs (newer):

-b
This option is no longer supported.


-b makes windbg send a break-in right after connecting. Apparently
there is a short time window when the break-in will work. I can
actually successfully connect with a Win10 windbg (so without -b) if I
hit Ctrl+Break shortly after the initial handshake. This also explains
why I was able to connect once during my initial testing. I was just
lucky and hit Ctrl+Break soon enough after connecting.

By initial handshake I mean this sequence (I have added a simple
logging, should be clear what it means):

Received control PACKET_TYPE_KD_RESET
Sending data 7
Sending control 6

Newer debuggers without -b will stop here. Older debuggers with -b
will continue with:

Received RESULT_BREAKIN_BYTE
Sending data 7
Received RESULT_BREAKIN_BYTE
Sending data 7
Received data PACKET_TYPE_KD_STATE_MANIPULATE (12614)
Sending control 4
Sending data 2
Received data PACKET_TYPE_KD_STATE_MANIPULATE (12592)
Sending control 4
Sending data 2
Received data PACKET_TYPE_KD_STATE_MANIPULATE (12592)
Sending control 4
Sending data 2
...


Next step, when I have time, is to find the differences between
sending the break-in early and sending it later. Also interesting
would be recording the exchange between windbg and the target when
doing regular remote kernel debugging. I would still expect to see the
"Connected to Windows 7 7601 x86 compatible target ..." output always,
even when not breaking in immediately. The handshake is likely still
missing something.

Thanks,
Ladi



[Qemu-devel] [PATCH v2] virtio-pci: Don't force Subsystem Vendor ID = Vendor ID

2017-11-13 Thread Ladi Prosek
The statement being removed doesn't change anything as virtio PCI devices 
already
have Subsystem Vendor ID set to pci_default_sub_vendor_id (0x1af4), same as 
Vendor
ID. And the Virtio spec does not require the two to be equal, either:

  "The PCI Subsystem Vendor ID and the PCI Subsystem Device ID MAY reflect the 
PCI
  Vendor and Device ID of the environment (for informational purposes by the 
driver)."

Background:

Following the recent virtio-win licensing change, several vendors are planning 
to
ship their own certified version of Windows guest Virtio drivers, potentially 
taking
advantage of Windows Update as a distribution channel. It is therefore critical 
that
each vendor uses their own PCI Subsystem Vendor ID for Virtio devices to prevent
drivers from other vendors binding to it.

This would be trivially done by adding:

  k->subsystem_vendor_id = ...

to virtio_pci_class_init(). Except for the problematic statement deleted by this
patch, which reverts the Subsystem Vendor ID back to 0x1af4 for legacy devices 
for
no good reason.

Signed-off-by: Ladi Prosek 
---

v1->v2:
* Added a comment about the default Subsystem Vendor ID.


 hw/virtio/virtio-pci.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e92837c42b..148621d9c7 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1588,9 +1588,11 @@ static void virtio_pci_device_plugged(DeviceState *d, 
Error **errp)
"neither legacy nor transitional device.");
 return ;
 }
-/* legacy and transitional */
-pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
- pci_get_word(config + PCI_VENDOR_ID));
+/*
+ * Legacy and transitional devices use specific subsystem IDs.
+ * Note that the subsystem vendor ID (config + PCI_SUBSYSTEM_VENDOR_ID)
+ * is set to PCI_SUBVENDOR_ID_REDHAT_QUMRANET by default.
+ */
 pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
 } else {
 /* pure virtio-1.0 */
-- 
2.13.5




[Qemu-devel] [PATCH 2/3] ivshmem: Always remove irqfd notifiers

2017-11-10 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

ivshmem: msix_set_vector_notifiers failed
msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && 
dev->msix_vector_release_notifier' failed.

if MSI-X is repeatedly enabled and disabled on the ivshmem device, for example
by loading and unloading the Windows ivshmem driver. This is because
msix_unset_vector_notifiers() doesn't call any of the release notifier callbacks
since MSI-X is already disabled at that point (msix_enabled() returning false
is how this transition is detected in the first place). Thus 
ivshmem_vector_mask()
doesn't run and when MSI-X is subsequently enabled again ivshmem_vector_unmask()
fails.

This is fixed by keeping track of unmasked vectors and making sure that
ivshmem_vector_mask() always runs on MSI-X disable.

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
---
 hw/misc/ivshmem.c | 30 --
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 6e46669744..493a5030a1 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -77,6 +77,7 @@ typedef struct Peer {
 typedef struct MSIVector {
 PCIDevice *pdev;
 int virq;
+bool unmasked;
 } MSIVector;
 
 typedef struct IVShmemState {
@@ -321,6 +322,7 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 error_report("ivshmem: vector %d route does not exist", vector);
 return -EINVAL;
 }
+assert(!v->unmasked);
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -328,7 +330,11 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 }
 kvm_irqchip_commit_routes(kvm_state);
 
-return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+ret = kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, v->virq);
+if (ret == 0) {
+v->unmasked = true;
+}
+return ret;
 }
 
 static void ivshmem_vector_mask(PCIDevice *dev, unsigned vector)
@@ -343,9 +349,12 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 error_report("ivshmem: vector %d route does not exist", vector);
 return;
 }
+assert(v->unmasked);
 
 ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
-if (ret != 0) {
+if (ret == 0) {
+v->unmasked = false;
+} else {
 error_report("remove_irqfd_notifier_gsi failed");
 }
 }
@@ -817,11 +826,20 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
-for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-ivshmem_remove_kvm_msi_virq(s, i);
-}
-
 msix_unset_vector_notifiers(pdev);
+
+for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
+/*
+ * MSI-X is already disabled here so msix_unset_vector_notifiers
+ * didn't call our release notifier. Do it now to keep our masks and
+ * unmasks balanced.
+ */
+if (s->msi_vectors[i].unmasked) {
+ivshmem_vector_mask(pdev, i);
+}
+ivshmem_remove_kvm_msi_virq(s, i);
+}
+
 }
 
 static void ivshmem_write_config(PCIDevice *pdev, uint32_t address,
-- 
2.13.5




[Qemu-devel] [PATCH 3/3] ivshmem: Improve MSI irqfd error handling

2017-11-10 Thread Ladi Prosek
Adds a rollback path to ivshmem_enable_irqfd() and fixes
ivshmem_disable_irqfd() to bail if irqfd has not been enabled.

Signed-off-by: Ladi Prosek 
---
 hw/misc/ivshmem.c | 37 -
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 493a5030a1..ff07a94691 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -784,6 +784,20 @@ static int ivshmem_setup_interrupts(IVShmemState *s, Error 
**errp)
 return 0;
 }
 
+static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
+{
+IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
+
+if (s->msi_vectors[vector].pdev == NULL) {
+return;
+}
+
+/* it was cleaned when masked in the frontend. */
+kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
+
+s->msi_vectors[vector].pdev = NULL;
+}
+
 static void ivshmem_enable_irqfd(IVShmemState *s)
 {
 PCIDevice *pdev = PCI_DEVICE(s);
@@ -795,7 +809,7 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
 ivshmem_add_kvm_msi_virq(s, i, &err);
 if (err) {
 error_report_err(err);
-/* TODO do we need to handle the error? */
+goto undo;
 }
 }
 
@@ -804,21 +818,14 @@ static void ivshmem_enable_irqfd(IVShmemState *s)
   ivshmem_vector_mask,
   ivshmem_vector_poll)) {
 error_report("ivshmem: msix_set_vector_notifiers failed");
+goto undo;
 }
-}
+return;
 
-static void ivshmem_remove_kvm_msi_virq(IVShmemState *s, int vector)
-{
-IVSHMEM_DPRINTF("ivshmem_remove_kvm_msi_virq vector:%d\n", vector);
-
-if (s->msi_vectors[vector].pdev == NULL) {
-return;
+undo:
+while (--i >= 0) {
+ivshmem_remove_kvm_msi_virq(s, i);
 }
-
-/* it was cleaned when masked in the frontend. */
-kvm_irqchip_release_virq(kvm_state, s->msi_vectors[vector].virq);
-
-s->msi_vectors[vector].pdev = NULL;
 }
 
 static void ivshmem_disable_irqfd(IVShmemState *s)
@@ -826,6 +833,10 @@ static void ivshmem_disable_irqfd(IVShmemState *s)
 PCIDevice *pdev = PCI_DEVICE(s);
 int i;
 
+if (!pdev->msix_vector_use_notifier) {
+return;
+}
+
 msix_unset_vector_notifiers(pdev);
 
 for (i = 0; i < s->peers[s->vm_id].nb_eventfds; i++) {
-- 
2.13.5




[Qemu-devel] [PATCH 0/3] ivshmem: MSI bug fixes

2017-11-10 Thread Ladi Prosek
Fixes bugs in the ivshmem device implementation uncovered with the new
Windows ivshmem driver:
https://github.com/virtio-win/kvm-guest-drivers-windows/tree/master/ivshmem

Ladi Prosek (3):
  ivshmem: Don't update non-existent MSI routes
  ivshmem: Always remove irqfd notifiers
  ivshmem: Improve MSI irqfd error handling

 hw/misc/ivshmem.c | 75 +--
 1 file changed, 56 insertions(+), 19 deletions(-)

-- 
2.13.5




[Qemu-devel] [PATCH 1/3] ivshmem: Don't update non-existent MSI routes

2017-11-10 Thread Ladi Prosek
As of commit 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications"),
QEMU crashes with:

  kvm_irqchip_commit_routes: Assertion `ret == 0' failed.

if the ivshmem device is configured with more vectors than what the server
supports. This is caused by the ivshmem_vector_unmask() being called on
vectors that have not been initialized by ivshmem_add_kvm_msi_virq().

This commit fixes it by adding a simple check to the mask and unmask
callbacks.

Note that the opposite mismatch, if the server supplies more vectors than
what the device is configured for, is already handled and leads to output
like:

  Too many eventfd received, device has 1 vectors

Fixes: 660c97eef6f8 ("ivshmem: use kvm irqfd for msi notifications")
Signed-off-by: Ladi Prosek 
---
 hw/misc/ivshmem.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index a5a46827fe..6e46669744 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -317,6 +317,10 @@ static int ivshmem_vector_unmask(PCIDevice *dev, unsigned 
vector,
 int ret;
 
 IVSHMEM_DPRINTF("vector unmask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return -EINVAL;
+}
 
 ret = kvm_irqchip_update_msi_route(kvm_state, v->virq, msg, dev);
 if (ret < 0) {
@@ -331,12 +335,16 @@ static void ivshmem_vector_mask(PCIDevice *dev, unsigned 
vector)
 {
 IVShmemState *s = IVSHMEM_COMMON(dev);
 EventNotifier *n = &s->peers[s->vm_id].eventfds[vector];
+MSIVector *v = &s->msi_vectors[vector];
 int ret;
 
 IVSHMEM_DPRINTF("vector mask %p %d\n", dev, vector);
+if (!v->pdev) {
+error_report("ivshmem: vector %d route does not exist", vector);
+return;
+}
 
-ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n,
-s->msi_vectors[vector].virq);
+ret = kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, n, v->virq);
 if (ret != 0) {
 error_report("remove_irqfd_notifier_gsi failed");
 }
-- 
2.13.5




Re: [Qemu-devel] [PATCH v2 00/43] Windbg supporting

2017-11-08 Thread Ladi Prosek
On Wed, Nov 8, 2017 at 12:54 PM, Mihail Abakumov
 wrote:
> Ladi Prosek писал 2017-11-06 18:15:
>
>> On Mon, Oct 23, 2017 at 10:31 AM, Ladi Prosek  wrote:
>>>
>>> On Tue, Oct 17, 2017 at 3:08 PM, Mihail Abakumov
>>>  wrote:
>>>>
>>>> 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 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)
>>>
>>>
>>> Thank you, I am planning to take a closer look and test the changes in
>>> a week or two.
>>>
>>> Still wondering if it is limited to Windows hosts or if it can be used
>>> on Linux as well, preferably with KVM.
>>
>>
>> I haven't been able to make this work.
>>
>> I've built a 32-bit QEMU for Windows with these patches and used the
>> command line parameters given above:
>>
>>   qemu-system-i386.exe run with -windbg pipe:win7_dbg
>>   windbg -b -k com:pipe,baud=115200,port=\\.\pipe\win7_dbg,resets=0
>>
>> The guest is a fresh install of Win7 32-bit.
>>
>> FS base passes all the checks in windbg_on_load() as the guest kernel
>> loads and it returns true. QEMU then sends some data over t

Re: [Qemu-devel] [PATCH] virtio-pci: Don't force Subsystem Vendor ID = Vendor ID

2017-11-07 Thread Ladi Prosek
On Mon, Nov 6, 2017 at 5:51 PM, Michael S. Tsirkin  wrote:
> On Mon, Nov 06, 2017 at 10:02:54AM +0100, Ladi Prosek wrote:
>> On Fri, Nov 3, 2017 at 4:11 PM, Michael S. Tsirkin  wrote:
>> > On Fri, Nov 03, 2017 at 09:23:07AM +0100, Ladi Prosek wrote:
>> >> On Fri, Nov 3, 2017 at 8:20 AM, Gerd Hoffmann  wrote:
>> >> >
>> >> >> > > Signed-off-by: Ladi Prosek 
>> >> >> >
>> >> >> > I wonder whether it's a problem that legacy devices ignore
>> >> >> > the subsystem ID (that's part of spec).
>> >> >>
>> >> >> I don't understand this comment. I don't see anything in the spec
>> >> >> related to ignoring the subsystem ID.
>> >> >
>> >> > Well, the subsystem *device* id is defined to be the virtio device id,
>> >> > so it is certainly not ignored.  The subsystem *vendor* id is not used
>> >> > as far I know (or ignored in the sense that it doesn't change driver
>> >> > behavior), allowing to set that makes sense to me.
>> >>
>> >> Yes, thanks, I'm assuming that Michael meant the subsystem device ID.
>> >> The PCI spec seems to be using "subsystem ID" for the name of this
>> >> field.
>> >
>> > Exactly.
>> >
>> >> I understand that this ID must not change in legacy devices.
>> >
>> > Interestingly the device ID is ignored except it must be within
>> > a specific range of values.
>> >
>> >> Interestingly, Windows appears to allow matching drivers only on the
>> >> full subsystem device ID + subsystem vendor ID 32-bit value, not on
>> >> only one of the two.
>> >>
>> >> PCI\VEN_v(4)&DEV_d(4)&SUBSYS_s(4)n(4)&REV_r(2)
>> >>
>> >> This might be a potential problem for a legacy driver that wants to
>> >> stay vendor-agnostic but I'm pretty sure there would be a reasonable
>> >> way of working around it. Actually, the device must use a designated
>> >> device ID (like 0x1000) in addition to the subsystem device ID so this
>> >> should be a non-issue altogether.
>> >
>> > The original virtio spec wasn't really workable for windows. It requires
>> > ignoring everything except the vendor ID, *range* of device IDs
>> > (specific ID is ignored) and subsystem ID.
>>
>> The original spec has been superseded though, no? The current spec
>> prescribes fixed device IDs for transitional devices (4.1.2.1 Device
>> Requirements: PCI Device Discovery).
>
> I agree, it's reasonable to ignore this part in the old spec.
>
>
>> > So in my humble opinion the right thing for people to do is simply to
>> > avoid legacy devices. Is something preventing that?
>>
>> The same reasons why the concept of transitional devices exists at all?
>
> It's there to support old drivers. If you are changing vendor id
> that is supposedly so you can ship new drivers.

That's true. And for Windows guests specifically we know that the
license change happened long after modern Virtio was implemented and
stabilized so vendors should be able to eliminate legacy Virtio.

I can imagine that it will still be more common to expose transitional
devices for some time, though. Like in all kinds of cloud set ups
where it's maybe not practical to change the configuration of virtual
devices based on the guest OS and maximum compatibility outweighs the
advantages of modern Virtio.

>> Anyway, I'm not quite sure why we're spending so much time discussing
>> this. The spec says "subsystem vendor MAY change". QEMU has this
>> unfortunate statement which makes it not as straightforward as it
>> should be. Removing the statement has zero impact on QEMU behavior. So
>> we either remove it now or whoever actually needs to change the
>> subsystem vendor ID will do it.
>
> I am fine with your patch as such, but I just realized that anyone
> tweaking subsystem vendor id in the past will get a different value now.
>
> Worth worrying about or do we need to make it depend on
> a machine type?

If subsystem vendor ID could be tweaked without a code change, then
yes, we wouldn't want to break anyone. But private code changes have
the inherent risk of being broken by upstream changes; I'd say we
shouldn't worry about that.

>> >> > Possibly not only for virtio devices, most pci devices have 1af4:1100
>> >> > as subsystem id, other vendors might want set it too for consistency.
>> >> >
>> >> > cheers,
>> >> >   Gerd



Re: [Qemu-devel] [PATCH v2 00/43] Windbg supporting

2017-11-07 Thread Ladi Prosek
On Mon, Nov 6, 2017 at 7:41 PM, Andrew Baumann
 wrote:
> Hi,
>
> I just noticed this thread, and the problem sounded very familiar...
>
>> From: Ladi Prosek
>> Sent: Monday, 6 November 2017 07:16
> [...]
>> FS base passes all the checks in windbg_on_load() as the guest kernel
>> loads and it returns true. QEMU then sends some data over the pipe.
>> Windbg doesn't print anything, it's still showing:
>>
>>   Opened \\.\pipe\win7_dbg
>>   Waiting to reconnect...
>>
>> Is this expected? In regular remote kernel debugging, windbg produces
>> a bunch of output about the target state when it attaches.
>
> Just a guess, but I suspect the problem you're seeing may be due to the 
> combination of windbg's tight timing requirements for the serial debug 
> protocol and qemu's polling-based implementation of named pipe IO. I ran into 
> this a year or two ago when bringing up raspberry pi... I could never 
> reliably connect windbg to the emulated serial port using a named pipe. I 
> believe the problem is that the named pipe driver relies on receiving input 
> through win_chr_pipe_poll(), which is called too infrequently to satisfy 
> windbg's needs (it has a rather short timeout before it gives up and 
> retransmits). The correct fix is to use blocking IO for the named pipes 
> inside qemu, but I know from experience that win32 is awful in this respect 
> -- qemu wants a single unified blocking call to wait for IO on any 
> combination of named pipes, sockets, events, etc. and Windows appears to lack 
> this, at least at the level of poll/select.

Thanks, I don't usually set up windbg remote debugging over named
pipes so this indeed sounded plausible.

My Windows runs in a QEMU/KVM VM so to eliminate the pipe I have set
up a virtual COM port like so:

-serial tcp:127.0.0.1:8889,server,nowait

and the nested QEMU ran with:

-windbg tcp:10.0.2.2:8889

where 10.0.2.2 is the address assigned to the host with user
networking. Windbg then used the default COM1 to connect to the
target. I routinely use COMx for remote debugging between VMs with a
TCP connection on the host side acting as a null-modem cable and never
had any timing related issues.

However, the symptoms were exactly the same with this set up.

I've also run the original command lines using a pipe on a physical
Windows machine, just in case being in a VM somehow screws it up.
Again, same issue.

At this point I think it would make sense for Mihai to take a look at
the trace in my previous email and maybe compare it with what works
for him.

For completeness, in the unlikely case that it makes a difference, I'm
on Win10 (tried 1511 and 1703) and use windbg that comes with one of
the latest WDK.

Thanks!
Ladi

> My workaround at the time was to kludge up a proxy between sockets and named 
> pipes, so the connection was:
> qemu <-socket-> proxy <-named pipe-> windbg
>
> (The proxy was a fairly flaky python script, but it was good enough to tide 
> me over until I could get kdnet working. I can probably dig it out if you're 
> interested.)
>
> Cheers,
> Andrew



Re: [Qemu-devel] [PATCH v2 00/43] Windbg supporting

2017-11-06 Thread Ladi Prosek
On Mon, Oct 23, 2017 at 10:31 AM, Ladi Prosek  wrote:
> On Tue, Oct 17, 2017 at 3:08 PM, Mihail Abakumov
>  wrote:
>> 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 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)
>
> Thank you, I am planning to take a closer look and test the changes in
> a week or two.
>
> Still wondering if it is limited to Windows hosts or if it can be used
> on Linux as well, preferably with KVM.

I haven't been able to make this work.

I've built a 32-bit QEMU for Windows with these patches and used the
command line parameters given above:

  qemu-system-i386.exe run with -windbg pipe:win7_dbg
  windbg -b -k com:pipe,baud=115200,port=\\.\pipe\win7_dbg,resets=0

The guest is a fresh install of Win7 32-bit.

FS base passes all the checks in windbg_on_load() as the guest kernel
loads and it returns true. QEMU then sends some data over the pipe.
Windbg doesn't print anything, it's still showing:

  Opened \\.\pipe\win7_dbg
  Waiting to reconnect...

Is this expected? In regular remote kernel debugging, windbg produces
a bunch of output about the target state when it attaches.

The only thing I can reasonably do at this point is Ctrl+Break. This
results in some data exchange between QEMU and windbg but nothing
really changes -- windbg still says "Waiting to reconnect...". Hitting
Ctrl+Break for the second time kills windbg. I tried running windbg
under windbg and was able to capture this output:

  Debug target initialization failed, 0x8000

Once I managed to make windbg actually attach (i.e. it generated the
target state output) but the QEMU process died shortly after that. I
don't know why because I haven't been able 

Re: [Qemu-devel] [PATCH] virtio-pci: Don't force Subsystem Vendor ID = Vendor ID

2017-11-06 Thread Ladi Prosek
On Fri, Nov 3, 2017 at 4:11 PM, Michael S. Tsirkin  wrote:
> On Fri, Nov 03, 2017 at 09:23:07AM +0100, Ladi Prosek wrote:
>> On Fri, Nov 3, 2017 at 8:20 AM, Gerd Hoffmann  wrote:
>> >
>> >> > > Signed-off-by: Ladi Prosek 
>> >> >
>> >> > I wonder whether it's a problem that legacy devices ignore
>> >> > the subsystem ID (that's part of spec).
>> >>
>> >> I don't understand this comment. I don't see anything in the spec
>> >> related to ignoring the subsystem ID.
>> >
>> > Well, the subsystem *device* id is defined to be the virtio device id,
>> > so it is certainly not ignored.  The subsystem *vendor* id is not used
>> > as far I know (or ignored in the sense that it doesn't change driver
>> > behavior), allowing to set that makes sense to me.
>>
>> Yes, thanks, I'm assuming that Michael meant the subsystem device ID.
>> The PCI spec seems to be using "subsystem ID" for the name of this
>> field.
>
> Exactly.
>
>> I understand that this ID must not change in legacy devices.
>
> Interestingly the device ID is ignored except it must be within
> a specific range of values.
>
>> Interestingly, Windows appears to allow matching drivers only on the
>> full subsystem device ID + subsystem vendor ID 32-bit value, not on
>> only one of the two.
>>
>> PCI\VEN_v(4)&DEV_d(4)&SUBSYS_s(4)n(4)&REV_r(2)
>>
>> This might be a potential problem for a legacy driver that wants to
>> stay vendor-agnostic but I'm pretty sure there would be a reasonable
>> way of working around it. Actually, the device must use a designated
>> device ID (like 0x1000) in addition to the subsystem device ID so this
>> should be a non-issue altogether.
>
> The original virtio spec wasn't really workable for windows. It requires
> ignoring everything except the vendor ID, *range* of device IDs
> (specific ID is ignored) and subsystem ID.

The original spec has been superseded though, no? The current spec
prescribes fixed device IDs for transitional devices (4.1.2.1 Device
Requirements: PCI Device Discovery).

> So in my humble opinion the right thing for people to do is simply to
> avoid legacy devices. Is something preventing that?

The same reasons why the concept of transitional devices exists at all?

Anyway, I'm not quite sure why we're spending so much time discussing
this. The spec says "subsystem vendor MAY change". QEMU has this
unfortunate statement which makes it not as straightforward as it
should be. Removing the statement has zero impact on QEMU behavior. So
we either remove it now or whoever actually needs to change the
subsystem vendor ID will do it.

>> > Possibly not only for virtio devices, most pci devices have 1af4:1100
>> > as subsystem id, other vendors might want set it too for consistency.
>> >
>> > cheers,
>> >   Gerd



Re: [Qemu-devel] [PATCH] virtio-pci: Don't force Subsystem Vendor ID = Vendor ID

2017-11-03 Thread Ladi Prosek
On Fri, Nov 3, 2017 at 8:20 AM, Gerd Hoffmann  wrote:
>
>> > > Signed-off-by: Ladi Prosek 
>> >
>> > I wonder whether it's a problem that legacy devices ignore
>> > the subsystem ID (that's part of spec).
>>
>> I don't understand this comment. I don't see anything in the spec
>> related to ignoring the subsystem ID.
>
> Well, the subsystem *device* id is defined to be the virtio device id,
> so it is certainly not ignored.  The subsystem *vendor* id is not used
> as far I know (or ignored in the sense that it doesn't change driver
> behavior), allowing to set that makes sense to me.

Yes, thanks, I'm assuming that Michael meant the subsystem device ID.
The PCI spec seems to be using "subsystem ID" for the name of this
field. I understand that this ID must not change in legacy devices.

Interestingly, Windows appears to allow matching drivers only on the
full subsystem device ID + subsystem vendor ID 32-bit value, not on
only one of the two.

PCI\VEN_v(4)&DEV_d(4)&SUBSYS_s(4)n(4)&REV_r(2)

This might be a potential problem for a legacy driver that wants to
stay vendor-agnostic but I'm pretty sure there would be a reasonable
way of working around it. Actually, the device must use a designated
device ID (like 0x1000) in addition to the subsystem device ID so this
should be a non-issue altogether.

> Possibly not only for virtio devices, most pci devices have 1af4:1100
> as subsystem id, other vendors might want set it too for consistency.
>
> cheers,
>   Gerd



Re: [Qemu-devel] [PATCH] virtio-pci: Don't force Subsystem Vendor ID = Vendor ID

2017-11-02 Thread Ladi Prosek
On Thu, Nov 2, 2017 at 3:52 PM, Michael S. Tsirkin  wrote:
> On Thu, Nov 02, 2017 at 02:31:15PM +0100, Ladi Prosek wrote:
>> The statement being removed doesn't change anything as virtio PCI devices 
>> already
>> have Subsystem Vendor ID set to pci_default_sub_vendor_id (0x1af4), same as 
>> Vendor
>> ID. And the Virtio spec does not require the two to be equal, either:
>>
>>   "The PCI Subsystem Vendor ID and the PCI Subsystem Device ID MAY reflect 
>> the PCI
>>   Vendor and Device ID of the environment (for informational purposes by the 
>> driver)."
>>
>> Background:
>>
>> Following the recent virtio-win licensing change, several vendors are 
>> planning to
>> ship their own certified version of Windows guest Virtio drivers, 
>> potentially taking
>> advantage of Windows Update as a distribution channel. It is therefore 
>> critical that
>> each vendor uses their own PCI Subsystem Vendor ID for Virtio devices to 
>> prevent
>> drivers from other vendors binding to it.
>>
>> This would be trivially done by adding:
>>
>>   k->subsystem_vendor_id = ...
>>
>> to virtio_pci_class_init(). Except for the problematic statement deleted by 
>> this
>> patch, which reverts the Subsystem Vendor ID back to 0x1af4 for legacy 
>> devices for
>> no good reason.
>>
>> Signed-off-by: Ladi Prosek 
>
> I wonder whether it's a problem that legacy devices ignore
> the subsystem ID (that's part of spec).

I don't understand this comment. I don't see anything in the spec
related to ignoring the subsystem ID.

>> ---
>>  hw/virtio/virtio-pci.c | 2 --
>>  1 file changed, 2 deletions(-)
>>
>> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
>> index e92837c42b..cb74aa3d85 100644
>> --- a/hw/virtio/virtio-pci.c
>> +++ b/hw/virtio/virtio-pci.c
>> @@ -1589,8 +1589,6 @@ static void virtio_pci_device_plugged(DeviceState *d, 
>> Error **errp)
>>  return ;
>>  }
>>  /* legacy and transitional */
>> -pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
>> - pci_get_word(config + PCI_VENDOR_ID));
>
>
> This happens to work because the default subsystem vendor id
> within qemu is 0x1af4. Let's add a comment to that end.

Sure, will do.

>>  pci_set_word(config + PCI_SUBSYSTEM_ID, 
>> virtio_bus_get_vdev_id(bus));
>>  } else {
>>  /* pure virtio-1.0 */
>> --
>> 2.13.5



[Qemu-devel] [PATCH] virtio-pci: Don't force Subsystem Vendor ID = Vendor ID

2017-11-02 Thread Ladi Prosek
The statement being removed doesn't change anything as virtio PCI devices 
already
have Subsystem Vendor ID set to pci_default_sub_vendor_id (0x1af4), same as 
Vendor
ID. And the Virtio spec does not require the two to be equal, either:

  "The PCI Subsystem Vendor ID and the PCI Subsystem Device ID MAY reflect the 
PCI
  Vendor and Device ID of the environment (for informational purposes by the 
driver)."

Background:

Following the recent virtio-win licensing change, several vendors are planning 
to
ship their own certified version of Windows guest Virtio drivers, potentially 
taking
advantage of Windows Update as a distribution channel. It is therefore critical 
that
each vendor uses their own PCI Subsystem Vendor ID for Virtio devices to prevent
drivers from other vendors binding to it.

This would be trivially done by adding:

  k->subsystem_vendor_id = ...

to virtio_pci_class_init(). Except for the problematic statement deleted by this
patch, which reverts the Subsystem Vendor ID back to 0x1af4 for legacy devices 
for
no good reason.

Signed-off-by: Ladi Prosek 
---
 hw/virtio/virtio-pci.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e92837c42b..cb74aa3d85 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1589,8 +1589,6 @@ static void virtio_pci_device_plugged(DeviceState *d, 
Error **errp)
 return ;
 }
 /* legacy and transitional */
-pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
- pci_get_word(config + PCI_VENDOR_ID));
 pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
 } else {
 /* pure virtio-1.0 */
-- 
2.13.5




Re: [Qemu-devel] [PATCH v2 00/43] Windbg supporting

2017-10-23 Thread Ladi Prosek
On Tue, Oct 17, 2017 at 3:08 PM, Mihail Abakumov
 wrote:
> 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 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)

Thank you, I am planning to take a closer look and test the changes in
a week or two.

Still wondering if it is limited to Windows hosts or if it can be used
on Linux as well, preferably with KVM.

Thanks!
Ladi

> ---
>
> Mihail Abakumov (43):
>   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: sized data buffer
>   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: imp

Re: [Qemu-devel] ivshmem Windows Driver

2017-10-19 Thread Ladi Prosek
On Thu, Oct 19, 2017 at 11:41 AM,   wrote:
> On 2017-10-19 20:07, ge...@hostfission.com wrote:
>>
>> On 2017-10-19 20:01, Ladi Prosek wrote:
>>>
>>> On Thu, Oct 19, 2017 at 10:44 AM,   wrote:
>>>>
>>>> On 2017-10-19 19:35, Ladi Prosek wrote:
>>>>>
>>>>>
>>>>> On Wed, Oct 18, 2017 at 5:04 PM,   wrote:
>>>>>>
>>>>>>
>>>>>> Hi Ladi & Yan,
>>>>>>
>>>>>> I am pleased to present the completed driver for review, please see:
>>>>>>
>>>>>> https://github.com/gnif/kvm-guest-drivers-windows
>>>>>
>>>>>
>>>>>
>>>>> Awesome!
>>>>>
>>>>> Feel free to open pull request, it should be easier to comment on.
>>>>
>>>>
>>>>
>>>> Great, I will do so after I have addressed the below. Thanks again.
>>>>
>
> I have created a PR, see:
>
> https://github.com/virtio-win/kvm-guest-drivers-windows/pull/174
>
>>>>>
>>>>> * WoW considerations: It would be nice if the driver could detect that
>>>>> the map request is coming from a 32-bit process and expect a different
>>>>> layout of struct IVSHMEM_MMAP.
>>>>
>>>>
>>>>
>>>> I did think of this but I am unsure as to how to detect this.
>>>
>>>
>>> I don't think I ever used it but IoIs32bitProcess() looks promising.
>>>
>
>
> Obviously PVOID will be 32bit which will mess with the struct size and
> offset of vectors but I am not aware of a solution to this. If you have
> any suggestions on how to rectify this it would be very much appreciated.

I was thinking something simple like:

#ifdef _WIN64
typedef struct IVSHMEM_MMAP_32
{
...
UINT32 ptr;
...
}
IVSHMEM_MMAP_32, *PIVSHMEM_MMAP_32;
#endif

in a private header. Then in the IOCTL handler call IoIs32bitProcess()
and if it returns true, expect IVSHMEM_MMAP_32 instead of
IVSHMEM_MMAP.

>>>>>
>>>>> * It would be cleaner to use READ_REGISTER_* and WRITE_REGISTER_*
>>>>> from/to IVSHMEMDeviceRegisters instead of plain memory accesses. Or at
>>>>> the very least the accesses should be marked volatile.
>>>>
>>>>
>>>>
>>>> I thought that mapping the IO space was enough for this since it is
>>>> mapped as non-cacheable. I can see the point of marking it volatile but
>>>> see no need to use the read/write register semantics. If this is what it
>>>> takes however I am happy to do so.
>>>
>>>
>>> Code like this raises eyebrows:
>>>
>>>   deviceContext->devRegisters->doorbell |= (UINT32)in->vector |
>>> (in->peerID << 16);
>>>
>>> Many readers will probably be wondering what exactly the compiler is
>>> allowed to do with this statement. May it end up ORing the lower and
>>> upper word separately, for example?
>>>
>>>   OR [word ptr addr], in->vector
>>>   OR [word ptr addr + 2], in->peerID
>>>
>>> And, by the way, is OR really what we want here?
>>>
>>
>> After double checking this you are dead right, the register is documented
>> as write only. I will fix this.
>
>
> Done.
>
>
>>
>>>>>
>>>>> * In ivshmem.inf: ManufacturerName="Red Hat, Inc." instead of "RedHat"
>>>>>
>>>>
>>>> No worries.
>>>>
>>>>> * Is any of the API used by the driver Win10-only? Just curious, it's
>>>>> fine to build the driver only for Win10 for now even if it isn't.
>>>>
>>>>
>>>>
>>>> I have not tried to build it on anything older then win 10 build 10586
>>>> as I have nothing older, but AFAIK it should build on windows 8.1 or
>>>> later just fine. This is more due to my lack of familiarity with Visual
>>>> Studio, give me gcc and vim any day :).
>>>
>>>
>>> Gotcha, no worries, other versions can be tested later.
>
>



Re: [Qemu-devel] ivshmem Windows Driver

2017-10-19 Thread Ladi Prosek
On Thu, Oct 19, 2017 at 10:44 AM,   wrote:
> On 2017-10-19 19:35, Ladi Prosek wrote:
>>
>> On Wed, Oct 18, 2017 at 5:04 PM,   wrote:
>>>
>>> Hi Ladi & Yan,
>>>
>>> I am pleased to present the completed driver for review, please see:
>>>
>>> https://github.com/gnif/kvm-guest-drivers-windows
>>
>>
>> Awesome!
>>
>> Feel free to open pull request, it should be easier to comment on.
>
>
> Great, I will do so after I have addressed the below. Thanks again.
>
>>
>> * WoW considerations: It would be nice if the driver could detect that
>> the map request is coming from a 32-bit process and expect a different
>> layout of struct IVSHMEM_MMAP.
>
>
> I did think of this but I am unsure as to how to detect this.

I don't think I ever used it but IoIs32bitProcess() looks promising.

>>
>> * It would be cleaner to use READ_REGISTER_* and WRITE_REGISTER_*
>> from/to IVSHMEMDeviceRegisters instead of plain memory accesses. Or at
>> the very least the accesses should be marked volatile.
>
>
> I thought that mapping the IO space was enough for this since it is
> mapped as non-cacheable. I can see the point of marking it volatile but
> see no need to use the read/write register semantics. If this is what it
> takes however I am happy to do so.

Code like this raises eyebrows:

  deviceContext->devRegisters->doorbell |= (UINT32)in->vector |
(in->peerID << 16);

Many readers will probably be wondering what exactly the compiler is
allowed to do with this statement. May it end up ORing the lower and
upper word separately, for example?

  OR [word ptr addr], in->vector
  OR [word ptr addr + 2], in->peerID

And, by the way, is OR really what we want here?

>>
>> * In ivshmem.inf: ManufacturerName="Red Hat, Inc." instead of "RedHat"
>>
>
> No worries.
>
>> * Is any of the API used by the driver Win10-only? Just curious, it's
>> fine to build the driver only for Win10 for now even if it isn't.
>
>
> I have not tried to build it on anything older then win 10 build 10586
> as I have nothing older, but AFAIK it should build on windows 8.1 or
> later just fine. This is more due to my lack of familiarity with Visual
> Studio, give me gcc and vim any day :).

Gotcha, no worries, other versions can be tested later.



Re: [Qemu-devel] ivshmem Windows Driver

2017-10-19 Thread Ladi Prosek
On Wed, Oct 18, 2017 at 5:04 PM,   wrote:
> Hi Ladi & Yan,
>
> I am pleased to present the completed driver for review, please see:
>
> https://github.com/gnif/kvm-guest-drivers-windows

Awesome!

Feel free to open pull request, it should be easier to comment on.

* WoW considerations: It would be nice if the driver could detect that
the map request is coming from a 32-bit process and expect a different
layout of struct IVSHMEM_MMAP.

* It would be cleaner to use READ_REGISTER_* and WRITE_REGISTER_*
from/to IVSHMEMDeviceRegisters instead of plain memory accesses. Or at
the very least the accesses should be marked volatile.

* In ivshmem.inf: ManufacturerName="Red Hat, Inc." instead of "RedHat"

* Is any of the API used by the driver Win10-only? Just curious, it's
fine to build the driver only for Win10 for now even if it isn't.

Thanks!

> All issues previously mentioned have been addressed and all missing
> functionality has been added.
>
> Please note that this work has exposed a bug in the qemu ivshmem
> virtual device itself, it seems that if the MSI interrupts are enabled
> and the driver is unloaded twice an assertion is thrown due to what
> looks to be a double free, crashing out qemu.
>
> Once this driver has been finalized I will look into the cause of
> this problem and see if I can correct it also.
>
> Kind Regards,
> Geoffrey McRae



Re: [Qemu-devel] ivshmem Windows Driver

2017-10-18 Thread Ladi Prosek
On Wed, Oct 18, 2017 at 8:56 AM,   wrote:
> On 2017-10-18 17:50, Ladi Prosek wrote:
>>
>> On Wed, Oct 18, 2017 at 7:50 AM,   wrote:
>>>
>>> On 2017-10-18 16:31, Ladi Prosek wrote:
>>>>
>>>>
>>>> Hi Geoff,
>>>>
>>>> On Mon, Oct 16, 2017 at 8:31 PM,   wrote:
>>>>>
>>>>>
>>>>> Hi Yan & Ladi.
>>>>>
>>>>> I have written an initial implementation that supports just the shared
>>>>> memory
>>>>> mapping at this time. I plan to add events also but before I go further
>>>>> I
>>>>> would
>>>>> like some feedback if possible on what I have implemented thus far.
>>>>>
>>>>> Please see:
>>>>>
>>>>>
>>>>>
>>>>> https://github.com/gnif/kvm-guest-drivers-windows/commit/8655cf12fbdd77b991f96d97bc20f967b5907c12
>>>>
>>>>
>>>>
>>>> Thank you, looks good overall.
>>>>
>>>> * Please don't use the 'vio' prefix for this driver. ivshmem is not a
>>>> VirtIO device (i.e. not using the VirtIO protocol). Also the test
>>>> program should live in a subdirectory, so maybe something like
>>>> /ivshmem and /ivshmem/test.
>>>
>>>
>>>
>>> Noted, I will remove the prefix throughout and move the test application.
>>>
>>>>
>>>> * In VIOIVSHMEMEvtDevicePrepareHardware: I don't think that Windows
>>>> guarantees that resources are enumerated in BAR order. In VirtIO
>>>> drivers we read the PCI config space to identify the BAR index:
>>>>
>>>>
>>>> https://github.com/virtio-win/kvm-guest-drivers-windows/blob/master/VirtIO/VirtIOPCICommon.c#L353
>>>
>>>
>>>
>>> The windows 'toaster' sample relies on the resource order, but as a
>>> belt and braces approach I will update the code to use the same
>>> approach.
>>
>>
>> Interesting, thanks! If that's really the case then we can remove the
>> code from VirtioLib. I have cloned the latest Windows-driver-samples
>> but can't find this under general/toaster. Namely
>> ToasterEvtDevicePrepareHardware just prints some info about all
>> resources but does not do anything order-related. Can you point me to
>> the right code?
>>
>
> Sorry, my mistake, it wasn't the toaster code but the kmdf driver, it
> assumes the BAR ordering to determine which is which.
>
> https://github.com/Microsoft/Windows-driver-samples/blob/aa6e0b36eb932099fa4eb950a6f5e289a23b6d6e/general/pcidrv/kmdf/HW/nic_init.c#L649

Got it. And MSDN says:

"A driver for a PCI bus device receives resources that are listed in
the order in which they appear in the device’s Base Address Registers
(BARs)."
https://docs.microsoft.com/en-us/windows-hardware/drivers/wdf/raw-and-translated-resources

So please disregard my comment.

We'll probably leave VirtioLib alone for now to stay robust, though.
Counting resources works only if the BAR layout is known. VirtIO 1.0
depends on knowing the exact BAR index and can't assume that the
second mem/IO resource is BAR #1, for example. Thanks!

>
>>>>
>>>> * IOCTL codes on Windows have a structure to them:
>>>>
>>>>
>>>> https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
>>>
>>>
>>>
>>> Thanks, I will fix this.
>>>
>>>>
>>>> * In VIOIVSHMEMEvtIoDeviceControl: The "only one mapping at a time is
>>>> allowed" test has a race. I think that simply making the IO queue
>>>> WdfIoQueueDispatchSequential instead of WdfIoQueueDispatchParallel
>>>> will fix it.
>>>
>>>
>>>
>>> Good point, I will change this.
>>>
>>>>
>>>> * According to MSDN, MmMapLockedPagesSpecifyCache(UserMode) should be
>>>> wrapped in try/except. Also, what happens if the file handle is
>>>> inherited by a child process? Can it unmap the mapping in parent's
>>>> address space? What if the parent exits? A possible solution is
>>>> discussed in this article:
>>>> http://www.osronline.com/article.cfm?article=39
>>>
>>>
>>>
>>> Noted re try/except. As for a child inheriting it, the owner is tracked
>>> by the WDFFILEOBJECT, which the child I believe will inherit also, which
>>> would mean that the child would gain the ability to issue IOCTLs to the
>>> mapping.
>>>
>>>>
>>>> Thanks!
>>>> Ladi
>>>
>>>
>>>
>>>
>>> No, thank you! I am grateful someone is willing to provide some feedback
>>> on this.
>>>
>>> I have been working on adding MSI interrupt support to the driver
>>> also which is close to ready, just trying to figure out why the driver
>>> fails to start with STATUS_DEVICE_POWER_FAILURE when I try to setup the
>>> IRQs with WdfInterruptCreate.
>>>
>>> Thanks again,
>>> Geoff
>
>



Re: [Qemu-devel] ivshmem Windows Driver

2017-10-17 Thread Ladi Prosek
On Wed, Oct 18, 2017 at 7:50 AM,   wrote:
> On 2017-10-18 16:31, Ladi Prosek wrote:
>>
>> Hi Geoff,
>>
>> On Mon, Oct 16, 2017 at 8:31 PM,   wrote:
>>>
>>> Hi Yan & Ladi.
>>>
>>> I have written an initial implementation that supports just the shared
>>> memory
>>> mapping at this time. I plan to add events also but before I go further I
>>> would
>>> like some feedback if possible on what I have implemented thus far.
>>>
>>> Please see:
>>>
>>>
>>> https://github.com/gnif/kvm-guest-drivers-windows/commit/8655cf12fbdd77b991f96d97bc20f967b5907c12
>>
>>
>> Thank you, looks good overall.
>>
>> * Please don't use the 'vio' prefix for this driver. ivshmem is not a
>> VirtIO device (i.e. not using the VirtIO protocol). Also the test
>> program should live in a subdirectory, so maybe something like
>> /ivshmem and /ivshmem/test.
>
>
> Noted, I will remove the prefix throughout and move the test application.
>
>>
>> * In VIOIVSHMEMEvtDevicePrepareHardware: I don't think that Windows
>> guarantees that resources are enumerated in BAR order. In VirtIO
>> drivers we read the PCI config space to identify the BAR index:
>>
>> https://github.com/virtio-win/kvm-guest-drivers-windows/blob/master/VirtIO/VirtIOPCICommon.c#L353
>
>
> The windows 'toaster' sample relies on the resource order, but as a
> belt and braces approach I will update the code to use the same
> approach.

Interesting, thanks! If that's really the case then we can remove the
code from VirtioLib. I have cloned the latest Windows-driver-samples
but can't find this under general/toaster. Namely
ToasterEvtDevicePrepareHardware just prints some info about all
resources but does not do anything order-related. Can you point me to
the right code?

>>
>> * IOCTL codes on Windows have a structure to them:
>>
>> https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
>
>
> Thanks, I will fix this.
>
>>
>> * In VIOIVSHMEMEvtIoDeviceControl: The "only one mapping at a time is
>> allowed" test has a race. I think that simply making the IO queue
>> WdfIoQueueDispatchSequential instead of WdfIoQueueDispatchParallel
>> will fix it.
>
>
> Good point, I will change this.
>
>>
>> * According to MSDN, MmMapLockedPagesSpecifyCache(UserMode) should be
>> wrapped in try/except. Also, what happens if the file handle is
>> inherited by a child process? Can it unmap the mapping in parent's
>> address space? What if the parent exits? A possible solution is
>> discussed in this article:
>> http://www.osronline.com/article.cfm?article=39
>
>
> Noted re try/except. As for a child inheriting it, the owner is tracked
> by the WDFFILEOBJECT, which the child I believe will inherit also, which
> would mean that the child would gain the ability to issue IOCTLs to the
> mapping.
>
>>
>> Thanks!
>> Ladi
>
>
>
> No, thank you! I am grateful someone is willing to provide some feedback
> on this.
>
> I have been working on adding MSI interrupt support to the driver
> also which is close to ready, just trying to figure out why the driver
> fails to start with STATUS_DEVICE_POWER_FAILURE when I try to setup the
> IRQs with WdfInterruptCreate.
>
> Thanks again,
> Geoff



Re: [Qemu-devel] ivshmem Windows Driver

2017-10-17 Thread Ladi Prosek
Hi Geoff,

On Mon, Oct 16, 2017 at 8:31 PM,   wrote:
> Hi Yan & Ladi.
>
> I have written an initial implementation that supports just the shared
> memory
> mapping at this time. I plan to add events also but before I go further I
> would
> like some feedback if possible on what I have implemented thus far.
>
> Please see:
>
> https://github.com/gnif/kvm-guest-drivers-windows/commit/8655cf12fbdd77b991f96d97bc20f967b5907c12

Thank you, looks good overall.

* Please don't use the 'vio' prefix for this driver. ivshmem is not a
VirtIO device (i.e. not using the VirtIO protocol). Also the test
program should live in a subdirectory, so maybe something like
/ivshmem and /ivshmem/test.

* In VIOIVSHMEMEvtDevicePrepareHardware: I don't think that Windows
guarantees that resources are enumerated in BAR order. In VirtIO
drivers we read the PCI config space to identify the BAR index:
https://github.com/virtio-win/kvm-guest-drivers-windows/blob/master/VirtIO/VirtIOPCICommon.c#L353

* IOCTL codes on Windows have a structure to them:
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes

* In VIOIVSHMEMEvtIoDeviceControl: The "only one mapping at a time is
allowed" test has a race. I think that simply making the IO queue
WdfIoQueueDispatchSequential instead of WdfIoQueueDispatchParallel
will fix it.

* According to MSDN, MmMapLockedPagesSpecifyCache(UserMode) should be
wrapped in try/except. Also, what happens if the file handle is
inherited by a child process? Can it unmap the mapping in parent's
address space? What if the parent exits? A possible solution is
discussed in this article:
http://www.osronline.com/article.cfm?article=39

Thanks!
Ladi



[Qemu-devel] [PATCH trivial] Remove empty statements

2017-10-17 Thread Ladi Prosek
Thanks to Laszlo Ersek for spotting the double semicolon in target/i386/kvm.c

I have trivially grepped the tree for ';;' in C files.

Suggested-by: Laszlo Ersek 
Signed-off-by: Ladi Prosek 
---
 hw/misc/imx6_ccm.c | 2 +-
 hw/s390x/virtio-ccw.c  | 2 +-
 linux-user/signal.c| 2 +-
 migration/block.c  | 2 +-
 target/i386/cpu.c  | 2 +-
 target/i386/kvm.c  | 2 +-
 target/sh4/translate.c | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
index 1b421013a3..4fa94835fe 100644
--- a/hw/misc/imx6_ccm.c
+++ b/hw/misc/imx6_ccm.c
@@ -335,7 +335,7 @@ static uint64_t imx6_ccm_get_ipg_clk(IMX6CCMState *dev)
 uint64_t freq = 0;
 
 freq = imx6_ccm_get_ahb_clk(dev)
-   / (1 + EXTRACT(dev->ccm[CCM_CBCDR], IPG_PODF));;
+   / (1 + EXTRACT(dev->ccm[CCM_CBCDR], IPG_PODF));
 
 DPRINTF("freq = %d\n", (uint32_t)freq);
 
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 085f17f871..429f10bc90 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -486,7 +486,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
 } else {
 address_space_stb(&address_space_memory, ccw.cda, vdev->status,
 MEMTXATTRS_UNSPECIFIED, NULL);
-sch->curr_status.scsw.count = ccw.count - sizeof(vdev->status);;
+sch->curr_status.scsw.count = ccw.count - sizeof(vdev->status);
 ret = 0;
 }
 break;
diff --git a/linux-user/signal.c b/linux-user/signal.c
index cc0c3fcee9..09055e8920 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -6487,7 +6487,7 @@ static void setup_rt_frame(int sig, struct 
target_sigaction *ka,
 haddr = dest;
 }
 env->iaoq_f = haddr;
-env->iaoq_b = haddr + 4;;
+env->iaoq_b = haddr + 4;
 return;
 
  give_sigsegv:
diff --git a/migration/block.c b/migration/block.c
index 3282809583..565625b9b2 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -896,7 +896,7 @@ static int block_load(QEMUFile *f, void *opaque, int 
version_id)
 int len, flags;
 char device_name[256];
 int64_t addr;
-BlockBackend *blk, *blk_prev = NULL;;
+BlockBackend *blk, *blk_prev = NULL;
 Error *local_err = NULL;
 uint8_t *buf;
 int64_t total_sectors = 0;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 98732cd65f..d44b0ed56c 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2218,7 +2218,7 @@ static void 
x86_cpu_class_check_missing_features(X86CPUClass *xcc,
 
 if (xcc->kvm_required && !kvm_enabled()) {
 strList *new = g_new0(strList, 1);
-new->value = g_strdup("kvm");;
+new->value = g_strdup("kvm");
 *missing_feats = new;
 return;
 }
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index b1e32e95d3..d4b2ce2e94 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1122,7 +1122,7 @@ static int kvm_get_supported_msrs(KVMState *s)
 break;
 case MSR_IA32_XSS:
 has_msr_xss = true;
-break;;
+break;
 case HV_X64_MSR_CRASH_CTL:
 has_msr_hv_crash = true;
 break;
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index 8db9fba26e..2b00cd2f35 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -679,7 +679,7 @@ static void _decode_opc(DisasContext * ctx)
return;
 case 0x6008:   /* swap.b Rm,Rn */
{
-TCGv low = tcg_temp_new();;
+TCGv low = tcg_temp_new();
tcg_gen_ext16u_i32(low, REG(B7_4));
tcg_gen_bswap16_i32(low, low);
 tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
-- 
2.13.5




Re: [Qemu-devel] [PATCH 00/43] Windbg supporting

2017-10-03 Thread Ladi Prosek
Hi,

On Tue, Sep 26, 2017 at 1:04 PM, Mihail Abakumov
 wrote:
> 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.

I wanted to try this to debug a WinXP VM running on Linux from another
VM on the same host. I used my usual windbg setup only instead of

  -serial tcp:localhost:

I had

  -windbg tcp:localhost:

in the QEMU command line of the debugging target and

  -serial tcp:localhost:,server,nowait

for the VM running windbg, but I didn't succeed even after disabling
KVM which seems to be one of the limitations.

I understand that you run QEMU on Windows. Before I dig deeper, have
you tried any other backend for -windbg or maybe running on a Linux
host? Is it expected to work?

Thank you!
Ladi

> ---
>
> Mihail Abakumov (43):
>   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: sized data buffer
>   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_read_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
>   windbg: implemented windbg_hw_breakpoint_insert and 
> windbg_hw_breakpoint_remove
>   windbg: implemented kd_api_write_breakpoint and 
> kd_api_restore_breakpoint
>   windbg: debug exception subscribing
>   windbg: implemented kd_api_continue
>   windbg: implemented kd_api_read_io_space and kd_api_write_io_space
>   windbg: implemented kd_api_read_physical_memory and 
> kd_api_write_physical_memory
>   windbg: implemented kd_api_get_version
>   windbg: implemented kd_api_read_msr and kd_api_write_msr
>   windbg: implemented kd_api_search_memory
>   windbg: implemented kd_api_fill_memory
>   windbg: implemented kd_api_query_memory
>
>
>  Makefile.target |5
>  cpus.c  |   18
>  gdbstub.c   |4
>  include/exec/windbgkd.h | 1030 ++
>  include/exec/windbgstub-utils.h |  132 +++
>  include/exec/windbgstub.h   |   21
>  include/sysemu/sysemu.h |2
>  qemu-options.h

Re: [Qemu-devel] [PATCH 42/43] windbg: implemented kd_api_fill_memory

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:08 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  include/exec/windbgstub-utils.h |1 +
>  windbgstub-utils.c  |   36 
>  windbgstub.c|4 
>  3 files changed, 41 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index ba001ddb42..d1a10c862e 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -119,6 +119,7 @@ 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_fill_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 2d3fbcc41c..3832e0b116 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -1570,6 +1570,42 @@ void kd_api_search_memory(CPUState *cpu, PacketData 
> *pd)
>  pd->extra_size = 0;
>  }
>
> +void kd_api_fill_memory(CPUState *cpu, PacketData *pd)
> +{
> +DBGKD_FILL_MEMORY *m64c = &pd->m64.u.FillMemory;
> +
> +uint32_t len = ldl_p(&m64c->Length);
> +target_ulong addr = ldq_p(&m64c->Address);
> +uint16_t pattern = ldl_p(&m64c->PatternLength);
> +uint16_t flags = ldl_p(&m64c->Flags);
> +
> +uint8_t mem[len];

Same as patch 41, break len into, say, page-sized regions and call
cpu_memory_rw_debug in a loop.

> +int i, err;
> +for (i = 0; i < len; ++i) {
> +mem[i] = pd->extra[i % pattern];
> +}
> +
> +switch (flags) {
> +case DBGKD_FILL_MEMORY_VIRTUAL:
> +err = cpu_memory_rw_debug(cpu, addr, mem, len, 1);
> +if (err) {
> +pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
> +WINDBG_DEBUG("fill_memory: No physical page mapped: " FMT_ADDR,
> +addr);
> +}
> +break;
> +
> +case DBGKD_FILL_MEMORY_PHYSICAL:
> +cpu_physical_memory_rw(addr, mem, len, 1);
> +break;
> +
> +default:
> +break;
> +}
> +
> +pd->extra_size = 0;
> +}
> +
>  void kd_api_unsupported(CPUState *cpu, PacketData *pd)
>  {
>  WINDBG_ERROR("Catched unimplemented api %s",
> diff --git a/windbgstub.c b/windbgstub.c
> index 7cff6bc514..b01ddcf009 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -209,6 +209,10 @@ static void 
> windbg_process_manipulate_packet(ParsingContext *ctx)
>  kd_api_search_memory(cpu, &ctx->data);
>  break;
>
> +case DbgKdFillMemoryApi:
> +kd_api_fill_memory(cpu, &ctx->data);
> +break;
> +
>  default:
>  kd_api_unsupported(cpu, &ctx->data);
>  break;
>



Re: [Qemu-devel] [PATCH 41/43] windbg: implemented kd_api_search_memory

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:07 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  include/exec/windbgstub-utils.h |1 +
>  windbgstub-utils.c  |   30 ++
>  windbgstub.c|4 
>  3 files changed, 35 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index 23cafb1a89..ba001ddb42 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -118,6 +118,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 26bdb1f6ea..2d3fbcc41c 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -1540,6 +1540,36 @@ void kd_api_write_msr(CPUState *cpu, PacketData *pd)
>  pd->m64.ReturnStatus = STATUS_SUCCESS;
>  }
>
> +void kd_api_search_memory(CPUState *cpu, PacketData *pd)
> +{
> +DBGKD_SEARCH_MEMORY *m64c = &pd->m64.u.SearchMemory;
> +int s_len = MAX(1, ldq_p(&m64c->SearchLength));
> +int p_len = MIN(ldl_p(&m64c->PatternLength), pd->extra_size);
> +target_ulong addr = ldq_p(&m64c->SearchAddress);
> +
> +uint8_t mem[s_len - 1 + p_len];

s_len could be very large, people do things like

0:000> s -d 0x8000 L?0x7fff 

You should not allocate this buffer on the stack and preferably break
large searches down to smaller ranges, i.e. don't allocate and read
~s_len bytes all at once.

> +int err = cpu_memory_rw_debug(cpu, addr, mem, sizeof(mem), 0);
> +if (!err) {
> +int i;
> +pd->m64.ReturnStatus = STATUS_NO_MORE_ENTRIES;
> +for (i = 0; i < s_len; ++i) {
> +if (memcmp(mem + i, pd->extra, p_len) == 0) {
> +m64c->FoundAddress = addr + i;
> +m64c->FoundAddress = ldq_p(&m64c->FoundAddress);
> +pd->m64.ReturnStatus = STATUS_SUCCESS;
> +break;
> +}
> +}

Use memmem instead?

> +} else {
> +pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
> +WINDBG_DEBUG("search_memory: No physical page mapped: " FMT_ADDR,
> + addr);
> +}
> +
> +pd->extra_size = 0;
> +}
> +
>  void kd_api_unsupported(CPUState *cpu, PacketData *pd)
>  {
>  WINDBG_ERROR("Catched unimplemented api %s",
> diff --git a/windbgstub.c b/windbgstub.c
> index 1ec4932ddc..7cff6bc514 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -205,6 +205,10 @@ static void 
> windbg_process_manipulate_packet(ParsingContext *ctx)
>  case DbgKdClearAllInternalBreakpointsApi:
>  return;
>
> +case DbgKdSearchMemoryApi:
> +kd_api_search_memory(cpu, &ctx->data);
> +break;
> +
>  default:
>  kd_api_unsupported(cpu, &ctx->data);
>  break;
>



Re: [Qemu-devel] [PATCH 38/43] windbg: implemented kd_api_read_physical_memory and kd_api_write_physical_memory

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:07 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  include/exec/windbgstub-utils.h |2 ++
>  windbgstub-utils.c  |   28 
>  windbgstub.c|8 
>  3 files changed, 38 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index 07e11c0494..d390bc1dfe 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -113,6 +113,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 6bf9868e51..1fba54f9d9 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -1170,6 +1170,34 @@ 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 = &pd->m64.u.ReadMemory;
> +uint32_t len;
> +target_ulong addr;
> +
> +len = MIN(ldl_p(&mem->TransferCount), PACKET_MAX_SIZE - M64_SIZE);
> +addr = ldtul_p(&mem->TargetBaseAddress);
> +
> +cpu_physical_memory_rw(addr, pd->extra, len, 0);
> +pd->extra_size = len;
> +mem->ActualBytesRead = ldl_p(&len);

stl_p(&mem->ActualBytesRead, len)

And the same pattern is in many other places. Stores to potentially
unaligned memory locations with the right endianness should be done
with st* not ld*.

> +}
> +
> +void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd)
> +{
> +DBGKD_WRITE_MEMORY64 *mem = &pd->m64.u.WriteMemory;
> +uint32_t len;
> +target_ulong addr;
> +
> +len = MIN(ldl_p(&mem->TransferCount), pd->extra_size);
> +addr = ldtul_p(&mem->TargetBaseAddress);
> +
> +cpu_physical_memory_rw(addr, pd->extra, len, 1);
> +pd->extra_size = 0;
> +mem->ActualBytesWritten = ldl_p(&len);
> +}
> +
>  void kd_api_unsupported(CPUState *cpu, PacketData *pd)
>  {
>  WINDBG_ERROR("Catched unimplemented api %s",
> diff --git a/windbgstub.c b/windbgstub.c
> index 0363d9a5c8..118e9dd697 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -182,6 +182,14 @@ static void 
> windbg_process_manipulate_packet(ParsingContext *ctx)
>  kd_api_write_control_space(cpu, &ctx->data);
>  break;
>
> +case DbgKdReadPhysicalMemoryApi:
> +kd_api_read_physical_memory(cpu, &ctx->data);
> +break;
> +
> +case DbgKdWritePhysicalMemoryApi:
> +kd_api_write_physical_memory(cpu, &ctx->data);
> +break;
> +
>  case DbgKdClearAllInternalBreakpointsApi:
>  return;
>
>



Re: [Qemu-devel] [PATCH 33/43] windbg: implemented windbg_hw_breakpoint_insert and windbg_hw_breakpoint_remove

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:07 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  windbgstub-utils.c |   60 
> 
>  1 file changed, 60 insertions(+)
>
> diff --git a/windbgstub-utils.c b/windbgstub-utils.c
> index e33789725e..05caf98c0c 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -294,11 +294,71 @@ static KDData *kd;
>
>  static int windbg_hw_breakpoint_insert(CPUState *cpu, int index)
>  {
> +CPUArchState *env = cpu->env_ptr;
> +
> +if (!IS_BP_ENABLED(env->dr[7], index)) {

nit: This is already checked by both callers.

> +return 0;
> +}
> +
> +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,
> +&env->cpu_watchpoint[index]);
> +break;
> +case DR7_TYPE_DATA_RW:
> +err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_ACCESS | BP_GDB,
> +&env->cpu_watchpoint[index]);
> +break;
> +case DR7_TYPE_BP_INST:
> +err = cpu_breakpoint_insert(cpu, addr, BP_GDB,
> +&env->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;
>  }
>
>



Re: [Qemu-devel] [PATCH 28/43] windbg: implemented windbg_read_ks_regs

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:06 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  windbgstub-utils.c |   38 ++
>  1 file changed, 38 insertions(+)
>
> diff --git a/windbgstub-utils.c b/windbgstub-utils.c
> index 73ff98dfbc..537ba9e2aa 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -587,6 +587,44 @@ static int windbg_write_context(CPUState *cpu, uint8_t 
> *buf, int len,
>  static int windbg_read_ks_regs(CPUState *cpu, uint8_t *buf, int len,
> int offset)
>  {
> +CPUArchState *env = cpu->env_ptr;
> +const bool new_mem = (len != sizeof(CPU_KSPECIAL_REGISTERS)
> +   || offset != 0);
> +CPU_KSPECIAL_REGISTERS *ckr;
> +if (new_mem) {
> +ckr = g_new(CPU_KSPECIAL_REGISTERS, 1);
> +} else {
> +ckr = (CPU_KSPECIAL_REGISTERS *) buf;
> +}
> +
> +memset(ckr, 0, len);

Buffer overrun on len > sizeof(CPU_KSPECIAL_REGISTERS).

> +ckr->Cr0 = ldl_p(&env->cr[0]);
> +ckr->Cr2 = ldl_p(&env->cr[2]);
> +ckr->Cr3 = ldl_p(&env->cr[3]);
> +ckr->Cr4 = ldl_p(&env->cr[4]);
> +
> +ckr->KernelDr0 = ldtul_p(&env->dr[0]);
> +ckr->KernelDr1 = ldtul_p(&env->dr[1]);
> +ckr->KernelDr2 = ldtul_p(&env->dr[2]);
> +ckr->KernelDr3 = ldtul_p(&env->dr[3]);
> +ckr->KernelDr6 = ldtul_p(&env->dr[6]);
> +ckr->KernelDr7 = ldtul_p(&env->dr[7]);
> +
> +ckr->Gdtr.Pad = lduw_p(&env->gdt.selector);
> +ckr->Idtr.Pad = lduw_p(&env->idt.selector);
> +
> +ckr->Gdtr.Limit = lduw_p(&env->gdt.limit);
> +ckr->Gdtr.Base  = ldtul_p(&env->gdt.base);
> +ckr->Idtr.Limit = lduw_p(&env->idt.limit);
> +ckr->Idtr.Base  = ldtul_p(&env->idt.base);
> +ckr->Tr = lduw_p(&env->tr.selector);
> +ckr->Ldtr   = lduw_p(&env->ldt.selector);
> +
> +if (new_mem) {
> +memcpy(buf, (uint8_t *) ckr + offset, len);
> +g_free(ckr);
> +}
>  return 0;
>  }
>
>



Re: [Qemu-devel] [PATCH 26/43] windbg: implemented windbg_read_context

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:06 PM, Mihail Abakumov
 wrote:
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  windbgstub-utils.c |   90 
> +++-
>  1 file changed, 89 insertions(+), 1 deletion(-)
>
> diff --git a/windbgstub-utils.c b/windbgstub-utils.c
> index c3ae2ddf5b..23bf4be9f0 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -280,7 +280,95 @@ static KDData *kd;
>  static int windbg_read_context(CPUState *cpu, uint8_t *buf, int len,
> int offset)
>  {
> -return 0;
> +const bool new_mem = (len != sizeof(CPU_CONTEXT) || offset != 0);
> +CPUArchState *env = cpu->env_ptr;
> +CPU_CONTEXT *cc;
> +int err = 0;
> +
> +if (new_mem) {
> +cc = g_new(CPU_CONTEXT, 1);
> +} else {
> +cc = (CPU_CONTEXT *) buf;
> +}
> +
> +memset(cc, 0, len);

This overruns the buffer if len > sizeof(CPU_CONTEXT).

> +
> +cc->ContextFlags = CPU_CONTEXT_ALL;
> +
> +if (cc->ContextFlags & CPU_CONTEXT_SEGMENTS) {
> +cc->SegCs = lduw_p(&env->segs[R_CS].selector);
> +cc->SegDs = lduw_p(&env->segs[R_DS].selector);
> +cc->SegEs = lduw_p(&env->segs[R_ES].selector);
> +cc->SegFs = lduw_p(&env->segs[R_FS].selector);
> +cc->SegGs = lduw_p(&env->segs[R_GS].selector);
> +cc->SegSs = lduw_p(&env->segs[R_SS].selector);
> +}
> +
> +if (cc->ContextFlags & CPU_CONTEXT_DEBUG_REGISTERS) {
> +cc->Dr0 = ldtul_p(&env->dr[0]);
> +cc->Dr1 = ldtul_p(&env->dr[1]);
> +cc->Dr2 = ldtul_p(&env->dr[2]);
> +cc->Dr3 = ldtul_p(&env->dr[3]);
> +cc->Dr6 = ldtul_p(&env->dr[6]);
> +cc->Dr7 = ldtul_p(&env->dr[7]);
> +}
> +
> +if (cc->ContextFlags & CPU_CONTEXT_INTEGER) {
> +cc->Edi= ldl_p(&env->regs[R_EDI]);
> +cc->Esi= ldl_p(&env->regs[R_ESI]);
> +cc->Ebx= ldl_p(&env->regs[R_EBX]);
> +cc->Edx= ldl_p(&env->regs[R_EDX]);
> +cc->Ecx= ldl_p(&env->regs[R_ECX]);
> +cc->Eax= ldl_p(&env->regs[R_EAX]);
> +cc->Ebp= ldl_p(&env->regs[R_EBP]);
> +cc->Esp= ldl_p(&env->regs[R_ESP]);
> +
> +cc->Eip= ldl_p(&env->eip);
> +cc->EFlags = ldl_p(&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;
> +}
> +
> +cc->FloatSave.ControlWord= ldl_p(&env->fpuc);
> +cc->FloatSave.StatusWord = ldl_p(&swd);
> +cc->FloatSave.TagWord= ldl_p(&twd);
> +cc->FloatSave.ErrorOffset= ldl_p(PTR(env->fpip));
> +cc->FloatSave.ErrorSelector  = ldl_p(PTR(env->fpip) + 32);
> +cc->FloatSave.DataOffset = ldl_p(PTR(env->fpdp));
> +cc->FloatSave.DataSelector   = ldl_p(PTR(env->fpdp) + 32);
> +cc->FloatSave.Cr0NpxState= ldl_p(&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);
> +}
> +
> +cc->ContextFlags = ldl_p(&cc->ContextFlags);
> +
> +if (new_mem) {
> +memcpy(buf, (uint8_t *) cc + offset, len);
> +g_free(cc);
> +}
> +return err;
>  }
>
>  static int windbg_write_context(CPUState *cpu, uint8_t *buf, int len,
>



Re: [Qemu-devel] [PATCH 22/43] windbg: implemented kd_api_read_virtual_memory and kd_api_read_virtual_memory

2017-10-03 Thread Ladi Prosek
nit: The subject line has "kd_api_read_virtual_memory" twice in it.
Was probably meant to be

[PATCH 22/43] windbg: implemented kd_api_read_virtual_memory and
kd_api_write_virtual_memory


On Tue, Sep 26, 2017 at 1:06 PM, Mihail Abakumov
 wrote:
> 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 ca21af7c91..c1ff1cec57 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -102,6 +102,8 @@ typedef struct SizedBuf {
>  buf.size = 0;   \
>  } while (false)
>
> +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 e7b381f829..1bde60a1e9 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -30,6 +30,53 @@ typedef struct KDData {
>
>  static KDData *kd;
>
> +void kd_api_read_virtual_memory(CPUState *cpu, PacketData *pd)
> +{
> +DBGKD_READ_MEMORY64 *mem = &pd->m64.u.ReadMemory;
> +uint32_t len;
> +target_ulong addr;
> +int err;
> +
> +len = MIN(ldl_p(&mem->TransferCount), PACKET_MAX_SIZE - M64_SIZE);
> +addr = ldtul_p(&mem->TargetBaseAddress);
> +err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 0);
> +
> +if (!err) {
> +pd->extra_size = len;
> +mem->ActualBytesRead = ldl_p(&len);
> +} else {
> +pd->extra_size = 0;
> +mem->ActualBytesRead = 0;
> +pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
> +
> +WINDBG_DEBUG("read_virtual_memory: No physical page mapped: " 
> FMT_ADDR,
> + (target_ulong) mem->TargetBaseAddress);
> +}
> +}
> +
> +void kd_api_write_virtual_memory(CPUState *cpu, PacketData *pd)
> +{
> +DBGKD_WRITE_MEMORY64 *mem = &pd->m64.u.WriteMemory;
> +uint32_t len;
> +target_ulong addr;
> +int err;
> +
> +len = MIN(ldl_p(&mem->TransferCount), pd->extra_size);
> +addr = ldtul_p(&mem->TargetBaseAddress);
> +err = cpu_memory_rw_debug(cpu, addr, pd->extra, len, 1);
> +
> +pd->extra_size = 0;
> +if (!err) {
> +mem->ActualBytesWritten = ldl_p(&len);
> +} else {
> +mem->ActualBytesWritten = 0;
> +pd->m64.ReturnStatus = STATUS_UNSUCCESSFUL;
> +
> +WINDBG_DEBUG("read_write_memory: No physical page mapped: " FMT_ADDR,
> + (target_ulong) mem->TargetBaseAddress);
> +}
> +}
> +
>  void kd_api_unsupported(CPUState *cpu, PacketData *pd)
>  {
>  WINDBG_ERROR("Catched unimplemented api %s",
> diff --git a/windbgstub.c b/windbgstub.c
> index 50b4ef0dea..327fe83f70 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -133,6 +133,14 @@ static void 
> windbg_process_manipulate_packet(ParsingContext *ctx)
>
>  switch (ctx->data.m64.ApiNumber) {
>
> +case DbgKdReadVirtualMemoryApi:
> +kd_api_read_virtual_memory(cpu, &ctx->data);
> +break;
> +
> +case DbgKdWriteVirtualMemoryApi:
> +kd_api_write_virtual_memory(cpu, &ctx->data);
> +break;
> +
>  default:
>  kd_api_unsupported(cpu, &ctx->data);
>  break;
>



Re: [Qemu-devel] [PATCH 19/43] windbg: implemented windbg_process_control_packet

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:05 PM, Mihail Abakumov
 wrote:
> 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 3a13d22349..b8053102dd 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -126,7 +126,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);
> +windbg_send_control_packet(ctx->packet.PacketType);
> +windbg_state->ctrl_packet_id = INITIAL_PACKET_ID;
> +SBUF_FREE(buf);
> +break;
> +}
> +default:
> +WINDBG_ERROR("Catched unsupported control packet 0x%x",

"caught" instead of "catched", same in patches 20 and 21.

> + 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)
>  {
>



Re: [Qemu-devel] [PATCH 15/43] windbg: sized data buffer

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:05 PM, Mihail Abakumov
 wrote:
> Defined useful sized data buffer. It contains pointer to data and size of 
> this data. Also, defined some macroses for init and free.

"macros" instead of "macroses", same in patch 31.

> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  include/exec/windbgstub-utils.h |   15 +++
>  1 file changed, 15 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index cf2996d8cb..791721d472 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -86,6 +86,21 @@ typedef struct PacketData {
>  uint16_t extra_size;
>  } PacketData;
>
> +typedef struct SizedBuf {
> +uint8_t *data;
> +size_t size;
> +} SizedBuf;
> +
> +#define SBUF_INIT(buf, mem_ptr, len) do { \
> +buf.data = mem_ptr;   \
> +buf.size = len;   \
> +} while (false)
> +#define SBUF_MALLOC(buf, size) SBUF_INIT(buf, g_malloc0(size), size)
> +#define SBUF_FREE(buf) do { \
> +g_free(buf.data);   \
> +buf.data = NULL;\
> +buf.size = 0;   \
> +} while (false)
>  bool windbg_on_load(void);
>  void windbg_on_exit(void);
>
>



Re: [Qemu-devel] [PATCH 15/43] windbg: sized data buffer

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:05 PM, Mihail Abakumov
 wrote:
> Defined useful sized data buffer. It contains pointer to data and size of 
> this data. Also, defined some macroses for init and free.

"macros" instead of "macroses", same in patch 31.

> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  include/exec/windbgstub-utils.h |   15 +++
>  1 file changed, 15 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index cf2996d8cb..791721d472 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -86,6 +86,21 @@ typedef struct PacketData {
>  uint16_t extra_size;
>  } PacketData;
>
> +typedef struct SizedBuf {
> +uint8_t *data;
> +size_t size;
> +} SizedBuf;
> +
> +#define SBUF_INIT(buf, mem_ptr, len) do { \
> +buf.data = mem_ptr;   \
> +buf.size = len;   \
> +} while (false)
> +#define SBUF_MALLOC(buf, size) SBUF_INIT(buf, g_malloc0(size), size)
> +#define SBUF_FREE(buf) do { \
> +g_free(buf.data);   \
> +buf.data = NULL;\
> +buf.size = 0;   \
> +} while (false)
>  bool windbg_on_load(void);
>  void windbg_on_exit(void);
>
>



Re: [Qemu-devel] [PATCH 09/43] windbg: handler of fs/gs register

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:04 PM, Mihail Abakumov
 wrote:
> 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 |5 +++
>  windbgstub-utils.c  |   63 
> ++-
>  2 files changed, 66 insertions(+), 2 deletions(-)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index 90fb766839..f2402ebb34 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -62,6 +62,11 @@
>  _t;   \
>  })
>
> +typedef struct InitedAddr {
> +target_ulong addr;
> +bool is_init;
> +} InitedAddr;
> +
>  bool windbg_on_load(void);
>  void windbg_on_exit(void);
>
> diff --git a/windbgstub-utils.c b/windbgstub-utils.c
> index b5fb6db3f2..662096647e 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -11,10 +11,69 @@
>
>  #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
> +
> +typedef struct KDData {
> +InitedAddr KPCR;
> +InitedAddr version;
> +} KDData;
> +
> +static KDData *kd;
> +
>  bool windbg_on_load(void)
>  {
> -return false;
> +CPUState *cpu = qemu_get_cpu(0);
> +CPUArchState *env = cpu->env_ptr;
> +
> +if (!kd) {
> +kd = g_new0(KDData, 1);
> +}
> +
> +if (!kd->KPCR.is_init) {
> +
> + #ifdef TARGET_X86_64
> +kd->KPCR.addr = env->segs[R_GS].base;
> + #else
> +kd->KPCR.addr = env->segs[R_FS].base;
> + #endif

What if Windows is rebooted and FS/GS changes? Do you need to flip
KPCR.is_init back to false on system reset?

> +static target_ulong prev_KPCR;
> +if (!kd->KPCR.addr || prev_KPCR == kd->KPCR.addr) {
> +return false;
> +}
> +prev_KPCR = kd->KPCR.addr;
> +
> +if (kd->KPCR.addr != READ_VMEM(cpu, kd->KPCR.addr + OFFSET_SELF_PCR,
> +   target_ulong)) {
> +return false;
> +}
> +
> +kd->KPCR.is_init = true;
> +}
> +
> +if (!kd->version.is_init && kd->KPCR.is_init) {
> +kd->version.addr = READ_VMEM(cpu, kd->KPCR.addr + OFFSET_VERS,
> + target_ulong);
> +if (!kd->version.addr) {
> +return false;
> +}
> +kd->version.is_init = true;
> +}
> +
> +WINDBG_DEBUG("windbg_on_load: KPCR " FMT_ADDR, kd->KPCR.addr);
> +WINDBG_DEBUG("windbg_on_load: version " FMT_ADDR, kd->version.addr);
> +
> +return true;
>  }
>
>  void windbg_on_exit(void)
> -{}
> +{
> +g_free(kd);
> +kd = NULL;
> +}
>



Re: [Qemu-devel] [PATCH 08/43] windbg: hook to wrmsr operation

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:04 PM, Mihail Abakumov
 wrote:
> 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 |3 +++
>  include/exec/windbgstub.h   |1 +
>  target/i386/misc_helper.c   |3 +++
>  windbgstub-utils.c  |8 
>  windbgstub.c|8 
>  5 files changed, 23 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index 65f336e4bf..90fb766839 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -62,4 +62,7 @@
>  _t;   \
>  })
>
> +bool windbg_on_load(void);
> +void windbg_on_exit(void);
> +
>  #endif
> diff --git a/include/exec/windbgstub.h b/include/exec/windbgstub.h
> index 703fc26b8f..2dbf1b1f13 100755
> --- a/include/exec/windbgstub.h
> +++ b/include/exec/windbgstub.h
> @@ -15,6 +15,7 @@
>  #define WINDBG "windbg"
>  #define WINDBG_DEBUG_ON false
>
> +void windbg_try_load(void);
>  int windbg_server_start(const char *device);
>
>  #endif
> 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();

Most people use QEMU with KVM and won't ever hit this code. Does your
work rely on TCG only for FS/GS write interception?

If KVM is out of scope for you, you should at least make sure that
users won't expect -windbg to work with it. So either fall back to TCG
if -windbg is passed or issue a warning.

>  }
>
>  void helper_rdmsr(CPUX86State *env)
> diff --git a/windbgstub-utils.c b/windbgstub-utils.c
> index dc5e505c63..b5fb6db3f2 100755
> --- a/windbgstub-utils.c
> +++ b/windbgstub-utils.c
> @@ -10,3 +10,11 @@
>   */
>
>  #include "exec/windbgstub-utils.h"
> +
> +bool windbg_on_load(void)
> +{
> +return false;
> +}
> +
> +void windbg_on_exit(void)
> +{}
> diff --git a/windbgstub.c b/windbgstub.c
> index 378d1b911f..99c3ef9b14 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -39,8 +39,16 @@ static void windbg_chr_receive(void *opaque, const uint8_t 
> *buf, int size)
>  }
>  }
>
> +void windbg_try_load(void)
> +{
> +if (windbg_state && !windbg_state->is_loaded) {
> +windbg_state->is_loaded = windbg_on_load();
> +}
> +}
> +
>  static void windbg_exit(void)
>  {
> +windbg_on_exit();
>  g_free(windbg_state);
>  }
>
>



Re: [Qemu-devel] [PATCH 07/43] windbg: added chardev

2017-10-03 Thread Ladi Prosek
On Tue, Sep 26, 2017 at 1:04 PM, Mihail Abakumov
 wrote:
> Added chardev for listening to windbg. Target device is a parameter in the 
> '-windbg' option.
>
> Signed-off-by: Mihail Abakumov 
> Signed-off-by: Pavel Dovgalyuk 
> Signed-off-by: Dmitriy Koltunov 
> ---
>  windbgstub.c |   26 ++
>  1 file changed, 26 insertions(+)
>
> diff --git a/windbgstub.c b/windbgstub.c
> index 60a380c213..378d1b911f 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -10,6 +10,7 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qapi/error.h"
>  #include "chardev/char.h"
>  #include "chardev/char-fe.h"
>  #include "exec/windbgstub.h"
> @@ -18,12 +19,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);
> @@ -31,6 +46,8 @@ static void windbg_exit(void)
>
>  int windbg_server_start(const char *device)
>  {
> +Chardev *chr = NULL;
> +
>  if (windbg_state) {
>  WINDBG_ERROR("Multiple instances are not supported");
>  exit(1);
> @@ -40,6 +57,15 @@ int windbg_server_start(const char *device)
>  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) {

This should generate error output. Passing "-windbg bogus" makes QEMU
exit silently.
-gdb seems to have the same problem.

> +return -1;
> +}
> +
> +qemu_chr_fe_init(&windbg_state->chr, chr, &error_abort);
> +qemu_chr_fe_set_handlers(&windbg_state->chr, windbg_chr_can_receive,
> + windbg_chr_receive, NULL, NULL, NULL, NULL, 
> true);
> +
>  atexit(windbg_exit);
>  return 0;
>  }
>



Re: [Qemu-devel] [PATCH v3 0/9] virtio: enhance virtio_error messages

2017-10-03 Thread Ladi Prosek
On Thu, Sep 14, 2017 at 7:59 AM, Ladi Prosek  wrote:
> On Fri, Jul 21, 2017 at 5:21 PM, Stefan Hajnoczi  wrote:
>> On Mon, Jul 17, 2017 at 10:11:43AM +0200, Ladi Prosek wrote:
>>> Output like "Virtqueue size exceeded" is not much useful in identifying the
>>> culprit. This series beefs up virtio_error to print the virtio device name
>>> and id, and introduces virtqueue_error which additionally includes the index
>>> of the virtqueue where the error occured.
>>>
>>> Patches 1 to 3 lay the groundwork, patches 4 to 8 convert virtio devices to
>>> use virtqueue_error instead of virtio_error. Patch 9 adds virtio_error and
>>> virtqueue_error to the list of error funcs in checkpatch.pl.
>>>
>>> v1->v2:
>>> * Modified virtio_error and added virtqueue_error (Stefan)
>>> * Now also printing device id (Stefan)
>>> * Went over all virtio_error call sites and converted them to 
>>> virtqueue_error
>>>   as appropriate; added virtio device maintainers to cc
>>>
>>> v2->v3:
>>> * Removed patch 1 (Stefan, Markus)
>>> * Split patch 3 into 2 (adds virtqueue_error) and 3 (makes virtio.c call it)
>>>   (Cornelia)
>>> * Added patch 9 to modify $qemu_error_funcs in checkpatch.pl (Greg)
>>> * s/includes queue index/includes the queue index/ in patch 3-9 commit
>>>   messages (Cornelia)
>>> * Fixed virtio_get_device_id to return empty string instead of NULL if the
>>>   device doesn't have an id (Stefan)
>>> * Simplified the change in virtio-crypto.c to use vcrypto->ctrl_vq instead
>>>   of propagating the vq pointer in function arguments (Cornelia, Gonglei)
>>>
>>> Ladi Prosek (9):
>>>   virtio: enhance virtio_error messages
>>>   virtio: introduce virtqueue_error
>>>   virtio: use virtqueue_error for errors with queue context
>>>   virtio-9p: use virtqueue_error for errors with queue context
>>>   virtio-blk: use virtqueue_error for errors with queue context
>>>   virtio-net: use virtqueue_error for errors with queue context
>>>   virtio-scsi: use virtqueue_error for errors with queue context
>>>   virtio-crypto: use virtqueue_error for errors with queue context
>>>   checkpatch: add virtio_error and virtqueue_error to error funcs
>>>
>>>  hw/9pfs/virtio-9p-device.c |  37 ++
>>>  hw/block/virtio-blk.c  |   6 +--
>>>  hw/net/virtio-net.c|  24 -
>>>  hw/scsi/virtio-scsi.c  |   2 +-
>>>  hw/virtio/virtio-crypto.c  |  49 ++-
>>>  hw/virtio/virtio.c | 119 
>>> +++--
>>>  include/hw/virtio/virtio.h |   1 +
>>>  scripts/checkpatch.pl  |   4 +-
>>>  8 files changed, 143 insertions(+), 99 deletions(-)
>>
>> Looks good.  QEMU is currently in freeze for the 2.10 release.  You may
>> need to resend so Michael Tsirkin can merge it after the release, or if
>> he maintainers a -next branch he could merge it right away.
>
> Should I resend the series, Michael?

Ping. The series applies cleanly on current master.



Re: [Qemu-devel] [PATCH v3 0/9] virtio: enhance virtio_error messages

2017-09-13 Thread Ladi Prosek
On Fri, Jul 21, 2017 at 5:21 PM, Stefan Hajnoczi  wrote:
> On Mon, Jul 17, 2017 at 10:11:43AM +0200, Ladi Prosek wrote:
>> Output like "Virtqueue size exceeded" is not much useful in identifying the
>> culprit. This series beefs up virtio_error to print the virtio device name
>> and id, and introduces virtqueue_error which additionally includes the index
>> of the virtqueue where the error occured.
>>
>> Patches 1 to 3 lay the groundwork, patches 4 to 8 convert virtio devices to
>> use virtqueue_error instead of virtio_error. Patch 9 adds virtio_error and
>> virtqueue_error to the list of error funcs in checkpatch.pl.
>>
>> v1->v2:
>> * Modified virtio_error and added virtqueue_error (Stefan)
>> * Now also printing device id (Stefan)
>> * Went over all virtio_error call sites and converted them to virtqueue_error
>>   as appropriate; added virtio device maintainers to cc
>>
>> v2->v3:
>> * Removed patch 1 (Stefan, Markus)
>> * Split patch 3 into 2 (adds virtqueue_error) and 3 (makes virtio.c call it)
>>   (Cornelia)
>> * Added patch 9 to modify $qemu_error_funcs in checkpatch.pl (Greg)
>> * s/includes queue index/includes the queue index/ in patch 3-9 commit
>>   messages (Cornelia)
>> * Fixed virtio_get_device_id to return empty string instead of NULL if the
>>   device doesn't have an id (Stefan)
>> * Simplified the change in virtio-crypto.c to use vcrypto->ctrl_vq instead
>>   of propagating the vq pointer in function arguments (Cornelia, Gonglei)
>>
>> Ladi Prosek (9):
>>   virtio: enhance virtio_error messages
>>   virtio: introduce virtqueue_error
>>   virtio: use virtqueue_error for errors with queue context
>>   virtio-9p: use virtqueue_error for errors with queue context
>>   virtio-blk: use virtqueue_error for errors with queue context
>>   virtio-net: use virtqueue_error for errors with queue context
>>   virtio-scsi: use virtqueue_error for errors with queue context
>>   virtio-crypto: use virtqueue_error for errors with queue context
>>   checkpatch: add virtio_error and virtqueue_error to error funcs
>>
>>  hw/9pfs/virtio-9p-device.c |  37 ++
>>  hw/block/virtio-blk.c  |   6 +--
>>  hw/net/virtio-net.c|  24 -
>>  hw/scsi/virtio-scsi.c  |   2 +-
>>  hw/virtio/virtio-crypto.c  |  49 ++-
>>  hw/virtio/virtio.c | 119 
>> +++--
>>  include/hw/virtio/virtio.h |   1 +
>>  scripts/checkpatch.pl  |   4 +-
>>  8 files changed, 143 insertions(+), 99 deletions(-)
>
> Looks good.  QEMU is currently in freeze for the 2.10 release.  You may
> need to resend so Michael Tsirkin can merge it after the release, or if
> he maintainers a -next branch he could merge it right away.

Should I resend the series, Michael?

Thanks,
Ladi



Re: [Qemu-devel] [PATCH] virtio-input: send rel-wheel events for wheel buttons

2017-08-29 Thread Ladi Prosek
On Wed, Aug 23, 2017 at 3:51 PM, Gerd Hoffmann  wrote:
> qemu uses wheel-up/down button events for mouse wheel input, however
> linux applications typically want REL_WHEEL events.
>
> This fixes wheel with linux guests. Tested with X11/wayland, and
> windows virtio-input driver.
>
> Based on a patch from Marc.
> Added property to enable/disable wheel axis.
> TODO: add compat properties for old machine types.
>
> Cc: Marc-André Lureau 
> Signed-off-by: Gerd Hoffmann 

Verified that the Windows driver correctly handles axis-based wheel. Thanks!

Tested-by: Ladi Prosek 



Re: [Qemu-devel] [PATCH v2 1/4] i386/kvm: use a switch statement for MSR detection

2017-08-07 Thread Ladi Prosek
On Mon, Aug 7, 2017 at 4:19 PM, David Hildenbrand  wrote:
> On 07.08.2017 10:57, Ladi Prosek wrote:
>> Switch is easier on the eye and might lead to better codegen.
>>
>> Signed-off-by: Ladi Prosek 
>> ---
>>  target/i386/kvm.c | 75 
>> +++
>>  1 file changed, 31 insertions(+), 44 deletions(-)
>>
>> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
>> index 6db7783..b14a0db 100644
>> --- a/target/i386/kvm.c
>> +++ b/target/i386/kvm.c
>> @@ -1081,65 +1081,52 @@ static int kvm_get_supported_msrs(KVMState *s)
>>  int i;
>>
>>  for (i = 0; i < kvm_msr_list->nmsrs; i++) {
>> -if (kvm_msr_list->indices[i] == MSR_STAR) {
>> +switch (kvm_msr_list->indices[i]) {
>> +case MSR_STAR:
>>  has_msr_star = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {
>> +break;
>> +case MSR_VM_HSAVE_PA:
>>  has_msr_hsave_pa = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_TSC_AUX) {
>> +break;
>> +case MSR_TSC_AUX:
>>  has_msr_tsc_aux = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_TSC_ADJUST) {
>> +break;
>> +case MSR_TSC_ADJUST:
>>  has_msr_tsc_adjust = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_IA32_TSCDEADLINE) {
>> +break;
>> +case MSR_IA32_TSCDEADLINE:
>>  has_msr_tsc_deadline = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_IA32_SMBASE) {
>> +break;
>> +case MSR_IA32_SMBASE:
>>  has_msr_smbase = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_IA32_MISC_ENABLE) {
>> +break;
>> +case MSR_IA32_MISC_ENABLE:
>>  has_msr_misc_enable = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_IA32_BNDCFGS) {
>> +break;
>> +case MSR_IA32_BNDCFGS:
>>  has_msr_bndcfgs = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == MSR_IA32_XSS) {
>> +break;
>> +case MSR_IA32_XSS:
>>  has_msr_xss = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == HV_X64_MSR_CRASH_CTL) {
>> +break;;
>> +case HV_X64_MSR_CRASH_CTL:
>>  has_msr_hv_crash = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == HV_X64_MSR_RESET) {
>> +break;
>> +case HV_X64_MSR_RESET:
>>  has_msr_hv_reset = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) {
>> +break;
>> +case HV_X64_MSR_VP_INDEX:
>>  has_msr_hv_vpindex = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) {
>> +break;
>> +case HV_X64_MSR_VP_RUNTIME:
>>  has_msr_hv_runtime = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
>> +break;
>> +case HV_X64_MSR_SCONTROL:
>>  has_msr_hv_synic = true;
>> -continue;
>> -}
>> -if (kvm_msr_list->indices[i] == HV_X64_MSR_STIMER0_CONFIG) {
>> +break;
>> +case HV_X64_MSR_STIMER0_CONFIG:
>>  has_msr_hv_stimer = true;
>> -continue;
>> +break;
>>  }
>>  }
>>  }
>>
>
> Think you forgot to add my r-b.

Oops, sorry about that!

> --
>
> Thanks,
>
> David



[Qemu-devel] [PATCH v2 4/4] i386/kvm: advertise Hyper-V frequency MSRs

2017-08-07 Thread Ladi Prosek
As of kernel commit eb82feea59d6 ("KVM: hyperv: support HV_X64_MSR_TSC_FREQUENCY
and HV_X64_MSR_APIC_FREQUENCY"), KVM supports two new MSRs which are required
for nested Hyper-V to read timestamps with RDTSC + TSC page.

This commit makes QEMU advertise the MSRs with CPUID.4003H:EAX[11] and
CPUID.4003H:EDX[8] as specified in the Hyper-V TLFS and experimentally
verified on a Hyper-V host. The feature is enabled with the existing hv-time CPU
flag, and only if the TSC frequency is stable across migrations and known.

Signed-off-by: Ladi Prosek 
---
 target/i386/kvm.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 2dc01c9..739334a 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -89,6 +89,7 @@ static bool has_msr_hv_vpindex;
 static bool has_msr_hv_runtime;
 static bool has_msr_hv_synic;
 static bool has_msr_hv_stimer;
+static bool has_msr_hv_frequencies;
 static bool has_msr_xss;
 
 static bool has_msr_architectural_pmu;
@@ -640,7 +641,13 @@ static int hyperv_handle_properties(CPUState *cs)
 if (cpu->hyperv_time) {
 env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_HYPERCALL_AVAILABLE;
 env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
-env->features[FEAT_HYPERV_EAX] |= 0x200;
+env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_REFERENCE_TSC_AVAILABLE;
+
+if (has_msr_hv_frequencies && tsc_is_stable_and_known(env)) {
+env->features[FEAT_HYPERV_EAX] |= HV_X64_ACCESS_FREQUENCY_MSRS;
+env->features[FEAT_HYPERV_EDX] |=
+HV_FEATURE_FREQUENCY_MSRS_AVAILABLE;
+}
 }
 if (cpu->hyperv_crash && has_msr_hv_crash) {
 env->features[FEAT_HYPERV_EDX] |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
@@ -1134,6 +1141,9 @@ static int kvm_get_supported_msrs(KVMState *s)
 case HV_X64_MSR_STIMER0_CONFIG:
 has_msr_hv_stimer = true;
 break;
+case HV_X64_MSR_TSC_FREQUENCY:
+has_msr_hv_frequencies = true;
+break;
 }
 }
 }
-- 
2.9.3




[Qemu-devel] [PATCH v2 2/4] i386/kvm: set tsc_khz before configuring Hyper-V CPUID

2017-08-07 Thread Ladi Prosek
Timing-related Hyper-V enlightenments will benefit from knowing the final
tsc_khz value. This commit just moves the code in preparation for further
changes.

Signed-off-by: Ladi Prosek 
---
 target/i386/kvm.c | 38 +++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index b14a0db..15d56ae 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -695,6 +695,25 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
 cpuid_i = 0;
 
+r = kvm_arch_set_tsc_khz(cs);
+if (r < 0) {
+goto fail;
+}
+
+/* vcpu's TSC frequency is either specified by user, or following
+ * the value used by KVM if the former is not present. In the
+ * latter case, we query it from KVM and record in env->tsc_khz,
+ * so that vcpu's TSC frequency can be migrated later via this field.
+ */
+if (!env->tsc_khz) {
+r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
+-ENOTSUP;
+if (r > 0) {
+env->tsc_khz = r;
+}
+}
+
 /* Paravirtualization CPUIDs */
 if (hyperv_enabled(cpu)) {
 c = &cpuid_data.entries[cpuid_i++];
@@ -961,25 +980,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 }
 
-r = kvm_arch_set_tsc_khz(cs);
-if (r < 0) {
-goto fail;
-}
-
-/* vcpu's TSC frequency is either specified by user, or following
- * the value used by KVM if the former is not present. In the
- * latter case, we query it from KVM and record in env->tsc_khz,
- * so that vcpu's TSC frequency can be migrated later via this field.
- */
-if (!env->tsc_khz) {
-r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
-kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
--ENOTSUP;
-if (r > 0) {
-env->tsc_khz = r;
-}
-}
-
 if (cpu->vmware_cpuid_freq
 /* Guests depend on 0x4000 to detect this feature, so only expose
  * it if KVM exposes leaf 0x4000. (Conflicts with Hyper-V) */
-- 
2.9.3




[Qemu-devel] [PATCH v2 1/4] i386/kvm: use a switch statement for MSR detection

2017-08-07 Thread Ladi Prosek
Switch is easier on the eye and might lead to better codegen.

Signed-off-by: Ladi Prosek 
---
 target/i386/kvm.c | 75 +++
 1 file changed, 31 insertions(+), 44 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 6db7783..b14a0db 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1081,65 +1081,52 @@ static int kvm_get_supported_msrs(KVMState *s)
 int i;
 
 for (i = 0; i < kvm_msr_list->nmsrs; i++) {
-if (kvm_msr_list->indices[i] == MSR_STAR) {
+switch (kvm_msr_list->indices[i]) {
+case MSR_STAR:
 has_msr_star = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {
+break;
+case MSR_VM_HSAVE_PA:
 has_msr_hsave_pa = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_TSC_AUX) {
+break;
+case MSR_TSC_AUX:
 has_msr_tsc_aux = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_TSC_ADJUST) {
+break;
+case MSR_TSC_ADJUST:
 has_msr_tsc_adjust = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_TSCDEADLINE) {
+break;
+case MSR_IA32_TSCDEADLINE:
 has_msr_tsc_deadline = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_SMBASE) {
+break;
+case MSR_IA32_SMBASE:
 has_msr_smbase = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_MISC_ENABLE) {
+break;
+case MSR_IA32_MISC_ENABLE:
 has_msr_misc_enable = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_BNDCFGS) {
+break;
+case MSR_IA32_BNDCFGS:
 has_msr_bndcfgs = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_XSS) {
+break;
+case MSR_IA32_XSS:
 has_msr_xss = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_CRASH_CTL) {
+break;;
+case HV_X64_MSR_CRASH_CTL:
 has_msr_hv_crash = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_RESET) {
+break;
+case HV_X64_MSR_RESET:
 has_msr_hv_reset = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) {
+break;
+case HV_X64_MSR_VP_INDEX:
 has_msr_hv_vpindex = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) {
+break;
+case HV_X64_MSR_VP_RUNTIME:
 has_msr_hv_runtime = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
+break;
+case HV_X64_MSR_SCONTROL:
 has_msr_hv_synic = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_STIMER0_CONFIG) {
+break;
+case HV_X64_MSR_STIMER0_CONFIG:
 has_msr_hv_stimer = true;
-continue;
+break;
 }
 }
 }
-- 
2.9.3




[Qemu-devel] [PATCH v2 0/4] i386/kvm: advertise Hyper-V frequency MSRs

2017-08-07 Thread Ladi Prosek
This is the QEMU part of the changes required for nested Hyper-V to read
timestamps with RDTSC + TSC page. Without exposing the frequency MSRs,
Windows with the Hyper-V role enabled use the much slower
HV_X64_MSR_TIME_REF_COUNT (0x4020) RDMSR to read timestamps.

The new registers are exposed only if the TSC frequency is stable across
migration and known, as suggested by Paolo.

v1->v2:
* deleted an extra empty line in patch 1
* added patch 3 introducing a helper function for the "TSC is stable and
  known" check (David)

Ladi Prosek (4):
  i386/kvm: use a switch statement for MSR detection
  i386/kvm: set tsc_khz before configuring Hyper-V CPUID
  i386/kvm: introduce tsc_is_stable_and_known()
  i386/kvm: advertise Hyper-V frequency MSRs

 target/i386/kvm.c | 138 --
 1 file changed, 71 insertions(+), 67 deletions(-)

-- 
2.9.3




[Qemu-devel] [PATCH v2 3/4] i386/kvm: introduce tsc_is_stable_and_known()

2017-08-07 Thread Ladi Prosek
Move the "is TSC stable and known" condition to a reusable helper.

Signed-off-by: Ladi Prosek 
---
 target/i386/kvm.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 15d56ae..2dc01c9 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -611,6 +611,15 @@ static int kvm_arch_set_tsc_khz(CPUState *cs)
 return 0;
 }
 
+static bool tsc_is_stable_and_known(CPUX86State *env)
+{
+if (!env->tsc_khz) {
+return false;
+}
+return (env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC)
+|| env->user_tsc_khz;
+}
+
 static int hyperv_handle_properties(CPUState *cs)
 {
 X86CPU *cpu = X86_CPU(cs);
@@ -986,9 +995,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 && cpu->expose_kvm
 && kvm_base == KVM_CPUID_SIGNATURE
 /* TSC clock must be stable and known for this feature. */
-&& ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC)
-|| env->user_tsc_khz != 0)
-&& env->tsc_khz != 0) {
+&& tsc_is_stable_and_known(env)) {
 
 c = &cpuid_data.entries[cpuid_i++];
 c->function = KVM_CPUID_SIGNATURE | 0x10;
-- 
2.9.3




Re: [Qemu-devel] [PATCH 3/3] i386/kvm: advertise Hyper-V frequency MSRs

2017-08-04 Thread Ladi Prosek
On Fri, Aug 4, 2017 at 3:39 PM, David Hildenbrand  wrote:
> On 04.08.2017 11:14, Ladi Prosek wrote:
>> As of kernel commit eb82feea59d6 ("KVM: hyperv: support 
>> HV_X64_MSR_TSC_FREQUENCY
>> and HV_X64_MSR_APIC_FREQUENCY"), KVM supports two new MSRs which are required
>> for nested Hyper-V to read timestamps with RDTSC + TSC page.
>>
>> This commit makes QEMU advertise the MSRs with CPUID.4003H:EAX[11] and
>> CPUID.4003H:EDX[8] as specified in the Hyper-V TLFS and experimentally
>> verified on a Hyper-V host. The feature is enabled with the existing hv-time 
>> CPU
>> flag, and only if the TSC frequency is stable across migration and known.
>>
>> Signed-off-by: Ladi Prosek 
>> ---
>>  target/i386/kvm.c | 16 +++-
>>  1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
>> index 77b6373..7e484a7 100644
>> --- a/target/i386/kvm.c
>> +++ b/target/i386/kvm.c
>> @@ -89,6 +89,7 @@ static bool has_msr_hv_vpindex;
>>  static bool has_msr_hv_runtime;
>>  static bool has_msr_hv_synic;
>>  static bool has_msr_hv_stimer;
>> +static bool has_msr_hv_frequencies;
>>  static bool has_msr_xss;
>>
>>  static bool has_msr_architectural_pmu;
>> @@ -631,7 +632,17 @@ static int hyperv_handle_properties(CPUState *cs)
>>  if (cpu->hyperv_time) {
>>  env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_HYPERCALL_AVAILABLE;
>>  env->features[FEAT_HYPERV_EAX] |= 
>> HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
>> -env->features[FEAT_HYPERV_EAX] |= 0x200;
>> +env->features[FEAT_HYPERV_EAX] |= 
>> HV_X64_MSR_REFERENCE_TSC_AVAILABLE;
>> +if (has_msr_hv_frequencies> +/* TSC clock must be 
>> stable and known for this feature. */
>> +&& ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC)
>> +|| env->user_tsc_khz != 0)
>> +&& env->tsc_khz != 0) {
>
> I'd drop the != 0 in both cases and move the env->tsc_khz check up to
> has_msr_hv_frequencies.
>
> if (has_msr_hv_frequencies && env->tsc_khz && ...
>
> Wonder if it even would make sense to move some parts of this check into
> a helper function, to beautify this a bit. tsc_stable(env)
> tsc_known(env) ...

Yup, especially since I copied these conditions from "if
(cpu->vmware_cpuid_freq .." further down in the file. So maybe one
helper called by both would be the best. Thanks!

>> +
>> +env->features[FEAT_HYPERV_EAX] |= HV_X64_ACCESS_FREQUENCY_MSRS;
>> +env->features[FEAT_HYPERV_EDX] |=
>> +HV_FEATURE_FREQUENCY_MSRS_AVAILABLE;
>> +}
>>  }
>>  if (cpu->hyperv_crash && has_msr_hv_crash) {
>>  env->features[FEAT_HYPERV_EDX] |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
>> @@ -1127,6 +1138,9 @@ static int kvm_get_supported_msrs(KVMState *s)
>>  case HV_X64_MSR_STIMER0_CONFIG:
>>  has_msr_hv_stimer = true;
>>  break;
>> +case HV_X64_MSR_TSC_FREQUENCY:
>> +has_msr_hv_frequencies = true;
>> +break;
>>  }
>>
>>  }
>>
>
>
> --
>
> Thanks,
>
> David



[Qemu-devel] [PATCH 2/3] i386/kvm: set tsc_khz before configuring Hyper-V CPUID

2017-08-04 Thread Ladi Prosek
Timing-related Hyper-V enlightenments will benefit from knowing the final
tsc_khz value. This commit just moves the code in preparation for further
changes.

Signed-off-by: Ladi Prosek 
---
 target/i386/kvm.c | 38 +++---
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index ed119ca..77b6373 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -695,6 +695,25 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
 cpuid_i = 0;
 
+r = kvm_arch_set_tsc_khz(cs);
+if (r < 0) {
+goto fail;
+}
+
+/* vcpu's TSC frequency is either specified by user, or following
+ * the value used by KVM if the former is not present. In the
+ * latter case, we query it from KVM and record in env->tsc_khz,
+ * so that vcpu's TSC frequency can be migrated later via this field.
+ */
+if (!env->tsc_khz) {
+r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
+kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
+-ENOTSUP;
+if (r > 0) {
+env->tsc_khz = r;
+}
+}
+
 /* Paravirtualization CPUIDs */
 if (hyperv_enabled(cpu)) {
 c = &cpuid_data.entries[cpuid_i++];
@@ -961,25 +980,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 }
 
-r = kvm_arch_set_tsc_khz(cs);
-if (r < 0) {
-goto fail;
-}
-
-/* vcpu's TSC frequency is either specified by user, or following
- * the value used by KVM if the former is not present. In the
- * latter case, we query it from KVM and record in env->tsc_khz,
- * so that vcpu's TSC frequency can be migrated later via this field.
- */
-if (!env->tsc_khz) {
-r = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?
-kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :
--ENOTSUP;
-if (r > 0) {
-env->tsc_khz = r;
-}
-}
-
 if (cpu->vmware_cpuid_freq
 /* Guests depend on 0x4000 to detect this feature, so only expose
  * it if KVM exposes leaf 0x4000. (Conflicts with Hyper-V) */
-- 
2.9.3




[Qemu-devel] [PATCH 0/3] i386/kvm: advertise Hyper-V frequency MSRs

2017-08-04 Thread Ladi Prosek
This is the QEMU part of the changes required for nested Hyper-V to read
timestamps with RDTSC + TSC page. Without exposing the frequency MSRs,
Windows with the Hyper-V role enabled use the much slower
HV_X64_MSR_TIME_REF_COUNT (0x4020) RDMSR to read timestamps.

The new registers are exposed only if the TSC frequency is stable across
migration and known, as suggested by Paolo.

Ladi Prosek (3):
  i386/kvm: use a switch statement for MSR detection
  i386/kvm: set tsc_khz before configuring Hyper-V CPUID
  i386/kvm: advertise Hyper-V frequency MSRs

 target/i386/kvm.c | 130 +++---
 1 file changed, 66 insertions(+), 64 deletions(-)

-- 
2.9.3




[Qemu-devel] [PATCH 3/3] i386/kvm: advertise Hyper-V frequency MSRs

2017-08-04 Thread Ladi Prosek
As of kernel commit eb82feea59d6 ("KVM: hyperv: support HV_X64_MSR_TSC_FREQUENCY
and HV_X64_MSR_APIC_FREQUENCY"), KVM supports two new MSRs which are required
for nested Hyper-V to read timestamps with RDTSC + TSC page.

This commit makes QEMU advertise the MSRs with CPUID.4003H:EAX[11] and
CPUID.4003H:EDX[8] as specified in the Hyper-V TLFS and experimentally
verified on a Hyper-V host. The feature is enabled with the existing hv-time CPU
flag, and only if the TSC frequency is stable across migration and known.

Signed-off-by: Ladi Prosek 
---
 target/i386/kvm.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 77b6373..7e484a7 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -89,6 +89,7 @@ static bool has_msr_hv_vpindex;
 static bool has_msr_hv_runtime;
 static bool has_msr_hv_synic;
 static bool has_msr_hv_stimer;
+static bool has_msr_hv_frequencies;
 static bool has_msr_xss;
 
 static bool has_msr_architectural_pmu;
@@ -631,7 +632,17 @@ static int hyperv_handle_properties(CPUState *cs)
 if (cpu->hyperv_time) {
 env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_HYPERCALL_AVAILABLE;
 env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_TIME_REF_COUNT_AVAILABLE;
-env->features[FEAT_HYPERV_EAX] |= 0x200;
+env->features[FEAT_HYPERV_EAX] |= HV_X64_MSR_REFERENCE_TSC_AVAILABLE;
+if (has_msr_hv_frequencies
+/* TSC clock must be stable and known for this feature. */
+&& ((env->features[FEAT_8000_0007_EDX] & CPUID_APM_INVTSC)
+|| env->user_tsc_khz != 0)
+&& env->tsc_khz != 0) {
+
+env->features[FEAT_HYPERV_EAX] |= HV_X64_ACCESS_FREQUENCY_MSRS;
+env->features[FEAT_HYPERV_EDX] |=
+HV_FEATURE_FREQUENCY_MSRS_AVAILABLE;
+}
 }
 if (cpu->hyperv_crash && has_msr_hv_crash) {
 env->features[FEAT_HYPERV_EDX] |= HV_X64_GUEST_CRASH_MSR_AVAILABLE;
@@ -1127,6 +1138,9 @@ static int kvm_get_supported_msrs(KVMState *s)
 case HV_X64_MSR_STIMER0_CONFIG:
 has_msr_hv_stimer = true;
 break;
+case HV_X64_MSR_TSC_FREQUENCY:
+has_msr_hv_frequencies = true;
+break;
 }
 
 }
-- 
2.9.3




[Qemu-devel] [PATCH 1/3] i386/kvm: use a switch statement for MSR detection

2017-08-04 Thread Ladi Prosek
Switch is easier on the eye and might lead to better codegen.

Signed-off-by: Ladi Prosek 
---
 target/i386/kvm.c | 76 +++
 1 file changed, 32 insertions(+), 44 deletions(-)

diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 6db7783..ed119ca 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1081,66 +1081,54 @@ static int kvm_get_supported_msrs(KVMState *s)
 int i;
 
 for (i = 0; i < kvm_msr_list->nmsrs; i++) {
-if (kvm_msr_list->indices[i] == MSR_STAR) {
+switch (kvm_msr_list->indices[i]) {
+case MSR_STAR:
 has_msr_star = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {
+break;
+case MSR_VM_HSAVE_PA:
 has_msr_hsave_pa = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_TSC_AUX) {
+break;
+case MSR_TSC_AUX:
 has_msr_tsc_aux = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_TSC_ADJUST) {
+break;
+case MSR_TSC_ADJUST:
 has_msr_tsc_adjust = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_TSCDEADLINE) {
+break;
+case MSR_IA32_TSCDEADLINE:
 has_msr_tsc_deadline = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_SMBASE) {
+break;
+case MSR_IA32_SMBASE:
 has_msr_smbase = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_MISC_ENABLE) {
+break;
+case MSR_IA32_MISC_ENABLE:
 has_msr_misc_enable = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_BNDCFGS) {
+break;
+case MSR_IA32_BNDCFGS:
 has_msr_bndcfgs = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == MSR_IA32_XSS) {
+break;
+case MSR_IA32_XSS:
 has_msr_xss = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_CRASH_CTL) {
+break;;
+case HV_X64_MSR_CRASH_CTL:
 has_msr_hv_crash = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_RESET) {
+break;
+case HV_X64_MSR_RESET:
 has_msr_hv_reset = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_INDEX) {
+break;
+case HV_X64_MSR_VP_INDEX:
 has_msr_hv_vpindex = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_VP_RUNTIME) {
+break;
+case HV_X64_MSR_VP_RUNTIME:
 has_msr_hv_runtime = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_SCONTROL) {
+break;
+case HV_X64_MSR_SCONTROL:
 has_msr_hv_synic = true;
-continue;
-}
-if (kvm_msr_list->indices[i] == HV_X64_MSR_STIMER0_CONFIG) {
+break;
+case HV_X64_MSR_STIMER0_CONFIG:
 has_msr_hv_stimer = true;
-continue;
+break;
 }
+
 }
 }
 
-- 
2.9.3




Re: [Qemu-devel] [PATCH] pc: acpi: force FADT rev1 for old i440fx machine types

2017-07-26 Thread Ladi Prosek
On Tue, Jul 25, 2017 at 3:26 PM, Michael S. Tsirkin  wrote:
> On Mon, Jul 24, 2017 at 08:48:48AM +0200, Igor Mammedov wrote:
>> On Sat, 22 Jul 2017 02:40:46 +0300
>> "Michael S. Tsirkin"  wrote:
>>
>> > On Fri, Jul 21, 2017 at 12:10:48PM +0200, Igor Mammedov wrote:
>> > > On Fri, 21 Jul 2017 10:49:55 +0100
>> > > "Daniel P. Berrange"  wrote:
>> > >
>> > > > On Fri, Jul 21, 2017 at 11:32:11AM +0200, Igor Mammedov wrote:
>> > > > > w2k used to boot on QEMU until we bumped revision of FADT to rev3
>> > > > > (commit 77af8a2b hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 
>> > > > > to improve guest OS support.)
>> > > > >
>> > > > > Considering that w2k is ancient and long time EOLed, leave default
>> > > > > rev3 but make pc-i440fx-2.9 and older machine types to force rev1
>> > > > > so old setups won't break (w2k could boot).
>> > > >
>> > > > There needs to be a machine type property added to control this
>> > > > feature. When provisioning new VMs, management apps need to be
>> > > > able to set the property explicitly - having them rely on picking
>> > > > particular machine type name+versions is not viable, because
>> > > > downstream vendors replace the machine types with their own
>> > > > names + versions.
>> > > having property doesn't really help here and we don't do it for every
>> > > compat tweak /ex: save_tsc_khz, linuxboot_dma_enabled/.
>> > >
>> > > Management would not benefit much from having property vs machine version
>> > > as it would have to encode somewhere that for w2k it should set
>> > > some machine property or pick a particular machine type.
>> >
>> > I think I'd disagree with that. If
>> > users might need this for compatibility with some guests,
>> > then it should be a property not just a machine type.
>> >
>> > But see below - I think we rushed it for the PC anyway.
>> >
>> > > Probably no one would worry about fixing virt-install or something
>> > > else for the sake of w2k and if they are going to fix it
>> > > it doesn't matter if they map machine type vs property.
>> > >
>> > > Also with new machine type deprecation policy we would be able
>> > > easily to phase out rev1 support along with 2.9 machine,
>> > > but if you expose property then removing it would break
>> > > CLI not only for 2.9 but possible later machines if it's set there.
>> > >
>> > > So I'm against adding properties/CLI options for unless we have to in 
>> > > this case,
>> > > and I'm not convinced that w2k deserves it.
>> >
>> > If I have to choose, I'd say Mac OSX is way less interesting than old
>> > windows versions. Lots of people have software that will only run on old
>> > windows and there's probably good money to be had running it on new
>> > hardware in VMs. And PC machine is all about compatibility - we have Q35
>> > for new stuff.  Besides OSX uses q35 anyway I think.
>> Question is for how long we are going to maintain legacy stuff,
>> ACPI spec periodically adds new stuff, which someday is going
>> to break legacy OSes. And maintaining 2 branches of or worse
>> a mix will cost us in time and future regressions, we need to
>> have some policy to cut off legacy features that hold us back,
>> like we are starting to do with machine types.
>> w2k has been EOLed in 2010 even if we drop its support now,
>> users still can use it as they have an option to use old QEMU
>> for that.
>
> Users can't normally get old QEMU, even if they could it is not
> a good idea because of security.
>
>> (Ladi said that w2k fails to install since 2.7).
>
> Bisect will likely find what's wrong.

I still intend to find the issue. Unlike this FADT revision/length
problem, setup fails after a long time, basically at the very end of
the process. I tried to speed up bisecting it by saving the state of
the VM before the failure and running just the problematic part but it
didn't work. I'll just have to bite the bullet and run setup from the
beginning every time.

>> >
>> > So maybe the right thing to do is to
>> > - switch default for PC back to rev 1
>> > - keep default for Q35 at rev 3
>> >
>> > No machinetype hacks.
>> it's still machine hack pc vs q35 and an extra branch to look
>> after but it's better than an option, I'll respin patch.
>>
>> >
>> > > > >
>> > > > > Signed-off-by: Igor Mammedov 
>> > > > > ---
>> > > > > CC: Programmingkid 
>> > > > > CC: Phil Dennis-Jordan 
>> > > > > CC: "Michael S. Tsirkin" 
>> > > > >
>> > > > > Only compile test since I don't have w2k to test with
>> > > > >
>> > > > > ---
>> > > > >  include/hw/i386/pc.h |  1 +
>> > > > >  hw/i386/acpi-build.c | 26 +++---
>> > > > >  hw/i386/pc_piix.c|  2 ++
>> > > > >  3 files changed, 22 insertions(+), 7 deletions(-)
>> > > > >
>> > > > > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
>> > > > > index d80859b..d6f65dd 100644
>> > > > > --- a/include/hw/i386/pc.h
>> > > > > +++ b/include/hw/i386/pc.h
>> > > > > @@ -122,6 +122,7 @@ struct PCMachineClass {
>> > > > >  bool rsdp_in_ram;
>> > > > >  i

Re: [Qemu-devel] [PATCH] pc: acpi: force FADT rev1 for old i440fx machine types

2017-07-24 Thread Ladi Prosek
On Fri, Jul 21, 2017 at 12:12 PM, Igor Mammedov  wrote:
> On Fri, 21 Jul 2017 11:54:20 +0200
> Ladi Prosek  wrote:
>
>> On Fri, Jul 21, 2017 at 11:32 AM, Igor Mammedov  wrote:
>> > w2k used to boot on QEMU until we bumped revision of FADT to rev3
>> > (commit 77af8a2b hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to 
>> > improve guest OS support.)
>> >
>> > Considering that w2k is ancient and long time EOLed, leave default
>> > rev3 but make pc-i440fx-2.9 and older machine types to force rev1
>> > so old setups won't break (w2k could boot).
>> >
>> > Signed-off-by: Igor Mammedov 
>> > ---
>> > CC: Programmingkid 
>> > CC: Phil Dennis-Jordan 
>> > CC: "Michael S. Tsirkin" 
>> >
>> > Only compile test since I don't have w2k to test with
>>
>> Confirming that Windows 2000 boots with this patch and -machine 
>> pc-i440fx-2.9.
> Ladi,
>
> Could you to try find out reason why w2k doesn't boot?

The FADT table must be 134 bytes or less. The revision number does not
matter and neither does the checksum.

This is experimental data, I haven't been able to find the offending code.

>>
>> Tested-by: Ladi Prosek 
>



Re: [Qemu-devel] [PATCH] pc: acpi: force FADT rev1 for old i440fx machine types

2017-07-21 Thread Ladi Prosek
On Fri, Jul 21, 2017 at 11:32 AM, Igor Mammedov  wrote:
> w2k used to boot on QEMU until we bumped revision of FADT to rev3
> (commit 77af8a2b hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to improve 
> guest OS support.)
>
> Considering that w2k is ancient and long time EOLed, leave default
> rev3 but make pc-i440fx-2.9 and older machine types to force rev1
> so old setups won't break (w2k could boot).
>
> Signed-off-by: Igor Mammedov 
> ---
> CC: Programmingkid 
> CC: Phil Dennis-Jordan 
> CC: "Michael S. Tsirkin" 
>
> Only compile test since I don't have w2k to test with

Confirming that Windows 2000 boots with this patch and -machine pc-i440fx-2.9.

Tested-by: Ladi Prosek 



Re: [Qemu-devel] [PATCH v4 0/8] KASLR kernel dump support

2017-07-18 Thread Ladi Prosek
On Tue, Jul 18, 2017 at 6:18 PM, Marc-André Lureau
 wrote:
> Hi
>
> On Tue, Jul 18, 2017 at 6:05 PM Ladi Prosek  wrote:
>>
>>
>> > I would like to hear from Ladi how he intended to use the device in
>> > the future, and if he would also prefer ACPI methods and what those
>> > methods should be.
>>
>> We should be able to drive pretty much anything from Windows. I wrote
>> a dummy driver for your earlier prototype just to be sure that ACPI
>> methods are fine, as I had not done or seen that before.
>>
>> There are constraints which may be unique to Windows, though. If the
>> dump-support data is kept in guest-allocated memory, the guest must be
>> able to revoke it (set / call the method with NULL PA?) because
>> Windows drivers must free everything on unload. Unlike Linux, I don't
>
>
> Well, the currently proposed vmcoreinfo device has a 4k memory region to put
> anything you want, Windows shouldn't be allowed to touch it directly (e820
> regions iirc)

Got it. And we would likely use it to put just addr/size there to make
updates atomic. I think we're supposed to update our dump-support data
on memory hot-plug for example.

>> think we can get a piece of memory at startup and keep it for as long
>> as the OS running. It would be flagged as a memory leak. But that
>> should be easy to have. Can't really think of anything else.
>
>
> The question is what kind of data you want to give to the host to help with
> debug. Is this something that can be as simple as addr/size, or you would
> rather have a 4k page to put various things there.

The size of the dump header as currently provided by Windows (that's
the dump-support data we want to pass to the host) is 4k. So I
wouldn't put it directly in the page anyway. That, plus the desire to
update the data at least somewhat atomically, would make me prefer a
simple addr/size pair I think.

>>
>>
>> >>>
>> >>> >> > instead of exporting a physical addess and storing address there.
>> >>> >> > This
>> >>> >> > way you can add more methods as you add functionality.
>> >>> >>
>> >>> >> I'm not saying this is a bad idea (especially because I don't fully
>> >>> >> understand your point), but I will say that I'm quite sad that you
>> >>> >> are
>> >>> >> sending Marc-André back to the drawing board after he posted v4 --
>> >>> >> also
>> >>> >> invalidating my review efforts. :/
>> >>> >>
>> >>> >> Laszlo
>> >>> >
>> >>> > You are right, I should have looked at this sooner. Early RFC
>> >>> > suggested writing into fw cfg directly. I couldn't find any
>> >>> > discussion around this - why was this abandoned?
>> >>>
>> >>> Violation (or rather abuse) of layers iirc
>> >>
>> >> Hmm.  I tried to find discussion about that and failed.  It is
>> >> available
>> >> through QEMU0002 in ACPI - would it be OK if guests went through that?
>> >
>> > I wouldn't mind, although merging functionality in a single device
>> > isn't what I would think of first. I guess Ladi would be happier with
>> > a single device. I suppose it shouldn't break drivers if we had
>> > memory, io, methods etc to the device?
>>
>> Yeah, it would be nice if this was part of pvpanic. Even something
>> really simple like:
>>
>>  /* The bit of supported pv event */
>>  #define PVPANIC_F_PANICKED  0
>> +#define PVPANIC_F_DUMP_INFO_SET  1
>
>
> QEMU0002 is fw_cfg

Ah, sorry, I got confused.

>>
>>
>> - memory_region_init_io(&s->io, OBJECT(s), &pvpanic_ops, s, "pvpanic",
>> 1);
>> +memory_region_init_io(&s->io, OBJECT(s), &pvpanic_ops, s,
>> "pvpanic", 32); // or whatever
>>
>> The guest writes to two or three registers: PA, size, type?, then sets
>> the PVPANIC_F_DUMP_INFO_SET bit.
>>
>> Although not sure if extending the I/O region is OK. And of course I
>> only need this on x86 :p
>>
>
> I would rather have a solution that works on various archs. It's a shame
> pvpanic was designed with x86 only in mind imho.

Understood. Thanks!

>
> --
> Marc-André Lureau



Re: [Qemu-devel] [PATCH v4 0/8] KASLR kernel dump support

2017-07-18 Thread Ladi Prosek
Hi Marc-Andre,

On Tue, Jul 18, 2017 at 3:29 PM, Marc-André Lureau
 wrote:
> Hi
>
> On Fri, Jul 14, 2017 at 4:29 PM, Michael S. Tsirkin  wrote:
>> On Sat, Jul 15, 2017 at 12:31:36AM +0200, Marc-André Lureau wrote:
>>> Hi
>>>
>>> On Sat, Jul 15, 2017 at 12:23 AM, Michael S. Tsirkin  
>>> wrote:
>>> > On Fri, Jul 14, 2017 at 10:21:43PM +0200, Laszlo Ersek wrote:
>>> >> On 07/14/17 21:59, Michael S. Tsirkin wrote:
>>> >> > On Fri, Jul 14, 2017 at 08:20:03PM +0200, Marc-André Lureau wrote:
>>> >> >> Recent linux kernels enable KASLR to randomize phys/virt memory
>>> >> >> addresses. This series aims to provide enough information in qemu
>>> >> >> dumps so that crash utility can work with randomized kernel too (it
>>> >> >> hasn't been tested on other archs than x86 though, help welcome).
>>> >> >>
>>> >> >> The vmcoreinfo device is an emulated ACPI device that exposes a 4k
>>> >> >> memory range to the guest to store various informations useful to
>>> >> >> debug the guest OS. (it is greatly inspired by the VMGENID device
>>> >> >> implementation). The version field with value 0 is meant to give
>>> >> >> paddr/size of the VMCOREINFO ELF PT_NOTE, other values can be used for
>>> >> >> different purposes or OSes. (note: some wanted to see pvpanic somehow
>>> >> >> merged with this device, I have no clear idea how to do that, nor do I
>>> >> >> think this is a good idea since the devices are quite different, used
>>> >> >> at different time for different purposes. And it can be done as a
>>> >> >> future iteration if it is appropriate, feel free to send patches)
>>> >> >
>>> >> > First, I think you underestimate the difficulty of maintaining
>>> >> > compatibility.
>>> >> >
>>> >> > Second, this seems racy - how do you know when is guest done writing 
>>> >> > out
>>> >> > the data?
>>> >>
>>> >> What data exactly?
>>> >>
>>> >> The guest kernel module points the fields in the "vmcoreinfo page" to
>>> >> the then-existent vmcoreinfo ELF note. At that point, the ELF note is
>>> >> complete.
>>> >
>>> > When does this happen?
>>>
>>> Very early boot afaik. But the exact details on when to expose it is
>>> left to the kernel side. For now, it's a test module I load manually.
>>>
>>> >
>>> >> If we catch the guest with a dump request while the kernel module is
>>> >> setting up the fields (i.e., the fields are not consistent), then we'll
>>> >> catch that in our sanity checks, and the note won't be extracted.
>>> >
>>> > Are there assumptions about e.g. in which order pa and size
>>> > are written out then? Atomicity of these writes?
>>>
>>> I expect it to be atomic, but as Laszlo said, the code should be quite
>>> careful when trying to read the data.
>>
>> Same when writing it out.  Worth documenting too.
>>
>>> >
>>> >> This
>>> >> is no different from the case when you simply dump the guest RAM before
>>> >> the module got invoked.
>>> >>
>>> >> > Given you have very little data to export (PA, size - do
>>> >> > you even need size?)
>>> >>
>>> >> Yes, it tells us in advance how much memory to allocate before we copy
>>> >> out the vmcoreinfo ELF note (and we enforce a sanity limit on the size).
>>> >>
>>> >> > - how about just using an ACPI method do it,
>>> >>
>>> >> Do what exactly?
>>> >
>>> > Pass address + size to host - that's what the interface is doing,
>>> > isn't it?
>>> >
>>>
>>>
>>> The memory region is meant to be usable for other OS, or to export
>>> more details in the future.
>>
>> That's the issue. You will never be able to increment version
>> just to add more data because that will break old hypervisors.
>
> Could you be more explicit on what will break?
>
>>
>>> I think if we add a method, it would be to
>>> tell qemu that the memory has been written, but it may still be
>>> corrupted at the time we read it. So I am not sure it will really help
>>
>> So don't. Just pass PA and size to method as arguments and let it figure
>> out how to pass it to QEMU. To extend, you will simply add another
>> method - which one is present tells you what does hypervisor
>> support, which one is called tells you what does guest support.
>>
>> What to do there internally? I don't mind it if it sticks this data
>> in reserved memory like you did here. And then you won't need to
>> reserve a full 4K, just a couple of bytes as it will be safe to extend.
>>
>
> I can see how for example nvdimm methods are implemented, there is a
> memory region reserved for data exchange, and an IO NTFY to give qemu
> execution context. Is this how we should design the interface?
>
> I would like to hear from Ladi how he intended to use the device in
> the future, and if he would also prefer ACPI methods and what those
> methods should be.

We should be able to drive pretty much anything from Windows. I wrote
a dummy driver for your earlier prototype just to be sure that ACPI
methods are fine, as I had not done or seen that before.

There are constraints which may be unique to Windows, though. If the
dump-support data is kept in gu

Re: [Qemu-devel] [PATCH v2 1/8] qemu-error: introduce error_report_nolf

2017-07-17 Thread Ladi Prosek
On Mon, Jul 17, 2017 at 10:58 AM, Daniel P. Berrange
 wrote:
> On Mon, Jul 17, 2017 at 08:54:18AM +0200, Ladi Prosek wrote:
>> On Fri, Jul 14, 2017 at 12:41 PM, Daniel P. Berrange
>>  wrote:
>> > On Thu, Jul 13, 2017 at 02:32:06PM +0100, Stefan Hajnoczi wrote:
>> >> On Thu, Jul 13, 2017 at 01:02:30PM +0200, Ladi Prosek wrote:
>> >> > +/*
>> >> > + * Print an error message to current monitor if we have one, else to 
>> >> > stderr.
>> >> > + * Format arguments like sprintf().  The resulting message should be a
>> >> > + * single phrase, with no trailing punctuation.  The no-LF version 
>> >> > allows
>> >> > + * additional text to be appended with error_printf() or 
>> >> > error_vprintf().
>> >> > + * Make sure to always close with a newline after all text is printed.
>> >> > + * Prepends the current location.
>> >> > + * It's wrong to call this in a QMP monitor.  Use error_setg() there.
>> >> > + */
>> >> > +void error_report_nolf(const char *fmt, ...)
>> >> > +{
>> >> > +va_list ap;
>> >> > +
>> >> > +va_start(ap, fmt);
>> >> > +error_vreport_nolf(fmt, ap);
>> >> > +va_end(ap);
>> >> >  }
>> >>
>> >> Each call to this function prepends the timestamp, so it cannot really
>> >> be used for a sequence of prints in a single line.
>> >>
>> >> It's a little ugly but I expected something along the lines of
>> >> g_strdup_vprintf() in virtio_error():
>> >>
>> >>   char *msg;
>> >>
>> >>   va_start(ap, fmt);
>> >>   msg = g_strdup_vprintf(fmt, ap);
>> >>   va_end(ap);
>> >>
>> >>   error_report("%s: %s", DEVICE(vdev)->id, msg);
>> >>
>> >>   g_free(msg);
>> >
>> > You could get the same thing by turning virtio_Error into a macro with
>> > a few games. Rename the current method to virtio_error_impl() and then
>> > define:
>> >
>> >   #define virtio_error(dev, fmt, ...) \
>> >  virtio_error_impl(dev, "%s: " fmt, DEVICE(dev)->id, __VA_ARGS__)
>>
>> Neat! I think I'll stick with a function though. This doesn't allocate
>> but it adds a little bit of code to each call site which has the
>> potential of slowing down the fast no-error path (I have no data, just
>> the general keeping-the-code-compact-is-good principle). Holler if you
>> disagree!
>
> IMHO that would be uneccessary optimization, particular since this is in
> the error scenario and so is not performance critical to normal operation.

Yeah, what I mean is that code getting bigger may have negative impact
even if it doesn't execute - it takes up space in caches and such.
Maybe it's an overkill but some of this common virtio code is pretty
low-level and every cache line counts. Actually, I'm tempted to wrap
the error conditions in virtio.c in unlikely() so the compiler knows
it's not part of normal operation. Thanks!

> Regards,
> Daniel
> --
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



[Qemu-devel] [PATCH v3 9/9] checkpatch: add virtio_error and virtqueue_error to error funcs

2017-07-17 Thread Ladi Prosek
Two more error functions that should not contain newlines.

Suggested-by: Greg Kurz 
Signed-off-by: Ladi Prosek 
---
 scripts/checkpatch.pl | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 4e91122..2cd2713 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2540,7 +2540,9 @@ sub process {
info_vreport|
error_report|
warn_report|
-   info_report}x;
+   info_report|
+   virtio_error|
+   virtqueue_error}x;
 
if ($rawline =~ /\b(?:$qemu_error_funcs)\s*\(.*\".*\\n/) {
ERROR("Error messages should not contain newlines\n" . 
$herecurr);
-- 
2.9.3




  1   2   3   >