Re: [Qemu-devel] [PATCH REBASE/RESEND 0/4] Auto-document qdev devices
Amit Shah writes: > Hello, > > This is yet another rebase of the patchset I'd sent earlier. > > The usual notes apply: this is just the start, just getting the > framework in place and a few examples so that people can then pick up > and start documenting their devices and options. We want to see all > of the devices covered, and hopefully turn on build_bug_on() on an > empty doc string. > > Maintainers should perhaps also look for patches that introduce > options without documentation. > > That's the long-term goal (0.15-final). For short-term, I'll be > preparing follow-on patches that add doc strings for a few more > options and perhaps bug people based on git history as to what > documentation is to be added for some options. Also to incorporate > Markus's comments on beautifying output. > > The earlier this patchset goes in the better since it'll reduce > conflicts and rebases needed. > > If this looks acceptable, please apply! As long as Amit keeps rebasing his patches, I'll keep resending my comment (it does get old, though): This has been stuck since forever. No idea why, it's neither hairy nor controversial. Quoting from my review of v2(?) last September: For QMP, we'll need to cover more than just device properties, and in more detail than just a help text, but this looks like a sensible step forward. I'm fine with committing it as is. We can polish in follow-up commits.
[Qemu-devel] [PATCH v3 01/16] vnc: qemu can die if the client is disconnected while updating screen
agraf reported that qemu_mutex_destroy(vs->output_mutex) while failing in vnc_disconnect_finish(). It's because vnc_worker_thread_loop() tries to unlock the mutex while not locked. The unlocking call doesn't fail (pthread bug ?), but the destroy call does. Signed-off-by: Corentin Chary --- ui/vnc-jobs-async.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c index 6e9cf08..0b5d750 100644 --- a/ui/vnc-jobs-async.c +++ b/ui/vnc-jobs-async.c @@ -227,6 +227,10 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) if (job->vs->csock == -1) { vnc_unlock_display(job->vs->vd); +/* output mutex must be locked before going to + * disconnected: + */ +vnc_lock_output(job->vs); goto disconnected; } -- 1.7.3.4
[Qemu-devel] [PATCH v3 00/16] vnc: adapative tight, zrle, zywrle, and bitmap module
From: Corentin Chary Hi, Since v2: - Fixed some styles issues - Rebased to current master - Fixed a Makefile issue (using .c instead of .o) I rebased the series against current master, it contains: - Adaptive Tight Encoding: send lossy or lossless updates depending on the update frequency of the screen region. If a lossy update is forced, then it will be refreshed with a lossless update as soon as the update frequency goes back to 0. - ZRLE/ZYWRLE Encodings: ZYWRLE use less bandwidth than tight, but the result is also probably more lossy. I wanted to make ZRLE/ZYWRLE adaptive, but this is not possible because most of the vnc clients can't switch between ZRLE and ZYWRLE. But a possible solution is to use another encoding for lossless updates, like zlib or tight. - Bitmap module: create bitmap.h and bitops.h, and remove duplicate code from vnc.c It was my last series from GSoC 2010 context, if necessary I can send different series for adaptive vnc, zrle and bitmap stuff. Thanks, Corentin Chary (16): vnc: qemu can die if the client is disconnected while updating screen vnc: don't set the quality if lossy encoding are disabled vnc: add a way to get the update frequency for a given region vnc: refresh lossy rect after a given timeout vnc: tight: use the update frequency to choose between lossy and lossless vnc: palette: use a pool to reduce memory allocations vnc: palette: add palette_init calls vnc: palette: and fill and color calls. vnc: Add ZRLE and ZYWRLE encodings. vnc: fix uint8_t comparisons with negative values vnc: fix lossy rect refreshing bitmap: add a generic bitmap and bitops library vnc: use the new generic bitmap functions vnc: don't try to send bigger updates that client height vnc: tight: tweak adaptive tight settings vnc: add a non-adaptive option Makefile.objs|2 + bitmap.c | 256 bitmap.h | 222 ++ bitops.c | 142 + bitops.h | 272 + osdep.h |4 + qemu-options.hx |9 + ui/vnc-enc-tight.c | 75 - ui/vnc-enc-zrle-template.c | 263 + ui/vnc-enc-zrle.c| 366 +++ ui/vnc-enc-zrle.h| 40 +++ ui/vnc-enc-zywrle-template.c | 170 +++ ui/vnc-enc-zywrle.h | 659 ++ ui/vnc-jobs-async.c |8 + ui/vnc-palette.c | 58 +++- ui/vnc-palette.h |7 +- ui/vnc.c | 283 ++- ui/vnc.h | 57 - 18 files changed, 2786 insertions(+), 107 deletions(-) create mode 100644 bitmap.c create mode 100644 bitmap.h create mode 100644 bitops.c create mode 100644 bitops.h create mode 100644 ui/vnc-enc-zrle-template.c create mode 100644 ui/vnc-enc-zrle.c create mode 100644 ui/vnc-enc-zrle.h create mode 100644 ui/vnc-enc-zywrle-template.c create mode 100644 ui/vnc-enc-zywrle.h -- 1.7.3.4
Re: [Qemu-devel] [PATCH v2 00/10] Make some devices optional
Blue Swirl writes: > Disabling some devices from build is a frequently requested feature. > Provide means to disable vmware_vga, vmmouse and HPET. Long patch series without proper threading are a PITA to review. git-send-email adds the necessary headers automatically. Could you try using it? Thanks.
[Qemu-devel] [PATCH v3 08/16] vnc: palette: and fill and color calls.
These two helpers are needed for zrle and zywrle. Signed-off-by: Corentin Chary --- ui/vnc-palette.c | 32 ui/vnc-palette.h |3 +++ 2 files changed, 35 insertions(+), 0 deletions(-) diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c index f93250b..c478060 100644 --- a/ui/vnc-palette.c +++ b/ui/vnc-palette.c @@ -126,3 +126,35 @@ void palette_iter(const VncPalette *palette, } } } + +uint32_t palette_color(const VncPalette *palette, int idx, bool *found) +{ +int i; +VncPaletteEntry *entry; + +for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) { +QLIST_FOREACH(entry, &palette->table[i], next) { +if (entry->idx == idx) { +*found = true; +return entry->color; +} +} +} + +*found = false; +return -1; +} + +static void palette_fill_cb(int idx, uint32_t color, void *opaque) +{ +uint32_t *colors = opaque; + +colors[idx] = color; +} + +size_t palette_fill(const VncPalette *palette, +uint32_t colors[VNC_PALETTE_MAX_SIZE]) +{ +palette_iter(palette, palette_fill_cb, colors); +return palette_size(palette); +} diff --git a/ui/vnc-palette.h b/ui/vnc-palette.h index c646e4d..3260885 100644 --- a/ui/vnc-palette.h +++ b/ui/vnc-palette.h @@ -61,5 +61,8 @@ size_t palette_size(const VncPalette *palette); void palette_iter(const VncPalette *palette, void (*iter)(int idx, uint32_t color, void *opaque), void *opaque); +uint32_t palette_color(const VncPalette *palette, int idx, bool *found); +size_t palette_fill(const VncPalette *palette, +uint32_t colors[VNC_PALETTE_MAX_SIZE]); #endif /* VNC_PALETTE_H */ -- 1.7.3.4
[Qemu-devel] [PATCH v3 04/16] vnc: refresh lossy rect after a given timeout
If an adaptive encoding has choosen to send a lossy update based on the result of vnc_update_freq(), then it should advertise it with vnc_sent_lossy_rect(). This will allow to automatically refresh this rect once it's static again. Signed-off-by: Corentin Chary --- ui/vnc-jobs-async.c |2 + ui/vnc.c| 67 -- ui/vnc.h|3 ++ 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c index 0b5d750..bfe8e86 100644 --- a/ui/vnc-jobs-async.c +++ b/ui/vnc-jobs-async.c @@ -166,6 +166,7 @@ static void vnc_async_encoding_start(VncState *orig, VncState *local) local->features = orig->features; local->ds = orig->ds; local->vd = orig->vd; +local->lossy_rect = orig->lossy_rect; local->write_pixels = orig->write_pixels; local->clientds = orig->clientds; local->tight = orig->tight; @@ -182,6 +183,7 @@ static void vnc_async_encoding_end(VncState *orig, VncState *local) orig->tight = local->tight; orig->zlib = local->zlib; orig->hextile = local->hextile; +orig->lossy_rect = local->lossy_rect; } static int vnc_worker_thread_loop(VncJobQueue *queue) diff --git a/ui/vnc.c b/ui/vnc.c index 6eacd1d..697b836 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1014,6 +1014,8 @@ static void vnc_disconnect_start(VncState *vs) static void vnc_disconnect_finish(VncState *vs) { +int i; + vnc_jobs_join(vs); /* Wait encoding jobs */ vnc_lock_output(vs); @@ -1050,6 +1052,10 @@ static void vnc_disconnect_finish(VncState *vs) #ifdef CONFIG_VNC_THREAD qemu_mutex_destroy(&vs->output_mutex); #endif +for (i = 0; i < VNC_STAT_ROWS; ++i) { +qemu_free(vs->lossy_rect[i]); +} +qemu_free(vs->lossy_rect); qemu_free(vs); } @@ -2267,10 +2273,57 @@ static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y) return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT]; } -static void vnc_update_stats(VncDisplay *vd, struct timeval * tv) +void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h) +{ +int i, j; + +w = (x + w) / VNC_STAT_RECT; +h = (y + h) / VNC_STAT_RECT; +x /= VNC_STAT_RECT; +y /= VNC_STAT_RECT; + +for (j = y; j <= y + h; j++) { +for (i = x; i <= x + w; i++) { +vs->lossy_rect[j][i] = 1; +} +} +} + +static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y) +{ +VncState *vs; +int sty = y / VNC_STAT_RECT; +int stx = x / VNC_STAT_RECT; +int has_dirty = 0; + +y = y / VNC_STAT_RECT * VNC_STAT_RECT; +x = x / VNC_STAT_RECT * VNC_STAT_RECT; + +QTAILQ_FOREACH(vs, &vd->clients, next) { +int j; + +/* kernel send buffers are full -> refresh later */ +if (vs->output.offset) { +continue; +} + +if (!vs->lossy_rect[sty][stx]) { +continue; +} +vs->lossy_rect[sty][stx] = 0; +for (j = 0; j < VNC_STAT_RECT; ++j) { +vnc_set_bits(vs->dirty[y + j], x / 16, VNC_STAT_RECT / 16); +} +has_dirty++; +} +return has_dirty; +} + +static int vnc_update_stats(VncDisplay *vd, struct timeval * tv) { int x, y; struct timeval res; +int has_dirty = 0; for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) { for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) { @@ -2283,7 +2336,7 @@ static void vnc_update_stats(VncDisplay *vd, struct timeval * tv) timersub(tv, &VNC_REFRESH_STATS, &res); if (timercmp(&vd->guest.last_freq_check, &res, >)) { -return ; +return has_dirty; } vd->guest.last_freq_check = *tv; @@ -2302,6 +2355,7 @@ static void vnc_update_stats(VncDisplay *vd, struct timeval * tv) if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) { rect->freq = 0; +has_dirty += vnc_refresh_lossy_rect(vd, x, y); memset(rect->times, 0, sizeof (rect->times)); continue ; } @@ -2315,6 +2369,7 @@ static void vnc_update_stats(VncDisplay *vd, struct timeval * tv) rect->freq = 1. / rect->freq; } } +return has_dirty; } double vnc_update_freq(VncState *vs, int x, int y, int w, int h) @@ -2366,7 +2421,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd) struct timeval tv; gettimeofday(&tv, NULL); -vnc_update_stats(vd, &tv); +has_dirty = vnc_update_stats(vd, &tv); /* * Walk through the guest dirty map. @@ -2468,7 +2523,13 @@ static void vnc_remove_timer(VncDisplay *vd) static void vnc_connect(VncDisplay *vd, int csock) { VncState *vs = qemu_mallocz(sizeof(VncState)); +int i; + vs->csock = csock; +vs->lossy_rect = qemu_mallocz(VNC_STAT_ROWS * sizeof (*vs->lossy_rect)); +for (i = 0; i < VNC_STAT_ROWS; ++i) { +vs->lossy_rect[i] = qemu_mallocz(VNC_STAT_COLS * sizeof (uint8_t)
[Qemu-devel] [PATCH v3 02/16] vnc: don't set the quality if lossy encoding are disabled
This should not change the current behavior, but if any new encoding try to use the tight quality, it will always be set to -1 when lossy encodings are disabled. Signed-off-by: Corentin Chary --- ui/vnc.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 560b98d..9c5c5b3 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1780,7 +1780,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vs->tight.compression = (enc & 0x0F); break; case VNC_ENCODING_QUALITYLEVEL0 ... VNC_ENCODING_QUALITYLEVEL0 + 9: -vs->tight.quality = (enc & 0x0F); +if (vs->vd->lossy) { +vs->tight.quality = (enc & 0x0F); +} break; default: VNC_DEBUG("Unknown encoding: %d (0x%.8x): %d\n", i, enc, enc); -- 1.7.3.4
[Qemu-devel] [PATCH v3 03/16] vnc: add a way to get the update frequency for a given region
This patch compute the update frequency (in Hz) for each 64x64 rects. Any adaptive encoding can get this value using vnc_update_freq(), and switch to a lossy encoding if the value is too high. The frequency is pre-calculated every 500ms, based on the last 10 updates per 64x64 rect. If a 64x64 rect was not updated in the last 2 second, then the frequency became 0, and all the stored timestamp are reseted. Signed-off-by: Corentin Chary --- ui/vnc.c | 101 ++ ui/vnc.h | 19 +++ 2 files changed, 120 insertions(+), 0 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 9c5c5b3..6eacd1d 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -35,6 +35,8 @@ #define VNC_REFRESH_INTERVAL_BASE 30 #define VNC_REFRESH_INTERVAL_INC 50 #define VNC_REFRESH_INTERVAL_MAX 2000 +static const struct timeval VNC_REFRESH_STATS = { 0, 50 }; +static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 }; #include "vnc_keysym.h" #include "d3des.h" @@ -2258,6 +2260,99 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len) return 0; } +static VncRectStat *vnc_stat_rect(VncDisplay *vd, int x, int y) +{ +struct VncSurface *vs = &vd->guest; + +return &vs->stats[y / VNC_STAT_RECT][x / VNC_STAT_RECT]; +} + +static void vnc_update_stats(VncDisplay *vd, struct timeval * tv) +{ +int x, y; +struct timeval res; + +for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) { +for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) { +VncRectStat *rect = vnc_stat_rect(vd, x, y); + +rect->updated = false; +} +} + +timersub(tv, &VNC_REFRESH_STATS, &res); + +if (timercmp(&vd->guest.last_freq_check, &res, >)) { +return ; +} +vd->guest.last_freq_check = *tv; + +for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) { +for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) { +VncRectStat *rect= vnc_stat_rect(vd, x, y); +int count = ARRAY_SIZE(rect->times); +struct timeval min, max; + +if (!timerisset(&rect->times[count - 1])) { +continue ; +} + +max = rect->times[(rect->idx + count - 1) % count]; +timersub(tv, &max, &res); + +if (timercmp(&res, &VNC_REFRESH_LOSSY, >)) { +rect->freq = 0; +memset(rect->times, 0, sizeof (rect->times)); +continue ; +} + +min = rect->times[rect->idx]; +max = rect->times[(rect->idx + count - 1) % count]; +timersub(&max, &min, &res); + +rect->freq = res.tv_sec + res.tv_usec / 100.; +rect->freq /= count; +rect->freq = 1. / rect->freq; +} +} +} + +double vnc_update_freq(VncState *vs, int x, int y, int w, int h) +{ +int i, j; +double total = 0; +int num = 0; + +x = (x / VNC_STAT_RECT) * VNC_STAT_RECT; +y = (y / VNC_STAT_RECT) * VNC_STAT_RECT; + +for (j = y; j <= y + h; j += VNC_STAT_RECT) { +for (i = x; i <= x + w; i += VNC_STAT_RECT) { +total += vnc_stat_rect(vs->vd, i, j)->freq; +num++; +} +} + +if (num) { +return total / num; +} else { +return 0; +} +} + +static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv) +{ +VncRectStat *rect; + +rect = vnc_stat_rect(vd, x, y); +if (rect->updated) { +return ; +} +rect->times[rect->idx] = *tv; +rect->idx = (rect->idx + 1) % ARRAY_SIZE(rect->times); +rect->updated = true; +} + static int vnc_refresh_server_surface(VncDisplay *vd) { int y; @@ -2268,6 +2363,11 @@ static int vnc_refresh_server_surface(VncDisplay *vd) VncState *vs; int has_dirty = 0; +struct timeval tv; + +gettimeofday(&tv, NULL); +vnc_update_stats(vd, &tv); + /* * Walk through the guest dirty map. * Check and copy modified bits from guest to server surface. @@ -2294,6 +2394,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd) if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0) continue; memcpy(server_ptr, guest_ptr, cmp_bytes); +vnc_rect_updated(vd, x, y, &tv); QTAILQ_FOREACH(vs, &vd->clients, next) { vnc_set_bit(vs->dirty[y], (x / 16)); } diff --git a/ui/vnc.h b/ui/vnc.h index 4f895be..c0e5ff3 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -80,6 +80,10 @@ typedef void VncSendHextileTile(VncState *vs, #define VNC_MAX_HEIGHT 2048 #define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32)) +#define VNC_STAT_RECT 64 +#define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT) +#define VNC_STAT_ROWS (VNC_MAX_HEIGHT / VNC_STAT_RECT) + #define VNC_AUTH_CHALLENGE_SIZE 16 typedef struct VncDisplay VncDisplay; @@ -92,9 +96,23 @@ typedef struct VncDisplay VncD
[Qemu-devel] [Bug 181561] Re: Hardy alpha [2-6] daily-live i386 don't boot
** Changed in: linux (Gentoo Linux) Importance: Unknown => Medium -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/181561 Title: Hardy alpha [2-6] daily-live i386 don't boot Status in The Linux Kernel: Fix Released Status in QEMU: Invalid Status in “linux” package in Ubuntu: Fix Released Status in “linux” package in Gentoo Linux: Won't Fix Bug description: Binary package hint: casper Since hardy alpha2 i386 daily-live, the system don't boot. Look at screenshot attached. This PC have seen dapper/feisty/gutsy livre cd booting well. What kind of informations can i provide ?
[Qemu-devel] [PATCH v3 06/16] vnc: palette: use a pool to reduce memory allocations
We now that the palette will never have more than 256 elements. Let's use a pool to reduce malloc calls. Signed-off-by: Corentin Chary --- ui/vnc-palette.c | 18 ++ ui/vnc-palette.h |3 ++- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c index bff6445..c47420b 100644 --- a/ui/vnc-palette.c +++ b/ui/vnc-palette.c @@ -63,23 +63,9 @@ VncPalette *palette_new(size_t max, int bpp) void palette_destroy(VncPalette *palette) { -int i; - if (palette == NULL) { -return ; +qemu_free(palette); } - -for (i = 0; i < VNC_PALETTE_HASH_SIZE; i++) { -VncPaletteEntry *entry = QLIST_FIRST(&palette->table[i]); -while (entry) { -VncPaletteEntry *tmp = QLIST_NEXT(entry, next); -QLIST_REMOVE(entry, next); -qemu_free(entry); -entry = tmp; -} -} - -qemu_free(palette); } int palette_put(VncPalette *palette, uint32_t color) @@ -97,7 +83,7 @@ int palette_put(VncPalette *palette, uint32_t color) if (!entry) { VncPaletteEntry *entry; -entry = qemu_mallocz(sizeof(*entry)); +entry = &palette->pool[palette->size]; entry->color = color; entry->idx = idx; QLIST_INSERT_HEAD(&palette->table[hash], entry, next); diff --git a/ui/vnc-palette.h b/ui/vnc-palette.h index d0645eb..f57d0e7 100644 --- a/ui/vnc-palette.h +++ b/ui/vnc-palette.h @@ -34,6 +34,7 @@ #include #define VNC_PALETTE_HASH_SIZE 256 +#define VNC_PALETTE_MAX_SIZE 256 typedef struct VncPaletteEntry { int idx; @@ -42,7 +43,7 @@ typedef struct VncPaletteEntry { } VncPaletteEntry; typedef struct VncPalette { -QObject_HEAD; +VncPaletteEntry pool[VNC_PALETTE_MAX_SIZE]; size_t size; size_t max; int bpp; -- 1.7.3.4
[Qemu-devel] [PATCH v3 05/16] vnc: tight: use the update frequency to choose between lossy and lossless
Use the new update frequency infrastructure to use jpeg for regions with high update frequency. Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c | 75 +++- 1 files changed, 62 insertions(+), 13 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index af45edd..ad9a9a8 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -72,6 +72,26 @@ static const struct { static int tight_send_framebuffer_update(VncState *vs, int x, int y, int w, int h); +#ifdef CONFIG_VNC_JPEG +static const struct { +double jpeg_freq_min; /* Don't send JPEG if the freq is bellow */ +double jpeg_freq_threshold; /* Always send JPEG if the freq is above */ +int jpeg_idx; /* Allow indexed JPEG */ +int jpeg_full; /* Allow full color JPEG */ +} tight_jpeg_conf[] = { +{ 0, 4, 1, 1 }, +{ 0, 4, 1, 1 }, +{ 0, 4, 1, 1 }, +{ 0, 4, 1, 1 }, +{ 0, 4, 0, 1 }, +{ 0.1, 4, 0, 1 }, +{ 0.2, 4, 0, 1 }, +{ 0.3, 6, 0, 0 }, +{ 0.4, 8, 0, 0 }, +{ 0.5, 10, 0, 0 }, +}; +#endif + #ifdef CONFIG_VNC_PNG static const struct { int png_zlib_level, png_filters; @@ -1476,12 +1496,13 @@ static int send_sub_rect_nojpeg(VncState *vs, int x, int y, int w, int h, #ifdef CONFIG_VNC_JPEG static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h, int bg, int fg, int colors, - VncPalette *palette) + VncPalette *palette, bool force) { int ret; if (colors == 0) { -if (tight_detect_smooth_image(vs, w, h)) { +if (force || (tight_jpeg_conf[vs->tight.quality].jpeg_full && + tight_detect_smooth_image(vs, w, h))) { int quality = tight_conf[vs->tight.quality].jpeg_quality; ret = send_jpeg_rect(vs, x, y, w, h, quality); @@ -1493,8 +1514,9 @@ static int send_sub_rect_jpeg(VncState *vs, int x, int y, int w, int h, } else if (colors == 2) { ret = send_mono_rect(vs, x, y, w, h, bg, fg); } else if (colors <= 256) { -if (colors > 96 && -tight_detect_smooth_image(vs, w, h)) { +if (force || (colors > 96 && + tight_jpeg_conf[vs->tight.quality].jpeg_idx && + tight_detect_smooth_image(vs, w, h))) { int quality = tight_conf[vs->tight.quality].jpeg_quality; ret = send_jpeg_rect(vs, x, y, w, h, quality); @@ -1514,6 +1536,8 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h) uint32_t bg = 0, fg = 0; int colors; int ret = 0; +bool force_jpeg = false; +bool allow_jpeg = true; vnc_framebuffer_update(vs, x, y, w, h, vs->tight.type); @@ -1521,11 +1545,26 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h) vnc_raw_send_framebuffer_update(vs, x, y, w, h); vnc_tight_stop(vs); +#ifdef CONFIG_VNC_JPEG +if (vs->tight.quality != -1) { +double freq = vnc_update_freq(vs, x, y, w, h); + +if (freq < tight_jpeg_conf[vs->tight.quality].jpeg_freq_min) { +allow_jpeg = false; +} +if (freq >= tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) { +force_jpeg = true; +vnc_sent_lossy_rect(vs, x, y, w, h); +} +} +#endif + colors = tight_fill_palette(vs, x, y, w * h, &fg, &bg, &palette); #ifdef CONFIG_VNC_JPEG -if (vs->tight.quality != (uint8_t)-1) { -ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, palette); +if (allow_jpeg && vs->tight.quality != (uint8_t)-1) { +ret = send_sub_rect_jpeg(vs, x, y, w, h, bg, fg, colors, palette, + force_jpeg); } else { ret = send_sub_rect_nojpeg(vs, x, y, w, h, bg, fg, colors, palette); } @@ -1548,7 +1587,8 @@ static int send_sub_rect_solid(VncState *vs, int x, int y, int w, int h) return send_solid_rect(vs); } -static int send_rect_simple(VncState *vs, int x, int y, int w, int h) +static int send_rect_simple(VncState *vs, int x, int y, int w, int h, +bool split) { int max_size, max_width; int max_sub_width, max_sub_height; @@ -1559,7 +1599,7 @@ static int send_rect_simple(VncState *vs, int x, int y, int w, int h) max_size = tight_conf[vs->tight.compression].max_rect_size; max_width = tight_conf[vs->tight.compression].max_rect_width; -if (w > max_width || w * h > max_size) { +if (split && (w > max_width || w * h > max_size)) { max_sub_width = (w > max_width) ? max_width : w; max_sub_height = max_size / max_sub_width; @@ -1590,7 +1630,7 @@ static int find_large_solid_color_rect(VncState *vs, int x, int y, /* If a rectangle becomes too large, send its upper part now. */ if (dy - y >= max_rows) { -
[Qemu-devel] [PATCH v3 07/16] vnc: palette: add palette_init calls
This allow to use palette on the stack instead of always allocating them. Signed-off-by: Corentin Chary --- ui/vnc-palette.c |8 +++- ui/vnc-palette.h |1 + 2 files changed, 8 insertions(+), 1 deletions(-) diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c index c47420b..f93250b 100644 --- a/ui/vnc-palette.c +++ b/ui/vnc-palette.c @@ -56,9 +56,15 @@ VncPalette *palette_new(size_t max, int bpp) VncPalette *palette; palette = qemu_mallocz(sizeof(*palette)); +palette_init(palette, max, bpp); +return palette; +} + +void palette_init(VncPalette *palette, size_t max, int bpp) +{ +memset(palette, 0, sizeof (*palette)); palette->max = max; palette->bpp = bpp; -return palette; } void palette_destroy(VncPalette *palette) diff --git a/ui/vnc-palette.h b/ui/vnc-palette.h index f57d0e7..c646e4d 100644 --- a/ui/vnc-palette.h +++ b/ui/vnc-palette.h @@ -51,6 +51,7 @@ typedef struct VncPalette { } VncPalette; VncPalette *palette_new(size_t max, int bpp); +void palette_init(VncPalette *palette, size_t max, int bpp); void palette_destroy(VncPalette *palette); int palette_put(VncPalette *palette, uint32_t color); -- 1.7.3.4
[Qemu-devel] [PATCH v3 12/16] bitmap: add a generic bitmap and bitops library
Add most used bitmap and bitops functions into bitmap.c and bitops.c. Theses functions are mostly copied from Linux kernel source. Some of these functions are already redefined in the VNC server. Some of them could be used for some block stuff. The yet yo be submitted NUMA work also need bitmaps. bitops_ffsl() and bitops_flsl() are here because bitops/bitmap works on unsigned long, not int, and we can't use current code because: * ffs only works on int * qemu_fls only works on int * ffsl is a GNU extension Signed-off-by: Corentin Chary --- Makefile.objs |1 + bitmap.c | 256 + bitmap.h | 222 ++ bitops.c | 142 ++ bitops.h | 272 + osdep.h |4 + 6 files changed, 897 insertions(+), 0 deletions(-) create mode 100644 bitmap.c create mode 100644 bitmap.h create mode 100644 bitops.c create mode 100644 bitops.h diff --git a/Makefile.objs b/Makefile.objs index 9691875..a4a6450 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -100,6 +100,7 @@ common-obj-y += msmouse.o ps2.o common-obj-y += qdev.o qdev-properties.o common-obj-y += block-migration.o common-obj-y += pflib.o +common-obj-y += bitmap.o bitops.o common-obj-$(CONFIG_BRLAPI) += baum.o common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o diff --git a/bitmap.c b/bitmap.c new file mode 100644 index 000..a62c8ba --- /dev/null +++ b/bitmap.c @@ -0,0 +1,256 @@ +/* + * Bitmap Module + * + * Stolen from linux/src/lib/bitmap.c + * + * Copyright (C) 2010 Corentin Chary + * + * This source code is licensed under the GNU General Public License, + * Version 2. + */ + +#include "bitops.h" +#include "bitmap.h" + +/* + * bitmaps provide an array of bits, implemented using an an + * array of unsigned longs. The number of valid bits in a + * given bitmap does _not_ need to be an exact multiple of + * BITS_PER_LONG. + * + * The possible unused bits in the last, partially used word + * of a bitmap are 'don't care'. The implementation makes + * no particular effort to keep them zero. It ensures that + * their value will not affect the results of any operation. + * The bitmap operations that return Boolean (bitmap_empty, + * for example) or scalar (bitmap_weight, for example) results + * carefully filter out these unused bits from impacting their + * results. + * + * These operations actually hold to a slightly stronger rule: + * if you don't input any bitmaps to these ops that have some + * unused bits set, then they won't output any set unused bits + * in output bitmaps. + * + * The byte ordering of bitmaps is more natural on little + * endian architectures. + */ + +int slow_bitmap_empty(const unsigned long *bitmap, int bits) +{ +int k, lim = bits/BITS_PER_LONG; + +for (k = 0; k < lim; ++k) { +if (bitmap[k]) { +return 0; +} +} +if (bits % BITS_PER_LONG) { +if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) { +return 0; +} +} + +return 1; +} + +int slow_bitmap_full(const unsigned long *bitmap, int bits) +{ +int k, lim = bits/BITS_PER_LONG; + +for (k = 0; k < lim; ++k) { +if (~bitmap[k]) { +return 0; +} +} + +if (bits % BITS_PER_LONG) { +if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) { +return 0; +} +} + +return 1; +} + +int slow_bitmap_equal(const unsigned long *bitmap1, + const unsigned long *bitmap2, int bits) +{ +int k, lim = bits/BITS_PER_LONG; + +for (k = 0; k < lim; ++k) { +if (bitmap1[k] != bitmap2[k]) { +return 0; +} +} + +if (bits % BITS_PER_LONG) { +if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) { +return 0; +} +} + +return 1; +} + +void slow_bitmap_complement(unsigned long *dst, const unsigned long *src, +int bits) +{ +int k, lim = bits/BITS_PER_LONG; + +for (k = 0; k < lim; ++k) { +dst[k] = ~src[k]; +} + +if (bits % BITS_PER_LONG) { +dst[k] = ~src[k] & BITMAP_LAST_WORD_MASK(bits); +} +} + +int slow_bitmap_and(unsigned long *dst, const unsigned long *bitmap1, +const unsigned long *bitmap2, int bits) +{ +int k; +int nr = BITS_TO_LONGS(bits); +unsigned long result = 0; + +for (k = 0; k < nr; k++) { +result |= (dst[k] = bitmap1[k] & bitmap2[k]); +} +return result != 0; +} + +void slow_bitmap_or(unsigned long *dst, const unsigned long *bitmap1, +const unsigned long *bitmap2, int bits) +{ +int k; +int nr = BITS_TO_LONGS(bits); + +for (k = 0; k < nr; k++) { +dst[k] = bitmap1[k] | bitmap2[k]; +} +} + +void slow_bitmap_xor(unsigned long *dst, const unsigned long *bitmap1, +
[Qemu-devel] [PATCH v3 10/16] vnc: fix uint8_t comparisons with negative values
Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c |4 ++-- ui/vnc-enc-zrle.c |3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index ad9a9a8..81024d5 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -1546,7 +1546,7 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h) vnc_tight_stop(vs); #ifdef CONFIG_VNC_JPEG -if (vs->tight.quality != -1) { +if (vs->tight.quality != (uint8_t)-1) { double freq = vnc_update_freq(vs, x, y, w, h); if (freq < tight_jpeg_conf[vs->tight.quality].jpeg_freq_min) { @@ -1711,7 +1711,7 @@ static int tight_send_framebuffer_update(VncState *vs, int x, int y, vs->tight.pixel24 = false; } -if (vs->tight.quality != -1) { +if (vs->tight.quality != (uint8_t)-1) { double freq = vnc_update_freq(vs, x, y, w, h); if (freq > tight_jpeg_conf[vs->tight.quality].jpeg_freq_threshold) { diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c index 016a406..917d384 100644 --- a/ui/vnc-enc-zrle.c +++ b/ui/vnc-enc-zrle.c @@ -260,7 +260,8 @@ static int zrle_send_framebuffer_update(VncState *vs, int x, int y, int zywrle_level; if (vs->zrle.type == VNC_ENCODING_ZYWRLE) { -if (!vs->vd->lossy || vs->tight.quality < 0 || vs->tight.quality == 9) { +if (!vs->vd->lossy || vs->tight.quality == (uint8_t)-1 +|| vs->tight.quality == 9) { zywrle_level = 0; vs->zrle.type = VNC_ENCODING_ZRLE; } else if (vs->tight.quality < 3) { -- 1.7.3.4
[Qemu-devel] [PATCH v3 11/16] vnc: fix lossy rect refreshing
The for loop in send_lossy_rect was totally wrong, and we can't call vnc_set_bits() because it does not really do what it should. Use vnc_set_bit() directly instead. Signed-off-by: Corentin Chary --- ui/vnc.c | 12 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 9920c0e..8c7cb0d 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2297,8 +2297,8 @@ void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h) x /= VNC_STAT_RECT; y /= VNC_STAT_RECT; -for (j = y; j <= y + h; j++) { -for (i = x; i <= x + w; i++) { +for (j = y; j <= h; j++) { +for (i = x; i <= w; i++) { vs->lossy_rect[j][i] = 1; } } @@ -2315,7 +2315,7 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y) x = x / VNC_STAT_RECT * VNC_STAT_RECT; QTAILQ_FOREACH(vs, &vd->clients, next) { -int j; +int j, i; /* kernel send buffers are full -> refresh later */ if (vs->output.offset) { @@ -2325,12 +2325,16 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y) if (!vs->lossy_rect[sty][stx]) { continue; } + vs->lossy_rect[sty][stx] = 0; for (j = 0; j < VNC_STAT_RECT; ++j) { -vnc_set_bits(vs->dirty[y + j], x / 16, VNC_STAT_RECT / 16); +for (i = x / 16; i < VNC_STAT_RECT / 16 + x / 16; ++i) { +vnc_set_bit(vs->dirty[y + j], i); +} } has_dirty++; } + return has_dirty; } -- 1.7.3.4
[Qemu-devel] [PATCH] Change snapshot_blkdev hmp to use correct argument type for device
From: Jes Sorensen Pointed out by Markus Signed-off-by: Jes Sorensen --- hmp-commands.hx |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 38e1eb7..372bef4 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -822,7 +822,7 @@ ETEXI { .name = "snapshot_blkdev", -.args_type = "device:s,snapshot_file:s?,format:s?", +.args_type = "device:B,snapshot_file:s?,format:s?", .params = "device [new-image-file] [format]", .help = "initiates a live snapshot\n\t\t\t" "of device. If a new image file is specified, the\n\t\t\t" -- 1.7.3.5
[Qemu-devel] [PATCH v3 14/16] vnc: don't try to send bigger updates that client height
Respect client size if it doesn't not support desktop resizing. Signed-off-by: Corentin Chary --- ui/vnc.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 6c57b0e..86c23207 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -795,12 +795,11 @@ static void vnc_dpy_cursor_define(QEMUCursor *c) } static int find_and_clear_dirty_height(struct VncState *vs, - int y, int last_x, int x) + int y, int last_x, int x, int height) { int h; -VncDisplay *vd = vs->vd; -for (h = 1; h < (vd->server->height - y); h++) { +for (h = 1; h < (height - y); h++) { int tmp_x; if (!test_bit(last_x, vs->dirty[y + h])) { break; @@ -865,7 +864,8 @@ static int vnc_update_client(VncState *vs, int has_dirty) } } else { if (last_x != -1) { -int h = find_and_clear_dirty_height(vs, y, last_x, x); +int h = find_and_clear_dirty_height(vs, y, last_x, x, +height); n += vnc_job_add_rect(job, last_x * 16, y, (x - last_x) * 16, h); @@ -874,7 +874,7 @@ static int vnc_update_client(VncState *vs, int has_dirty) } } if (last_x != -1) { -int h = find_and_clear_dirty_height(vs, y, last_x, x); +int h = find_and_clear_dirty_height(vs, y, last_x, x, height); n += vnc_job_add_rect(job, last_x * 16, y, (x - last_x) * 16, h); } -- 1.7.3.4
[Qemu-devel] [PATCH v3 16/16] vnc: add a non-adaptive option
This option allow to disable adaptive behaviors in some encodings. Signed-off-by: Corentin Chary --- qemu-options.hx|9 + ui/vnc-enc-tight.c |2 +- ui/vnc.c | 13 + ui/vnc.h |1 + 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 945edf3..badb730 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -913,6 +913,15 @@ option is set, VNC client may receive lossy framebuffer updates depending on its encoding settings. Enabling this option can save a lot of bandwidth at the expense of quality. +@item non-adaptive + +Disable adaptive encodings. Adaptive encodings are enabled by default. +An adaptive encoding will try to detect frequently updated screen regions, +and send updates in these regions using a lossy encoding (like JPEG). +This can be really helpfull to save bandwidth when playing videos. Disabling +adaptive encodings allow to restore the original static behavior of encodings +like Tight. + @end table ETEXI diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 82c1e96..5933394 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -1546,7 +1546,7 @@ static int send_sub_rect(VncState *vs, int x, int y, int w, int h) vnc_tight_stop(vs); #ifdef CONFIG_VNC_JPEG -if (vs->tight.quality != (uint8_t)-1) { +if (!vs->vd->non_adaptive && vs->tight.quality != (uint8_t)-1) { double freq = vnc_update_freq(vs, x, y, w, h); if (freq < tight_jpeg_conf[vs->tight.quality].jpeg_freq_min) { diff --git a/ui/vnc.c b/ui/vnc.c index 86c23207..626b430 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2387,10 +2387,12 @@ static int vnc_refresh_server_surface(VncDisplay *vd) VncState *vs; int has_dirty = 0; -struct timeval tv; +struct timeval tv = { 0, 0 }; -gettimeofday(&tv, NULL); -has_dirty = vnc_update_stats(vd, &tv); +if (!vd->non_adaptive) { +gettimeofday(&tv, NULL); +has_dirty = vnc_update_stats(vd, &tv); +} /* * Walk through the guest dirty map. @@ -2419,7 +2421,8 @@ static int vnc_refresh_server_surface(VncDisplay *vd) if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0) continue; memcpy(server_ptr, guest_ptr, cmp_bytes); -vnc_rect_updated(vd, x, y, &tv); +if (!vd->non_adaptive) +vnc_rect_updated(vd, x, y, &tv); QTAILQ_FOREACH(vs, &vd->clients, next) { set_bit((x / 16), vs->dirty[y]); } @@ -2754,6 +2757,8 @@ int vnc_display_open(DisplayState *ds, const char *display) #endif } else if (strncmp(options, "lossy", 5) == 0) { vs->lossy = true; +} else if (strncmp(options, "non-adapative", 13) == 0) { +vs->non_adaptive = true; } } diff --git a/ui/vnc.h b/ui/vnc.h index 98a1885..8a1e7b9 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -144,6 +144,7 @@ struct VncDisplay time_t expires; int auth; bool lossy; +bool non_adaptive; #ifdef CONFIG_VNC_TLS int subauth; /* Used by VeNCrypt */ VncDisplayTLS tls; -- 1.7.3.4
[Qemu-devel] [Bug 181561] Re: Hardy alpha [2-6] daily-live i386 don't boot
** Changed in: linux Importance: Unknown => Medium -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/181561 Title: Hardy alpha [2-6] daily-live i386 don't boot Status in The Linux Kernel: Fix Released Status in QEMU: Invalid Status in “linux” package in Ubuntu: Fix Released Status in “linux” package in Gentoo Linux: Won't Fix Bug description: Binary package hint: casper Since hardy alpha2 i386 daily-live, the system don't boot. Look at screenshot attached. This PC have seen dapper/feisty/gutsy livre cd booting well. What kind of informations can i provide ?
[Qemu-devel] [PATCH master/0.14] virtio-serial: Make sure virtqueue is ready before discarding data
This can happen if a port gets unplugged before guest has chance to initialise vqs. Reported-by: Juan Quintela Signed-off-by: Amit Shah --- hw/virtio-serial-bus.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 09e22aa..e05ab5e 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -117,6 +117,9 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev) { VirtQueueElement elem; +if (!virtio_queue_ready(vq)) { +return; +} while (virtqueue_pop(vq, &elem)) { virtqueue_push(vq, &elem, 0); } -- 1.7.3.5
Re: [Qemu-devel] Re: [PATCH] vnc: Fix password expiration through 'change vnc ""'
Anthony Liguori writes: > On 02/03/2011 11:02 AM, Daniel P. Berrange wrote: >> On Thu, Feb 03, 2011 at 10:35:51AM -0600, Anthony Liguori wrote: >> >>> On 02/03/2011 10:29 AM, Daniel P. Berrange wrote: >>> On Mon, Jan 31, 2011 at 02:43:19PM -0600, Anthony Liguori wrote: > commit 52c18be9e99dabe295321153fda7fce9f76647ac introduced a regression > in the > change vnc password command that changed the behavior of setting the VNC > password to an empty string from disabling login to disabling > authentication. > > This commit refactors the code to eliminate this overloaded semantics in > vnc_display_password and instead introduces the > vnc_display_disable_login. The > monitor implementation then determines the behavior of an empty or missing > string. > Personally I think this is a little overkill& just reverting the original patch was fine, but from a functional POV your patch produces the same results, so I won't argue. >>> For 0.15, I'd like to introduce a new set of commands such that we >>> don't multiplex the change command anymore. This refactoring lays >>> the ground work for that. >>> >>> For instance, if you created a block device with the name 'vnc', >>> you'd get very unexpected results! Multiplexing based on special >>> values on top of existing commands is pretty evil. >>> >> Doesn't Gerd's 'set_password' command already replace the functionality >> of the 'change vnc' command. So we should likely declare 'change vnc' >> as deprecated in 0.14 and remove it in 0.16 >> > > Yup. But it doesn't let you disable login. Since that was a feature > of 'change vnc', I think we need to provide a proper interface to do > this. > > Likewise, we need a new interface for changing the block device. The > way password setting is handled is fubar right now. Not just that. > I've got some new commands documented in a git tree if you're interested. > > http://repo.or.cz/w/qemu/aliguori.git/blob/refs/heads/glib:/qmp-schema.json The command to insert media into an empty block backend needs to support same range of media options as the command to create a block backend with media (that command is currently caught within drive_add, struggling to get out). My efforts to provide exactly that got bogged down last year by protracted design discussions on the finer points of its QMP interface, and the need to clean up and fix N+1 things before I can even start attacking the goal problem. Fortunately, much of the preliminary work got in. Unfortunately, I haven't been able to work on the rest, lately :( Media change is just a convenience command fusing eject and insert. For even more convenience, we can make it inherit option defaults from the media being replaced.
Re: [Qemu-devel] Re: [RFC: 0/2] patch for QEMU HPET periodic timer emulation to alleviate time drift
On 2011-02-04 03:06, Anthony Liguori wrote: > On 02/03/2011 03:24 PM, Jan Kiszka wrote: >> On 2011-02-03 21:07, Anthony Liguori wrote: >> >>> On 02/03/2011 09:28 AM, Jan Kiszka wrote: >>> On 2011-02-03 14:43, Ulrich Obergfell wrote: > Hi, > > I am observing severe backward time drift in a MS Windows Vista(tm) > guest running on a Fedora 14 KVM host. I can reproduce the problem > with the following steps: > > 1. Use 'vncviewer' to connect to the guest's desktop. > 2. Click on the menu title bar of a window on the guest's desktop. > 3. Move that window around on the guest's desktop. > > While I keep on moving the window around for one minute, the guest > time falls up to 15 seconds behind host time. > > The problem is caused by delayed callbacks of hpet_timer(). A timer > interrupt is injected into the guest during each callback. However, > interrupts are lost if delays are greater than a comparator period. > > > Yes, that's a well known limitation of qemu, in fact. We are lacking a generic irq coalescing infrastructure. That, once designed and available, would also allow to fix the HPET. >>> I don't think it requires anything that sophisticated. >>> >>> It's just the period calculation of the HPET that's wrong and doesn't >>> account for loss. >>> >> Blind (/wrt the guest state) reinjection from the iothread will >> compensate for lost time of *that* thread but not of the target vcpu(s). >> > > Is the case your concern about where you try to set an interrupt from > the I/O thread and the VCPU is not scheduled such that it doesn't > actually get injected into KVM until after the period is over? > > This should be a rare event. If you are missing 50% of your > notifications, not amount of gradual catchup is going to help you out. But that's the only thing this patch is after: lost ticks at QEMU level. > >> So, depending on your workload, you may reduce the drift more or less, >> but you won't fix it this way. >> > > There is no such thing as "fix" it. Time drift can happen on bare metal > too. Interrupts can be coalesced due to crappy SMM code. It's > something we see quite a lot in practice. We don't have this issues. Relative to the host's time base, we can actually prevent lost ticks, thus drift. > > My point is that there's really low hanging fruit and while for some > curious reason I don't actually see this patch, I believe that a patch > like this probably can help us quite a lot in the short term. > > The think the two biggest problems we have right now are bad period > calculations due to sloppy unit conversion (PIT/RTC) and lack of > accounting for missed periods. I don't disagree. The question is just how to detect guest-missed ticks. > > It's worth noting again that if you don't use a gradual catchup policy, > interrupt notifiers are extremely important because you're not going to > inject before the end of the interrupt window. However, with a gradual > policy, it shouldn't be a huge issue. Again, I don't disagree, but I would like to finally attack this in a non-ad-hoc manner, specifically when going upstream. The input & output infrastructure (aka injection feedback), and all these calculations should be generically available so that we do not reinvent the wheel every time we add another timer device that guests me use for time keeping. This issue is surely not an x86-only thing. Even on x86, we need it also for the PIT and the RTC, conceptually also for the APIC when configured in periodic mode. Jan signature.asc Description: OpenPGP digital signature
[Qemu-devel] [PATCH v3 13/16] vnc: use the new generic bitmap functions
Switch to bitmap.h and bitops.h instead of redefining our own bitmap helpers. Signed-off-by: Corentin Chary --- ui/vnc.c | 91 ++--- ui/vnc.h |7 +++-- 2 files changed, 25 insertions(+), 73 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index 8c7cb0d..6c57b0e 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -41,13 +41,6 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 }; #include "vnc_keysym.h" #include "d3des.h" -#define count_bits(c, v) { \ -for (c = 0; v; v >>= 1) \ -{ \ -c += v & 1; \ -} \ -} - static VncDisplay *vnc_display; /* needed for info vnc */ static DisplayChangeListener *dcl; @@ -378,47 +371,6 @@ static void framebuffer_update_request(VncState *vs, int incremental, static void vnc_refresh(void *opaque); static int vnc_refresh_server_surface(VncDisplay *vd); -static inline void vnc_set_bit(uint32_t *d, int k) -{ -d[k >> 5] |= 1 << (k & 0x1f); -} - -static inline void vnc_clear_bit(uint32_t *d, int k) -{ -d[k >> 5] &= ~(1 << (k & 0x1f)); -} - -static inline void vnc_set_bits(uint32_t *d, int n, int nb_words) -{ -int j; - -j = 0; -while (n >= 32) { -d[j++] = -1; -n -= 32; -} -if (n > 0) -d[j++] = (1 << n) - 1; -while (j < nb_words) -d[j++] = 0; -} - -static inline int vnc_get_bit(const uint32_t *d, int k) -{ -return (d[k >> 5] >> (k & 0x1f)) & 1; -} - -static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2, - int nb_words) -{ -int i; -for(i = 0; i < nb_words; i++) { -if ((d1[i] & d2[i]) != 0) -return 1; -} -return 0; -} - static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) { int i; @@ -441,7 +393,7 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) for (; y < h; y++) for (i = 0; i < w; i += 16) -vnc_set_bit(s->dirty[y], (x + i) / 16); +set_bit((x + i) / 16, s->dirty[y]); } void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, @@ -780,7 +732,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int memmove(dst_row, src_row, cmp_bytes); QTAILQ_FOREACH(vs, &vd->clients, next) { if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { -vnc_set_bit(vs->dirty[y], ((x + dst_x) / 16)); +set_bit(((x + dst_x) / 16), vs->dirty[y]); } } } @@ -850,10 +802,12 @@ static int find_and_clear_dirty_height(struct VncState *vs, for (h = 1; h < (vd->server->height - y); h++) { int tmp_x; -if (!vnc_get_bit(vs->dirty[y + h], last_x)) +if (!test_bit(last_x, vs->dirty[y + h])) { break; -for (tmp_x = last_x; tmp_x < x; tmp_x++) -vnc_clear_bit(vs->dirty[y + h], tmp_x); +} +for (tmp_x = last_x; tmp_x < x; tmp_x++) { +clear_bit(tmp_x, vs->dirty[y + h]); +} } return h; @@ -905,11 +859,10 @@ static int vnc_update_client(VncState *vs, int has_dirty) int x; int last_x = -1; for (x = 0; x < width / 16; x++) { -if (vnc_get_bit(vs->dirty[y], x)) { +if (test_and_clear_bit(x, vs->dirty[y])) { if (last_x == -1) { last_x = x; } -vnc_clear_bit(vs->dirty[y], x); } else { if (last_x != -1) { int h = find_and_clear_dirty_height(vs, y, last_x, x); @@ -1702,8 +1655,7 @@ static void framebuffer_update_request(VncState *vs, int incremental, if (!incremental) { vs->force_update = 1; for (i = 0; i < h; i++) { -vnc_set_bits(vs->dirty[y_position + i], - (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS); +bitmap_set(vs->dirty[y_position + i], x_position / 16, w / 16); } } } @@ -1842,15 +1794,15 @@ static void set_pixel_format(VncState *vs, vs->clientds = *(vs->vd->guest.ds); vs->clientds.pf.rmax = red_max; -count_bits(vs->clientds.pf.rbits, red_max); +vs->clientds.pf.rbits = hweight_long(red_max); vs->clientds.pf.rshift = red_shift; vs->clientds.pf.rmask = red_max << red_shift; vs->clientds.pf.gmax = green_max; -count_bits(vs->clientds.pf.gbits, green_max); +vs->clientds.pf.gbits = hweight_long(green_max); vs->clientds.pf.gshift = green_shift; vs->clientds.pf.gmask = green_max << green_shift; vs->clientds.pf.bmax = blue_max; -count_bits(vs->clientds.pf.bbits, blue_max); +vs->clientds.pf.bbits = hweight_long(blue_max); vs->clientds.pf.bshift = blue_shift; vs->clientds.pf.bmask = blue_max << blue_shift; vs->clientds.pf.bits_per_pixel = bits_per_pixel; @@ -2315,7 +226
[Qemu-devel] [PATCH v3 15/16] vnc: tight: tweak adaptive tight settings
The force_jpeg threshold was too low. Signed-off-by: Corentin Chary --- ui/vnc-enc-tight.c | 20 ++-- 1 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c index 81024d5..82c1e96 100644 --- a/ui/vnc-enc-tight.c +++ b/ui/vnc-enc-tight.c @@ -79,16 +79,16 @@ static const struct { int jpeg_idx; /* Allow indexed JPEG */ int jpeg_full; /* Allow full color JPEG */ } tight_jpeg_conf[] = { -{ 0, 4, 1, 1 }, -{ 0, 4, 1, 1 }, -{ 0, 4, 1, 1 }, -{ 0, 4, 1, 1 }, -{ 0, 4, 0, 1 }, -{ 0.1, 4, 0, 1 }, -{ 0.2, 4, 0, 1 }, -{ 0.3, 6, 0, 0 }, -{ 0.4, 8, 0, 0 }, -{ 0.5, 10, 0, 0 }, +{ 0, 8, 1, 1 }, +{ 0, 8, 1, 1 }, +{ 0, 8, 1, 1 }, +{ 0, 8, 1, 1 }, +{ 0, 10, 1, 1 }, +{ 0.1, 10, 1, 1 }, +{ 0.2, 10, 1, 1 }, +{ 0.3, 12, 0, 0 }, +{ 0.4, 14, 0, 0 }, +{ 0.5, 16, 0, 0 }, }; #endif -- 1.7.3.4
Re: [Qemu-devel] Re: [RFC: 0/2] patch for QEMU HPET periodic timer emulation to alleviate time drift
Anthony, in reply to: > My point is that there's really low hanging fruit and while for some > curious reason I don't actually see this patch, I believe that a patch > like this probably can help us quite a lot in the short term. I've sent the patch in two separate emails: - code part 1 (introduces the qemu command line option) http://article.gmane.org/gmane.comp.emulators.kvm.devel/67347 - code part 2 (implements compensation of lost interrupts) http://article.gmane.org/gmane.comp.emulators.kvm.devel/67348 Regards, Uli Obergfell
[Qemu-devel] [Bug 712416] Re: kvm_intel kernel module crash with via nano vmx
Thanks for your help. I've subscribed to these mailing list. Have i do report the bug in these mailing list too ? (or is it a useless other duplication ?) -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/712416 Title: kvm_intel kernel module crash with via nano vmx Status in QEMU: New Status in “kvm” package in Ubuntu: Incomplete Status in “kvm” package in Debian: New Bug description: kvm module for hardware virtualisation not work properly on via nano processors. Tested with processor: VIA Nano processor U2250. Processors flags (visible in /proc/cpuinfo): fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush acpi mmx fxsr sse sse2 ss tm syscall nx lm constant_tsc up rep_good pni monitor vmx est tm2 ssse3 cx16 xtpr rng rng_en ace ace_en ace2 phe phe_en lahf_lm With kernel 2.6.32: kvm not work and dmesg contains a lot of: handle_exception: unexpected, vectoring info 0x800d intr info 0x8b0d With kernel 2.6.35: all the system crash. Nothing visible in logs
Re: [Qemu-devel] [PATCH] Change snapshot_blkdev hmp to use correct argument type for device
On Fri, Feb 4, 2011 at 8:22 AM, wrote: > From: Jes Sorensen > > Pointed out by Markus > > Signed-off-by: Jes Sorensen > --- > hmp-commands.hx | 2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) Reviewed-by: Stefan Hajnoczi
Re: [Qemu-devel] [PATCH] qcow2: Add full image preallocation option
On Thu, Jan 27, 2011 at 11:45:55AM -0600, Anthony Liguori wrote: > On 01/27/2011 09:52 AM, Kevin Wolf wrote: > >This adds a preallocation=full mode to qcow2 image creation, which does not > >only allocate metadata for the whole image, but also writes zeros to it, > >creating a non-sparse image file. > > The writing zeros bit is in order to support physical devices? > Would it be better to have a flag in BlockDriverState that indicated > whether uninitialized sectors could be assumed to be zero filled and > key off of that? There is already: int bdrv_has_zero_init(BlockDriverState *bs); Stefan
Re: [Qemu-devel] [PATCH] target-arm: Set the right overflow bit for neon 32 and 64 bit saturating add/sub.
On 24 January 2011 12:41, Christophe Lyon wrote: > Here is an updated patch with these minor fixes. > +uint64_t HELPER(neon_qadd_u64)(CPUState *env, uint64_t src1, uint64_t src2) > +{ > + uint64_t res; > + > + res = src1 + src2; > + if (res < src1) { > + SET_QC(); > + res = ~(uint64_t)0; > + } > + return res; > +} Indentation is still wrong here (not sure why checkpatch didn't spot it) and in the other s64 and u64 helpers. Sorry I didn't notice that last time round. When you resubmit v3 can you make sure you use the right email format to give a sensible git commit message, please? (ie random commentary below the '---' so it doesn't go in the git changelog.) Thanks -- PMM
[Qemu-devel] New stable branch information
To help make the stable branch more active than it has been in the past, I'd like to split the stable branch into a separate tree to allow the tree to develop a life of its own over time. I'd like to begin this process with 0.14 and as such, have created a new stable tree at git://git.qemu.org/qemu-stable-0.14.git. Justin Forbes has volunteered to help collect patches for this tree. The same stable rules still apply: patches should go into master first except for rare exceptions where that's feasible. I plan on making the stable-0.14 branch in git be a mirror of the stable-0.14.git tree so it shouldn't really affect most people. However, I probably won't set this up until after next week. Regards, Anthony Liguori
[Qemu-devel] [PATCH v3 0/2] virtagent - fsfreeze support
From: Jes Sorensen Hi This is a first attempt to add fsfreeze support to virtagent. The idea is for the guest agent to walk the list of locally mounted file systems in the guest, and issuing an ioctl to freeze them. The host can then do a live snapshot of the guest, obtaining stable file systems. After the snapshot, the host then calls the thaw function in virtagent, which goes through the list of previously frozen file systems and unfreezes them. The list walking ignores remote file systems such as NFS and CIFS as well as all pseudo file systems. The guest agent code is in the first patch, and host agent code is in the second patch. For now there is only human monitor support, but it should be pretty straight forward to add QMP support as well. Comments and suggestions welcome! v3 of the patch encapsulates the freeze states in a struct and fixes some tab issues that I had missed. Both pointed out by Michael Roth. v2 of the patch addresses the issues pointed out by Stefan and Michael. Note I will be gone all of next week, so if I don't reply it's because I am busy skiing :) Cheers, Jes Jes Sorensen (2): Add virtagent file system freeze/thaw Add monitor commands for fsfreeze support hmp-commands.hx| 48 +++ virtagent-common.h |9 ++ virtagent-server.c | 195 +++ virtagent.c| 235 virtagent.h|9 ++ 5 files changed, 496 insertions(+), 0 deletions(-) -- 1.7.3.5
Re: [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
On 02/03/11 18:41, Michael Roth wrote: > On 02/02/2011 02:48 AM, Jes Sorensen wrote: >> Yes very much so[1] - one reason why it would be nice to have virtagent >> use threads to execute the actual commands. We should probably add a >> flag to agent commands indicating whether they issue disk I/O or not, so >> we can block attempts to execute commands that do so, while the guest is >> frozen. > > **Warning, epic response** > > For things like logging and i/o on a frozen system...I agree we'd need > some flag for these kinds of situations. Maybe a disable_logging() > flagi really don't like this though... I'd imagine even syslogd() > could block virtagent in this type of situation, so that would need to > be disabled as well. One way to resolve this would be to have the logging handled in it's own thread, which uses non blocking calls to do the actual logging. Obviously we'd have to use a non file system based communication method between the main thread and the logging thread :) > But doing so completely subverts our attempts and providing proper > accounting of what the agent is doing to the user. A user can freeze the > filesystem, knowing that logging would be disabled, then prod at > whatever he wants. So the handling should be something specific to > fsfreeze, with stricter requirements: > > If a user calls fsfreeze(), we disable logging, but also disable the > ability to do anything other than fsthaw() or fsstatus(). This actually > solves the potential deadlocking problem for other RPCs as well...since > they cant be executed in the first place. I disagree that we should block all calls, except for fsfreeze/fsstatus/ fsthaw in this case. There are other calls that could be valid in this situations, so I think it needs to be evaluated on a case by case basis. > So a solution for these situations is still needed, and I'm starting to > agree that threads are needed, but I don't think we should do RPCs > concurrently (not sure if that's what is being suggested or not). At > least, there's no pressing reason for it as things currently stand > (there aren't currently any RPCs where fast response times are all that > important, so it's okay to serialize them behind previous RPCs, and > HMP/QMP are command at a time), and it's something that Im fairly > confident can be added if the need arises in the future. Eventually I think we will need to be able to support concurrent RPC calls. There can be situations where an operation takes a long time while it is valid to be able to ping the guest agent to verify that it is still alive etc. Cheers, Jes
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
On 02/02/2011 01:28 PM, Stefan Weil wrote: Hello, these are some patches which I found on my stack of open patches. All of them should go into 0.14, and at least some of them could also be applied to 0.13. This need the following Acks: [PATCH] hw/fmopl: Fix buffer access out-of-bounds errors (http://patchwork.ozlabs.org/patch/79054/) malc [PATCH] linux-user: Fix possible realloc memory leak (http://patchwork.ozlabs.org/patch/79217/) Riku [PATCH 1/3] tests: Fix two memory leaks (http://patchwork.ozlabs.org/patch/79945/) [PATCH 2/3] check-qdict: Fix possible crash (http://patchwork.ozlabs.org/patch/79946/) Luiz [PATCH 3/3] w64: Fix problem with missing sigset_t (http://patchwork.ozlabs.org/patch/79947/) We don't support w64... [PATCH 1/3] pci: Fix memory leak (http://patchwork.ozlabs.org/patch/79996/) mst (looks like he did) [PATCH 2/3] ppc405: Fix memory leak (http://patchwork.ozlabs.org/patch/79997/) [PATCH 3/3] s390: Fix memory leak (http://patchwork.ozlabs.org/patch/79998/) Alex for both of these. Regards, Anthony Liguori [PATCH] Fix trivial "endianness bugs" (http://patchwork.ozlabs.org/patch/80223/) [PATCH] HACKING: Update status of format checking (http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg02476.html) [PATCH] mingw32: Fix definitions for PRId64, PRIx64, PRIu64, PRIo64 (http://patchwork.ozlabs.org/patch/74276/) Regards, Stefan Weil
[Qemu-devel] [PATCH 2/2] Add monitor commands for fsfreeze support
From: Jes Sorensen This patch adds the following monitor commands: agent_fsfreeze: - Freezes all local file systems in the guest. Command will print the number of file systems that were frozen. agent_fsthaw: - Thaws all local file systems in the guest. Command will print the number of file systems that were thawed. agent_fsstatus: - Prints the current status of file systems in the guest: Thawed, frozen, thaw in progress, freeze in progress, error. Signed-off-by: Jes Sorensen --- hmp-commands.hx| 48 +++ virtagent-common.h |1 + virtagent.c| 235 virtagent.h|9 ++ 4 files changed, 293 insertions(+), 0 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 9c7ac0b..f4150da 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1310,6 +1310,54 @@ STEXI Fetch and re-negotiate guest agent capabilties ETEXI +{ +.name = "agent_fsfreeze", +.args_type = "", +.params = "", +.help = "Freeze all local file systems mounted in the guest", +.user_print = do_agent_fsfreeze_print, +.mhandler.cmd_async = do_agent_fsfreeze, +.flags = MONITOR_CMD_ASYNC, +}, + +STEXI +@item agent_fsfreeze +@findex agent_fsfreeze +Freeze all local mounted file systems in guest +ETEXI + +{ +.name = "agent_fsthaw", +.args_type = "", +.params = "", +.help = "Thaw all local file systems mounted in the guest", +.user_print = do_agent_fsthaw_print, +.mhandler.cmd_async = do_agent_fsthaw, +.flags = MONITOR_CMD_ASYNC, +}, + +STEXI +@item agent_fsthaw +@findex agent_fsthaw +Thaw all local mounted file systems in guest +ETEXI + +{ +.name = "agent_fsstatus", +.args_type = "", +.params = "", +.help = "Display status of file system freeze progress in guest", +.user_print = do_agent_fsstatus_print, +.mhandler.cmd_async = do_agent_fsstatus, +.flags = MONITOR_CMD_ASYNC, +}, + +STEXI +@item agent_fsstatus +@findex agent_fsstatus +Get status of file system freeze in guest +ETEXI + STEXI @end table ETEXI diff --git a/virtagent-common.h b/virtagent-common.h index 7c6d9ef..ff7bf23 100644 --- a/virtagent-common.h +++ b/virtagent-common.h @@ -24,6 +24,7 @@ #include "monitor.h" #include "virtagent-server.h" #include "virtagent.h" +#include "qint.h" #define DEBUG_VA diff --git a/virtagent.c b/virtagent.c index b5e7944..4277802 100644 --- a/virtagent.c +++ b/virtagent.c @@ -640,3 +640,238 @@ int va_send_hello(void) xmlrpc_DECREF(params); return ret; } + +void do_agent_fsfreeze_print(Monitor *mon, const QObject *data) +{ +TRACE("called"); + +monitor_printf(mon, "File systems frozen: %" PRId64 "\n", + qint_get_int((qobject_to_qint(data; +} + +static void do_agent_fsfreeze_cb(const char *resp_data, + size_t resp_data_len, + MonitorCompletion *mon_cb, + void *mon_data) +{ +xmlrpc_value *resp = NULL; +xmlrpc_env env; +xmlrpc_int32 retval = 0; +QInt *qint; + +TRACE("called"); + +if (resp_data == NULL) { +LOG("error handling RPC request"); +return; +} + +xmlrpc_env_init(&env); +resp = xmlrpc_parse_response(&env, resp_data, resp_data_len); +if (va_rpc_has_error(&env)) { +LOG("error parsing RPC response"); +return; +} + +xmlrpc_parse_value(&env, resp, "i", &retval); +if (va_rpc_has_error(&env)) { +retval = -1; +goto out; +} + +out: +qint = qint_from_int(retval); +xmlrpc_DECREF(resp); +if (mon_cb) { +mon_cb(mon_data, QOBJECT(qint)); +} +qobject_decref(QOBJECT(qint)); +} + +int do_agent_fsfreeze(Monitor *mon, const QDict *mon_params, + MonitorCompletion cb, void *opaque) +{ +xmlrpc_env env; +xmlrpc_value *params; +int ret; + +TRACE("called"); + +xmlrpc_env_init(&env); +params = xmlrpc_build_value(&env, "()"); +if (va_rpc_has_error(&env)) { +return -1; +} + +ret = va_do_rpc(&env, "va.fsfreeze", params, do_agent_fsfreeze_cb, +cb, opaque); +if (ret) { +qerror_report(QERR_VA_FAILED, ret, strerror(ret)); +} +xmlrpc_DECREF(params); +return ret; +} + +void do_agent_fsthaw_print(Monitor *mon, const QObject *data) +{ +TRACE("called"); + +monitor_printf(mon, "File systems thawed: %" PRId64 "\n", + qint_get_int((qobject_to_qint(data; +} + +static void do_agent_fsthaw_cb(const char *resp_data, + size_t resp_data_len, + MonitorCompletion *mon_cb, + void *mon_data) +{ +xmlrpc_value *resp = NULL; +xmlrpc_env env
Re: [Qemu-devel] [PATCH] target-arm: Fix Neon vsra instructions.
On 25 January 2011 17:18, Christophe Lyon wrote: > This patch fixes the errors reported by my tests in VSRA. > > Signed-off-by: Christophe Lyon Reviewed-by: Peter Maydell
[Qemu-devel] Re: [PATCH master/0.14] virtio-serial: Make sure virtqueue is ready before discarding data
Amit Shah wrote: > This can happen if a port gets unplugged before guest has chance to > initialise vqs. > > Reported-by: Juan Quintela > Signed-off-by: Amit Shah > --- > hw/virtio-serial-bus.c |3 +++ > 1 files changed, 3 insertions(+), 0 deletions(-) > > diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c > index 09e22aa..e05ab5e 100644 > --- a/hw/virtio-serial-bus.c > +++ b/hw/virtio-serial-bus.c > @@ -117,6 +117,9 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice > *vdev) > { > VirtQueueElement elem; > > +if (!virtio_queue_ready(vq)) { > +return; > +} > while (virtqueue_pop(vq, &elem)) { > virtqueue_push(vq, &elem, 0); > } Reviewed-by: Juan Quintela
[Qemu-devel] Re: [PATCH 1/2] Add virtagent file system freeze/thaw
On 02/03/11 19:11, Michael Roth wrote: >> @@ -217,6 +221,186 @@ static xmlrpc_value *va_hello(xmlrpc_env *env, >> return result; >> } >> >> + >> +/* >> + * Walk the mount table and build a list of local file systems >> + */ >> + >> +struct direntry { >> +char *dirname; >> +char *devtype; >> +struct direntry *next; >> +}; >> + >> +static struct direntry *va_mount_list; >> +static int va_fsfreeze_status; > > And what I meant in the last RFC about using "objects" was to > encapsulate global state information for a particular group of commands > in single data type/variable. We're gonna end up with a similar set of > variables for stateful RPCs like copyfile and potentially a few for > things like spice. So to avoid having things get too cluttered up I'd > prefer something like, in this particular case: > > typedef struct VAFSFreezeState { > struct direntry *mount_list; > int status; > } VAFSFeezeState; > > static VAFSFreezeState va_fsfreeze_state; Ok, I got rid of the tabs (damn I thought I had caught them all), and added a struct to keep the freeze state. I didn't add any typedef grossness though. v3 coming up. Cheers, Jes
Re: [Qemu-devel] Re: phys_page_find bug?
Tested-by: Artyom Tarasenko > There's two bugs in phys_page_find_alloc(). When the bottom level L2 > table is populated with IO_MEM_UNASSIGNED, region_offset is then used > for reporting the physical address. First, region_offset may not be > aligned to the base address of the L2 region. And second, region_offset > won't hold the full 36-bit address on a 32-bit host. > > It seems that both can be fixed by returning NULL for unassigned > addresses from phys_page_find(). All callers already handle a NULL > return value. Would this allow any further optimizations to be made? > > Here's a patch to try: > > diff --git a/exec.c b/exec.c > index 49c28b1..77b49c8 100644 > --- a/exec.c > +++ b/exec.c > @@ -434,7 +434,11 @@ static PhysPageDesc > *phys_page_find_alloc(target_phys_addr_t index, int alloc) > > static inline PhysPageDesc *phys_page_find(target_phys_addr_t index) > { > - return phys_page_find_alloc(index, 0); > + PhysPageDesc *pd = phys_page_find_alloc(index, 0); > + if (pd && pd->phys_offset == IO_MEM_UNASSIGNED) { > + return NULL; > + } > + return pd; > } > > static void tlb_protect_code(ram_addr_t ram_addr); > > > -- Regards, Artyom Tarasenko solaris/sparc under qemu blog: http://tyom.blogspot.com/
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
On 02/04/2011 01:30 PM, Anthony Liguori wrote: [PATCH 3/3] w64: Fix problem with missing sigset_t (http://patchwork.ozlabs.org/patch/79947/) We don't support w64... AFAIK mingw-w64 supports both 32-bit and 64-bit compilation, so the patch subject is misleading. Paolo
[Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
From: Jes Sorensen Implement freeze/thaw support in the guest, allowing the host to request the guest freezes all it's file systems before a live snapshot is performed. - fsfreeze(): Walk the list of mounted local real file systems, and freeze them. - fsthaw(): Walk the list of previously frozen file systems and thaw them. - fsstatus(): Return the current status of freeze/thaw. The host must poll this function, in case fsfreeze() returned with a timeout, to wait for the operation to finish. Signed-off-by: Jes Sorensen --- virtagent-common.h |8 ++ virtagent-server.c | 195 2 files changed, 203 insertions(+), 0 deletions(-) diff --git a/virtagent-common.h b/virtagent-common.h index 5d8f5c1..7c6d9ef 100644 --- a/virtagent-common.h +++ b/virtagent-common.h @@ -61,6 +61,14 @@ typedef struct VAContext { const char *channel_path; } VAContext; +enum va_fsfreeze_status { +FREEZE_ERROR = -1, +FREEZE_THAWED = 0, +FREEZE_INPROGRESS = 1, +FREEZE_FROZEN = 2, +FREEZE_THAWINPROGRESS = 3, +}; + enum va_job_status { VA_JOB_STATUS_PENDING = 0, VA_JOB_STATUS_OK, diff --git a/virtagent-server.c b/virtagent-server.c index 7bb35b2..5140918 100644 --- a/virtagent-server.c +++ b/virtagent-server.c @@ -14,6 +14,10 @@ #include #include "qemu_socket.h" #include "virtagent-common.h" +#include +#include +#include +#include static VAServerData *va_server_data; static bool va_enable_syslog = false; /* enable syslog'ing of RPCs */ @@ -217,6 +221,191 @@ static xmlrpc_value *va_hello(xmlrpc_env *env, return result; } + +/* + * Walk the mount table and build a list of local file systems + */ + +struct direntry { +char *dirname; +char *devtype; +struct direntry *next; +}; + +struct va_freezestate { +struct direntry *mount_list; +int status; +}; + +static struct va_freezestate freezestate; + +static int build_mount_list(void) +{ +struct mntent *mnt; +struct direntry *entry; +struct direntry *next; +char const *mtab = MOUNTED; +FILE *fp; + +fp = setmntent(mtab, "r"); +if (!fp) { +fprintf(stderr, "unable to read mtab\n"); +goto fail; +} + +while ((mnt = getmntent(fp))) { +/* + * An entry which device name doesn't start with a '/' is + * either a dummy file system or a network file system. + * Add special handling for smbfs and cifs as is done by + * coreutils as well. + */ +if ((mnt->mnt_fsname[0] != '/') || +(strcmp(mnt->mnt_type, "smbfs") == 0) || +(strcmp(mnt->mnt_type, "cifs") == 0)) { +continue; +} + +entry = qemu_malloc(sizeof(struct direntry)); +entry->dirname = qemu_strdup(mnt->mnt_dir); +entry->devtype = qemu_strdup(mnt->mnt_type); +entry->next = freezestate.mount_list; + +freezestate.mount_list = entry; +} + +endmntent(fp); + +return 0; + +fail: +while(freezestate.mount_list) { +next = freezestate.mount_list->next; +qemu_free(freezestate.mount_list->dirname); +qemu_free(freezestate.mount_list->devtype); +qemu_free(freezestate.mount_list); +freezestate.mount_list = next; +} + +return -1; +} + +/* + * va_fsfreeze(): Walk list of mounted file systems in the guest, and + * freeze the ones which are real local file systems. + * rpc return values: Number of file systems frozen, -1 on error. + */ +static xmlrpc_value *va_fsfreeze(xmlrpc_env *env, + xmlrpc_value *params, + void *user_data) +{ +xmlrpc_int32 ret = 0, i = 0; +xmlrpc_value *result; +struct direntry *entry; +int fd; +SLOG("va_fsfreeze()"); + +if (freezestate.status != FREEZE_THAWED) { +ret = 0; +goto out; +} + +ret = build_mount_list(); +if (ret < 0) { +goto out; +} + +freezestate.status = FREEZE_INPROGRESS; + +entry = freezestate.mount_list; +while(entry) { +fd = qemu_open(entry->dirname, O_RDONLY); +if (fd == -1) { +ret = errno; +goto error; +} +ret = ioctl(fd, FIFREEZE); +close(fd); +if (ret < 0 && ret != EOPNOTSUPP) { +goto error; +} + +entry = entry->next; +i++; +} + +freezestate.status = FREEZE_FROZEN; +ret = i; +out: +result = xmlrpc_build_value(env, "i", ret); +return result; +error: +if (i > 0) { +freezestate.status = FREEZE_ERROR; +} +goto out; +} + +/* + * va_fsthaw(): Walk list of frozen file systems in the guest, and + * thaw them. + * rpc return values: Number of file systems thawed on success, -1 on error. + */ +static xmlrpc_value *va_fsthaw(xmlrpc_env *env, + xmlrpc_value *params, +
[Qemu-devel] 0.14.0 Release Schedule - Update
I've also updated http://wiki.qemu.org/Planning/0.14 No dates were changed, but I've put in dates for two release candidates. I'll be travelling over the next week but I don't expect that to be a problem here. Please note that the dates are targets for tagging. Formal announcements will lag about 24 hours. I'd like to also take this opportunity to encourage everyone to visit the testing wiki page and either contribute with things you've been testing or pick an area to test. http://wiki.qemu.org/Planning/0.14/Testing Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH 0.14] savevm: fix corruption in vmstate_subsection_load().
On 02/02/2011 10:34 PM, Yoshiaki Tamura wrote: Although it's rare to happen in live migration, when the head of a byte stream contains 0x05 which is the marker of subsection, the loader gets corrupted because vmstate_subsection_load() continues even the device doesn't require it. This patch adds a checker whether subsection is needed, and skips following routines if not needed. Signed-off-by: Yoshiaki Tamura Acked-by: Paolo Bonzini Applied to master, Thanks. Regards, Anthony Liguori --- savevm.c | 10 +- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/savevm.c b/savevm.c index 4453217..6d83b0f 100644 --- a/savevm.c +++ b/savevm.c @@ -1638,6 +1638,12 @@ static const VMStateDescription *vmstate_get_subsection(const VMStateSubsection static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, void *opaque) { +const VMStateSubsection *sub = vmsd->subsections; + +if (!sub || !sub->needed) { +return 0; +} + while (qemu_peek_byte(f) == QEMU_VM_SUBSECTION) { char idstr[256]; int ret; @@ -1650,10 +1656,11 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, idstr[len] = 0; version_id = qemu_get_be32(f); -sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr); +sub_vmsd = vmstate_get_subsection(sub, idstr); if (sub_vmsd == NULL) { return -ENOENT; } +assert(!sub_vmsd->subsections); ret = vmstate_load_state(f, sub_vmsd, opaque, version_id); if (ret) { return ret; @@ -1677,6 +1684,7 @@ static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, qemu_put_byte(f, len); qemu_put_buffer(f, (uint8_t *)vmsd->name, len); qemu_put_be32(f, vmsd->version_id); +assert(!vmsd->subsections); vmstate_save_state(f, vmsd, opaque); } sub++;
Re: [Qemu-devel] [PATCH v2 1/3] use nanoseconds everywhere for timeout computation
On 02/03/2011 07:48 AM, Paolo Bonzini wrote: Suggested by Aurelien Jarno. Signed-off-by: Paolo Bonzini Applied to master, Thanks. Regards, Anthony Liguori --- qemu-timer.c | 30 +++--- 1 files changed, 15 insertions(+), 15 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index db1ec49..60283a8 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -197,8 +197,8 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) t->rearm(t); } -/* TODO: MIN_TIMER_REARM_US should be optimized */ -#define MIN_TIMER_REARM_US 250 +/* TODO: MIN_TIMER_REARM_NS should be optimized */ +#define MIN_TIMER_REARM_NS 25 #ifdef _WIN32 @@ -698,11 +698,11 @@ int64_t qemu_next_deadline(void) if (active_timers[QEMU_CLOCK_VIRTUAL]) { delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time - - qemu_get_clock(vm_clock); + qemu_get_clock_ns(vm_clock); } if (active_timers[QEMU_CLOCK_HOST]) { int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time - - qemu_get_clock(host_clock); + qemu_get_clock_ns(host_clock); if (hdelta< delta) delta = hdelta; } @@ -727,17 +727,17 @@ static uint64_t qemu_next_deadline_dyntick(void) if (use_icount) delta = INT32_MAX; else -delta = (qemu_next_deadline() + 999) / 1000; +delta = qemu_next_deadline(); if (active_timers[QEMU_CLOCK_REALTIME]) { -rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time - - qemu_get_clock(rt_clock))*1000; +rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time * 100 - + qemu_get_clock_ns(rt_clock)); if (rtdelta< delta) delta = rtdelta; } -if (delta< MIN_TIMER_REARM_US) -delta = MIN_TIMER_REARM_US; +if (delta< MIN_TIMER_REARM_NS) +delta = MIN_TIMER_REARM_NS; return delta; } @@ -887,8 +887,8 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t) { timer_t host_timer = (timer_t)(long)t->priv; struct itimerspec timeout; -int64_t nearest_delta_us = INT64_MAX; -int64_t current_us; +int64_t nearest_delta_ns = INT64_MAX; +int64_t current_ns; assert(alarm_has_dynticks(t)); if (!active_timers[QEMU_CLOCK_REALTIME]&& @@ -896,7 +896,7 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t) !active_timers[QEMU_CLOCK_HOST]) return; -nearest_delta_us = qemu_next_deadline_dyntick(); +nearest_delta_ns = qemu_next_deadline_dyntick(); /* check whether a timer is already running */ if (timer_gettime(host_timer,&timeout)) { @@ -904,14 +904,14 @@ static void dynticks_rearm_timer(struct qemu_alarm_timer *t) fprintf(stderr, "Internal timer error: aborting\n"); exit(1); } -current_us = timeout.it_value.tv_sec * 100 + timeout.it_value.tv_nsec/1000; -if (current_us&& current_us<= nearest_delta_us) +current_ns = timeout.it_value.tv_sec * 10LL + timeout.it_value.tv_nsec; +if (current_ns&& current_ns<= nearest_delta_ns) return; timeout.it_interval.tv_sec = 0; timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */ -timeout.it_value.tv_sec = nearest_delta_us / 100; -timeout.it_value.tv_nsec = (nearest_delta_us % 100) * 1000; +timeout.it_value.tv_sec = nearest_delta_ns / 10; +timeout.it_value.tv_nsec = nearest_delta_ns % 10; if (timer_settime(host_timer, 0 /* RELATIVE */,&timeout, NULL)) { perror("settime"); fprintf(stderr, "Internal timer error: aborting\n");
Re: [Qemu-devel] [0.14?][PATCH v3 1/4] ioapic: Implement EOI handling for level-triggered IRQs
On 02/03/2011 03:54 PM, Jan Kiszka wrote: From: Jan Kiszka Add the missing EOI broadcast from local APIC to the IOAPICs on completion of level-triggered IRQs. This ensures that a still asserted IRQ source properly re-triggers an APIC IRQ. Signed-off-by: Jan Kiszka Applied to master, Thanks. Regards, Anthony Liguori --- hw/apic.c |9 ++--- hw/ioapic.c | 43 +-- hw/ioapic.h | 20 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 hw/ioapic.h diff --git a/hw/apic.c b/hw/apic.c index ff581f0..2f8376a 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -18,6 +18,7 @@ */ #include "hw.h" #include "apic.h" +#include "ioapic.h" #include "qemu-timer.h" #include "host-utils.h" #include "sysbus.h" @@ -57,7 +58,8 @@ #define ESR_ILLEGAL_ADDRESS (1<< 7) -#define APIC_SV_ENABLE (1<< 8) +#define APIC_SV_DIRECTED_IO (1<<12) +#define APIC_SV_ENABLE (1<<8) #define MAX_APICS 255 #define MAX_APIC_WORDS 8 @@ -420,8 +422,9 @@ static void apic_eoi(APICState *s) if (isrv< 0) return; reset_bit(s->isr, isrv); -/* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to -set the remote IRR bit for level triggered interrupts. */ +if (!(s->spurious_vec& APIC_SV_DIRECTED_IO)&& get_bit(s->tmr, isrv)) { +ioapic_eoi_broadcast(isrv); +} apic_update_irq(s); } diff --git a/hw/ioapic.c b/hw/ioapic.c index 2109568..8bc31f7 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -23,6 +23,7 @@ #include "hw.h" #include "pc.h" #include "apic.h" +#include "ioapic.h" #include "qemu-timer.h" #include "host-utils.h" #include "sysbus.h" @@ -36,7 +37,10 @@ #define DPRINTF(fmt, ...) #endif -#define IOAPIC_LVT_MASKED (1<<16) +#define MAX_IOAPICS 1 + +#define IOAPIC_LVT_MASKED (1<< 16) +#define IOAPIC_LVT_REMOTE_IRR (1<< 14) #define IOAPIC_TRIGGER_EDGE 0 #define IOAPIC_TRIGGER_LEVEL 1 @@ -61,6 +65,8 @@ struct IOAPICState { uint64_t ioredtbl[IOAPIC_NUM_PINS]; }; +static IOAPICState *ioapics[MAX_IOAPICS]; + static void ioapic_service(IOAPICState *s) { uint8_t i; @@ -83,8 +89,11 @@ static void ioapic_service(IOAPICState *s) dest_mode = (entry>> 11)& 1; delivery_mode = (entry>> 8)& 7; polarity = (entry>> 13)& 1; -if (trig_mode == IOAPIC_TRIGGER_EDGE) +if (trig_mode == IOAPIC_TRIGGER_EDGE) { s->irr&= ~mask; +} else { +s->ioredtbl[i] |= IOAPIC_LVT_REMOTE_IRR; +} if (delivery_mode == IOAPIC_DM_EXTINT) vector = pic_read_irq(isa_pic); else @@ -131,6 +140,29 @@ static void ioapic_set_irq(void *opaque, int vector, int level) } } +void ioapic_eoi_broadcast(int vector) +{ +IOAPICState *s; +uint64_t entry; +int i, n; + +for (i = 0; i< MAX_IOAPICS; i++) { +s = ioapics[i]; +if (!s) { +continue; +} +for (n = 0; n< IOAPIC_NUM_PINS; n++) { +entry = s->ioredtbl[n]; +if ((entry& IOAPIC_LVT_REMOTE_IRR)&& (entry& 0xff) == vector) { +s->ioredtbl[n] = entry& ~IOAPIC_LVT_REMOTE_IRR; +if (!(entry& IOAPIC_LVT_MASKED)&& (s->irr& (1<< n))) { +ioapic_service(s); +} +} +} +} +} + static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr) { IOAPICState *s = opaque; @@ -240,6 +272,11 @@ static int ioapic_init1(SysBusDevice *dev) { IOAPICState *s = FROM_SYSBUS(IOAPICState, dev); int io_memory; +static int ioapic_no; + +if (ioapic_no>= MAX_IOAPICS) { +return -1; +} io_memory = cpu_register_io_memory(ioapic_mem_read, ioapic_mem_write, s, @@ -248,6 +285,8 @@ static int ioapic_init1(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, ioapic_set_irq, IOAPIC_NUM_PINS); +ioapics[ioapic_no++] = s; + return 0; } diff --git a/hw/ioapic.h b/hw/ioapic.h new file mode 100644 index 000..cb2642a --- /dev/null +++ b/hw/ioapic.h @@ -0,0 +1,20 @@ +/* + * ioapic.c IOAPIC emulation logic + * + * Copyright (c) 2011 Jan Kiszka, Siemens AG + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License f
Re: [Qemu-devel] [PATCH master/0.14] virtio-serial: Make sure virtqueue is ready before discarding data
On 02/04/2011 02:54 AM, Amit Shah wrote: This can happen if a port gets unplugged before guest has chance to initialise vqs. Reported-by: Juan Quintela Signed-off-by: Amit Shah Applied to master, Thanks. Regards, Anthony Liguori --- hw/virtio-serial-bus.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 09e22aa..e05ab5e 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -117,6 +117,9 @@ static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev) { VirtQueueElement elem; +if (!virtio_queue_ready(vq)) { +return; +} while (virtqueue_pop(vq,&elem)) { virtqueue_push(vq,&elem, 0); }
Re: [Qemu-devel] [PATCH 0.14] ui/sdl: Fix handling of caps lock and num lock keys
On 02/03/2011 03:35 PM, Stefan Weil wrote: Starting with SDL version 1.2.14, caps lock and num lock keys will send a SDL_KEYUP when SDL_DISABLE_LOCK_KEYS=1 is set in the environment. The new code sets the environment unconditionally (it won't harm old versions which do not know it). The workaround for SDL_KEYUP is only compiled with old SDL versions. A similar patch without handling of old SDL versions was already published by Benjamin Drung for Ubuntu. Cc: Anthony Liguori Cc: Kevin Wolf Cc: Benjamin Drung Signed-off-by: Stefan Weil Applied to master, Thanks. Regards, Anthony Liguori --- ui/sdl.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/ui/sdl.c b/ui/sdl.c index a1458ce..47ac49c 100644 --- a/ui/sdl.c +++ b/ui/sdl.c @@ -388,12 +388,16 @@ static void sdl_process_key(SDL_KeyboardEvent *ev) else modifiers_state[keycode] = 1; break; +#define QEMU_SDL_VERSION ((SDL_MAJOR_VERSION<< 8) + SDL_MINOR_VERSION) +#if QEMU_SDL_VERSION< 0x102 || QEMU_SDL_VERSION == 0x102&& SDL_PATCHLEVEL< 14 +/* SDL versions before 1.2.14 don't support key up for caps/num lock. */ case 0x45: /* num lock */ case 0x3a: /* caps lock */ /* SDL does not send the key up event, so we generate it */ kbd_put_keycode(keycode); kbd_put_keycode(keycode | SCANCODE_UP); return; +#endif } /* now send the key code */ @@ -831,6 +835,10 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0); } +/* Enable normal up/down events for Caps-Lock and Num-Lock keys. + * This requires SDL>= 1.2.14. */ +setenv("SDL_DISABLE_LOCK_KEYS", "1", 1); + flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE; if (SDL_Init (flags)) { fprintf(stderr, "Could not initialize SDL(%s) - exiting\n",
Re: [Qemu-devel] [PATCH v3 01/16] vnc: qemu can die if the client is disconnected while updating screen
On 02/04/2011 02:05 AM, Corentin Chary wrote: agraf reported that qemu_mutex_destroy(vs->output_mutex) while failing in vnc_disconnect_finish(). It's because vnc_worker_thread_loop() tries to unlock the mutex while not locked. The unlocking call doesn't fail (pthread bug ?), but the destroy call does. Signed-off-by: Corentin Chary Applied (just this patch) to master, Thanks. Regards, Anthony Liguori --- ui/vnc-jobs-async.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c index 6e9cf08..0b5d750 100644 --- a/ui/vnc-jobs-async.c +++ b/ui/vnc-jobs-async.c @@ -227,6 +227,10 @@ static int vnc_worker_thread_loop(VncJobQueue *queue) if (job->vs->csock == -1) { vnc_unlock_display(job->vs->vd); +/* output mutex must be locked before going to + * disconnected: + */ +vnc_lock_output(job->vs); goto disconnected; }
[Qemu-devel] qemu compiling error on ppc64: kvm.c:81: error: struct kvm_sregs has no member named pvr
Hi, I am trying to install kvm on ppc64 system (imac G5). I have built kernel with kvm module. When I try to install qemu, I am getting this error $ ./configure --enable-kvm --target-list="ppc-softmmu" $ make [...] CCslirp/tftp.o CClibdis/ppc-dis.o GEN config-target.h CCppc-softmmu/arch_init.o CCppc-softmmu/cpus.o GEN ppc-softmmu/hmp-commands.h GEN ppc-softmmu/qmp-commands.h CCppc-softmmu/monitor.o CCppc-softmmu/machine.o CCppc-softmmu/gdbstub.o CCppc-softmmu/balloon.o CCppc-softmmu/virtio-blk.o CCppc-softmmu/virtio-balloon.o CCppc-softmmu/virtio-net.o CCppc-softmmu/virtio-serial-bus.o CCppc-softmmu/virtio-pci.o CCppc-softmmu/vhost_net.o CCppc-softmmu/rwhandler.o CCppc-softmmu/kvm.o /home/user/project/qemu/target-ppc/kvm.c: In function kvm_arch_init_vcpu: /home/user/project/qemu/target-ppc/kvm.c:81: error: struct kvm_sregs has no member named pvr make[1]: *** [kvm.o] Error 1 make: *** [subdir-ppc-softmmu] Error 2 qemu-version: 0.13.5, 0.13.0 Other information: Host os : ubuntu-desktop-10.04-powerpc $ uname -a Linux user-desktop 2.6.37-rc6 #2 SMP Fri Feb 4 16:29:05 IST 2011 ppc64 GNU/Linux $ cat /proc/cpuinfo processor : 0 cpu : PPC970FX, altivec supported clock : 2100.00MHz revision: 3.1 (pvr 003c 0301) timebase: platform: PowerMac model : PowerMac12,1 machine : PowerMac12,1 motherboard : PowerMac12,1 MacRISC4 Power Macintosh detected as : 337 (iMac G5 (iSight)) pmac flags : L2 cache: 512K unified pmac-generation : NewWorld Thanks, Dushyant
[Qemu-devel] IO APIC emulation failure with qemu-kvm
Hi all, I'm Initializing the Local and IO APIC for a propeitary operating system running in Virtualized Environment . Im facing some problem with qemu-kvm but the code runs fine with qemu. when i run my kernel image with qemu-kvm it gives emulation error failure trying to execute the code outside ROM or RAM at fec0(IO APIC base address) but the same code runs fine with qemu. can anyone please point me where might be the problem or how to find out this one? Warm Regards, Ravi Kulkarni.
[Qemu-devel] [RFC][PATCH v6 00/04] qtest: qemu unit testing framework
These patches apply to master (2-04-2011), and can also be obtained from: git://repo.or.cz/qemu/mdroth.git qtest_v1 OVERVIEW: QEMU currently lacks a standard means to do targeted unit testing of the device model. Frameworks like kvm-autotest interact via guest OS, which provide a highly abstracted interface to the underlying machine, and are susceptable to bugs in the guest OS itself. This allows for reasonable test coverage of guest functionality as a whole, but reduces the accuracy and specificity with which we can exercise paths in the underlying devices. The following patches provide the basic beginnings of a test framework which replaces vcpu threads with test threads that interact with the underlying machine directly, allowing for directed unit/performance testing of individual devices. Test modules are built directly into the qemu binary, and each module provides the following interfaces: init(): Called in place of qemu's normal machine initialization to setup up devices explicitly. A full machine can be created here by calling into the normal init path, as well as minimal machines with a select set of buses/devices/IRQ handlers. run(): Test logic that interacts with the now-created machine. cleanup(): Currently unused, but potentially allows for chaining multiple tests together. Currently we run one module, then exit. As mentioned these are very early starting points. We're mostly looking for input from the community on the basic approach and overall requirements for an acceptable framework. A basic RTC test module is provided as an example. BUILD/EXAMPLE USAGE: $ ./configure --target-list=x86_64-softmmu --enable-qtest --enable-io-thread $ make $ ./x86_64-softmmu/qemu-system-x86_64 -test ? Available test modules: rtc $ ./x86_64-softmmu/qemu-system-x86_64 -test rtc ../qtest/qtest_rtc.c:test_drift():L94: hz: 2, duration_ms: 4999, exp_duration: 5000, drift ratio: 0.000200 ../qtest/qtest_rtc.c:test_drift():L111: hz: 1024, duration_ms: 4999, exp_duration: 5000, drift ratio: 0.000200 GENERAL PLAN: - Provide libraries for common operations like PCI device enumeration, APIC configuration, default-configured machine setup, interrupt handling, etc. - Develop tests as machine/target specific, potentially make some tests re-usable as interfaces are better defined - Do port i/o via cpu_in/cpu_out commands - Do guest memory access via a CPUPhysMemoryClient interface - Allow interrupts to be sent by writing to an FD, detection in test modules via select()/read() TODO: - A means to propagate test returns values to main i/o thread - Better defined test harness for individual test cases and/or modules, likely via GLib - Support for multiple test threads in a single test module for scalability testing - Modify vl.c hooks so tests can configure their own timers/clocksources - More test modules, improve current rtc module - Further implementing/fleshing out of the overall plan Comments/feedback are welcome! Makefile.objs |4 +- Makefile.target |1 + configure | 20 ++ module.h |5 +- qemu-options.hx |9 +++ qtest/qtest-rtc.c | 170 + qtest/qtest.c | 65 qtest/qtest.h | 37 roms/seabios |2 +- vl.c | 35 +++ 10 files changed, 345 insertions(+), 3 deletions(-)
[Qemu-devel] [RFC][PATCH v1 4/4] qtest: build qtest and add -test cmdline opt
Signed-off-by: Michael Roth --- Makefile.objs |4 +++- Makefile.target |1 + configure | 20 qemu-options.hx |9 + vl.c| 11 +++ 5 files changed, 44 insertions(+), 1 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index f1c7bfe..ec0cd91 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -139,6 +139,9 @@ ui-obj-y += vnc-jobs-sync.o endif common-obj-y += $(addprefix ui/, $(ui-obj-y)) +qtest-obj-y += qtest.o +common-obj-$(CONFIG_QTEST) += $(addprefix qtest/, $(qtest-obj-y)) + common-obj-y += iov.o acl.o common-obj-$(CONFIG_THREAD) += qemu-thread.o common-obj-$(CONFIG_IOTHREAD) += compatfd.o @@ -315,4 +318,3 @@ endif vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) - diff --git a/Makefile.target b/Makefile.target index b0ba95f..5c775bc 100644 --- a/Makefile.target +++ b/Makefile.target @@ -76,6 +76,7 @@ libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o libobj-y += op_helper.o helper.o ifeq ($(TARGET_BASE_ARCH), i386) libobj-y += cpuid.o +libobj-$(CONFIG_QTEST) += ../qtest/qtest_rtc.o endif libobj-$(CONFIG_NEED_MMU) += mmu.o libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o diff --git a/configure b/configure index 598e8e1..355928e 100755 --- a/configure +++ b/configure @@ -174,6 +174,7 @@ trace_backend="nop" trace_file="trace" spice="" rbd="" +qtest="" # parse CC options first for opt do @@ -719,6 +720,10 @@ for opt do ;; --enable-rbd) rbd="yes" ;; + --disable-qtest) qtest="no" + ;; + --enable-qtest) qtest="yes" + ;; *) echo "ERROR: unknown option $opt"; show_help="yes" ;; esac @@ -914,6 +919,9 @@ echo " Default:trace-" echo " --disable-spice disable spice" echo " --enable-spice enable spice" echo " --enable-rbd enable building the rados block device (rbd)" +echo " --disable-qtest disable qtest unit testing support" +echo " --enable-qtest enable qtest unit testing support" +echo " (requires --enable-io-thread)" echo "" echo "NOTE: The object files are built at the place where configure is launched" exit 1 @@ -1656,6 +1664,8 @@ EOF fi ## + +## # kvm probe if test "$kvm" != "no" ; then cat > $TMPC <" echo "spice support $spice" echo "rbd support $rbd" echo "xfsctl support$xfs" +echo "QTest support $qtest" if test $sdl_too_old = "yes"; then echo "-> Your SDL version is too old - please upgrade to have SDL support" @@ -2784,6 +2795,15 @@ if test "$trace_backend" = "dtrace" -a "$trace_backend_stap" = "yes" ; then fi echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak +if test "$qtest" = "yes"; then +if test "$io_thread" = "yes"; then +echo "CONFIG_QTEST=y" >> $config_host_mak +else +echo "ERROR: --enable-io-thread is currently required for qtest" +exit 1 +fi +fi + echo "TOOLS=$tools" >> $config_host_mak echo "ROMS=$roms" >> $config_host_mak echo "MAKE=$make" >> $config_host_mak diff --git a/qemu-options.hx b/qemu-options.hx index 945edf3..6f7e00b 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2339,6 +2339,15 @@ STEXI Specify a trace file to log output traces to. ETEXI #endif +#ifdef CONFIG_QTEST +DEF("test", HAS_ARG, QEMU_OPTION_test, +"-test \n", QEMU_ARCH_ALL) +STEXI +@item -test @var{testname} +@findex -test +Execute test case specified by @var{testname}. Use "?" to list available tests. +ETEXI +#endif HXCOMM This is the last statement. Insert new options before this line! STEXI diff --git a/vl.c b/vl.c index 0b5b613..4daf948 100644 --- a/vl.c +++ b/vl.c @@ -2722,6 +2722,17 @@ int main(int argc, char **argv, char **envp) } break; #endif +#ifdef CONFIG_QTEST +case QEMU_OPTION_test: +{ +if (*optarg == '?') { +qtest_list_modules(); +exit(0); +} +qtest_module = optarg; +break; +} +#endif case QEMU_OPTION_readconfig: { int ret = qemu_read_config_file(optarg); -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v1 2/4] qtest: basic test infrastructure and vl.c hooks
Signed-off-by: Michael Roth --- qtest/qtest.c | 65 + qtest/qtest.h | 37 vl.c | 24 + 3 files changed, 126 insertions(+), 0 deletions(-) create mode 100644 qtest/qtest.c create mode 100644 qtest/qtest.h diff --git a/qtest/qtest.c b/qtest/qtest.c new file mode 100644 index 000..fa30bdc --- /dev/null +++ b/qtest/qtest.c @@ -0,0 +1,65 @@ +#include "qtest.h" +#include "qemu-thread.h" + +static QTAILQ_HEAD(, QTestModule) qtest_module_list = +QTAILQ_HEAD_INITIALIZER(qtest_module_list); + +static const QTestModule *qtest_module_by_name(const char *test_name) +{ +const QTestModule *module; +QTAILQ_FOREACH(module, &qtest_module_list, next) { +if (strcmp(module->name, test_name) == 0) { +return module; +} +} + +return NULL; +} + +void qtest_list_modules(void) +{ +const QTestModule *module; +printf("Available test modules:\n"); +QTAILQ_FOREACH(module, &qtest_module_list, next) { +printf("%s\n", module->name); +} +} + +void qtest_register(QTestModule *module) +{ +QTAILQ_INSERT_TAIL(&qtest_module_list, module, next); +} + +void qtest_init(const char *test_name) +{ +const QTestModule *module = qtest_module_by_name(test_name); + +if (!module) { +fprintf(stderr, "unknown qtest module: %s\n", test_name); +exit(1); +} +module->init(); +} + +void qtest_cleanup(const char *test_name) +{ +const QTestModule *module = qtest_module_by_name(test_name); + +if (!module) { +fprintf(stderr, "unknown qtest module: %s\n", test_name); +exit(1); +} +module->cleanup(); +} + +void qtest_start(const char *test_name, void *thread_args) +{ +const QTestModule *module = qtest_module_by_name(test_name); +QemuThread thread; + +if (!module) { +fprintf(stderr, "unknown qtest module: %s\n", test_name); +exit(1); +} +qemu_thread_create(&thread, module->start, thread_args); +} diff --git a/qtest/qtest.h b/qtest/qtest.h new file mode 100644 index 000..7e3daed --- /dev/null +++ b/qtest/qtest.h @@ -0,0 +1,37 @@ +/* + * qtest - general interface definitions + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ +#ifndef QTEST_H +#define QTEST_H + +#include "qemu-common.h" +#include "qemu-queue.h" + +typedef void *(QTestStartFunc)(void *thread_args); +typedef void (QTestCleanupFunc)(void); +typedef void (QTestInitFunc)(void); + +typedef struct QTestModule { +const char *name; +QTestInitFunc *init; +QTestCleanupFunc *cleanup; +QTestStartFunc *start; +QTAILQ_ENTRY(QTestModule) next; +} QTestModule; + +void qtest_register(QTestModule *module); +void qtest_init(const char *test_name); +void qtest_cleanup(const char *test_name); +void qtest_start(const char *test_name, void *thread_args); +void qtest_list_modules(void); + +#endif diff --git a/vl.c b/vl.c index 655617f..0b5b613 100644 --- a/vl.c +++ b/vl.c @@ -164,6 +164,9 @@ int main(int argc, char **argv) #include "arch_init.h" #include "ui/qemu-spice.h" +#ifdef CONFIG_QTEST +#include "qtest/qtest.h" +#endif //#define DEBUG_NET //#define DEBUG_SLIRP @@ -1930,6 +1933,9 @@ int main(int argc, char **argv, char **envp) int show_vnc_port = 0; int defconfig = 1; +#ifdef CONFIG_QTEST +const char *qtest_module = NULL; +#endif #ifdef CONFIG_SIMPLE_TRACE const char *trace_file = NULL; #endif @@ -1943,6 +1949,9 @@ int main(int argc, char **argv, char **envp) QLIST_INIT (&vm_change_state_head); os_setup_early_signal_handling(); +#ifdef CONFIG_QTEST +module_call_init(MODULE_INIT_QTEST_REGISTRY); +#endif module_call_init(MODULE_INIT_MACHINE); machine = find_default_machine(); cpu_model = NULL; @@ -2859,7 +2868,11 @@ int main(int argc, char **argv, char **envp) exit(1); } +#ifdef CONFIG_QTEST +if (!qtest_module && kvm_allowed) { +#else if (kvm_allowed) { +#endif int ret = kvm_init(); if (ret < 0) { if (!kvm_available()) { @@ -2986,6 +2999,14 @@ int main(int argc, char **argv, char **envp) exit(1); module_call_init(MODULE_INIT_DEVICE); +#ifdef CONFIG_QTEST +if (qtest_module) { +module_call_init(MODULE_INIT_QTEST_REGISTRY); +qtest_init(qtest_module); +qtest_start(qtest_module, NULL); +goto out_machine_creation; +} +#endif if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0) != 0) exit(0); @@ -3101,6 +3122,9 @@ int main(int argc, char **argv, char **envp) exit(1); } +#ifdef CONFIG_QTEST +out_machine_creation: +#endif qdev_machine_creation_done(); if (rom_load_all() != 0) { -- 1.7.0.4
[Qemu-devel] [RFC][PATCH v1 3/4] qtest: add basic rtc test module
This test module initializes a basic system with an ISA bus, a PIC (currently not used in the test), and an RTC. Currently only drift testing is performed at various frequencies. This is currently more of a proof of concept than a rigorous test, and will be improved over time. Signed-off-by: Michael Roth --- qtest/qtest-rtc.c | 170 + 1 files changed, 170 insertions(+), 0 deletions(-) create mode 100644 qtest/qtest-rtc.c diff --git a/qtest/qtest-rtc.c b/qtest/qtest-rtc.c new file mode 100644 index 000..a494fd5 --- /dev/null +++ b/qtest/qtest-rtc.c @@ -0,0 +1,170 @@ +#include +#include "qtest/qtest.h" +#include "sysemu.h" +#include "hw/pc.h" +#include "hw/isa.h" +#include "hw/irq.h" +#include "hw/mc146818rtc.h" + +#define RAM_SIZE_B 128 * 1024 * 1024 +#define DEBUG_QT +#ifdef DEBUG_QT +#define TRACE(msg, ...) do { \ +fprintf(stderr, "%s:%s():L%d: " msg "\n", \ +__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \ +} while(0) +#else +#define TRACE(msg, ...) \ +do { } while (0) +#endif + +static enum { +HANDLER_MODE_NORMAL = 0, +HANDLER_MODE_DRIFT_TEST_INIT, +HANDLER_MODE_DRIFT_TEST_STARTED, +HANDLER_MODE_ONESHOT_TEST_INIT, +HANDLER_MODE_ONESHOT_TEST_STARTED, +} handler_mode = HANDLER_MODE_NORMAL; + +static uint32_t irq_count, irq_count_max; +static struct timeval ts1, ts2; + +static void cmos_write(int addr, unsigned int val) +{ +cpu_outb(0x70, addr - 0x70); +cpu_outb(0x71, val); +} + +static unsigned int cmos_read(int addr) +{ +cpu_outb(0x70, addr - 0x70); +return cpu_inb(0x71); +} + +static void rtc_irq_handler(void *opaque, int n, int level) +{ +int rtc_reg_c = 0; +if (level) { +switch (handler_mode) { +case HANDLER_MODE_DRIFT_TEST_INIT: +irq_count = 0; +gettimeofday(&ts1, NULL); +handler_mode = HANDLER_MODE_DRIFT_TEST_STARTED; +break; +case HANDLER_MODE_DRIFT_TEST_STARTED: +if (++irq_count == irq_count_max) { +gettimeofday(&ts2, NULL); +handler_mode = HANDLER_MODE_NORMAL; +} +break; +default: +break; +} +/* reset irq line */ +rtc_reg_c = cmos_read(0x7C); +} +//TRACE("irq: %d, level: %d, 0x7c: %d", n, level, rtc_reg_c); +} + +#define DRIFT_RATIO_MAX .05 + +static void test_drift(void) +{ +uint32_t hz, start, stop, duration_ms, exp_duration_ms; +float drift_ratio; + +handler_mode = HANDLER_MODE_NORMAL; +/* enable timer interrupts */ +cmos_write(0x7B, cmos_read(0x7B) | 0x40); + +/* set frequency to 2hz (32*1024khz >> (div - 1)), div is bottom 4 bits */ +cmos_write(0x7A, (cmos_read(0x7A) & 0xF0) | 0x0F); +hz = 2; +irq_count_max = hz*5; +handler_mode = HANDLER_MODE_DRIFT_TEST_INIT; +while (handler_mode != HANDLER_MODE_NORMAL) { +sleep(1); +} +start = ts1.tv_sec * 1000 * 1000 + ts1.tv_usec; +stop = ts2.tv_sec * 1000 * 1000 + ts2.tv_usec; +duration_ms = (stop - start) / 1000; +exp_duration_ms = irq_count_max / 2 * 1000; +drift_ratio = fabs(1.0 - (float)duration_ms/exp_duration_ms); +TRACE("hz: %u, duration_ms: %u, exp_duration: %u, drift ratio: %f", + hz, duration_ms, exp_duration_ms, drift_ratio); +assert(drift_ratio <= .05); + +/* set frequency to 1024hz */ +cmos_write(0x7A, (cmos_read(0x7A) & 0xF0) | 0x06); +hz = 1024; +irq_count_max = hz * 5; +handler_mode = HANDLER_MODE_DRIFT_TEST_INIT; +while (handler_mode != HANDLER_MODE_NORMAL) { +sleep(1); +} +start = ts1.tv_sec * 1000 * 1000 + ts1.tv_usec; +stop = ts2.tv_sec * 1000 * 1000 + ts2.tv_usec; +duration_ms = (stop - start) / 1000; +exp_duration_ms = irq_count_max / hz * 1000; +drift_ratio = fabs(1.0 - (float)duration_ms/exp_duration_ms); +TRACE("hz: %u, duration_ms: %u, exp_duration: %u, drift ratio: %f", + hz, duration_ms, exp_duration_ms, drift_ratio); +assert(drift_ratio <= .05); +} + +static void qtest_rtc_init(void) +{ +ram_addr_t below_4g_mem_size, above_4g_mem_size; +IsaIrqState *isa_irq_state; +ISADevice *rtc_state; +qemu_irq *rtc_irq, *cpu_irq, *isa_irq, *i8259; + +/* allocate ram */ +pc_memory_init(RAM_SIZE_B, NULL, NULL, NULL, + &below_4g_mem_size, &above_4g_mem_size); +/* +pc_cmos_init(below_4g_mem_size, above_4g_mem_size, NULL, + NULL, NULL, NULL, NULL); + */ + +/* set up the isa bus. we'll use an intercept handler for the rtc + * interrupts, but set the PIC up in case we want to use it later + */ +cpu_irq = pc_allocate_cpu_irq(); +i8259 = i8259_init(cpu_irq[0]); +isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state)); +isa_irq_state->i8259 = i8259; +isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); +isa_bus_new(NULL); +isa_bus_irqs(isa_
[Qemu-devel] [RFC][PATCH v1 1/4] qtest: add qtest to supported qemu modules
Signed-off-by: Michael Roth --- module.h |5 - 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/module.h b/module.h index 9263f1c..d2bf34d 100644 --- a/module.h +++ b/module.h @@ -24,12 +24,15 @@ typedef enum { MODULE_INIT_BLOCK, MODULE_INIT_DEVICE, MODULE_INIT_MACHINE, -MODULE_INIT_MAX +MODULE_INIT_QTEST_REGISTRY, +MODULE_INIT_MAX, } module_init_type; #define block_init(function) module_init(function, MODULE_INIT_BLOCK) #define device_init(function) module_init(function, MODULE_INIT_DEVICE) #define machine_init(function) module_init(function, MODULE_INIT_MACHINE) +#define qtest_init_registry(function) \ +module_init(function, MODULE_INIT_QTEST_REGISTRY) void register_module_init(void (*fn)(void), module_init_type type); -- 1.7.0.4
[Qemu-devel] Re: IO APIC emulation failure with qemu-kvm
On 2011-02-04 14:35, Ravi Kumar Kulkarni wrote: > Hi all, > I'm Initializing the Local and IO APIC for a propeitary operating > system running in Virtualized Environment . > Im facing some problem with qemu-kvm but the code runs fine with qemu. Does it also run fine with qemu-kvm and -no-kvm-irqchip? What versions of the kernel and qemu-kvm are you using? If not the latest git, does updating change the picture? > when i run my kernel image with qemu-kvm it gives emulation error failure > trying to execute the code outside ROM or RAM at fec0(IO APIC base > address) > but the same code runs fine with qemu. can anyone please point me > where might be the problem or how to find out this one? Start with capturing the activity of you guest via ftrace, enabling all kvm:* events. You may also try to attach gdb to qemu and analyze the different code path in both versions (specifically if you have debugging symbols for your guest). BTW, is your OS doing any fancy [IO]APIC relocations? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [PATCH] Softfloat: Add support to softfloat to return floatxx_default_nan when the corresponding target status flag is set.
Some CPUs have a status flag imposing to return floatxx_default_nan whatever the input value, when converting from one FP format to another. Implement this, using the already existing default_nan_mode status flag, only for ARM at the moment, though other architectures may have the same feature. This patch only modifies the commonNaNToFloat32 and commonNaNToFloat64 conversion functions, as ARM only uses these. Signed-off-by: Christophe Lyon --- checkpatch complains in this patch, but I have kept the style already present in the involved files. fpu/softfloat-specialize.h | 15 +-- fpu/softfloat.c| 12 ++-- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 11521ce..1a618bd 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -144,9 +144,15 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | precision floating-point format. **/ -static float32 commonNaNToFloat32( commonNaNT a ) +static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM ) { bits32 mantissa = a.high>>41; + +#if defined(TARGET_ARM) +if ( STATUS(default_nan_mode) ) { +return float32_default_nan; +} +#endif if ( mantissa ) return make_float32( ( ( (bits32) a.sign )<<31 ) | 0x7F80 | ( a.high>>41 ) ); @@ -398,10 +404,15 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | precision floating-point format. **/ -static float64 commonNaNToFloat64( commonNaNT a ) +static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM ) { bits64 mantissa = a.high>>12; +#if defined(TARGET_ARM) +if ( STATUS(default_nan_mode) ) { +return float64_default_nan; +} +#endif if ( mantissa ) return make_float64( ( ( (bits64) a.sign )<<63 ) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 17842f4..4674d37 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1534,7 +1534,7 @@ float64 float32_to_float64( float32 a STATUS_PARAM ) aExp = extractFloat32Exp( a ); aSign = extractFloat32Sign( a ); if ( aExp == 0xFF ) { -if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR )); +if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloat64( aSign, 0x7FF, 0 ); } if ( aExp == 0 ) { @@ -2689,7 +2689,7 @@ float32 float64_to_float32( float64 a STATUS_PARAM ) aExp = extractFloat64Exp( a ); aSign = extractFloat64Sign( a ); if ( aExp == 0x7FF ) { -if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) ); +if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); return packFloat32( aSign, 0xFF, 0 ); } shift64RightJamming( aSig, 22, &aSig ); @@ -3843,7 +3843,7 @@ float32 floatx80_to_float32( floatx80 a STATUS_PARAM ) aSign = extractFloatx80Sign( a ); if ( aExp == 0x7FFF ) { if ( (bits64) ( aSig<<1 ) ) { -return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) ); +return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat32( aSign, 0xFF, 0 ); } @@ -3871,7 +3871,7 @@ float64 floatx80_to_float64( floatx80 a STATUS_PARAM ) aSign = extractFloatx80Sign( a ); if ( aExp == 0x7FFF ) { if ( (bits64) ( aSig<<1 ) ) { -return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) ); +return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat64( aSign, 0x7FF, 0 ); } @@ -4863,7 +4863,7 @@ float32 float128_to_float32( float128 a STATUS_PARAM ) aSign = extractFloat128Sign( a ); if ( aExp == 0x7FFF ) { if ( aSig0 | aSig1 ) { -return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) ); +return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat32( aSign, 0xFF, 0 ); } @@ -4897,7 +4897,7 @@ float64 float128_to_float64( float128 a STATUS_PARAM ) aSign = extractFloat128Sign( a ); if ( aExp == 0x7FFF ) { if ( aSig0 | aSig1 ) { -return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) ); +return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR ); } return packFloat64( aSign, 0x7FF, 0 ); } -- 1.7.2.3
[Qemu-devel] [PATCH v3] Set the right overflow bit for neon 32 and 64 bit saturating add/sub.
Signed-off-by: Christophe Lyon --- target-arm/helpers.h | 12 -- target-arm/neon_helper.c | 89 ++ target-arm/op_helper.c | 49 - target-arm/translate.c | 18 - 4 files changed, 105 insertions(+), 63 deletions(-) diff --git a/target-arm/helpers.h b/target-arm/helpers.h index 8cc6a44..4d0de00 100644 --- a/target-arm/helpers.h +++ b/target-arm/helpers.h @@ -137,10 +137,6 @@ DEF_HELPER_2(rsqrte_f32, f32, f32, env) DEF_HELPER_2(recpe_u32, i32, i32, env) DEF_HELPER_2(rsqrte_u32, i32, i32, env) DEF_HELPER_4(neon_tbl, i32, i32, i32, i32, i32) -DEF_HELPER_2(neon_add_saturate_u64, i64, i64, i64) -DEF_HELPER_2(neon_add_saturate_s64, i64, i64, i64) -DEF_HELPER_2(neon_sub_saturate_u64, i64, i64, i64) -DEF_HELPER_2(neon_sub_saturate_s64, i64, i64, i64) DEF_HELPER_2(add_cc, i32, i32, i32) DEF_HELPER_2(adc_cc, i32, i32, i32) @@ -160,10 +156,18 @@ DEF_HELPER_3(neon_qadd_u8, i32, env, i32, i32) DEF_HELPER_3(neon_qadd_s8, i32, env, i32, i32) DEF_HELPER_3(neon_qadd_u16, i32, env, i32, i32) DEF_HELPER_3(neon_qadd_s16, i32, env, i32, i32) +DEF_HELPER_3(neon_qadd_u32, i32, env, i32, i32) +DEF_HELPER_3(neon_qadd_s32, i32, env, i32, i32) DEF_HELPER_3(neon_qsub_u8, i32, env, i32, i32) DEF_HELPER_3(neon_qsub_s8, i32, env, i32, i32) DEF_HELPER_3(neon_qsub_u16, i32, env, i32, i32) DEF_HELPER_3(neon_qsub_s16, i32, env, i32, i32) +DEF_HELPER_3(neon_qsub_u32, i32, env, i32, i32) +DEF_HELPER_3(neon_qsub_s32, i32, env, i32, i32) +DEF_HELPER_3(neon_qadd_u64, i64, env, i64, i64) +DEF_HELPER_3(neon_qadd_s64, i64, env, i64, i64) +DEF_HELPER_3(neon_qsub_u64, i64, env, i64, i64) +DEF_HELPER_3(neon_qsub_s64, i64, env, i64, i64) DEF_HELPER_2(neon_hadd_s8, i32, i32, i32) DEF_HELPER_2(neon_hadd_u8, i32, i32, i32) diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c index 2f96575..9641ccc 100644 --- a/target-arm/neon_helper.c +++ b/target-arm/neon_helper.c @@ -198,6 +198,28 @@ NEON_VOP_ENV(qadd_u16, neon_u16, 2) #undef NEON_FN #undef NEON_USAT +uint32_t HELPER(neon_qadd_u32)(CPUState *env, uint32_t a, uint32_t b) +{ +uint32_t res = a + b; +if (res < a) { +SET_QC(); +res = ~0; +} +return res; +} + +uint64_t HELPER(neon_qadd_u64)(CPUState *env, uint64_t src1, uint64_t src2) +{ +uint64_t res; + +res = src1 + src2; +if (res < src1) { +SET_QC(); +res = ~(uint64_t)0; +} +return res; +} + #define NEON_SSAT(dest, src1, src2, type) do { \ int32_t tmp = (uint32_t)src1 + (uint32_t)src2; \ if (tmp != (type)tmp) { \ @@ -218,6 +240,28 @@ NEON_VOP_ENV(qadd_s16, neon_s16, 2) #undef NEON_FN #undef NEON_SSAT +uint32_t HELPER(neon_qadd_s32)(CPUState *env, uint32_t a, uint32_t b) +{ +uint32_t res = a + b; +if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) { +SET_QC(); +res = ~(((int32_t)a >> 31) ^ SIGNBIT); +} +return res; +} + +uint64_t HELPER(neon_qadd_s64)(CPUState *env, uint64_t src1, uint64_t src2) +{ +uint64_t res; + +res = src1 + src2; +if (((res ^ src1) & SIGNBIT64) && !((src1 ^ src2) & SIGNBIT64)) { +SET_QC(); +res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64; +} +return res; +} + #define NEON_USAT(dest, src1, src2, type) do { \ uint32_t tmp = (uint32_t)src1 - (uint32_t)src2; \ if (tmp != (type)tmp) { \ @@ -234,6 +278,29 @@ NEON_VOP_ENV(qsub_u16, neon_u16, 2) #undef NEON_FN #undef NEON_USAT +uint32_t HELPER(neon_qsub_u32)(CPUState *env, uint32_t a, uint32_t b) +{ +uint32_t res = a - b; +if (res > a) { +SET_QC(); +res = 0; +} +return res; +} + +uint64_t HELPER(neon_qsub_u64)(CPUState *env, uint64_t src1, uint64_t src2) +{ +uint64_t res; + +if (src1 < src2) { +SET_QC(); +res = 0; +} else { +res = src1 - src2; +} +return res; +} + #define NEON_SSAT(dest, src1, src2, type) do { \ int32_t tmp = (uint32_t)src1 - (uint32_t)src2; \ if (tmp != (type)tmp) { \ @@ -254,6 +321,28 @@ NEON_VOP_ENV(qsub_s16, neon_s16, 2) #undef NEON_FN #undef NEON_SSAT +uint32_t HELPER(neon_qsub_s32)(CPUState *env, uint32_t a, uint32_t b) +{ +uint32_t res = a - b; +if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) { +SET_QC(); +res = ~(((int32_t)a >> 31) ^ SIGNBIT); +} +return res; +} + +uint64_t HELPER(neon_qsub_s64)(CPUState *env, uint64_t src1, uint64_t src2) +{ +uint64_t res; + +res = src1 - src2; +if (((res ^ src1) & SIGNBIT64) && ((src1 ^ src2) & SIGNBIT64)) { +SET_QC(); +res = ((int64_t)src1 >> 63) ^ ~SIGNBIT64; +} +return res; +} + #define NEON_FN(dest, src1, src2) dest = (src1 + src2) >> 1 NEON_VOP(hadd_s8, neon_s8, 4) NEON_VOP(hadd_u8, neon_u8, 4) diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 43baa63..3de2610 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -424,52 +424,3 @@ uint32_t HELPER(ror_cc
[Qemu-devel] Re: [PATCH] x86: Fix MCA broadcast parameters for TCG case
On Wed, Feb 02, 2011 at 09:35:26PM +0100, Jan Kiszka wrote: > On 2011-02-02 20:05, Blue Swirl wrote: > > Signed-off-by: Blue Swirl > > --- > > target-i386/helper.c |2 +- > > 1 files changed, 1 insertions(+), 1 deletions(-) > > > > diff --git a/target-i386/helper.c b/target-i386/helper.c > > index 1217452..4bbf9b1 100644 > > --- a/target-i386/helper.c > > +++ b/target-i386/helper.c > > @@ -1148,7 +1148,7 @@ void cpu_inject_x86_mce(CPUState *cenv, int > > bank, uint64_t status, > > continue; > > } > > > > -qemu_inject_x86_mce(env, 1, 0xa000, 0, 0, 0); > > +qemu_inject_x86_mce(env, 1, 0xa000ULL, 0, 0, > > 0); > > } > > } > > } > > Let's fix this for real, the value is wrong anyway: > > --8<-- > > From: Jan Kiszka > > When broadcasting MCEs, we need to set MCIP and RIPV in mcg_status like > it is done for KVM. Use the symbolic constants at this chance. > > Signed-off-by: Jan Kiszka Applied to uq/master, thanks.
[Qemu-devel] Re: [PATCH v2 00/24] [uq/master] Patch queue, part II
On Tue, Feb 01, 2011 at 10:15:40PM +0100, Jan Kiszka wrote: > Version 2 of part II. Changes: > - Fixed "Unconditionally reenter kernel after IO exits" to take >self-INIT into account > - Fixed misplaced hunk in "Fix race between timer signals and vcpu >entry under !IOTHREAD" (rebase artifact) > - Factor out block_synchronous_signals (analogue to block_io_signals) > - Additional fix to break out of SMP VCPU loop on pending IO event > - Fork qemu_kvm_init_cpu_signals over CONFIG_IOTHREAD > - Additional cleanup, flattening the main loop > > Hope I addressed all review comments (except for passing env to > qemu_cpu_kick_self which I think is better as it is). 1 and 24 rejected, applied the remaining ones, thanks.
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
On 04.02.2011, at 13:30, Anthony Liguori wrote: > On 02/02/2011 01:28 PM, Stefan Weil wrote: >> Hello, >> >> these are some patches which I found on my stack of open patches. >> >> All of them should go into 0.14, and at least some of them could also be >> applied to 0.13. > > This need the following Acks: > >> >> [PATCH] hw/fmopl: Fix buffer access out-of-bounds errors >> (http://patchwork.ozlabs.org/patch/79054/) > > malc > >> [PATCH] linux-user: Fix possible realloc memory leak >> (http://patchwork.ozlabs.org/patch/79217/) > > Riku > >> [PATCH 1/3] tests: Fix two memory leaks >> (http://patchwork.ozlabs.org/patch/79945/) >> [PATCH 2/3] check-qdict: Fix possible crash >> (http://patchwork.ozlabs.org/patch/79946/) > > Luiz > >> [PATCH 3/3] w64: Fix problem with missing sigset_t >> (http://patchwork.ozlabs.org/patch/79947/) > > We don't support w64... > >> [PATCH 1/3] pci: Fix memory leak (http://patchwork.ozlabs.org/patch/79996/) > > mst (looks like he did) > >> [PATCH 2/3] ppc405: Fix memory leak >> (http://patchwork.ozlabs.org/patch/79997/) >> [PATCH 3/3] s390: Fix memory leak (http://patchwork.ozlabs.org/patch/79998/) > > Alex for both of these. Acked-by: Alexander Graf for both :) Alex > > Regards, > > Anthony Liguori > >> [PATCH] Fix trivial "endianness bugs" >> (http://patchwork.ozlabs.org/patch/80223/) >> >> [PATCH] HACKING: Update status of format checking >> (http://lists.nongnu.org/archive/html/qemu-devel/2011-01/msg02476.html) >> [PATCH] mingw32: Fix definitions for PRId64, PRIx64, PRIu64, PRIo64 >> (http://patchwork.ozlabs.org/patch/74276/) >> >> Regards, >> Stefan Weil >> >> >
Re: [Qemu-devel] [PATCH] Softfloat: Add support to softfloat to return floatxx_default_nan when the corresponding target status flag is set.
On 4 February 2011 14:01, Christophe Lyon wrote: > Some CPUs have a status flag imposing to return floatxx_default_nan > whatever the input value, when converting from one FP format to > another. Implement this, using the already existing default_nan_mode > status flag, only for ARM at the moment, though other architectures > may have the same feature. This patch only modifies the > commonNaNToFloat32 and commonNaNToFloat64 conversion functions, as ARM > only uses these. > -static float32 commonNaNToFloat32( commonNaNT a ) > +static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM ) > { > bits32 mantissa = a.high>>41; > + > +#if defined(TARGET_ARM) > + if ( STATUS(default_nan_mode) ) { > + return float32_default_nan; > + } > +#endif The target-specific #ifdef is pretty ugly. Fortunately the only architecture except ARM that sets default_nan_mode is sh4, so all we have to do is find out what it does with its float-to-float conversions. It looks to me from http://documentation.renesas.com/eng/products/mpumcu/rej09b0318_sh_4sm.pdf that it also returns the default NaN for converting a NaN from one float format to another. So you can just drop the #ifdef. (cc'ing Aurelien to check since he's the SH4 maintainer.) I also think the change is simple enough that we ought to do it consistently for the floatx80 and float128 functions even if neither ARM nor sh4 use them. -- PMM
Re: [Qemu-devel] [PATCH v3] Set the right overflow bit for neon 32 and 64 bit saturating add/sub.
On 4 February 2011 14:17, Christophe Lyon wrote: > > Signed-off-by: Christophe Lyon Reviewed-by: Peter Maydell -- PMM
[Qemu-devel] Re: [PATCH 1/4] Add config-devices.h again
Stefan Weil wrote: > Am 01.02.2011 17:53, schrieb Eduardo Habkost: >> This reverts part of commit a992fe3d0fc185112677286f7a02204d8245b61e. >> >> We do have code that needs #ifdefs depending on the list of enabled devices, >> but currently that code breaks when we try to disable a feature that is >> enabled >> by default. >> >> For example, if we try to disable CONFIG_VMWARE_VGA, we get the following: >> >> LINK x86_64-softmmu/qemu-system-x86_64 >>pc.o: In function `pc_vga_init': >>/home/ehabkost/pessoal/proj/virt/qemu/qemu/hw/pc.c:991: undefined >> reference to `pci_vmsvga_init' >>collect2: ld returned 1 exit status >>make[1]: *** [qemu-system-x86_64] Error 1 >>rm config-devices.h-timestamp >>make: *** [subdir-x86_64-softmmu] Error 2 >> >> config-devices.h will allow us to add an #ifdef to fix the above error, and >> other similar cases. >> >> Signed-off-by: Eduardo Habkost >> --- >> Makefile|7 +-- >> Makefile.target |2 +- >> config.h| 11 +++ >> 3 files changed, 17 insertions(+), 3 deletions(-) >> >> diff --git a/Makefile b/Makefile >> index 4e120a2..22b53f6 100644 >> --- a/Makefile >> +++ b/Makefile >> @@ -1,6 +1,6 @@ >> # Makefile for QEMU. >> >> -GENERATED_HEADERS = config-host.h trace.h qemu-options.def >> +GENERATED_HEADERS = config-host.h trace.h qemu-options.def >> config-all-devices.h >> ifeq ($(TRACE_BACKEND),dtrace) >> GENERATED_HEADERS += trace-dtrace.h >> endif >> @@ -77,6 +77,9 @@ config-host.h-timestamp: config-host.mak >> qemu-options.def: $(SRC_PATH)/qemu-options.hx >> $(call quiet-command,sh $(SRC_PATH)/hxtool -h< $< > $@," GEN $@") >> >> +config-all-devices.h: config-all-devices.h-timestamp >> +config-all-devices.h-timestamp: config-all-devices.mak >> + >> SUBDIR_RULES=$(patsubst %,subdir-%, $(TARGET_DIRS)) >> >> subdir-%: $(GENERATED_HEADERS) >> @@ -190,7 +193,7 @@ clean: >> >> distclean: clean >> rm -f config-host.mak config-host.h* config-host.ld $(DOCS) >> qemu-options.texi qemu-img-cmds.texi qemu-monitor.texi >> -rm -f config-all-devices.mak >> +rm -f config-all-devices.mak config-all-devices.h* >> rm -f roms/seabios/config.mak roms/vgabios/config.mak >> rm -f qemu-doc.info qemu-doc.aux qemu-doc.cp qemu-doc.dvi qemu-doc.fn >> qemu-doc.info qemu-doc.ky qemu-doc.log qemu-doc.pdf qemu-doc.pg qemu-doc.toc >> qemu-doc.tp qemu-doc.vr >> rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi >> qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf >> qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr >> diff --git a/Makefile.target b/Makefile.target >> index 2800f47..03fc486 100644 >> --- a/Makefile.target >> +++ b/Makefile.target >> @@ -1,6 +1,6 @@ >> # -*- Mode: makefile -*- >> >> -GENERATED_HEADERS = config-target.h >> +GENERATED_HEADERS = config-target.h config-devices.h >> CONFIG_NO_KVM = $(if $(subst n,,$(CONFIG_KVM)),n,y) >> >> include ../config-host.mak >> diff --git a/config.h b/config.h >> index e20f786..07d79d4 100644 >> --- a/config.h >> +++ b/config.h >> @@ -1,2 +1,13 @@ >> + >> #include "config-host.h" >> #include "config-target.h" >> + >> +/* We want to include different config files for specific targets >> + And for the common library. They need a different name because >> + we don't want to rely in paths */ >> > > on paths? yeap, sorry.
[Qemu-devel] Re: qemu compiling error on ppc64: kvm.c:81: error: struct kvm_sregs has no member named pvr
On 04.02.2011, at 14:25, "Dushyant Bansal" wrote: > Hi, > I am trying to install kvm on ppc64 system (imac G5). I have built > kernel with kvm module. When I try to install qemu, I am getting this > error > > $ ./configure --enable-kvm --target-list="ppc-softmmu" > $ make > > [...] > CCslirp/tftp.o > CClibdis/ppc-dis.o > GEN config-target.h > CCppc-softmmu/arch_init.o > CCppc-softmmu/cpus.o > GEN ppc-softmmu/hmp-commands.h > GEN ppc-softmmu/qmp-commands.h > CCppc-softmmu/monitor.o > CCppc-softmmu/machine.o > CCppc-softmmu/gdbstub.o > CCppc-softmmu/balloon.o > CCppc-softmmu/virtio-blk.o > CCppc-softmmu/virtio-balloon.o > CCppc-softmmu/virtio-net.o > CCppc-softmmu/virtio-serial-bus.o > CCppc-softmmu/virtio-pci.o > CCppc-softmmu/vhost_net.o > CCppc-softmmu/rwhandler.o > CCppc-softmmu/kvm.o > /home/user/project/qemu/target-ppc/kvm.c: In function ‘kvm_arch_init_vcpu’: > /home/user/project/qemu/target-ppc/kvm.c:81: error: ‘struct kvm_sregs’ has > no member named ‘pvr’ Hrm. This means that your kernel headers in /usr/include/linux are too old. Can you try and find out which kernel version they are from please? Thanks, Alex > make[1]: *** [kvm.o] Error 1 > make: *** [subdir-ppc-softmmu] Error 2 > > > qemu-version: 0.13.5, 0.13.0 > > Other information: > Host os : ubuntu-desktop-10.04-powerpc > > $ uname -a > Linux user-desktop 2.6.37-rc6 #2 SMP Fri Feb 4 16:29:05 IST 2011 ppc64 > GNU/Linux > > $ cat /proc/cpuinfo > processor: 0 > cpu: PPC970FX, altivec supported > clock: 2100.00MHz > revision: 3.1 (pvr 003c 0301) > timebase: > platform: PowerMac > model: PowerMac12,1 > machine: PowerMac12,1 > motherboard: PowerMac12,1 MacRISC4 Power Macintosh > detected as: 337 (iMac G5 (iSight)) > pmac flags: > L2 cache: 512K unified > pmac-generation: NewWorld > > > Thanks, > Dushyant > > > -- > To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
[Qemu-devel] Re: [Bug 712416] Re: kvm_intel kernel module crash with via nano vmx
Quoting khetzal (712...@bugs.launchpad.net): > Thanks for your help. I've subscribed to these mailing list. Have i do > report the bug in these mailing list too ? (or is it a useless other > duplication ?) It will not be duplication. These are development lists, not support lists, so you won't be filing a bug report. Rather, report your failures and ask whether (a) they are aware of it, (b) it is expected, (c) anyone is currently working on support for via nano, and (d) how others can help. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/712416 Title: kvm_intel kernel module crash with via nano vmx Status in QEMU: New Status in “kvm” package in Ubuntu: Incomplete Status in “kvm” package in Debian: New Bug description: kvm module for hardware virtualisation not work properly on via nano processors. Tested with processor: VIA Nano processor U2250. Processors flags (visible in /proc/cpuinfo): fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush acpi mmx fxsr sse sse2 ss tm syscall nx lm constant_tsc up rep_good pni monitor vmx est tm2 ssse3 cx16 xtpr rng rng_en ace ace_en ace2 phe phe_en lahf_lm With kernel 2.6.32: kvm not work and dmesg contains a lot of: handle_exception: unexpected, vectoring info 0x800d intr info 0x8b0d With kernel 2.6.35: all the system crash. Nothing visible in logs
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
Anthony Liguori writes: > On 02/02/2011 01:28 PM, Stefan Weil wrote: [...] >> [PATCH 1/3] tests: Fix two memory leaks >> (http://patchwork.ozlabs.org/patch/79945/) >> [PATCH 2/3] check-qdict: Fix possible crash >> (http://patchwork.ozlabs.org/patch/79946/) > > Luiz I wouldn't bother with the second one for 0.14. Yes, we're reading lines from a file with %s, but it's a fixed file with known contents, no long lines, and we're reading it in a test program only developers ever use. As to the first one, Luiz has never touched that file. Neither have I, and it's not obvious to me why it should go into 0.14. [...]
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
On 02/04/2011 09:27 AM, Markus Armbruster wrote: Anthony Liguori writes: On 02/02/2011 01:28 PM, Stefan Weil wrote: [...] [PATCH 1/3] tests: Fix two memory leaks (http://patchwork.ozlabs.org/patch/79945/) [PATCH 2/3] check-qdict: Fix possible crash (http://patchwork.ozlabs.org/patch/79946/) Luiz I wouldn't bother with the second one for 0.14. Yes, we're reading lines from a file with %s, but it's a fixed file with known contents, no long lines, and we're reading it in a test program only developers ever use. As to the first one, Luiz has never touched that file. Neither have I, and it's not obvious to me why it should go into 0.14. Yeah, I just meant the qdict one. Regards, Anthony Liguori [...]
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
On Fri, 4 Feb 2011, Anthony Liguori wrote: > On 02/02/2011 01:28 PM, Stefan Weil wrote: > > Hello, > > > > these are some patches which I found on my stack of open patches. > > > > All of them should go into 0.14, and at least some of them could also be > > applied to 0.13. > > This need the following Acks: > > > > > [PATCH] hw/fmopl: Fix buffer access out-of-bounds errors > > (http://patchwork.ozlabs.org/patch/79054/) > > malc The patch looks correct. [..snip..] -- mailto:av1...@comtv.ru
[Qemu-devel] [PATCH 07/23] kvm: Report proper error on GET_VCPU_MMAP_SIZE failures
From: Jan Kiszka Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- kvm-all.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 2ec9e09..55f6ac3 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -219,6 +219,7 @@ int kvm_init_vcpu(CPUState *env) mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0); if (mmap_size < 0) { +ret = mmap_size; DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n"); goto err; } -- 1.7.2.3
[Qemu-devel] [PATCH 21/23] kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN
From: Jan Kiszka The reset we issue on KVM_EXIT_SHUTDOWN implies that we should also leave the VCPU loop. As we now check for exit_request which is set by qemu_system_reset_request, this bug is no longer critical. Still it's an unneeded extra turn. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- kvm-all.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 4729ec5..42dfed8 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -963,7 +963,6 @@ int kvm_cpu_exec(CPUState *env) case KVM_EXIT_SHUTDOWN: DPRINTF("shutdown\n"); qemu_system_reset_request(); -ret = 1; break; case KVM_EXIT_UNKNOWN: fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n", -- 1.7.2.3
[Qemu-devel] [PATCH 19/23] kvm: Unconditionally reenter kernel after IO exits
From: Jan Kiszka KVM requires to reenter the kernel after IO exits in order to complete instruction emulation. Failing to do so will leave the kernel state inconsistently behind. To ensure that we will get back ASAP, we issue a self-signal that will cause KVM_RUN to return once the pending operations are completed. We can move kvm_arch_process_irqchip_events out of the inner VCPU loop. The only state that mattered at its old place was a pending INIT request. Catch it in kvm_arch_pre_run and also trigger a self-signal to process the request on next kvm_cpu_exec. This patch also fixes the missing exit_request check in kvm_cpu_exec in the CONFIG_IOTHREAD case. Signed-off-by: Jan Kiszka CC: Gleb Natapov Signed-off-by: Marcelo Tosatti --- kvm-all.c | 31 +-- target-i386/kvm.c |5 + 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index a83aff2..0c20f9e 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -199,7 +199,6 @@ int kvm_pit_in_kernel(void) return kvm_state->pit_in_kernel; } - int kvm_init_vcpu(CPUState *env) { KVMState *s = kvm_state; @@ -896,29 +895,33 @@ int kvm_cpu_exec(CPUState *env) DPRINTF("kvm_cpu_exec()\n"); -do { -#ifndef CONFIG_IOTHREAD -if (env->exit_request) { -DPRINTF("interrupt exit requested\n"); -ret = 0; -break; -} -#endif - -if (kvm_arch_process_irqchip_events(env)) { -ret = 0; -break; -} +if (kvm_arch_process_irqchip_events(env)) { +env->exit_request = 0; +env->exception_index = EXCP_HLT; +return 0; +} +do { if (env->kvm_vcpu_dirty) { kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE); env->kvm_vcpu_dirty = 0; } kvm_arch_pre_run(env, run); +if (env->exit_request) { +DPRINTF("interrupt exit requested\n"); +/* + * KVM requires us to reenter the kernel after IO exits to complete + * instruction emulation. This self-signal will ensure that we + * leave ASAP again. + */ +qemu_cpu_kick_self(); +} cpu_single_env = NULL; qemu_mutex_unlock_iothread(); + ret = kvm_vcpu_ioctl(env, KVM_RUN, 0); + qemu_mutex_lock_iothread(); cpu_single_env = env; kvm_arch_post_run(env, run); diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 9df8ff8..8a87244 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1426,6 +1426,11 @@ int kvm_arch_get_registers(CPUState *env) int kvm_arch_pre_run(CPUState *env, struct kvm_run *run) { +/* Force the VCPU out of its inner loop to process the INIT request */ +if (env->interrupt_request & CPU_INTERRUPT_INIT) { +env->exit_request = 1; +} + /* Inject NMI */ if (env->interrupt_request & CPU_INTERRUPT_NMI) { env->interrupt_request &= ~CPU_INTERRUPT_NMI; -- 1.7.2.3
[Qemu-devel] [PATCH 18/23] Introduce VCPU self-signaling service
From: Jan Kiszka Introduce qemu_cpu_kick_self to send SIG_IPI to the calling VCPU context. First user will be kvm. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c| 21 + qemu-common.h |1 + 2 files changed, 22 insertions(+), 0 deletions(-) diff --git a/cpus.c b/cpus.c index c4c5914..9c50a34 100644 --- a/cpus.c +++ b/cpus.c @@ -537,6 +537,17 @@ void qemu_cpu_kick(void *env) return; } +void qemu_cpu_kick_self(void) +{ +#ifndef _WIN32 +assert(cpu_single_env); + +raise(SIG_IPI); +#else +abort(); +#endif +} + void qemu_notify_event(void) { CPUState *env = cpu_single_env; @@ -835,6 +846,16 @@ void qemu_cpu_kick(void *_env) } } +void qemu_cpu_kick_self(void) +{ +assert(cpu_single_env); + +if (!cpu_single_env->thread_kicked) { +qemu_thread_signal(cpu_single_env->thread, SIG_IPI); +cpu_single_env->thread_kicked = true; +} +} + int qemu_cpu_self(void *_env) { CPUState *env = _env; diff --git a/qemu-common.h b/qemu-common.h index c7ff280..a4d9c21 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -288,6 +288,7 @@ void qemu_notify_event(void); /* Unblock cpu */ void qemu_cpu_kick(void *env); +void qemu_cpu_kick_self(void); int qemu_cpu_self(void *env); /* work queue */ -- 1.7.2.3
[Qemu-devel] [PATCH 23/23] kvm: make tsc stable over migration and machine start
From: Glauber Costa If the machine is stopped, we should not record two different tsc values upon a save operation. The same problem happens with kvmclock. But kvmclock is taking a different diretion, being now seen as a separate device. Since this is unlikely to happen with the tsc, I am taking the approach here of simply registering a handler for state change, and using a per-CPUState variable that prevents double updates for the TSC. Signed-off-by: Glauber Costa CC: Jan Kiszka Signed-off-by: Marcelo Tosatti --- target-i386/cpu.h |1 + target-i386/kvm.c | 18 +- 2 files changed, 18 insertions(+), 1 deletions(-) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index af701a4..5f1df8b 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -734,6 +734,7 @@ typedef struct CPUX86State { uint32_t sipi_vector; uint32_t cpuid_kvm_features; uint32_t cpuid_svm_features; +bool tsc_valid; /* in order to simplify APIC support, we leave this pointer to the user */ diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 8a87244..ba183c4 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -301,6 +301,15 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, #endif } +static void cpu_update_state(void *opaque, int running, int reason) +{ +CPUState *env = opaque; + +if (running) { +env->tsc_valid = false; +} +} + int kvm_arch_init_vcpu(CPUState *env) { struct { @@ -434,6 +443,8 @@ int kvm_arch_init_vcpu(CPUState *env) } #endif +qemu_add_vm_change_state_handler(cpu_update_state, env); + return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data); } @@ -1061,7 +1072,12 @@ static int kvm_get_msrs(CPUState *env) if (has_msr_hsave_pa) { msrs[n++].index = MSR_VM_HSAVE_PA; } -msrs[n++].index = MSR_IA32_TSC; + +if (!env->tsc_valid) { +msrs[n++].index = MSR_IA32_TSC; +env->tsc_valid = !vm_running; +} + #ifdef TARGET_X86_64 if (lm_capable_kernel) { msrs[n++].index = MSR_CSTAR; -- 1.7.2.3
[Qemu-devel] [PATCH 00/23] [PULL] qemu-kvm.git uq/master queue
The following changes since commit bfddb47a343b4718e5768aa80bce8adead0f7fca: Open up the 0.15 development branch (2011-02-02 08:39:28 +0100) are available in the git repository at: git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master Glauber Costa (1): kvm: make tsc stable over migration and machine start Jan Kiszka (22): Prevent abortion on multiple VCPU kicks Stop current VCPU on synchronous reset requests Process vmstop requests in IO thread Trigger exit from cpu_exec_all on pending IO events Leave inner main_loop faster on pending requests Flatten the main loop kvm: Report proper error on GET_VCPU_MMAP_SIZE failures kvm: Drop redundant kvm_enabled from kvm_cpu_thread_fn kvm: Handle kvm_init_vcpu errors kvm: Provide sigbus services arch-independently Refactor signal setup functions in cpus.c kvm: Set up signal mask also for !CONFIG_IOTHREAD kvm: Refactor qemu_kvm_eat_signals kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD Set up signalfd under !CONFIG_IOTHREAD kvm: Fix race between timer signals and vcpu entry under !IOTHREAD kvm: Add MCE signal support for !CONFIG_IOTHREAD Introduce VCPU self-signaling service kvm: Unconditionally reenter kernel after IO exits kvm: Remove static return code of kvm_handle_io kvm: Leave kvm_cpu_exec directly after KVM_EXIT_SHUTDOWN x86: Fix MCA broadcast parameters for TCG case Makefile.objs|2 +- configure|6 + cpu-defs.h |1 + cpus.c | 549 +++--- cpus.h |1 + kvm-all.c| 60 --- kvm-stub.c |5 + kvm.h|7 +- qemu-common.h|1 + target-i386/cpu.h|1 + target-i386/helper.c |4 +- target-i386/kvm.c| 27 +++- target-ppc/kvm.c | 10 + target-s390x/kvm.c | 10 + vl.c | 40 ++-- 15 files changed, 466 insertions(+), 258 deletions(-)
[Qemu-devel] [PATCH 08/23] kvm: Drop redundant kvm_enabled from kvm_cpu_thread_fn
From: Jan Kiszka Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cpus.c b/cpus.c index 5dfc54e..312c7a2 100644 --- a/cpus.c +++ b/cpus.c @@ -607,8 +607,8 @@ static void *kvm_cpu_thread_fn(void *arg) qemu_mutex_lock(&qemu_global_mutex); qemu_thread_self(env->thread); -if (kvm_enabled()) -kvm_init_vcpu(env); + +kvm_init_vcpu(env); kvm_init_ipi(env); -- 1.7.2.3
[Qemu-devel] [PATCH 13/23] kvm: Refactor qemu_kvm_eat_signals
From: Jan Kiszka We do not use the timeout, so drop its logic. As we always poll our signals, we do not need to drop the global lock. Removing those calls allows some further simplifications. Also fix the error processing of sigpending at this chance. Signed-off-by: Jan Kiszka Reviewed-by: Paolo Bonzini Signed-off-by: Marcelo Tosatti --- cpus.c | 23 +++ 1 files changed, 7 insertions(+), 16 deletions(-) diff --git a/cpus.c b/cpus.c index a33e470..04138ba 100644 --- a/cpus.c +++ b/cpus.c @@ -648,31 +648,22 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, } } -static void qemu_kvm_eat_signal(CPUState *env, int timeout) +static void qemu_kvm_eat_signals(CPUState *env) { -struct timespec ts; -int r, e; +struct timespec ts = { 0, 0 }; siginfo_t siginfo; sigset_t waitset; sigset_t chkset; - -ts.tv_sec = timeout / 1000; -ts.tv_nsec = (timeout % 1000) * 100; +int r; sigemptyset(&waitset); sigaddset(&waitset, SIG_IPI); sigaddset(&waitset, SIGBUS); do { -qemu_mutex_unlock(&qemu_global_mutex); - r = sigtimedwait(&waitset, &siginfo, &ts); -e = errno; - -qemu_mutex_lock(&qemu_global_mutex); - -if (r == -1 && !(e == EAGAIN || e == EINTR)) { -fprintf(stderr, "sigtimedwait: %s\n", strerror(e)); +if (r == -1 && !(errno == EAGAIN || errno == EINTR)) { +perror("sigtimedwait"); exit(1); } @@ -688,7 +679,7 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout) r = sigpending(&chkset); if (r == -1) { -fprintf(stderr, "sigpending: %s\n", strerror(e)); +perror("sigpending"); exit(1); } } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); @@ -699,7 +690,7 @@ static void qemu_kvm_wait_io_event(CPUState *env) while (!cpu_has_work(env)) qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000); -qemu_kvm_eat_signal(env, 0); +qemu_kvm_eat_signals(env); qemu_wait_io_event_common(env); } -- 1.7.2.3
[Qemu-devel] [PATCH 05/23] Leave inner main_loop faster on pending requests
From: Jan Kiszka If there is any pending request that requires us to leave the inner loop if main_loop, makes sure we do this as soon as possible by enforcing non-blocking IO processing. At this change, move variable definitions out of the inner loop to improve readability. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- vl.c | 11 +++ 1 files changed, 7 insertions(+), 4 deletions(-) diff --git a/vl.c b/vl.c index 57b4c9f..6aa896c 100644 --- a/vl.c +++ b/vl.c @@ -1402,18 +1402,21 @@ qemu_irq qemu_system_powerdown; static void main_loop(void) { +bool nonblocking = false; +#ifdef CONFIG_PROFILER +int64_t ti; +#endif int r; qemu_main_loop_start(); for (;;) { do { -bool nonblocking = false; -#ifdef CONFIG_PROFILER -int64_t ti; -#endif #ifndef CONFIG_IOTHREAD nonblocking = cpu_exec_all(); +if (!vm_can_run()) { +nonblocking = true; +} #endif #ifdef CONFIG_PROFILER ti = profile_getclock(); -- 1.7.2.3
[Qemu-devel] [PATCH 06/23] Flatten the main loop
From: Jan Kiszka First of all, vm_can_run is a misnomer, it actually means "no request pending". Moreover, there is no need to check all pending requests twice, the first time via the inner loop check and then again when actually processing the requests. We can simply remove the inner loop and do the checks directly. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- vl.c | 30 +++--- 1 files changed, 15 insertions(+), 15 deletions(-) diff --git a/vl.c b/vl.c index 6aa896c..837be97 100644 --- a/vl.c +++ b/vl.c @@ -1389,14 +1389,16 @@ void main_loop_wait(int nonblocking) } -static int vm_can_run(void) +#ifndef CONFIG_IOTHREAD +static int vm_request_pending(void) { -return !(powerdown_requested || - reset_requested || - shutdown_requested || - debug_requested || - vmstop_requested); +return powerdown_requested || + reset_requested || + shutdown_requested || + debug_requested || + vmstop_requested; } +#endif qemu_irq qemu_system_powerdown; @@ -1411,21 +1413,19 @@ static void main_loop(void) qemu_main_loop_start(); for (;;) { -do { #ifndef CONFIG_IOTHREAD -nonblocking = cpu_exec_all(); -if (!vm_can_run()) { -nonblocking = true; -} +nonblocking = cpu_exec_all(); +if (vm_request_pending()) { +nonblocking = true; +} #endif #ifdef CONFIG_PROFILER -ti = profile_getclock(); +ti = profile_getclock(); #endif -main_loop_wait(nonblocking); +main_loop_wait(nonblocking); #ifdef CONFIG_PROFILER -dev_time += profile_getclock() - ti; +dev_time += profile_getclock() - ti; #endif -} while (vm_can_run()); if ((r = qemu_debug_requested())) { vm_stop(r); -- 1.7.2.3
[Qemu-devel] [PATCH 16/23] kvm: Fix race between timer signals and vcpu entry under !IOTHREAD
From: Jan Kiszka Found by Stefan Hajnoczi: There is a race in kvm_cpu_exec between checking for exit_request on vcpu entry and timer signals arriving before KVM starts to catch them. Plug it by blocking both timer related signals also on !CONFIG_IOTHREAD and process those via signalfd. As this fix depends on real signalfd support (otherwise the timer signals only kick the compat helper thread, and the main thread hangs), we need to detect the invalid constellation and abort configure. Signed-off-by: Jan Kiszka CC: Stefan Hajnoczi Signed-off-by: Marcelo Tosatti --- configure |6 ++ cpus.c| 31 ++- 2 files changed, 36 insertions(+), 1 deletions(-) diff --git a/configure b/configure index 598e8e1..a3f5345 100755 --- a/configure +++ b/configure @@ -2057,6 +2057,12 @@ EOF if compile_prog "" "" ; then signalfd=yes +elif test "$kvm" = "yes" -a "$io_thread" != "yes"; then + echo + echo "ERROR: Host kernel lacks signalfd() support," + echo "but KVM depends on it when the IO thread is disabled." + echo + exit 1 fi # check if eventfd is supported diff --git a/cpus.c b/cpus.c index 359361f..18caf47 100644 --- a/cpus.c +++ b/cpus.c @@ -327,6 +327,12 @@ static void qemu_kvm_eat_signals(CPUState *env) exit(1); } } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); + +#ifndef CONFIG_IOTHREAD +if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) { +qemu_notify_event(); +} +#endif } #else /* _WIN32 */ @@ -376,11 +382,15 @@ static void qemu_kvm_init_cpu_signals(CPUState *env) sigemptyset(&set); sigaddset(&set, SIG_IPI); +sigaddset(&set, SIGIO); +sigaddset(&set, SIGALRM); pthread_sigmask(SIG_BLOCK, &set, NULL); pthread_sigmask(SIG_BLOCK, NULL, &set); sigdelset(&set, SIG_IPI); sigdelset(&set, SIGBUS); +sigdelset(&set, SIGIO); +sigdelset(&set, SIGALRM); r = kvm_set_signal_mask(env, &set); if (r) { fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r)); @@ -389,13 +399,32 @@ static void qemu_kvm_init_cpu_signals(CPUState *env) #endif } +#ifndef _WIN32 +static sigset_t block_synchronous_signals(void) +{ +sigset_t set; + +sigemptyset(&set); +if (kvm_enabled()) { +/* + * We need to process timer signals synchronously to avoid a race + * between exit_request check and KVM vcpu entry. + */ +sigaddset(&set, SIGIO); +sigaddset(&set, SIGALRM); +} + +return set; +} +#endif + int qemu_init_main_loop(void) { #ifndef _WIN32 sigset_t blocked_signals; int ret; -sigemptyset(&blocked_signals); +blocked_signals = block_synchronous_signals(); ret = qemu_signalfd_init(blocked_signals); if (ret) { -- 1.7.2.3
[Qemu-devel] [PATCH 22/23] x86: Fix MCA broadcast parameters for TCG case
From: Jan Kiszka When broadcasting MCEs, we need to set MCIP and RIPV in mcg_status like it is done for KVM. Use the symbolic constants at this chance. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- target-i386/helper.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 1217452..f0c546d 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1147,8 +1147,8 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status, if (cenv == env) { continue; } - -qemu_inject_x86_mce(env, 1, 0xa000, 0, 0, 0); +qemu_inject_x86_mce(env, 1, MCI_STATUS_VAL | MCI_STATUS_UC, +MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0); } } } -- 1.7.2.3
[Qemu-devel] [PATCH 12/23] kvm: Set up signal mask also for !CONFIG_IOTHREAD
From: Jan Kiszka Block SIG_IPI, unblock it during KVM_RUN, just like in io-thread mode. It's unused so far, but this infrastructure will be required for self-IPIs and to process SIGBUS plus, in KVM mode, SIGIO and SIGALRM. As Windows doesn't support signal services, we need to provide a stub for the init function. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c | 29 +++-- 1 files changed, 27 insertions(+), 2 deletions(-) diff --git a/cpus.c b/cpus.c index 42717ba..a33e470 100644 --- a/cpus.c +++ b/cpus.c @@ -231,11 +231,9 @@ fail: return err; } -#ifdef CONFIG_IOTHREAD static void dummy_signal(int sig) { } -#endif #else /* _WIN32 */ @@ -267,6 +265,32 @@ static void qemu_event_increment(void) #endif /* _WIN32 */ #ifndef CONFIG_IOTHREAD +static void qemu_kvm_init_cpu_signals(CPUState *env) +{ +#ifndef _WIN32 +int r; +sigset_t set; +struct sigaction sigact; + +memset(&sigact, 0, sizeof(sigact)); +sigact.sa_handler = dummy_signal; +sigaction(SIG_IPI, &sigact, NULL); + +sigemptyset(&set); +sigaddset(&set, SIG_IPI); +pthread_sigmask(SIG_BLOCK, &set, NULL); + +pthread_sigmask(SIG_BLOCK, NULL, &set); +sigdelset(&set, SIG_IPI); +sigdelset(&set, SIGBUS); +r = kvm_set_signal_mask(env, &set); +if (r) { +fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r)); +exit(1); +} +#endif +} + int qemu_init_main_loop(void) { cpu_set_debug_excp_handler(cpu_debug_handler); @@ -292,6 +316,7 @@ void qemu_init_vcpu(void *_env) fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r)); exit(1); } +qemu_kvm_init_cpu_signals(env); } } -- 1.7.2.3
[Qemu-devel] [PATCH 02/23] Stop current VCPU on synchronous reset requests
From: Jan Kiszka If some I/O operation ends up calling qemu_system_reset_request in VCPU context, we record this and inform the io-thread, but we do not terminate the VCPU loop. This can lead to fairly unexpected behavior if the triggering reset operation is supposed to work synchronously. Fix this for TCG (when run in deterministic I/O mode) by setting the VCPU on stop and issuing a cpu_exit. KVM requires some more work on its VCPU loop. [ ported from qemu-kvm ] Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c | 13 + cpus.h |1 + vl.c |1 + 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cpus.c b/cpus.c index ab6e40e..ceb3a83 100644 --- a/cpus.c +++ b/cpus.c @@ -99,6 +99,14 @@ void cpu_synchronize_all_post_init(void) } } +void cpu_stop_current(void) +{ +if (cpu_single_env) { +cpu_single_env->stopped = 1; +cpu_exit(cpu_single_env); +} +} + int cpu_is_stopped(CPUState *env) { return !vm_running || env->stopped; @@ -863,10 +871,7 @@ void vm_stop(int reason) * FIXME: should not return to device code in case * vm_stop() has been requested. */ -if (cpu_single_env) { -cpu_exit(cpu_single_env); -cpu_single_env->stop = 1; -} +cpu_stop_current(); return; } do_vm_stop(reason); diff --git a/cpus.h b/cpus.h index bf4d9bb..4cadb64 100644 --- a/cpus.h +++ b/cpus.h @@ -6,6 +6,7 @@ int qemu_init_main_loop(void); void qemu_main_loop_start(void); void resume_all_vcpus(void); void pause_all_vcpus(void); +void cpu_stop_current(void); /* vl.c */ extern int smp_cores; diff --git a/vl.c b/vl.c index 655617f..b1dc3ff 100644 --- a/vl.c +++ b/vl.c @@ -1296,6 +1296,7 @@ void qemu_system_reset_request(void) } else { reset_requested = 1; } +cpu_stop_current(); qemu_notify_event(); } -- 1.7.2.3
[Qemu-devel] [PATCH 01/23] Prevent abortion on multiple VCPU kicks
From: Jan Kiszka If we call qemu_cpu_kick more than once before the target was able to process the signal, pthread_kill will fail, and qemu will abort. Prevent this by avoiding the redundant signal. This logic can be found in qemu-kvm as well. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpu-defs.h |1 + cpus.c |6 +- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index 8d4bf86..db809ed 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -205,6 +205,7 @@ typedef struct CPUWatchpoint { uint32_t stopped; /* Artificially stopped */\ struct QemuThread *thread; \ struct QemuCond *halt_cond; \ +int thread_kicked; \ struct qemu_work_item *queued_work_first, *queued_work_last;\ const char *cpu_model_str; \ struct KVMState *kvm_state; \ diff --git a/cpus.c b/cpus.c index 4c9928e..ab6e40e 100644 --- a/cpus.c +++ b/cpus.c @@ -481,6 +481,7 @@ static void qemu_wait_io_event_common(CPUState *env) qemu_cond_signal(&qemu_pause_cond); } flush_queued_work(env); +env->thread_kicked = false; } static void qemu_tcg_wait_io_event(void) @@ -648,7 +649,10 @@ void qemu_cpu_kick(void *_env) { CPUState *env = _env; qemu_cond_broadcast(env->halt_cond); -qemu_thread_signal(env->thread, SIG_IPI); +if (!env->thread_kicked) { +qemu_thread_signal(env->thread, SIG_IPI); +env->thread_kicked = true; +} } int qemu_cpu_self(void *_env) -- 1.7.2.3
[Qemu-devel] [PATCH 20/23] kvm: Remove static return code of kvm_handle_io
From: Jan Kiszka Improve the readability of the exit dispatcher by moving the static return value of kvm_handle_io to its caller. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- kvm-all.c | 17 - 1 files changed, 8 insertions(+), 9 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 0c20f9e..4729ec5 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -774,8 +774,8 @@ err: return ret; } -static int kvm_handle_io(uint16_t port, void *data, int direction, int size, - uint32_t count) +static void kvm_handle_io(uint16_t port, void *data, int direction, int size, + uint32_t count) { int i; uint8_t *ptr = data; @@ -809,8 +809,6 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size, ptr += size; } - -return 1; } #ifdef KVM_CAP_INTERNAL_ERROR_DATA @@ -944,11 +942,12 @@ int kvm_cpu_exec(CPUState *env) switch (run->exit_reason) { case KVM_EXIT_IO: DPRINTF("handle_io\n"); -ret = kvm_handle_io(run->io.port, -(uint8_t *)run + run->io.data_offset, -run->io.direction, -run->io.size, -run->io.count); +kvm_handle_io(run->io.port, + (uint8_t *)run + run->io.data_offset, + run->io.direction, + run->io.size, + run->io.count); +ret = 1; break; case KVM_EXIT_MMIO: DPRINTF("handle_mmio\n"); -- 1.7.2.3
[Qemu-devel] [PATCH 04/23] Trigger exit from cpu_exec_all on pending IO events
From: Jan Kiszka Except for timer events, we currently do not leave the loop over all VCPUs if an IO event was filed. That may cause unexpected IO latencies under !CONFIG_IOTHREAD in SMP scenarios. Fix it by setting the global exit_request which breaks the loop. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/cpus.c b/cpus.c index ceb3a83..5dfc54e 100644 --- a/cpus.c +++ b/cpus.c @@ -315,6 +315,7 @@ void qemu_notify_event(void) if (next_cpu && env != next_cpu) { cpu_exit(next_cpu); } +exit_request = 1; } void qemu_mutex_lock_iothread(void) {} -- 1.7.2.3
[Qemu-devel] [PATCH 10/23] kvm: Provide sigbus services arch-independently
From: Jan Kiszka Provide arch-independent kvm_on_sigbus* stubs to remove the #ifdef'ery from cpus.c. This patch also fixes --disable-kvm build by providing the missing kvm_on_sigbus_vcpu kvm-stub. Signed-off-by: Jan Kiszka Reviewed-by: Paolo Bonzini Acked-by: Alexander Graf Signed-off-by: Marcelo Tosatti --- cpus.c | 10 -- kvm-all.c | 10 ++ kvm-stub.c |5 + kvm.h |7 +-- target-i386/kvm.c |4 ++-- target-ppc/kvm.c | 10 ++ target-s390x/kvm.c | 10 ++ 7 files changed, 46 insertions(+), 10 deletions(-) diff --git a/cpus.c b/cpus.c index 8475757..3a32828 100644 --- a/cpus.c +++ b/cpus.c @@ -543,10 +543,9 @@ static void sigbus_reraise(void) static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, void *ctx) { -#if defined(TARGET_I386) -if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) -#endif +if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr)) { sigbus_reraise(); +} } static void qemu_kvm_eat_signal(CPUState *env, int timeout) @@ -579,10 +578,9 @@ static void qemu_kvm_eat_signal(CPUState *env, int timeout) switch (r) { case SIGBUS: -#ifdef TARGET_I386 -if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) -#endif +if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) { sigbus_reraise(); +} break; default: break; diff --git a/kvm-all.c b/kvm-all.c index 55f6ac3..a83aff2 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1366,3 +1366,13 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) return -ENOSYS; #endif } + +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ +return kvm_arch_on_sigbus_vcpu(env, code, addr); +} + +int kvm_on_sigbus(int code, void *addr) +{ +return kvm_arch_on_sigbus(code, addr); +} diff --git a/kvm-stub.c b/kvm-stub.c index 88682f2..d6b6c8e 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -147,6 +147,11 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign) return -ENOSYS; } +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ +return 1; +} + int kvm_on_sigbus(int code, void *addr) { return 1; diff --git a/kvm.h b/kvm.h index ca57517..b2fb5c6 100644 --- a/kvm.h +++ b/kvm.h @@ -81,6 +81,9 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset); int kvm_pit_in_kernel(void); int kvm_irqchip_in_kernel(void); +int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr); +int kvm_on_sigbus(int code, void *addr); + /* internal API */ struct KVMState; @@ -121,8 +124,8 @@ int kvm_arch_init_vcpu(CPUState *env); void kvm_arch_reset_vcpu(CPUState *env); -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr); -int kvm_on_sigbus(int code, void *addr); +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr); +int kvm_arch_on_sigbus(int code, void *addr); struct kvm_guest_debug; struct kvm_debug_exit_arch; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 05010bb..9df8ff8 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1839,7 +1839,7 @@ static void kvm_mce_inj_srao_memscrub2(CPUState *env, target_phys_addr_t paddr) #endif -int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr) { #if defined(KVM_CAP_MCE) void *vaddr; @@ -1889,7 +1889,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) return 0; } -int kvm_on_sigbus(int code, void *addr) +int kvm_arch_on_sigbus(int code, void *addr) { #if defined(KVM_CAP_MCE) if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) { diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 710eca1..93ecc57 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -404,3 +404,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env) { return true; } + +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ +return 1; +} + +int kvm_arch_on_sigbus(int code, void *addr) +{ +return 1; +} diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 38823f5..1702c46 100644 --- a/target-s390x/kvm.c +++ b/target-s390x/kvm.c @@ -505,3 +505,13 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env) { return true; } + +int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr) +{ +return 1; +} + +int kvm_arch_on_sigbus(int code, void *addr) +{ +return 1; +} -- 1.7.2.3
[Qemu-devel] [PATCH 17/23] kvm: Add MCE signal support for !CONFIG_IOTHREAD
From: Jan Kiszka Currently, we only configure and process MCE-related SIGBUS events if CONFIG_IOTHREAD is enabled. The groundwork is laid, we just need to factor out the required handler registration and system configuration. Signed-off-by: Jan Kiszka CC: Huang Ying CC: Hidetoshi Seto CC: Jin Dongming Signed-off-by: Marcelo Tosatti --- cpus.c | 107 +++- 1 files changed, 65 insertions(+), 42 deletions(-) diff --git a/cpus.c b/cpus.c index 18caf47..c4c5914 100644 --- a/cpus.c +++ b/cpus.c @@ -34,9 +34,6 @@ #include "cpus.h" #include "compatfd.h" -#ifdef CONFIG_LINUX -#include -#endif #ifdef SIGRTMIN #define SIG_IPI (SIGRTMIN+4) @@ -44,10 +41,24 @@ #define SIG_IPI SIGUSR1 #endif +#ifdef CONFIG_LINUX + +#include + #ifndef PR_MCE_KILL #define PR_MCE_KILL 33 #endif +#ifndef PR_MCE_KILL_SET +#define PR_MCE_KILL_SET 1 +#endif + +#ifndef PR_MCE_KILL_EARLY +#define PR_MCE_KILL_EARLY 1 +#endif + +#endif /* CONFIG_LINUX */ + static CPUState *next_cpu; /***/ @@ -166,6 +177,52 @@ static void cpu_debug_handler(CPUState *env) vm_stop(EXCP_DEBUG); } +#ifdef CONFIG_LINUX +static void sigbus_reraise(void) +{ +sigset_t set; +struct sigaction action; + +memset(&action, 0, sizeof(action)); +action.sa_handler = SIG_DFL; +if (!sigaction(SIGBUS, &action, NULL)) { +raise(SIGBUS); +sigemptyset(&set); +sigaddset(&set, SIGBUS); +sigprocmask(SIG_UNBLOCK, &set, NULL); +} +perror("Failed to re-raise SIGBUS!\n"); +abort(); +} + +static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, + void *ctx) +{ +if (kvm_on_sigbus(siginfo->ssi_code, + (void *)(intptr_t)siginfo->ssi_addr)) { +sigbus_reraise(); +} +} + +static void qemu_init_sigbus(void) +{ +struct sigaction action; + +memset(&action, 0, sizeof(action)); +action.sa_flags = SA_SIGINFO; +action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; +sigaction(SIGBUS, &action, NULL); + +prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0); +} + +#else /* !CONFIG_LINUX */ + +static void qemu_init_sigbus(void) +{ +} +#endif /* !CONFIG_LINUX */ + #ifndef _WIN32 static int io_thread_fd = -1; @@ -288,8 +345,6 @@ static int qemu_signalfd_init(sigset_t mask) return 0; } -static void sigbus_reraise(void); - static void qemu_kvm_eat_signals(CPUState *env) { struct timespec ts = { 0, 0 }; @@ -310,13 +365,11 @@ static void qemu_kvm_eat_signals(CPUState *env) } switch (r) { -#ifdef CONFIG_IOTHREAD case SIGBUS: if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) { sigbus_reraise(); } break; -#endif default: break; } @@ -405,6 +458,7 @@ static sigset_t block_synchronous_signals(void) sigset_t set; sigemptyset(&set); +sigaddset(&set, SIGBUS); if (kvm_enabled()) { /* * We need to process timer signals synchronously to avoid a race @@ -433,6 +487,8 @@ int qemu_init_main_loop(void) #endif cpu_set_debug_excp_handler(cpu_debug_handler); +qemu_init_sigbus(); + return qemu_event_init(); } @@ -565,13 +621,9 @@ static void qemu_tcg_init_cpu_signals(void) pthread_sigmask(SIG_UNBLOCK, &set, NULL); } -static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, - void *ctx); - static sigset_t block_io_signals(void) { sigset_t set; -struct sigaction action; /* SIGUSR2 used by posix-aio-compat.c */ sigemptyset(&set); @@ -585,12 +637,6 @@ static sigset_t block_io_signals(void) sigaddset(&set, SIGBUS); pthread_sigmask(SIG_BLOCK, &set, NULL); -memset(&action, 0, sizeof(action)); -action.sa_flags = SA_SIGINFO; -action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; -sigaction(SIGBUS, &action, NULL); -prctl(PR_MCE_KILL, 1, 1, 0, 0); - return set; } @@ -601,6 +647,8 @@ int qemu_init_main_loop(void) cpu_set_debug_excp_handler(cpu_debug_handler); +qemu_init_sigbus(); + blocked_signals = block_io_signals(); ret = qemu_signalfd_init(blocked_signals); @@ -708,31 +756,6 @@ static void qemu_tcg_wait_io_event(void) } } -static void sigbus_reraise(void) -{ -sigset_t set; -struct sigaction action; - -memset(&action, 0, sizeof(action)); -action.sa_handler = SIG_DFL; -if (!sigaction(SIGBUS, &action, NULL)) { -raise(SIGBUS); -sigemptyset(&set); -sigaddset(&set, SIGBUS); -sigprocmask(SIG_UNBLOCK, &set, NULL); -} -perror("Failed to re-raise SIGBUS!\n"); -abort(); -} - -static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, - void *ctx)
[Qemu-devel] [PATCH 15/23] Set up signalfd under !CONFIG_IOTHREAD
From: Jan Kiszka Will be required for SIGBUS handling. For obvious reasons, this will remain a nop on Windows hosts. Signed-off-by: Jan Kiszka Reviewed-by: Paolo Bonzini Signed-off-by: Marcelo Tosatti --- Makefile.objs |2 +- cpus.c| 117 +++-- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index f1c7bfe..05014e9 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -141,7 +141,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y)) common-obj-y += iov.o acl.o common-obj-$(CONFIG_THREAD) += qemu-thread.o -common-obj-$(CONFIG_IOTHREAD) += compatfd.o +common-obj-$(CONFIG_POSIX) += compatfd.o common-obj-y += notify.o event_notifier.o common-obj-y += qemu-timer.o qemu-timer-common.o diff --git a/cpus.c b/cpus.c index 861e270..359361f 100644 --- a/cpus.c +++ b/cpus.c @@ -235,6 +235,59 @@ static void dummy_signal(int sig) { } +/* If we have signalfd, we mask out the signals we want to handle and then + * use signalfd to listen for them. We rely on whatever the current signal + * handler is to dispatch the signals when we receive them. + */ +static void sigfd_handler(void *opaque) +{ +int fd = (unsigned long) opaque; +struct qemu_signalfd_siginfo info; +struct sigaction action; +ssize_t len; + +while (1) { +do { +len = read(fd, &info, sizeof(info)); +} while (len == -1 && errno == EINTR); + +if (len == -1 && errno == EAGAIN) { +break; +} + +if (len != sizeof(info)) { +printf("read from sigfd returned %zd: %m\n", len); +return; +} + +sigaction(info.ssi_signo, NULL, &action); +if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) { +action.sa_sigaction(info.ssi_signo, +(siginfo_t *)&info, NULL); +} else if (action.sa_handler) { +action.sa_handler(info.ssi_signo); +} +} +} + +static int qemu_signalfd_init(sigset_t mask) +{ +int sigfd; + +sigfd = qemu_signalfd(&mask); +if (sigfd == -1) { +fprintf(stderr, "failed to create signalfd\n"); +return -errno; +} + +fcntl_setfl(sigfd, O_NONBLOCK); + +qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL, + (void *)(unsigned long) sigfd); + +return 0; +} + static void sigbus_reraise(void); static void qemu_kvm_eat_signals(CPUState *env) @@ -338,6 +391,17 @@ static void qemu_kvm_init_cpu_signals(CPUState *env) int qemu_init_main_loop(void) { +#ifndef _WIN32 +sigset_t blocked_signals; +int ret; + +sigemptyset(&blocked_signals); + +ret = qemu_signalfd_init(blocked_signals); +if (ret) { +return ret; +} +#endif cpu_set_debug_excp_handler(cpu_debug_handler); return qemu_event_init(); @@ -430,41 +494,6 @@ static QemuCond qemu_system_cond; static QemuCond qemu_pause_cond; static QemuCond qemu_work_cond; -/* If we have signalfd, we mask out the signals we want to handle and then - * use signalfd to listen for them. We rely on whatever the current signal - * handler is to dispatch the signals when we receive them. - */ -static void sigfd_handler(void *opaque) -{ -int fd = (unsigned long) opaque; -struct qemu_signalfd_siginfo info; -struct sigaction action; -ssize_t len; - -while (1) { -do { -len = read(fd, &info, sizeof(info)); -} while (len == -1 && errno == EINTR); - -if (len == -1 && errno == EAGAIN) { -break; -} - -if (len != sizeof(info)) { -printf("read from sigfd returned %zd: %m\n", len); -return; -} - -sigaction(info.ssi_signo, NULL, &action); -if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) { -action.sa_sigaction(info.ssi_signo, -(siginfo_t *)&info, NULL); -} else if (action.sa_handler) { -action.sa_handler(info.ssi_signo); -} -} -} - static void cpu_signal(int sig) { if (cpu_single_env) { @@ -536,24 +565,6 @@ static sigset_t block_io_signals(void) return set; } -static int qemu_signalfd_init(sigset_t mask) -{ -int sigfd; - -sigfd = qemu_signalfd(&mask); -if (sigfd == -1) { -fprintf(stderr, "failed to create signalfd\n"); -return -errno; -} - -fcntl_setfl(sigfd, O_NONBLOCK); - -qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL, - (void *)(unsigned long) sigfd); - -return 0; -} - int qemu_init_main_loop(void) { int ret; -- 1.7.2.3
[Qemu-devel] [PATCH 14/23] kvm: Call qemu_kvm_eat_signals also under !CONFIG_IOTHREAD
From: Jan Kiszka Move qemu_kvm_eat_signals around and call it also when the IO-thread is not used. Do not yet process SIGBUS, will be armed in a separate step. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c | 90 +--- 1 files changed, 52 insertions(+), 38 deletions(-) diff --git a/cpus.c b/cpus.c index 04138ba..861e270 100644 --- a/cpus.c +++ b/cpus.c @@ -235,6 +235,47 @@ static void dummy_signal(int sig) { } +static void sigbus_reraise(void); + +static void qemu_kvm_eat_signals(CPUState *env) +{ +struct timespec ts = { 0, 0 }; +siginfo_t siginfo; +sigset_t waitset; +sigset_t chkset; +int r; + +sigemptyset(&waitset); +sigaddset(&waitset, SIG_IPI); +sigaddset(&waitset, SIGBUS); + +do { +r = sigtimedwait(&waitset, &siginfo, &ts); +if (r == -1 && !(errno == EAGAIN || errno == EINTR)) { +perror("sigtimedwait"); +exit(1); +} + +switch (r) { +#ifdef CONFIG_IOTHREAD +case SIGBUS: +if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) { +sigbus_reraise(); +} +break; +#endif +default: +break; +} + +r = sigpending(&chkset); +if (r == -1) { +perror("sigpending"); +exit(1); +} +} while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); +} + #else /* _WIN32 */ HANDLE qemu_event_handle; @@ -262,6 +303,10 @@ static void qemu_event_increment(void) exit (1); } } + +static void qemu_kvm_eat_signals(CPUState *env) +{ +} #endif /* _WIN32 */ #ifndef CONFIG_IOTHREAD @@ -648,43 +693,6 @@ static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, } } -static void qemu_kvm_eat_signals(CPUState *env) -{ -struct timespec ts = { 0, 0 }; -siginfo_t siginfo; -sigset_t waitset; -sigset_t chkset; -int r; - -sigemptyset(&waitset); -sigaddset(&waitset, SIG_IPI); -sigaddset(&waitset, SIGBUS); - -do { -r = sigtimedwait(&waitset, &siginfo, &ts); -if (r == -1 && !(errno == EAGAIN || errno == EINTR)) { -perror("sigtimedwait"); -exit(1); -} - -switch (r) { -case SIGBUS: -if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr)) { -sigbus_reraise(); -} -break; -default: -break; -} - -r = sigpending(&chkset); -if (r == -1) { -perror("sigpending"); -exit(1); -} -} while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS)); -} - static void qemu_kvm_wait_io_event(CPUState *env) { while (!cpu_has_work(env)) @@ -949,6 +957,8 @@ static int qemu_cpu_exec(CPUState *env) bool cpu_exec_all(void) { +int r; + if (next_cpu == NULL) next_cpu = first_cpu; for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) { @@ -960,7 +970,11 @@ bool cpu_exec_all(void) if (qemu_alarm_pending()) break; if (cpu_can_run(env)) { -if (qemu_cpu_exec(env) == EXCP_DEBUG) { +r = qemu_cpu_exec(env); +if (kvm_enabled()) { +qemu_kvm_eat_signals(env); +} +if (r == EXCP_DEBUG) { break; } } else if (env->stop) { -- 1.7.2.3
[Qemu-devel] [PATCH 11/23] Refactor signal setup functions in cpus.c
From: Jan Kiszka Move {tcg,kvm}_init_ipi and block_io_signals to avoid prototypes, rename the former two to clarify that they deal with more than SIG_IPI. No functional changes - except for the tiny fixup of strerror usage. The forward declaration of sigbus_handler is just temporarily, it will be moved in a succeeding patch. dummy_signal is moved into the !_WIN32 block as we will soon need it also for !CONFIG_IOTHREAD. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c | 162 +--- 1 files changed, 83 insertions(+), 79 deletions(-) diff --git a/cpus.c b/cpus.c index 3a32828..42717ba 100644 --- a/cpus.c +++ b/cpus.c @@ -230,7 +230,15 @@ fail: close(fds[1]); return err; } -#else + +#ifdef CONFIG_IOTHREAD +static void dummy_signal(int sig) +{ +} +#endif + +#else /* _WIN32 */ + HANDLE qemu_event_handle; static void dummy_event_handler(void *opaque) @@ -256,7 +264,7 @@ static void qemu_event_increment(void) exit (1); } } -#endif +#endif /* _WIN32 */ #ifndef CONFIG_IOTHREAD int qemu_init_main_loop(void) @@ -352,10 +360,6 @@ static QemuCond qemu_system_cond; static QemuCond qemu_pause_cond; static QemuCond qemu_work_cond; -static void tcg_init_ipi(void); -static void kvm_init_ipi(CPUState *env); -static sigset_t block_io_signals(void); - /* If we have signalfd, we mask out the signals we want to handle and then * use signalfd to listen for them. We rely on whatever the current signal * handler is to dispatch the signals when we receive them. @@ -391,6 +395,77 @@ static void sigfd_handler(void *opaque) } } +static void cpu_signal(int sig) +{ +if (cpu_single_env) { +cpu_exit(cpu_single_env); +} +exit_request = 1; +} + +static void qemu_kvm_init_cpu_signals(CPUState *env) +{ +int r; +sigset_t set; +struct sigaction sigact; + +memset(&sigact, 0, sizeof(sigact)); +sigact.sa_handler = dummy_signal; +sigaction(SIG_IPI, &sigact, NULL); + +pthread_sigmask(SIG_BLOCK, NULL, &set); +sigdelset(&set, SIG_IPI); +sigdelset(&set, SIGBUS); +r = kvm_set_signal_mask(env, &set); +if (r) { +fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r)); +exit(1); +} +} + +static void qemu_tcg_init_cpu_signals(void) +{ +sigset_t set; +struct sigaction sigact; + +memset(&sigact, 0, sizeof(sigact)); +sigact.sa_handler = cpu_signal; +sigaction(SIG_IPI, &sigact, NULL); + +sigemptyset(&set); +sigaddset(&set, SIG_IPI); +pthread_sigmask(SIG_UNBLOCK, &set, NULL); +} + +static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo, + void *ctx); + +static sigset_t block_io_signals(void) +{ +sigset_t set; +struct sigaction action; + +/* SIGUSR2 used by posix-aio-compat.c */ +sigemptyset(&set); +sigaddset(&set, SIGUSR2); +pthread_sigmask(SIG_UNBLOCK, &set, NULL); + +sigemptyset(&set); +sigaddset(&set, SIGIO); +sigaddset(&set, SIGALRM); +sigaddset(&set, SIG_IPI); +sigaddset(&set, SIGBUS); +pthread_sigmask(SIG_BLOCK, &set, NULL); + +memset(&action, 0, sizeof(action)); +action.sa_flags = SA_SIGINFO; +action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; +sigaction(SIGBUS, &action, NULL); +prctl(PR_MCE_KILL, 1, 1, 0, 0); + +return set; +} + static int qemu_signalfd_init(sigset_t mask) { int sigfd; @@ -619,7 +694,7 @@ static void *kvm_cpu_thread_fn(void *arg) exit(1); } -kvm_init_ipi(env); +qemu_kvm_init_cpu_signals(env); /* signal CPU creation */ env->created = 1; @@ -642,7 +717,7 @@ static void *tcg_cpu_thread_fn(void *arg) { CPUState *env = arg; -tcg_init_ipi(); +qemu_tcg_init_cpu_signals(); qemu_thread_self(env->thread); /* signal CPU creation */ @@ -683,77 +758,6 @@ int qemu_cpu_self(void *_env) return qemu_thread_equal(&this, env->thread); } -static void cpu_signal(int sig) -{ -if (cpu_single_env) -cpu_exit(cpu_single_env); -exit_request = 1; -} - -static void tcg_init_ipi(void) -{ -sigset_t set; -struct sigaction sigact; - -memset(&sigact, 0, sizeof(sigact)); -sigact.sa_handler = cpu_signal; -sigaction(SIG_IPI, &sigact, NULL); - -sigemptyset(&set); -sigaddset(&set, SIG_IPI); -pthread_sigmask(SIG_UNBLOCK, &set, NULL); -} - -static void dummy_signal(int sig) -{ -} - -static void kvm_init_ipi(CPUState *env) -{ -int r; -sigset_t set; -struct sigaction sigact; - -memset(&sigact, 0, sizeof(sigact)); -sigact.sa_handler = dummy_signal; -sigaction(SIG_IPI, &sigact, NULL); - -pthread_sigmask(SIG_BLOCK, NULL, &set); -sigdelset(&set, SIG_IPI); -sigdelset(&set, SIGBUS); -r = kvm_set_signal_mask(env, &set); -if (r) { -fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r)); -exit(1); -} -} - -static s
[Qemu-devel] [PATCH 09/23] kvm: Handle kvm_init_vcpu errors
From: Jan Kiszka Do not ignore errors of kvm_init_vcpu, they are fatal. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- cpus.c | 19 +++ 1 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cpus.c b/cpus.c index 312c7a2..8475757 100644 --- a/cpus.c +++ b/cpus.c @@ -273,12 +273,18 @@ void qemu_main_loop_start(void) void qemu_init_vcpu(void *_env) { CPUState *env = _env; +int r; env->nr_cores = smp_cores; env->nr_threads = smp_threads; -if (kvm_enabled()) -kvm_init_vcpu(env); -return; + +if (kvm_enabled()) { +r = kvm_init_vcpu(env); +if (r < 0) { +fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r)); +exit(1); +} +} } int qemu_cpu_self(void *env) @@ -604,11 +610,16 @@ static int qemu_cpu_exec(CPUState *env); static void *kvm_cpu_thread_fn(void *arg) { CPUState *env = arg; +int r; qemu_mutex_lock(&qemu_global_mutex); qemu_thread_self(env->thread); -kvm_init_vcpu(env); +r = kvm_init_vcpu(env); +if (r < 0) { +fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r)); +exit(1); +} kvm_init_ipi(env); -- 1.7.2.3
[Qemu-devel] [PATCH 03/23] Process vmstop requests in IO thread
From: Jan Kiszka A pending vmstop request is also a reason to leave the inner main loop. So far we ignored it, and pending stop requests issued over VCPU threads were simply ignored. Signed-off-by: Jan Kiszka Signed-off-by: Marcelo Tosatti --- vl.c | 14 +- 1 files changed, 5 insertions(+), 9 deletions(-) diff --git a/vl.c b/vl.c index b1dc3ff..57b4c9f 100644 --- a/vl.c +++ b/vl.c @@ -1391,15 +1391,11 @@ void main_loop_wait(int nonblocking) static int vm_can_run(void) { -if (powerdown_requested) -return 0; -if (reset_requested) -return 0; -if (shutdown_requested) -return 0; -if (debug_requested) -return 0; -return 1; +return !(powerdown_requested || + reset_requested || + shutdown_requested || + debug_requested || + vmstop_requested); } qemu_irq qemu_system_powerdown; -- 1.7.2.3
Re: [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
On 02/04/2011 12:13 AM, Stefan Hajnoczi wrote: On Thu, Feb 3, 2011 at 5:41 PM, Michael Roth wrote: For things like logging and i/o on a frozen system...I agree we'd need some flag for these kinds of situations. Maybe a disable_logging() flagi really don't like this though... I'd imagine even syslogd() could block virtagent in this type of situation, so that would need to be disabled as well. But doing so completely subverts our attempts and providing proper accounting of what the agent is doing to the user. A user can freeze the filesystem, knowing that logging would be disabled, then prod at whatever he wants. So the handling should be something specific to fsfreeze, with stricter requirements: If a user calls fsfreeze(), we disable logging, but also disable the ability to do anything other than fsthaw() or fsstatus(). This actually solves the potential deadlocking problem for other RPCs as well...since they cant be executed in the first place. So I think that addresses the agent deadlocking itself, post-freeze. However, fsfreeze() itself might lock-up the agent as well...I'm not confident we can really put any kind of bound on how long it'll take to execute, and if we timeout on the client-side the agent can still block here. Plus there are any number of other situations where an RPC can still hang things...in the future when we potentially allow things like script execution, they might do something like attempt to connect to a socket that's already in use and wait on the server for an arbitrary amount of time, or open a file on an nfs share that in currently unresponsive. So a solution for these situations is still needed, and I'm starting to agree that threads are needed, but I don't think we should do RPCs concurrently (not sure if that's what is being suggested or not). At least, there's no pressing reason for it as things currently stand (there aren't currently any RPCs where fast response times are all that important, so it's okay to serialize them behind previous RPCs, and HMP/QMP are command at a time), and it's something that Im fairly confident can be added if the need arises in the future. But for dealing with a situation where an RPC can hang the agent, I think one thread should do it. Basically: We associate each RPC with a time limit. Some RPCs, very special ones that we'd trust with our kids, could potentially specify an unlimited timeout. The client side should use this same timeout on it's end. In the future we might allow the user to explicitly disable the timeout for a certain RPC. The logic would then be: - read in a client RPC request - start a thread to do RPC - if there's a timeout, register an alarm(), with a handler that will call something like pthread_kill(current_worker_thread). On the thread side, this signal will induce a pthread_exit() - wait for the thread to return (pthread_join(current_worker_thread)) - return it's response back to the caller if it finished, return a timeout indication otherwise I'm not sure about a timeout inside virtagent. A client needs to protect itself with its own timeout and shouldn't rely on the server to prevent it from locking up - especially since the server is a guest which we have no control over. So the timeout does not help the guest. We actually have timeouts for the client already (though they'll need to be reworked a bit to handle the proposed solutions), what I'm proposing is an additional timeout on the guest/server side for the actual RPCs, since a blocking RPC can still hang the guest agent. Aborting an RPC handler could leave the system in an inconsistent state unless we are careful. For example, aborting freeze requires thawing those file systems that have been successfully frozen so far. For other handlers it might leave temporary files around, or if they are not carefully written may partially update files in-place and leave them corrupted. So instead of a blanket timeout, I think handlers that perform operations that may block for unknown periods of time could specifically use timeouts. That gives the handler control to perform cleanup. Good point. Although, I'm not sure I want to push timeout handling to the actual RPCs thoughsomething as simple as open()/read() can block indefinitely in certain situations, and it'll be difficult to account for every situation, and the resulting code will be tedious as well. I'd really like the make the actual RPC as simple as possible, since it's something that may be extended heavily over time. So what if we simply allow an RPC to register a timeout handler at the beginning of the RPC call? So when the thread doing the RPC exits we: - check to see if thread exited as a result of timeout - check to see if a timeout handler was registered, if so, call it, reset the handler, then return a timeout indication - if it didn't time out, return the response The only burden this puts on the RPC author is that information they need to recover state w
[Qemu-devel] Re: [PATCH v2 00/24] [uq/master] Patch queue, part II
On 2011-02-04 14:54, Marcelo Tosatti wrote: > On Tue, Feb 01, 2011 at 10:15:40PM +0100, Jan Kiszka wrote: >> Version 2 of part II. Changes: >> - Fixed "Unconditionally reenter kernel after IO exits" to take >>self-INIT into account >> - Fixed misplaced hunk in "Fix race between timer signals and vcpu >>entry under !IOTHREAD" (rebase artifact) >> - Factor out block_synchronous_signals (analogue to block_io_signals) >> - Additional fix to break out of SMP VCPU loop on pending IO event >> - Fork qemu_kvm_init_cpu_signals over CONFIG_IOTHREAD >> - Additional cleanup, flattening the main loop >> >> Hope I addressed all review comments (except for passing env to >> qemu_cpu_kick_self which I think is better as it is). > > 1 and 24 rejected, applied the remaining ones, thanks. 23 is missing as well. You want me to post the last two directly? Jan signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
On Fri, 04 Feb 2011 16:27:46 +0100 Markus Armbruster wrote: > Anthony Liguori writes: > > > On 02/02/2011 01:28 PM, Stefan Weil wrote: > [...] > >> [PATCH 1/3] tests: Fix two memory leaks > >> (http://patchwork.ozlabs.org/patch/79945/) > > >> [PATCH 2/3] check-qdict: Fix possible crash > >> (http://patchwork.ozlabs.org/patch/79946/) > > > > Luiz > > I wouldn't bother with the second one for 0.14. Yes, we're reading > lines from a file with %s, but it's a fixed file with known contents, no > long lines, and we're reading it in a test program only developers ever > use. Agreed. > > As to the first one, Luiz has never touched that file. Neither have I, > and it's not obvious to me why it should go into 0.14. > > [...] >
[Qemu-devel] Re: [PATCH v2 00/24] [uq/master] Patch queue, part II
On Fri, Feb 04, 2011 at 05:29:00PM +0100, Jan Kiszka wrote: > On 2011-02-04 14:54, Marcelo Tosatti wrote: > > On Tue, Feb 01, 2011 at 10:15:40PM +0100, Jan Kiszka wrote: > >> Version 2 of part II. Changes: > >> - Fixed "Unconditionally reenter kernel after IO exits" to take > >>self-INIT into account > >> - Fixed misplaced hunk in "Fix race between timer signals and vcpu > >>entry under !IOTHREAD" (rebase artifact) > >> - Factor out block_synchronous_signals (analogue to block_io_signals) > >> - Additional fix to break out of SMP VCPU loop on pending IO event > >> - Fork qemu_kvm_init_cpu_signals over CONFIG_IOTHREAD > >> - Additional cleanup, flattening the main loop > >> > >> Hope I addressed all review comments (except for passing env to > >> qemu_cpu_kick_self which I think is better as it is). > > > > 1 and 24 rejected, applied the remaining ones, thanks. > > 23 is missing as well. You want me to post the last two directly? > > Jan Better include in the next round to make Anthony's life easier (they're not critical anyway). BTW, Anthony, patches are being sent twice to the list, once by author and again by pull request. It is that way by your request.
Re: [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
On 02/04/2011 05:03 AM, Jes Sorensen wrote: On 02/03/11 18:41, Michael Roth wrote: On 02/02/2011 02:48 AM, Jes Sorensen wrote: Yes very much so[1] - one reason why it would be nice to have virtagent use threads to execute the actual commands. We should probably add a flag to agent commands indicating whether they issue disk I/O or not, so we can block attempts to execute commands that do so, while the guest is frozen. **Warning, epic response** For things like logging and i/o on a frozen system...I agree we'd need some flag for these kinds of situations. Maybe a disable_logging() flagi really don't like this though... I'd imagine even syslogd() could block virtagent in this type of situation, so that would need to be disabled as well. One way to resolve this would be to have the logging handled in it's own thread, which uses non blocking calls to do the actual logging. Obviously we'd have to use a non file system based communication method between the main thread and the logging thread :) I suspect syslogd() already buffers to some extent. But the problem there, as well the problem with having our own buffered logging implementation, is that we can't rely on being able to log an arbitrary number of messages. As some point that interface would need to either block, or stop dropping log messages. If it blocks, we're deadlocked again. If it drops messages, it's trivial for someone to flood it with messages after the fsfreeze() to get back into a state where they can execute RPC without any accounting. So a seperate logging thread doesn't buy us much, and what we come up with is rely gonna come down to syslogd: 1) if syslogd blocks, we must disable logging after fsfreeze(). Buffering, on syslogd's side or our own, only buys us time. If we disable logging, we must only allow absolutely required/benign RPCs. fsstatus/fsthaw are required, things like va.ping are benign, and potentially useful, in this particular situation. copyfile/shutdown/exec/etc should be considered "high-risk"...we want to make sure these are logged. 2) if syslogd doesnt block, it either drops messages at some point with no indication to us, or it drops them and provides some indication. If there's no indication, we must treat this the same way we treat 1), since we must assume that logging is effectively disabled. So only required or benign RPCs. if we get some indication when a call to syslog() fails to log/buffer, we can allow all RPCs, but treat failures to log as a cue to immediately cleanup and exit the RPC. fsfreeze() under this circumstance will need to make sure it only logs after it does the unfreeze, else we may never be able to unfreeze at that point forward. So the solution is dependent on syslogd's behavior. Ill have to do some testing to confirm...but I think the above covers the possibilities. But doing so completely subverts our attempts and providing proper accounting of what the agent is doing to the user. A user can freeze the filesystem, knowing that logging would be disabled, then prod at whatever he wants. So the handling should be something specific to fsfreeze, with stricter requirements: If a user calls fsfreeze(), we disable logging, but also disable the ability to do anything other than fsthaw() or fsstatus(). This actually solves the potential deadlocking problem for other RPCs as well...since they cant be executed in the first place. I disagree that we should block all calls, except for fsfreeze/fsstatus/ fsthaw in this case. There are other calls that could be valid in this situations, so I think it needs to be evaluated on a case by case basis. So a solution for these situations is still needed, and I'm starting to agree that threads are needed, but I don't think we should do RPCs concurrently (not sure if that's what is being suggested or not). At least, there's no pressing reason for it as things currently stand (there aren't currently any RPCs where fast response times are all that important, so it's okay to serialize them behind previous RPCs, and HMP/QMP are command at a time), and it's something that Im fairly confident can be added if the need arises in the future. Eventually I think we will need to be able to support concurrent RPC calls. There can be situations where an operation takes a long time while it is valid to be able to ping the guest agent to verify that it is still alive etc. Currently we're limited to 1 RPC at a time by the monitor/hmp/qmp (except for some niche cases where virtagent has multiple requests in flight). Ideally this will remain the interface we expose to users, but there could be situations where this isn't the case...for instance, other bits of qemu making direct calls into virtagent. I think we can add support for concurrent RPCs incrementally though...I've thought over the implementation details a bit and it seems to be fairly straightforward. I think we need to get the basic use cases down first though.
Re: [Qemu-devel] [PATCH 1/2] Add virtagent file system freeze/thaw
On Fri, Feb 4, 2011 at 4:27 PM, Michael Roth wrote: >> Aborting an RPC handler could leave the system in an inconsistent >> state unless we are careful. For example, aborting freeze requires >> thawing those file systems that have been successfully frozen so far. >> For other handlers it might leave temporary files around, or if they >> are not carefully written may partially update files in-place and >> leave them corrupted. >> >> So instead of a blanket timeout, I think handlers that perform >> operations that may block for unknown periods of time could >> specifically use timeouts. That gives the handler control to perform >> cleanup. > > Good point. Although, I'm not sure I want to push timeout handling to the > actual RPCs thoughsomething as simple as open()/read() can block > indefinitely in certain situations, and it'll be difficult to account for > every situation, and the resulting code will be tedious as well. I'd really > like the make the actual RPC as simple as possible, since it's something > that may be extended heavily over time. > > So what if we simply allow an RPC to register a timeout handler at the > beginning of the RPC call? So when the thread doing the RPC exits we: > > - check to see if thread exited as a result of timeout > - check to see if a timeout handler was registered, if so, call it, reset > the handler, then return a timeout indication > - if it didn't time out, return the response > > The only burden this puts on the RPC author is that information they need to > recover state would need to be accessible outside the thread, which is > easily done by encapsulating state in static/global structs. So the timeout > handler for fsfreeze, as it is currently written, would be something like: > > va_fsfreeze_timeout_handler(): > foreach mnt in fsfreeze.mount_list: > unfreeze(mnt) > fsfreeze.mount_list = NULL > > We'll need to be careful about lists/objects being in weird states due to > the forced exit, but I think it's doable. Yeah, still requires discipline but it could work. Stefan
[Qemu-devel] Re: [PATCH 01/11] .gitignore: ignore vi swap files and ctags files
Hi, What about these patches? -- With best wishes Dmitry
Re: [Qemu-devel] [PING 0.14] Missing patches (mostly fixes)
Am 04.02.2011 16:27, schrieb Markus Armbruster: Anthony Liguori writes: On 02/02/2011 01:28 PM, Stefan Weil wrote: [...] [PATCH 1/3] tests: Fix two memory leaks (http://patchwork.ozlabs.org/patch/79945/) [PATCH 2/3] check-qdict: Fix possible crash (http://patchwork.ozlabs.org/patch/79946/) Luiz I wouldn't bother with the second one for 0.14. Yes, we're reading lines from a file with %s, but it's a fixed file with known contents, no long lines, and we're reading it in a test program only developers ever use. As to the first one, Luiz has never touched that file. Neither have I, and it's not obvious to me why it should go into 0.14. [...] Even if the current code does not result in a real bug at the moment, it should get fixed: * Using tools like cppcheck (or others) to find bugs is good, because it finds bugs which are important. Sorting out "unimportant" bugs from the results wastes time which could be invested better, and this waste of time lasts forever until the "unimportant" bug will be fixed. The sooner you fix it, the better it is. * Code gets copied, and maybe the copy of code with some weakness can expose a real problem. Therefore I think that both patches should be applied at least to qemu master (as they are really simple patches, applying them to 0.14 would be cheap and good as well). Regards, Stefan Weil