Re: [Qemu-devel] [PATCH v10] Support vhd type VHD_DIFFERENCING
Thank you for this patch. I found a few places where you have 32-bit integer overflows that result in failure. They are marked inline below. On 03/04/2015 09:18 AM, Xiaodong Gong wrote: diff --git a/block/vpc.c b/block/vpc.c index 46803b1..d9a8d19 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -29,17 +29,29 @@ #if defined(CONFIG_UUID) #include #endif +#include /**/ #define HEADER_SIZE 512 +#define DYNAMIC_HEADER_SIZE 1024 +#define PARENT_LOCATOR_NUM 8 +#define TBBATMAP_HEAD_SIZE 28 + +#define MACX_PREFIX_LEN 7 /* file:// */ + +#define PLATFORM_MACX 0x4D616358 +#define PLATFORM_W2RU 0x57327275 +#define PLATFORM_W2KU 0x57326B75 + +#define VHD_VERSION(major, minor) (((major) << 16) | ((minor) & 0x)) //#define CACHE enum vhd_type { VHD_FIXED = 2, VHD_DYNAMIC = 3, -VHD_DIFFERENCING= 4, +VHD_DIFF= 4, }; // Seconds since Jan 1, 2000 0:00:00 (UTC) @@ -138,6 +150,15 @@ typedef struct BDRVVPCState { Error *migration_blocker; } BDRVVPCState; +typedef struct vhd_tdbatmap_header { +char magic[8]; /* always "tdbatmap" */ + +uint64_t batmap_offset; +uint32_t batmap_size; +uint32_t batmap_version; +uint32_t checksum; +} QEMU_PACKED VHDTdBatmapHeader; + static uint32_t vpc_checksum(uint8_t* buf, size_t size) { uint32_t res = 0; @@ -157,6 +178,224 @@ static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename) return 0; } +static int vpc_decode_maxc_loc(BlockDriverState *bs, uint32_t data_length) +{ +GIConv cd; +gchar *inbuf, *outbuf, *buf; +gsize inbyteleft, outbyteleft, outbyte; +int ret = 0; +gsize ret1; +gint ret2; + +if (!bs || !bs->backing_file || !data_length) { +return -1; +} + +cd = g_iconv_open("ASCII", "UTF8"); +if (cd == (GIConv) -1) { +return -1; +} + +inbuf = bs->backing_file; +outbuf = buf = (gchar *) g_malloc(data_length + 1); +if (!outbuf) { +ret = -1; +goto fail2; +} +inbyteleft = outbyteleft = data_length; + +ret1 = g_iconv(cd, &inbuf, &inbyteleft, &outbuf, &outbyteleft); +if (ret1 == (gsize) -1 || inbyteleft) { +ret = -1; +goto fail1; +} +outbyte = data_length - outbyteleft; +if (outbyte > sizeof(bs->backing_file) - 1) { +ret = -1; +goto fail1; +} +if (outbyte < MACX_PREFIX_LEN) { +ret = -1; +goto fail1; +} +buf[outbyte] = '\0'; + +pstrcpy(bs->backing_file, sizeof(bs->backing_file), buf + MACX_PREFIX_LEN); + +fail1: +g_free(buf); +buf = NULL; + +fail2: +ret2 = g_iconv_close(cd); +if (ret2 == (gint) -1) { +ret = -1; +} + +return ret; +} + +static int vpc_decode_w2u_loc(BlockDriverState *bs, uint32_t data_length) +{ +GIConv cd; +gchar *buf, *inbuf, *outbuf; +gsize inbyteleft, outbyteleft, outbyte; +gchar *ptr; +char len = 0; +int ret = 0; +gsize ret1; +gint ret2; + +if (!bs || !bs->backing_file || !data_length) { +return -1; +} + +cd = g_iconv_open("ASCII", "UTF-16LE"); +if (cd == (GIConv) -1) { +return -1; +} + +inbuf = bs->backing_file; +outbuf = buf = ptr = (char *) g_malloc(data_length + 1); +if (!buf) { +ret = -1; +goto fail2; +} +inbyteleft = outbyteleft = data_length; + +ret1 = g_iconv(cd, &inbuf, &inbyteleft, &outbuf, &outbyteleft); +if (ret1 == (gsize) -1 || inbyteleft) { +ret = -1; +goto fail1; +} +outbyte = data_length - outbyteleft; +if (outbyte > sizeof(bs->backing_file) - 1) { +ret = -1; +goto fail1; +} +buf[outbyte] = '\0'; + +while (ptr != outbuf) { +if (*ptr == '\\') { +*ptr = '/'; +} +ptr++; +} +ptr = strstr(buf, ":"); +if (ptr) { +*ptr = '.'; +len = ptr - buf; +} + +pstrcpy(bs->backing_file, sizeof(bs->backing_file), buf + len); + +fail1: +g_free(buf); +buf = NULL; + +fail2: +ret2 = g_iconv_close(cd); +if (ret2 == (gint) -1) { +return -1; +} + +return ret; +} + +static int vpc_decode_parent_loc(uint32_t platform, + BlockDriverState *bs, + uint32_t data_length) +{ +int ret; + +switch (platform) { +case PLATFORM_MACX: +ret = vpc_decode_maxc_loc(bs, data_length); +if (ret < 0) { +return ret; +} +break; + +case PLATFORM_W2RU: +/* fall through! */ +case PLATFORM_W2KU: +ret = vpc_decode_w2u_loc(bs, data_length); +if (ret < 0) { +return ret; +} +break; + +default: +return -1; +} + +return 0; +} + +static int vpc_read_backing_loc(VHDDynDiskHeader *dyndisk_header, +
Re: [Qemu-devel] Cannot boot my VM image after switching to ahci.
I assume Windows 7 or newer? In order to speed boot time, Windows will remove the AHCI driver from the critical driver database when you boot with no AHCI controller on the bus. If you later want to switch to AHCI mode, you have to boot with IDE again, and re-add the AHCI driver, reboot, and then reboot again with QEMU AHCI enabled. To do this on Windows 7, set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\msahci\Start to 0 To do this on Windows 8, delete the entire StartOverride key under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\storahci Good luck. On 04/23/2014 04:33 PM, Alex Davis wrote: I currently run my QEMU VM using the following command: /spare/qemu-1.7.1/bin/qemu-system-x86_64 -soundhw ac97 -sdl -vga std -net nic,macaddr=de:ad:be:ef:89:32 -net user -m 2048 -enable-kvm -drive file="$1",media=disk,if=ide,index=0 -drive file=/dev/sr0,media=cdrom,if=ide,index=1 -boot c -smp 2 I'm trying to run the VM using the following command: /spare/qemu-1.7.1/bin/qemu-system-x86_64 \ -machine type=q35,accel=kvm \ -acpitable file=/spare/qemu-1.7.1/share/qemu/q35-acpi-dsdt.aml \ -soundhw ac97 \ -sdl -vga std \ -net nic,macaddr=de:ad:be:ef:89:32 \ -net user \ -m 2G -enable-kvm \ -device ahci,id=ahci0 \ -drive file=win7.img,if=none,id=drive-sata0-0-0,index=0,media=disk \ -drive file=/dev/sr0,if=none,id=drive-sata0-0-1,index=1,media=cdrom \ -device ide-drive,bus=ahci0.0,unit=0,drive=drive-sata0-0-0,id=drive-sata0-0-0 \ -device ide-cd,bus=ahci0.1,unit=0,drive=drive-sata0-0-1,id=drive-sata0-0-1 \ -boot menu=on -smp 2 -monitor stdio I get 0x0007B unable to find boot device. I can boot into rescue mode and start a command prompt: the 'disk' and 'cdrom' are seen as d: and e:, instead of c: and d:. Any suggestions? I code, therefore I am
Re: [Qemu-devel] Qemu 2.0 regression with xen: qemu crash on any domUs S.O. start
Can you post your options to configure? The tip seems to be working here... On 04/01/2014 11:01 AM, Fabio Fantoni wrote: Today I tried latest qemu 2.0 compiled from git (commit 63678e17cf399ff81b93417fe7bee8d6ef6b6b1b) on this dom0: Debian 7 (Wheezy) 64 bit with kernel from package linux-image-3.2.0-4-amd64 version 3.2.54-2 and all dependency packages for xen, spice and usb redirection. Seabios 1.7.3-3, spice 0.12.4-0nocelt2 and usbredir 0.6-2 compiled from debian unstable sources. The xen-unstable upstream commit is 4787f667bcee205c56a27da59b766a53e1e929eb, plus these patches not upstream: tools: various things just to build test tools: Improve make debball libxl: Add qxl vga interface support for upstream qemu libxl: add basic spice support for pv domUs Qemu crashes always on domU S.O. start, on both pv and hvm domUs. Same dom0 with qemu 1.6 from xen-unstable repository used for some tests yesterday and was full working. I also update seabios to 1.7.4-4 compiled from debian unstable sources but the problem persists. I looked on dom0 logs, qemu logs and xl dmesg and I found only a qemu segfault related on each domU in dom0 syslog, for example the latest: [ 844.273170] qemu-system-i38[3545]: segfault at 8 ip 7fa905dcc4c1 sp 7fff41220810 error 4 in qemu-system-i386[7fa905ad5000+598000] If you need more informations, tests and/or logs tell me and I'll post them. Thanks for any reply.
[Qemu-devel] [PATCH 3/7] console: Add graphic_hw_add_display()
From: "John V. Baboval" Hook for adding another QemuConsole to the active display adapter. Signed-off-by: John V. Baboval --- include/ui/console.h |2 ++ ui/console.c |8 2 files changed, 10 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index 61455d6..95ed12a 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -275,6 +275,7 @@ typedef struct GraphicHwOps { void (*text_update)(void *opaque, console_ch_t *text); void (*update_interval)(void *opaque, uint64_t interval); void (*store_edid)(void *opaque, uint8_t *edid, size_t edid_size); +QemuConsole *(*add_display)(void *opaque); void (*set_orientation)(void *opaque, uint32_t x, uint32_t y, uint32_t r); } GraphicHwOps; @@ -287,6 +288,7 @@ void graphic_hw_store_edid(QemuConsole *con, uint8_t *edid, size_t edid_size); void graphic_hw_set_orientation(QemuConsole *con, uint32_t x, uint32_t y, uint32_t r); void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); +QemuConsole *graphic_hw_add_display(void); QemuConsole *qemu_console_lookup_by_index(unsigned int index); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev); diff --git a/ui/console.c b/ui/console.c index 22de32c..fc60570 100644 --- a/ui/console.c +++ b/ui/console.c @@ -285,6 +285,15 @@ void graphic_hw_invalidate(QemuConsole *con) } } +QemuConsole *graphic_hw_add_display(void) +{ +if (active_console && active_console->hw_ops->add_display) { +return active_console->hw_ops->add_display(active_console->hw); +} + +return NULL; +} + static void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp) { -- 1.7.9.5
[Qemu-devel] [PATCH 2/7] console: Add graphic_hw_set_orientation()
From: "John V. Baboval" Add a hook in GraphicHwOps for the ui to inform the hw of display orientation changes Signed-off-by: John V. Baboval --- include/ui/console.h |2 ++ ui/console.c | 10 ++ 2 files changed, 12 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index 9c928fa..61455d6 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -275,6 +275,7 @@ typedef struct GraphicHwOps { void (*text_update)(void *opaque, console_ch_t *text); void (*update_interval)(void *opaque, uint64_t interval); void (*store_edid)(void *opaque, uint8_t *edid, size_t edid_size); +void (*set_orientation)(void *opaque, uint32_t x, uint32_t y, uint32_t r); } GraphicHwOps; QemuConsole *graphic_console_init(DeviceState *dev, @@ -283,6 +284,8 @@ QemuConsole *graphic_console_init(DeviceState *dev, void graphic_hw_update(QemuConsole *con); void graphic_hw_store_edid(QemuConsole *con, uint8_t *edid, size_t edid_size); +void graphic_hw_set_orientation(QemuConsole *con, uint32_t x, uint32_t y, +uint32_t r); void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); diff --git a/ui/console.c b/ui/console.c index 1f6c840..22de32c 100644 --- a/ui/console.c +++ b/ui/console.c @@ -255,6 +255,17 @@ void graphic_hw_store_edid(QemuConsole *con, uint8_t *edid, size_t edid_size) } } +void graphic_hw_set_orientation(QemuConsole *con, uint32_t x, uint32_t y, +uint32_t r) +{ +if (!con) { +con = active_console; +} +if (con && con->hw_ops->set_orientation) { +con->hw_ops->set_orientation(con->hw, x, y, r); +} +} + void graphic_hw_update(QemuConsole *con) { if (!con) { -- 1.7.9.5
[Qemu-devel] [PATCH 5/7] ui: Add dpy_reset()
From: "John V. Baboval" To be called by graphics adapter to have the ui re-initialize monitor state. Signed-off-by: John V. Baboval --- include/ui/console.h |3 +++ ui/console.c |8 2 files changed, 11 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index a69ac3d..a7171cc 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -176,6 +176,8 @@ typedef struct DisplayChangeListenerOps { void (*dpy_text_update)(DisplayChangeListener *dcl, int x, int y, int w, int h); +void (*dpy_reset)(DisplayChangeListener *dcl); + void (*dpy_mouse_set)(DisplayChangeListener *dcl, int x, int y, int on); void (*dpy_cursor_define)(DisplayChangeListener *dcl, @@ -230,6 +232,7 @@ void dpy_text_resize(QemuConsole *con, int w, int h); void dpy_mouse_set(QemuConsole *con, int x, int y, int on); void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor); bool dpy_cursor_define_supported(QemuConsole *con); +void dpy_reset(QemuConsole *con); static inline int surface_stride(DisplaySurface *s) { diff --git a/ui/console.c b/ui/console.c index 0919973..201e602 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1560,6 +1560,17 @@ bool dpy_cursor_define_supported(QemuConsole *con) return false; } +void dpy_reset(QemuConsole *con) +{ +DisplayState *s = con->ds; +struct DisplayChangeListener *dcl; +QLIST_FOREACH(dcl, &s->listeners, next) { +if (dcl->ops->dpy_reset) { +dcl->ops->dpy_reset(dcl); +} +} +} + /***/ /* register display */ -- 1.7.9.5
[Qemu-devel] [PATCH 1/7] console: Add graphic_hw_store_edid()
From: "John V. Baboval" Add a hook in GraphicHwOps to pass monitor EDID for a QemuConsole from the ui to the hw. Signed-off-by: John V. Baboval --- include/ui/console.h |2 ++ ui/console.c | 10 ++ 2 files changed, 12 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index 4156a87..9c928fa 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -274,6 +274,7 @@ typedef struct GraphicHwOps { void (*gfx_update)(void *opaque); void (*text_update)(void *opaque, console_ch_t *text); void (*update_interval)(void *opaque, uint64_t interval); +void (*store_edid)(void *opaque, uint8_t *edid, size_t edid_size); } GraphicHwOps; QemuConsole *graphic_console_init(DeviceState *dev, @@ -281,6 +282,7 @@ QemuConsole *graphic_console_init(DeviceState *dev, void *opaque); void graphic_hw_update(QemuConsole *con); +void graphic_hw_store_edid(QemuConsole *con, uint8_t *edid, size_t edid_size); void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); diff --git a/ui/console.c b/ui/console.c index 502e160..1f6c840 100644 --- a/ui/console.c +++ b/ui/console.c @@ -245,6 +245,16 @@ static void gui_setup_refresh(DisplayState *ds) ds->have_text = have_text; } +void graphic_hw_store_edid(QemuConsole *con, uint8_t *edid, size_t edid_size) +{ +if (!con) { +con = active_console; +} +if (con && con->hw_ops->store_edid) { +con->hw_ops->store_edid(con->hw, edid, edid_size); +} +} + void graphic_hw_update(QemuConsole *con) { if (!con) { -- 1.7.9.5
[Qemu-devel] [PATCH 4/7] console: Add graphic_hw_notify()
From: "John V. Baboval" Hook to notify a display adapter of interesting UI changes such as monitor hotplug, orientation changes, etc... Signed-off-by: John V. Baboval --- include/ui/console.h |9 + ui/console.c |7 +++ 2 files changed, 16 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index 95ed12a..a69ac3d 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -110,6 +110,13 @@ struct QemuConsoleClass { #define QEMU_BIG_ENDIAN_FLAG0x01 #define QEMU_ALLOCATED_FLAG 0x02 +typedef enum { +GN_PNP,/* Guest should rescan PCI bus */ +GN_MONITOR_PNP,/* Guest should reload monitor port EDIDs */ +GN_DISPLAY_CONFIG, /* Guest should reload display orientation */ +GN_MOUSE_ENABLED, /* Guest should reconfigure cursor */ +} gn_cmd_t; + struct PixelFormat { uint8_t bits_per_pixel; uint8_t bytes_per_pixel; @@ -277,6 +284,7 @@ typedef struct GraphicHwOps { void (*store_edid)(void *opaque, uint8_t *edid, size_t edid_size); QemuConsole *(*add_display)(void *opaque); void (*set_orientation)(void *opaque, uint32_t x, uint32_t y, uint32_t r); +void (*notify)(void *opaque, gn_cmd_t cmd, int value); } GraphicHwOps; QemuConsole *graphic_console_init(DeviceState *dev, @@ -289,6 +297,7 @@ void graphic_hw_set_orientation(QemuConsole *con, uint32_t x, uint32_t y, uint32 void graphic_hw_invalidate(QemuConsole *con); void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata); QemuConsole *graphic_hw_add_display(void); +void graphic_hw_notify(QemuConsole *con, gn_cmd_t cmd, int value); QemuConsole *qemu_console_lookup_by_index(unsigned int index); QemuConsole *qemu_console_lookup_by_device(DeviceState *dev); diff --git a/ui/console.c b/ui/console.c index fc60570..0919973 100644 --- a/ui/console.c +++ b/ui/console.c @@ -293,6 +293,13 @@ QemuConsole *graphic_hw_add_display(void) return NULL; } +void graphic_hw_notify(QemuConsole *con, gn_cmd_t cmd, int value) +{ +if (con && con->hw_ops->notify) +con->hw_ops->notify(con->hw, cmd, value); +} + + static void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp) { -- 1.7.9.5
[Qemu-devel] [PATCH 0/7] Multi-head support infrastructure
From: "John V. Baboval" This is mostly just RFC at this point, since I'm not quite ready to submit the associated multi-head video adapter, drivers and UI that consume this stuff. (I still have to remove some Xen/XenClient specific stuff from it). These are the infrastructure hooks I needed to add in order to support XenClient Enterprise style multi-head with the current QEMU tip. The general architecture is as follows: Other than the initial display (which works as it always has), displays are dynamically added by the UI. This can be the result of command line parameters, hotplug notifications from UDEV, the user clicking an "Add Display" button in a menu, or whatever. The UI adds the display by calling graphic_hw_add_display(), which returns the QemuConsole for the new display. The video adapter can either allocate all supported displays up-front, or spoof up a new one when its add_display handler is called, either way, it's responsible for providing the new QemuConsole to the UI. If the display hardware doesn't support multi-head (add_display handler == NULL), or if the maximum number of displays are already connected, graphic_hw_add_display returns NULL. Once the UI has the new QemuConsole, it needs to do basic configuration. A new opaque pointer has been added to the DisplayChangeListener. The UI should set this to something which will allow it to determine which QemuConsole its handlers have been called for. It should then register its DisplayChangeListener with the QemuConsole. It should then provide a sane EDID with graphic_hw_store_edid(), and notify the adapter of the relative positions of the display windows with graphic_hw_set_orientation(). (Per earlier discussions with Gerd, the orientation should eventually live on the QemuConsole itself, in which case graphic_hw_set_orientation would need to be replaced with something like qemu_console_set_orientation(). I'll take care of that before the next version; I wanted to get something out for people to see before leaving for holiday travel though.) Once configuration is complete, and anytime the UI has completed configuration changes (plugs/unplugs, re-orientation, change in "supported resolution" due to window resizing), the UI should call graphic_hw_notify(). If the display adapter needs to re-initialize, it can call dpy_reset(). The UI should then reconfigure the EDID and orientation. The last hook added here is not really multi-head related, but is an optimization for showing/hiding the cursor. Things I'd still like to do: Submit the emulated multi-head graphics adapter along with the GPL Xorg and binary Windows drivers. Clean up the "active_console" stuff, which doesn't make a lot of sense anymore. Modify one of the stock UIs to consume this stuff. John V. Baboval (7): console: Add graphic_hw_store_edid() console: Add graphic_hw_set_orientation() console: Add graphic_hw_add_display() console: Add graphic_hw_notify() ui: Add dpy_reset() ui: Add dpy_cursor_enable() ui: Add an opaque pointer to the DisplayChangeListener include/ui/console.h | 22 ui/console.c | 54 ++ 2 files changed, 76 insertions(+) -- 1.7.9.5
[Qemu-devel] [PATCH 7/7] ui: Add an opaque pointer to the DisplayChangeListener
From: "John V. Baboval" The pointer is a place for the UI to hang a structure off of. In the multi-head case, the UI can use this pointer to distinguish which QemuConsole a dpy_* call was made for. Signed-off-by: John V. Baboval --- include/ui/console.h |1 + 1 file changed, 1 insertion(+) diff --git a/include/ui/console.h b/include/ui/console.h index 7efa119..271f577 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -191,6 +191,7 @@ struct DisplayChangeListener { const DisplayChangeListenerOps *ops; DisplayState *ds; QemuConsole *con; +void *ui; QLIST_ENTRY(DisplayChangeListener) next; }; -- 1.7.9.5
[Qemu-devel] [PATCH 6/7] ui: Add dpy_cursor_enable()
From: "John V. Baboval" This is an optimization to allow the UI to show/hide the current cursor without setting it to a new bitmap. In-guest screen sharing applications which show/hide the cursor when capturing the screen every frame (GoToMeeting, WebEx, etc.) cause high QEMU CPU usage if cursor hiding/restoring is implemented as setting a blank cursor and re-setting the original glyph. In-guest driver APIs typically have enable/disable called out as a separate operation to provide input for this optimization. Signed-off-by: John V. Baboval --- include/ui/console.h |3 +++ ui/console.c | 11 +++ 2 files changed, 14 insertions(+) diff --git a/include/ui/console.h b/include/ui/console.h index a7171cc..7efa119 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -182,6 +182,8 @@ typedef struct DisplayChangeListenerOps { int x, int y, int on); void (*dpy_cursor_define)(DisplayChangeListener *dcl, QEMUCursor *cursor); +void (*dpy_cursor_enable)(DisplayChangeListener *dcl, + bool state); } DisplayChangeListenerOps; struct DisplayChangeListener { @@ -232,6 +234,7 @@ void dpy_text_resize(QemuConsole *con, int w, int h); void dpy_mouse_set(QemuConsole *con, int x, int y, int on); void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor); bool dpy_cursor_define_supported(QemuConsole *con); +void dpy_cursor_enable(QemuConsole *con, bool state); void dpy_reset(QemuConsole *con); static inline int surface_stride(DisplaySurface *s) diff --git a/ui/console.c b/ui/console.c index 201e602..e9f74c9 100644 --- a/ui/console.c +++ b/ui/console.c @@ -1560,6 +1560,17 @@ bool dpy_cursor_define_supported(QemuConsole *con) return false; } +void dpy_cursor_enable(QemuConsole *con, bool state) +{ +DisplayState *s = con->ds; +struct DisplayChangeListener *dcl; +QLIST_FOREACH(dcl, &s->listeners, next) { +if (dcl->ops->dpy_cursor_enable) { +dcl->ops->dpy_cursor_enable(dcl, state); +} +} +} + void dpy_reset(QemuConsole *con) { DisplayState *s = con->ds; -- 1.7.9.5
Re: [Qemu-devel] [RFC PATCH 12/15] input: mouse: add qemu_input_is_absolute()
Perhaps this should just return the mask instead of a boolean? It would be nice at some point to handle a USB HID style device that can send both relative and absolute events, for example. Though perhaps that would be better as future work, since this is a nice drop-in replacement for the old call. On 11/28/2013 09:30 AM, Gerd Hoffmann wrote: Same as kbd_mouse_is_absolute(), but using new input core. Signed-off-by: Gerd Hoffmann --- include/ui/input.h | 1 + ui/input.c | 8 2 files changed, 9 insertions(+) diff --git a/include/ui/input.h b/include/ui/input.h index 0d79342..43b9afc 100644 --- a/include/ui/input.h +++ b/include/ui/input.h @@ -39,6 +39,7 @@ void qemu_input_queue_btn(QemuConsole *src, InputButton btn, bool down); void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, uint32_t button_old, uint32_t button_new); +bool qemu_input_is_absolute(void); int qemu_input_scale_axis(int value, int size_in, int size_out); InputEvent *qemu_input_event_new_move(InputEventKind kind, InputAxis axis, int value); diff --git a/ui/input.c b/ui/input.c index abfe3a3..719c427 100644 --- a/ui/input.c +++ b/ui/input.c @@ -167,6 +167,14 @@ void qemu_input_update_buttons(QemuConsole *src, uint32_t *button_map, } } +bool qemu_input_is_absolute(void) +{ +QemuInputHandlerState *s; + +s = qemu_input_find_handler(INPUT_EVENT_MASK_REL | INPUT_EVENT_MASK_ABS); +return (s != NULL) && (s->handler->mask & INPUT_EVENT_MASK_ABS); +} + int qemu_input_scale_axis(int value, int size_in, int size_out) { if (size_in < 2) {
Re: [Qemu-devel] [RFC PATCH 11/15] input: mouse: add graphic_rotate support
I'm not sure this is correct. Generally when the display gets rotated, the input device coordinates do not, and the in-guest code handles the math. On 11/28/2013 09:30 AM, Gerd Hoffmann wrote: Transform absolute mouse events according to graphic_rotate. Legacy input code does it for both absolute and relative events, but the logic is broken for relative coordinates, so this is most likely not used anyway. Signed-off-by: Gerd Hoffmann --- ui/input.c | 33 + 1 file changed, 33 insertions(+) diff --git a/ui/input.c b/ui/input.c index fa6d677..abfe3a3 100644 --- a/ui/input.c +++ b/ui/input.c @@ -50,6 +50,33 @@ qemu_input_find_handler(uint32_t mask) return NULL; } +static void qemu_input_transform_abs_rotate(InputEvent *evt) +{ +switch (graphic_rotate) { +case 90: +if (evt->abs->axis == INPUT_AXIS_X) { +evt->abs->axis = INPUT_AXIS_Y; +} +if (evt->abs->axis == INPUT_AXIS_Y) { +evt->abs->axis = INPUT_AXIS_X; +evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis; +} +break; +case 180: +evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis; +break; +case 270: +if (evt->abs->axis == INPUT_AXIS_X) { +evt->abs->axis = INPUT_AXIS_Y; +evt->abs->axis = INPUT_EVENT_ABS_SIZE - 1 - evt->abs->axis; +} +if (evt->abs->axis == INPUT_AXIS_Y) { +evt->abs->axis = INPUT_AXIS_X; +} +break; +} +} + void qemu_input_event_send(QemuConsole *src, InputEvent *evt) { QemuInputHandlerState *s; @@ -58,6 +85,12 @@ void qemu_input_event_send(QemuConsole *src, InputEvent *evt) return; } +/* pre processing */ +if (graphic_rotate && (evt->kind == INPUT_EVENT_KIND_ABS)) { +qemu_input_transform_abs_rotate(evt); +} + +/* send event */ s = qemu_input_find_handler(1 << evt->kind); s->handler->event(s->dev, src, evt); s->events++;
Re: [Qemu-devel] console muti-head some more design input
On 11/26/2013 11:29 PM, Dave Airlie wrote: On Fri, Nov 22, 2013 at 6:41 PM, Gerd Hoffmann wrote: Hi, While thinking about this: A completely different approach to tackle this would be to implement touchscreen emulation. So we don't have a single usb-tablet, but multiple (one per display) touch input devices. Then we can simply route absolute input events from this display as-is to that touch device and be done with it. No need to deal with coordinate transformations in qemu, the guest will deal with it. This is a nice dream, except you'll find the guest won't deal with it very well, and you'll have all kinds of guest scenarios to link up that touchscreen a talks to monitor a etc. Ok, scratch the idea then. I don't have personal experience with this, no touch capable displays here. Hmm I think we get to unscratch this idea, After looking into this a bit more I think we probably do need something outside the gpu to handle this. The problem is that there are two scenarios for a GPU multi-head, a) one resource - two outputs, the second output has an offset to scanout into the resource b) two resources - two outputs, both outputs have a 0,0 into their respective resources. So the GPU doesn't have this information in all cases on what the input device configuration should be, Neither do we have anyway in the guests to specify this relationship at the driver level. There is a third, likely option: c) one resource - two outputs, the second output's scanout offset isn't the same as the logical offset from the perspective of the input device There are two possible solutions to this, both of which I have added interfaces for. (I really should hurry up and send out patches) The individual logical display offsets can be provided by the UI, and pushed into the guest, or the guest driver can push the offsets down. So if the UI provides absolute coordinates normalized to the individual displays, and the offsets are stored in the QemuConsole, then the input layer can do the math as Gerd suggested. It just requires one additional coordinate set transformation. In XenClient, we use both interfaces, so the user can set the display offsets from wherever they care to. The in-guest side is relatively easy to implement in Linux guests that run X. It's more complicated in Windows, since the display driver isn't actually told about the offsets, so there needs to be an additional user-level service running to inform it of changes. So I think we probably do need treat multi-head windows as separate input devices, and/or have an agent in the guest to do the right thing by configuring multiple input devices to map to multiple outputs. This is essentially correct, except that only the UI needs to treat it as separate input devices. The rest of the stack should be OK as one input device. I suppose spice must do something like this already, maybe they can tell me more. Dave.
Re: [Qemu-devel] console muti-head some more design input
On 11/20/2013 10:14 AM, Gerd Hoffmann wrote: On Mi, 2013-11-20 at 09:32 -0500, John Baboval wrote: On 11/20/2013 03:12 AM, Gerd Hoffmann wrote: Hi, I think you are only considering output here, for input we definitely need some idea of screen layout, and this needs to be stored somewhere. Oh yea, input. That needs quite some work for multihead / multiseat. I think we should *not* try to hack that into the ui. We should extend the input layer instead. This would be a contrast to how a real system works. No. We have to solve problem here which doesn't exist on real hardware in the first place. IMO, the UI is the appropriate place for this sort of thing. A basic UI is going to be sending relative events anyway. I think a "seat" should be a UI construct as well. A seat on real hardware is a group of input (kbd, mouse, tablet, ...) and output (display, speakers, ) devices. In qemu the displays are represented by QemuConsoles. So to model real hardware we should put the QemuConsoles and input devices for a seat into a group. The ui displays some QemuConsole. If we tag input events with the QemuConsole the input layer can figure the correct input device which should receive the event according to the seat grouping. With absolute pointer events the whole thing becomes a bit more tricky as we have to map input from multiple displays (QemuConsoles) to a single absolute pointing device (usb tablet). This is what Dave wants the screen layout for. I still think the input layer is the place to do this transformation. We solve this problem in our UI now. It's not enough to know the offsets. You also need to know all the resolutions - the display window, the guest, and the device coordinate system of the virtual pointing device (we use a PV event ring instead of a USB tablet). If your UI can scale the guest output, that means you need to also store the UI's window geometry in the QemuConsole to get the math right. Incidentally, XenClient will eventually be moving back to relative coordinates from mice. We will handle seamless transitions by having the guest feed the pointer coordinates back down through an emulated hardware cursor channel. The reason for this is that operating systems like Windows 8 implement various types of "pointer friction" that don't work when you send absolute coordinates. We are still working out the latency kinks. While thinking about this: A completely different approach to tackle this would be to implement touchscreen emulation. So we don't have a single usb-tablet, but multiple (one per display) touch input devices. Then we can simply route absolute input events from this display as-is to that touch device and be done with it. No need to deal with coordinate transformations in qemu, the guest will deal with it. cheers, Gerd
Re: [Qemu-devel] console muti-head some more design input
On 11/20/2013 03:12 AM, Gerd Hoffmann wrote: Hi, I think you are only considering output here, for input we definitely need some idea of screen layout, and this needs to be stored somewhere. Oh yea, input. That needs quite some work for multihead / multiseat. I think we should *not* try to hack that into the ui. We should extend the input layer instead. This would be a contrast to how a real system works. IMO, the UI is the appropriate place for this sort of thing. A basic UI is going to be sending relative events anyway. I think a "seat" should be a UI construct as well. The functions used to notify qemu about mouse + keyboard events should get an additional parameter to indicate the source of the event. I think we can use a QemuConsole here. Then teach the input layer about seats, where a seat is a group of input devices (kbd, mouse, tablet) and a group of QemuConsoles. With x+y for each QemuConsole. The input layer will do the event routing: Translate coordinates, send to the correct device. I think initially we just can handle all existing QemuConsole and input devices implicitly as "seat 0". Stick x+y into QemuConsole for now, and have the input layer get it from there. At some point in the future we might want move this to a QemuSeat when we actually go multiseat. Bottom line: please do the coordinates math in input.c not sdl2.c so we don't run into roadblocks in the future. cheers, Gerd
Re: [Qemu-devel] console muti-head some more design input
On Nov 19, 2013, at 9:59 PM, Dave Airlie wrote: > On Tue, Nov 19, 2013 at 6:11 PM, Gerd Hoffmann wrote: >> Hi, >> >>> So I felt I had a choice here for sharing a single output surface >>> amongst outputs: >>> >>> a) have multiple QemuConsole reference multiple DisplaySurface wihch >>> reference a single pixman image, >> >> This one. >> >>> In either case we need to store, width/height of the console and x/y >>> offset into the output surface somewhere, as the output dimensions >>> will not correspond to surface dimensions or the surface dimensions >>> won't correspond to the pixman image dimensions >> >> Not needed (well, internal to virtio-gpu probably). > > I think you are only considering output here, for input we definitely > need some idea of screen layout, and this needs to be stored > somewhere. > > e.g. SDL2 gets an input event in the right hand window it needs to > translate that into an input event on the whole output surface. > > Have a look the virtio-gpu branch in my repo (don't look at the > history, its ugly, just the final state), you'll see code in sdl2.c to > do input translation from window coordinates to the overall screen > space. So we need at least the x,y offset in the ui code, and I think > we need to communicate that via the console. > One of the patches I will be submitting as part of this includes bi-directional calls to set the orientation. A HwOp, and a DisplayChangeListenerOp. This allows you to move the display orientation around in the guest (if your driver and backend support it), or to move the orientation around by dragging windows... Either way you have the data you need to get absolute coordinates right, even if you are scaling the guest display in your windows. Whether the orientation offsets end up stored in the QemuConsole or not becomes an implementation detail if you get notifications. > Otherwise I think I've done things the way you've said and it seems to > be working for me on a dual-head setup. > > (oh and yes this all sw rendering only, to do 3D rendering we need to > put a thread in to do the GL stuff, but it interacts with the console > layer quite a bit, since SDL and the virtio-gpu need to be in the same > thread, so things like resize can work). > I also have a patch to add dpy_lock and dpy_unlock hooks to the DisplayChangeListener so that the UI can be in another thread. In fact, on XenClient we run with the bulk of the UI in another process so that multiple VMs can share the same windows and GL textures. Otherwise dom0 doesn't have enough memory for lots of guests with multiple big monitors connected. I wasn't planning on submitting the lock patch since I figured nobody would want our UI that uses it. But if there is interest I can. Eventually I would like to write a GEM/KMS UI for full zero-copy display, and that would need locking hooks anyway. We used to run with a GLX UI that was a thread per display inside qemu. If you'd like I can send you that patch, but I don't have the bandwidth to modernize it. I believe it is qemu 1.0 vintage. (It's on the Citrix website in some obscure location already) > Dave. >
Re: [Qemu-devel] Multi-head support RFC
On 11/19/2013 1:57 AM, Gerd Hoffmann wrote: Hi, I think it would be better if the HwOps calls all took a QemuConsole instead of the opaque structure. The hw implementations can dig their opaque structure out from there. QemuConsole is private to ui/console.c though (and I prefer to keep it this way). So we need either a helper function to query con->hw or we keep the opaque and pass QemuConsole as additional parameter. When going this route. Alternative approach: struct my_gfx_card_state { PCIDevice pci; [ ... ] struct my_head_state { QemuConsole *con; [ ... ] } heads[MAX_HEADS]; } Then instead of graphic_console_init(..., &state); call graphic_console_init(..., &state->heads[i]); so you can figure the head in the callbacks. What I had prototyped (I got impatient) was to add a helper: qemu_console_hw_opaque() to console.c so the HwOps could query the opaque pointer. I don't like it because it requires an additional function call at the top of frequently called operations... However I'm not a huge fan of the head state array either, since it will require either pointer duplication, or pointer acrobatics, or the same helper function to get the card state. A third option would be to use the console index as a parameter to each HwOp. graphic_console_init and QemuConsole could remain unchanged, as could all the graphic_hw_*() helpers. If the HwOp needs the QemuConsole for any given operation, it could then use qemu_console_lookup_by_index(). Many operations would only need the index though. cheers, Gerd
Re: [Qemu-devel] Multi-head support RFC
I've dug into this further, and basically gotten what I had before working against the latest code. So now the ugly bits are making themselves known. In my existing patch set, dpy_refresh is called for each display, however since hw_update takes an opaque pointer to the hw info structure, it has to be called per-hw, not per-display. So the ui's dpy_refresh implementation calls hw_update only for the first display, and the hw updates all displays each time it is called. Not only is this ugly, but it requires a mechanism to loop through all the consoles in the hw code, which can't be done without breaking all the nice protections that have been set up between the ui and hw. The lack of a per-display hook in the HwOps calls is cumbersome in other places too. For example in the hook I'm adding for store_edid, the EDID needs to be for a specific console, so I have to pass an index. I think it would be better if the HwOps calls all took a QemuConsole instead of the opaque structure. The hw implementations can dig their opaque structure out from there. (Of course I'd have to go update all the emulated cards to handle the new model... But that's the price of progress I suppose.) I'd love you're opinion on the matter before I spend the time making the changes though... On 11/7/2013 10:54 AM, John Baboval wrote: On 11/7/2013 8:46 AM, Gerd Hoffmann wrote: Hi, As far as the EDID is concerned, there can only be one EDID for a display+hw pair, or the guest won't know what to do. In my use-case, I simply pass real EDIDs through, and create a full-screen window for each real monitor. Ok, makes sense. If you wanted to have two UIs displaying the same DisplaySurface, the EDID would have to come from one of them, and the other would have to clip, or scale. Yes. Why not? That is exactly my plan. Just have the virtual graphic card call graphic_console_init() multiple times, once for each display connector it has. Do you see fundamental issues with that approach? Currently only one QemuConsole is active at a time, so that would have to change That isn't mandatory any more. It is still the default behavior of a DisplayChangeListener to follow the active_console, for compatibility reasons. SDL and VNC still behave that way. You can explicitly bind a DisplayChangeListener to a QemuConsole though, by setting DisplayChangeListener->con before calling register_displaychangelistener(). gtk binds to QemuConsole #0. spice creates a display channel per (graphical) console. Each display channel has a DisplayChangeListener instance, and each DisplayChangeListener is linked to a different QemuConsole. For your UI you probably want follow the spice model. Have a DisplayChangeListener for each physical monitor of the host, have a fixed QemuConsole bound to each DisplayChangeListener. DisplayChangeListeners can come and go at runtime just fine, so you should be able to create/destroy them on monitor plug/unplug events on the host. I think the best thing for me to do at this point is to just start implementing with multiple QemuConsole, then, and post again when I have a better idea of what it ends up looking like. I'll keep you posted. cheers, Gerd
Re: [Qemu-devel] Multi-head support RFC
On 11/06/2013 06:44 PM, Dave Airlie wrote: On Wed, Nov 6, 2013 at 8:57 PM, Gerd Hoffmann wrote: Hi, It currently just adds multiple DisplaySurfaces to the QemuConsole, now Gerd said he thought I should be using multiple QemuConsoles but I really didn't think this was a good idea, Why? It's a fair question and I haven't tried the other way yet and I fully intend to do further investigating, I think my main reason was the current console at least when interacting with gtk frontend are done on a console per tab, now if we have multiple outputs I would want them to be visible at the same time, now I understand we could fix this but we'd need some sort of console grouping to say this group of consoles represent this set of outputs, Though further to that I'm not sure how we'd want to represent multiple graphic cards I assume we'd want to be able to see them all at once, but still have some sort of binding between separate outputs on one card. Multiple graphic cards is actually a reasonable argument for the multiple QemuConsole route, since each would have its own GraphicHwOps, so it would simply be a matter of having the UI give the user a mechanism for choosing which card to attach a new display to. Dave.
Re: [Qemu-devel] Multi-head support RFC
On 11/7/2013 8:46 AM, Gerd Hoffmann wrote: Hi, As far as the EDID is concerned, there can only be one EDID for a display+hw pair, or the guest won't know what to do. In my use-case, I simply pass real EDIDs through, and create a full-screen window for each real monitor. Ok, makes sense. If you wanted to have two UIs displaying the same DisplaySurface, the EDID would have to come from one of them, and the other would have to clip, or scale. Yes. Why not? That is exactly my plan. Just have the virtual graphic card call graphic_console_init() multiple times, once for each display connector it has. Do you see fundamental issues with that approach? Currently only one QemuConsole is active at a time, so that would have to change That isn't mandatory any more. It is still the default behavior of a DisplayChangeListener to follow the active_console, for compatibility reasons. SDL and VNC still behave that way. You can explicitly bind a DisplayChangeListener to a QemuConsole though, by setting DisplayChangeListener->con before calling register_displaychangelistener(). gtk binds to QemuConsole #0. spice creates a display channel per (graphical) console. Each display channel has a DisplayChangeListener instance, and each DisplayChangeListener is linked to a different QemuConsole. For your UI you probably want follow the spice model. Have a DisplayChangeListener for each physical monitor of the host, have a fixed QemuConsole bound to each DisplayChangeListener. DisplayChangeListeners can come and go at runtime just fine, so you should be able to create/destroy them on monitor plug/unplug events on the host. I think the best thing for me to do at this point is to just start implementing with multiple QemuConsole, then, and post again when I have a better idea of what it ends up looking like. I'll keep you posted. cheers, Gerd
Re: [Qemu-devel] Multi-head support RFC
On 11/06/2013 05:55 AM, Gerd Hoffmann wrote: Hi, In QEMU 1.3, there was a DisplayState list. We used one DisplayState per monitor. The DisplayChangeListener has a new hw_add_display vector, so that when the UI requests a second monitor the new display gets attached to the emulated hardware. (patch: add_display_ptr) I don't think we want actually add/remove stuff here. On real hardware your gfx card has a fixed set of display connectors, and I think we are best of mimic that. I think that's a property of the emulated hardware. Monitors get connected and disconnected, and that's what the UI cares about. Support for propagating connect/disconnect events and enabling/disabling displays needs to be added properly. Currently qxl/spice can handle this, but it uses a private side channel. A new vector, hw_store_edid, was added to DisplayState so that UIs could tell emulated hardware what the EDID for a given display should be. (patch: edid-vector) Note that multiple uis can be active at the same time. What happened with the edids then? This is why it seemed to me that we shouldn't have multiple QemuConsoles. There should be one per UI type. In my current patches, each DisplayState has a new DisplayType enum, so I can keep track of which active UI the DisplayState goes with. As far as the EDID is concerned, there can only be one EDID for a display+hw pair, or the guest won't know what to do. In my use-case, I simply pass real EDIDs through, and create a full-screen window for each real monitor. If you wanted to have two UIs displaying the same DisplaySurface, the EDID would have to come from one of them, and the other would have to clip, or scale. VRAM size was made configurable, so that more could be allocated to handle multiple high-resolution displays. (patch: variable-vram-size) upstream stdvga has this meanwhile. I don't think it makes sense to have a QemuConsole per display. Why not? That is exactly my plan. Just have the virtual graphic card call graphic_console_init() multiple times, once for each display connector it has. Do you see fundamental issues with that approach? Currently only one QemuConsole is active at a time, so that would have to change It could certainly be done this way, but it seemed like more churn. Perhaps we should step back and define what we want each of these objects to be. There are things in QemuConsole that we don't really need another copy of. There is also stuff in the QemuConsole that we don't want to duplicate just to have multiple displays. Like the CharDriverState. I can use a model similar to what qxl does, and put the framebuffer for each display inside a single DisplaySurface allocated to be a bounding rectangle around all framebuffers. This has the advantage of looking like something that already exists in the tree, but has several disadvantages. Indeed. I don't recommend that. It is that way for several historical reasons (one being that the code predates the qemu console cleanup in the 1.5 devel cycle). Are these features something that people would want to see in the tree? Sure. One of the reasons for the console cleanup was to allow proper multihead support. cheers, Gerd
Re: [Qemu-devel] Multi-head support RFC
On 11/05/2013 08:46 PM, Dave Airlie wrote: On Wed, Nov 6, 2013 at 6:42 AM, John Baboval wrote: Hello, I am currently the device model maintainer for XenClient Enterprise. As you may or may not know, we maintain a patch queue on top of QEMU (currently 1.3) that adds functionality needed to support XCE features. One of the major things we add is robust multi-head support. This includes DDC emulation for EDID data, variable VRAM size, monitor hot-plug support, simulated VSYNC, and guest controlled display orientation. This includes both the necessary interfaces between the hw and ui, and a new emulated adapter (with drivers) that exercises the interfaces. I don't think we'd want to lump all these things together though, I agree. In my current patch set they are all separated out into individual bits. I've started looking at doing multi-head support for a new virtio-gpu, and I've gotten basic multi-head working with SDL2.0 with cursor support. It currently just adds multiple DisplaySurfaces to the QemuConsole, now Gerd said he thought I should be using multiple QemuConsoles but I really didn't think this was a good idea, and I still think multiple surfaces makes more sense wrt how best to interact with this. Why do you need to emulate DDC btw? is this just to fool the guest vesa code etc? Basically, yes. It's convenient if you don't want to install a driver in the guest, but you want it to boot to a reasonable resolution. There are two parts to the change. The big part is in the vga BIOS, to add an INT10(0x4F) handler that reads the EDID from an IO port. The QEMU side is simply the IO port handler, and a place in VGACommonState to squirrel away the EDID. For multi-head, we install a driver anyway (The X.org driver is GPL. The windows one, we can only distribute the binary for now because it's got closed-source code from Microsoft in it), and then it doesn't even use the DDC. There's a shared memory channel for passing EDID. Dave.
[Qemu-devel] Multi-head support RFC
Hello, I am currently the device model maintainer for XenClient Enterprise. As you may or may not know, we maintain a patch queue on top of QEMU (currently 1.3) that adds functionality needed to support XCE features. One of the major things we add is robust multi-head support. This includes DDC emulation for EDID data, variable VRAM size, monitor hot-plug support, simulated VSYNC, and guest controlled display orientation. This includes both the necessary interfaces between the hw and ui, and a new emulated adapter (with drivers) that exercises the interfaces. Between QEMU 1.3 and QEMU 1.6, a lot of changes were made to the QemuConsole and DisplayState structures that will require significant changes to our patches. I'd like to adapt to these changes in such a way that they might make some of our work acceptable upstream. As such, I'd like to describe how the patches currently work, describe how I'd propose they work in the new version, and solicit feedback as to if the plans would be acceptable. I've stuck our current patch queue on github for convenience. If I refer to a patch in the below description, you can check it out there: https://github.com/jbaboval/xce-qemu.pq This is what we currently do: In QEMU 1.3, there was a DisplayState list. We used one DisplayState per monitor. The DisplayChangeListener has a new hw_add_display vector, so that when the UI requests a second monitor the new display gets attached to the emulated hardware. (patch: add_display_ptr) Each DisplayState was given an ID, so that emulated hardware could keep track of which EDID and other metadata went with with DisplayState. (patch: display-id-allocation) A new function, gui_start_updates, starts refresh of the new display. This seems to be equivalent to the new gui_setup_refresh() that exists in newer versions. (patch: gui_start_updates) A new vector, hw_store_edid, was added to DisplayState so that UIs could tell emulated hardware what the EDID for a given display should be. (patch: edid-vector) A new vector, hw_notify, was added to DisplayState so the UIs could tell the emulated hardware about interesting events, such as monitor hotplugs (new windows), orientation changes, availability of hardware cursor functionality, etc... (patch: display-hw-notify) VRAM size was made configurable, so that more could be allocated to handle multiple high-resolution displays. (patch: variable-vram-size) The flow is: - The user requests a hotplug (user added a "monitor" with a menu, UI reacted to a udev hotplug or XRandR event, or whatever) - The UI asks the hw to allocate a new display. If the hw doesn't support it (vector is NULL), the system continues with one display. - The hw returns a new DisplayState to the UI with all the hw_ vectors filled in - The UI registers its DisplayChangeListener with the new DisplayState - The UI provides an EDID for the new display with hw_store_edid() - The UI notifies the guest that an event has occured with hw_notify() - The UI starts a gui timer for the new DisplayState with gui_start_updates() - The guest driver does its normal thing, sets the mode on the new display, and starts rendering - The timer handler calls gfx_hw_update for the DisplayState - The hw calls dpy_update for changes on the new DisplayState . In the latest code, DisplayState isn't a list anymore, and many operations that apply to a DisplayState apply to a QemuConsole instead. Also, the DisplaySurface is a property of the QemuConsole now instead of part of the DisplayState. I'm going to have to make some fairly fundamental changes to our current architecture to adapt to the latest upstream changes, and I would appreciate feedback on the options. I don't think it makes sense to have a QemuConsole per display. I can use a model similar to what qxl does, and put the framebuffer for each display inside a single DisplaySurface allocated to be a bounding rectangle around all framebuffers. This has the advantage of looking like something that already exists in the tree, but has several disadvantages. It was convenient - but not necessary - to have a DisplaySurface per display, since that kept track of the display mode, allowed different depths per monitor (not very useful, but possible), etc. If the displays are different resolutions, it leaves a dead space of wasted memory inside the region. If there's a single DisplaySurface, some other structure/list/array will need to be added to track the individual resolutions, offsets, and strides of the sub-regions in order to be able to display them in separate windows or - more likely - as full screen on real displays. It also makes hot-plugging more complex, since adding/removing a display will alter the configuration of the existing displays. I could turn the DisplayState and DisplaySurface in QEMU console into lists, and run much like my existing patches. I could move the DisplaySurface back into DisplaySta
Re: [Qemu-devel] [PATCH v4] Add 'maxqdepth' as an option to tty character devices.
On 05/10/2013 11:28 PM, Eric Blake wrote: On 05/07/2013 04:39 PM, John Baboval wrote: From: "John V. Baboval" This parameter will cause writes to tty backed chardevs to return -EAGAIN if the backing tty has buffered more than the specified number of characters. When data is sent, the TIOCOUTQ ioctl is invoked to determine the current TTY output buffer depth. +++ b/qapi-schema.json @@ -3182,11 +3182,14 @@ # # @device: The name of the special file for the device, # i.e. /dev/ttyS0 on Unix or COM1: on Windows -# @type: What kind of device this is. +# +# @maxqdepth: #optional The maximum depth of the underlying tty +# output queue (Unix) (Since 1.6) # # Since: 1.4 ## -{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } } +{ 'type': 'ChardevHostdev', 'data': { 'device': 'str', + '*maxqdepth' : 'int' } } Thanks; this interface change looks better (I'd still like to see someone working on introspection, but it doesn't have to be you). I'll still leave the implementation details to others more qualified for that part of the review. In particular, since you are claiming this optional attribute is Linux-only, that means we'd need introspection to know whether a given qemu build supports the field (compiled on Linux) or not (compiled on mingw), not just whether the qemu is new enough (1.6) or older (1.4). I believe (though I haven't tested on Windows) that the option at least does no harm there. You can still set it - It's just a no-op.
[Qemu-devel] [PATCH v4] Add 'maxqdepth' as an option to tty character devices.
From: "John V. Baboval" This parameter will cause writes to tty backed chardevs to return -EAGAIN if the backing tty has buffered more than the specified number of characters. When data is sent, the TIOCOUTQ ioctl is invoked to determine the current TTY output buffer depth. Background: Some devices use DTR/DSR as flow control. (eg. Check/Receipt printers with some POS software). When the device de-asserts DTR, the guest OS notifies the application and new data is blocked. When running on a QEMU serial port backed by a TTY, though the guest stops transmitting, all the characters in the TTY output buffer are still sent. The device buffer overflows and data is lost. In this case the user could set maxqdepth=1. Signed-off-by: John Baboval --- Includes changes recommended by Eric Blake and Paolo Bonzini: Parameter documentation includes a (since 1.6) Documentation for stale @type parameter was removed maxqdepth parameter is now optional Patch passes style checks qemu_chr_parse_serial sets has_maxqdepth as appropriate include/sysemu/char.h |2 ++ qapi-schema.json |7 +-- qemu-char.c | 46 +- qemu-options.hx |4 ++-- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 5e42c90..a94c1fb 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -43,6 +43,7 @@ typedef struct { #define CHR_IOCTL_SERIAL_SET_TIOCM 13 #define CHR_IOCTL_SERIAL_GET_TIOCM 14 +#define CHR_IOCTL_SERIAL_TIOCOUTQ15 #define CHR_TIOCM_CTS 0x020 #define CHR_TIOCM_CAR 0x040 @@ -77,6 +78,7 @@ struct CharDriverState { int fe_open; int explicit_fe_open; int avail_connections; +uint32_t maxqdepth; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; diff --git a/qapi-schema.json b/qapi-schema.json index 7797400..53a6d12 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3182,11 +3182,14 @@ # # @device: The name of the special file for the device, # i.e. /dev/ttyS0 on Unix or COM1: on Windows -# @type: What kind of device this is. +# +# @maxqdepth: #optional The maximum depth of the underlying tty +# output queue (Unix) (Since 1.6) # # Since: 1.4 ## -{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } } +{ 'type': 'ChardevHostdev', 'data': { 'device': 'str', + '*maxqdepth' : 'int' } } ## # @ChardevSocket: diff --git a/qemu-char.c b/qemu-char.c index 64e824d..cfc0793 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -782,6 +782,7 @@ typedef struct FDCharDriver { GIOChannel *fd_in, *fd_out; guint fd_in_tag; int max_size; +int tiocoutq_failed; QTAILQ_ENTRY(FDCharDriver) node; } FDCharDriver; @@ -1260,6 +1261,23 @@ static CharDriverState *qemu_chr_open_pty(const char *id, return chr; } +static int tty_serial_write(CharDriverState *chr, const uint8_t *buf, int len) +{ +FDCharDriver *s = chr->opaque; +uint32_t inflight = 0; + +qemu_chr_fe_ioctl(chr, CHR_IOCTL_SERIAL_TIOCOUTQ, &inflight); +if (inflight >= chr->maxqdepth) { +return -EAGAIN; +} + +if (inflight + len > chr->maxqdepth) { +len = chr->maxqdepth - inflight; +} + +return io_channel_send(s->fd_out, buf, len); +} + static void tty_serial_init(int fd, int speed, int parity, int data_bits, int stop_bits) { @@ -1438,6 +1456,18 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ); } break; +case CHR_IOCTL_SERIAL_TIOCOUTQ: +{ +if (!s->tiocoutq_failed) { +s->tiocoutq_failed = ioctl(g_io_channel_unix_get_fd(s->fd_in), + TIOCOUTQ, arg); +} + +if (s->tiocoutq_failed) { +*(unsigned int *)arg = 0; +} +} +break; default: return -ENOTSUP; } @@ -1466,6 +1496,7 @@ static CharDriverState *qemu_chr_open_tty_fd(int fd) tty_serial_init(fd, 115200, 'N', 8, 1); chr = qemu_chr_open_fd(fd, fd); +chr->chr_write = tty_serial_write; chr->chr_ioctl = tty_serial_ioctl; chr->chr_close = qemu_chr_close_tty; return chr; @@ -3172,6 +3203,11 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, } backend->serial = g_new0(ChardevHostdev, 1); backend->serial->device = g_strdup(device); +backend->serial->maxqdepth = +qemu_opt_get_number(opts, "maxqdepth", -1); +if (backend->serial->maxqdepth != -1) { +backend->serial->has_maxqdepth =
Re: [Qemu-devel] [PATCH] Add 'maxqdepth' as an option to tty character devices.
Sorry about fumbling with the tools. The wiki link is very helpful. I'll give it another go in a little while. -Original Message- From: Eric Blake [mailto:ebl...@redhat.com] Sent: Tuesday, May 07, 2013 1:17 PM To: John Baboval Cc: qemu-devel@nongnu.org; John Baboval Subject: Re: [Qemu-devel] [PATCH] Add 'maxqdepth' as an option to tty character devices. On 05/07/2013 10:51 AM, John Baboval wrote: > From: "John V. Baboval" > > This parameter will cause writes to tty backed chardevs to return > -EAGAIN if the backing tty has buffered more than the specified number > of characters. When data is sent, the TIOCOUTQ ioctl is invoked to > determine the current TTY output buffer depth. When submitting a v2 patch, please adjust the subject line to call out that it is a v2, and send it as a top-level thread rather than in-reply-to an earlier thread. For more details, see: http://wiki.qemu.org/Contribute/SubmitAPatch > +++ b/qapi-schema.json > @@ -3182,11 +3182,14 @@ > # > # @device: The name of the special file for the device, > # i.e. /dev/ttyS0 on Unix or COM1: on Windows > +# @maxqdepth: The maximum depth of the underlying tty > + output queue (Unix) > # @type: What kind of device this is. > # > # Since: 1.4 > ## > -{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } } > +{ 'type': 'ChardevHostdev', 'data': { 'device': 'str', > + 'maxqdepth' : 'int' } } You did not address any of my review concerns from v1, such as listing a (since 1.6) label or marking maxqdepth as optional. Are you sure you sent the right patch? -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org
[Qemu-devel] [PATCH v3] Add 'maxqdepth' as an option to tty character devices.
Includes changes requested by Eric Blake and Paolo Bonzini
[Qemu-devel] [PATCH] Add 'maxqdepth' as an option to tty character devices.
From: "John V. Baboval" This parameter will cause writes to tty backed chardevs to return -EAGAIN if the backing tty has buffered more than the specified number of characters. When data is sent, the TIOCOUTQ ioctl is invoked to determine the current TTY output buffer depth. Background: Some devices use DTR/DSR as flow control. (eg. Check/Receipt printers with some POS software). When the device de-asserts DTR, the guest OS notifies the application and new data is blocked. When running on a QEMU serial port backed by a TTY, though the guest stops transmitting, all the characters in the TTY output buffer are still sent. The device buffer overflows and data is lost. In this case the user could set maxqdepth=1. Signed-off-by: John Baboval --- include/sysemu/char.h |2 ++ qapi-schema.json |5 - qemu-char.c | 40 +++- qemu-options.hx |4 ++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 5e42c90..a94c1fb 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -43,6 +43,7 @@ typedef struct { #define CHR_IOCTL_SERIAL_SET_TIOCM 13 #define CHR_IOCTL_SERIAL_GET_TIOCM 14 +#define CHR_IOCTL_SERIAL_TIOCOUTQ15 #define CHR_TIOCM_CTS 0x020 #define CHR_TIOCM_CAR 0x040 @@ -77,6 +78,7 @@ struct CharDriverState { int fe_open; int explicit_fe_open; int avail_connections; +uint32_t maxqdepth; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; diff --git a/qapi-schema.json b/qapi-schema.json index 7797400..029e7c9 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3182,11 +3182,14 @@ # # @device: The name of the special file for the device, # i.e. /dev/ttyS0 on Unix or COM1: on Windows +# @maxqdepth: The maximum depth of the underlying tty + output queue (Unix) # @type: What kind of device this is. # # Since: 1.4 ## -{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } } +{ 'type': 'ChardevHostdev', 'data': { 'device': 'str', + 'maxqdepth' : 'int' } } ## # @ChardevSocket: diff --git a/qemu-char.c b/qemu-char.c index 64e824d..e2e4217 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -782,6 +782,7 @@ typedef struct FDCharDriver { GIOChannel *fd_in, *fd_out; guint fd_in_tag; int max_size; +int tiocoutq_failed; QTAILQ_ENTRY(FDCharDriver) node; } FDCharDriver; @@ -1260,6 +1261,22 @@ static CharDriverState *qemu_chr_open_pty(const char *id, return chr; } +static int tty_serial_write(CharDriverState *chr, const uint8_t *buf, int len) +{ +FDCharDriver *s = chr->opaque; +uint32_t inflight = 0; + +qemu_chr_fe_ioctl(chr, CHR_IOCTL_SERIAL_TIOCOUTQ, &inflight); +if (inflight >= chr->maxqdepth) +return -EAGAIN; + +if (inflight + len > chr->maxqdepth) { +len = chr->maxqdepth - inflight; +} + +return io_channel_send(s->fd_out, buf, len); +} + static void tty_serial_init(int fd, int speed, int parity, int data_bits, int stop_bits) { @@ -1438,6 +1455,16 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ); } break; +case CHR_IOCTL_SERIAL_TIOCOUTQ: +{ +if (!s->tiocoutq_failed) +s->tiocoutq_failed = ioctl(g_io_channel_unix_get_fd(s->fd_in), + TIOCOUTQ, arg); + +if (s->tiocoutq_failed) +*(unsigned int *)arg = 0; +} +break; default: return -ENOTSUP; } @@ -1466,6 +1493,7 @@ static CharDriverState *qemu_chr_open_tty_fd(int fd) tty_serial_init(fd, 115200, 'N', 8, 1); chr = qemu_chr_open_fd(fd, fd); +chr->chr_write = tty_serial_write; chr->chr_ioctl = tty_serial_ioctl; chr->chr_close = qemu_chr_close_tty; return chr; @@ -3172,6 +3200,8 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, } backend->serial = g_new0(ChardevHostdev, 1); backend->serial->device = g_strdup(device); +backend->serial->maxqdepth = +qemu_opt_get_number(opts, "maxqdepth", -1); } static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, @@ -3575,6 +3605,9 @@ QemuOptsList qemu_chardev_opts = { },{ .name = "size", .type = QEMU_OPT_SIZE, +},{ +.name = "maxqdepth", +.type = QEMU_OPT_NUMBER, }, { /* end of list */ } }, @@ -3653,6 +3686,7 @@ static CharDriverState *qmp_chardev_open_serial(ChardevH
Re: [Qemu-devel] [PATCH] Add 'maxqdepth' as an option to tty character devices.
Hmm. I seem to have screwed up the "In-Reply-To" on this one. Sorry about that. On 05/07/2013 12:36 PM, John Baboval wrote: From: "John V. Baboval" This parameter will cause writes to tty backed chardevs to return -EAGAIN if the backing tty has buffered more than the specified number of characters. When data is sent, the TIOCOUTQ ioctl is invoked to determine the current TTY output buffer depth. Background: Some devices use DTR/DSR as flow control. (eg. Check/Receipt printers with some POS software). When the device de-asserts DTR, the guest OS notifies the application and new data is blocked. When running on a QEMU serial port backed by a TTY, though the guest stops transmitting, all the characters in the TTY output buffer are still sent. The device buffer overflows and data is lost. In this case the user could set maxqdepth=1. Signed-off-by: John Baboval --- include/sysemu/char.h |2 ++ qapi-schema.json |5 - qemu-char.c | 40 +++- qemu-options.hx |4 ++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 5e42c90..a94c1fb 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -43,6 +43,7 @@ typedef struct { #define CHR_IOCTL_SERIAL_SET_TIOCM 13 #define CHR_IOCTL_SERIAL_GET_TIOCM 14 +#define CHR_IOCTL_SERIAL_TIOCOUTQ15 #define CHR_TIOCM_CTS 0x020 #define CHR_TIOCM_CAR 0x040 @@ -77,6 +78,7 @@ struct CharDriverState { int fe_open; int explicit_fe_open; int avail_connections; +uint32_t maxqdepth; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; diff --git a/qapi-schema.json b/qapi-schema.json index 7797400..029e7c9 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3182,11 +3182,14 @@ # # @device: The name of the special file for the device, # i.e. /dev/ttyS0 on Unix or COM1: on Windows +# @maxqdepth: The maximum depth of the underlying tty + output queue (Unix) # @type: What kind of device this is. # # Since: 1.4 ## -{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } } +{ 'type': 'ChardevHostdev', 'data': { 'device': 'str', + 'maxqdepth' : 'int' } } ## # @ChardevSocket: diff --git a/qemu-char.c b/qemu-char.c index 64e824d..e2e4217 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -782,6 +782,7 @@ typedef struct FDCharDriver { GIOChannel *fd_in, *fd_out; guint fd_in_tag; int max_size; +int tiocoutq_failed; QTAILQ_ENTRY(FDCharDriver) node; } FDCharDriver; @@ -1260,6 +1261,22 @@ static CharDriverState *qemu_chr_open_pty(const char *id, return chr; } +static int tty_serial_write(CharDriverState *chr, const uint8_t *buf, int len) +{ +FDCharDriver *s = chr->opaque; +uint32_t inflight = 0; + +qemu_chr_fe_ioctl(chr, CHR_IOCTL_SERIAL_TIOCOUTQ, &inflight); +if (inflight >= chr->maxqdepth) +return -EAGAIN; + +if (inflight + len > chr->maxqdepth) { +len = chr->maxqdepth - inflight; +} + +return io_channel_send(s->fd_out, buf, len); +} + static void tty_serial_init(int fd, int speed, int parity, int data_bits, int stop_bits) { @@ -1438,6 +1455,16 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ); } break; +case CHR_IOCTL_SERIAL_TIOCOUTQ: +{ +if (!s->tiocoutq_failed) +s->tiocoutq_failed = ioctl(g_io_channel_unix_get_fd(s->fd_in), + TIOCOUTQ, arg); + +if (s->tiocoutq_failed) +*(unsigned int *)arg = 0; +} +break; default: return -ENOTSUP; } @@ -1466,6 +1493,7 @@ static CharDriverState *qemu_chr_open_tty_fd(int fd) tty_serial_init(fd, 115200, 'N', 8, 1); chr = qemu_chr_open_fd(fd, fd); +chr->chr_write = tty_serial_write; chr->chr_ioctl = tty_serial_ioctl; chr->chr_close = qemu_chr_close_tty; return chr; @@ -3172,6 +3200,8 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, } backend->serial = g_new0(ChardevHostdev, 1); backend->serial->device = g_strdup(device); +backend->serial->maxqdepth = +qemu_opt_get_number(opts, "maxqdepth", -1); } static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, @@ -3575,6 +3605,9 @@ QemuOptsList qemu_chardev_opts = { },{ .name = "size", .type = QEMU_OPT_
[Qemu-devel] [PATCH] Add 'maxqdepth' as an option to tty character devices.
From: "John V. Baboval" This parameter will cause writes to tty backed chardevs to return -EAGAIN if the backing tty has buffered more than the specified number of characters. When data is sent, the TIOCOUTQ ioctl is invoked to determine the current TTY output buffer depth. Background: Some devices use DTR/DSR as flow control. (eg. Check/Receipt printers with some POS software). When the device de-asserts DTR, the guest OS notifies the application and new data is blocked. When running on a QEMU serial port backed by a TTY, though the guest stops transmitting, all the characters in the TTY output buffer are still sent. The device buffer overflows and data is lost. In this case the user could set maxqdepth=1. Signed-off-by: John Baboval --- include/sysemu/char.h |2 ++ qapi-schema.json |5 - qemu-char.c | 40 +++- qemu-options.hx |4 ++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 5e42c90..a94c1fb 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -43,6 +43,7 @@ typedef struct { #define CHR_IOCTL_SERIAL_SET_TIOCM 13 #define CHR_IOCTL_SERIAL_GET_TIOCM 14 +#define CHR_IOCTL_SERIAL_TIOCOUTQ15 #define CHR_TIOCM_CTS 0x020 #define CHR_TIOCM_CAR 0x040 @@ -77,6 +78,7 @@ struct CharDriverState { int fe_open; int explicit_fe_open; int avail_connections; +uint32_t maxqdepth; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; diff --git a/qapi-schema.json b/qapi-schema.json index 7797400..029e7c9 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3182,11 +3182,14 @@ # # @device: The name of the special file for the device, # i.e. /dev/ttyS0 on Unix or COM1: on Windows +# @maxqdepth: The maximum depth of the underlying tty + output queue (Unix) # @type: What kind of device this is. # # Since: 1.4 ## -{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } } +{ 'type': 'ChardevHostdev', 'data': { 'device': 'str', + 'maxqdepth' : 'int' } } ## # @ChardevSocket: diff --git a/qemu-char.c b/qemu-char.c index 64e824d..e2e4217 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -782,6 +782,7 @@ typedef struct FDCharDriver { GIOChannel *fd_in, *fd_out; guint fd_in_tag; int max_size; +int tiocoutq_failed; QTAILQ_ENTRY(FDCharDriver) node; } FDCharDriver; @@ -1260,6 +1261,22 @@ static CharDriverState *qemu_chr_open_pty(const char *id, return chr; } +static int tty_serial_write(CharDriverState *chr, const uint8_t *buf, int len) +{ +FDCharDriver *s = chr->opaque; +uint32_t inflight = 0; + +qemu_chr_fe_ioctl(chr, CHR_IOCTL_SERIAL_TIOCOUTQ, &inflight); +if (inflight >= chr->maxqdepth) +return -EAGAIN; + +if (inflight + len > chr->maxqdepth) { +len = chr->maxqdepth - inflight; +} + +return io_channel_send(s->fd_out, buf, len); +} + static void tty_serial_init(int fd, int speed, int parity, int data_bits, int stop_bits) { @@ -1438,6 +1455,16 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ); } break; +case CHR_IOCTL_SERIAL_TIOCOUTQ: +{ +if (!s->tiocoutq_failed) +s->tiocoutq_failed = ioctl(g_io_channel_unix_get_fd(s->fd_in), + TIOCOUTQ, arg); + +if (s->tiocoutq_failed) +*(unsigned int *)arg = 0; +} +break; default: return -ENOTSUP; } @@ -1466,6 +1493,7 @@ static CharDriverState *qemu_chr_open_tty_fd(int fd) tty_serial_init(fd, 115200, 'N', 8, 1); chr = qemu_chr_open_fd(fd, fd); +chr->chr_write = tty_serial_write; chr->chr_ioctl = tty_serial_ioctl; chr->chr_close = qemu_chr_close_tty; return chr; @@ -3172,6 +3200,8 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, } backend->serial = g_new0(ChardevHostdev, 1); backend->serial->device = g_strdup(device); +backend->serial->maxqdepth = +qemu_opt_get_number(opts, "maxqdepth", -1); } static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, @@ -3575,6 +3605,9 @@ QemuOptsList qemu_chardev_opts = { },{ .name = "size", .type = QEMU_OPT_SIZE, +},{ +.name = "maxqdepth", +.type = QEMU_OPT_NUMBER, }, { /* end of list */ } }, @@ -3653,6 +3686,7 @@ static CharDriverState *qmp_chardev_open_serial(ChardevH
[Qemu-devel] (no subject)
Thanks for the feedback. I've made the maxqdepth parameter optional as requested.
[Qemu-devel] [PATCH] Add 'maxqdepth' as an option to tty character devices.
From: "John V. Baboval" This parameter will cause writes to tty backed chardevs to return -EAGAIN if the backing tty has buffered more than the specified number of characters. When data is sent, the TIOCOUTQ ioctl is invoked to determine the current TTY output buffer depth. Background: Some devices use DTR/DSR as flow control. (eg. Check/Receipt printers with some POS software). When the device de-asserts DTR, the guest OS notifies the application and new data is blocked. When running on a QEMU serial port backed by a TTY, though the guest stops transmitting, all the characters in the TTY output buffer are still sent. The device buffer overflows and data is lost. In this case the user could set maxqdepth=1. Signed-off-by: John Baboval --- include/sysemu/char.h |2 ++ qapi-schema.json |5 - qemu-char.c | 40 +++- qemu-options.hx |4 ++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 5e42c90..a94c1fb 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -43,6 +43,7 @@ typedef struct { #define CHR_IOCTL_SERIAL_SET_TIOCM 13 #define CHR_IOCTL_SERIAL_GET_TIOCM 14 +#define CHR_IOCTL_SERIAL_TIOCOUTQ15 #define CHR_TIOCM_CTS 0x020 #define CHR_TIOCM_CAR 0x040 @@ -77,6 +78,7 @@ struct CharDriverState { int fe_open; int explicit_fe_open; int avail_connections; +uint32_t maxqdepth; QemuOpts *opts; QTAILQ_ENTRY(CharDriverState) next; }; diff --git a/qapi-schema.json b/qapi-schema.json index 7797400..029e7c9 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3182,11 +3182,14 @@ # # @device: The name of the special file for the device, # i.e. /dev/ttyS0 on Unix or COM1: on Windows +# @maxqdepth: The maximum depth of the underlying tty + output queue (Unix) # @type: What kind of device this is. # # Since: 1.4 ## -{ 'type': 'ChardevHostdev', 'data': { 'device' : 'str' } } +{ 'type': 'ChardevHostdev', 'data': { 'device': 'str', + 'maxqdepth' : 'int' } } ## # @ChardevSocket: diff --git a/qemu-char.c b/qemu-char.c index 64e824d..e2e4217 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -782,6 +782,7 @@ typedef struct FDCharDriver { GIOChannel *fd_in, *fd_out; guint fd_in_tag; int max_size; +int tiocoutq_failed; QTAILQ_ENTRY(FDCharDriver) node; } FDCharDriver; @@ -1260,6 +1261,22 @@ static CharDriverState *qemu_chr_open_pty(const char *id, return chr; } +static int tty_serial_write(CharDriverState *chr, const uint8_t *buf, int len) +{ +FDCharDriver *s = chr->opaque; +uint32_t inflight = 0; + +qemu_chr_fe_ioctl(chr, CHR_IOCTL_SERIAL_TIOCOUTQ, &inflight); +if (inflight >= chr->maxqdepth) +return -EAGAIN; + +if (inflight + len > chr->maxqdepth) { +len = chr->maxqdepth - inflight; +} + +return io_channel_send(s->fd_out, buf, len); +} + static void tty_serial_init(int fd, int speed, int parity, int data_bits, int stop_bits) { @@ -1438,6 +1455,16 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd, void *arg) ioctl(g_io_channel_unix_get_fd(s->fd_in), TIOCMSET, &targ); } break; +case CHR_IOCTL_SERIAL_TIOCOUTQ: +{ +if (!s->tiocoutq_failed) +s->tiocoutq_failed = ioctl(g_io_channel_unix_get_fd(s->fd_in), + TIOCOUTQ, arg); + +if (s->tiocoutq_failed) +*(unsigned int *)arg = 0; +} +break; default: return -ENOTSUP; } @@ -1466,6 +1493,7 @@ static CharDriverState *qemu_chr_open_tty_fd(int fd) tty_serial_init(fd, 115200, 'N', 8, 1); chr = qemu_chr_open_fd(fd, fd); +chr->chr_write = tty_serial_write; chr->chr_ioctl = tty_serial_ioctl; chr->chr_close = qemu_chr_close_tty; return chr; @@ -3172,6 +3200,8 @@ static void qemu_chr_parse_serial(QemuOpts *opts, ChardevBackend *backend, } backend->serial = g_new0(ChardevHostdev, 1); backend->serial->device = g_strdup(device); +backend->serial->maxqdepth = +qemu_opt_get_number(opts, "maxqdepth", -1); } static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend, @@ -3575,6 +3605,9 @@ QemuOptsList qemu_chardev_opts = { },{ .name = "size", .type = QEMU_OPT_SIZE, +},{ +.name = "maxqdepth", +.type = QEMU_OPT_NUMBER, }, { /* end of list */ } }, @@ -3653,6 +3686,7 @@ static CharDriverState *qmp_chardev_open_serial(ChardevH
Re: [Qemu-devel] Support for 1366x768 (720p) resolution?
Josh, Somehow missed this message going by. Sorry about that. The 720p support patch (and variable VRAM size) slipped off my radar. I'm going to try and get another batch of interesting patches from the XenClient Enterprise device model ready to submit in the coming weeks, and I'll add that one to the list. -John On 02/08/2013 11:35 AM, Josh Triplett wrote: Late last year, I saw a patch go by adding support for the unfortunately common 1366x768 resolution. Some discussion in the resulting thread suggested some possible improvements to the patch that needed to occur before merging; however, I haven't seen a newer version go by. Just wanted to check back about the status of that patch to make sure it didn't get lost. See also the Launchpad bug about this: https://bugs.launchpad.net/qemu/+bug/1054558 - Josh Triplett
Re: [Qemu-devel] [PATCH 1/3] Support guest reboots when in Xen HVM mode
On 11/07/2011 11:43 AM, Stefano Stabellini wrote: On Fri, 28 Oct 2011, John Baboval wrote: Call xc_domain_shutdown with the reboot flag when the guest requests a reboot. Thanks for the patch! Sorry for the delay in replaying but away for XenSummit Asia. Signed-off-by: John V. Baboval Signed-off-by: Tom Goetz --- xen-all.c | 22 ++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/xen-all.c b/xen-all.c index b5e28ab..cd71b24 100644 --- a/xen-all.c +++ b/xen-all.c @@ -742,6 +742,7 @@ static void cpu_handle_ioreq(void *opaque) } if (qemu_reset_requested_get()) { qemu_system_reset(VMRESET_REPORT); +reboot_hvm_domain(); } } @@ -979,3 +980,24 @@ void destroy_hvm_domain(void) xc_interface_close(xc_handle); } } + +void reboot_hvm_domain(void) +{ +XenXC xc_handle; +int sts; + +xc_handle = xen_xc_interface_open(0, 0, 0); +if (xc_handle == XC_HANDLER_INITIAL_VALUE) { +fprintf(stderr, "Cannot acquire xenctrl handle\n"); +} else { +sts = xc_domain_shutdown(xc_handle, xen_domid, SHUTDOWN_reboot); +if (sts != 0) { +fprintf(stderr, "? xc_domain_shutdown failed to issue reboot, " +"sts %d, %s\n", sts, strerror(errno)); +} else { +fprintf(stderr, "Issued domain %d reboot\n", xen_domid); +} +xc_interface_close(xc_handle); +} +} I think that what you are doing is correct but I couldn't help but notice that reboot_hvm_domain is very similar to destroy_hvm_domain. I would rather unify the two functions and have a single shutdown_domain function with two arguments: a reboot/destroy argument and xc_handle (we don't need to open a new one, we can reuse state->xce_handle). Are you OK with submitting a new version of this patch with these changes? Sounds good to me. I have a huge backlog of stuff to debug and test though, so it'll be a few days before I get to this.
Re: [Qemu-devel] [PATCH 1/2] Allow 1366x768 as a valid VGA resolution
This is a good idea. I'm going to re-work the patch, but I have a lot of other stuff going on too, so it may be a week or so before I get back to it. On 11/01/2011 12:57 PM, Gerd Hoffmann wrote: On 11/01/11 14:39, John Baboval wrote: I don't know of any reason for it. I'd guess it is alignment, probably not important for all color depts. Maybe it is a good idea to do all sanity checks in the VBE_DISPI_INDEX_ENABLE branch where the actual mode switch happens. Then you already know xres, yres and depth when applying the checks. You can calculate the scanline length, then check the scanline alignment instead of being overly strict on xres in high color modes to satisfy alignment requirements in low color modes. You can also simply calculate how much memory the video mode needs and check that against the configured video ram instead of pulling xres and yres limits out of thin air. cheers, Gerd
Re: [Qemu-devel] [PATCH 1/2] Allow 1366x768 as a valid VGA resolution
I don't know of any reason for it. -John On Nov 1, 2011, at 4:58 AM, "Gerd Hoffmann" wrote: > On 10/28/11 21:24, John Baboval wrote: >> 760p TV panels have a 1366x768 resolution, and have been popular >> recently as low-cost monitors. The 1366 resolution doesn't pass >> the (xres & 7) == 0 test. > > Why is it save to simply remove the test? > Guess there is a reason why it is there in the first place? > > cheers, > Gerd >
[Qemu-devel] [PATCH] IDE Debug compiler warnings
This fixes up a few compiler warnings/errors when building with IDE_DEBUG or AHCI_DEBUG enabled. Signed-off-by: John V. Baboval --- hw/ide/ahci.c |2 +- hw/ide/pci.c |2 +- hw/ide/piix.c |4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 1c7e3a0..79277bb 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -327,7 +327,7 @@ static void ahci_mem_write(void *opaque, target_phys_addr_t addr, } if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) { -DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val); +DPRINTF(-1, "(addr 0x%08X), val 0x%08lX\n", (unsigned) addr, val); switch (addr) { case HOST_CAP: /* R/WO, RO */ diff --git a/hw/ide/pci.c b/hw/ide/pci.c index f133c42..0d3f2f9 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -335,7 +335,7 @@ static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr, data = (bm->addr >> (addr * 8)) & mask; #ifdef DEBUG_IDE -printf("%s: 0x%08x\n", __func__, (unsigned)*data); +printf("%s: 0x%08x\n", __func__, (unsigned)data); #endif return data; } diff --git a/hw/ide/piix.c b/hw/ide/piix.c index 08cbbe2..3d71126 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -53,7 +53,7 @@ static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, unsigned size) break; } #ifdef DEBUG_IDE -printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val); +printf("bmdma: readb 0x%02lx : 0x%02x\n", addr, val); #endif return val; } @@ -68,7 +68,7 @@ static void bmdma_write(void *opaque, target_phys_addr_t addr, } #ifdef DEBUG_IDE -printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val); +printf("bmdma: writeb 0x%02lx : 0x%02lx\n", addr, val); #endif switch(addr & 3) { case 0: -- 1.7.4.1
[Qemu-devel] [PATCH 2/3] Xen conditionals
Don't perform RTC or APIC setup when running in xen mode. Signed-off-by: John V. Baboval --- hw/pc.c | 56 +--- hw/pc_piix.c |2 +- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index eb4c2d8..e571d38 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -40,6 +40,7 @@ #include "sysbus.h" #include "sysemu.h" #include "blockdev.h" +#include "xen.h" #include "ui/qemu-spice.h" #include "memory.h" #include "exec-memory.h" @@ -340,35 +341,36 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, static pc_cmos_init_late_arg arg; /* various important CMOS locations needed by PC/Bochs bios */ - -/* memory size */ -val = 640; /* base memory in K */ -rtc_set_memory(s, 0x15, val); -rtc_set_memory(s, 0x16, val >> 8); - -val = (ram_size / 1024) - 1024; -if (val > 65535) -val = 65535; -rtc_set_memory(s, 0x17, val); -rtc_set_memory(s, 0x18, val >> 8); -rtc_set_memory(s, 0x30, val); -rtc_set_memory(s, 0x31, val >> 8); - -if (above_4g_mem_size) { -rtc_set_memory(s, 0x5b, (unsigned int)above_4g_mem_size >> 16); -rtc_set_memory(s, 0x5c, (unsigned int)above_4g_mem_size >> 24); -rtc_set_memory(s, 0x5d, (uint64_t)above_4g_mem_size >> 32); +if (!xen_enabled()) { + /* memory size */ + val = 640; /* base memory in K */ + rtc_set_memory(s, 0x15, val); + rtc_set_memory(s, 0x16, val >> 8); + + val = (ram_size / 1024) - 1024; + if (val > 65535) + val = 65535; + rtc_set_memory(s, 0x17, val); + rtc_set_memory(s, 0x18, val >> 8); + rtc_set_memory(s, 0x30, val); + rtc_set_memory(s, 0x31, val >> 8); + + if (above_4g_mem_size) { + rtc_set_memory(s, 0x5b, (unsigned int)above_4g_mem_size >> 16); + rtc_set_memory(s, 0x5c, (unsigned int)above_4g_mem_size >> 24); + rtc_set_memory(s, 0x5d, (uint64_t)above_4g_mem_size >> 32); + } + + if (ram_size > (16 * 1024 * 1024)) + val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536); + else + val = 0; + if (val > 65535) + val = 65535; + rtc_set_memory(s, 0x34, val); + rtc_set_memory(s, 0x35, val >> 8); } -if (ram_size > (16 * 1024 * 1024)) -val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536); -else -val = 0; -if (val > 65535) -val = 65535; -rtc_set_memory(s, 0x34, val); -rtc_set_memory(s, 0x35, val >> 8); - /* set the number of CPU */ rtc_set_memory(s, 0x5f, smp_cpus - 1); diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 8c7f2b7..f91658c 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -162,7 +162,7 @@ static void pc_init1(MemoryRegion *system_memory, for (i = 0; i < ISA_NUM_IRQS; i++) { gsi_state->i8259_irq[i] = i8259[i]; } -if (pci_enabled) { +if (pci_enabled && !xen_enabled()) { ioapic_init(gsi_state); } -- 1.7.4.1
[Qemu-devel] [PATCH 3/3] piix4 acpi xen support
When in xen mode, handle the view of pm ioport appropriately. I'm not entirely comfortable with this patch, since it relies on values that are hard coded into the DSDT that is shipped with Xen. There has to be a better way to handle it, but I haven't thought of what that might be yet... Perhaps there should be an acpi_xen.c. Or perhaps the Xen table should be modified to match the device model. Or perhaps there is a good way to match them up dynamically. Signed-off-by: John V. Baboval Signed-off-by: Tom Goetz --- hw/acpi_piix4.c | 82 +-- 1 files changed, 73 insertions(+), 9 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 29f0f76..277ae9f 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -24,6 +24,7 @@ #include "sysemu.h" #include "range.h" #include "ioport.h" +#include "xen.h" //#define DEBUG @@ -111,6 +112,35 @@ static void pm_ioport_write(IORange *ioport, uint64_t addr, unsigned width, (unsigned)addr, width, (unsigned)val); } +if (xen_enabled()) { +/* + * Only the PM control register is emulated in Qemu under Xen. The + * remaining registers are emulated by the hypervisor. + */ +int sus_typ; +s->pm1_cnt.cnt = val & ~(ACPI_BITMASK_SLEEP_ENABLE); +if (val & ACPI_BITMASK_SLEEP_ENABLE) { +/* change suspend type */ +sus_typ = (val >> 10) & 7; +switch(sus_typ) { +case 6: /* soft power off */ +case 7: /* soft power off */ +qemu_system_shutdown_request(); +break; +case 5: +/* ACPI_BITMASK_WAKE_STATUS should be set on resume. + Pretend that resume was caused by power button */ +qemu_system_reset_request(); +if (s->pm1_cnt.cmos_s3) { +qemu_irq_raise(s->pm1_cnt.cmos_s3); +} +default: +break; +} +} +return; +} + switch(addr) { case 0x00: acpi_pm1_evt_write_sts(&s->pm1a, &s->tmr, val); @@ -136,6 +166,15 @@ static void pm_ioport_read(IORange *ioport, uint64_t addr, unsigned width, PIIX4PMState *s = container_of(ioport, PIIX4PMState, ioport); uint32_t val; +if (xen_enabled()) { +/* + * Only the PM control register is emulated in Qemu under Xen. The + * remaining registers are emulated by the hypervisor. + */ +val = s->pm1_cnt.cnt; +return; +} + switch(addr) { case 0x00: val = acpi_pm1_evt_get_sts(&s->pm1a, s->tmr.overflow_time); @@ -181,19 +220,28 @@ static void acpi_dbg_writel(void *opaque, uint32_t addr, uint32_t val) PIIX4_DPRINTF("ACPI: DBG: 0x%08x\n", val); } +#define PMCNTRL 0x04 static void pm_io_space_update(PIIX4PMState *s) { -uint32_t pm_io_base; +uint32_t pm_io_base, size; + +if (!(s->dev.config[0x80] & 1) && !xen_enabled()) { +return; +} -if (s->dev.config[0x80] & 1) { -pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40)); -pm_io_base &= 0xffc0; +pm_io_base = le32_to_cpu(*(uint32_t *)(s->dev.config + 0x40)); +pm_io_base &= 0xffc0; +size = 16; -/* XXX: need to improve memory and ioport allocation */ -PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base); -iorange_init(&s->ioport, &pm_iorange_ops, pm_io_base, 64); -ioport_register(&s->ioport); +if (xen_enabled()) { +size = 2; +pm_io_base += PMCNTRL; } + +/* XXX: need to improve memory and ioport allocation */ +PIIX4_DPRINTF("PM: mapping to 0x%x\n", pm_io_base); +iorange_init(&s->ioport, &pm_iorange_ops, pm_io_base, size); +ioport_register(&s->ioport); } static void pm_write_config(PCIDevice *d, @@ -326,6 +374,13 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) } +#definePIIX4_BASE_IOADDR 0x1f40 +#definePIIX4_BASE_IOADDR_LO((PIIX4_BASE_IOADDR) & 0xff) +#definePIIX4_BASE_IOADDR_HI((PIIX4_BASE_IOADDR)>>8) + +/* PM1a_CNT bits, as defined in the ACPI specification. */ +#define SCI_EN(1 << 0) + static int piix4_pm_initfn(PCIDevice *dev) { PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev); @@ -337,7 +392,13 @@ static int piix4_pm_initfn(PCIDevice *dev) pci_conf[0x09] = 0x00; pci_conf[0x3d] = 0x01; // interrupt pin 1 -pci_conf[0x40] = 0x01; /* PM io base read only bit */ +if (!xen_enabled()) { +pci_conf[0x40] = 0x01; /* PM io base read only bit */ +} else { +pci_conf[0x40] = PIIX4_BASE_IOADDR_LO | 0x01; /* Special device-specific BAR at 0x40 */ +pci_conf[0x41] = PIIX4_BASE_IOADDR_HI; +s->pm1_cnt.cnt = SCI_EN; +} /* APM */ apm_init(&s->apm, apm_ctrl_changed, s); @@ -369,6 +430,9 @@ static int piix4_pm_initfn(PCIDevice *dev) qemu_register_reset(piix4_r
[Qemu-devel] [PATCH 1/3] Support guest reboots when in Xen HVM mode
Call xc_domain_shutdown with the reboot flag when the guest requests a reboot. Signed-off-by: John V. Baboval Signed-off-by: Tom Goetz --- xen-all.c | 22 ++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/xen-all.c b/xen-all.c index b5e28ab..cd71b24 100644 --- a/xen-all.c +++ b/xen-all.c @@ -742,6 +742,7 @@ static void cpu_handle_ioreq(void *opaque) } if (qemu_reset_requested_get()) { qemu_system_reset(VMRESET_REPORT); +reboot_hvm_domain(); } } @@ -979,3 +980,24 @@ void destroy_hvm_domain(void) xc_interface_close(xc_handle); } } + +void reboot_hvm_domain(void) +{ +XenXC xc_handle; +int sts; + +xc_handle = xen_xc_interface_open(0, 0, 0); +if (xc_handle == XC_HANDLER_INITIAL_VALUE) { +fprintf(stderr, "Cannot acquire xenctrl handle\n"); +} else { +sts = xc_domain_shutdown(xc_handle, xen_domid, SHUTDOWN_reboot); +if (sts != 0) { +fprintf(stderr, "? xc_domain_shutdown failed to issue reboot, " +"sts %d, %s\n", sts, strerror(errno)); +} else { +fprintf(stderr, "Issued domain %d reboot\n", xen_domid); +} +xc_interface_close(xc_handle); +} +} + -- 1.7.4.1
[Qemu-devel] [PATCH 0/3] Xen related patches
These are some xen related patches that have been sitting around in are queue waiting for us to re-base onto a modern qemu. Now that we're up-to-date, they're ready to share with the list. They are all things that enable successfully running windows in xen HVM guests. Support guest reboots when in Xen HVM mode Xen conditionals piix4 acpi xen support -John
[Qemu-devel] [PATCH 2/2] Variable VRAM size
High resolution VGA modes require more than the default 8MB of VGA RAM. Add a command line parameter to allow larger sizes. Signed-off-by: John V. Baboval --- hw/vga.c| 64 ++ hw/vga_int.h|4 +++ qemu-options.hx |3 ++ vl.c|4 +++ 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/hw/vga.c b/hw/vga.c index ca79aa1..8003eda 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -565,23 +565,76 @@ static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr) return val; } +typedef struct vga_ram_info { + int max_xres; + int max_yres; + int max_bpp; +} vga_ram_info_t; + +static vga_ram_info_t vbe_ram_info(int ramsize) +{ +vga_ram_info_t s; +s.max_bpp = 32; + +switch(ramsize) { +case 8 * 1024 * 1024: +s.max_xres = 1920; +s.max_yres = 1080; +break; +case 16 * 1024 * 1024: +s.max_xres = 2560; +s.max_yres = 1600; +break; +default: +case 32 * 1024 * 1024: +s.max_xres = 2560; +s.max_yres = 2048; +break; +} +return s; +} + +static int vga_ram_sz = VGA_RAM_SIZE; +void set_vga_ram_size(int size) +{ +const char *msg = NULL; + +if (size < 8) +msg = "is too small"; +else if (size > 512) +msg = "is too large"; +else if (size != (size & ~(size - 1))) +msg = "is not a power of 2"; +if (msg) { +fprintf(stderr, "VGA RAM size %d %s\n", size, msg); +exit(1); +} +vga_ram_sz = size * 1024 * 1024; +} + +int vga_ram_size(void) +{ +return vga_ram_sz; +} + static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr) { VGACommonState *s = opaque; uint32_t val; +vga_ram_info_t vs = vbe_ram_info(s->vram_size); if (s->vbe_index < VBE_DISPI_INDEX_NB) { if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_GETCAPS) { switch(s->vbe_index) { /* XXX: do not hardcode ? */ case VBE_DISPI_INDEX_XRES: -val = VBE_DISPI_MAX_XRES; +val = vs.max_xres; break; case VBE_DISPI_INDEX_YRES: -val = VBE_DISPI_MAX_YRES; +val = vs.max_yres; break; case VBE_DISPI_INDEX_BPP: -val = VBE_DISPI_MAX_BPP; +val = vs.max_bpp; break; default: val = s->vbe_regs[s->vbe_index]; @@ -610,6 +663,7 @@ static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val) static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) { VGACommonState *s = opaque; +vga_ram_info_t vs = vbe_ram_info(s->vram_size); if (s->vbe_index <= VBE_DISPI_INDEX_NB) { #ifdef DEBUG_BOCHS_VBE @@ -626,12 +680,12 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) } break; case VBE_DISPI_INDEX_XRES: -if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) { +if ((val <= vs.max_xres) && ((val & 7) == 0)) { s->vbe_regs[s->vbe_index] = val; } break; case VBE_DISPI_INDEX_YRES: -if (val <= VBE_DISPI_MAX_YRES) { +if (val <= vs.max_yres) { s->vbe_regs[s->vbe_index] = val; } break; diff --git a/hw/vga_int.h b/hw/vga_int.h index c1e700f..3864fba 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -24,6 +24,7 @@ #include #include "memory.h" +#include "console.h" #define MSR_COLOR_EMULATION 0x01 #define MSR_PAGE_SELECT 0x20 @@ -224,6 +225,9 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *address_space); extern const uint8_t sr_mask[8]; extern const uint8_t gr_mask[16]; +void set_vga_ram_size(int size); +int vga_ram_size(void); + #define VGA_RAM_SIZE (8192 * 1024) #define VGABIOS_FILENAME "vgabios.bin" #define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin" diff --git a/qemu-options.hx b/qemu-options.hx index 5d2a776..00177f3 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -896,6 +896,9 @@ Disable VGA card. @end table ETEXI +DEF("vga-mem", HAS_ARG, QEMU_OPTION_vga_ram_size, + "-vga-mem megs set virtual FB size to megs MB\n", QEMU_ARCH_ALL) + DEF("full-screen", 0, QEMU_OPTION_full_screen, "-full-screenstart in full screen\n", QEMU_ARCH_ALL) STEXI diff --git a/vl.c b/vl.c index 1ddb17b..66277d6 100644 --- a/vl.c +++ b/vl.c @@ -126,6 +126,7 @@ int main(int argc, char **argv) #include "hw/xen.h" #include "hw/qdev.h" #include "hw/loader.h" +#include "hw/vga_int.h" #include "bt-host.h" #include "net.h" #include "net/slirp.h" @@ -2585,6 +2586,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_vga: select_vgahw (optarg); break; +case QEMU_OPTION_vga_ram_size: +
[Qemu-devel] [PATCH 0/2] VGA related patches
This is a pair of VGA related patches. The first allows the use of a 1366x768 VGA resolution. The second allows the user to specify an alternate VRAM size with a command line parameter. -John
[Qemu-devel] [PATCH 1/2] Allow 1366x768 as a valid VGA resolution
760p TV panels have a 1366x768 resolution, and have been popular recently as low-cost monitors. The 1366 resolution doesn't pass the (xres & 7) == 0 test. Signed-off-by: John V. Baboval --- hw/vga.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/vga.c b/hw/vga.c index 8003eda..f12a371 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -680,7 +680,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) } break; case VBE_DISPI_INDEX_XRES: -if ((val <= vs.max_xres) && ((val & 7) == 0)) { +if (val <= vs.max_xres) { s->vbe_regs[s->vbe_index] = val; } break; -- 1.7.4.1
Re: [Qemu-devel] New Memory API Question
So I've figured out the answer to my own question... I was, in fact, missing something. The destructor for the subregion is not overwritten. It's the parent region's destructor that is written. On 10/26/2011 09:52 AM, John Baboval wrote: Sorry for coming late to the party on this... I only read qemu-devel through a filter so I missed all the discussions on the new memory API. I have a question as to how it works and how it's supposed to work in certain scenarios. It's a question of flow. I'm following the code path through the creation of a new memory subregion. If I'm reading this properly, it would seem that a MemoryRegion - for example the ones used by VGA - go through the following flow: memory_region_init_ram() - (mr->destructor is set to memory_region_destructor_ram) memory_region_add_subregion(system_memory, ...) -> memory_region_update_topology() -> address_space_update_topology() address_space_update_topology_part() as_memory_range_add() - through the ops vector memory_region_prepare_ram_addr() At this point it seems that the destructor is overwritten with the memory_region_destructor_iomem(), and it loses track of the proper way to ever free the memory region. Is this correct, or am I missing something? Or does it not matter because nobody ever calls memory_region_destroy for system memory regions? Thanks, -John
[Qemu-devel] New Memory API Question
Sorry for coming late to the party on this... I only read qemu-devel through a filter so I missed all the discussions on the new memory API. I have a question as to how it works and how it's supposed to work in certain scenarios. It's a question of flow. I'm following the code path through the creation of a new memory subregion. If I'm reading this properly, it would seem that a MemoryRegion - for example the ones used by VGA - go through the following flow: memory_region_init_ram() - (mr->destructor is set to memory_region_destructor_ram) memory_region_add_subregion(system_memory, ...) -> memory_region_update_topology() -> address_space_update_topology() address_space_update_topology_part() as_memory_range_add() - through the ops vector memory_region_prepare_ram_addr() At this point it seems that the destructor is overwritten with the memory_region_destructor_iomem(), and it loses track of the proper way to ever free the memory region. Is this correct, or am I missing something? Or does it not matter because nobody ever calls memory_region_destroy for system memory regions? Thanks, -John
Re: [Qemu-devel] [PATCH] v6 revamp acpitable parsing and allow to specify complete (headerful) table
Thanks. Somehow completely missed Blue's response back on the 15th. Glad to see this in. When using this for SLIC I had to patch the OEM ID fields in the other tables to match at runtime in order to make windows licensing happy. But thats a BIOS change, not something in QEMU On Jul 30, 2011, at 2:41 AM, "Blue Swirl" wrote: > Thanks, applied. > > On Fri, Jul 29, 2011 at 4:49 AM, Isaku Yamahata > wrote: >> On Fri, Jul 15, 2011 at 07:51:43PM +0300, Blue Swirl wrote: >>> On Fri, Jul 15, 2011 at 6:18 PM, John Baboval >>> wrote: >>>> Is there something I can do to help take this patch the rest of the way? >>>> >>>> I'd hate to see it die because of a style issue and a compiler warning. >>> >>> There's also suspicious missing 'break' statement. How about fixing >>> the issues and submitting the patch? >> >> I fixed the compile error. >> I think the missing break is intentional, so added an comment there. Michael? >> Blue, can you please take a look of it? >> >> >> From 9a5e4158074ea251ab064a946927bcaf861f5c1e Mon Sep 17 00:00:00 2001 >> Message-Id: >> <9a5e4158074ea251ab064a946927bcaf861f5c1e.1311903724.git.yamah...@valinux.co.jp> >> From: Michael Tokarev >> Date: Thu, 12 May 2011 18:44:17 +0400 >> Subject: [PATCH] revamp acpitable parsing and allow to specify complete >> (headerful) table >> >> From Michael Tokarev >> >> This patch almost rewrites acpi_table_add() function >> (but still leaves it using old get_param_value() interface). >> The result is that it's now possible to specify whole table >> (together with a header) in an external file, instead of just >> data portion, with a new file= parameter, but at the same time >> it's still possible to specify header fields as before. >> >> Now with the checkpatch.pl formatting fixes, thanks to >> Stefan Hajnoczi for suggestions, with changes from >> Isaku Yamahata, and with my further refinements. >> >> Signed-off-by: Michael Tokarev >> Cc:: Isaku Yamahata >> Cc: John Baboval >> Cc: Blue Swirl >> >> --- >> v5: rediffed against current qemu/master. >> v6: fix one "} else {" coding style defect (noted by Blue Swirl) >> v7: style fix and added an comment for suspicious break >>I think that the missing break of case 0 is intentional. >>I added the fallthrough comment there. >> --- >> hw/acpi.c | 298 >> --- >> qemu-options.hx |7 +- >> 2 files changed, 178 insertions(+), 127 deletions(-) >> >> diff --git a/hw/acpi.c b/hw/acpi.c >> index ad40fb4..79ec66c 100644 >> --- a/hw/acpi.c >> +++ b/hw/acpi.c >> @@ -20,19 +20,30 @@ >> #include "pc.h" >> #include "acpi.h" >> >> -struct acpi_table_header >> -{ >> -char signature [4];/* ACPI signature (4 ASCII characters) */ >> +struct acpi_table_header { >> +uint16_t _length; /* our length, not actual part of the hdr */ >> + /* XXX why we have 2 length fields here? */ >> +char sig[4]; /* ACPI signature (4 ASCII characters) */ >> uint32_t length; /* Length of table, in bytes, including header >> */ >> uint8_t revision; /* ACPI Specification minor version # */ >> uint8_t checksum; /* To make sum of entire table == 0 */ >> -char oem_id [6]; /* OEM identification */ >> -char oem_table_id [8]; /* OEM table identification */ >> +char oem_id[6]; /* OEM identification */ >> +char oem_table_id[8]; /* OEM table identification */ >> uint32_t oem_revision;/* OEM revision number */ >> -char asl_compiler_id [4]; /* ASL compiler vendor ID */ >> +char asl_compiler_id[4]; /* ASL compiler vendor ID */ >> uint32_t asl_compiler_revision; /* ASL compiler revision number */ >> } __attribute__((packed)); >> >> +#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header) >> +#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */ >> + >> +static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] = >> +"\0\0" /* fake _length (2) */ >> +"QEMU\0\0\0\0\1\0" /* sig (4), len(4), revno (1), csum (1) */ >> +"QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */ >> +"QEMU\1\0\0\0" /* ASL compiler ID (4), version (4) */ >>
Re: [Qemu-devel] [PATCH] v6 revamp acpitable parsing and allow to specify complete (headerful) table
Is there something I can do to help take this patch the rest of the way? I'd hate to see it die because of a style issue and a compiler warning. -John On 06/15/2011 02:19 PM, Blue Swirl wrote: On Sat, Jun 11, 2011 at 1:29 AM, Michael Tokarev wrote: I've given up on this one. Personally I don't need this stuff for my win7 guests since I can hack either bios or the O/S loader to include all the necessary verifications for the win7 activation to work. I tried to make this process to be legal (no hacks or "cracks" needed) and easy for others, but since noone is interested in this after 6 versions and 5 resends, I wont continue - what I am trying to achieve by pushing this so hard, after all? Thanks to everyone who gave (mostly code style) comments - at least I know the changes has been read by someone. Frustrated, Sorry about that. I get this error: /src/qemu/hw/acpi.c: In function 'acpi_table_add': /src/qemu/hw/acpi.c:167: error: format '%u' expects type 'unsigned int', but argument 4 has type 'size_t' /mjt 12.05.2011 18:44, Michael Tokarev wrote: This patch almost rewrites acpi_table_add() function (but still leaves it using old get_param_value() interface). The result is that it's now possible to specify whole table (together with a header) in an external file, instead of just data portion, with a new file= parameter, but at the same time it's still possible to specify header fields as before. Now with the checkpatch.pl formatting fixes, thanks to Stefan Hajnoczi for suggestions, with changes from Isaku Yamahata, and with my further refinements. v5: rediffed against current qemu/master. v6: fix one "} else {" coding style defect (noted by Blue Swirl) Signed-off-by: Michael Tokarev --- hw/acpi.c | 292 --- qemu-options.hx |7 +- 2 files changed, 175 insertions(+), 124 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index ad40fb4..4316189 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -22,17 +22,29 @@ struct acpi_table_header { -char signature [4];/* ACPI signature (4 ASCII characters) */ +uint16_t _length; /* our length, not actual part of the hdr */ + /* XXX why we have 2 length fields here? */ +char sig[4]; /* ACPI signature (4 ASCII characters) */ uint32_t length; /* Length of table, in bytes, including header */ uint8_t revision; /* ACPI Specification minor version # */ uint8_t checksum; /* To make sum of entire table == 0 */ -char oem_id [6]; /* OEM identification */ -char oem_table_id [8]; /* OEM table identification */ +char oem_id[6]; /* OEM identification */ +char oem_table_id[8]; /* OEM table identification */ uint32_t oem_revision;/* OEM revision number */ -char asl_compiler_id [4]; /* ASL compiler vendor ID */ +char asl_compiler_id[4]; /* ASL compiler vendor ID */ uint32_t asl_compiler_revision; /* ASL compiler revision number */ } __attribute__((packed)); +#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header) +#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */ + +static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] = +"\0\0" /* fake _length (2) */ +"QEMU\0\0\0\0\1\0" /* sig (4), len(4), revno (1), csum (1) */ +"QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */ +"QEMU\1\0\0\0" /* ASL compiler ID (4), version (4) */ +; + char *acpi_tables; size_t acpi_tables_len; @@ -45,158 +57,192 @@ static int acpi_checksum(const uint8_t *data, int len) return (-sum)& 0xff; } +/* like strncpy() but zero-fills the tail of destination */ +static void strzcpy(char *dst, const char *src, size_t size) +{ +size_t len = strlen(src); +if (len>= size) { +len = size; +} else { + memset(dst + len, 0, size - len); +} +memcpy(dst, src, len); +} + +/* XXX fixme: this function uses obsolete argument parsing interface */ int acpi_table_add(const char *t) { -static const char *dfl_id = "QEMUQEMU"; char buf[1024], *p, *f; -struct acpi_table_header acpi_hdr; unsigned long val; -uint32_t length; -struct acpi_table_header *acpi_hdr_p; -size_t off; +size_t len, start, allen; +bool has_header; +int changed; +int r; +struct acpi_table_header hdr; + +r = 0; +r |= get_param_value(buf, sizeof(buf), "data", t) ? 1 : 0; +r |= get_param_value(buf, sizeof(buf), "file", t) ? 2 : 0; +switch (r) { +case 0: +buf[0] = '\0'; Missing 'break' or comment about fall through. +case 1: +has_header = false; +break; +case 2: +has_header = true; +break; +default: +fprintf(stderr, "acpitable: both data and file are specified\n"); +return -1; +} + +if (!acpi_tables) { +allen = sizeof(uint16_t); +
Re: [Qemu-devel] Upstream Qemu With Xen configuration problem
I find I have to point at the src directories, and not the dist directory. My extra-cflags looks something like this: --extra-cflags=-I /path/to/xen/tools/include -L /path/to/xen/tools/libxc -I /path/to/xen/tools/libxc -L /path/to/xen/tools/xenstore -I /path/to/xen/tools/xenstore' -John On 07/07/2011 01:17 PM, Daniel Castro wrote: Greetings, I am trying to configure Xen4.2 unstable with upstream qemu. I am running on a small problem when running the configuration of qemu, Qemu Config can not find Xen. I have debugged the Configuration script and the temp c file that qemu uses to detect xen version are returning empty string, hence the config script can tell xen version. Xen with staging branch works fine. My configure call is as follows: ./configure --enable-xen --target-list=i386-softmmu --extra-cflags="-I/usr/src/xen-unstable.hg/dist/install/usr/include" --extra-ldflags="-L/usr/src/xen-unstable.hg/dist/install/usr/lib" --enable-debug The contents of /usr/src/xen-unstable.hg/dist/install/usr/include are: blktaplib.h libxl.h temp.c xenguest.hxs_lib.h fsimage_grub.h_libxl_types.h xen xenstat.h fsimage.h libxl_utils.h xenctrl.h xentoollog.h fsimage_plugin.h libxl_uuid.hxenctrlosdep.h xs.h The contents of /usr/src/xen-unstable.hg/dist/install/usr/lib are: python2.7 xen Qemu is on master branch 744d3644181ddb16ef5944a0f9217e46961c8c84 "pxa2xx_lcd: add proper rotation support" Xen is on unstable branch 23608:2f63562df1c4 "libxl: Do not SEGV when no 'removable' disk parameter in xenstore" I can change xen changeset freely, but I can not change qemu changeset since I need some features present in qemu. Any help, or pointers are greatly appreciated. Thanks for your time, Daniel
Re: [Qemu-devel] [PATCH] v6 revamp acpitable parsing and allow to specify complete (headerful) table
Sorry for coming late to this thread. I've tested this patch, after fixing the format specifier, and it works. (Though I did test with Xen, and not KVM.) It's quite convenient. I'm planning on including it in the build we ship with our product. It would be nice to see the style issues cleaned up and this to make it into the tree. -John On 06/15/2011 02:19 PM, Blue Swirl wrote: On Sat, Jun 11, 2011 at 1:29 AM, Michael Tokarev wrote: I've given up on this one. Personally I don't need this stuff for my win7 guests since I can hack either bios or the O/S loader to include all the necessary verifications for the win7 activation to work. I tried to make this process to be legal (no hacks or "cracks" needed) and easy for others, but since noone is interested in this after 6 versions and 5 resends, I wont continue - what I am trying to achieve by pushing this so hard, after all? Thanks to everyone who gave (mostly code style) comments - at least I know the changes has been read by someone. Frustrated, Sorry about that. I get this error: /src/qemu/hw/acpi.c: In function 'acpi_table_add': /src/qemu/hw/acpi.c:167: error: format '%u' expects type 'unsigned int', but argument 4 has type 'size_t' /mjt 12.05.2011 18:44, Michael Tokarev wrote: This patch almost rewrites acpi_table_add() function (but still leaves it using old get_param_value() interface). The result is that it's now possible to specify whole table (together with a header) in an external file, instead of just data portion, with a new file= parameter, but at the same time it's still possible to specify header fields as before. Now with the checkpatch.pl formatting fixes, thanks to Stefan Hajnoczi for suggestions, with changes from Isaku Yamahata, and with my further refinements. v5: rediffed against current qemu/master. v6: fix one "} else {" coding style defect (noted by Blue Swirl) Signed-off-by: Michael Tokarev --- hw/acpi.c | 292 --- qemu-options.hx |7 +- 2 files changed, 175 insertions(+), 124 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index ad40fb4..4316189 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -22,17 +22,29 @@ struct acpi_table_header { -char signature [4];/* ACPI signature (4 ASCII characters) */ +uint16_t _length; /* our length, not actual part of the hdr */ + /* XXX why we have 2 length fields here? */ +char sig[4]; /* ACPI signature (4 ASCII characters) */ uint32_t length; /* Length of table, in bytes, including header */ uint8_t revision; /* ACPI Specification minor version # */ uint8_t checksum; /* To make sum of entire table == 0 */ -char oem_id [6]; /* OEM identification */ -char oem_table_id [8]; /* OEM table identification */ +char oem_id[6]; /* OEM identification */ +char oem_table_id[8]; /* OEM table identification */ uint32_t oem_revision;/* OEM revision number */ -char asl_compiler_id [4]; /* ASL compiler vendor ID */ +char asl_compiler_id[4]; /* ASL compiler vendor ID */ uint32_t asl_compiler_revision; /* ASL compiler revision number */ } __attribute__((packed)); +#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header) +#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t) /* size of the extra prefix */ + +static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] = +"\0\0" /* fake _length (2) */ +"QEMU\0\0\0\0\1\0" /* sig (4), len(4), revno (1), csum (1) */ +"QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */ +"QEMU\1\0\0\0" /* ASL compiler ID (4), version (4) */ +; + char *acpi_tables; size_t acpi_tables_len; @@ -45,158 +57,192 @@ static int acpi_checksum(const uint8_t *data, int len) return (-sum)& 0xff; } +/* like strncpy() but zero-fills the tail of destination */ +static void strzcpy(char *dst, const char *src, size_t size) +{ +size_t len = strlen(src); +if (len>= size) { +len = size; +} else { + memset(dst + len, 0, size - len); +} +memcpy(dst, src, len); +} + +/* XXX fixme: this function uses obsolete argument parsing interface */ int acpi_table_add(const char *t) { -static const char *dfl_id = "QEMUQEMU"; char buf[1024], *p, *f; -struct acpi_table_header acpi_hdr; unsigned long val; -uint32_t length; -struct acpi_table_header *acpi_hdr_p; -size_t off; +size_t len, start, allen; +bool has_header; +int changed; +int r; +struct acpi_table_header hdr; + +r = 0; +r |= get_param_value(buf, sizeof(buf), "data", t) ? 1 : 0; +r |= get_param_value(buf, sizeof(buf), "file", t) ? 2 : 0; +switch (r) { +case 0: +buf[0] = '\0'; Missing 'break' or comment about fall through. +case 1: +has_header = false; +break; +case 2: +has_header = true; +
Re: [Qemu-devel] [PATCH V11 11/15] Introduce qemu_put_ram_ptr
This seems to leak entries on the map cache locked entries list. Patch below: Signed-off-by: John Baboval --- exec.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/exec.c b/exec.c index 1f88d6a..f18cb7d 100644 --- a/exec.c +++ b/exec.c @@ -3759,9 +3759,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, } } else { /* RAM case */ -ptr = qemu_get_ram_ptr(pd& TARGET_PAGE_MASK) + -(addr& ~TARGET_PAGE_MASK); -memcpy(buf, ptr, l); +ptr = qemu_get_ram_ptr(pd& TARGET_PAGE_MASK); +memcpy(buf, ptr + (addr& ~TARGET_PAGE_MASK), l); qemu_put_ram_ptr(ptr); } } -- 1.7.0.4 On 03/01/2011 01:35 PM, anthony.per...@citrix.com wrote: From: Anthony PERARD This function allows to unlock a ram_ptr give by qemu_get_ram_ptr. After a call to qemu_put_ram_ptr, the pointer may be unmap from QEMU when used with Xen. Signed-off-by: Anthony PERARD Acked-by: Alexander Graf --- cpu-common.h |1 + exec.c | 10 ++ xen-mapcache.c | 34 ++ 3 files changed, 45 insertions(+), 0 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index 54d21d4..1f1c886 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -55,6 +55,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr); /* Same but slower, to use for migration, where the order of * RAMBlocks must not change. */ void *qemu_safe_ram_ptr(ram_addr_t addr); +void qemu_put_ram_ptr(void *addr); /* This should not be used by devices. */ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr); ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr); diff --git a/exec.c b/exec.c index 558595a..3f3caaa 100644 --- a/exec.c +++ b/exec.c @@ -3007,6 +3007,13 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) return NULL; } +void qemu_put_ram_ptr(void *addr) +{ +if (xen_mapcache_enabled()) { +qemu_map_cache_unlock(addr); +} +} + int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr) { RAMBlock *block; @@ -3722,6 +3729,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, cpu_physical_memory_set_dirty_flags( addr1, (0xff& ~CODE_DIRTY_FLAG)); } +qemu_put_ram_ptr(ptr); } } else { if ((pd& ~TARGET_PAGE_MASK)> IO_MEM_ROM&& @@ -3752,6 +3760,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, ptr = qemu_get_ram_ptr(pd& TARGET_PAGE_MASK) + (addr& ~TARGET_PAGE_MASK); memcpy(buf, ptr, l); +qemu_put_ram_ptr(ptr); } } len -= l; @@ -3792,6 +3801,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, /* ROM/RAM case */ ptr = qemu_get_ram_ptr(addr1); memcpy(ptr, buf, l); +qemu_put_ram_ptr(ptr); } len -= l; buf += l; diff --git a/xen-mapcache.c b/xen-mapcache.c index d7f44a7..6398456 100644 --- a/xen-mapcache.c +++ b/xen-mapcache.c @@ -195,6 +195,40 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u return mapcache->last_address_vaddr + address_offset; } +void qemu_map_cache_unlock(void *buffer) +{ +MapCacheEntry *entry = NULL, *pentry = NULL; +MapCacheRev *reventry; +target_phys_addr_t paddr_index; +int found = 0; + +QTAILQ_FOREACH(reventry,&mapcache->locked_entries, next) { +if (reventry->vaddr_req == buffer) { +paddr_index = reventry->paddr_index; +found = 1; +break; +} +} +if (!found) { +return; +} +QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next); +qemu_free(reventry); + +entry =&mapcache->entry[paddr_index % mapcache->nr_buckets]; +while (entry&& entry->paddr_index != paddr_index) { +pentry = entry; +entry = entry->next; +} +if (!entry) { +return; +} +entry->lock--; +if (entry->lock> 0) { +entry->lock--; +} +} + ram_addr_t qemu_ram_addr_from_mapcache(void *ptr) { MapCacheRev *reventry;