Re: [Qemu-devel] [PATCH 2/2] curses: add option to specify VGA font encoding
Another difference is that Samuel's patch supports platforms on which wchar_t is not Unicode. I don't know if there are many/any such platforms but it does support them! On Mon, Mar 4, 2019 at 3:14 AM Samuel Thibault wrote: > Gerd Hoffmann, le lun. 04 mars 2019 09:03:38 +0100, a ecrit: > > On Sun, Mar 03, 2019 at 11:44:30AM +0100, Samuel Thibault wrote: > > > This uses iconv to convert glyphs from the specified VGA font encoding > to > > > unicode, and makes use of cchar_t instead of chtype when using > ncursesw, > > > which allows to store all wide char as well as the WACS values. > > > > > > Signed-off-by: Samuel Thibault > > > Cc: Eddie Kohler > > > > So the difference to the patch from Eddie is that charset > > is configurable instead of being hard-coded to CP437? > > Yes. > > Samuel >
[Qemu-devel] [PATCH] Use wide-character ncurses functions.
Hi, QEMU is unable to display all VGA characters to console output; for instance, the smiley (VGA character 0x01) is printed just as \001. However, QEMU links with the wide-character ncurses library, which can output all VGA characters (since they have Unicode equivalents). The attached patch switches QEMU to use wide-character functions, using the VGA character Unicode equivalents from Wikipedia. It works for me, and I'm hoping something like it would be acceptable for QEMU. Thanks for any comments, Eddie Kohler *** All VGA console characters have Unicode equivalents, and most modern terminals can display them. Signed-off-by: Eddie Kohler --- ui/curses.c | 143 +--- 1 file changed, 92 insertions(+), 51 deletions(-) diff --git a/ui/curses.c b/ui/curses.c index 6e0091c3b2..a07528770f 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -27,6 +27,7 @@ #include #include #endif +#include #include "qapi/error.h" #include "qemu-common.h" @@ -48,25 +49,106 @@ static WINDOW *screenpad = NULL; static int width, height, gwidth, gheight, invalidate; static int px, py, sminx, sminy, smaxx, smaxy; -static chtype vga_to_curses[256]; +static const wchar_t vga_to_wchar[256] = { +// 0x0_ +L' ', L'\u263A', L'\u263B', L'\u2665', +L'\u2666', L'\u2663', L'\u2660', L'\u2022', +L'\u25D8', L'\u25CB', L'\u25D9', L'\u2642', +L'\u2640', L'\u266A', L'\u266B', L'\u263C', + +// 0x1_ +L'\u25BA', L'\u25C4', L'\u2195', L'\u203C', +L'\u00B6', L'\u00A7', L'\u25AC', L'\u21A8', +L'\u2191', L'\u2193', L'\u2192', L'\u2190', +L'\u221F', L'\u2194', L'\u25B2', L'\u25BC', + +// 0x2_ +L' ', L'!', L'"', L'#', L'$', L'%', L'&', L'\'', +L'(', L')', L'*', L'+', L',', L'-', L'.', L'/', + +// 0x3_ +L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', +L'8', L'9', L':', L';', L'<', L'=', L'>', L'?', + +// 0x4_ +L'@', L'A', L'B', L'C', L'D', L'E', L'F', L'G', +L'H', L'I', L'J', L'K', L'L', L'M', L'N', L'O', + +// 0x5_ +L'P', L'Q', L'R', L'S', L'T', L'U', L'V', L'W', +L'X', L'Y', L'Z', L'[', L'\\', L']', L'^', L'_', + +// 0x6_ +L'`', L'a', L'b', L'c', L'd', L'e', L'f', L'g', +L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o', + +// 0x7_ +L'p', L'q', L'r', L's', L't', L'u', L'v', L'w', +L'x', L'y', L'z', L'{', L'|', L'}', L'~', L'\u2302', + +// 0x8_ +L'\u00C7', L'\u00FC', L'\u00E9', L'\u00E2', +L'\u00E4', L'\u00E0', L'\u00E5', L'\u00E7', +L'\u00EA', L'\u00EB', L'\u00E8', L'\u00EF', +L'\u00EE', L'\u00EC', L'\u00C4', L'\u00C5', + +// 0x9_ +L'\u00C9', L'\u00E6', L'\u00C6', L'\u00F4', +L'\u00F6', L'\u00F2', L'\u00FB', L'\u00F9', +L'\u00FF', L'\u00D6', L'\u00DC', L'\u00A2', +L'\u00A3', L'\u00A5', L'\u20A7', L'\u0192', + +// 0xA_ +L'\u00E1', L'\u00ED', L'\u00F3', L'\u00FA', +L'\u00F1', L'\u00D1', L'\u00AA', L'\u00BA', +L'\u00BF', L'\u2310', L'\u00AC', L'\u00BD', +L'\u00BC', L'\u00A1', L'\u00AB', L'\u00BB', + +// 0xB_ +L'\u2591', L'\u2592', L'\u2593', L'\u2502', +L'\u2524', L'\u2561', L'\u2562', L'\u2556', +L'\u2555', L'\u2563', L'\u2551', L'\u2557', +L'\u255D', L'\u255C', L'\u255B', L'\u2510', + +// 0xC_ +L'\u2514', L'\u2534', L'\u252C', L'\u251C', +L'\u2500', L'\u253C', L'\u255E', L'\u255F', +L'\u255A', L'\u2554', L'\u2569', L'\u2566', +L'\u2560', L'\u2550', L'\u256C', L'\u2567', + +// 0xD_ +L'\u2568', L'\u2564', L'\u2565', L'\u2559', +L'\u2558', L'\u2552', L'\u2553', L'\u256B', +L'\u256A', L'\u2518', L'\u250C', L'\u2588', +L'\u2584', L'\u258C', L'\u2590', L'\u2580', + +// 0xE_ +L'\u03B1', L'\u00DF', L'\u0393', L'\u03C0', +L'\u03A3', L'\u03C3', L'\u00B5', L'\u03C4', +L'\u03A6', L'\u0398', L'\u03A9', L'\u03B4', +L'\u221E', L'\u03C6', L'\u03B5', L'\u2229', + +// 0xF_ +L'\u2261', L'\u00B1', L'\u2265', L'\u2264', +L'\u2320', L'\u2321', L'\u00F7', L'\u2248', +L'\u00B0', L'\u2219', L'\u00B7', L'\u221A', +L'\u207F', L'\u00B2', L'\u25A0', L'\u00A0' +}; static void curses_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { console_ch_t *line; -chtype curses_line[width]; +cchar_t curses_line[width]; line = screen + y * width; for (h += y; y < h; y ++, line += width) { for (x = 0; x < width; x++) { -chtype ch = line[x] & 0xff; -chtype at = line[x] & ~0xff; -if (vga_to_curses[ch]) { -ch = vga_to_curses[ch]; -} -curses_line[x] = ch | at; +curses_line[x].attr = line[x] & ~0xff; +curses_line[x].chars[0] = vga_to_wchar[line[x] & 0xff]; +curses_line[x].chars[1] = L'\0'; } -mvwaddchnstr(screenpad, y, 0, curses_line, width); +mvwadd_wchnstr(screenpad, y, 0, curses_line, width); }
[Qemu-devel] [PATCH] Reverse VNC connections: Avoid segmentation fault.
Hi -vnc HOST:PORT,reverse connections are currently broken, because vnc_refresh_server_surface is called before the guest is actually available. The following patch fixes reverse connections. Eddie From 32fe1bc61ee9f2f1a8220642a48acb05b5be7322 Mon Sep 17 00:00:00 2001 From: Eddie Kohler ekoh...@gmail.com Date: Wed, 29 Sep 2010 12:00:55 -0700 Subject: [PATCH] Reverse VNC connections: Avoid segmentation fault. --- ui/vnc.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/ui/vnc.c b/ui/vnc.c index c7a1831..8c3af8a 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2261,6 +2261,10 @@ static int vnc_refresh_server_surface(VncDisplay *vd) VncState *vs; int has_dirty = 0; +/* On reverse connections, the guest might not be connected yet. */ +if (!vd-guest.ds) + return 0; + /* * Walk through the guest dirty map. * Check and copy modified bits from guest to server surface. -- 1.7.0.4
[Qemu-devel] loadvm for read-only snapshot files?
Hi, I would like to make QEMU snapshots work with read-only image files of some kind (QCOW2 or whatever else). In other words, I would like to use -loadvm with a read-only hard disk image. Several years ago I sent in a patch that allowed the use of -loadvm with read-only QCOW2 files: http://www.mail-archive.com/qemu-devel@nongnu.org/msg15774.html 1. Would such a patch have a chance if submitted today? 2. Is there a better or different way to do this? Eddie
Re: [Qemu-devel] Re: [PATCH] i386 debugging stubs: Consider segment bases
OK, thanks. I understand how you're relying on the current behavior. I'd rather not change all of QEMU and GDB in one step, but I'd like to address this. QEMU documentation implies, and new users expect, that debugging uses virtual addresses, not the segmentation-specific linear addresses that are actually used now. - How about a maintenance packet type that changed behavior to what I would prefer (breakpoints and memory access use virtual addresses, not linear addresses)? - We could add a segment identifier parameter to cpu_get_phys_page_debug, ignored on all targets but i386 at first. Then we could pass information through to cpu_get_phys_page_debug about what kind of address is being translated. This change could be propagated to cpu_memory_rw_debug (now or later). Would you object? Eddie
Re: [Qemu-devel] Re: [PATCH] i386 debugging stubs: Consider segment bases
Thanks for the response. I agree the patch is a workaround, but it is a useful workaround, and I'd still argue for including it. The patch doesn't *require* that CS.base == DS.base. Breakpoints correctly and exclusively use CS.base. However, any memory examination uses DS.base, and you're right that the user might want to examine some other segment. A GDB fix would involve changing the gdb remote protocol as well as GDB itself and the GDB user interface. Google says you've been thinking about that for a while now -- is it going well? For the time being, you should be able to workaround the gdb limitation by setting two breakpoints: one on the linear address and another one on the CS offset. Not nice, but used to work for us. I don't mind the double-breakpoint as much, but memory examination would still be broken, yes? I don't understand the comment about prevents setting breakpoints on inactive segments. The code for setting breakpoints has not changed. Do you think the patch would actually make debugging WORSE on any OS? Or have any other undesirable effects, or make it harder to DTRT when GDB is ready? It seems safe useful to me; it's 2 LOC! Eddie
[Qemu-devel] [PATCH] i386 debugging stubs: Consider segment bases
Hi, QEMU has a bug that complicates GDB debugging of i386 targets when the current code or data segment has a nonzero base. A fix is attached. If the current code segment has a nonzero base, breakpoints don't work as expected, because the breakpoint detector does not consider segment bases. If the current data segment has a nonzero base, memory inspection doesn't work, because cpu_get_phys_page_debug does not consider segment bases. A tiny 'operating system' demonstrating the problem is here: http://read.cs.ucla.edu/~kohler/qemu-gdbseg-demo.tgz The README enclosed in that tarball gives steps on how to replicate the breakpoint problem. The 'kernel' runs with segment base 0x1000, so that linear address 0xF0001000 is translated into physical address 0x1000. But breakpoints (which should use virtual addresses) at a linear address (e.g. 0xF010) are ignored. You can stop execution using a physical address, but all the addresses reported back to GDB are linear addresses, so this isn't consistent. This is a real problem that prevents us from using unpatched QEMU in classwork. Any comments on the fix?? (A version was initially posted several years ago.) Thanks, Eddie Kohler From 6784824c7576514456a989192e07e63352bdb4ae Mon Sep 17 00:00:00 2001 From: Eddie Kohler ekoh...@gmail.com Date: Fri, 24 Sep 2010 16:42:27 -0700 Subject: [PATCH] i386 debugging stubs: Consider segment bases - Access dumpable memory relative to the current data segment base. - Detect breakpoints relative to the current code segment base. --- target-i386/helper.c|1 + target-i386/translate.c |2 +- 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index e134340..0bfd4a9 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -831,6 +831,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) target_phys_addr_t paddr; uint32_t page_offset; int page_size; +addr += env-segs[R_DS].base; if (env-cr[4] CR4_PAE_MASK) { target_ulong pdpe_addr; diff --git a/target-i386/translate.c b/target-i386/translate.c index 7b6e3c2..d9e5b79 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -7816,7 +7816,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, for(;;) { if (unlikely(!QTAILQ_EMPTY(env-breakpoints))) { QTAILQ_FOREACH(bp, env-breakpoints, entry) { -if (bp-pc == pc_ptr +if (bp-pc == pc_ptr - dc-cs_base !((bp-flags BP_CPU) (tb-flags HF_RF_MASK))) { gen_debug(dc, pc_ptr - dc-cs_base); break; -- 1.7.0.4
[Qemu-devel] PATCH: allow i386 debugging when segment offset != 0
Hi all, This patch makes QEMU's gdb debugging stub and CPU breakpoints work when the segment offset is not 0. Previously, the debugging stub assumed the segment offset was 0, leading to very odd behavior. This patch assumes that the code segment and data segment have the same offset. This is a reasonable assumption. Making the code work for different code and data offsets would be more invasive. Please accept this patch (this is a resend.) Eddie Kohler Index: target-i386/helper2.c === RCS file: /sources/qemu/qemu/target-i386/helper2.c,v retrieving revision 1.62 diff -u -r1.62 helper2.c --- target-i386/helper2.c 24 Dec 2007 14:04:06 - 1.62 +++ target-i386/helper2.c 6 Mar 2008 22:46:46 - @@ -1081,6 +1081,7 @@ { uint32_t pde_addr, pte_addr; uint32_t pde, pte, paddr, page_offset, page_size; +addr += env-segs[R_DS].base; if (env-cr[4] CR4_PAE_MASK) { uint32_t pdpe_addr, pde_addr, pte_addr; Index: target-i386/translate.c === RCS file: /sources/qemu/qemu/target-i386/translate.c,v retrieving revision 1.79 diff -u -r1.79 translate.c --- target-i386/translate.c 24 Feb 2008 07:45:42 - 1.79 +++ target-i386/translate.c 6 Mar 2008 22:46:46 - @@ -6740,7 +6740,7 @@ for(;;) { if (env-nb_breakpoints 0) { for(j = 0; j env-nb_breakpoints; j++) { -if (env-breakpoints[j] == pc_ptr) { +if (env-breakpoints[j] == pc_ptr - dc-cs_base) { gen_debug(dc, pc_ptr - dc-cs_base); break; }
Re: [Qemu-devel] [PATCH] loadvm for read-only snapshot files
andrzej zaborowski wrote: On 03/02/2008, Eddie Kohler [EMAIL PROTECTED] wrote: The following patch, against cvs, supports read-only snapshots on read-only qcow2 image files. Snapshots can be loaded, but not saved. This is really useful in my context, which is operating systems projects; a read-only memory snapshot allows students to share a snapshot that skips the boot process, allowing them to run their code right away. Please let me know if anything needs changing. Instead of including block_int.h in vl.c you should use the provided functions from block.h (bs-drv can be checked with _is_inserted). Thanks for the comment. The attached patch introduces a new block.h function, bdev_is_snapshot_capable. Better? Eddie Index: block-qcow2.c === RCS file: /sources/qemu/qemu/block-qcow2.c,v retrieving revision 1.10 diff -u -u -r1.10 block-qcow2.c --- block-qcow2.c 11 Nov 2007 02:51:16 - 1.10 +++ block-qcow2.c 10 Feb 2008 23:54:34 - @@ -429,7 +429,6 @@ BDRVQcowState *s = bs-opaque; int new_l1_size, new_l1_size2, ret, i; uint64_t *new_l1_table; -uint64_t new_l1_table_offset; uint64_t data64; uint32_t data32; @@ -450,28 +449,32 @@ memcpy(new_l1_table, s-l1_table, s-l1_size * sizeof(uint64_t)); /* write new table (align to cluster) */ -new_l1_table_offset = alloc_clusters(bs, new_l1_size2); +if (!bs-read_only) { + uint64_t new_l1_table_offset = alloc_clusters(bs, new_l1_size2); -for(i = 0; i s-l1_size; i++) -new_l1_table[i] = cpu_to_be64(new_l1_table[i]); -ret = bdrv_pwrite(s-hd, new_l1_table_offset, new_l1_table, new_l1_size2); -if (ret != new_l1_size2) -goto fail; -for(i = 0; i s-l1_size; i++) -new_l1_table[i] = be64_to_cpu(new_l1_table[i]); - -/* set new table */ -data64 = cpu_to_be64(new_l1_table_offset); -if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_table_offset), -data64, sizeof(data64)) != sizeof(data64)) -goto fail; -data32 = cpu_to_be32(new_l1_size); -if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_size), -data32, sizeof(data32)) != sizeof(data32)) -goto fail; + for(i = 0; i s-l1_size; i++) + new_l1_table[i] = cpu_to_be64(new_l1_table[i]); + ret = bdrv_pwrite(s-hd, new_l1_table_offset, new_l1_table, new_l1_size2); + if (ret != new_l1_size2) + goto fail; + for(i = 0; i s-l1_size; i++) + new_l1_table[i] = be64_to_cpu(new_l1_table[i]); + + /* set new table */ + data64 = cpu_to_be64(new_l1_table_offset); + if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_table_offset), + data64, sizeof(data64)) != sizeof(data64)) + goto fail; + data32 = cpu_to_be32(new_l1_size); + if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_size), + data32, sizeof(data32)) != sizeof(data32)) + goto fail; + free_clusters(bs, s-l1_table_offset, s-l1_size * sizeof(uint64_t)); + + s-l1_table_offset = new_l1_table_offset; +} + qemu_free(s-l1_table); -free_clusters(bs, s-l1_table_offset, s-l1_size * sizeof(uint64_t)); -s-l1_table_offset = new_l1_table_offset; s-l1_table = new_l1_table; s-l1_size = new_l1_size; return 0; @@ -521,7 +524,8 @@ /* update the L1 entry */ s-l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED; tmp = cpu_to_be64(l2_offset | QCOW_OFLAG_COPIED); -if (bdrv_pwrite(s-hd, s-l1_table_offset + l1_index * sizeof(tmp), +if (!bs-read_only + bdrv_pwrite(s-hd, s-l1_table_offset + l1_index * sizeof(tmp), tmp, sizeof(tmp)) != sizeof(tmp)) return 0; min_index = l2_cache_new_entry(bs); @@ -535,7 +539,8 @@ s-l2_size * sizeof(uint64_t)) return 0; } -if (bdrv_pwrite(s-hd, l2_offset, +if (!bs-read_only + bdrv_pwrite(s-hd, l2_offset, l2_table, s-l2_size * sizeof(uint64_t)) != s-l2_size * sizeof(uint64_t)) return 0; @@ -624,7 +629,8 @@ } /* update L2 table */ l2_table[l2_index] = tmp; -if (bdrv_pwrite(s-hd, +if (!bs-read_only + bdrv_pwrite(s-hd, l2_offset + l2_index * sizeof(tmp), tmp, sizeof(tmp)) != sizeof(tmp)) return 0; return cluster_offset; @@ -1322,7 +1328,7 @@ } } } -if (l2_modified) { +if (l2_modified !bs-read_only) { if (bdrv_pwrite(s-hd, l2_offset, l2_table, l2_size) != l2_size) goto fail; @@ -1342,7 +1348,7 @@ } } } -if (l1_modified) { +if (l1_modified !bs-read_only) { for(i = 0; i l1_size; i++) cpu_to_be64s(l1_table[i]); if (bdrv_pwrite(s-hd, l1_table_offset, l1_table, @@ -1553,6 +1559,9 @@ int i, ret; uint64_t *l1_table = NULL
Re: [Qemu-devel] Making qemu use 10.0.3.x not 10.0.2.x
Warner Losh wrote: From: Andreas Färber [EMAIL PROTECTED] Subject: Re: [Qemu-devel] Making qemu use 10.0.3.x not 10.0.2.x Date: Tue, 5 Feb 2008 13:58:28 +0100 Am 05.02.2008 um 12:30 schrieb Ian Jackson: I don't believe that 10.0.2.0/24 was chosen randomly :-). It would be better for qemu's default range to be a randomly chosen one. Please don't randomly choose a default subnet; knowing that QEMU uses 10.0.2.x allows to adapt to this. If however QEMU starts randomly assigning addresses we will also get random conflicts. Please stick with a default like the current and simply make it statically configurable. I think that the suggestion is that qemu picks, one time, a new default. This new default would be selected at random, and would be the same on all new versions of qemu. I don't think that the suggestion is to pick a random address every time qemu starts. I already have some scripts that depend on the 10.0.2.x default -- probably others do too. Would changing to a different subnet by default really make that much difference? 10.0.2.x is, after all, a possible random choice :) Eddie
[Qemu-devel] [PATCH] loadvm for read-only snapshot files
Hi all, The following patch, against cvs, supports read-only snapshots on read-only qcow2 image files. Snapshots can be loaded, but not saved. This is really useful in my context, which is operating systems projects; a read-only memory snapshot allows students to share a snapshot that skips the boot process, allowing them to run their code right away. Please let me know if anything needs changing. Eddie Kohler Index: block-qcow2.c === RCS file: /sources/qemu/qemu/block-qcow2.c,v retrieving revision 1.10 diff -u -u -r1.10 block-qcow2.c --- block-qcow2.c 11 Nov 2007 02:51:16 - 1.10 +++ block-qcow2.c 3 Feb 2008 18:10:07 - @@ -429,7 +429,6 @@ BDRVQcowState *s = bs-opaque; int new_l1_size, new_l1_size2, ret, i; uint64_t *new_l1_table; -uint64_t new_l1_table_offset; uint64_t data64; uint32_t data32; @@ -450,28 +449,32 @@ memcpy(new_l1_table, s-l1_table, s-l1_size * sizeof(uint64_t)); /* write new table (align to cluster) */ -new_l1_table_offset = alloc_clusters(bs, new_l1_size2); +if (!bs-read_only) { + uint64_t new_l1_table_offset = alloc_clusters(bs, new_l1_size2); -for(i = 0; i s-l1_size; i++) -new_l1_table[i] = cpu_to_be64(new_l1_table[i]); -ret = bdrv_pwrite(s-hd, new_l1_table_offset, new_l1_table, new_l1_size2); -if (ret != new_l1_size2) -goto fail; -for(i = 0; i s-l1_size; i++) -new_l1_table[i] = be64_to_cpu(new_l1_table[i]); - -/* set new table */ -data64 = cpu_to_be64(new_l1_table_offset); -if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_table_offset), -data64, sizeof(data64)) != sizeof(data64)) -goto fail; -data32 = cpu_to_be32(new_l1_size); -if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_size), -data32, sizeof(data32)) != sizeof(data32)) -goto fail; + for(i = 0; i s-l1_size; i++) + new_l1_table[i] = cpu_to_be64(new_l1_table[i]); + ret = bdrv_pwrite(s-hd, new_l1_table_offset, new_l1_table, new_l1_size2); + if (ret != new_l1_size2) + goto fail; + for(i = 0; i s-l1_size; i++) + new_l1_table[i] = be64_to_cpu(new_l1_table[i]); + + /* set new table */ + data64 = cpu_to_be64(new_l1_table_offset); + if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_table_offset), + data64, sizeof(data64)) != sizeof(data64)) + goto fail; + data32 = cpu_to_be32(new_l1_size); + if (bdrv_pwrite(s-hd, offsetof(QCowHeader, l1_size), + data32, sizeof(data32)) != sizeof(data32)) + goto fail; + free_clusters(bs, s-l1_table_offset, s-l1_size * sizeof(uint64_t)); + + s-l1_table_offset = new_l1_table_offset; +} + qemu_free(s-l1_table); -free_clusters(bs, s-l1_table_offset, s-l1_size * sizeof(uint64_t)); -s-l1_table_offset = new_l1_table_offset; s-l1_table = new_l1_table; s-l1_size = new_l1_size; return 0; @@ -521,7 +524,8 @@ /* update the L1 entry */ s-l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED; tmp = cpu_to_be64(l2_offset | QCOW_OFLAG_COPIED); -if (bdrv_pwrite(s-hd, s-l1_table_offset + l1_index * sizeof(tmp), +if (!bs-read_only + bdrv_pwrite(s-hd, s-l1_table_offset + l1_index * sizeof(tmp), tmp, sizeof(tmp)) != sizeof(tmp)) return 0; min_index = l2_cache_new_entry(bs); @@ -535,7 +539,8 @@ s-l2_size * sizeof(uint64_t)) return 0; } -if (bdrv_pwrite(s-hd, l2_offset, +if (!bs-read_only + bdrv_pwrite(s-hd, l2_offset, l2_table, s-l2_size * sizeof(uint64_t)) != s-l2_size * sizeof(uint64_t)) return 0; @@ -624,7 +629,8 @@ } /* update L2 table */ l2_table[l2_index] = tmp; -if (bdrv_pwrite(s-hd, +if (!bs-read_only + bdrv_pwrite(s-hd, l2_offset + l2_index * sizeof(tmp), tmp, sizeof(tmp)) != sizeof(tmp)) return 0; return cluster_offset; @@ -1322,7 +1328,7 @@ } } } -if (l2_modified) { +if (l2_modified !bs-read_only) { if (bdrv_pwrite(s-hd, l2_offset, l2_table, l2_size) != l2_size) goto fail; @@ -1342,7 +1348,7 @@ } } } -if (l1_modified) { +if (l1_modified !bs-read_only) { for(i = 0; i l1_size; i++) cpu_to_be64s(l1_table[i]); if (bdrv_pwrite(s-hd, l1_table_offset, l1_table, @@ -1553,6 +1559,9 @@ int i, ret; uint64_t *l1_table = NULL; +if (bs-read_only) + return -EACCES; + memset(sn, 0, sizeof(*sn)); if (sn_info-id_str[0] == '\0') { @@ -1628,7 +1637,8 @@ return -ENOENT; sn = s-snapshots[snapshot_index]; -if (update_snapshot_refcount(bs, s-l1_table_offset, s-l1_size, -1) 0) +if (!bs-read_only
Re: [Qemu-devel] [PATCH] add VNC reverse connections
Daniel P. Berrange wrote: We already have the ability to pass multiple flags / options to the VNC driver as a post-fix to the host:port pair, so I'm not a fan of introducing a new option as a prefix. If using existing options syntax, it could look like: -vnc :5500,rev -vnc read.cs.ucla.edu:5500,rev This doesn't feel like an option to me, though; rather a different means of connecting. Among other things, in -vnc :0, the QEMU VNC server opens port 5900. But the client's listening port for reverse connections defaults to 5500. -vnc :-400,rev is clearly insane, but it seems strange for an option like ,rev to change the meaning of the port field. If you still disagree I'll produce a patch with ,reverse as an option. Eddie
Re: [Qemu-devel] [PATCH] add VNC reverse connections
Anthony Liguori wrote: This doesn't feel like an option to me, though; rather a different means of connecting. Among other things, in -vnc :0, the QEMU VNC server opens port 5900. But the client's listening port for reverse connections defaults to 5500. -vnc :-400,rev is clearly insane, but it seems strange for an option like ,rev to change the meaning of the port field. Yes that is a valid point. It is a little unfortunate we switched to using display num instead of port num for the current VNC code. Having a syntax which makes people use negative display nums for reverse connections would suck. So reluctantly I think your original proposal may actually be better. Yet this is the syntax we use for normal connections. I don't see why the asymmetry is okay for reverse connections. Because reverse connections feel very different from normal connections, use ports instead of display numbers, etc.? Here's what the manual would look like for the rev: syntax. interface:d TCP connections will only be allowed from interface on display d. By convention the TCP port is 5900+d. Optionally, interface can be omitted in which case the server will bind to all interfaces. ... rev:[address:]port Connects to a VNC client listening at address:port. Optionally, address can be omitted in which case the server connects to localhost:port. Here's what the manual would look like for the ,reverse syntax. Valid syntax for the display is interface:d TCP connections will only be allowed from interface on display d. By convention the TCP port is 5900+d. Optionally, interface can be omitted in which case the server will bind to all interfaces. ... reverse QEMU will connect to a listening VNC client, rather than waiting for a client connection. If the connection has type interface:d, then interface is the client address; if omitted, localhost is used. The display number d is added to 5900 to determine the port, so negative numbers might be necessary to connect to default client ports. Or are you thinking For reverse connections, the display number d is added to 5500 to determine the port. in which case the interface:d definition is incorrect? I'm not trying to make this look ugly on purpose. The prefix syntax seems friendlier. Eddie
[Qemu-devel] [PATCH] add VNC reverse connections
Hi all, This patch against current CVS adds VNC reverse connections, where the server connects actively to a waiting client, as in -vnc rev:5500 or -vnc rev:read.cs.ucla.edu:5500. This is quite useful if the user expects to run QEMU many times in succession (for example, is debugging a toy OS), and doesn't want to reopen a VNC client each time. Eddie Index: qemu-doc.texi === RCS file: /sources/qemu/qemu/qemu-doc.texi,v retrieving revision 1.179 diff -u -r1.179 qemu-doc.texi --- qemu-doc.texi 14 Jan 2008 22:09:11 - 1.179 +++ qemu-doc.texi 16 Jan 2008 07:25:30 - @@ -429,10 +429,16 @@ Connections will be allowed over UNIX domain sockets where @var{path} is the location of a unix socket to listen for connections on. [EMAIL PROTECTED] @var{rev}:@var{interface}:@var{port} + +Makes a reverse connection to a VNC viewer listening on [EMAIL PROTECTED] on port @var{port}. Optionally, @var{interface} can be +omitted in which case QEMU will connect to @var{port} on the local machine. + @item none -VNC is initialized by not started. The monitor @code{change} command can be used -to later start the VNC server. +VNC is initialized but not started. The monitor @code{change} command +can be used to later start the VNC server. @end table Index: vnc.c === RCS file: /sources/qemu/qemu/vnc.c,v retrieving revision 1.33 diff -u -r1.33 vnc.c --- vnc.c 14 Jan 2008 21:45:55 - 1.33 +++ vnc.c 16 Jan 2008 07:25:30 - @@ -1898,6 +1898,22 @@ return 0; } +static void vnc_connect(VncState *vs) +{ +VNC_DEBUG(New client on socket %d\n, vs-csock); +socket_set_nonblock(vs-csock); +qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, vs); +vnc_write(vs, RFB 003.008\n, 12); +vnc_flush(vs); +vnc_read_when(vs, protocol_version, 12); +memset(vs-old_data, 0, vs-ds-linesize * vs-ds-height); +memset(vs-dirty_row, 0xFF, sizeof(vs-dirty_row)); +vs-has_resize = 0; +vs-has_hextile = 0; +vs-ds-dpy_copy = NULL; +vnc_update_client(vs); +} + static void vnc_listen_read(void *opaque) { VncState *vs = opaque; @@ -1909,18 +1925,7 @@ vs-csock = accept(vs-lsock, (struct sockaddr *)addr, addrlen); if (vs-csock != -1) { - VNC_DEBUG(New client on socket %d\n, vs-csock); -socket_set_nonblock(vs-csock); - qemu_set_fd_handler2(vs-csock, NULL, vnc_client_read, NULL, opaque); - vnc_write(vs, RFB 003.008\n, 12); - vnc_flush(vs); - vnc_read_when(vs, protocol_version, 12); - memset(vs-old_data, 0, vs-ds-linesize * vs-ds-height); - memset(vs-dirty_row, 0xFF, sizeof(vs-dirty_row)); - vs-has_resize = 0; - vs-has_hextile = 0; - vs-ds-dpy_copy = NULL; -vnc_update_client(vs); + vnc_connect(vs); } } @@ -2087,6 +2092,7 @@ VncState *vs = ds ? (VncState *)ds-opaque : vnc_state; const char *options; int password = 0; +int reverse = 0; #if CONFIG_VNC_TLS int tls = 0, x509 = 0; #endif @@ -2179,6 +2185,13 @@ } #endif } +if (strstart(display, rev:, p)) { + reverse = 1; + display = p; + if (!strchr(display, ':')) { + display = p - 1; + } +} #ifndef _WIN32 if (strstart(display, unix:, p)) { addr = (struct sockaddr *)uaddr; @@ -2196,7 +2209,9 @@ memset(uaddr.sun_path, 0, 108); snprintf(uaddr.sun_path, 108, %s, p); - unlink(uaddr.sun_path); + if (!reverse) { + unlink(uaddr.sun_path); + } } else #endif { @@ -2210,7 +2225,7 @@ return -1; } - iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900); + iaddr.sin_port = htons(ntohs(iaddr.sin_port) + (reverse ? 0 : 5900)); vs-lsock = socket(PF_INET, SOCK_STREAM, 0); if (vs-lsock == -1) { @@ -2233,6 +2248,22 @@ } } +if (reverse) { + if (connect(vs-lsock, addr, addrlen) == -1) { + fprintf(stderr, Connection to VNC client failed\n); + close(vs-lsock); + vs-lsock = -1; + free(vs-display); + vs-display = NULL; + return -1; + } else { + vs-csock = vs-lsock; + vs-lsock = -1; + vnc_connect(vs); + return 0; + } +} + if (bind(vs-lsock, addr, addrlen) == -1) { fprintf(stderr, bind() failed\n); close(vs-lsock);
[Qemu-devel] [Patch] x86 breakpoints and memory examination
Hi all, The following patch is useful for whole-system mode debugging and breakpoint setting on i386 QEMU. It seems like both breakpoints and memory examination used semi-physical addresses, in that neither took account of segment translation. This patch (relative to 0.9.1) adds segment translation. I'm not sure this is the right way to do it (in fact, I'm sure that the memory examination patch is the WRONG way to do it) and would appreciate pointers or advice. Thanks, Eddie Kohler diff -ru qemu-0.9.1/target-i386/helper2.c qemu-0.9.1-p/target-i386/helper2.c --- qemu-0.9.1/target-i386/helper2.c 2008-01-06 11:38:45.0 -0800 +++ qemu-0.9.1-p/target-i386/helper2.c 2008-01-12 23:56:34.0 -0800 @@ -1081,6 +1081,7 @@ { uint32_t pde_addr, pte_addr; uint32_t pde, pte, paddr, page_offset, page_size; +addr += env-segs[R_DS].base; if (env-cr[4] CR4_PAE_MASK) { uint32_t pdpe_addr, pde_addr, pte_addr; diff -ru qemu-0.9.1/target-i386/translate.c qemu-0.9.1-p/target-i386/translate.c --- qemu-0.9.1/target-i386/translate.c 2008-01-06 11:38:45.0 -0800 +++ qemu-0.9.1-p/target-i386/translate.c 2008-01-13 00:00:23.0 -0800 @@ -6758,7 +6758,7 @@ for(;;) { if (env-nb_breakpoints 0) { for(j = 0; j env-nb_breakpoints; j++) { -if (env-breakpoints[j] == pc_ptr) { +if (env-breakpoints[j] == pc_ptr - dc-cs_base) { gen_debug(dc, pc_ptr - dc-cs_base); break; }