diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-03-08 09:47:55 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-03-08 09:47:55 +0000 |
commit | 033c7ddf86fe4315069ac4cf3cfab9bc6035dee7 (patch) | |
tree | 9a0fcb113fc5ce223b2b1fcc2596b004571c0d35 | |
parent | b6d527fbc0b64a2ba7d83623e47b05c745b88043 (diff) | |
parent | 7c6044a94e52db8aef9a71d616c7a0914adb71ab (diff) |
Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20150304-1' into staging
misc spice/qxl fixes.
# gpg: Signature made Wed Mar 4 13:57:42 2015 GMT using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg: aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>"
* remotes/spice/tags/pull-spice-20150304-1:
hmp: info spice: take out webdav
hmp: info spice: Show string channel name
qxl: drop update_displaychangelistener call for secondary qxl devices
vga: refactor vram_size clamping and rounding
qxl: refactor rounding up to a nearest power of 2
spice: fix invalid memory access to vga.vram
qxl: document minimal video memory for new modes
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hmp.c | 32 | ||||
-rw-r--r-- | hw/display/qxl.c | 35 | ||||
-rw-r--r-- | hw/display/vga.c | 22 | ||||
-rw-r--r-- | include/qemu-common.h | 3 | ||||
-rw-r--r-- | util/cutils.c | 14 |
5 files changed, 80 insertions, 26 deletions
@@ -29,6 +29,10 @@ #include "block/qapi.h" #include "qemu-io.h" +#ifdef CONFIG_SPICE +#include <spice/enums.h> +#endif + static void hmp_handle_error(Monitor *mon, Error **errp) { assert(errp); @@ -545,6 +549,25 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict) { SpiceChannelList *chan; SpiceInfo *info; + const char *channel_name; + const char * const channel_names[] = { + [SPICE_CHANNEL_MAIN] = "main", + [SPICE_CHANNEL_DISPLAY] = "display", + [SPICE_CHANNEL_INPUTS] = "inputs", + [SPICE_CHANNEL_CURSOR] = "cursor", + [SPICE_CHANNEL_PLAYBACK] = "playback", + [SPICE_CHANNEL_RECORD] = "record", + [SPICE_CHANNEL_TUNNEL] = "tunnel", + [SPICE_CHANNEL_SMARTCARD] = "smartcard", + [SPICE_CHANNEL_USBREDIR] = "usbredir", + [SPICE_CHANNEL_PORT] = "port", +#if 0 + /* minimum spice-protocol is 0.12.3, webdav was added in 0.12.7, + * no easy way to #ifdef (SPICE_CHANNEL_* is a enum). Disable + * as quick fix for build failures with older versions. */ + [SPICE_CHANNEL_WEBDAV] = "webdav", +#endif + }; info = qmp_query_spice(NULL); @@ -581,6 +604,15 @@ void hmp_info_spice(Monitor *mon, const QDict *qdict) chan->value->connection_id); monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n", chan->value->channel_type, chan->value->channel_id); + + channel_name = "unknown"; + if (chan->value->channel_type > 0 && + chan->value->channel_type < ARRAY_SIZE(channel_names) && + channel_names[chan->value->channel_type]) { + channel_name = channel_names[chan->value->channel_type]; + } + + monitor_printf(mon, " channel name: %s\n", channel_name); } } diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 61df477264..762f75dc2d 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -120,9 +120,12 @@ static QXLMode qxl_modes[] = { QXL_MODE_EX(2560, 2048), QXL_MODE_EX(2800, 2100), QXL_MODE_EX(3200, 2400), + /* these modes need more than 32 MB video memory */ QXL_MODE_EX(3840, 2160), /* 4k mainstream */ QXL_MODE_EX(4096, 2160), /* 4k */ + /* these modes need more than 64 MB video memory */ QXL_MODE_EX(7680, 4320), /* 8k mainstream */ + /* these modes need more than 128 MB video memory */ QXL_MODE_EX(8192, 4320), /* 8k */ }; @@ -297,19 +300,6 @@ void qxl_spice_reset_cursor(PCIQXLDevice *qxl) qxl->ssd.cursor = cursor_builtin_hidden(); } - -static inline uint32_t msb_mask(uint32_t val) -{ - uint32_t mask; - - do { - mask = ~(val - 1) & val; - val &= ~mask; - } while (mask < val); - - return mask; -} - static ram_addr_t qxl_rom_size(void) { uint32_t required_rom_size = sizeof(QXLRom) + sizeof(QXLModes) + @@ -367,6 +357,8 @@ static void init_qxl_rom(PCIQXLDevice *d) num_pages -= surface0_area_size; num_pages = num_pages / QXL_PAGE_SIZE; + assert(ram_header_size + surface0_area_size <= d->vga.vram_size); + rom->draw_area_offset = cpu_to_le32(0); rom->surface0_area_size = cpu_to_le32(surface0_area_size); rom->pages_offset = cpu_to_le32(surface0_area_size); @@ -1155,7 +1147,6 @@ static void qxl_soft_reset(PCIQXLDevice *d) qxl_enter_vga_mode(d); } else { d->mode = QXL_MODE_UNDEFINED; - update_displaychangelistener(&d->ssd.dcl, GUI_REFRESH_INTERVAL_IDLE); } } @@ -1880,6 +1871,12 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl) if (qxl->vgamem_size_mb < 8) { qxl->vgamem_size_mb = 8; } + /* XXX: we round vgamem_size_mb up to a nearest power of two and it must be + * less than vga_common_init()'s maximum on qxl->vga.vram_size (512 now). + */ + if (qxl->vgamem_size_mb > 256) { + qxl->vgamem_size_mb = 256; + } qxl->vgamem_size = qxl->vgamem_size_mb * 1024 * 1024; /* vga ram (bar 0, total) */ @@ -1910,10 +1907,10 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl) qxl->vram32_size = 4096; qxl->vram_size = 4096; } - qxl->vgamem_size = msb_mask(qxl->vgamem_size * 2 - 1); - qxl->vga.vram_size = msb_mask(qxl->vga.vram_size * 2 - 1); - qxl->vram32_size = msb_mask(qxl->vram32_size * 2 - 1); - qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1); + qxl->vgamem_size = pow2ceil(qxl->vgamem_size); + qxl->vga.vram_size = pow2ceil(qxl->vga.vram_size); + qxl->vram32_size = pow2ceil(qxl->vram32_size); + qxl->vram_size = pow2ceil(qxl->vram_size); } static int qxl_init_common(PCIQXLDevice *qxl) @@ -1945,7 +1942,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) break; case 4: /* qxl-4 */ pci_device_rev = QXL_REVISION_STABLE_V12; - io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); + io_size = pow2ceil(QXL_IO_RANGE_SIZE); break; default: error_report("Invalid revision %d for qxl device (max %d)", diff --git a/hw/display/vga.c b/hw/display/vga.c index c8c49abc6e..c0f7b343bb 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -2094,6 +2094,17 @@ static const GraphicHwOps vga_ops = { .text_update = vga_update_text, }; +static inline uint32_t uint_clamp(uint32_t val, uint32_t vmin, uint32_t vmax) +{ + if (val < vmin) { + return vmin; + } + if (val > vmax) { + return vmax; + } + return val; +} + void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) { int i, j, v, b; @@ -2121,13 +2132,10 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate) expand4to8[i] = v; } - /* valid range: 1 MB -> 256 MB */ - s->vram_size = 1024 * 1024; - while (s->vram_size < (s->vram_size_mb << 20) && - s->vram_size < (256 << 20)) { - s->vram_size <<= 1; - } - s->vram_size_mb = s->vram_size >> 20; + s->vram_size_mb = uint_clamp(s->vram_size_mb, 1, 512); + s->vram_size_mb = pow2ceil(s->vram_size_mb); + s->vram_size = s->vram_size_mb << 20; + if (!s->vbe_size) { s->vbe_size = s->vram_size; } diff --git a/include/qemu-common.h b/include/qemu-common.h index 644b46dcdd..1b5cffb403 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -418,6 +418,9 @@ static inline bool is_power_of_2(uint64_t value) /* round down to the nearest power of 2*/ int64_t pow2floor(int64_t value); +/* round up to the nearest power of 2 (0 if overflow) */ +uint64_t pow2ceil(uint64_t value); + #include "qemu/module.h" /* diff --git a/util/cutils.c b/util/cutils.c index dbe7412bd8..c2250d1ba5 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -483,6 +483,20 @@ int64_t pow2floor(int64_t value) return value; } +/* round up to the nearest power of 2 (0 if overflow) */ +uint64_t pow2ceil(uint64_t value) +{ + uint8_t nlz = clz64(value); + + if (is_power_of_2(value)) { + return value; + } + if (!nlz) { + return 0; + } + return 1ULL << (64 - nlz); +} + /* * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128) * Input is limited to 14-bit numbers |