Re: [Qemu-devel] [PATCH 2/2] curses: add option to specify VGA font encoding

2019-03-04 Thread Eddie Kohler
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.

2019-02-28 Thread Eddie Kohler
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.

2010-09-29 Thread Eddie Kohler
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?

2010-09-28 Thread Eddie Kohler

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

2010-09-26 Thread Eddie Kohler

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

2010-09-25 Thread Eddie Kohler
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

2010-09-24 Thread Eddie Kohler
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

2008-03-06 Thread Eddie Kohler

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

2008-02-10 Thread Eddie Kohler

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

2008-02-05 Thread Eddie Kohler

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

2008-02-03 Thread Eddie Kohler

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

2008-01-16 Thread Eddie Kohler

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

2008-01-16 Thread Eddie Kohler

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

2008-01-15 Thread Eddie Kohler

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

2008-01-13 Thread Eddie Kohler

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;
 }