[Qemu-devel] [PATCH v4] blizzard: Remove support for DEPTH != 32

2016-03-25 Thread Pooja Dhannawat
Removing support for DEPTH != 32 from blizzard template header
and file that includes it, as macro DEPTH == 32 only used.

Reviewed-by: Eric Blake 
Signed-off-by: Pooja Dhannawat 
---
 hw/display/blizzard.c  | 41 -
 hw/display/blizzard_template.h | 30 +-
 2 files changed, 5 insertions(+), 66 deletions(-)

diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
index c231960..5684e49 100644
--- a/hw/display/blizzard.c
+++ b/hw/display/blizzard.c
@@ -925,14 +925,6 @@ static void blizzard_update_display(void *opaque)
 s->my[1] = 0;
 }
 
-#define DEPTH 8
-#include "blizzard_template.h"
-#define DEPTH 15
-#include "blizzard_template.h"
-#define DEPTH 16
-#include "blizzard_template.h"
-#define DEPTH 24
-#include "blizzard_template.h"
 #define DEPTH 32
 #include "blizzard_template.h"
 
@@ -951,35 +943,10 @@ void *s1d13745_init(qemu_irq gpio_int)
 s->con = graphic_console_init(NULL, 0, _ops, s);
 surface = qemu_console_surface(s->con);
 
-switch (surface_bits_per_pixel(surface)) {
-case 0:
-s->line_fn_tab[0] = s->line_fn_tab[1] =
-g_malloc0(sizeof(blizzard_fn_t) * 0x10);
-break;
-case 8:
-s->line_fn_tab[0] = blizzard_draw_fn_8;
-s->line_fn_tab[1] = blizzard_draw_fn_r_8;
-break;
-case 15:
-s->line_fn_tab[0] = blizzard_draw_fn_15;
-s->line_fn_tab[1] = blizzard_draw_fn_r_15;
-break;
-case 16:
-s->line_fn_tab[0] = blizzard_draw_fn_16;
-s->line_fn_tab[1] = blizzard_draw_fn_r_16;
-break;
-case 24:
-s->line_fn_tab[0] = blizzard_draw_fn_24;
-s->line_fn_tab[1] = blizzard_draw_fn_r_24;
-break;
-case 32:
-s->line_fn_tab[0] = blizzard_draw_fn_32;
-s->line_fn_tab[1] = blizzard_draw_fn_r_32;
-break;
-default:
-fprintf(stderr, "%s: Bad color depth\n", __FUNCTION__);
-exit(1);
-}
+assert(surface_bits_per_pixel(surface) == 32)
+
+s->line_fn_tab[0] = blizzard_draw_fn_32;
+s->line_fn_tab[1] = blizzard_draw_fn_r_32;
 
 blizzard_reset(s);
 
diff --git a/hw/display/blizzard_template.h b/hw/display/blizzard_template.h
index b7ef27c..bc38d7a 100644
--- a/hw/display/blizzard_template.h
+++ b/hw/display/blizzard_template.h
@@ -19,31 +19,7 @@
  */
 
 #define SKIP_PIXEL(to) (to += deststep)
-#if DEPTH == 8
-# define PIXEL_TYPEuint8_t
-# define COPY_PIXEL(to, from)  do { *to = from; SKIP_PIXEL(to); } while (0)
-# define COPY_PIXEL1(to, from) (*to++ = from)
-#elif DEPTH == 15 || DEPTH == 16
-# define PIXEL_TYPEuint16_t
-# define COPY_PIXEL(to, from)  do { *to = from; SKIP_PIXEL(to); } while (0)
-# define COPY_PIXEL1(to, from) (*to++ = from)
-#elif DEPTH == 24
-# define PIXEL_TYPEuint8_t
-# define COPY_PIXEL(to, from) \
-do {  \
-to[0] = from; \
-to[1] = (from) >> 8;  \
-to[2] = (from) >> 16; \
-SKIP_PIXEL(to);   \
-} while (0)
-
-# define COPY_PIXEL1(to, from) \
-do {   \
-*to++ = from;  \
-*to++ = (from) >> 8;   \
-*to++ = (from) >> 16;  \
-} while (0)
-#elif DEPTH == 32
+#if DEPTH == 32
 # define PIXEL_TYPEuint32_t
 # define COPY_PIXEL(to, from)  do { *to = from; SKIP_PIXEL(to); } while (0)
 # define COPY_PIXEL1(to, from) (*to++ = from)
@@ -58,9 +34,6 @@
 static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE *dest,
 const uint16_t *src, unsigned int width)
 {
-#if !defined(SWAP_WORDS) && DEPTH == 16
-memcpy(dest, src, width);
-#else
 uint16_t data;
 unsigned int r, g, b;
 const uint16_t *end = (const void *) src + width;
@@ -74,7 +47,6 @@ static void glue(blizzard_draw_line16_, DEPTH)(PIXEL_TYPE 
*dest,
 data >>= 5;
 COPY_PIXEL1(dest, glue(rgb_to_pixel, DEPTH)(r, g, b));
 }
-#endif
 }
 
 static void glue(blizzard_draw_line24mode1_, DEPTH)(PIXEL_TYPE *dest,
-- 
2.5.0




Re: [Qemu-devel] [PATCH RFC 00/14] vhost-user: shutdown and reconnection

2016-03-25 Thread Marc-André Lureau
Hi

On Thu, Mar 24, 2016 at 8:10 AM, Yuanhan Liu
 wrote:
>> > The following series starts from the idea that the slave can request a
>> > "managed" shutdown instead and later recover (I guess the use case for
>> > this is to allow for example to update static dispatching/filter rules
>> > etc)
>
> What if the backend crashes, that no such request will be sent? And
> I'm wondering why this request is needed, as we are able to detect
> the disconnect now (with your patches).

I don't think trying to handle backend crashes is really a thing we
need to take care of. If the backend is bad enough to crash, it may as
well corrupt the guest memory (mst: my understanding of vhost-user is
that backend must be trusted, or it could just throw garbage in the
queue descriptors with surprising consequences or elsewhere in the
guest memory actually, right?).

> BTW, you meant to let QEMU as the server and the backend as the client
> here, right? Honestly, that's what we've thought of, too, in the first
> time.
> However, I'm wondering could we still go with the QEMU as the client
> and the backend as the server (the default and the only way DPDK
> supports), and let QEMU to try to reconnect when the backend crashes
> and restarts. In such case, we need enable the "reconnect" option
> for vhost-user, and once I have done that, it basically works in my
> test:
>

Conceptually, I think if we allow the backend to disconnect, it makes
sense that qemu is actually the socket server. But it doesn't matter
much, it's simple to teach qemu to reconnect a timer... So we should
probably allow both cases anyway.

> - start DPDK vhost-switch example
>
> - start QEMU, which will connect to DPDK vhost-user
>
>   link is good now.
>
> - kill DPDK vhost-switch
>
>   link is broken at this stage
>
> - start DPDK vhost-switch again
>
>   you will find that the link is back again.
>
>
> Will that makes sense to you? If so, we may need do nothing (or just
> very few) changes at all to DPDK to get the reconnect work.

The main issue with handling crashes (gone at any time) is that the
backend my not have time to sync the used idx (at the least). It may
already have processed incoming packets, so on reconnect, it may
duplicate the receiving/dispatching work. Similarly, on the backend
receiving end, some packets may be lost, never received by the VM, and
later overwritten by the backend after reconnect (for the same used
idx update reason). This may not be a big deal for unreliable
protocols, but I am not familiar enough with network usage to know if
that's fine in all cases. It may be fine for some packets, such as
udp.

However, in general, vhost-user should not be specific to network
transmission, and it would be nice to have a reliable way for the the
backend to reconnect. That's what I try to do in this series. I'll
repost it after I have done more testing.

thanks

-- 
Marc-André Lureau



[Qemu-devel] [PATCH 3/3] hid.c: Add debug support

2016-03-25 Thread Programmingkid
Add debug macros to the code for easier debugging.

Signed-off-by: John Arbuckle 
---
 hw/input/hid.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/hw/input/hid.c b/hw/input/hid.c
index 329a27b..42ca592 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -37,6 +37,13 @@
 #define RELEASED -1
 #define PUSHED -2
 
+/* #define DEBUG_HID_CODE */
+#ifdef DEBUG_HID_CODE
+#define DEBUG_HID(fmt, ...) printf(fmt, __VA_ARGS__)
+#else
+#define DEBUG_HID(fmt, ...) (void)0
+#endif
+
 /* Translates a QKeyCode to USB HID value */
 static const uint8_t qcode_to_usb_hid[] = {
 [Q_KEY_CODE_SHIFT] = USB_HID_LEFT_SHIFT,
@@ -331,6 +338,7 @@ static void hid_keyboard_event(DeviceState *dev, 
QemuConsole *src,
 return;
 }
 keycode = qcode_to_usb_hid[qcode];
+DEBUG_HID("keycode = 0x%x qcode:%d\n", keycode, qcode);
 
 count = 2;
 if (evt->u.key.data->down == false) { /* if key up event */
@@ -381,6 +389,9 @@ static void hid_keyboard_process_keycode(HIDState *hs)
 slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--;
 keycode = hs->kbd.keycodes[slot];
 
+DEBUG_HID("keycode:0x%x status:%s\n", keycode, (status == PUSHED ? "Pushed"
+  : "Released"));
+
 /* handle Control, Option, GUI/Windows/Command, and Shift keys */
 if (keycode >= 0xe0) {
 process_modifier_key(status, keycode, &(hs->kbd.modifiers));
-- 
2.7.2





[Qemu-devel] [PATCH 2/3] hid.c: convert to QKeyCode

2016-03-25 Thread Programmingkid
Switches hid.c from PS/2 to QKeyCode support.

Signed-off-by: John Arbuckle 
---
 hw/input/hid.c | 270 ++---
 1 file changed, 179 insertions(+), 91 deletions(-)

diff --git a/hw/input/hid.c b/hw/input/hid.c
index 5912677..329a27b 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -27,47 +27,144 @@
 #include "ui/console.h"
 #include "qemu/timer.h"
 #include "hw/input/hid.h"
+#include "include/hw/input/usb-keys.h"
+#include 
 
 #define HID_USAGE_ERROR_ROLLOVER0x01
 #define HID_USAGE_POSTFAIL  0x02
 #define HID_USAGE_ERROR_UNDEFINED   0x03
 
-/* Indices are QEMU keycodes, values are from HID Usage Table.  Indices
- * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d.  */
-static const uint8_t hid_usage_keys[0x100] = {
-0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
-0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b,
-0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c,
-0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16,
-0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33,
-0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19,
-0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55,
-0xe2, 0x2c, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
-0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f,
-0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59,
-0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x64, 0x44,
-0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
-0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65,
-
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46,
-0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a,
-0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d,
-0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+#define RELEASED -1
+#define PUSHED -2
+
+/* Translates a QKeyCode to USB HID value */
+static const uint8_t qcode_to_usb_hid[] = {
+[Q_KEY_CODE_SHIFT] = USB_HID_LEFT_SHIFT,
+[Q_KEY_CODE_SHIFT_R] = USB_HID_RIGHT_SHIFT,
+[Q_KEY_CODE_ALT] = USB_HID_LEFT_OPTION,
+[Q_KEY_CODE_ALT_R] = USB_HID_RIGHT_OPTION,
+[Q_KEY_CODE_ALTGR] = USB_HID_LEFT_OPTION,
+[Q_KEY_CODE_ALTGR_R] = USB_HID_RIGHT_OPTION,
+[Q_KEY_CODE_CTRL] = USB_HID_LEFT_CONTROL,
+[Q_KEY_CODE_CTRL_R] = USB_HID_RIGHT_CONTROL,
+[Q_KEY_CODE_MENU] = USB_HID_MENU,
+[Q_KEY_CODE_ESC] = USB_HID_ESC,
+[Q_KEY_CODE_1] = USB_HID_1,
+[Q_KEY_CODE_2] = USB_HID_2,
+[Q_KEY_CODE_3] = USB_HID_3,
+[Q_KEY_CODE_4] = USB_HID_4,
+[Q_KEY_CODE_5] = USB_HID_5,
+[Q_KEY_CODE_6] = USB_HID_6,
+[Q_KEY_CODE_7] = USB_HID_7,
+[Q_KEY_CODE_8] = USB_HID_8,
+[Q_KEY_CODE_9] = USB_HID_9,
+[Q_KEY_CODE_0] = USB_HID_0,
+[Q_KEY_CODE_MINUS] = USB_HID_MINUS,
+[Q_KEY_CODE_EQUAL] = USB_HID_EQUALS,
+[Q_KEY_CODE_BACKSPACE] = USB_HID_DELETE,
+[Q_KEY_CODE_TAB] = USB_HID_TAB,
+[Q_KEY_CODE_Q] = USB_HID_Q,
+[Q_KEY_CODE_W] = USB_HID_W,
+[Q_KEY_CODE_E] = USB_HID_E,
+[Q_KEY_CODE_R] = USB_HID_R,
+[Q_KEY_CODE_T] = USB_HID_T,
+[Q_KEY_CODE_Y] = USB_HID_Y,
+[Q_KEY_CODE_U] = USB_HID_U,
+[Q_KEY_CODE_I] = USB_HID_I,
+[Q_KEY_CODE_O] = USB_HID_O,
+[Q_KEY_CODE_P] = USB_HID_P,
+[Q_KEY_CODE_BRACKET_LEFT] = USB_HID_LEFT_BRACKET,
+[Q_KEY_CODE_BRACKET_RIGHT] = USB_HID_RIGHT_BRACKET,
+[Q_KEY_CODE_RET] = USB_HID_RETURN,
+[Q_KEY_CODE_A] = USB_HID_A,
+[Q_KEY_CODE_S] = USB_HID_S,
+[Q_KEY_CODE_D] = USB_HID_D,
+[Q_KEY_CODE_F] = USB_HID_F,
+[Q_KEY_CODE_G] = USB_HID_G,
+[Q_KEY_CODE_H] = USB_HID_H,
+[Q_KEY_CODE_J] = USB_HID_J,
+[Q_KEY_CODE_K] = USB_HID_K,
+[Q_KEY_CODE_L] = USB_HID_L,
+[Q_KEY_CODE_SEMICOLON] = USB_HID_SEMICOLON,
+[Q_KEY_CODE_APOSTROPHE] = USB_HID_QUOTE,
+[Q_KEY_CODE_GRAVE_ACCENT] = USB_HID_GRAVE_ACCENT,
+[Q_KEY_CODE_BACKSLASH] = USB_HID_BACKSLASH,
+[Q_KEY_CODE_Z] = USB_HID_Z,
+[Q_KEY_CODE_X] = USB_HID_X,
+[Q_KEY_CODE_C] = USB_HID_C,
+[Q_KEY_CODE_V] = USB_HID_V,
+[Q_KEY_CODE_B] = USB_HID_B,
+[Q_KEY_CODE_N] = USB_HID_N,
+[Q_KEY_CODE_M] = USB_HID_M,
+[Q_KEY_CODE_COMMA] = USB_HID_COMMA,
+[Q_KEY_CODE_DOT] = USB_HID_PERIOD,
+[Q_KEY_CODE_SLASH] = USB_HID_FORWARD_SLASH,
+

[Qemu-devel] [PATCH 1/3] usb-keys.h: initial commit

2016-03-25 Thread Programmingkid
Create an emum of all the USB HID keyboard values.

Signed-off-by: John Arbuckle 
---
 include/hw/input/usb-keys.h | 154 
 1 file changed, 154 insertions(+)
 create mode 100644 include/hw/input/usb-keys.h

diff --git a/include/hw/input/usb-keys.h b/include/hw/input/usb-keys.h
new file mode 100644
index 000..6a9fba8
--- /dev/null
+++ b/include/hw/input/usb-keys.h
@@ -0,0 +1,154 @@
+/*
+ * QEMU USB HID Emulator
+ *
+ * Copyright (c) 2016 John Arbuckle
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ *  File: usb-keys.h
+ *  Description: Creates an enum of all the USB keycodes.
+ *  Additional information: http://www.usb.org/developers/hidpage/Hut1_12v2.pdf
+ *  page 53
+ */
+
+#ifndef USB_KEYS_H
+#define USB_KEYS_H
+
+enum {
+USB_HID_A = 0x04,
+USB_HID_B = 0x05,
+USB_HID_C = 0x06,
+USB_HID_D = 0x07,
+USB_HID_E = 0x08,
+USB_HID_F = 0x09,
+USB_HID_G = 0x0a,
+USB_HID_H = 0x0b,
+USB_HID_I = 0x0c,
+USB_HID_J = 0x0d,
+USB_HID_K = 0x0e,
+USB_HID_L = 0x0f,
+USB_HID_M = 0x10,
+USB_HID_N = 0x11,
+USB_HID_O = 0x12,
+USB_HID_P = 0x13,
+USB_HID_Q = 0x14,
+USB_HID_R = 0x15,
+USB_HID_S = 0x16,
+USB_HID_T = 0x17,
+USB_HID_U = 0x18,
+USB_HID_V = 0x19,
+USB_HID_W = 0x1a,
+USB_HID_X = 0x1b,
+USB_HID_Y = 0x1c,
+USB_HID_Z = 0x1d,
+
+USB_HID_1 = 0x1e,
+USB_HID_2 = 0x1f,
+USB_HID_3 = 0x20,
+USB_HID_4 = 0x21,
+USB_HID_5 = 0x22,
+USB_HID_6 = 0x23,
+USB_HID_7 = 0x24,
+USB_HID_8 = 0x25,
+USB_HID_9 = 0x26,
+USB_HID_0 = 0x27,
+
+USB_HID_RETURN = 0x28,
+USB_HID_ESC = 0x29,
+USB_HID_DELETE = 0x2a,
+USB_HID_TAB = 0x2b,
+USB_HID_SPACE = 0x2c,
+USB_HID_MINUS = 0x2d,
+USB_HID_EQUALS = 0x2e,
+USB_HID_LEFT_BRACKET = 0x2f,
+USB_HID_RIGHT_BRACKET = 0x30,
+USB_HID_BACKSLASH = 0x31,
+USB_HID_NON_US_NUMBER_SIGN = 0x32,
+USB_HID_SEMICOLON = 0x33,
+USB_HID_QUOTE = 0x34,
+USB_HID_GRAVE_ACCENT = 0x35,
+USB_HID_COMMA = 0x36,
+USB_HID_PERIOD = 0x37,
+USB_HID_FORWARD_SLASH = 0x38,
+USB_HID_CAPS_LOCK = 0x39,
+
+USB_HID_F1 = 0x3a,
+USB_HID_F2 = 0x3b,
+USB_HID_F3 = 0x3c,
+USB_HID_F4 = 0x3d,
+USB_HID_F5 = 0x3e,
+USB_HID_F6 = 0x3f,
+USB_HID_F7 = 0x40,
+USB_HID_F8 = 0x41,
+USB_HID_F9 = 0x42,
+USB_HID_F10 = 0x43,
+USB_HID_F11 = 0x44,
+USB_HID_F12 = 0x45,
+USB_HID_PRINT = 0x46,
+USB_HID_SCROLL_LOCK = 0x47,
+USB_HID_PAUSE = 0x48,
+
+USB_HID_INSERT = 0x49,
+USB_HID_HOME = 0x4a,
+USB_HID_PAGE_UP = 0x4b,
+USB_HID_FORWARD_DELETE = 0x4c,
+USB_HID_END = 0x4d,
+USB_HID_PAGE_DOWN = 0x4e,
+USB_HID_RIGHT_ARROW = 0x4f,
+USB_HID_LEFT_ARROW = 0x50,
+USB_HID_DOWN_ARROW = 0x51,
+USB_HID_UP_ARROW = 0x52,
+
+USB_HID_CLEAR = 0x53,
+USB_HID_KP_DIVIDE = 0x54,
+USB_HID_KP_MULTIPLY = 0x55,
+USB_HID_KP_MINUS = 0x56,
+USB_HID_KP_ADD = 0x57,
+USB_HID_KP_ENTER = 0x58,
+USB_HID_KP_1 = 0x59,
+USB_HID_KP_2 = 0x5a,
+USB_HID_KP_3  = 0x5b,
+USB_HID_KP_4 = 0x5c,
+USB_HID_KP_5 = 0x5d,
+USB_HID_KP_6 = 0x5e,
+USB_HID_KP_7 = 0x5f,
+USB_HID_KP_8 = 0x60,
+USB_HID_KP_9 = 0x61,
+USB_HID_KP_0 = 0x62,
+USB_HID_KP_PERIOD = 0x63,
+
+USB_HID_NON_US_BACKSLASH = 0x64,
+USB_HID_APPLICATION = 0x65,
+USB_HID_POWER = 0x66,
+USB_HID_KP_EQUALS = 0x67,
+USB_HID_F13 = 0x68,
+USB_HID_F14 = 0x69,
+USB_HID_F15 = 0x6a,
+USB_HID_EXECUTE = 0x74,
+USB_HID_HELP = 0x75,
+USB_HID_MENU = 0x76,
+USB_HID_SELECT = 0x77,
+USB_HID_STOP = 0x78,
+USB_HID_AGAIN = 0x79,
+USB_HID_UNDO = 0x7a,
+USB_HID_CUT = 0x7b,
+USB_HID_COPY = 0x7c,
+USB_HID_PASTE = 0x7d,
+USB_HID_FIND = 0x7e,
+USB_HID_MUTE = 0x7f,
+USB_HID_VOLUME_UP = 0x80,
+USB_HID_VOLUME_DOWN = 0x81,
+USB_HID_KP_COMMA = 0x85,
+
+USB_HID_LEFT_CONTROL = 0xe0,
+USB_HID_LEFT_SHIFT = 0xe1,
+USB_HID_LEFT_OPTION = 0xe2,
+USB_HID_LEFT_GUI = 0xe3,
+USB_HID_RIGHT_CONTROL = 0xe4,
+USB_HID_RIGHT_SHIFT = 0xe5,
+USB_HID_RIGHT_OPTION = 0xe6,
+USB_HID_RIGHT_GUI = 0xe7,
+};
+
+#endif /* USB_KEYS_H */
-- 
2.7.2





[Qemu-devel] [PATCH 0/3] Switch USB HID to QKeyCode

2016-03-25 Thread Programmingkid
This patchset switches from the PS/2 keycode to QKeyCode support in the hid.c
file. 

John Arbuckle (3):
  usb-keys.h: initial commit
  hid.c: convert to QKeyCode
  hid.c: Add debug support

 hw/input/hid.c  | 279 ++--
 include/hw/input/usb-keys.h | 154 
 2 files changed, 343 insertions(+), 90 deletions(-)
 create mode 100644 include/hw/input/usb-keys.h

-- 
2.7.2





Re: [Qemu-devel] TCG question reg. tcg_cpu_exec()

2016-03-25 Thread Paolo Bonzini


On 14/03/2016 16:26, Pranith Kumar wrote:
> I am trying to understand what scenarios can result in no TBs
> executing for that CPU. My understanding is that there is a pending
> operation which needs to be handled before we can execute TBs from
> this CPU(I/O?).

For example the CPU could be halted and won't execute until it receives
an interrupt.

Paolo



[Qemu-devel] [PATCH 1/2] softfloat: Enable run-time-configurable meaning of signaling NaN bit

2016-03-25 Thread Aleksandar Markovic
From: Aleksandar Markovic 

This patch enables SoftFloat library to be configured at run-time in
relation to the meaning of signaling NaN bit.

Background:

In floating-point calculations, there is a need for denoting undefined or
unrepresentable values. This is achieved by defining certain floating-point
numerical values to be NaNs (which stands for "not a number"). For additional
reasons, virtually all modern floating-point unit implementations use two
kinds of NaNs: quiet and signaling. The binary representations of these two
kinds of NaNs, as a rule, differ only in one bit (it is traditionally,
the first bit of mantissa).

Up to 2008, standards for floating-point did not specify all details about
binary representation of NaNs. More specifically, the meaning of the bit
that is used for distinguishing between signaling and quiet NaNs was not
strictly prescribed. (IEEE 754-2008 was the first floating-point standard
that defined that meaning clearly, see [1], p. 35) As a result, different
platforms took different approaches, and this presented certain challenge
in emulators like QEMU.

Mips architecture represent the most complex case among QEMU-supported
architectures regarding signaling NaN bit. Up to Release 6 of Mips
architecture, "1" in signaling NaN bit denoted signaling NaN, which is
opposite to IEEE 754-2008 standard. From Release 6 on, Mips architecture
adopted IEEE standard prescription, and "0" denotes signaling NaN. On top of
that, Mips architecture for SIMD (also known as MSA, or vector instructions)
also specifies signaling bit in accordance to IEEE standard. MSA unit can be
implemented with both pre-Release 6 and Release 6 main processor units.

QEMU uses SoftFloat library to implement various floating-point-related
instructions on all platforms. The current implementation allows for defining
meaning of signaling NaN bit during build time, and is implemented via
preprocessor macro called SNAN_BIT_IS_ONE.

The change in this patch enables SoftFloat library to be configured in
run-time. This configuration is meant to occur during CPU initialization,
when it is definitely known what desired behavior for particular CPU
(or any additional FPUs) is.

The change is implemented so that it is consistent with existing
implementation of similar cases. This means that structure float_status is
used for passing the information about desired signaling NaN bit during each
invocation of SoftFloat functions. The additional field in float_status is
called snan_bit_is_one, which supersedes macro SNAN_BIT_IS_ONE.

Further break down of changes:

  (for the sake of brevity, a placeholder XXX is used below and it might
  mean float16, float32, float64, floatx80, or float128)

  1) Added field snan_bit_is_one to the structure float_status,
 and the correspondent setter function set_snan_bit_is_one().

  2) SoftFloat library constants XXX_default_nan converted to functions
 XXX_default_nan(float_status*). This is necessary since they are
 dependant on signaling bit meaning.

  3) Added a float_status* argument to SoftFloat library functions
 XXX_is_quiet_nan(XXX a_), XXX_is_signaling_nan(XXX a_),
 XXX_maybe_silence_nan(XXX a_).

  4) Updated code in all architectures to reflect changes in SoftFloat
 library. This change is twofolds: it includes modification of SoftFloat
 library functions invocations, and addition of invocations of function
 set_snan_bit_is_one() during CPU initialization, with arguments that
 are appropriate for each architecture.

IMPORTANT:

This change is not meant to create any change in emulator behavior or
functionality on any platform. It just provides the means for SoftFloat
library to be used in a more flexible way - in other words, it will just
prepare SoftFloat library for usage related to Mips platform and its
specifics regarding signaling bit meaning, which is done in the next patch.

[1] "IEEE Standard for Floating-Point Arithmetic",
IEEE Computer Society, August 29, 2008.
(http://www.csee.umbc.edu/~tsimo1/CMSC455/IEEE-754-2008.pdf)

Signed-off-by: Aleksandar Markovic 
---
 fpu/softfloat-specialize.h| 546 +-
 fpu/softfloat.c   | 170 +++--
 include/fpu/softfloat.h   |  49 ++--
 target-alpha/cpu.c|   2 +
 target-arm/cpu.c  |   2 +
 target-arm/helper-a64.c   |  14 +-
 target-arm/helper.c   |  40 ++--
 target-i386/cpu.c |   4 +
 target-m68k/cpu.c |   2 +
 target-m68k/helper.c  |   6 +-
 target-microblaze/cpu.c   |   2 +
 target-microblaze/op_helper.c |   6 +-
 target-mips/helper.h  |   4 +-
 target-mips/msa_helper.c  |  96 
 target-mips/op_helper.c   |  13 +-
 target-mips/translate.c   |   4 +-
 target-mips/translate_init.c  |   6 +-
 target-openrisc/cpu.c |   2 +
 target-ppc/fpu_helper.c   | 120 

[Qemu-devel] [PATCH 0/2] target-mips: Fix IEEE 754-2008-related issues

2016-03-25 Thread Aleksandar Markovic
From: Aleksandar Markovic 

Mips platform represents the most complex case among QEMU-supported
platforms in reference to certain aspects of floating-point arithmetics.
This is mostly a consequence of the fact that Mips platform, for many
reasons, evolved considerably over time related to floating-point
arithmetics standards (significantly more than other platforms).
It has been difficult for emulators like QEMU to support such variety
of configurations.

This patch set provides solution to this problem, and furnishes
accurate emulation of floating-point arithmetics for all Mips cases.

Aleksandar Markovic (2):
  softfloat: Enable run-time-configurable meaning of signaling NaN bit
  target-mips: Implement IEEE 754-2008 functionality for R6 and MSA
instructions

 fpu/softfloat-specialize.h| 546 +-
 fpu/softfloat.c   | 170 +++--
 include/fpu/softfloat.h   |  49 ++--
 target-alpha/cpu.c|   2 +
 target-arm/cpu.c  |   2 +
 target-arm/helper-a64.c   |  14 +-
 target-arm/helper.c   |  40 ++--
 target-i386/cpu.c |   4 +
 target-m68k/cpu.c |   2 +
 target-m68k/helper.c  |   6 +-
 target-microblaze/cpu.c   |   2 +
 target-microblaze/op_helper.c |   6 +-
 target-mips/helper.h  |  14 +-
 target-mips/msa_helper.c  | 144 +++
 target-mips/op_helper.c   | 527 +---
 target-mips/translate.c   |  20 +-
 target-mips/translate_init.c  |  24 +-
 target-openrisc/cpu.c |   2 +
 target-ppc/fpu_helper.c   | 120 +-
 target-ppc/translate_init.c   |   2 +
 target-s390x/cpu.c|   1 +
 target-s390x/fpu_helper.c |  28 ++-
 target-s390x/helper.h |   6 +-
 target-s390x/translate.c  |   6 +-
 target-sh4/cpu.c  |   1 +
 target-sparc/cpu.c|   1 +
 target-tricore/helper.c   |   1 +
 target-unicore32/cpu.c|   1 +
 target-xtensa/cpu.c   |   3 +
 29 files changed, 1119 insertions(+), 625 deletions(-)

-- 
1.9.1




[Qemu-devel] [PATCH 2/2] target-mips: Implement IEEE 754-2008 functionality for R6 and MSA instructions

2016-03-25 Thread Aleksandar Markovic
From: Aleksandar Markovic 

This patch utilizes provisions from the previous patch, and configures
Mips R6 CPUs and Mips MSA units appropriately with reference to the meaning
of the signaling NaN bit (this is mentioned in point 3 in the list below).
The majority of involved MIPS instructions will be fixed just with that
change. Certain number of other IEEE 754-2008 standard-related MIPS issues
are addreessed with this patch as well.

The changes can be summarized this way:

1) Definitions of Mips processors are updated to reflect supported
   IEEE-754-2008-related features. (file target-mips/translate_init.c)

2) Functions fpu_init() and msa_reset() are updated so that flag
   snan_bit_is_one is properly set for any Mips configuration.
   (file target-mips/translate_init.c)

3) Helpers helper_float_abs_() and helper_float_chs_() are
   rewritten to reflect new behavior of instructions ABS.fmt and NEG.fmt
   in MIPS Release 6. Affected MIPS instructions are:

   ABS.S
   ABS.D
   NEG.S
   NEG.D

   Note that legacy (pre-R6) ABS and NEG instructions are arithmetic
   (any NaN operand signals invalid operation), while R6 ones are
   non-arithmetic, always changing the sign bit, even for NaN-like operands.

   Details on these instructions are documented in [1] p. 35 and 359.

   Affected files are target-mips/helper.h and target-mips/op_helper.c.

4) Helpers helper_float_ceilxxx(), helper_float_cvtxxx(),
   helper_float_floorxxx(), helper_float_roundxxx(), and
   helper_float_truncxxx() are rewritten to reflect the behavior of
   relevant instructions if its operands are floating numbers out of
   the range of the integer destination.

   Affected MIPS instructions are:

   CEIL.L.fmt
   CEIL.W.fmt
   CVT.L.fmt
   CVT.W.fmt
   FLOOR.L.fmt
   FLOOR.W.fmt
   ROUND.L.fmt
   ROUND.W.fmt
   TRUNC.L.fmt
   TRUNC.W.fmt

   Details on these instructions are presented in [1] p. 129, 130, 149,
   155, 222, 223, 393, 394, 504, 505.

   Affected files are target-mips/helper.h and target-mips/translate.c.

5) Helpers helper_msa_class_s() and helper_msa_class_d() added so that
   MSA version of instruction CLASS can operate independently of the one
   from the base set of instructions. Affected MIPS instructions are:

   FCLASS.W
   FCLASS.D

   Details on these instructions can be found in [2] p. 158.

   Affected source code files are target-mips/helper.h and
   target-mips/msa_helper.c.

6) Handling og instructions CVT.S.PU and CVT.S.PL is updated to reflect
   the fact that they are removed in Mips R6 architecture and belong to
   so-called paired-single class of instructions. Details on these
   instructions can be found in [1], p. 152 and 153. Affected source
   code file is target-mips/translate.c.

[1] "MIPS® Architecture For Programmers Volume II-A:
The MIPS64® Instruction Set Reference Manual",
Imagination Technologies LTD, Revision 6.04, November 13, 2015
(https://imagination-technologies-cloudfront-assets.s3.amazonaws.com/
 documentation/MD00087-2B-MIPS64BIS-AFP-06.04.pdf)

[2] "MIPS Architecture for Programmers Volume IV-j:
The MIPS32® SIMD Architecture Module",
Imagination Technologies LTD, Revision 1.12, February 3, 2016
(https://imagination-technologies-cloudfront-assets.s3.amazonaws.com/
 documentation/MD00866-2B-MSA32-AFP-01.12.pdf)

Signed-off-by: Aleksandar Markovic 
---
 target-mips/helper.h |  10 +-
 target-mips/msa_helper.c |  60 -
 target-mips/op_helper.c  | 516 ---
 target-mips/translate.c  |  16 +-
 target-mips/translate_init.c |  22 +-
 5 files changed, 520 insertions(+), 104 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 1aaa316..952af63 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -254,10 +254,10 @@ FOP_PROTO(recip)
 FOP_PROTO(rint)
 #undef FOP_PROTO
 
-#define FOP_PROTO(op)   \
-DEF_HELPER_1(float_ ## op ## _s, i32, i32)  \
-DEF_HELPER_1(float_ ## op ## _d, i64, i64)  \
-DEF_HELPER_1(float_ ## op ## _ps, i64, i64)
+#define FOP_PROTO(op)\
+DEF_HELPER_2(float_ ## op ## _s, i32, env, i32)  \
+DEF_HELPER_2(float_ ## op ## _d, i64, env, i64)  \
+DEF_HELPER_2(float_ ## op ## _ps, i64, env, i64)
 FOP_PROTO(abs)
 FOP_PROTO(chs)
 #undef FOP_PROTO
@@ -924,6 +924,8 @@ DEF_HELPER_4(msa_pcnt_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nloc_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_nlzc_df, void, env, i32, i32, i32)
 
+DEF_HELPER_2(msa_class_s, i32, env, i32)
+DEF_HELPER_2(msa_class_d, i64, env, i64)
 DEF_HELPER_4(msa_fclass_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_s_df, void, env, i32, i32, i32)
 DEF_HELPER_4(msa_ftrunc_u_df, void, env, i32, i32, i32)
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 47fbba0..fed430d 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -2924,19 +2924,67 @@ 

[Qemu-devel] [PATCH v2 8/8] hw/mips/cps: enable ITU for multithreading processors

2016-03-25 Thread Leon Alrae
Make ITU available in the system if CPU supports multithreading
and is part of CPS.

Signed-off-by: Leon Alrae 
---
 hw/mips/cps.c | 32 
 include/hw/mips/cps.h |  2 ++
 2 files changed, 34 insertions(+)

diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 59e7926..d2ee0e4 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -21,6 +21,7 @@
 #include "hw/mips/cps.h"
 #include "hw/mips/mips.h"
 #include "hw/mips/cpudevs.h"
+#include "sysemu/kvm.h"
 
 qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number)
 {
@@ -55,6 +56,14 @@ static void main_cpu_reset(void *opaque)
 cs->halted = 1;
 }
 
+static bool cpu_mips_itu_supported(CPUMIPSState *env)
+{
+bool is_mt = (env->CP0_Config5 & (1 << CP0C5_VP)) ||
+ (env->CP0_Config3 & (1 << CP0C3_MT));
+
+return is_mt && !kvm_enabled();
+}
+
 static void mips_cps_realize(DeviceState *dev, Error **errp)
 {
 MIPSCPSState *s = MIPS_CPS(dev);
@@ -63,6 +72,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 int i;
 Error *err = NULL;
 target_ulong gcr_base;
+bool itu_present = false;
 
 for (i = 0; i < s->num_vp; i++) {
 cpu = cpu_mips_init(s->cpu_model);
@@ -75,12 +85,34 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 /* Init internal devices */
 cpu_mips_irq_init_cpu(env);
 cpu_mips_clock_init(env);
+if (cpu_mips_itu_supported(env)) {
+itu_present = true;
+/* Attach ITC Tag to the VP */
+env->itc_tag = mips_itu_get_tag_region(>itu);
+}
 qemu_register_reset(main_cpu_reset, cpu);
 }
 
 cpu = MIPS_CPU(first_cpu);
 env = >env;
 
+/* Inter-Thread Communication Unit */
+if (itu_present) {
+object_initialize(>itu, sizeof(s->itu), TYPE_MIPS_ITU);
+qdev_set_parent_bus(DEVICE(>itu), sysbus_get_default());
+
+object_property_set_int(OBJECT(>itu), 16, "num-fifo", );
+object_property_set_int(OBJECT(>itu), 16, "num-semaphores", );
+object_property_set_bool(OBJECT(>itu), true, "realized", );
+if (err != NULL) {
+error_propagate(errp, err);
+return;
+}
+
+memory_region_add_subregion(>container, 0,
+   sysbus_mmio_get_region(SYS_BUS_DEVICE(>itu), 0));
+}
+
 /* Cluster Power Controller */
 object_initialize(>cpc, sizeof(s->cpc), TYPE_MIPS_CPC);
 qdev_set_parent_bus(DEVICE(>cpc), sysbus_get_default());
diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h
index 88be765..4dbae9c 100644
--- a/include/hw/mips/cps.h
+++ b/include/hw/mips/cps.h
@@ -23,6 +23,7 @@
 #include "hw/sysbus.h"
 #include "hw/misc/mips_cmgcr.h"
 #include "hw/misc/mips_cpc.h"
+#include "hw/misc/mips_itu.h"
 
 #define TYPE_MIPS_CPS "mips-cps"
 #define MIPS_CPS(obj) OBJECT_CHECK(MIPSCPSState, (obj), TYPE_MIPS_CPS)
@@ -37,6 +38,7 @@ typedef struct MIPSCPSState {
 MemoryRegion container;
 MIPSGCRState gcr;
 MIPSCPCState cpc;
+MIPSITUState itu;
 } MIPSCPSState;
 
 qemu_irq get_cps_irq(MIPSCPSState *cps, int pin_number);
-- 
2.7.4




[Qemu-devel] [PATCH v2 7/8] target-mips: make ITC Configuration Tags accessible to the CPU

2016-03-25 Thread Leon Alrae
Add CP0.ErrCtl register with WST, SPR and ITC bits. In 34K and interAptiv
processors these bits are used to enable CACHE instruction access to
different arrays. When WST=0, SPR=0 and ITC=1 the CACHE instruction will
access ITC tag values.

Generally we do not model caches and we have been treating the CACHE
instruction as NOP. But since CACHE can operate on ITC Tags new
MIPS_HFLAG_ITC_CACHE hflag is introduced to generate the helper only when
CACHE is in the ITC Access mode.

Signed-off-by: Leon Alrae 
---
 target-mips/cpu.h   |  7 +-
 target-mips/helper.h|  3 +++
 target-mips/op_helper.c | 40 ++-
 target-mips/translate.c | 62 +
 4 files changed, 100 insertions(+), 12 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 725aaef..67bbb25 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -519,6 +519,10 @@ struct CPUMIPSState {
 #define CP0DB_DSS  0
 target_ulong CP0_DEPC;
 int32_t CP0_Performance0;
+int32_t CP0_ErrCtl;
+#define CP0EC_WST 29
+#define CP0EC_SPR 28
+#define CP0EC_ITC 26
 uint64_t CP0_TagLo;
 int32_t CP0_DataLo;
 int32_t CP0_TagHi;
@@ -534,7 +538,7 @@ struct CPUMIPSState {
 #define EXCP_INST_NOTAVAIL 0x2 /* No valid instruction word for BadInstr */
 uint32_t hflags;/* CPU State */
 /* TMASK defines different execution modes */
-#define MIPS_HFLAG_TMASK  0x75807FF
+#define MIPS_HFLAG_TMASK  0xF5807FF
 #define MIPS_HFLAG_MODE   0x7 /* execution modes*/
 /* The KSU flags must be the lowest bits in hflags. The flag order
must be the same as defined for CP0 Status. This allows to use
@@ -583,6 +587,7 @@ struct CPUMIPSState {
 #define MIPS_HFLAG_MSA   0x100
 #define MIPS_HFLAG_FRE   0x200 /* FRE enabled */
 #define MIPS_HFLAG_ELPA  0x400
+#define MIPS_HFLAG_ITC_CACHE  0x800 /* CACHE instr. operates on ITC tag */
 target_ulong btarget;/* Jump / branch target   */
 target_ulong bcond;  /* Branch condition (if needed)   */
 
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 1bc8bb2..62fe20b 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -151,6 +151,7 @@ DEF_HELPER_2(mtc0_framemask, void, env, tl)
 DEF_HELPER_2(mtc0_debug, void, env, tl)
 DEF_HELPER_2(mttc0_debug, void, env, tl)
 DEF_HELPER_2(mtc0_performance0, void, env, tl)
+DEF_HELPER_2(mtc0_errctl, void, env, tl)
 DEF_HELPER_2(mtc0_taglo, void, env, tl)
 DEF_HELPER_2(mtc0_datalo, void, env, tl)
 DEF_HELPER_2(mtc0_taghi, void, env, tl)
@@ -949,3 +950,5 @@ MSALDST_PROTO(h)
 MSALDST_PROTO(w)
 MSALDST_PROTO(d)
 #undef MSALDST_PROTO
+
+DEF_HELPER_3(cache, void, env, tl, i32)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 7c5669c..dcd44c4 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1632,9 +1632,31 @@ void helper_mtc0_performance0(CPUMIPSState *env, 
target_ulong arg1)
 env->CP0_Performance0 = arg1 & 0x07ff;
 }
 
+void helper_mtc0_errctl(CPUMIPSState *env, target_ulong arg1)
+{
+int32_t wst = arg1 & (1 << CP0EC_WST);
+int32_t spr = arg1 & (1 << CP0EC_SPR);
+int32_t itc = env->itc_tag ? (arg1 & (1 << CP0EC_ITC)) : 0;
+
+env->CP0_ErrCtl = wst | spr | itc;
+
+if (itc && !wst && !spr) {
+env->hflags |= MIPS_HFLAG_ITC_CACHE;
+} else {
+env->hflags &= ~MIPS_HFLAG_ITC_CACHE;
+}
+}
+
 void helper_mtc0_taglo(CPUMIPSState *env, target_ulong arg1)
 {
-env->CP0_TagLo = arg1 & 0xFCF6;
+if (env->hflags & MIPS_HFLAG_ITC_CACHE) {
+/* If CACHE instruction is configured for ITC tags then make all
+   CP0.TagLo bits writable. The actual write to ITC Configuration
+   Tag will take care of the read-only bits. */
+env->CP0_TagLo = arg1;
+} else {
+env->CP0_TagLo = arg1 & 0xFCF6;
+}
 }
 
 void helper_mtc0_datalo(CPUMIPSState *env, target_ulong arg1)
@@ -3781,3 +3803,19 @@ MSA_ST_DF(DF_HALF,   h, cpu_stw_data)
 MSA_ST_DF(DF_WORD,   w, cpu_stl_data)
 MSA_ST_DF(DF_DOUBLE, d, cpu_stq_data)
 #endif
+
+void helper_cache(CPUMIPSState *env, target_ulong addr, uint32_t op)
+{
+#ifndef CONFIG_USER_ONLY
+target_ulong index = addr & 0x1fff;
+if (op == 9) {
+/* Index Store Tag */
+memory_region_dispatch_write(env->itc_tag, index, env->CP0_TagLo,
+ 8, MEMTXATTRS_UNSPECIFIED);
+} else if (op == 5) {
+/* Index Load Tag */
+memory_region_dispatch_read(env->itc_tag, index, >CP0_TagLo,
+8, MEMTXATTRS_UNSPECIFIED);
+}
+#endif
+}
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 65f2caf..592e4e3 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -5486,8 +5486,14 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int 
reg, int sel)
 }
 break;
 case 26:
-

[Qemu-devel] [PATCH v2 5/8] hw/mips: implement ITC Storage - Bypass View

2016-03-25 Thread Leon Alrae
Bypass View does not cause issuing thread to block and does not affect
any of the cells state bit.

Read from a FIFO cell returns the value of the oldest entry.
Store to a FIFO cell changes the value of the newest entry.

Signed-off-by: Leon Alrae 
---
 hw/misc/mips_itu.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index 45083b3..e628bbe 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -181,6 +181,27 @@ static void QEMU_NORETURN 
block_thread_and_exit(ITCStorageCell *c)
 cpu_loop_exit(current_cpu);
 }
 
+/* ITC Bypass View */
+
+static inline uint64_t view_bypass_read(ITCStorageCell *c)
+{
+if (c->tag.FIFO) {
+return c->data[c->fifo_out];
+} else {
+return c->data[0];
+}
+}
+
+static inline void view_bypass_write(ITCStorageCell *c, uint64_t val)
+{
+if (c->tag.FIFO && (c->tag.FIFOPtr > 0)) {
+int idx = (c->fifo_out + c->tag.FIFOPtr - 1) % ITC_CELL_DEPTH;
+c->data[idx] = val;
+}
+
+/* ignore a write to the semaphore cell */
+}
+
 /* ITC Control View */
 
 static inline uint64_t view_control_read(ITCStorageCell *c)
@@ -347,6 +368,9 @@ static uint64_t itc_storage_read(void *opaque, hwaddr addr, 
unsigned size)
 uint64_t ret = -1;
 
 switch (view) {
+case ITCVIEW_BYPASS:
+ret = view_bypass_read(cell);
+break;
 case ITCVIEW_CONTROL:
 ret = view_control_read(cell);
 break;
@@ -379,6 +403,9 @@ static void itc_storage_write(void *opaque, hwaddr addr, 
uint64_t data,
 ITCView view = get_itc_view(addr);
 
 switch (view) {
+case ITCVIEW_BYPASS:
+view_bypass_write(cell, data);
+break;
 case ITCVIEW_CONTROL:
 view_control_write(cell, data);
 break;
-- 
2.7.4




[Qemu-devel] [PATCH v2 3/8] hw/mips: implement ITC Storage - Empty/Full Sync and Try Views

2016-03-25 Thread Leon Alrae
Empty/Full Synchronized and Try views can be used to access FIFO cells.
Store to the FIFO cell pushes the value into the queue, load pops the oldest
element from the queue. Cell's Full and Empty bits are automatically updated
to reflect new state of the cell.

Empty/Full Synchronized View causes the issuing thread to block when FIFO is
empty while thread is performing a read, or FIFO is full while thread is
performing a write.

Empty/Full Try View never blocks the thread. If cell is full then write is
ignored, if cell is empty then load returns 0.

Trap bit (i.e. Gating Storage exceptions) not implemented.
Store Conditional support for E/F Try View (i.e. indicate failure if FIFO
is full) not implemented.

Signed-off-by: Leon Alrae 
---
 hw/misc/mips_itu.c | 113 +
 1 file changed, 113 insertions(+)

diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index 742656d..ae59ae4 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -159,6 +159,26 @@ static inline ITCStorageCell *get_cell(MIPSITUState *s,
 return >cell[cell_idx];
 }
 
+static void wake_blocked_threads(ITCStorageCell *c)
+{
+CPUState *cs;
+CPU_FOREACH(cs) {
+if (cs->halted && (c->blocked_threads & (1ULL << cs->cpu_index))) {
+cpu_interrupt(cs, CPU_INTERRUPT_WAKE);
+}
+}
+c->blocked_threads = 0;
+}
+
+static void QEMU_NORETURN block_thread_and_exit(ITCStorageCell *c)
+{
+c->blocked_threads |= 1ULL << current_cpu->cpu_index;
+cpu_restore_state(current_cpu, current_cpu->mem_io_pc);
+current_cpu->halted = 1;
+current_cpu->exception_index = EXCP_HLT;
+cpu_loop_exit(current_cpu);
+}
+
 /* ITC Control View */
 
 static inline uint64_t view_control_read(ITCStorageCell *c)
@@ -182,6 +202,87 @@ static inline void view_control_write(ITCStorageCell *c, 
uint64_t val)
 }
 }
 
+/* ITC Empty/Full View */
+
+static uint64_t view_ef_common_read(ITCStorageCell *c, bool blocking)
+{
+uint64_t ret = 0;
+
+if (!c->tag.FIFO) {
+return 0;
+}
+
+c->tag.F = 0;
+
+if (blocking && c->tag.E) {
+block_thread_and_exit(c);
+}
+
+if (c->blocked_threads) {
+wake_blocked_threads(c);
+}
+
+if (c->tag.FIFOPtr > 0) {
+ret = c->data[c->fifo_out];
+c->fifo_out = (c->fifo_out + 1) % ITC_CELL_DEPTH;
+c->tag.FIFOPtr--;
+}
+
+if (c->tag.FIFOPtr == 0) {
+c->tag.E = 1;
+}
+
+return ret;
+}
+
+static uint64_t view_ef_sync_read(ITCStorageCell *c)
+{
+return view_ef_common_read(c, true);
+}
+
+static uint64_t view_ef_try_read(ITCStorageCell *c)
+{
+return view_ef_common_read(c, false);
+}
+
+static inline void view_ef_common_write(ITCStorageCell *c, uint64_t val,
+bool blocking)
+{
+if (!c->tag.FIFO) {
+return;
+}
+
+c->tag.E = 0;
+
+if (blocking && c->tag.F) {
+block_thread_and_exit(c);
+}
+
+if (c->blocked_threads) {
+wake_blocked_threads(c);
+}
+
+if (c->tag.FIFOPtr < ITC_CELL_DEPTH) {
+int idx = (c->fifo_out + c->tag.FIFOPtr) % ITC_CELL_DEPTH;
+c->data[idx] = val;
+c->tag.FIFOPtr++;
+}
+
+if (c->tag.FIFOPtr == ITC_CELL_DEPTH) {
+c->tag.F = 1;
+}
+}
+
+static void view_ef_sync_write(ITCStorageCell *c, uint64_t val)
+{
+view_ef_common_write(c, val, true);
+}
+
+static void view_ef_try_write(ITCStorageCell *c, uint64_t val)
+{
+view_ef_common_write(c, val, false);
+}
+
 static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
 {
 MIPSITUState *s = (MIPSITUState *)opaque;
@@ -193,6 +294,12 @@ static uint64_t itc_storage_read(void *opaque, hwaddr 
addr, unsigned size)
 case ITCVIEW_CONTROL:
 ret = view_control_read(cell);
 break;
+case ITCVIEW_EF_SYNC:
+ret = view_ef_sync_read(cell);
+break;
+case ITCVIEW_EF_TRY:
+ret = view_ef_try_read(cell);
+break;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
   "itc_storage_read: Bad ITC View %d\n", (int)view);
@@ -213,6 +320,12 @@ static void itc_storage_write(void *opaque, hwaddr addr, 
uint64_t data,
 case ITCVIEW_CONTROL:
 view_control_write(cell, data);
 break;
+case ITCVIEW_EF_SYNC:
+view_ef_sync_write(cell, data);
+break;
+case ITCVIEW_EF_TRY:
+view_ef_try_write(cell, data);
+break;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
   "itc_storage_write: Bad ITC View %d\n", (int)view);
-- 
2.7.4




[Qemu-devel] [PATCH v2 2/8] hw/mips: implement ITC Storage - Control View

2016-03-25 Thread Leon Alrae
Control view is used to access the ITC Storage Cell Tags. It never causes
the issuing thread to block.

Guest can empty the FIFO cell by setting Empty bit to 1.

Signed-off-by: Leon Alrae 
---
 hw/misc/mips_itu.c | 104 +
 1 file changed, 104 insertions(+)

diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index 8cadfd4..742656d 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -32,12 +32,28 @@
 #define ITC_SEMAPH_NUM_MAX 16
 #define ITC_AM1_NUMENTRIES_OFS 20
 
+#define ITC_CELL_TAG_FIFO_DEPTH 28
+#define ITC_CELL_TAG_FIFO_PTR 18
+#define ITC_CELL_TAG_FIFO 17
+#define ITC_CELL_TAG_T 16
+#define ITC_CELL_TAG_F 1
+#define ITC_CELL_TAG_E 0
+
 #define ITC_AM0_BASE_ADDRESS_MASK 0xFC00ULL
 #define ITC_AM0_EN_MASK 0x1
 
 #define ITC_AM1_ADDR_MASK_MASK 0x1FC00
 #define ITC_AM1_ENTRY_GRAIN_MASK 0x7
 
+typedef enum ITCView {
+ITCVIEW_BYPASS  = 0,
+ITCVIEW_CONTROL = 1,
+ITCVIEW_EF_SYNC = 2,
+ITCVIEW_EF_TRY  = 3,
+ITCVIEW_PV_SYNC = 4,
+ITCVIEW_PV_TRY  = 5
+} ITCView;
+
 MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu)
 {
 return >tag_io;
@@ -119,7 +135,95 @@ static inline uint32_t get_num_cells(MIPSITUState *s)
 return s->num_fifo + s->num_semaphores;
 }
 
+static inline ITCView get_itc_view(hwaddr addr)
+{
+return (addr >> 3) & 0xf;
+}
+
+static inline int get_cell_stride_shift(const MIPSITUState *s)
+{
+/* Minimum interval (for EntryGain = 0) is 128 B */
+return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK);
+}
+
+static inline ITCStorageCell *get_cell(MIPSITUState *s,
+   hwaddr addr)
+{
+uint32_t cell_idx = addr >> get_cell_stride_shift(s);
+uint32_t num_cells = get_num_cells(s);
+
+if (cell_idx >= num_cells) {
+cell_idx = num_cells - 1;
+}
+
+return >cell[cell_idx];
+}
+
+/* ITC Control View */
+
+static inline uint64_t view_control_read(ITCStorageCell *c)
+{
+return ((uint64_t)c->tag.FIFODepth << ITC_CELL_TAG_FIFO_DEPTH) |
+   (c->tag.FIFOPtr << ITC_CELL_TAG_FIFO_PTR) |
+   (c->tag.FIFO << ITC_CELL_TAG_FIFO) |
+   (c->tag.T << ITC_CELL_TAG_T) |
+   (c->tag.E << ITC_CELL_TAG_E) |
+   (c->tag.F << ITC_CELL_TAG_F);
+}
+
+static inline void view_control_write(ITCStorageCell *c, uint64_t val)
+{
+c->tag.T = (val >> ITC_CELL_TAG_T) & 1;
+c->tag.E = (val >> ITC_CELL_TAG_E) & 1;
+c->tag.F = (val >> ITC_CELL_TAG_F) & 1;
+
+if (c->tag.E) {
+c->tag.FIFOPtr = 0;
+}
+}
+
+static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
+{
+MIPSITUState *s = (MIPSITUState *)opaque;
+ITCStorageCell *cell = get_cell(s, addr);
+ITCView view = get_itc_view(addr);
+uint64_t ret = -1;
+
+switch (view) {
+case ITCVIEW_CONTROL:
+ret = view_control_read(cell);
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "itc_storage_read: Bad ITC View %d\n", (int)view);
+break;
+}
+
+return ret;
+}
+
+static void itc_storage_write(void *opaque, hwaddr addr, uint64_t data,
+  unsigned size)
+{
+MIPSITUState *s = (MIPSITUState *)opaque;
+ITCStorageCell *cell = get_cell(s, addr);
+ITCView view = get_itc_view(addr);
+
+switch (view) {
+case ITCVIEW_CONTROL:
+view_control_write(cell, data);
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "itc_storage_write: Bad ITC View %d\n", (int)view);
+break;
+}
+
+}
+
 static const MemoryRegionOps itc_storage_ops = {
+.read = itc_storage_read,
+.write = itc_storage_write,
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-- 
2.7.4




[Qemu-devel] [PATCH v2 1/8] hw/mips: implement ITC Configuration Tags and Storage Cells

2016-03-25 Thread Leon Alrae
Implement ITC as a single object consisting of two memory regions:

1) tag_io: ITC Configuration Tags (i.e. ITCAddressMap{0,1} registers) which
are accessible by the CPU via CACHE instruction. Also adding
MemoryRegion *itc_tag to the CPUMIPSState so that CACHE instruction will
dispatch reads/writes directly.

2) storage_io: memory-mapped ITC Storage whose address space is configurable
(i.e. enabled/remapped/resized) by writing to ITCAddressMap{0,1} registers.

ITC Storage contains FIFO and Semaphore cells. Read-only FIFO bit in the
ITC cell tag indicates the type of the cell. If the ITC Storage contains
both types of cells then FIFOs are located before Semaphores.

Since issuing thread can get blocked on the access to a cell (in E/F
Synchronized and P/V Synchronized Views) each cell has a bitmap to track
which threads are currently blocked.

Signed-off-by: Leon Alrae 
---
 default-configs/mips-softmmu-common.mak |   1 +
 hw/misc/Makefile.objs   |   1 +
 hw/misc/mips_itu.c  | 213 
 include/hw/misc/mips_itu.h  |  72 +++
 target-mips/cpu.h   |   1 +
 5 files changed, 288 insertions(+)
 create mode 100644 hw/misc/mips_itu.c
 create mode 100644 include/hw/misc/mips_itu.h

diff --git a/default-configs/mips-softmmu-common.mak 
b/default-configs/mips-softmmu-common.mak
index 18e4beb..0394514 100644
--- a/default-configs/mips-softmmu-common.mak
+++ b/default-configs/mips-softmmu-common.mak
@@ -31,3 +31,4 @@ CONFIG_MC146818RTC=y
 CONFIG_ISA_TESTDEV=y
 CONFIG_EMPTY_SLOT=y
 CONFIG_MIPS_CPS=y
+CONFIG_MIPS_ITU=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 7805262..93f9528 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -45,6 +45,7 @@ obj-$(CONFIG_ZYNQ) += zynq-xadc.o
 obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
 obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
+obj-$(CONFIG_MIPS_ITU) += mips_itu.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
new file mode 100644
index 000..8cadfd4
--- /dev/null
+++ b/hw/misc/mips_itu.c
@@ -0,0 +1,213 @@
+/*
+ * Inter-Thread Communication Unit emulation.
+ *
+ * Copyright (c) 2016 Imagination Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "sysemu/sysemu.h"
+#include "hw/misc/mips_itu.h"
+
+#define ITC_TAG_ADDRSPACE_SZ (ITC_ADDRESSMAP_NUM * 8)
+/* Initialize as 4kB area to fit all 32 cells with default 128B grain.
+   Storage may be resized by the software. */
+#define ITC_STORAGE_ADDRSPACE_SZ 0x1000
+
+#define ITC_FIFO_NUM_MAX 16
+#define ITC_SEMAPH_NUM_MAX 16
+#define ITC_AM1_NUMENTRIES_OFS 20
+
+#define ITC_AM0_BASE_ADDRESS_MASK 0xFC00ULL
+#define ITC_AM0_EN_MASK 0x1
+
+#define ITC_AM1_ADDR_MASK_MASK 0x1FC00
+#define ITC_AM1_ENTRY_GRAIN_MASK 0x7
+
+MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu)
+{
+return >tag_io;
+}
+
+static uint64_t itc_tag_read(void *opaque, hwaddr addr, unsigned size)
+{
+MIPSITUState *tag = (MIPSITUState *)opaque;
+uint64_t index = addr >> 3;
+uint64_t ret = 0;
+
+switch (index) {
+case 0 ... ITC_ADDRESSMAP_NUM:
+ret = tag->ITCAddressMap[index];
+break;
+default:
+qemu_log_mask(LOG_GUEST_ERROR, "Read 0x%" PRIx64 "\n", addr);
+break;
+}
+
+return ret;
+}
+
+static void itc_reconfigure(MIPSITUState *tag)
+{
+uint64_t *am = >ITCAddressMap[0];
+MemoryRegion *mr = >storage_io;
+hwaddr address = am[0] & ITC_AM0_BASE_ADDRESS_MASK;
+uint64_t size = (1 << 10) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
+bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;
+
+memory_region_transaction_begin();
+if (!(size & (size - 1))) {
+memory_region_set_size(mr, size);
+}
+memory_region_set_address(mr, address);
+memory_region_set_enabled(mr, is_enabled);
+memory_region_transaction_commit();
+}
+
+static void itc_tag_write(void *opaque, hwaddr addr,
+  uint64_t data, unsigned size)
+{
+MIPSITUState *tag = (MIPSITUState *)opaque;
+uint64_t *am = >ITCAddressMap[0];
+uint64_t am_old, mask;
+uint64_t index = addr >> 3;
+
+

[Qemu-devel] [PATCH v2 4/8] hw/mips: implement ITC Storage - P/V Sync and Try Views

2016-03-25 Thread Leon Alrae
P/V Synchronized and Try Views can be used to access Semaphore cells.
Load returns current value and post-decrements the value in the cell
(until it reaches zero). Stores increment the value (until it saturates
at 0x).

P/V Synchronized View causes the issuing thread to block on read if value
is 0. P/V Try View does not block the thread, it returns 0 in this case.

Cell's Empty and Full bits are not modified.

Trap bit (i.e. Gating Storage exceptions) not implemented.

Signed-off-by: Leon Alrae 
---
 hw/misc/mips_itu.c | 68 ++
 1 file changed, 68 insertions(+)

diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index ae59ae4..45083b3 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -32,6 +32,8 @@
 #define ITC_SEMAPH_NUM_MAX 16
 #define ITC_AM1_NUMENTRIES_OFS 20
 
+#define ITC_CELL_PV_MAX_VAL 0x
+
 #define ITC_CELL_TAG_FIFO_DEPTH 28
 #define ITC_CELL_TAG_FIFO_PTR 18
 #define ITC_CELL_TAG_FIFO 17
@@ -283,6 +285,60 @@ static void view_ef_try_write(ITCStorageCell *c, uint64_t 
val)
 view_ef_common_write(c, val, false);
 }
 
+/* ITC P/V View */
+
+static uint64_t view_pv_common_read(ITCStorageCell *c, bool blocking)
+{
+uint64_t ret = c->data[0];
+
+if (c->tag.FIFO) {
+return 0;
+}
+
+if (c->data[0] > 0) {
+c->data[0]--;
+} else if (blocking) {
+block_thread_and_exit(c);
+}
+
+return ret;
+}
+
+static uint64_t view_pv_sync_read(ITCStorageCell *c)
+{
+return view_pv_common_read(c, true);
+}
+
+static uint64_t view_pv_try_read(ITCStorageCell *c)
+{
+return view_pv_common_read(c, false);
+}
+
+static inline void view_pv_common_write(ITCStorageCell *c)
+{
+if (c->tag.FIFO) {
+return;
+}
+
+if (c->data[0] < ITC_CELL_PV_MAX_VAL) {
+c->data[0]++;
+}
+
+if (c->blocked_threads) {
+wake_blocked_threads(c);
+}
+}
+
+static void view_pv_sync_write(ITCStorageCell *c)
+{
+view_pv_common_write(c);
+}
+
+static void view_pv_try_write(ITCStorageCell *c)
+{
+view_pv_common_write(c);
+}
+
 static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
 {
 MIPSITUState *s = (MIPSITUState *)opaque;
@@ -300,6 +356,12 @@ static uint64_t itc_storage_read(void *opaque, hwaddr 
addr, unsigned size)
 case ITCVIEW_EF_TRY:
 ret = view_ef_try_read(cell);
 break;
+case ITCVIEW_PV_SYNC:
+ret = view_pv_sync_read(cell);
+break;
+case ITCVIEW_PV_TRY:
+ret = view_pv_try_read(cell);
+break;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
   "itc_storage_read: Bad ITC View %d\n", (int)view);
@@ -326,6 +388,12 @@ static void itc_storage_write(void *opaque, hwaddr addr, 
uint64_t data,
 case ITCVIEW_EF_TRY:
 view_ef_try_write(cell, data);
 break;
+case ITCVIEW_PV_SYNC:
+view_pv_sync_write(cell);
+break;
+case ITCVIEW_PV_TRY:
+view_pv_try_write(cell);
+break;
 default:
 qemu_log_mask(LOG_GUEST_ERROR,
   "itc_storage_write: Bad ITC View %d\n", (int)view);
-- 
2.7.4




[Qemu-devel] [PATCH v2 6/8] target-mips: check CP0 enabled for CACHE instruction also in R6

2016-03-25 Thread Leon Alrae
Signed-off-by: Leon Alrae 
---
 target-mips/translate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index a5b8805..65f2caf 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -17194,6 +17194,7 @@ static void decode_opc_special3_r6(CPUMIPSState *env, 
DisasContext *ctx)
 /* Treat as NOP. */
 break;
 case R6_OPC_CACHE:
+check_cp0_enabled(ctx);
 /* Treat as NOP. */
 break;
 case R6_OPC_SC:
-- 
2.7.4




[Qemu-devel] [PATCH v2 0/8] mips: implement Inter-Thread Communication Unit

2016-03-25 Thread Leon Alrae
Here's version 2 of the ITC feature. The main change is that this patchset
is rebased on top of CPS patch series and now ITU block is created within
the CPS container instead of Malta board directly.

Original description in version 1 of the series:
https://lists.gnu.org/archive/html/qemu-devel/2016-02/msg00735.html

v2:
* rebased on top of CPS patchset and now ITU is created inside CPS
* merged patches #1 and #2 into single patch and moved few lines from
  realize to reset function
* using memory_region_transaction_{begin,commit} during ITC reconfiguration
* calling itc_reconfiguration also on reset to disable the block

Leon Alrae (8):
  hw/mips: implement ITC Configuration Tags and Storage Cells
  hw/mips: implement ITC Storage - Control View
  hw/mips: implement ITC Storage - Empty/Full Sync and Try Views
  hw/mips: implement ITC Storage - P/V Sync and Try Views
  hw/mips: implement ITC Storage - Bypass View
  target-mips: check CP0 enabled for CACHE instruction also in R6
  target-mips: make ITC Configuration Tags accessible to the CPU
  hw/mips/cps: enable ITU for multithreading processors

 default-configs/mips-softmmu-common.mak |   1 +
 hw/mips/cps.c   |  32 ++
 hw/misc/Makefile.objs   |   1 +
 hw/misc/mips_itu.c  | 525 
 include/hw/mips/cps.h   |   2 +
 include/hw/misc/mips_itu.h  |  72 +
 target-mips/cpu.h   |   8 +-
 target-mips/helper.h|   3 +
 target-mips/op_helper.c |  40 ++-
 target-mips/translate.c |  63 +++-
 10 files changed, 735 insertions(+), 12 deletions(-)
 create mode 100644 hw/misc/mips_itu.c
 create mode 100644 include/hw/misc/mips_itu.h

-- 
2.7.4




Re: [Qemu-devel] [PATCH 2/2] memory: hide mr->ram_addr from qemu_get_ram_ptr users

2016-03-25 Thread Paolo Bonzini
> > > If called by address_space_unmap, is this addition still correct?
> > 
> > No, thanks for the careful review!  That's another opportunity
> > for cleanup actually, splitting the (few) users of qemu_ram_addr_from_host
> > that really need a ram_addr_t and those (the majority) that need a
> > MemoryRegion and offset.  They can use two different functions.  I'll
> > defer this to 2.7 and post the patches to do so later.
> 
> Good idea. The above "block == NULL" qemu_get_ram_ptr callers could use a
> separate function, too - frankly I don't like that function interface too
> much.
> What do you think?

I don't know, at least block == NULL has a clear meaning.  It's not entirely
satisfying, but the users are readable and the ones that pass NULL stand out.

In the case of qemu_ram_addr_from_host, on the other hand, there's a clear
opportunity to avoid bugs.

Paolo



Re: [Qemu-devel] [PATCH 2/2] memory: hide mr->ram_addr from qemu_get_ram_ptr users

2016-03-25 Thread Fam Zheng
On Fri, 03/25 07:58, Paolo Bonzini wrote:
> 
> 
> - Original Message -
> > From: "Fam Zheng" 
> > To: "Paolo Bonzini" 
> > Cc: qemu-devel@nongnu.org, "arei gonglei" , 
> > m...@redhat.com
> > Sent: Friday, March 25, 2016 7:20:38 AM
> > Subject: Re: [PATCH 2/2] memory: hide mr->ram_addr from qemu_get_ram_ptr 
> > users
> > 
> > On Thu, 03/24 12:03, Paolo Bonzini wrote:
> > > Let users of qemu_get_ram_ptr and qemu_ram_ptr_length pass in an
> > > address that is relative to the MemoryRegion.  This basically means
> > > what address_space_translate returns.
> > > 
> > > invalidate_and_set_dirty has to add back mr->ram_addr, but reads do
> > > not need it at all.
> > > 
> > > Signed-off-by: Paolo Bonzini 
> > > ---
> > >  exec.c   | 40 
> > > +++-
> > >  include/exec/memory.h|  1 -
> > >  memory.c |  4 ++--
> > >  scripts/dump-guest-memory.py | 19 +++
> > >  4 files changed, 20 insertions(+), 44 deletions(-)
> > > 
> > > diff --git a/exec.c b/exec.c
> > > index 001b669..ca9e3b6 100644
> > > --- a/exec.c
> > > +++ b/exec.c
> > > @@ -1876,6 +1876,7 @@ void *qemu_get_ram_ptr(RAMBlock *ram_block,
> > > ram_addr_t addr)
> > 
> > Shall we rename the parameter to "offset" then?  I don't know, but that 
> > seems
> > easier to read for me.
> 
> Good question.  I'm not sure about that because of the block == NULL case,
> where the address is absolute.
> 
> > > @@ -1924,7 +1924,7 @@ static void *qemu_ram_ptr_length(RAMBlock 
> > > *ram_block,
> > > ram_addr_t addr,
> > >  block->host = xen_map_cache(block->offset, block->max_length, 1);
> > >  }
> > >  
> > > -return ramblock_ptr(block, offset_inside_block);
> > > +return ramblock_ptr(block, addr);
> > >  }
> > >  
> > >  /*
> > > @@ -2504,6 +2504,8 @@ static void invalidate_and_set_dirty(MemoryRegion
> > > *mr, hwaddr addr,
> > >   hwaddr length)
> > >  {
> > >  uint8_t dirty_log_mask = memory_region_get_dirty_log_mask(mr);
> > > +addr += memory_region_get_ram_addr(mr);
> > > +
> > 
> > If called by address_space_unmap, is this addition still correct?
> 
> No, thanks for the careful review!  That's another opportunity
> for cleanup actually, splitting the (few) users of qemu_ram_addr_from_host
> that really need a ram_addr_t and those (the majority) that need a
> MemoryRegion and offset.  They can use two different functions.  I'll
> defer this to 2.7 and post the patches to do so later.

Good idea. The above "block == NULL" qemu_get_ram_ptr callers could use a
separate function, too - frankly I don't like that function interface too much.
What do you think?

Fam



Re: [Qemu-devel] [PATCH 2/2] memory: hide mr->ram_addr from qemu_get_ram_ptr users

2016-03-25 Thread Paolo Bonzini


- Original Message -
> From: "Fam Zheng" 
> To: "Paolo Bonzini" 
> Cc: qemu-devel@nongnu.org, "arei gonglei" , 
> m...@redhat.com
> Sent: Friday, March 25, 2016 7:20:38 AM
> Subject: Re: [PATCH 2/2] memory: hide mr->ram_addr from qemu_get_ram_ptr users
> 
> On Thu, 03/24 12:03, Paolo Bonzini wrote:
> > Let users of qemu_get_ram_ptr and qemu_ram_ptr_length pass in an
> > address that is relative to the MemoryRegion.  This basically means
> > what address_space_translate returns.
> > 
> > invalidate_and_set_dirty has to add back mr->ram_addr, but reads do
> > not need it at all.
> > 
> > Signed-off-by: Paolo Bonzini 
> > ---
> >  exec.c   | 40 +++-
> >  include/exec/memory.h|  1 -
> >  memory.c |  4 ++--
> >  scripts/dump-guest-memory.py | 19 +++
> >  4 files changed, 20 insertions(+), 44 deletions(-)
> > 
> > diff --git a/exec.c b/exec.c
> > index 001b669..ca9e3b6 100644
> > --- a/exec.c
> > +++ b/exec.c
> > @@ -1876,6 +1876,7 @@ void *qemu_get_ram_ptr(RAMBlock *ram_block,
> > ram_addr_t addr)
> 
> Shall we rename the parameter to "offset" then?  I don't know, but that seems
> easier to read for me.

Good question.  I'm not sure about that because of the block == NULL case,
where the address is absolute.

> > @@ -1924,7 +1924,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block,
> > ram_addr_t addr,
> >  block->host = xen_map_cache(block->offset, block->max_length, 1);
> >  }
> >  
> > -return ramblock_ptr(block, offset_inside_block);
> > +return ramblock_ptr(block, addr);
> >  }
> >  
> >  /*
> > @@ -2504,6 +2504,8 @@ static void invalidate_and_set_dirty(MemoryRegion
> > *mr, hwaddr addr,
> >   hwaddr length)
> >  {
> >  uint8_t dirty_log_mask = memory_region_get_dirty_log_mask(mr);
> > +addr += memory_region_get_ram_addr(mr);
> > +
> 
> If called by address_space_unmap, is this addition still correct?

No, thanks for the careful review!  That's another opportunity
for cleanup actually, splitting the (few) users of qemu_ram_addr_from_host
that really need a ram_addr_t and those (the majority) that need a
MemoryRegion and offset.  They can use two different functions.  I'll
defer this to 2.7 and post the patches to do so later.

> > @@ -3382,13 +3374,13 @@ void address_space_stl_notdirty(AddressSpace *as,
> > hwaddr addr, uint32_t val,
> >  
> >  r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
> >  } else {
> > -addr1 += memory_region_get_ram_addr(mr);
> >  ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
> >  stl_p(ptr, val);
> >  
> >  dirty_log_mask = memory_region_get_dirty_log_mask(mr);
> >  dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE);
> > -cpu_physical_memory_set_dirty_range(addr1, 4, dirty_log_mask);
> > +cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr)
> > + addr,
> 
> Is this line too long?

It's 82 characters

Paolo



Re: [Qemu-devel] [Qemu-ppc] [PATCH] spapr: compute interrupt vector address from LPCR

2016-03-25 Thread Greg Kurz
Hi Cedric,

On Thu, 24 Mar 2016 16:28:53 +0100
Cédric Le Goater  wrote:

> This address is changed by the linux kernel using the H_SET_MODE hcall
> and needs to be migrated in order to restart a spapr VM running in
> TCG. This can be done using the AIL bits from the LPCR register.
> 
> The patch introduces a spapr_h_set_mode_resource_addr() helper to
> share some code with the H_SET_MODE hcall.
> 
> Signed-off-by: Cédric Le Goater 
> ---
>  hw/ppc/spapr.c |   21 +
>  hw/ppc/spapr_hcall.c   |   13 ++---
>  include/hw/ppc/spapr.h |   14 ++
>  3 files changed, 37 insertions(+), 11 deletions(-)
> 
> Index: qemu-dgibson-for-2.6.git/hw/ppc/spapr.c
> ===
> --- qemu-dgibson-for-2.6.git.orig/hw/ppc/spapr.c
> +++ qemu-dgibson-for-2.6.git/hw/ppc/spapr.c
> @@ -1244,6 +1244,24 @@ static bool spapr_vga_init(PCIBus *pci_b
>  }
>  }
> 
> +static int load_excp_prefix(void)
> +{
> +CPUState *cs;
> +
> +CPU_FOREACH(cs) {
> +CPUPPCState *env = _CPU(cs)->env;

And how are we sure env contains the migrated register values ?

Actually, this "works" because vmstate_ppc_cpu is registered before 
vmstate_spapr,
and the same ordering happens to be used when sending state over the wire, but 
it
looks wrong.

The excp_prefix should be restored in cpu_post_load(), unless I'm missing
something.

Cheers.

--
Greg

> +int ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
> +
> +env->excp_prefix = spapr_h_set_mode_resource_addr(ail);
> +if (env->excp_prefix == H_UNSUPPORTED_FLAG) {
> +error_report("LPCR has an invalid AIL value");
> +return -EINVAL;
> +}
> +}
> +
> +return 0;
> +}
> +
>  static int spapr_post_load(void *opaque, int version_id)
>  {
>  sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
> @@ -1257,6 +1275,9 @@ static int spapr_post_load(void *opaque,
>  err = spapr_rtc_import_offset(spapr->rtc, spapr->rtc_offset);
>  }
> 
> +if (!err) {
> +err = load_excp_prefix();
> +}
>  return err;
>  }
> 
> Index: qemu-dgibson-for-2.6.git/include/hw/ppc/spapr.h
> ===
> --- qemu-dgibson-for-2.6.git.orig/include/hw/ppc/spapr.h
> +++ qemu-dgibson-for-2.6.git/include/hw/ppc/spapr.h
> @@ -561,6 +561,20 @@ struct sPAPREventLogEntry {
>  QTAILQ_ENTRY(sPAPREventLogEntry) next;
>  };
> 
> +static inline target_ulong spapr_h_set_mode_resource_addr(target_ulong 
> mflags)
> +{
> +switch (mflags) {
> +case H_SET_MODE_ADDR_TRANS_NONE:
> +return 0;
> +case H_SET_MODE_ADDR_TRANS_0001_8000:
> +return 0x18000;
> +case H_SET_MODE_ADDR_TRANS_C000___4000:
> +return 0xC0004000ULL;
> +default:
> +return H_UNSUPPORTED_FLAG;
> +}
> +}
> +
>  void spapr_events_init(sPAPRMachineState *sm);
>  void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
>  int spapr_h_cas_compose_response(sPAPRMachineState *sm,
> Index: qemu-dgibson-for-2.6.git/hw/ppc/spapr_hcall.c
> ===
> --- qemu-dgibson-for-2.6.git.orig/hw/ppc/spapr_hcall.c
> +++ qemu-dgibson-for-2.6.git/hw/ppc/spapr_hcall.c
> @@ -835,17 +835,8 @@ static target_ulong h_set_mode_resource_
>  return H_P4;
>  }
> 
> -switch (mflags) {
> -case H_SET_MODE_ADDR_TRANS_NONE:
> -prefix = 0;
> -break;
> -case H_SET_MODE_ADDR_TRANS_0001_8000:
> -prefix = 0x18000;
> -break;
> -case H_SET_MODE_ADDR_TRANS_C000___4000:
> -prefix = 0xC0004000ULL;
> -break;
> -default:
> +prefix = spapr_h_set_mode_resource_addr(mflags);
> +if (prefix == H_UNSUPPORTED_FLAG) {
>  return H_UNSUPPORTED_FLAG;
>  }
> 
> 
> 




Re: [Qemu-devel] [PATCH 0/2] memory: Dead code removals

2016-03-25 Thread Paolo Bonzini
> Fam Zheng (2):
>   memory: Remove code for mr->may_overlap
>   memory: Drop FlatRange.romd_mode
> 
>  include/exec/memory.h |  1 -
>  memory.c  | 39 ---
>  2 files changed, 40 deletions(-)


Thanks, both look good.  Not sure they'll make it in 2.6 though.

Paolo



Re: [Qemu-devel] [PATCH RFC 00/17] Dirty bitmaps postcopy migration

2016-03-25 Thread Vladimir Sementsov-Ogievskiy

Hi there.. ping. Hey, what do you think about this all?

On 12.02.2016 21:00, Vladimir Sementsov-Ogievskiy wrote:

Hi all!

These series are derived from my 'Dirty bitmaps migration' series. The
core idea is switch to postcopy migration and drop usage of meta
bitmaps.

These patches provide dirty bitmap postcopy migration feature. Only
named dirty bitmaps are to be migrated. Migration may be enabled using
migration capabilities.

The overall method (thanks to John Snow):

1. migrate bitmaps meta data in .save_live_setup
- create/find related bitmaps on target
- disable them
- create successors (anonimous children) only for enabled migrated
  bitmaps
2. do nothing in precopy stage
3. just before target vm start: enable successors, created in (1)
4. migrate bitmap data
5. reclaime bitmaps (merge successors to their parents)
6. enable bitmaps (only bitmaps, which was enabled in source)


Some patches are unchnaged from (v7) of 'Dirty bitmaps migration'
(DBMv7). I've left Reviewed-by's for them, if you don't like it, say me
and I'll drop them in the following version.

So, relatively to last DBMv7:

01-04: new patches, splitting common postcopy migration out of ram
postcopy migration
05: equal to DBMv7.05
06: new
07: equal to DBMv7.06
08: new
09: equal to DBMv7.07
10: new
11: derived from DBMv7.08, see below
12-15: equal to DBMv7.09-12
16: derived from DBMv7.13
- switch from fifo to socket, as postcopy don't work with fifo
  for now
- change parameters: size, granularity, regions
- add time.sleep, to wait for postcopy migration phase (bad
  temporary solution.
- drop Reviewed-by
17: new

11: the core patch of the series, it is derived from
[DBMv7.08: migration: add migration_block-dirty-bitmap.c]
There are a lot of changes related to switching from precopy to
postcopy, but functions related to migration stream itself
(structs, send/load sequences) are mostly unchnaged.

So, changes, to switch from precopy to postcopy:
- removed all staff related to meta bitmaps and dirty phase!!!
- add dirty_bitmap_mig_enable_successors, and call it before
  target vm start in loadvm_postcopy_handle_run
- add enabled_bitmaps list of bitmaps for
  dirty_bitmap_mig_enable_successors

- enabled flag is send with start bitmap chunk instead of
  completion chunk
- sectors_per_chunk is calculated directly from CHUNK_SIZE, not
  using meta bitmap granularity

- dirty_bitmap_save_iterate: remove dirty_phase, move bulk_phase
  to postcopy stage
- dirty_bitmap_save_pending: remove dirty phase related pending,
  switch pending to non-postcopyable
- dirty_bitmap_load_start: get enabled flag and prepare
  successors for enabled bitmaps, also add them to
  enabled_bitmaps list
- dirty_bitmap_load_complete: for enabled bitmaps: merge them
  with successors and enable

- savevm handlers:
  * remove separate savevm_dirty_bitmap_live_iterate_handlers state
(it was bad idea, any way), and move its save_live_iterate to
savevm_dirty_bitmap_handlers
  * add is_active_iterate savevm handler, which allows iterations
only in postcopy stage (after stopping source vm)
  * add has_postcopy savevm handler. (ofcourse, just returning true)
  * use save_live_complete_postcopy instead of
save_live_complete_precopy

Other changes:
- some debug output changed
- remove MIN_LIVE_SIZE, is_live_iterative and related staff (it
  was needed to omit iterations if bitmap data is small, possibly
  this should be reimplemented)

Vladimir Sementsov-Ogievskiy (17):
   migration: add has_postcopy savevm handler
   migration: fix ram_save_pending
   migration: split common postcopy out of ram postcopy
   migration: introduce postcopy-only pending
   block: add bdrv_next_dirty_bitmap()
   block: add bdrv_dirty_bitmap_enable_successor()
   qapi: add dirty-bitmaps migration capability
   migration: include migrate_dirty_bitmaps in migrate_postcopy
   migration/qemu-file: add qemu_put_counted_string()
   migration: add is_active_iterate handler
   migration: add postcopy migration of dirty bitmaps
   iotests: maintain several vms in test
   iotests: add add_incoming_migration to VM class
   qapi: add md5 checksum of last dirty bitmap level to query-block
   iotests: add default node-name
   iotests: add dirty bitmap migration test 117
   iotests: add dirty bitmap migration test 170

  block/dirty-bitmap.c   |  16 +
  include/block/dirty-bitmap.h   |   4 +
  include/migration/block.h  |   1 +
  include/migration/migration.h  |   5 +
  include/migration/qemu-file.h  |   2 +
  include/migration/vmstate.h|   7 +-
  include/qemu/hbitmap.h |   

[Qemu-devel] [PATCH v2] util: Improved qemu_hexmap() to include an ascii dump of the buffer

2016-03-25 Thread Isaac Lozano
qemu_hexdump() in util/hexdump.c has been changed to give also include a
ascii dump of the buffer. Also, calls to hex_dump() in net/net.c have
been replaced with calls to qemu_hexdump(). This takes care of two misc
BiteSized Tasks.

Signed-off-by: Isaac Lozano <109loza...@gmail.com>
---

v2: Fixed code-style and made debug line smaller.

 net/net.c  | 30 +-
 util/hexdump.c | 33 ++---
 2 files changed, 23 insertions(+), 40 deletions(-)

diff --git a/net/net.c b/net/net.c
index 1a78edf..9bc9ad3 100644
--- a/net/net.c
+++ b/net/net.c
@@ -79,34 +79,6 @@ int default_net = 1;
 /***/
 /* network device redirectors */
 
-#if defined(DEBUG_NET)
-static void hex_dump(FILE *f, const uint8_t *buf, int size)
-{
-int len, i, j, c;
-
-for(i=0;i 16)
-len = 16;
-fprintf(f, "%08x ", i);
-for(j=0;j<16;j++) {
-if (j < len)
-fprintf(f, " %02x", buf[i+j]);
-else
-fprintf(f, "   ");
-}
-fprintf(f, " ");
-for(j=0;j '~')
-c = '.';
-fprintf(f, "%c", c);
-}
-fprintf(f, "\n");
-}
-}
-#endif
-
 static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
 {
 const char *p, *p1;
@@ -662,7 +634,7 @@ static ssize_t 
qemu_send_packet_async_with_flags(NetClientState *sender,
 
 #ifdef DEBUG_NET
 printf("qemu_send_packet_async:\n");
-hex_dump(stdout, buf, size);
+qemu_hexdump((const char *)buf, stdout, "net", size);
 #endif
 
 if (sender->link_down || !sender->peer) {
diff --git a/util/hexdump.c b/util/hexdump.c
index 1d9c129..f879ff0 100644
--- a/util/hexdump.c
+++ b/util/hexdump.c
@@ -18,21 +18,32 @@
 
 void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
 {
-unsigned int b;
+unsigned int b, len, i, c;
 
-for (b = 0; b < size; b++) {
-if ((b % 16) == 0) {
-fprintf(fp, "%s: %04x:", prefix, b);
+for (b = 0; b < size; b += 16) {
+len = size - b;
+if (len > 16) {
+len = 16;
 }
-if ((b % 4) == 0) {
-fprintf(fp, " ");
+fprintf(fp, "%s: %04x:", prefix, b);
+for (i = 0; i < 16; i++) {
+if ((i % 4) == 0) {
+fprintf(fp, " ");
+}
+if (i < len) {
+fprintf(fp, " %02x", (unsigned char)buf[b + i]);
+} else {
+fprintf(fp, "   ");
+}
 }
-fprintf(fp, " %02x", (unsigned char)buf[b]);
-if ((b % 16) == 15) {
-fprintf(fp, "\n");
+fprintf(fp, " ");
+for (i = 0; i < len; i++) {
+c = buf[b + i];
+if (c < ' ' || c > '~') {
+c = '.';
+}
+fprintf(fp, "%c", c);
 }
-}
-if ((b % 16) != 0) {
 fprintf(fp, "\n");
 }
 }
-- 
2.7.2




[Qemu-devel] [PATCH 2/2] memory: Drop FlatRange.romd_mode

2016-03-25 Thread Fam Zheng
Its value is alway set to mr->romd_mode, so the removed comparisons are
fully superseded by "a->mr == b->mr".

Signed-off-by: Fam Zheng 
---
 memory.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/memory.c b/memory.c
index d5b75f2..26af83f 100644
--- a/memory.c
+++ b/memory.c
@@ -224,7 +224,6 @@ struct FlatRange {
 hwaddr offset_in_region;
 AddrRange addr;
 uint8_t dirty_log_mask;
-bool romd_mode;
 bool readonly;
 };
 
@@ -249,7 +248,6 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
 return a->mr == b->mr
 && addrrange_equal(a->addr, b->addr)
 && a->offset_in_region == b->offset_in_region
-&& a->romd_mode == b->romd_mode
 && a->readonly == b->readonly;
 }
 
@@ -309,7 +307,6 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
 r1->addr.size),
  int128_make64(r2->offset_in_region))
 && r1->dirty_log_mask == r2->dirty_log_mask
-&& r1->romd_mode == r2->romd_mode
 && r1->readonly == r2->readonly;
 }
 
@@ -663,7 +660,6 @@ static void render_memory_region(FlatView *view,
 
 fr.mr = mr;
 fr.dirty_log_mask = memory_region_get_dirty_log_mask(mr);
-fr.romd_mode = mr->romd_mode;
 fr.readonly = readonly;
 
 /* Render the region itself into any gaps left by the current view. */
-- 
2.4.3




[Qemu-devel] [PATCH 0/3] Add guest PMU in machine virt

2016-03-25 Thread Shannon Zhao
From: Shannon Zhao 

KVM-ARM64 supports guest PMU now. This series add the support in machine
virt so that guest could use PMU.

Shannon Zhao (3):
  target-arm: kvm64: set guest PMUv3 feature bit if supported
  hw/arm/virt: Add PMU node for virt machine
  hw/arm/virt-acpi-build: Add PMU IRQ number in ACPI table

 hw/arm/virt-acpi-build.c  |  3 +++
 hw/arm/virt.c | 31 
 include/hw/arm/virt.h |  2 ++
 include/sysemu/kvm.h  |  1 +
 linux-headers/asm-arm64/kvm.h |  6 +
 linux-headers/linux/kvm.h |  2 ++
 stubs/kvm.c   |  5 
 target-arm/cpu-qom.h  |  2 ++
 target-arm/kvm64.c| 56 +++
 9 files changed, 108 insertions(+)

-- 
2.0.4





[Qemu-devel] [PATCH 2/3] hw/arm/virt: Add PMU node for virt machine

2016-03-25 Thread Shannon Zhao
From: Shannon Zhao 

Add a virtual PMU device for virt machine while use PPI 7 for PMU
overflow interrupt number.

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt.c | 31 +++
 include/hw/arm/virt.h |  2 ++
 include/sysemu/kvm.h  |  1 +
 stubs/kvm.c   |  5 +
 target-arm/kvm64.c| 51 +++
 5 files changed, 90 insertions(+)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 95331a5..94c2beb 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -427,6 +427,35 @@ static void fdt_add_gic_node(VirtBoardInfo *vbi, int type)
 qemu_fdt_setprop_cell(vbi->fdt, "/intc", "phandle", vbi->gic_phandle);
 }
 
+static void fdt_add_pmu_nodes(const VirtBoardInfo *vbi)
+{
+CPUState *cpu;
+ARMCPU *armcpu;
+uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;
+
+CPU_FOREACH(cpu) {
+armcpu = ARM_CPU(cpu);
+   if (!armcpu->has_pmu) {
+   return;
+   }
+
+kvm_arm_pmu_create(cpu, VIRTUAL_PMU_IRQ + 16);
+}
+
+irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,
+ GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1);
+
+armcpu = ARM_CPU(qemu_get_cpu(0));
+qemu_fdt_add_subnode(vbi->fdt, "/pmu");
+if (arm_feature(>env, ARM_FEATURE_V8)) {
+const char compat[] = "arm,armv8-pmuv3";
+qemu_fdt_setprop(vbi->fdt, "/pmu", "compatible",
+ compat, sizeof(compat));
+qemu_fdt_setprop_cells(vbi->fdt, "/pmu", "interrupts",
+   GIC_FDT_IRQ_TYPE_PPI, VIRTUAL_PMU_IRQ, 
irqflags);
+}
+}
+
 static void create_v2m(VirtBoardInfo *vbi, qemu_irq *pic)
 {
 int i;
@@ -1242,6 +1271,8 @@ static void machvirt_init(MachineState *machine)
 
 create_gic(vbi, pic, gic_version, vms->secure);
 
+fdt_add_pmu_nodes(vbi);
+
 create_uart(vbi, pic, VIRT_UART, sysmem);
 
 if (vms->secure) {
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index ecd8589..864eb49 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -40,6 +40,8 @@
 #define ARCH_TIMER_NS_EL1_IRQ 14
 #define ARCH_TIMER_NS_EL2_IRQ 10
 
+#define VIRTUAL_PMU_IRQ 7
+
 enum {
 VIRT_FLASH,
 VIRT_MEM,
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 6695fa7..80b6cb3 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -514,4 +514,5 @@ int kvm_set_one_reg(CPUState *cs, uint64_t id, void 
*source);
  * Returns: 0 on success, or a negative errno on failure.
  */
 int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target);
+void kvm_arm_pmu_create(CPUState *cs, int irq);
 #endif
diff --git a/stubs/kvm.c b/stubs/kvm.c
index ddd6204..58a348a 100644
--- a/stubs/kvm.c
+++ b/stubs/kvm.c
@@ -6,3 +6,8 @@ int kvm_arch_irqchip_create(MachineState *ms, KVMState *s)
 {
 return 0;
 }
+
+void kvm_arm_pmu_create(CPUState *cs, int irq)
+{
+return;
+}
diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index b364789..b97b9ef 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -382,6 +382,57 @@ static CPUWatchpoint *find_hw_watchpoint(CPUState *cpu, 
target_ulong addr)
 return NULL;
 }
 
+static bool kvm_arm_pmu_support_ctrl(CPUState *cs, struct kvm_device_attr 
*attr)
+{
+return kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, attr) == 0;
+}
+
+static void kvm_arm_pmu_init(CPUState *cs)
+{
+int err;
+
+struct kvm_device_attr attr = {
+.group = KVM_ARM_VCPU_PMU_V3_CTRL,
+.attr = KVM_ARM_VCPU_PMU_V3_INIT,
+.flags = 0,
+};
+
+if (!kvm_arm_pmu_support_ctrl(cs, )) {
+return;
+}
+
+err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, );
+if (err < 0) {
+fprintf(stderr, "KVM_{SET/GET}_DEVICE_ATTR failed: %s\n",
+strerror(-err));
+abort();
+}
+}
+
+void kvm_arm_pmu_create(CPUState *cs, int irq)
+{
+int err;
+
+struct kvm_device_attr attr = {
+.group = KVM_ARM_VCPU_PMU_V3_CTRL,
+.addr = (intptr_t),
+.attr = KVM_ARM_VCPU_PMU_V3_IRQ,
+.flags = 0,
+};
+
+if (!kvm_arm_pmu_support_ctrl(cs, )) {
+return;
+}
+
+err = kvm_vcpu_ioctl(cs, KVM_SET_DEVICE_ATTR, );
+if (err < 0) {
+fprintf(stderr, "KVM_{SET/GET}_DEVICE_ATTR failed: %s\n",
+strerror(-err));
+abort();
+}
+
+kvm_arm_pmu_init(cs);
+}
 
 static inline void set_feature(uint64_t *features, int feature)
 {
-- 
2.0.4





[Qemu-devel] [PATCH 1/3] target-arm: kvm64: set guest PMUv3 feature bit if supported

2016-03-25 Thread Shannon Zhao
From: Shannon Zhao 

Check if kvm supports guest PMUv3. If so, set the corresponding feature
bit for vcpu.

Signed-off-by: Shannon Zhao 
---
 linux-headers/asm-arm64/kvm.h | 6 ++
 linux-headers/linux/kvm.h | 2 ++
 target-arm/cpu-qom.h  | 2 ++
 target-arm/kvm64.c| 5 +
 4 files changed, 15 insertions(+)

diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
index a2fd4d9..3097f2f 100644
--- a/linux-headers/asm-arm64/kvm.h
+++ b/linux-headers/asm-arm64/kvm.h
@@ -94,6 +94,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
 #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
 #define KVM_ARM_VCPU_PSCI_0_2  2 /* CPU uses PSCI v0.2 */
+#define KVM_ARM_VCPU_PMU_V33
 
 struct kvm_vcpu_init {
__u32 target;
@@ -204,6 +205,11 @@ struct kvm_arch_memory_slot {
 #define KVM_DEV_ARM_VGIC_GRP_CTRL  4
 #define   KVM_DEV_ARM_VGIC_CTRL_INIT   0
 
+/* Device Control API on vcpu fd */
+#define KVM_ARM_VCPU_PMU_V3_CTRL   0
+#define   KVM_ARM_VCPU_PMU_V3_IRQ  0
+#define   KVM_ARM_VCPU_PMU_V3_INIT 1
+
 /* KVM_IRQ_LINE irq field index values */
 #define KVM_ARM_IRQ_TYPE_SHIFT 24
 #define KVM_ARM_IRQ_TYPE_MASK  0xff
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 4a56b9e..104210a 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -856,6 +856,8 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
 #define KVM_CAP_HYPERV_SYNIC 123
 #define KVM_CAP_S390_RI 124
+#define KVM_CAP_ARM_PMU_V3 125
+#define KVM_CAP_VCPU_ATTRIBUTES 126
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 1061c08..93aa6a4 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -105,6 +105,8 @@ typedef struct ARMCPU {
 bool powered_off;
 /* CPU has security extension */
 bool has_el3;
+/* CPU has PMU (Performance Monitor Unit) */
+bool has_pmu;
 
 /* CPU has memory protection unit */
 bool has_mpu;
diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index e8527bf..b364789 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -461,6 +461,11 @@ int kvm_arch_init_vcpu(CPUState *cs)
 if (!arm_feature(>env, ARM_FEATURE_AARCH64)) {
 cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_EL1_32BIT;
 }
+if (kvm_irqchip_in_kernel() &&
+kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PMU_V3)) {
+cpu->has_pmu = true;
+cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PMU_V3;
+}
 
 /* Do KVM_ARM_VCPU_INIT ioctl */
 ret = kvm_arm_vcpu_init(cs);
-- 
2.0.4





[Qemu-devel] [PATCH 3/3] hw/arm/virt-acpi-build: Add PMU IRQ number in ACPI table

2016-03-25 Thread Shannon Zhao
From: Shannon Zhao 

Add PMU IRQ number in ACPI table, then we can use PMU in guest through
ACPI.

Signed-off-by: Shannon Zhao 
---
 hw/arm/virt-acpi-build.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 6a86b2c..7a377e5 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -490,6 +490,9 @@ build_madt(GArray *table_data, GArray *linker, 
VirtGuestInfo *guest_info)
 gicc->arm_mpidr = armcpu->mp_affinity;
 gicc->uid = i;
 gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
+
+if (armcpu->has_pmu)
+gicc->performance_interrupt = VIRTUAL_PMU_IRQ + 16;
 }
 
 if (guest_info->gic_version == 3) {
-- 
2.0.4





[Qemu-devel] [PATCH 0/2] memory: Dead code removals

2016-03-25 Thread Fam Zheng



Fam Zheng (2):
  memory: Remove code for mr->may_overlap
  memory: Drop FlatRange.romd_mode

 include/exec/memory.h |  1 -
 memory.c  | 39 ---
 2 files changed, 40 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH 1/2] memory: Remove code for mr->may_overlap

2016-03-25 Thread Fam Zheng
The collision check does nothing and hasn't been used. Remove the
variable together with related code.

Signed-off-by: Fam Zheng 
---
 include/exec/memory.h |  1 -
 memory.c  | 35 ---
 2 files changed, 36 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 2de7898..f071a7c 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -188,7 +188,6 @@ struct MemoryRegion {
 MemoryRegion *alias;
 hwaddr alias_offset;
 int32_t priority;
-bool may_overlap;
 QTAILQ_HEAD(subregions, MemoryRegion) subregions;
 QTAILQ_ENTRY(MemoryRegion) subregions_link;
 QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
diff --git a/memory.c b/memory.c
index 95f7209..d5b75f2 100644
--- a/memory.c
+++ b/memory.c
@@ -1054,13 +1054,6 @@ static void memory_region_get_priority(Object *obj, 
Visitor *v,
 visit_type_int32(v, name, , errp);
 }
 
-static bool memory_region_get_may_overlap(Object *obj, Error **errp)
-{
-MemoryRegion *mr = MEMORY_REGION(obj);
-
-return mr->may_overlap;
-}
-
 static void memory_region_get_size(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
@@ -1098,10 +1091,6 @@ static void memory_region_initfn(Object *obj)
 memory_region_get_priority,
 NULL, /* memory_region_set_priority */
 NULL, NULL, _abort);
-object_property_add_bool(OBJECT(mr), "may-overlap",
- memory_region_get_may_overlap,
- NULL, /* memory_region_set_may_overlap */
- _abort);
 object_property_add(OBJECT(mr), "size", "uint64",
 memory_region_get_size,
 NULL, /* memory_region_set_size, */
@@ -1861,7 +1850,6 @@ void memory_region_del_eventfd(MemoryRegion *mr,
 
 static void memory_region_update_container_subregions(MemoryRegion *subregion)
 {
-hwaddr offset = subregion->addr;
 MemoryRegion *mr = subregion->container;
 MemoryRegion *other;
 
@@ -1869,27 +1857,6 @@ static void 
memory_region_update_container_subregions(MemoryRegion *subregion)
 
 memory_region_ref(subregion);
 QTAILQ_FOREACH(other, >subregions, subregions_link) {
-if (subregion->may_overlap || other->may_overlap) {
-continue;
-}
-if (int128_ge(int128_make64(offset),
-  int128_add(int128_make64(other->addr), other->size))
-|| int128_le(int128_add(int128_make64(offset), subregion->size),
- int128_make64(other->addr))) {
-continue;
-}
-#if 0
-printf("warning: subregion collision %llx/%llx (%s) "
-   "vs %llx/%llx (%s)\n",
-   (unsigned long long)offset,
-   (unsigned long long)int128_get64(subregion->size),
-   subregion->name,
-   (unsigned long long)other->addr,
-   (unsigned long long)int128_get64(other->size),
-   other->name);
-#endif
-}
-QTAILQ_FOREACH(other, >subregions, subregions_link) {
 if (subregion->priority >= other->priority) {
 QTAILQ_INSERT_BEFORE(other, subregion, subregions_link);
 goto done;
@@ -1915,7 +1882,6 @@ void memory_region_add_subregion(MemoryRegion *mr,
  hwaddr offset,
  MemoryRegion *subregion)
 {
-subregion->may_overlap = false;
 subregion->priority = 0;
 memory_region_add_subregion_common(mr, offset, subregion);
 }
@@ -1925,7 +1891,6 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
  MemoryRegion *subregion,
  int priority)
 {
-subregion->may_overlap = true;
 subregion->priority = priority;
 memory_region_add_subregion_common(mr, offset, subregion);
 }
-- 
2.4.3




Re: [Qemu-devel] [PATCH 0/6] virtio: refactor host notifiers

2016-03-25 Thread Fam Zheng
On Thu, 03/24 17:15, Cornelia Huck wrote:
> Here's the next version of my refactoring of the virtio host notifiers.
> This one actually survives a bit of testing for me (reboot loop).
> 
> As this patchset fixes a latent bug exposed by the recent dataplane
> changes (we have a deassigned ioeventfd for a short period of time
> during dataplane start, which leads to the virtqueue handler being
> called in both the vcpu thread and the iothread simultaneously), I'd
> like to see this in 2.6.
> 
> Changes from RFC:
> - Fixed some silly errors (checking for !disabled instead of disabled,
>   virtio_ccw_stop_ioeventfd() calling virtio_bus_start_ioeventfd()).
> - Completely reworked set_host_notifier(): We only want to set/unset
>   the actual handler function and don't want to do anything to the
>   ioeventfd backing, so reduce the function to actually doing only
>   that.
> - With the change above, we can lose the 'assign' parameter in
>   virtio_bus_stop_ioeventfd() again.
> - Added more comments that hopefully make it clearer what is going on.
> 
> I'd appreciate it if people could give it some testing; I'll be back
> to look at the fallout after Easter.

Tested-by: Fam Zheng 

> 
> Cornelia Huck (6):
>   virtio-bus: common ioeventfd infrastructure
>   virtio-bus: have callers tolerate new host notifier api
>   virtio-ccw: convert to ioeventfd callbacks
>   virtio-pci: convert to ioeventfd callbacks
>   virtio-mmio: convert to ioeventfd callbacks
>   virtio-bus: remove old set_host_notifier callback
> 
>  hw/block/dataplane/virtio-blk.c |   6 +-
>  hw/s390x/virtio-ccw.c   | 133 
> ++--
>  hw/scsi/virtio-scsi-dataplane.c |   9 ++-
>  hw/virtio/vhost.c   |  13 ++--
>  hw/virtio/virtio-bus.c  | 132 +++
>  hw/virtio/virtio-mmio.c | 128 +-
>  hw/virtio/virtio-pci.c  | 124 +
>  include/hw/virtio/virtio-bus.h  |  31 +-
>  8 files changed, 303 insertions(+), 273 deletions(-)
> 
> -- 
> 2.6.5
> 



Re: [Qemu-devel] [PATCH] pci_register_bar: cleanup

2016-03-25 Thread Paolo Bonzini


On 25/03/2016 07:49, Cao jin wrote:
> place relevant code tegother, make the code easier to read
> 
> Signed-off-by: Cao jin 
> ---
>  hw/pci/pci.c | 16 
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index e67664d..f0f41dc 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -974,7 +974,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
>uint8_t type, MemoryRegion *memory)
>  {
>  PCIIORegion *r;
> -uint32_t addr;
> +uint32_t addr; /* offset in pci config space */
>  uint64_t wmask;
>  pcibus_t size = memory_region_size(memory);
>  
> @@ -990,15 +990,20 @@ void pci_register_bar(PCIDevice *pci_dev, int 
> region_num,
>  r->addr = PCI_BAR_UNMAPPED;
>  r->size = size;
>  r->type = type;
> -r->memory = NULL;
> +r->memory = memory;
> +r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
> +? pci_dev->bus->address_space_io
> +: pci_dev->bus->address_space_mem;
>  
>  wmask = ~(size - 1);
> -addr = pci_bar(pci_dev, region_num);
>  if (region_num == PCI_ROM_SLOT) {
>  /* ROM enable bit is writable */
>  wmask |= PCI_ROM_ADDRESS_ENABLE;
>  }
> +
> +addr = pci_bar(pci_dev, region_num);
>  pci_set_long(pci_dev->config + addr, type);
> +
>  if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
>  r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
>  pci_set_quad(pci_dev->wmask + addr, wmask);
> @@ -1007,11 +1012,6 @@ void pci_register_bar(PCIDevice *pci_dev, int 
> region_num,
>  pci_set_long(pci_dev->wmask + addr, wmask & 0x);
>  pci_set_long(pci_dev->cmask + addr, 0x);
>  }
> -pci_dev->io_regions[region_num].memory = memory;
> -pci_dev->io_regions[region_num].address_space
> -= type & PCI_BASE_ADDRESS_SPACE_IO
> -? pci_dev->bus->address_space_io
> -: pci_dev->bus->address_space_mem;
>  }
>  
>  static void pci_update_vga(PCIDevice *pci_dev)
> 

Reviewed-by: Paolo Bonzini 



Re: [Qemu-devel] [Qemu-ppc] [PATCHv2 2/3] target-ppc: Add helpers for updating a CPU's SDR1 and external HPT

2016-03-25 Thread Greg Kurz
Hi Laurent,

On Thu, 24 Mar 2016 09:41:59 +0100
Laurent Vivier  wrote:

> On 24/03/2016 06:35, David Gibson wrote:
> > On Tue, Mar 22, 2016 at 05:33:45PM +0100, Laurent Vivier wrote:  
> >> Hi David,
> >>
> >> using kvm-unit-tests, I've found a side effect of your patches: the MSR
> >> is cleared (and perhaps some others).
> >>
> >> I was trying to test my patch on top of QEMU master:
> >>
> >> "ppc64: set MSR_SF bit"
> >> http://patchwork.ozlabs.org/patch/598198/
> >>
> >> and it was not working anymore.
> >>
> >> By bisecting, I've found this commit.
> >>
> >> I think "cpu_synchronize_state()" in "ppc_hash64_set_external_hpt()"
> >> restores the MSR from KVM whereas the one from QEMU has not been saved,
> >> because cpu_synchronize_all_post_reset() is called later.
> >>
> >> So it is cleared.
> >>
> >> You can test this by applying the MSR_SF patch and using the "emulator"
> >> test of kvm-unit-tests (the "emulator: 64bit" test case)  
> > 
> > Ugh, you're right of course.  But, I'm having a bit of trouble
> > figuring out how to fix it propertly.  
> 
> Perhaps you can just remove the cpu_synchronize_state()?
> 
> As this is in the reset phase (spapr_cpu_reset()), I think the content
> of the QEMU side registers are correct, and they will be synchronized at
> the end of the reset phase.
> 

I think this is right because qemu_system_reset() is called either:
- during system startup:

cpu_synchronize_all_post_init();   => push regs to KVM, kvm_vcpu_dirty = 
false
...
qemu_system_reset(VMRESET_SILENT);

QEMU still have good values for the registers though, since KVM hasn't run yet.

But ppc_hash64_set_external_hpt()->cpu_synchronize_state() will indeed pull
the registers from KVM and clear MSR_SF, since we have kvm_vcpu_dirty == false.

- or from main_loop_should_exit() and we have:

cpu_synchronize_all_states();
qemu_system_reset(VMRESET_REPORT);
and
cpu_synchronize_all_states();
qemu_system_reset(VMRESET_SILENT);

In which case ppc_hash64_set_external_hpt()->cpu_synchronize_state() isn't
needed.

Makes sense ?

Cheers.

--
Greg

> You can see in spapr_cpu_reset(), SPR_HIOR is updated without prior
> sync. I think spapr_cpu_reset() is called by qemu_device_reset() in
> qemu_system_reset(), which is always followed by a
> cpu_synchronize_all_post_reset(), which will call
> do_kvm_cpu_synchronize_post_reset() (kvm_arch_put_registers(cpu,
> KVM_PUT_RESET_STATE)) at the end.
> 
> 
> Laurent
> 
> >> On 07/03/2016 03:26, David Gibson wrote:  
> >>> When a Power cpu with 64-bit hash MMU has it's hash page table (HPT)
> >>> pointer updated by a write to the SDR1 register we need to update some
> >>> derived variables.  Likewise, when the cpu is configured for an external
> >>> HPT (one not in the guest memory space) some derived variables need to be
> >>> updated.
> >>>
> >>> Currently the logic for this is (partially) duplicated in ppc_store_sdr1()
> >>> and in spapr_cpu_reset().  In future we're going to need it in some other
> >>> places, so make some common helpers for this update.
> >>>
> >>> In addition the new ppc_hash64_set_external_hpt() helper also updates
> >>> SDR1 in KVM - it's not updated by the normal runtime KVM <-> qemu CPU
> >>> synchronization.  In a sense this belongs logically in the
> >>> ppc_hash64_set_sdr1() helper, but that is called from
> >>> kvm_arch_get_registers() so can't itself call cpu_synchronize_state()
> >>> without infinite recursion.  In practice this doesn't matter because
> >>> the only other caller is TCG specific.
> >>>
> >>> Currently there aren't situations where updating SDR1 at runtime in KVM
> >>> matters, but there are going to be in future.
> >>>
> >>> Signed-off-by: David Gibson 
> >>> ---
> >>>  hw/ppc/spapr.c  | 13 ++---
> >>>  target-ppc/kvm.c|  2 +-
> >>>  target-ppc/kvm_ppc.h|  6 ++
> >>>  target-ppc/mmu-hash64.c | 43 +++
> >>>  target-ppc/mmu-hash64.h |  6 ++
> >>>  target-ppc/mmu_helper.c | 13 ++---
> >>>  6 files changed, 64 insertions(+), 19 deletions(-)
> >>>
> >>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> >>> index 64c4acc..72a018b 100644
> >>> --- a/hw/ppc/spapr.c
> >>> +++ b/hw/ppc/spapr.c
> >>> @@ -1196,17 +1196,8 @@ static void spapr_cpu_reset(void *opaque)
> >>>  
> >>>  env->spr[SPR_HIOR] = 0;
> >>>  
> >>> -env->external_htab = (uint8_t *)spapr->htab;
> >>> -env->htab_base = -1;
> >>> -/*
> >>> - * htab_mask is the mask used to normalize hash value to PTEG index.
> >>> - * htab_shift is log2 of hash table size.
> >>> - * We have 8 hpte per group, and each hpte is 16 bytes.
> >>> - * ie have 128 bytes per hpte entry.
> >>> - */
> >>> -env->htab_mask = (1ULL << (spapr->htab_shift - 7)) - 1;
> >>> -env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab |
> >>> -(spapr->htab_shift - 18);
> >>> +

[Qemu-devel] [PATCH V1 1/3] colo-compare: introduce colo compare initlization

2016-03-25 Thread Zhang Chen
packet come from primary char indev will be send to
outdev - packet come from secondary char dev will be drop

Signed-off-by: Li Zhijian 
Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
---
 net/Makefile.objs  |   1 +
 net/colo-compare.c | 344 +
 vl.c   |   3 +-
 3 files changed, 347 insertions(+), 1 deletion(-)
 create mode 100644 net/colo-compare.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index b7c22fd..ba92f73 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -16,3 +16,4 @@ common-obj-$(CONFIG_NETMAP) += netmap.o
 common-obj-y += filter.o
 common-obj-y += filter-buffer.o
 common-obj-y += filter-mirror.o
+common-obj-y += colo-compare.o
diff --git a/net/colo-compare.c b/net/colo-compare.c
new file mode 100644
index 000..62c66df
--- /dev/null
+++ b/net/colo-compare.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2016 FUJITSU LIMITED
+ * Author: Zhang Chen 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
+
+#include "net/net.h"
+#include "net/vhost_net.h"
+#include "qom/object_interfaces.h"
+#include "qemu/iov.h"
+#include "qom/object.h"
+#include "qemu/typedefs.h"
+#include "net/queue.h"
+#include "sysemu/char.h"
+#include "qemu/sockets.h"
+
+#define TYPE_COLO_COMPARE "colo-compare"
+#define COLO_COMPARE(obj) \
+OBJECT_CHECK(CompareState, (obj), TYPE_COLO_COMPARE)
+
+#define COMPARE_READ_LEN_MAX NET_BUFSIZE
+
+static QTAILQ_HEAD(, CompareState) net_compares =
+   QTAILQ_HEAD_INITIALIZER(net_compares);
+
+typedef struct ReadState {
+int state; /* 0 = getting length, 1 = getting data */
+unsigned int index;
+unsigned int packet_len;
+uint8_t buf[COMPARE_READ_LEN_MAX];
+} ReadState;
+
+typedef struct CompareState {
+Object parent;
+
+char *pri_indev;
+char *sec_indev;
+char *outdev;
+CharDriverState *chr_pri_in;
+CharDriverState *chr_sec_in;
+CharDriverState *chr_out;
+QTAILQ_ENTRY(CompareState) next;
+ReadState pri_rs;
+ReadState sec_rs;
+} CompareState;
+
+static int compare_chr_send(CharDriverState *out, const uint8_t *buf, int size)
+{
+int ret = 0;
+uint32_t len = htonl(size);
+
+if (!size) {
+return 0;
+}
+
+ret = qemu_chr_fe_write_all(out, (uint8_t *), sizeof(len));
+if (ret != sizeof(len)) {
+goto err;
+}
+
+ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
+if (ret != size) {
+goto err;
+}
+
+return 0;
+
+err:
+return ret < 0 ? ret : -EIO;
+}
+
+static int compare_chr_can_read(void *opaque)
+{
+return COMPARE_READ_LEN_MAX;
+}
+
+/* Returns
+ * 0: readstate is not ready
+ * 1: readstate is ready
+ * otherwise error occurs
+ */
+static int compare_chr_fill_rstate(ReadState *rs, const uint8_t *buf, int size)
+{
+unsigned int l;
+while (size > 0) {
+/* reassemble a packet from the network */
+switch (rs->state) { /* 0 = getting length, 1 = getting data */
+case 0:
+l = 4 - rs->index;
+if (l > size) {
+l = size;
+}
+memcpy(rs->buf + rs->index, buf, l);
+buf += l;
+size -= l;
+rs->index += l;
+if (rs->index == 4) {
+/* got length */
+rs->packet_len = ntohl(*(uint32_t *)rs->buf);
+rs->index = 0;
+rs->state = 1;
+}
+break;
+case 1:
+l = rs->packet_len - rs->index;
+if (l > size) {
+l = size;
+}
+if (rs->index + l <= sizeof(rs->buf)) {
+memcpy(rs->buf + rs->index, buf, l);
+} else {
+error_report("serious error: oversized packet received.");
+rs->index = rs->state = 0;
+return -1;
+}
+
+rs->index += l;
+buf += l;
+size -= l;
+if (rs->index >= rs->packet_len) {
+rs->index = 0;
+rs->state = 0;
+return 1;
+}
+break;
+}
+}
+return 0;
+}
+
+static void compare_pri_chr_in(void *opaque, const uint8_t *buf, int size)
+{
+CompareState *s = COLO_COMPARE(opaque);
+int ret;
+
+ret = compare_chr_fill_rstate(>pri_rs, buf, size);
+if (ret == 1) {
+/* FIXME: enqueue to primary packet list */
+compare_chr_send(s->chr_out, buf, size);
+} else if (ret == -1) {
+qemu_chr_add_handlers(s->chr_pri_in, NULL, NULL, NULL, NULL);
+}
+}
+
+static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size)
+{
+

[Qemu-devel] [PATCH V1 0/3] Introduce COLO-compare

2016-03-25 Thread Zhang Chen
COLO-compare is a part of COLO project. It is used
to compare the network package to help COLO decide
whether to do checkpoint.

v1:
 - initial patch


Zhang Chen (3):
  colo-compare: introduce colo compare initlization
  colo-compare: track connection and enqueue packet
  colo-compare: introduce packet comparison thread

 net/Makefile.objs  |   1 +
 net/colo-compare.c | 782 +
 vl.c   |   3 +-
 3 files changed, 785 insertions(+), 1 deletion(-)
 create mode 100644 net/colo-compare.c

-- 
1.9.1






[Qemu-devel] [PATCH V1 2/3] colo-compare: track connection and enqueue packet

2016-03-25 Thread Zhang Chen
In this patch we use kernel jhash table to track
connection, and then enqueue net packet like this:

+ CompareState ++
|   |
+---+   +---+ +---+
|conn list  +--->conn   +->conn   |
+---+   +---+ +---+
|   | |   | |  |
+---+ +---v+  +---v++---v+ +---v+
  |primary |  |secondary|primary | |secondary
  |packet  |  |packet  +|packet  | |packet  +
  ++  ++++ ++
  |   | |  |
  +---v+  +---v++---v+ +---v+
  |primary |  |secondary|primary | |secondary
  |packet  |  |packet  +|packet  | |packet  +
  ++  ++++ ++
  |   | |  |
  +---v+  +---v++---v+ +---v+
  |primary |  |secondary|primary | |secondary
  |packet  |  |packet  +|packet  | |packet  +
  ++  ++++ ++

Signed-off-by: Zhang Chen 
Signed-off-by: Li Zhijian 
Signed-off-by: Wen Congyang 
---
 net/colo-compare.c | 324 -
 1 file changed, 321 insertions(+), 3 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 62c66df..0bb5a51 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -20,15 +20,22 @@
 #include "net/queue.h"
 #include "sysemu/char.h"
 #include "qemu/sockets.h"
+#include 
+#include "slirp/slirp.h"
+#include "qemu/jhash.h"
+#include 
 
 #define TYPE_COLO_COMPARE "colo-compare"
 #define COLO_COMPARE(obj) \
 OBJECT_CHECK(CompareState, (obj), TYPE_COLO_COMPARE)
 
 #define COMPARE_READ_LEN_MAX NET_BUFSIZE
+#define PAGE_SIZE 4096
+#define ETH_HLEN 14
 
 static QTAILQ_HEAD(, CompareState) net_compares =
QTAILQ_HEAD_INITIALIZER(net_compares);
+static ssize_t hashtable_max_size;
 
 typedef struct ReadState {
 int state; /* 0 = getting length, 1 = getting data */
@@ -37,6 +44,28 @@ typedef struct ReadState {
 uint8_t buf[COMPARE_READ_LEN_MAX];
 } ReadState;
 
+/*
+  + CompareState ++
+  |   |
+  +---+   +---+ +---+
+  |conn list  +--->conn   +->conn   |
+  +---+   +---+ +---+
+  |   | |   | |  |
+  +---+ +---v+  +---v++---v+ +---v+
+|primary |  |secondary|primary | |secondary
+|packet  |  |packet  +|packet  | |packet  +
+++  ++++ ++
+|   | |  |
++---v+  +---v++---v+ +---v+
+|primary |  |secondary|primary | |secondary
+|packet  |  |packet  +|packet  | |packet  +
+++  ++++ ++
+|   | |  |
++---v+  +---v++---v+ +---v+
+|primary |  |secondary|primary | |secondary
+|packet  |  |packet  +|packet  | |packet  +
+++  ++++ ++
+*/
 typedef struct CompareState {
 Object parent;
 
@@ -49,8 +78,268 @@ typedef struct CompareState {
 QTAILQ_ENTRY(CompareState) next;
 ReadState pri_rs;
 ReadState sec_rs;
+
+/* connection list: the connections belonged to this NIC could be found
+ * in this list.
+ * element type: Connection
+ */
+GQueue conn_list;
+QemuMutex conn_list_lock; /* to protect conn_list */
+/* hashtable to save connection */
+GHashTable *connection_track_table;
+/* to save unprocessed_connections */
+GQueue unprocessed_connections;
+/* proxy current hash size */
+ssize_t hashtable_size;
 } CompareState;
 
+typedef struct Packet {
+void *data;
+union {
+uint8_t *network_layer;
+struct ip *ip;
+};
+uint8_t *transport_layer;
+int size;
+CompareState *s;
+} Packet;
+
+typedef struct ConnectionKey {
+/* (src, dst) must be grouped, in the same way than in IP header */
+struct in_addr src;
+struct in_addr dst;
+uint16_t src_port;
+uint16_t dst_port;
+uint8_t ip_proto;
+} QEMU_PACKED ConnectionKey;
+
+typedef struct Connection {
+QemuMutex list_lock;
+/* connection primary send queue: element type: Packet */
+GQueue primary_list;
+/* 

[Qemu-devel] [PATCH V1 3/3] colo-compare: introduce packet comparison thread

2016-03-25 Thread Zhang Chen
if packets are same, we send primary packet and drop secondary
packet, otherwise notify COLO do checkpoint.

Signed-off-by: Zhang Chen 
Signed-off-by: Li Zhijian 
Signed-off-by: Wen Congyang 
---
 net/colo-compare.c | 122 -
 1 file changed, 121 insertions(+), 1 deletion(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 0bb5a51..1debc0e 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -36,6 +36,7 @@
 static QTAILQ_HEAD(, CompareState) net_compares =
QTAILQ_HEAD_INITIALIZER(net_compares);
 static ssize_t hashtable_max_size;
+static int colo_need_checkpoint;
 
 typedef struct ReadState {
 int state; /* 0 = getting length, 1 = getting data */
@@ -91,6 +92,13 @@ typedef struct CompareState {
 GQueue unprocessed_connections;
 /* proxy current hash size */
 ssize_t hashtable_size;
+
+/* notify compare thread */
+QemuEvent event;
+/* compare thread, a thread for each NIC */
+QemuThread thread;
+int thread_status;
+
 } CompareState;
 
 typedef struct Packet {
@@ -129,6 +137,15 @@ enum {
 SECONDARY_IN,
 };
 
+enum {
+/* compare thread isn't started */
+COMPARE_THREAD_NONE,
+/* compare thread is running */
+COMPARE_THREAD_RUNNING,
+/* compare thread exit */
+COMPARE_THREAD_EXIT,
+};
+
 static void packet_destroy(void *opaque, void *user_data);
 static int compare_chr_send(CharDriverState *out, const uint8_t *buf, int 
size);
 
@@ -340,6 +357,88 @@ static inline void colo_flush_connection(void *opaque, 
void *user_data)
 qemu_mutex_unlock(>list_lock);
 }
 
+static void colo_notify_checkpoint(void)
+{
+colo_need_checkpoint = true;
+}
+
+/* TODO colo_do_checkpoint() {
+ * we flush the connections and reset 'colo_need_checkpoint'
+ * }
+ */
+
+static inline void colo_dump_packet(Packet *pkt)
+{
+int i;
+for (i = 0; i < pkt->size; i++) {
+printf("%02x ", ((uint8_t *)pkt->data)[i]);
+}
+printf("\n");
+}
+
+/*
+ * The IP packets sent by primary and secondary
+ * will be compared in here
+ * TODO support ip fragment, Out-Of-Order
+ * return:0  means packet same
+ *> 0 || < 0 means packet different
+ */
+static int colo_packet_compare(Packet *ppkt, Packet *spkt)
+{
+colo_dump_packet(ppkt);
+colo_dump_packet(spkt);
+
+if (ppkt->size == spkt->size) {
+return memcmp(ppkt->data, spkt->data, spkt->size);
+} else {
+return -1;
+}
+}
+
+static void colo_compare_connection(void *opaque, void *user_data)
+{
+Connection *conn = opaque;
+Packet *pkt = NULL;
+GList *result = NULL;
+int ret;
+
+qemu_mutex_lock(>list_lock);
+while (!g_queue_is_empty(>primary_list) &&
+   !g_queue_is_empty(>secondary_list)) {
+pkt = g_queue_pop_head(>primary_list);
+result = g_queue_find_custom(>secondary_list,
+  pkt, (GCompareFunc)colo_packet_compare);
+
+if (result) {
+ret = compare_chr_send(pkt->s->chr_out, pkt->data, pkt->size);
+if (ret < 0) {
+error_report("colo_send_primary_packet failed");
+}
+g_queue_remove(>secondary_list, result);
+} else {
+g_queue_push_head(>primary_list, pkt);
+colo_notify_checkpoint();
+break;
+}
+}
+qemu_mutex_unlock(>list_lock);
+}
+
+static void *colo_compare_thread(void *opaque)
+{
+CompareState *s = opaque;
+
+while (s->thread_status == COMPARE_THREAD_RUNNING) {
+qemu_event_wait(>event);
+qemu_event_reset(>event);
+qemu_mutex_lock(>conn_list_lock);
+g_queue_foreach(>conn_list, colo_compare_connection, NULL);
+qemu_mutex_unlock(>conn_list_lock);
+}
+
+return NULL;
+}
+
 static int compare_chr_send(CharDriverState *out, const uint8_t *buf, int size)
 {
 int ret = 0;
@@ -433,7 +532,9 @@ static void compare_pri_chr_in(void *opaque, const uint8_t 
*buf, int size)
 if (ret == 1) {
 if (packet_enqueue(s, PRIMARY_IN)) {
 error_report("primary: unsupported packet in");
-compare_chr_send(s->chr_out, buf, size);
+compare_chr_send(s->chr_out, s->pri_rs.buf, s->pri_rs.packet_len);
+} else {
+qemu_event_set(>event);
 }
 } else if (ret == -1) {
 qemu_chr_add_handlers(s->chr_pri_in, NULL, NULL, NULL, NULL);
@@ -449,6 +550,8 @@ static void compare_sec_chr_in(void *opaque, const uint8_t 
*buf, int size)
 if (ret == 1) {
 if (packet_enqueue(s, SECONDARY_IN)) {
 error_report("secondary: unsupported packet in");
+} else {
+qemu_event_set(>event);
 }
 } else if (ret == -1) {
 qemu_chr_add_handlers(s->chr_sec_in, NULL, NULL, NULL, NULL);
@@ -504,6 +607,8 @@ static void colo_compare_complete(UserCreatable *uc, Error 
**errp)
 

Re: [Qemu-devel] [Nbd] [PATCH 2/2] NBD proto: add GET_LBA_STATUS extension

2016-03-25 Thread Alex Bligh

On 25 Mar 2016, at 08:49, Wouter Verhelst  wrote:

> Yes. This has been discussed on the nbd-general list in the past. There
> is also the (significant) problem of the server having maybe already
> sent out the header before discovering there is an error, at which point
> it can *only* drop the connection.

Indeed.

I think where we got to last time this was discussed was that the
server could have the option of returning 'chunks' of reply, each
chunk either being a {length, data} tuple, or an error. The total
data transmitted would add up to the full length if there is no
error.

>> I could write up a negotiation of global flags for structured reply
>> lengths as an extension proposal, if you think it is worth it.
> 
> I think it is worth it...

+1 - for NBD_CMD_READ too

-- 
Alex Bligh







Re: [Qemu-devel] [Nbd] [PATCH 2/2] NBD proto: add GET_LBA_STATUS extension

2016-03-25 Thread Wouter Verhelst
On Thu, Mar 24, 2016 at 04:08:13PM -0600, Eric Blake wrote:
> On 03/23/2016 08:16 AM, Denis V. Lunev wrote:
> > From: Pavel Borzenkov 
> > 
> > With the availability of sparse storage formats, it is often needed to
> > query status of a particular LBA range and read only those blocks of
> > data that are actually present on the block device.
> > 
> > To provide such information, the patch adds GET_LBA_STATUS extension
> > with one new NBD_CMD_GET_LBA_STATUS command.
> > 
> 
> > +* `NBD_CMD_GET_LBA_STATUS` (7)
> > +
> > +An LBA range status query request. Length and offset define the range
> > +of interest. The server MUST reply with a reply header, followed
> > +immediately by the following data:
> > +
> > +  - 32 bits, length of parameter data that follow (unsigned)
> > +  - zero or more LBA status descriptors, each having the following
> > +structure:
> > +
> > +* 64 bits, offset (unsigned)
> > +* 32 bits, length (unsigned)
> > +* 16 bits, status (unsigned)
> > +
> > +unless an error condition has occurred.
> 
> To date, only the NBD_CMD_READ command caused the server to send data
> after the handle in its reply.  This would be the second command with a
> data field in the response, but it is returning a variable amount of
> data, not directly tied to the client's length - but at least you did
> make it structured so that the client knows how much to read.  However,
> your patch is incomplete; you'll need to edit the "Transmission" section
> of the document to mention the rules on the server sending data, as the
> existing text would now be wrong:
> 
> > The server replies with:
> > 
> > S: 32 bits, 0x67446698, magic (NBD_REPLY_MAGIC)
> > S: 32 bits, error
> > S: 64 bits, handle
> > S: (length bytes of data if the request is of type NBD_CMD_READ)
> 
> You may also want to add a rule that for all future extensions, any
> command that requires data in the server response (other than the server
> response to NBD_CMD_READ) must include a 32-bit length as the first
> field of its data payload, so that the server reply is always structured.

Right.

> Hmm, I still think it would be hard to write a wireshark dissector for
> server replies, since there is no indication whether a given reply will
> include data or not.

Well, a wireshark dissector already exists. However, it is very old; it
doesn't support the NBD_CMD_TRIM or NBD_CMD_FLUSH commands, it doesn't
support the NBD_CMD_FLAG_FUA option to NBD_CMD_WRITE, and it doesn't
deal with negotiation at all. It was written when newstyle negotiation
didn't exist yet, and scanning for INIT_PASSWD at the time was too hard,
according to the guy who wrote it (don't remember who that was).

> The _client_ knows (well, any well-written client
> that uses a different value for 'handle' for every command sent to the
> server), because it can read the returned 'handle' field to know what
> command it matches to and therefore what data to expect; but a
> third-party observer seeing _just_ the server messages has no idea which
> server responses should have payload.

It can if it knows enough about the protocol, but granted, that makes it
harder for us to extend the protocol without breaking the dissector.

> Scanning the stream and assuming that a new reply starts each time
> NBD_REPLY_MAGIC is encountered is a close approximation, but hits
> false positives if the data being returned for NBD_CMD_READ contains
> the same magic number as part of its contents.

Indeed.

> Obviously, back-compat says we can't change the response to
> NBD_CMD_READ, but that means that a wireshark dissector has to either
> maintain context, or hunt through returned data looking for potential
> magic numbers and possibly hitting false positives.
>
> That said, maybe we want to allow global flag negotiation prior to
> transmission to add a new flag on both server and client side - the
> server would advertise that it is capable of a new reply mode, and the
> client then has to reply that it wants to use the new reply mode; in

Global flag negotiation is already possible. There is a client flags
field, which is sent before option haggling, that could be used for
negotiation of such backwards-incompatible features.

> that mode, all server replies starting with magic 0x67446698
> (NBD_REPLY_MAGIC) will never have a data payload, and all commands that
> cause a reply with payload (both NBD_CMD_READ and the new
> NBD_CMD_GET_LBA_STATUS of this message, or whatever name we give it)
> will reply with a NEW magic number:
> 
> S: 32 bits, , magic (NBD_REPLY_MAGIC2)
> S: 32 bits, error
> S: 64 bits, handle
> S: 32 bits, length
> S: length bytes of data

I like this. However, before committing to it, I would like to see
Markus' feedback on that (explicit Cc added, even though he's on the
list, too).

We'd also need a way to communicate the ability to speak this protocol
from the kernel to userspace before telling the 

Re: [Qemu-devel] [PATCH 2/2] tap: vhost busy polling support

2016-03-25 Thread Jason Wang


On 03/21/2016 03:26 PM, Fam Zheng wrote:
> On Mon, 03/21 13:25, Jason Wang wrote:
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index 88f9b81..ea56a01 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -2532,7 +2532,8 @@
>>  '*vhostfd':'str',
>>  '*vhostfds':   'str',
>>  '*vhostforce': 'bool',
>> -'*queues': 'uint32'} }
>> +'*queues': 'uint32',
>> +'*vhost_poll_us': 'uint32'} }
> Need to update the comment too?
>
> Fam

I thought I did, but looks not :(

Will do it in V2.



Re: [Qemu-devel] [PATCH 2/2] tap: vhost busy polling support

2016-03-25 Thread Jason Wang


On 03/25/2016 04:34 AM, Eric Blake wrote:
> On 03/20/2016 11:25 PM, Jason Wang wrote:
>> This patch add the capability of basic vhost net busy polling which is
>> supported by recent kernel. User could configure the maximum number of
>> us that could be spent on busy polling through a new property of tap
>> "vhost_poll_us".
>>
>> Signed-off-by: Jason Wang 
>> ---
>> +++ b/qapi-schema.json
>> @@ -2532,7 +2532,8 @@
>>  '*vhostfd':'str',
>>  '*vhostfds':   'str',
>>  '*vhostforce': 'bool',
>> -'*queues': 'uint32'} }
>> +'*queues': 'uint32',
>> +'*vhost_poll_us': 'uint32'} }
> Missing documentation.

Right.

>
> New interfaces should prefer '-' over '_'; but this is an existing
> interface where we already have 'vnet_hdr', so intra-command consistency
> makes your naming okay.
>

Will change to use '-'.

Thanks



[Qemu-devel] [PULL 4/7] net/filter-mirror: implement filter-redirector

2016-03-25 Thread Jason Wang
From: Zhang Chen 

Filter-redirector is a netfilter plugin.
It gives qemu the ability to redirect net packet.
redirector can redirect filter's net packet to outdev.
and redirect indev's packet to filter.

  filter
+
redirector  |
   +--+
   || |
  indev +---+   +-->  outdev
   || |
   +--+
|
v
  filter

usage:

-netdev user,id=hn0
-chardev socket,id=s0,host=ip_primary,port=X,server,nowait
-chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
Signed-off-by: Li Zhijian 
Signed-off-by: Jason Wang 
---
 net/filter-mirror.c | 248 +++-
 qemu-options.hx |   9 ++
 vl.c|   3 +-
 3 files changed, 257 insertions(+), 3 deletions(-)

diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index 1b1ec16..f9e3b5c 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -26,12 +26,23 @@
 #define FILTER_MIRROR(obj) \
 OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR)
 
+#define FILTER_REDIRECTOR(obj) \
+OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_REDIRECTOR)
+
 #define TYPE_FILTER_MIRROR "filter-mirror"
+#define TYPE_FILTER_REDIRECTOR "filter-redirector"
+#define REDIRECTOR_MAX_LEN NET_BUFSIZE
 
 typedef struct MirrorState {
 NetFilterState parent_obj;
+char *indev;
 char *outdev;
+CharDriverState *chr_in;
 CharDriverState *chr_out;
+int state; /* 0 = getting length, 1 = getting data */
+unsigned int index;
+unsigned int packet_len;
+uint8_t buf[REDIRECTOR_MAX_LEN];
 } MirrorState;
 
 static int filter_mirror_send(CharDriverState *chr_out,
@@ -68,6 +79,96 @@ err:
 return ret < 0 ? ret : -EIO;
 }
 
+static void
+redirector_to_filter(NetFilterState *nf, const uint8_t *buf, int len)
+{
+struct iovec iov = {
+.iov_base = (void *)buf,
+.iov_len = len,
+};
+
+if (nf->direction == NET_FILTER_DIRECTION_ALL ||
+nf->direction == NET_FILTER_DIRECTION_TX) {
+qemu_netfilter_pass_to_next(nf->netdev, 0, , 1, nf);
+}
+
+if (nf->direction == NET_FILTER_DIRECTION_ALL ||
+nf->direction == NET_FILTER_DIRECTION_RX) {
+qemu_netfilter_pass_to_next(nf->netdev->peer, 0, , 1, nf);
+ }
+}
+
+static int redirector_chr_can_read(void *opaque)
+{
+return REDIRECTOR_MAX_LEN;
+}
+
+static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
+{
+NetFilterState *nf = opaque;
+MirrorState *s = FILTER_REDIRECTOR(nf);
+unsigned int l;
+
+while (size > 0) {
+/* reassemble a packet from the network */
+switch (s->state) { /* 0 = getting length, 1 = getting data */
+case 0:
+l = 4 - s->index;
+if (l > size) {
+l = size;
+}
+memcpy(s->buf + s->index, buf, l);
+buf += l;
+size -= l;
+s->index += l;
+if (s->index == 4) {
+/* got length */
+s->packet_len = ntohl(*(uint32_t *)s->buf);
+s->index = 0;
+s->state = 1;
+}
+break;
+case 1:
+l = s->packet_len - s->index;
+if (l > size) {
+l = size;
+}
+if (s->index + l <= sizeof(s->buf)) {
+memcpy(s->buf + s->index, buf, l);
+} else {
+error_report("serious error: oversized packet received.");
+s->index = s->state = 0;
+qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL);
+return;
+}
+
+s->index += l;
+buf += l;
+size -= l;
+if (s->index >= s->packet_len) {
+s->index = 0;
+s->state = 0;
+redirector_to_filter(nf, s->buf, s->packet_len);
+}
+break;
+}
+}
+}
+
+static void redirector_chr_event(void *opaque, int event)
+{
+NetFilterState *nf = opaque;
+MirrorState *s = FILTER_REDIRECTOR(nf);
+
+switch (event) {
+case CHR_EVENT_CLOSED:
+qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL);
+break;
+default:
+break;
+}
+}
+
 static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
  NetClientState *sender,
  unsigned flags,
@@ -90,6 +191,27 @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
 return 0;
 }
 
+static ssize_t 

[Qemu-devel] [PULL 2/7] tests/test-filter-mirror:add filter-mirror unit test

2016-03-25 Thread Jason Wang
From: Zhang Chen 

In this unit test we will test the mirror function.

start qemu with:
  -netdev socket,id=qtest-bn0,fd=sockfd
  -device e1000,netdev=qtest-bn0,id=qtest-e0
  -chardev socket,id=mirror0,path=/tmp/filter-mirror-test.sock,server,nowait
  -object filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0

We inject packet to netdev socket id = qtest-bn0,
filter-mirror will copy and mirror the packet to mirror0.
we read packet from mirror0 and then compare to what we injected.

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
Signed-off-by: Jason Wang 
---
 tests/.gitignore   |  1 +
 tests/Makefile |  2 +
 tests/test-filter-mirror.c | 93 ++
 3 files changed, 96 insertions(+)
 create mode 100644 tests/test-filter-mirror.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 5f30cbe..7bb4c73 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -68,5 +68,6 @@ test-write-threshold
 test-x86-cpuid
 test-xbzrle
 test-netfilter
+test-filter-mirror
 *-test
 qapi-schema/*.test.*
diff --git a/tests/Makefile b/tests/Makefile
index d1ff182..52c7362 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -218,6 +218,7 @@ ifeq ($(CONFIG_VHOST_NET_TEST_i386),)
 check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += 
tests/vhost-user-test$(EXESUF)
 endif
 check-qtest-i386-y += tests/test-netfilter$(EXESUF)
+check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -576,6 +577,7 @@ tests/qemu-iotests/socket_scm_helper$(EXESUF): 
tests/qemu-iotests/socket_scm_hel
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
 tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
$(test-block-obj-y)
 tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
+tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
 tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o 
contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
 tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
 
diff --git a/tests/test-filter-mirror.c b/tests/test-filter-mirror.c
new file mode 100644
index 000..f60bf2a
--- /dev/null
+++ b/tests/test-filter-mirror.c
@@ -0,0 +1,93 @@
+/*
+ * QTest testcase for filter-mirror
+ *
+ * Copyright (c) 2016 FUJITSU LIMITED
+ * Author: Zhang Chen 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "libqtest.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
+
+static void test_mirror(void)
+{
+#ifndef _WIN32
+/* socketpair(PF_UNIX) which does not exist on windows */
+
+int send_sock[2], recv_sock;
+char *cmdline;
+uint32_t ret = 0, len = 0;
+char send_buf[] = "Hello! filter-mirror~";
+char sock_path[] = "filter-mirror.XX";
+char *recv_buf;
+uint32_t size = sizeof(send_buf);
+size = htonl(size);
+
+ret = socketpair(PF_UNIX, SOCK_STREAM, 0, send_sock);
+g_assert_cmpint(ret, !=, -1);
+
+ret = mkstemp(sock_path);
+g_assert_cmpint(ret, !=, -1);
+
+cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "
+ "-device e1000,netdev=qtest-bn0,id=qtest-e0 "
+ "-chardev socket,id=mirror0,path=%s,server,nowait "
+ "-object 
filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0 "
+ , send_sock[1], sock_path);
+qtest_start(cmdline);
+g_free(cmdline);
+
+recv_sock = unix_connect(sock_path, NULL);
+g_assert_cmpint(recv_sock, !=, -1);
+
+struct iovec iov[] = {
+{
+.iov_base = ,
+.iov_len = sizeof(size),
+}, {
+.iov_base = send_buf,
+.iov_len = sizeof(send_buf),
+},
+};
+
+/* send a qmp command to guarantee that 'connected' is setting to true. */
+qmp("{ 'execute' : 'query-status'}");
+ret = iov_send(send_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf));
+g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
+close(send_sock[0]);
+
+ret = qemu_recv(recv_sock, , sizeof(len), 0);
+g_assert_cmpint(ret, ==, sizeof(len));
+len = ntohl(len);
+
+g_assert_cmpint(len, ==, sizeof(send_buf));
+recv_buf = g_malloc(len);
+ret = qemu_recv(recv_sock, recv_buf, len, 0);
+g_assert_cmpstr(recv_buf, ==, send_buf);
+
+g_free(recv_buf);
+close(recv_sock);
+unlink(sock_path);
+
+#endif
+}
+
+int main(int argc, char **argv)
+{
+int ret;
+
+g_test_init(, , NULL);
+
+  

[Qemu-devel] [PULL 6/7] e1000: Fixing interrupts pace.

2016-03-25 Thread Jason Wang
From: Sameeh Jubran 

This patch introduces an upper bound for number of interrupts
per second. Without this bound an interrupt storm can occur as
it has been observed on Windows 10 when disabling the device.

According to the SPEC - Intel PCI/PCI-X Family of Gigabit
Ethernet Controllers Software Developer's Manual, section
13.4.18 - the Ethernet controller guarantees a maximum
observable interrupt rate of 7813 interrupts/sec. If there is
no upper bound this could lead to an interrupt storm by e1000
(when mit_delay < 500) causing interrupts to fire at a very high
pace.
Thus if mit_delay < 500 then the delay should be set to the
minimum delay possible which is 500. This can be calculated
easily as follows:

Interval = 10^9 / (7813 * 256) = 500.

Signed-off-by: Sameeh Jubran 
Signed-off-by: Jason Wang 
---
 hw/net/e1000.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 0387fa0..09b9ab5 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -357,6 +357,14 @@ set_interrupt_cause(E1000State *s, int index, uint32_t val)
 }
 mit_update_delay(_delay, s->mac_reg[ITR]);
 
+/*
+ * According to e1000 SPEC, the Ethernet controller guarantees
+ * a maximum observable interrupt rate of 7813 interrupts/sec.
+ * Thus if mit_delay < 500 then the delay should be set to the
+ * minimum delay possible which is 500.
+ */
+mit_delay = (mit_delay < 500) ? 500 : mit_delay;
+
 if (mit_delay) {
 s->mit_timer_on = 1;
 timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-- 
2.5.0




[Qemu-devel] [PULL 0/7] Net patches

2016-03-25 Thread Jason Wang
The following changes since commit b68a80139e37e806f004237e55311ebc42151434:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20160324' into 
staging (2016-03-24 16:24:02 +)

are available in the git repository at:

  https://github.com/jasowang/qemu.git tags/net-pull-request

for you to fetch changes up to e680f08328f6a05a43963c3e9db1b0cdc701ed9f:

  Revert "e1000: fix hang of win2k12 shutdown with flood ping" (2016-03-25 
10:39:43 +0800)



- mirror/redirector which could mirror or redirct the traffic between
  netdev and chardev
- fix e1000 interrupt strom and remove previous hack


Sameeh Jubran (2):
  e1000: Fixing interrupts pace.
  Revert "e1000: fix hang of win2k12 shutdown with flood ping"

Zhang Chen (5):
  net/filter-mirror:Add filter-mirror
  tests/test-filter-mirror:add filter-mirror unit test
  net/filter-mirror: Change filter_mirror_send interface
  net/filter-mirror: implement filter-redirector
  tests/test-filter-redirector: Add unit test for filter-redirector

 hw/net/e1000.c |  13 +-
 net/Makefile.objs  |   1 +
 net/filter-mirror.c| 426 +
 qemu-options.hx|  14 ++
 tests/.gitignore   |   2 +
 tests/Makefile |   4 +
 tests/test-filter-mirror.c |  93 +
 tests/test-filter-redirector.c | 221 +
 vl.c   |   4 +-
 9 files changed, 772 insertions(+), 6 deletions(-)
 create mode 100644 net/filter-mirror.c
 create mode 100644 tests/test-filter-mirror.c
 create mode 100644 tests/test-filter-redirector.c



[Qemu-devel] [PULL 3/7] net/filter-mirror: Change filter_mirror_send interface

2016-03-25 Thread Jason Wang
From: Zhang Chen 

Change filter_mirror_send interface to make it easier
to used by other filter

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
Signed-off-by: Li Zhijian 
Signed-off-by: Jason Wang 
---
 net/filter-mirror.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index 2e2ed27..1b1ec16 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -34,11 +34,10 @@ typedef struct MirrorState {
 CharDriverState *chr_out;
 } MirrorState;
 
-static int filter_mirror_send(NetFilterState *nf,
+static int filter_mirror_send(CharDriverState *chr_out,
   const struct iovec *iov,
   int iovcnt)
 {
-MirrorState *s = FILTER_MIRROR(nf);
 int ret = 0;
 ssize_t size = 0;
 uint32_t len =  0;
@@ -50,14 +49,14 @@ static int filter_mirror_send(NetFilterState *nf,
 }
 
 len = htonl(size);
-ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
+ret = qemu_chr_fe_write_all(chr_out, (uint8_t *), sizeof(len));
 if (ret != sizeof(len)) {
 goto err;
 }
 
 buf = g_malloc(size);
 iov_to_buf(iov, iovcnt, 0, buf, size);
-ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size);
+ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)buf, size);
 g_free(buf);
 if (ret != size) {
 goto err;
@@ -76,9 +75,10 @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
  int iovcnt,
  NetPacketSent *sent_cb)
 {
+MirrorState *s = FILTER_MIRROR(nf);
 int ret;
 
-ret = filter_mirror_send(nf, iov, iovcnt);
+ret = filter_mirror_send(s->chr_out, iov, iovcnt);
 if (ret) {
 error_report("filter_mirror_send failed(%s)", strerror(-ret));
 }
-- 
2.5.0




[Qemu-devel] [PULL 5/7] tests/test-filter-redirector: Add unit test for filter-redirector

2016-03-25 Thread Jason Wang
From: Zhang Chen 

In this unit test,we will test the filter redirector function.

Case 1, tx traffic flow:

qemu side  | test side
   |
+-+|  +---+
| backend <---+ sock0 |
+++|  +---+
 | |
+v+  +---+ |
|  rd0+->+chardev| |
+-+  +---+---+ |
 | |
+-+  | |
|  rd1<--+ |
+++|
 | |
+v+|  +---+
|  rd2+--->sock1  |
+-+|  +---+
   +

a. we(sock0) inject packet to qemu socket backend
b. backend pass packet to filter redirector0(rd0)
c. rd0 redirect packet to out_dev(chardev) which is connected with
filter redirector1's(rd1) in_dev
d. rd1 read this packet from in_dev, and pass to next filter redirector2(rd2)
e. rd2 redirect packet to rd2's out_dev which is connected with an opened 
socketed(sock1)
f. we read packet from sock1 and compare to what we inject

Start qemu with:

"-netdev socket,id=qtest-bn0,fd=%d "
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait "
"-chardev socket,id=redirector1,path=%s,server,nowait "
"-chardev socket,id=redirector2,path=%s,nowait "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=tx,outdev=redirector0 "
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
"queue=tx,indev=redirector2 "
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
"queue=tx,outdev=redirector1 "

--
Case 2, rx traffic flow
qemu side  | test side
   |
+-+|  +---+
| backend +---> sock1 |
+^+|  +---+
 | |
+++  +---+ |
|  rd0+<-+chardev| |
+-+  +---+---+ |
 ^ |
+-+  | |
|  rd1+--+ |
+^+|
 | |
+++|  +---+
|  rd2<---+sock0  |
+-+|  +---+

a. we(sock0) insert packet to filter redirector2(rd2)
b. rd2 pass packet to filter redirector1(rd1)
c. rd1 redirect packet to out_dev(chardev) which is connected with
   filter redirector0's(rd0) in_dev
d. rd0 read this packet from in_dev, and pass ti to qemu backend which is
   connected with an opened socketed(sock1)
e. we read packet from sock1 and compare to what we inject

Start qemu with:

"-netdev socket,id=qtest-bn0,fd=%d "
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait "
"-chardev socket,id=redirector1,path=%s,server,nowait "
"-chardev socket,id=redirector2,path=%s,nowait "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=rx,outdev=redirector0 "
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
"queue=rx,indev=redirector2 "
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
"queue=rx,outdev=redirector1 "

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
Signed-off-by: Li Zhijian 
Signed-off-by: Jason Wang 
---
 tests/.gitignore   |   1 +
 tests/Makefile |   2 +
 tests/test-filter-redirector.c | 221 +
 3 files changed, 224 insertions(+)
 create mode 100644 tests/test-filter-redirector.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 7bb4c73..b7bf13e 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -69,5 +69,6 @@ test-x86-cpuid
 test-xbzrle
 test-netfilter
 test-filter-mirror
+test-filter-redirector
 *-test
 qapi-schema/*.test.*
diff --git a/tests/Makefile b/tests/Makefile
index 52c7362..4b7b62c 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -219,6 +219,7 @@ check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += 
tests/vhost-user-test$(EXE
 endif
 check-qtest-i386-y += tests/test-netfilter$(EXESUF)
 check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
+check-qtest-i386-y += tests/test-filter-redirector$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
 gcov-files-x86_64-y = $(subst 
i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -578,6 +579,7 @@ tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o 
$(test-util-obj-y)
 tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o 
$(test-block-obj-y)
 tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
 tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
+tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o 
$(qtest-obj-y)
 tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o 
contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
 tests/vhost-user-bridge$(EXESUF): 

[Qemu-devel] [PULL 7/7] Revert "e1000: fix hang of win2k12 shutdown with flood ping"

2016-03-25 Thread Jason Wang
From: Sameeh Jubran 

This reverts commit 9596ef7c7b8528bedb240792ea1fb598543ad3c4.

This workaround in order to fix endless interrupts is no
longer needed because it was superseded by the previous patch
(e1000: Fixing interrupt pace).

Signed-off-by: Sameeh Jubran 
Signed-off-by: Jason Wang 
---
 hw/net/e1000.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 09b9ab5..8e79b55 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -456,11 +456,6 @@ static void e1000_reset(void *opaque)
 e1000_link_down(d);
 }
 
-/* Throttle interrupts to prevent guest (e.g Win 2012) from
- * reinjecting interrupts endlessly. TODO: fix non ITR case.
- */
-d->mac_reg[ITR] = 250;
-
 /* Some guests expect pre-initialized RAH/RAL (AddrValid flag + MACaddr) */
 d->mac_reg[RA] = 0;
 d->mac_reg[RA + 1] = E1000_RAH_AV;
-- 
2.5.0




[Qemu-devel] [PULL 1/7] net/filter-mirror:Add filter-mirror

2016-03-25 Thread Jason Wang
From: Zhang Chen 

Filter-mirror is a netfilter plugin.
It gives qemu the ability to mirror
packets to a chardev.

usage:

-netdev tap,id=hn0
-chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait
-filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0

Signed-off-by: Zhang Chen 
Signed-off-by: Wen Congyang 
Reviewed-by: Yang Hongyang 
Reviewed-by: zhanghailiang 
Signed-off-by: Jason Wang 
---
 net/Makefile.objs   |   1 +
 net/filter-mirror.c | 182 
 qemu-options.hx |   5 ++
 vl.c|   3 +-
 4 files changed, 190 insertions(+), 1 deletion(-)
 create mode 100644 net/filter-mirror.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index 5fa2f97..b7c22fd 100644
--- a/net/Makefile.objs
+++ b/net/Makefile.objs
@@ -15,3 +15,4 @@ common-obj-$(CONFIG_VDE) += vde.o
 common-obj-$(CONFIG_NETMAP) += netmap.o
 common-obj-y += filter.o
 common-obj-y += filter-buffer.o
+common-obj-y += filter-mirror.o
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
new file mode 100644
index 000..2e2ed27
--- /dev/null
+++ b/net/filter-mirror.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ * Copyright (c) 2016 FUJITSU LIMITED
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * Author: Zhang Chen 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "net/filter.h"
+#include "net/net.h"
+#include "qemu-common.h"
+#include "qapi/qmp/qerror.h"
+#include "qapi-visit.h"
+#include "qom/object.h"
+#include "qemu/main-loop.h"
+#include "qemu/error-report.h"
+#include "trace.h"
+#include "sysemu/char.h"
+#include "qemu/iov.h"
+#include "qemu/sockets.h"
+
+#define FILTER_MIRROR(obj) \
+OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR)
+
+#define TYPE_FILTER_MIRROR "filter-mirror"
+
+typedef struct MirrorState {
+NetFilterState parent_obj;
+char *outdev;
+CharDriverState *chr_out;
+} MirrorState;
+
+static int filter_mirror_send(NetFilterState *nf,
+  const struct iovec *iov,
+  int iovcnt)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+int ret = 0;
+ssize_t size = 0;
+uint32_t len =  0;
+char *buf;
+
+size = iov_size(iov, iovcnt);
+if (!size) {
+return 0;
+}
+
+len = htonl(size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
+if (ret != sizeof(len)) {
+goto err;
+}
+
+buf = g_malloc(size);
+iov_to_buf(iov, iovcnt, 0, buf, size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size);
+g_free(buf);
+if (ret != size) {
+goto err;
+}
+
+return 0;
+
+err:
+return ret < 0 ? ret : -EIO;
+}
+
+static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt,
+ NetPacketSent *sent_cb)
+{
+int ret;
+
+ret = filter_mirror_send(nf, iov, iovcnt);
+if (ret) {
+error_report("filter_mirror_send failed(%s)", strerror(-ret));
+}
+
+/*
+ * we don't hope this error interrupt the normal
+ * path of net packet, so we always return zero.
+ */
+return 0;
+}
+
+static void filter_mirror_cleanup(NetFilterState *nf)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+
+if (s->chr_out) {
+qemu_chr_fe_release(s->chr_out);
+}
+}
+
+static void filter_mirror_setup(NetFilterState *nf, Error **errp)
+{
+MirrorState *s = FILTER_MIRROR(nf);
+
+if (!s->outdev) {
+error_setg(errp, "filter filter mirror needs 'outdev' "
+"property set");
+return;
+}
+
+s->chr_out = qemu_chr_find(s->outdev);
+if (s->chr_out == NULL) {
+error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+  "Device '%s' not found", s->outdev);
+return;
+}
+
+if (qemu_chr_fe_claim(s->chr_out) != 0) {
+error_setg(errp, QERR_DEVICE_IN_USE, s->outdev);
+return;
+}
+}
+
+static void filter_mirror_class_init(ObjectClass *oc, void *data)
+{
+NetFilterClass *nfc = NETFILTER_CLASS(oc);
+
+nfc->setup = filter_mirror_setup;
+nfc->cleanup = filter_mirror_cleanup;
+nfc->receive_iov = filter_mirror_receive_iov;
+}
+
+static char *filter_mirror_get_outdev(Object *obj, Error **errp)
+{
+MirrorState *s = FILTER_MIRROR(obj);
+
+return g_strdup(s->outdev);
+}
+
+static void
+filter_mirror_set_outdev(Object *obj, const char *value, Error **errp)

Re: [Qemu-devel] [RFC 6/7] virtio: handle virtqueue_num_heads() errors

2016-03-25 Thread Fam Zheng
On Thu, 03/24 17:56, Stefan Hajnoczi wrote:
> If the index avail ring index is bogus virtqueue_num_heads() must return

s/index avail/avail/ ?

> -EINVAL.
> 
> The only caller is virtqueue_get_avail_bytes().  Return saying no bytes
> are available when virtqueue_num_heads() fails.
> 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  hw/virtio/virtio.c | 11 ---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index f845df2..525af8b 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -320,9 +320,9 @@ static int virtqueue_num_heads(VirtQueue *vq, unsigned 
> int idx)
>  
>  /* Check it isn't doing very strange things with descriptor numbers. */
>  if (num_heads > vq->vring.num) {
> -error_report("Guest moved used index from %u to %u",
> +virtio_error(vq->vdev, "Guest moved used index from %u to %u",
>   idx, vq->shadow_avail_idx);
> -exit(1);
> +return -EINVAL;
>  }
>  /* On success, callers read a descriptor at vq->last_avail_idx.
>   * Make sure descriptor read does not bypass avail index read. */
> @@ -390,7 +390,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned 
> int *in_bytes,
>  idx = vq->last_avail_idx;
>  
>  total_bufs = in_total = out_total = 0;
> -while (virtqueue_num_heads(vq, idx)) {
> +while ((rc = virtqueue_num_heads(vq, idx)) > 0) {
>  VirtIODevice *vdev = vq->vdev;
>  unsigned int max, num_bufs, indirect = 0;
>  VRingDesc desc;
> @@ -451,6 +451,11 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned 
> int *in_bytes,
>  else
>  total_bufs++;
>  }
> +
> +if (rc < 0) {
> +goto err;
> +}
> +
>  done:
>  if (in_bytes) {
>  *in_bytes = in_total;
> -- 
> 2.5.5
> 



Re: [Qemu-devel] [RFC 5/7] virtio: handle virtqueue_read_next_desc() errors

2016-03-25 Thread Fam Zheng
On Thu, 03/24 17:56, Stefan Hajnoczi wrote:
> Stop processing the vring if an avail ring index is invalid.
> 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  hw/virtio/virtio.c | 47 +--
>  1 file changed, 33 insertions(+), 14 deletions(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 4758fe3..f845df2 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -350,28 +350,33 @@ static unsigned int virtqueue_get_head(VirtQueue *vq, 
> unsigned int idx)
>  return head;
>  }
>  
> -static unsigned virtqueue_read_next_desc(VirtIODevice *vdev, VRingDesc *desc,
> - hwaddr desc_pa, unsigned int max)
> -{
> -unsigned int next;
> +enum {
> +VIRTQUEUE_READ_DESC_ERROR = -1,
> +VIRTQUEUE_READ_DESC_DONE = 0,   /* end of chain */
> +VIRTQUEUE_READ_DESC_MORE = 1,   /* more buffers in chain */
> +};
>  
> +static int virtqueue_read_next_desc(VirtIODevice *vdev, VRingDesc *desc,
> +hwaddr desc_pa, unsigned int max,
> +unsigned int *next)
> +{
>  /* If this descriptor says it doesn't chain, we're done. */
>  if (!(desc->flags & VRING_DESC_F_NEXT)) {
> -return max;
> +return VIRTQUEUE_READ_DESC_DONE;
>  }
>  
>  /* Check they're not leading us off end of descriptors. */
> -next = desc->next;
> +*next = desc->next;
>  /* Make sure compiler knows to grab that: we don't want it changing! */
>  smp_wmb();
>  
> -if (next >= max) {
> -error_report("Desc next is %u", next);
> -exit(1);
> +if (*next >= max) {
> +virtio_error(vdev, "Desc next is %u", *next);
> +return VIRTQUEUE_READ_DESC_ERROR;
>  }
>  
> -vring_desc_read(vdev, desc, desc_pa, next);
> -return next;
> +vring_desc_read(vdev, desc, desc_pa, *next);
> +return VIRTQUEUE_READ_DESC_MORE;
>  }
>  
>  void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
> @@ -380,6 +385,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned 
> int *in_bytes,
>  {
>  unsigned int idx;
>  unsigned int total_bufs, in_total, out_total;
> +int rc;
>  
>  idx = vq->last_avail_idx;
>  
> @@ -389,7 +395,7 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned 
> int *in_bytes,
>  unsigned int max, num_bufs, indirect = 0;
>  VRingDesc desc;
>  hwaddr desc_pa;
> -int i;
> +unsigned int i;

This change seems a candicate for a separate patch, otherwise looks good to me!


>  
>  max = vq->vring.num;
>  num_bufs = total_bufs;
> @@ -432,7 +438,13 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned 
> int *in_bytes,
>  if (in_total >= max_in_bytes && out_total >= max_out_bytes) {
>  goto done;
>  }
> -} while ((i = virtqueue_read_next_desc(vdev, , desc_pa, max)) 
> != max);
> +
> +rc = virtqueue_read_next_desc(vdev, , desc_pa, max, );
> +} while (rc == VIRTQUEUE_READ_DESC_MORE);
> +
> +if (rc == VIRTQUEUE_READ_DESC_ERROR) {
> +goto err;
> +}
>  
>  if (!indirect)
>  total_bufs = num_bufs;
> @@ -584,6 +596,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
>  hwaddr addr[VIRTQUEUE_MAX_SIZE];
>  struct iovec iov[VIRTQUEUE_MAX_SIZE];
>  VRingDesc desc;
> +int rc;
>  
>  if (unlikely(vdev->broken)) {
>  return NULL;
> @@ -646,7 +659,13 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
>  virtio_error(vdev, "Looped descriptor");
>  goto err_undo_map;
>  }
> -} while ((i = virtqueue_read_next_desc(vdev, , desc_pa, max)) != 
> max);
> +
> +rc = virtqueue_read_next_desc(vdev, , desc_pa, max, );
> +} while (rc == VIRTQUEUE_READ_DESC_MORE);
> +
> +if (rc == VIRTQUEUE_READ_DESC_ERROR) {
> +goto err_undo_map;
> +}
>  
>  /* Now copy what we have collected and mapped */
>  elem = virtqueue_alloc_element(sz, out_num, in_num);
> -- 
> 2.5.5
> 



Re: [Qemu-devel] [RFC for-2.7 1/1] block/qapi: Add query-block-node-tree

2016-03-25 Thread Wen Congyang
On 03/25/2016 03:07 AM, Max Reitz wrote:
> This command returns the tree of BlockDriverStates under a given root
> node.
> 
> Every tree node is described by its node name and the connection of a
> parent node to its children additionally contains the role the child
> assumes.
> 
> A node's name can then be used e.g. in conjunction with
> query-named-block-nodes to get more information about the node.

I found another problem:

{'execute': 'query-block-node-tree', 'arguments': {'root-node': 'disk1' } }
{"return": {"children": [{"role": "children.1", "node": {"children": [{"role": 
"file", "node": {}}], "node-name": "test1"}}, {"role": "children.0", "node": 
{"children": [{"role": "file", "node": {}}]}}]}}

s->children[0] is children.0, and s->children[1] is children.1.
But we output them in reverse order. The reason is:

BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
 BlockDriverState *child_bs,
 const char *child_name,
 const BdrvChildRole *child_role)
{
BdrvChild *child = bdrv_root_attach_child(child_bs, child_name, child_role);
QLIST_INSERT_HEAD(_bs->children, child, next);
return child;
}

We insert the new child to the head, not the tail...

Thanks
Wen Congyang

> 
> Signed-off-by: Max Reitz 
> ---
>  block/qapi.c | 43 +++
>  qapi/block-core.json | 46 ++
>  qmp-commands.hx  | 38 ++
>  3 files changed, 127 insertions(+)
> 
> diff --git a/block/qapi.c b/block/qapi.c
> index 6a4869a..a35d32b 100644
> --- a/block/qapi.c
> +++ b/block/qapi.c
> @@ -493,6 +493,49 @@ BlockInfoList *qmp_query_block(Error **errp)
>  return head;
>  }
>  
> +static BlockNodeTreeNode *qmp_query_block_node_tree_by_bs(BlockDriverState 
> *bs)
> +{
> +BlockNodeTreeNode *bntn;
> +BlockNodeTreeChildList **p_next;
> +BdrvChild *child;
> +
> +bntn = g_new0(BlockNodeTreeNode, 1);
> +
> +bntn->node_name = g_strdup(bdrv_get_node_name(bs));
> +bntn->has_node_name = bntn->node_name;
> +
> +p_next = >children;
> +QLIST_FOREACH(child, >children, next) {
> +BlockNodeTreeChild *bntc;
> +
> +bntc = g_new(BlockNodeTreeChild, 1);
> +*bntc = (BlockNodeTreeChild){
> +.role = g_strdup(child->name),
> +.node = qmp_query_block_node_tree_by_bs(child->bs),
> +};
> +
> +*p_next = g_new0(BlockNodeTreeChildList, 1);
> +(*p_next)->value = bntc;
> +p_next = &(*p_next)->next;
> +}
> +
> +*p_next = NULL;
> +return bntn;
> +}
> +
> +BlockNodeTreeNode *qmp_query_block_node_tree(const char *root_node,
> + Error **errp)
> +{
> +BlockDriverState *bs;
> +
> +bs = bdrv_lookup_bs(root_node, root_node, errp);
> +if (!bs) {
> +return NULL;
> +}
> +
> +return qmp_query_block_node_tree_by_bs(bs);
> +}
> +
>  static bool next_query_bds(BlockBackend **blk, BlockDriverState **bs,
> bool query_nodes)
>  {
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index b1cf77d..754ccd6 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -470,6 +470,52 @@
>  
>  
>  ##
> +# @BlockNodeTreeNode:
> +#
> +# Describes a node in the block node graph.
> +#
> +# @node-name: If present, the node's name.
> +#
> +# @children:  List of the node's children.
> +#
> +# Since: 2.7
> +##
> +{ 'struct': 'BlockNodeTreeNode',
> +  'data': { '*node-name': 'str',
> +'children': ['BlockNodeTreeChild'] } }
> +
> +##
> +# @BlockNodeTreeChild:
> +#
> +# Describes a child node in the block node graph.
> +#
> +# @role: Role the child assumes for its parent, e.g. "file" or "backing".
> +#
> +# @node: The child node's BlockNodeTreeNode structure.
> +#
> +# Since: 2.7
> +##
> +{ 'struct': 'BlockNodeTreeChild',
> +  'data': { 'role': 'str',
> +'node': 'BlockNodeTreeNode' } }
> +
> +##
> +# @query-block-node-tree:
> +#
> +# Queries the tree of nodes under a given node in the block graph.
> +#
> +# @root-node: Node name or device name of the tree's root node.
> +#
> +# Returns: The root node's BlockNodeTreeNode structure.
> +#
> +# Since: 2.7
> +##
> +{ 'command': 'query-block-node-tree',
> +  'data': { 'root-node': 'str' },
> +  'returns': 'BlockNodeTreeNode' }
> +
> +
> +##
>  # @BlockDeviceTimedStats:
>  #
>  # Statistics of a block device during a given interval of time.
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 9e05365..5c404aa 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -2637,6 +2637,44 @@ EQMP
>  },
>  
>  SQMP
> +query-block-node-tree
> +-
> +
> +Queries the tree of nodes under a given node in the block graph.
> +
> +Arguments:
> +
> +- "root-node": Node name or device name of the tree's root node (json-string)
> +
> +The block 

Re: [Qemu-devel] [RFC 2/7] virtio: stop virtqueue processing if device is broken

2016-03-25 Thread Fam Zheng
On Thu, 03/24 17:56, Stefan Hajnoczi wrote:
> QEMU prints an error message and exits when the device enters an invalid
> state.  Terminating the process is heavy-handed.  The guest may still be
> able to function even if there is a bug in a virtio guest driver.
> 
> Moreover, exiting is a bug in nested virtualization where a nested guest
> could DoS other nested guests by killing a pass-through virtio device.
> I don't think this configuration is possible today but it is likely in
> the future.
> 
> If the broken flag is set, do not process virtqueues or write back used
> descriptors.  The broken flag can be cleared again by resetting the
> device.
> 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  hw/virtio/virtio.c | 34 ++
>  include/hw/virtio/virtio.h |  3 +++
>  2 files changed, 37 insertions(+)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index de8a3b3..8fac47c 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -276,6 +276,10 @@ void virtqueue_fill(VirtQueue *vq, const 
> VirtQueueElement *elem,
>  
>  virtqueue_unmap_sg(vq, elem, len);
>  
> +if (unlikely(vq->vdev->broken)) {
> +return;
> +}
> +
>  idx = (idx + vq->used_idx) % vq->vring.num;
>  
>  uelem.id = elem->index;
> @@ -286,6 +290,12 @@ void virtqueue_fill(VirtQueue *vq, const 
> VirtQueueElement *elem,
>  void virtqueue_flush(VirtQueue *vq, unsigned int count)
>  {
>  uint16_t old, new;
> +
> +if (unlikely(vq->vdev->broken)) {
> +vq->inuse -= count;
> +return;
> +}
> +
>  /* Make sure buffer is written before we update index. */
>  smp_wmb();
>  trace_virtqueue_flush(vq, count);
> @@ -546,6 +556,9 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
>  struct iovec iov[VIRTQUEUE_MAX_SIZE];
>  VRingDesc desc;
>  
> +if (unlikely(vdev->broken)) {
> +return NULL;
> +}
>  if (virtio_queue_empty(vq)) {
>  return NULL;
>  }
> @@ -705,6 +718,10 @@ static void virtio_notify_vector(VirtIODevice *vdev, 
> uint16_t vector)
>  BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
>  VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
>  
> +if (unlikely(vdev->broken)) {
> +return;
> +}
> +
>  if (k->notify) {
>  k->notify(qbus->parent, vector);
>  }
> @@ -788,6 +805,7 @@ void virtio_reset(void *opaque)
>  k->reset(vdev);
>  }
>  
> +vdev->broken = false;
>  vdev->guest_features = 0;
>  vdev->queue_sel = 0;
>  vdev->status = 0;
> @@ -1091,6 +1109,10 @@ void virtio_queue_notify_vq(VirtQueue *vq)
>  if (vq->vring.desc && vq->handle_output) {
>  VirtIODevice *vdev = vq->vdev;
>  
> +if (unlikely(vdev->broken)) {
> +return;
> +}
> +
>  trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
>  vq->handle_output(vdev, vq);
>  }
> @@ -1661,6 +1683,7 @@ void virtio_init(VirtIODevice *vdev, const char *name,
>  vdev->config_vector = VIRTIO_NO_VECTOR;
>  vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_QUEUE_MAX);
>  vdev->vm_running = runstate_is_running();
> +vdev->broken = false;
>  for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
>  vdev->vq[i].vector = VIRTIO_NO_VECTOR;
>  vdev->vq[i].vdev = vdev;
> @@ -1829,6 +1852,17 @@ void virtio_device_set_child_bus_name(VirtIODevice 
> *vdev, char *bus_name)
>  vdev->bus_name = g_strdup(bus_name);
>  }
>  
> +void GCC_FMT_ATTR(2, 3) virtio_error(VirtIODevice *vdev, const char *fmt, 
> ...)
> +{
> +va_list ap;
> +
> +va_start(ap, fmt);
> +error_vreport(fmt, ap);
> +va_end(ap);
> +
> +vdev->broken = true;
> +}
> +

Since it's not used by the rest of the patch and it is independent, Probably
split this change to a separate patch?

>  static void virtio_device_realize(DeviceState *dev, Error **errp)
>  {
>  VirtIODevice *vdev = VIRTIO_DEVICE(dev);
> diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
> index 2b5b248..1565e53 100644
> --- a/include/hw/virtio/virtio.h
> +++ b/include/hw/virtio/virtio.h
> @@ -87,6 +87,7 @@ struct VirtIODevice
>  VirtQueue *vq;
>  uint16_t device_id;
>  bool vm_running;
> +bool broken; /* device in invalid state, needs reset */
>  VMChangeStateEntry *vmstate;
>  char *bus_name;
>  uint8_t device_endian;
> @@ -135,6 +136,8 @@ void virtio_init(VirtIODevice *vdev, const char *name,
>   uint16_t device_id, size_t config_size);
>  void virtio_cleanup(VirtIODevice *vdev);
>  
> +void virtio_error(VirtIODevice *vdev, const char *fmt, ...) GCC_FMT_ATTR(2, 
> 3);
> +
>  /* Set the child bus name. */
>  void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name);
>  
> -- 
> 2.5.5
> 



[Qemu-devel] [PATCH] pci_register_bar: cleanup

2016-03-25 Thread Cao jin
place relevant code tegother, make the code easier to read

Signed-off-by: Cao jin 
---
 hw/pci/pci.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index e67664d..f0f41dc 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -974,7 +974,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
   uint8_t type, MemoryRegion *memory)
 {
 PCIIORegion *r;
-uint32_t addr;
+uint32_t addr; /* offset in pci config space */
 uint64_t wmask;
 pcibus_t size = memory_region_size(memory);
 
@@ -990,15 +990,20 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
 r->addr = PCI_BAR_UNMAPPED;
 r->size = size;
 r->type = type;
-r->memory = NULL;
+r->memory = memory;
+r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
+? pci_dev->bus->address_space_io
+: pci_dev->bus->address_space_mem;
 
 wmask = ~(size - 1);
-addr = pci_bar(pci_dev, region_num);
 if (region_num == PCI_ROM_SLOT) {
 /* ROM enable bit is writable */
 wmask |= PCI_ROM_ADDRESS_ENABLE;
 }
+
+addr = pci_bar(pci_dev, region_num);
 pci_set_long(pci_dev->config + addr, type);
+
 if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) &&
 r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
 pci_set_quad(pci_dev->wmask + addr, wmask);
@@ -1007,11 +1012,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
 pci_set_long(pci_dev->wmask + addr, wmask & 0x);
 pci_set_long(pci_dev->cmask + addr, 0x);
 }
-pci_dev->io_regions[region_num].memory = memory;
-pci_dev->io_regions[region_num].address_space
-= type & PCI_BASE_ADDRESS_SPACE_IO
-? pci_dev->bus->address_space_io
-: pci_dev->bus->address_space_mem;
 }
 
 static void pci_update_vga(PCIDevice *pci_dev)
-- 
2.1.0






Re: [Qemu-devel] [RFC 1/7] virtio: fix stray tab character

2016-03-25 Thread Fam Zheng
On Thu, 03/24 17:56, Stefan Hajnoczi wrote:
> The patches fixes a single occurrence of a tab character that resulted
> in mis-aligned indentation.
> 
> Signed-off-by: Stefan Hajnoczi 
> ---
>  hw/virtio/virtio.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 08275a9..de8a3b3 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -1531,7 +1531,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int 
> version_id)
>   "inconsistent with Host index 0x%x",
>   i, vdev->vq[i].last_avail_idx);
>  return -1;
> - }
> +}
>  if (k->load_queue) {
>  ret = k->load_queue(qbus->parent, i, f);
>  if (ret)
> -- 
> 2.5.5
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH v2 4/4] iotests: Test qemu-img convert -S 0 behavior

2016-03-25 Thread Fam Zheng
On Thu, 03/24 23:34, Max Reitz wrote:
> Passing -S 0 to qemu-img convert should result in all source data being
> copied to the output, even if that source data is known to be 0. The
> output image should therefore have exactly the same size on disk as an
> image which we explicitly filled with data.
> 
> Signed-off-by: Max Reitz 
> ---
>  tests/qemu-iotests/150 | 105 
> +
>  tests/qemu-iotests/150.out |  14 ++
>  tests/qemu-iotests/group   |   1 +
>  3 files changed, 120 insertions(+)
>  create mode 100755 tests/qemu-iotests/150
>  create mode 100644 tests/qemu-iotests/150.out
> 
> diff --git a/tests/qemu-iotests/150 b/tests/qemu-iotests/150
> new file mode 100755
> index 000..97d2a35
> --- /dev/null
> +++ b/tests/qemu-iotests/150
> @@ -0,0 +1,105 @@
> +#!/bin/bash
> +#
> +# Test that qemu-img convert -S 0 fully allocates the target image
> +#
> +# Copyright (C) 2016 Red Hat, Inc.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program.  If not, see .
> +#
> +
> +# creator
> +owner=mre...@redhat.com
> +
> +seq="$(basename $0)"
> +echo "QA output created by $seq"
> +
> +here="$PWD"
> +tmp=/tmp/$$
> +status=1 # failure is the default!
> +
> +_cleanup()
> +{
> +_cleanup_test_img
> +}
> +trap "_cleanup; exit \$status" 0 1 2 3 15
> +
> +# get standard environment, filters and checks
> +. ./common.rc
> +. ./common.filter
> +
> +_supported_fmt generic
> +_supported_proto file
> +_supported_os Linux
> +
> +
> +on_disk_size()
> +{
> +du "$@" | sed -e 's/\t\+.*//'
> +}
> +
> +
> +img_size=1048576
> +
> +
> +echo
> +echo '=== Comparing empty image against sparse conversion ==='
> +echo
> +
> +_make_test_img $img_size
> +
> +empty_size=$(on_disk_size "$TEST_IMG")
> +
> +
> +$QEMU_IMG_PROG convert -O "$IMGFMT" -S 512 \
> +"json:{ 'driver': 'null-co', 'size': $img_size, 'read-zeroes': true }" \
> +"$TEST_IMG"
> +
> +sparse_convert_size=$(on_disk_size "$TEST_IMG")
> +
> +
> +if [ "$empty_size" -eq "$sparse_convert_size" ]; then
> +echo 'Equal image size'
> +else
> +echo 'Different image size'
> +fi
> +
> +
> +echo
> +echo '=== Comparing full image against non-sparse conversion ==='
> +echo
> +
> +_make_test_img $img_size
> +$QEMU_IO -c "write 0 $img_size" "$TEST_IMG" | _filter_qemu_io
> +
> +full_size=$(on_disk_size "$TEST_IMG")
> +
> +
> +$QEMU_IMG convert -O "$IMGFMT" -S 0 \
> +"json:{ 'driver': 'null-co', 'size': $img_size, 'read-zeroes': true }" \
> +"$TEST_IMG"
> +
> +non_sparse_convert_size=$(on_disk_size "$TEST_IMG")
> +
> +
> +if [ "$full_size" -eq "$non_sparse_convert_size" ]; then
> +echo 'Equal image size'
> +else
> +echo 'Different image size'
> +fi
> +
> +
> +# success, all done
> +echo "*** done"
> +rm -f $seq.full
> +status=0
> diff --git a/tests/qemu-iotests/150.out b/tests/qemu-iotests/150.out
> new file mode 100644
> index 000..2d29da1
> --- /dev/null
> +++ b/tests/qemu-iotests/150.out
> @@ -0,0 +1,14 @@
> +QA output created by 150
> +
> +=== Comparing empty image against sparse conversion ===
> +
> +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
> +Equal image size
> +
> +=== Comparing full image against non-sparse conversion ===
> +
> +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
> +wrote 1048576/1048576 bytes at offset 0
> +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> +Equal image size
> +*** done
> diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
> index faf0f21..87e5ea4 100644
> --- a/tests/qemu-iotests/group
> +++ b/tests/qemu-iotests/group
> @@ -150,3 +150,4 @@
>  145 auto quick
>  146 auto quick
>  148 rw auto quick
> +150 rw auto quick
> -- 
> 2.7.4
> 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH v2 1/4] qemu-img: Fix preallocation with -S 0 for convert

2016-03-25 Thread Fam Zheng
On Thu, 03/24 23:33, Max Reitz wrote:
> When passing -S 0 to qemu-img convert, the target image is supposed to
> be fully allocated. Right now, this is not the case if the source image
> contains areas which bdrv_get_block_status() reports as being zero.
> 
> This patch changes a zeroed area's status from BLK_ZERO to BLK_DATA
> before invoking convert_write() if -S 0 has been specified. In addition,
> the check whether convert_read() actually needs to do anything
> (basically only if the current area is a BLK_DATA area) is pulled out of
> that function to the caller.
> 
> If -S 0 has been specified, zeroed areas need to be written as data to
> the output, thus they then have to be accounted when calculating the
> progress made.
> 
> This patch changes the reference output for iotest 122; contrary to what
> it assumed, -S 0 really should allocate everything in the output, not
> just areas that are filled with zeros (as opposed to being zeroed).
> 
> Signed-off-by: Max Reitz 
> ---
>  qemu-img.c | 26 +++---
>  tests/qemu-iotests/122.out |  6 ++
>  2 files changed, 17 insertions(+), 15 deletions(-)
> 
> diff --git a/qemu-img.c b/qemu-img.c
> index 29eae2a..b2e07bb 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -1507,10 +1507,6 @@ static int convert_read(ImgConvertState *s, int64_t 
> sector_num, int nb_sectors,
>  int n;
>  int ret;
>  
> -if (s->status == BLK_ZERO || s->status == BLK_BACKING_FILE) {
> -return 0;
> -}
> -
>  assert(nb_sectors <= s->buf_sectors);
>  while (nb_sectors > 0) {
>  BlockBackend *blk;
> @@ -1648,7 +1644,8 @@ static int convert_do_copy(ImgConvertState *s)
>  ret = n;
>  goto fail;
>  }
> -if (s->status == BLK_DATA) {
> +if (s->status == BLK_DATA || (!s->min_sparse && s->status == 
> BLK_ZERO))
> +{
>  s->allocated_sectors += n;
>  }
>  sector_num += n;
> @@ -1668,17 +1665,24 @@ static int convert_do_copy(ImgConvertState *s)
>  ret = n;
>  goto fail;
>  }
> -if (s->status == BLK_DATA) {
> +if (s->status == BLK_DATA || (!s->min_sparse && s->status == 
> BLK_ZERO))
> +{
>  allocated_done += n;
>  qemu_progress_print(100.0 * allocated_done / 
> s->allocated_sectors,
>  0);
>  }
>  
> -ret = convert_read(s, sector_num, n, buf);
> -if (ret < 0) {
> -error_report("error while reading sector %" PRId64
> - ": %s", sector_num, strerror(-ret));
> -goto fail;
> +if (s->status == BLK_DATA) {
> +ret = convert_read(s, sector_num, n, buf);
> +if (ret < 0) {
> +error_report("error while reading sector %" PRId64
> + ": %s", sector_num, strerror(-ret));
> +goto fail;
> +}
> +} else if (!s->min_sparse && s->status == BLK_ZERO) {
> +n = MIN(n, s->buf_sectors);
> +memset(buf, 0, n * BDRV_SECTOR_SIZE);
> +s->status = BLK_DATA;
>  }
>  
>  ret = convert_write(s, sector_num, n, buf);
> diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
> index 0068e96..98814de 100644
> --- a/tests/qemu-iotests/122.out
> +++ b/tests/qemu-iotests/122.out
> @@ -112,16 +112,14 @@ read 3145728/3145728 bytes at offset 0
>  3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  read 63963136/63963136 bytes at offset 3145728
>  61 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> -[{ "start": 0, "length": 6291456, "depth": 0, "zero": false, "data": true, 
> "offset": 327680},
> -{ "start": 6291456, "length": 60817408, "depth": 0, "zero": true, "data": 
> false}]
> +[{ "start": 0, "length": 67108864, "depth": 0, "zero": false, "data": true, 
> "offset": 327680}]
>  
>  convert -c -S 0:
>  read 3145728/3145728 bytes at offset 0
>  3 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  read 63963136/63963136 bytes at offset 3145728
>  61 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> -[{ "start": 0, "length": 6291456, "depth": 0, "zero": false, "data": true},
> -{ "start": 6291456, "length": 60817408, "depth": 0, "zero": true, "data": 
> false}]
> +[{ "start": 0, "length": 67108864, "depth": 0, "zero": false, "data": true}]
>  Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
>  wrote 33554432/33554432 bytes at offset 0
>  32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
> -- 
> 2.7.4
> 

Looks sane to me,

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH V4] hw/pxb: add chassis_nr property

2016-03-25 Thread Cao jin



On 03/24/2016 11:34 PM, Marcel Apfelbaum wrote:


Hi,

You used hot-plug correctly, it doesn't work yet since I am still
working on this feature.
The bridge gives us the basics environment for hot-plug, what is missing
is ACPI "bsel" mechanism.

Thanks,
Marcel


I see, Thanks for your information:)
--
Yours Sincerely,

Cao jin





Re: [Qemu-devel] [PATCH 2/2] memory: hide mr->ram_addr from qemu_get_ram_ptr users

2016-03-25 Thread Fam Zheng
On Thu, 03/24 12:03, Paolo Bonzini wrote:
> Let users of qemu_get_ram_ptr and qemu_ram_ptr_length pass in an
> address that is relative to the MemoryRegion.  This basically means
> what address_space_translate returns.
> 
> invalidate_and_set_dirty has to add back mr->ram_addr, but reads do
> not need it at all.
> 
> Signed-off-by: Paolo Bonzini 
> ---
>  exec.c   | 40 +++-
>  include/exec/memory.h|  1 -
>  memory.c |  4 ++--
>  scripts/dump-guest-memory.py | 19 +++
>  4 files changed, 20 insertions(+), 44 deletions(-)
> 
> diff --git a/exec.c b/exec.c
> index 001b669..ca9e3b6 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -1876,6 +1876,7 @@ void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t 
> addr)

Shall we rename the parameter to "offset" then?  I don't know, but that seems
easier to read for me.

>  
>  if (block == NULL) {
>  block = qemu_get_ram_block(addr);
> +addr -= block->offset;
>  }
>  
>  if (xen_enabled() && block->host == NULL) {
> @@ -1889,7 +1890,7 @@ void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t 
> addr)
>  
>  block->host = xen_map_cache(block->offset, block->max_length, 1);
>  }
> -return ramblock_ptr(block, addr - block->offset);
> +return ramblock_ptr(block, addr);
>  }
>  
>  /* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
> @@ -1901,16 +1902,15 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, 
> ram_addr_t addr,
>   hwaddr *size)
>  {
>  RAMBlock *block = ram_block;
> -ram_addr_t offset_inside_block;
>  if (*size == 0) {
>  return NULL;
>  }
>  
>  if (block == NULL) {
>  block = qemu_get_ram_block(addr);
> +addr -= block->offset;
>  }
> -offset_inside_block = addr - block->offset;
> -*size = MIN(*size, block->max_length - offset_inside_block);
> +*size = MIN(*size, block->max_length - addr);
>  
>  if (xen_enabled() && block->host == NULL) {
>  /* We need to check if the requested address is in the RAM
> @@ -1924,7 +1924,7 @@ static void *qemu_ram_ptr_length(RAMBlock *ram_block, 
> ram_addr_t addr,
>  block->host = xen_map_cache(block->offset, block->max_length, 1);
>  }
>  
> -return ramblock_ptr(block, offset_inside_block);
> +return ramblock_ptr(block, addr);
>  }
>  
>  /*
> @@ -2504,6 +2504,8 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, 
> hwaddr addr,
>   hwaddr length)
>  {
>  uint8_t dirty_log_mask = memory_region_get_dirty_log_mask(mr);
> +addr += memory_region_get_ram_addr(mr);
> +

If called by address_space_unmap, is this addition still correct?

void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
 int is_write, hwaddr access_len)
{
if (buffer != bounce.buffer) {
MemoryRegion *mr;
ram_addr_t addr1;

mr = qemu_ram_addr_from_host(buffer, );
assert(mr != NULL);
if (is_write) {
invalidate_and_set_dirty(mr, addr1, access_len);
  ^
  `-- IIUC this is not an offset into
  mr, is it?

>  /* No early return if dirty_log_mask is or becomes 0, because
>   * cpu_physical_memory_set_dirty_range will still call
>   * xen_modified_memory.
> @@ -2616,7 +2618,6 @@ static MemTxResult 
> address_space_write_continue(AddressSpace *as, hwaddr addr,
>  abort();
>  }
>  } else {
> -addr1 += memory_region_get_ram_addr(mr);
>  /* RAM case */
>  ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
>  memcpy(ptr, buf, l);
> @@ -2709,8 +2710,7 @@ MemTxResult address_space_read_continue(AddressSpace 
> *as, hwaddr addr,
>  }
>  } else {
>  /* RAM case */
> -ptr = qemu_get_ram_ptr(mr->ram_block,
> -   memory_region_get_ram_addr(mr) + addr1);
> +ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
>  memcpy(buf, ptr, l);
>  }
>  
> @@ -3382,13 +3374,13 @@ void address_space_stl_notdirty(AddressSpace *as, 
> hwaddr addr, uint32_t val,
>  
>  r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
>  } else {
> -addr1 += memory_region_get_ram_addr(mr);
>  ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
>  stl_p(ptr, val);
>  
>  dirty_log_mask = memory_region_get_dirty_log_mask(mr);
>  dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE);
> -cpu_physical_memory_set_dirty_range(addr1, 4, dirty_log_mask);
> +cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr) + 
> addr,

Is this line too long?

> +4, 

Re: [Qemu-devel] [PATCH 1/2] memory: remove unnecessary masking of MemoryRegion ram_addr

2016-03-25 Thread Fam Zheng
On Thu, 03/24 12:03, Paolo Bonzini wrote:
> mr->ram_block->offset is already aligned to both host and target size
> (see qemu_ram_alloc_internal).  Remove further masking as it is
> unnecessary.
> 
> Signed-off-by: Paolo Bonzini 

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH v4] blizzard: Remove support for DEPTH != 32

2016-03-25 Thread Pooja Dhannawat
On Fri, Mar 25, 2016 at 8:39 AM, Fam Zheng  wrote:

> On Thu, 03/24 23:48, Pooja Dhannawat wrote:
> > Removing support for DEPTH != 32 from blizzard template header
> > and file that includes it, as macro DEPTH == 32 only used.
> >
> > Signed-off-by: Pooja Dhannawat 
>
> Hi Pooja, a meta-comment: in the future, when post a subsequent revision,
> please include what is changed since previous revision, in the cover
> letter if
> there are multiple patches, or under a "---" line in the commit message if
> there is no cover letter. (Remember that the Signed-off-by line must still
> stay
> above the "---" line).
>
> The reason to use "---" line is for maintainers to avoid "git am" applying
> the
> revision changelog into git history (apparently it is meaningless out of
> patch
> review context).
>
> In this case, it would be like:
>
> 8<---
>
> Removing support for DEPTH != 32 from blizzard template header
> and file that includes it, as macro DEPTH == 32 only used.
>
> Signed-off-by: Pooja Dhannawat 
>
> ---
>
> v4: Changed foo to bar, and baz to qux. [$name_of_suggester]
>
> >8---
>

Thank you Fam. I will keep this in mind from onward.


Re: [Qemu-devel] [PATCH] qdev property: cleanup

2016-03-25 Thread Cao jin



On 03/24/2016 07:25 PM, Paolo Bonzini wrote:




A question about legacy property: I don`t see legacy property is really
used in the code, so, why still add legacy property to object?


It's used here:

static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
  int indent)


Thanks Paolo, I saw here, and then I thought the property is added and 
just be printed out, seems for no real benefit("really used"). Now I 
think I see where I was wrong. Thanks.


BTW, is this patch right?
--
Yours Sincerely,

Cao jin