Re: [Qemu-devel] [PATCH] linux-user: bigger default stack

2011-03-04 Thread Riku Voipio
On Thu, Mar 03, 2011 at 08:46:40AM -0800, Nathan Froyd wrote:
> On Thu, Mar 03, 2011 at 06:15:49PM +0200, Riku Voipio wrote:
> > QEMU linux-user calls glibc functions which, while usually very conservative
> > with memory usage, are not guaranteed not take less than 10KB (at do_syscall
> > we are already around 5 functions deep).
 
> Bleh.  OK, so it needs to be increased.  Could we get by with somewhat
> less (256K?), to try and maximize the number of threads we can
> potentially run?  Maybe it doesn't matter (people creating thousands of
> simultaneous threads inside QEMU have other problems...), but not
> gratuitously wasting memory would be good.

I believe 256K should be enough for everone now, then again we know 
what happened when someone suggested same about 640K.. In this case
however, if the limit is ever hit, increasing the limit again is easy.

Originally I did put the limit much higher, as I assume due to lazy
memory allocation from kernel it doesn't matter if we ask for 256K or
8M, as unused pages will never be allocated. But I'll do some testing with
lots of threads and see if stack size has an impact on how many threads
we can run.

Riku



Re: [Qemu-devel] [PATCH] vnc: tight: Fix crash after 2GB of output

2011-03-04 Thread Corentin Chary
>>
>>     bytes = zstream->total_out - previous_out;

Good catch

> total_out isn't used by zlib internally, so if the resulting
> "total" counter is not needed in qemu, we can just zero-out
> the total_out in this function before calling zlib, and
> use the resulting value directly as "bytes", without
> saving its previous value in previous_out.  Something like
> the attached patch does.

If you're certain that total_out is not used by zlib, could you also
send a patch for zlib encoding please ? (vnc-enc-zlib.c)
Thanks,

-- 
Corentin Chary
http://xf.iksaif.net



[Qemu-devel] Re: [PATCH] vnc: Fix stack corruption and other bitmap related bugs

2011-03-04 Thread Corentin Chary
On Thu, Mar 3, 2011 at 9:37 PM, Stefan Weil  wrote:
> Commit bc2429b9174ac2d3c56b7fd35884b0d89ec7fb02 introduced
> a severe bug (stack corruption).
>
> bitmap_clear was called with a wrong argument
> which caused out-of-bound writes to the local variable width_mask.
>
> This bug was detected with QEMU running on windows.
> It also occurs with wine:
>
> *** stack smashing detected ***:  terminated
> wine: Unhandled illegal instruction at address 0x6115c7 (thread 0009), 
> starting debugger...
>
> The bug is not windows specific!
>
> Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
> and width_mask were removed, and bitmap_intersect() was replaced by
> !bitmap_empty(). The new operation is much shorter and equivalent to
> the old operations.
>
> The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
> hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
> longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
> VNC_DIRTY_WORDS was too small.
>
> Fix both declarations by using the macro which is designed for this
> purpose.
>
> Cc: Corentin Chary 
> Cc: Wen Congyang 
> Cc: Gerhard Wiesinger 
> Cc: Anthony Liguori 
> Signed-off-by: Stefan Weil 
> ---
>  ui/vnc.c |    6 +-
>  ui/vnc.h |    9 ++---
>  2 files changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 610f884..34dc0cd 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -2383,7 +2383,6 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>     uint8_t *guest_row;
>     uint8_t *server_row;
>     int cmp_bytes;
> -    unsigned long width_mask[VNC_DIRTY_WORDS];
>     VncState *vs;
>     int has_dirty = 0;
>
> @@ -2399,14 +2398,11 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
>      * Check and copy modified bits from guest to server surface.
>      * Update server dirty map.
>      */
> -    bitmap_set(width_mask, 0, (ds_get_width(vd->ds) / 16));
> -    bitmap_clear(width_mask, (ds_get_width(vd->ds) / 16),
> -                 VNC_DIRTY_WORDS * BITS_PER_LONG);
>     cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
>     guest_row  = vd->guest.ds->data;
>     server_row = vd->server->data;
>     for (y = 0; y < vd->guest.ds->height; y++) {
> -        if (bitmap_intersects(vd->guest.dirty[y], width_mask, 
> VNC_DIRTY_WORDS)) {
> +        if (!bitmap_empty(vd->guest.dirty[y], VNC_DIRTY_BITS)) {
>             int x;
>             uint8_t *guest_ptr;
>             uint8_t *server_ptr;
> diff --git a/ui/vnc.h b/ui/vnc.h
> index 8a1e7b9..f10c5dc 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
>                                 void *last_fg,
>                                 int *has_bg, int *has_fg);
>
> +/* VNC_MAX_WIDTH must be a multiple of 16. */
>  #define VNC_MAX_WIDTH 2560
>  #define VNC_MAX_HEIGHT 2048
> -#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * BITS_PER_LONG))
> +
> +/* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */
> +#define VNC_DIRTY_BITS (VNC_MAX_WIDTH / 16)
>
>  #define VNC_STAT_RECT  64
>  #define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
> @@ -114,7 +117,7 @@ typedef struct VncRectStat VncRectStat;
>  struct VncSurface
>  {
>     struct timeval last_freq_check;
> -    unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
> +    DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16);
>     VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
>     DisplaySurface *ds;
>  };
> @@ -234,7 +237,7 @@ struct VncState
>     int csock;
>
>     DisplayState *ds;
> -    unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
> +    DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS);
>     uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
>                            * vnc-jobs-async.c */
>
> --
> 1.7.2.3
>
>

Hi,
Thanks, this patch is a lot cleaner that my early port to new
bitmap/bitops operations.
This patch fix all previous bugs, but not the
framebuffer_update_request + !incremental bug right ?

-- 
Corentin Chary
http://xf.iksaif.net



[Qemu-devel] [V7 PATCH 0/9] virtio-9p: Use chroot to safely access files in passthrough security model

2011-03-04 Thread M. Mohan Kumar
In passthrough security model, following symbolic links in the server
side could result in TOCTTOU vulnerabilities.

This patchset resolves this issue by creating a dedicated process which
chroots into the share path and all file object access is done in the
chroot environment.

This patchset implements chroot enviroment, provides necessary functions
that can be used by the passthrough function calls.

Changes from version V6:
* Send only fd/errno in socket operations instead of FdInfo structure
* Minor cleanups

Changes from version V5:
* Return errno on failure instead of setting errno
* Minor cleanups like updated comments, enable CONFIG_THREAD if
  CONFIG_VIRTFS is enabled

Changes from version V4:
* Avoid using malloc/free inside chroot process
* Seperate chroot server and client functions

Changes from version V3
* Return EIO incase of socket read/write fail instead of exiting
* Changed data types as suggested by Blue Swirl
* Chroot process reports error through qemu process

Changes from version V2
* Treat socket IO errors as fatal, ie qemu will exit
* Split patchset based on chroot side (server) and qemu side(client)
  functionalities


M. Mohan Kumar (9):
  Implement qemu_read_full
  virtio-9p: Enable CONFIG_THREAD if CONFIG_VIRTFS is enabled
  virtio-9p: Provide chroot worker side interfaces
  virtio-9p: Add qemu side interfaces for chroot environment
  virtio-9p: Add support to open a file in chroot environment
  virtio-9p: Create support in chroot environment
  virtio-9p: Support for creating special files
  virtio-9p: Move file post creation changes to none security model
  virtio-9p: Chroot environment for other functions

 Makefile.objs |1 +
 configure |1 +
 hw/9pfs/virtio-9p-chroot-worker.c |  271 +++
 hw/9pfs/virtio-9p-chroot.c|  127 +++
 hw/9pfs/virtio-9p-chroot.h|   45 
 hw/9pfs/virtio-9p-local.c |  433 ++---
 hw/9pfs/virtio-9p.c   |   25 +++
 hw/file-op-9p.h   |4 +
 osdep.c   |   32 +++
 qemu-common.h |2 +
 10 files changed, 861 insertions(+), 80 deletions(-)
 create mode 100644 hw/9pfs/virtio-9p-chroot-worker.c
 create mode 100644 hw/9pfs/virtio-9p-chroot.c
 create mode 100644 hw/9pfs/virtio-9p-chroot.h

-- 
1.7.3.4




[Qemu-devel] [V7 PATCH 2/9] virtio-9p: Enable CONFIG_THREAD if CONFIG_VIRTFS is enabled

2011-03-04 Thread M. Mohan Kumar
9p Chroot environment needs APIs defined in qemu-thread.c, so enable
CONFIG_THREAD if virtfs is enabled

Signed-off-by: M. Mohan Kumar 
---
 configure |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 2560357..9eddd38 100755
--- a/configure
+++ b/configure
@@ -2767,6 +2767,7 @@ fi
 if test "$linux" = "yes" ; then
   if test "$attr" = "yes" ; then
 echo "CONFIG_VIRTFS=y" >> $config_host_mak
+echo "CONFIG_THREAD=y" >> $config_host_mak
   fi
 fi
 if test "$blobs" = "yes" ; then
-- 
1.7.3.4




[Qemu-devel] [V7 PATCH 1/9] Implement qemu_read_full

2011-03-04 Thread M. Mohan Kumar
Add qemu_read_full function

Signed-off-by: M. Mohan Kumar 
---
 osdep.c   |   32 
 qemu-common.h |2 ++
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/osdep.c b/osdep.c
index 327583b..8d84a88 100644
--- a/osdep.c
+++ b/osdep.c
@@ -127,6 +127,38 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t 
count)
 }
 
 /*
+ * A variant of read(2) which handles interrupted read.
+ * Simlar to qemu_write_full function
+ *
+ * Return the number of bytes read.
+ *
+ * This function does not work with non-blocking fd's.
+ * errno is set if fewer than `count' bytes are read because of any
+ * error
+ */
+ssize_t qemu_read_full(int fd, void *buf, size_t count)
+{
+ssize_t ret = 0;
+ssize_t total = 0;
+
+while (count) {
+ret = read(fd, buf, count);
+if (ret <= 0) {
+if (errno == EINTR) {
+continue;
+}
+break;
+}
+
+count -= ret;
+buf += ret;
+total += ret;
+}
+
+return total;
+}
+
+/*
  * Opens a socket with FD_CLOEXEC set
  */
 int qemu_socket(int domain, int type, int protocol)
diff --git a/qemu-common.h b/qemu-common.h
index 40dad52..325b16a 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -207,6 +207,8 @@ void qemu_mutex_unlock_iothread(void);
 int qemu_open(const char *name, int flags, ...);
 ssize_t qemu_write_full(int fd, const void *buf, size_t count)
 QEMU_WARN_UNUSED_RESULT;
+ssize_t qemu_read_full(int fd, void *buf, size_t count)
+QEMU_WARN_UNUSED_RESULT;
 void qemu_set_cloexec(int fd);
 
 #ifndef _WIN32
-- 
1.7.3.4




[Qemu-devel] [V7 PATCH 3/9] virtio-9p: Provide chroot worker side interfaces

2011-03-04 Thread M. Mohan Kumar
Implement chroot worker side interfaces like sending the file
descriptor to qemu process, reading the object request from socket etc.
Also add chroot main function and other helper routines.

Signed-off-by: M. Mohan Kumar 
---
 Makefile.objs |1 +
 hw/9pfs/virtio-9p-chroot-worker.c |  183 +
 hw/9pfs/virtio-9p-chroot.h|   43 +
 hw/9pfs/virtio-9p.c   |   25 +
 hw/file-op-9p.h   |4 +
 5 files changed, 256 insertions(+), 0 deletions(-)
 create mode 100644 hw/9pfs/virtio-9p-chroot-worker.c
 create mode 100644 hw/9pfs/virtio-9p-chroot.h

diff --git a/Makefile.objs b/Makefile.objs
index 6a9f765..44891c1 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -283,6 +283,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
+9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-chroot-worker.o
 
 hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 $(addprefix 9pfs/, $(9pfs-nested-y)): CFLAGS +=  -I$(SRC_PATH)/hw/
diff --git a/hw/9pfs/virtio-9p-chroot-worker.c 
b/hw/9pfs/virtio-9p-chroot-worker.c
new file mode 100644
index 000..e7bc6c2
--- /dev/null
+++ b/hw/9pfs/virtio-9p-chroot-worker.c
@@ -0,0 +1,183 @@
+/*
+ * Virtio 9p chroot environment for contained access to the exported path
+ * Code path handles chroot worker side interfaces
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * M. Mohan Kumar 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the copying file in the top-level directory
+ *
+ */
+
+#include 
+#include 
+#include 
+#include "virtio.h"
+#include "qemu_socket.h"
+#include "qemu-thread.h"
+#include "qerror.h"
+#include "virtio-9p.h"
+#include "virtio-9p-chroot.h"
+
+/* Send file descriptor and error status to qemu process */
+static void chroot_sendfd(int sockfd, int fd, int fd_valid)
+{
+struct msghdr msg = { };
+struct iovec iov;
+struct cmsghdr *cmsg;
+int retval;
+union MsgControl msg_control;
+
+iov.iov_base = &fd;
+iov.iov_len = sizeof(fd);
+
+memset(&msg, 0, sizeof(msg));
+msg.msg_iov = &iov;
+msg.msg_iovlen = 1;
+/* No ancillary data on error */
+if (fd_valid) {
+msg.msg_control = &msg_control;
+msg.msg_controllen = sizeof(msg_control);
+
+cmsg = &msg_control.cmsg;
+cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+cmsg->cmsg_level = SOL_SOCKET;
+cmsg->cmsg_type = SCM_RIGHTS;
+memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+}
+do {
+retval = sendmsg(sockfd, &msg, 0);
+} while (retval < 0 && errno == EINTR);
+if (retval < 0) {
+_exit(1);
+}
+if (fd_valid) {
+close(fd);
+}
+}
+
+/* Read V9fsFileObjectRequest sent by QEMU process */
+static int chroot_read_request(int sockfd, V9fsFileObjectRequest *request)
+{
+int retval;
+retval = qemu_read_full(sockfd, request, sizeof(*request));
+if (retval != sizeof(*request)) {
+if (errno == EBADF) {
+_exit(1);
+}
+return -EIO;
+}
+return 0;
+}
+
+/*
+ * Helper routine to open a file
+ */
+static int chroot_do_open(V9fsFileObjectRequest *request)
+{
+int fd;
+fd = open(request->path.path, request->data.flags);
+if (fd < 0) {
+fd = -errno;
+}
+return fd;
+}
+
+static void chroot_daemonize(int chroot_sock)
+{
+sigset_t sigset;
+struct rlimit nr_fd;
+int fd;
+
+/* Block all signals for this process */
+sigfillset(&sigset);
+sigprocmask(SIG_SETMASK, &sigset, NULL);
+
+/* Close other file descriptors */
+getrlimit(RLIMIT_NOFILE, &nr_fd);
+for (fd = 0; fd < nr_fd.rlim_cur; fd++) {
+if (fd != chroot_sock) {
+close(fd);
+}
+}
+chdir("/");
+/* Create files with mode as per request */
+umask(0);
+}
+
+/*
+ * Fork a process and chroot into the share path. Communication
+ * between qemu process and chroot process happens via socket.
+ * All file descriptors (including stdout and stderr) are closed
+ * except one socket descriptor (which is used for communicating
+ * between qemu process and chroot process).
+ * Note: To avoid errors in forked process in multi threaded environment
+ * only async-signal safe functions used. For more information see
+ * man fork(3p), signal(7)
+ */
+int v9fs_chroot(FsContext *fs_ctx)
+{
+int fd_pair[2], chroot_sock, error;
+V9fsFileObjectRequest request;
+pid_t pid;
+uint32_t code;
+int fd, valid_fd;
+
+if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd_pair) < 0) {
+error_report("socketpair %s", strerror(errno));
+return -1;
+}
+
+pid = fork();
+if (pid < 0) {
+error_report("fork %s", strerror(errno));
+return -1;
+}
+if (pid != 0)

[Qemu-devel] [V7 PATCH 5/9] virtio-9p: Add support to open a file in chroot environment

2011-03-04 Thread M. Mohan Kumar
This patch adds both chroot worker and qemu side support to open a file/
directory in the chroot environment

Signed-off-by: M. Mohan Kumar 
---
 hw/9pfs/virtio-9p-chroot.c |   28 ++-
 hw/9pfs/virtio-9p-chroot.h |2 +-
 hw/9pfs/virtio-9p-local.c  |   62 +---
 3 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/hw/9pfs/virtio-9p-chroot.c b/hw/9pfs/virtio-9p-chroot.c
index 4aa3b43..0c91db6 100644
--- a/hw/9pfs/virtio-9p-chroot.c
+++ b/hw/9pfs/virtio-9p-chroot.c
@@ -80,13 +80,25 @@ static int v9fs_write_request(int sockfd, 
V9fsFileObjectRequest *request)
 return 0;
 }
 
-/*
- * This patch adds v9fs_receivefd and v9fs_write_request functions,
- * but there is no callers. To avoid compiler warning message,
- * refer these two functions
- */
-void chroot_dummy(void)
+/* Return opened file descriptor on success or -errno on error */
+int v9fs_request(FsContext *fs_ctx, V9fsFileObjectRequest *request)
 {
-(void)v9fs_receivefd;
-(void)v9fs_write_request;
+int fd, sock_error;
+qemu_mutex_lock(&fs_ctx->chroot_mutex);
+if (fs_ctx->chroot_ioerror) {
+fd = -EIO;
+goto unlock;
+}
+if (v9fs_write_request(fs_ctx->chroot_socket, request) < 0) {
+fs_ctx->chroot_ioerror = 1;
+fd = -EIO;
+goto unlock;
+}
+fd = v9fs_receivefd(fs_ctx->chroot_socket, &sock_error);
+if (fd < 0 && sock_error) {
+fs_ctx->chroot_ioerror = 1;
+}
+unlock:
+qemu_mutex_unlock(&fs_ctx->chroot_mutex);
+return fd;
 }
diff --git a/hw/9pfs/virtio-9p-chroot.h b/hw/9pfs/virtio-9p-chroot.h
index 0c020f8..6f676e9 100644
--- a/hw/9pfs/virtio-9p-chroot.h
+++ b/hw/9pfs/virtio-9p-chroot.h
@@ -39,6 +39,6 @@ typedef struct V9fsFileObjectRequest
 } V9fsFileObjectRequest;
 
 int v9fs_chroot(FsContext *fs_ctx);
-void chroot_dummy(void);
+int v9fs_request(FsContext *fs_ctx, V9fsFileObjectRequest *or);
 
 #endif /* _QEMU_VIRTIO_9P_CHROOT_H */
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 0a015de..8c187d7 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -13,6 +13,9 @@
 #include "virtio.h"
 #include "virtio-9p.h"
 #include "virtio-9p-xattr.h"
+#include "qemu_socket.h"
+#include "fsdev/qemu-fsdev.h"
+#include "virtio-9p-chroot.h"
 #include 
 #include 
 #include 
@@ -20,6 +23,44 @@
 #include 
 #include 
 
+/* Helper routine to fill V9fsFileObjectRequest structure */
+static int fill_fileobjectrequest(V9fsFileObjectRequest *request,
+const char *path, FsCred *credp)
+{
+if (strlen(path) >= PATH_MAX) {
+return -ENAMETOOLONG;
+}
+memset(request, 0, sizeof(*request));
+request->data.path_len = strlen(path);
+strcpy(request->path.path, path);
+if (credp) {
+request->data.mode = credp->fc_mode;
+request->data.uid = credp->fc_uid;
+request->data.gid = credp->fc_gid;
+request->data.dev = credp->fc_rdev;
+}
+return 0;
+}
+
+static int passthrough_open(FsContext *fs_ctx, const char *path, int flags)
+{
+V9fsFileObjectRequest request;
+int fd;
+
+fd = fill_fileobjectrequest(&request, path, NULL);
+if (fd < 0) {
+errno = -fd;
+return -1;
+}
+request.data.flags = flags;
+request.data.type = T_OPEN;
+fd = v9fs_request(fs_ctx, &request);
+if (fd < 0) {
+errno = -fd;
+fd = -1;
+}
+return fd;
+}
 
 static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
 {
@@ -138,14 +179,27 @@ static int local_closedir(FsContext *ctx, DIR *dir)
 return closedir(dir);
 }
 
-static int local_open(FsContext *ctx, const char *path, int flags)
+static int local_open(FsContext *fs_ctx, const char *path, int flags)
 {
-return open(rpath(ctx, path), flags);
+if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+return passthrough_open(fs_ctx, path, flags);
+} else {
+return open(rpath(fs_ctx, path), flags);
+}
 }
 
-static DIR *local_opendir(FsContext *ctx, const char *path)
+static DIR *local_opendir(FsContext *fs_ctx, const char *path)
 {
-return opendir(rpath(ctx, path));
+if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+int fd;
+fd = passthrough_open(fs_ctx, path, O_DIRECTORY);
+if (fd < 0) {
+return NULL;
+}
+return fdopendir(fd);
+} else {
+return opendir(rpath(fs_ctx, path));
+}
 }
 
 static void local_rewinddir(FsContext *ctx, DIR *dir)
-- 
1.7.3.4




[Qemu-devel] [V7 PATCH 4/9] virtio-9p: Add qemu side interfaces for chroot environment

2011-03-04 Thread M. Mohan Kumar
QEMU side interfaces to communicate with chroot worker process.

Signed-off-by: M. Mohan Kumar 
---
 Makefile.objs  |2 +-
 hw/9pfs/virtio-9p-chroot.c |   92 
 hw/9pfs/virtio-9p-chroot.h |1 +
 3 files changed, 94 insertions(+), 1 deletions(-)
 create mode 100644 hw/9pfs/virtio-9p-chroot.c

diff --git a/Makefile.objs b/Makefile.objs
index 44891c1..6610de9 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -283,7 +283,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
-9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-chroot-worker.o
+9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-chroot-worker.o virtio-9p-chroot.o
 
 hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 $(addprefix 9pfs/, $(9pfs-nested-y)): CFLAGS +=  -I$(SRC_PATH)/hw/
diff --git a/hw/9pfs/virtio-9p-chroot.c b/hw/9pfs/virtio-9p-chroot.c
new file mode 100644
index 000..4aa3b43
--- /dev/null
+++ b/hw/9pfs/virtio-9p-chroot.c
@@ -0,0 +1,92 @@
+/*
+ * Virtio 9p chroot environment for contained access to exported path
+ * Code handles qemu side interfaces to communicate with chroot worker process
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ * M. Mohan Kumar 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the copying file in the top-level directory
+ *
+ */
+
+#include 
+#include 
+#include 
+#include "virtio.h"
+#include "qemu_socket.h"
+#include "qemu-thread.h"
+#include "qerror.h"
+#include "virtio-9p.h"
+#include "virtio-9p-chroot.h"
+
+/*
+ * Return received file descriptor on success and -errno on failure.
+ * sock_error is set to 1 whenever there is error in socket IO
+ */
+static int v9fs_receivefd(int sockfd, int *sock_error)
+{
+struct msghdr msg = { };
+struct iovec iov;
+union MsgControl msg_control;
+struct cmsghdr *cmsg;
+int retval, fd;
+
+iov.iov_base = &fd;
+iov.iov_len = sizeof(fd);
+
+*sock_error = 0;
+memset(&msg, 0, sizeof(msg));
+msg.msg_iov = &iov;
+msg.msg_iovlen = 1;
+msg.msg_control = &msg_control;
+msg.msg_controllen = sizeof(msg_control);
+
+do {
+retval = recvmsg(sockfd, &msg, 0);
+} while (retval < 0 && errno == EINTR);
+if (retval <= 0) {
+*sock_error = 1;
+return -EIO;
+}
+
+if (fd < 0) {
+return fd;
+}
+for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)) ||
+cmsg->cmsg_level != SOL_SOCKET ||
+cmsg->cmsg_type != SCM_RIGHTS) {
+continue;
+}
+fd = *((int *)CMSG_DATA(cmsg));
+return fd;
+}
+return fd;
+}
+
+/*
+ * V9fsFileObjectRequest is written into the socket by QEMU process.
+ * Then this request is read by chroot process using v9fs_read_request function
+ */
+static int v9fs_write_request(int sockfd, V9fsFileObjectRequest *request)
+{
+int retval;
+retval = qemu_write_full(sockfd, request, sizeof(*request));
+if (retval != sizeof(*request)) {
+return -EIO;
+}
+return 0;
+}
+
+/*
+ * This patch adds v9fs_receivefd and v9fs_write_request functions,
+ * but there is no callers. To avoid compiler warning message,
+ * refer these two functions
+ */
+void chroot_dummy(void)
+{
+(void)v9fs_receivefd;
+(void)v9fs_write_request;
+}
diff --git a/hw/9pfs/virtio-9p-chroot.h b/hw/9pfs/virtio-9p-chroot.h
index 97f616c..0c020f8 100644
--- a/hw/9pfs/virtio-9p-chroot.h
+++ b/hw/9pfs/virtio-9p-chroot.h
@@ -39,5 +39,6 @@ typedef struct V9fsFileObjectRequest
 } V9fsFileObjectRequest;
 
 int v9fs_chroot(FsContext *fs_ctx);
+void chroot_dummy(void);
 
 #endif /* _QEMU_VIRTIO_9P_CHROOT_H */
-- 
1.7.3.4




[Qemu-devel] [V7 PATCH 8/9] virtio-9p: Move file post creation changes to none security model

2011-03-04 Thread M. Mohan Kumar
After creating a file object, its permission and ownership details are updated
as per 9p client's request for both passthrough and none security model.
But with chrooted environment its not required for passthrough security model.
Move all post file creation changes to none security model.

Signed-off-by: M. Mohan Kumar 
---
 hw/9pfs/virtio-9p-local.c |   19 ++-
 1 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 904ee71..864334d 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -176,21 +176,14 @@ static int local_set_xattr(const char *path, FsCred 
*credp)
 return 0;
 }
 
-static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
+static int local_post_create_none(FsContext *fs_ctx, const char *path,
 FsCred *credp)
 {
+int retval;
 if (chmod(rpath(fs_ctx, path), credp->fc_mode & 0) < 0) {
 return -1;
 }
-if (lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid) < 0) {
-/*
- * If we fail to change ownership and if we are
- * using security model none. Ignore the error
- */
-if (fs_ctx->fs_sm != SM_NONE) {
-return -1;
-}
-}
+retval = lchown(rpath(fs_ctx, path), credp->fc_uid, credp->fc_gid);
 return 0;
 }
 
@@ -331,7 +324,7 @@ static int local_mknod(FsContext *fs_ctx, const char *path, 
FsCred *credp)
 if (err == -1) {
 return err;
 }
-err = local_post_create_passthrough(fs_ctx, path, credp);
+err = local_post_create_none(fs_ctx, path, credp);
 if (err == -1) {
 serrno = errno;
 goto err_end;
@@ -373,7 +366,7 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, 
FsCred *credp)
 if (err == -1) {
 return err;
 }
-err = local_post_create_passthrough(fs_ctx, path, credp);
+err = local_post_create_none(fs_ctx, path, credp);
 if (err == -1) {
 serrno = errno;
 goto err_end;
@@ -448,7 +441,7 @@ static int local_open2(FsContext *fs_ctx, const char *path, 
int flags,
 if (fd == -1) {
 return fd;
 }
-err = local_post_create_passthrough(fs_ctx, path, credp);
+err = local_post_create_none(fs_ctx, path, credp);
 if (err == -1) {
 serrno = errno;
 goto err_end;
-- 
1.7.3.4




[Qemu-devel] [V7 PATCH 6/9] virtio-9p: Create support in chroot environment

2011-03-04 Thread M. Mohan Kumar
Add both chroot worker & qemu side interfaces to create regular files in
chroot environment

Signed-off-by: M. Mohan Kumar 
---
 hw/9pfs/virtio-9p-chroot-worker.c |   36 
 hw/9pfs/virtio-9p-local.c |   26 --
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/hw/9pfs/virtio-9p-chroot-worker.c 
b/hw/9pfs/virtio-9p-chroot-worker.c
index e7bc6c2..cdcb303 100644
--- a/hw/9pfs/virtio-9p-chroot-worker.c
+++ b/hw/9pfs/virtio-9p-chroot-worker.c
@@ -85,6 +85,36 @@ static int chroot_do_open(V9fsFileObjectRequest *request)
 return fd;
 }
 
+/*
+ * Helper routine to create a file and return the file descriptor
+ */
+static int chroot_do_create(V9fsFileObjectRequest *request)
+{
+uid_t cur_uid;
+gid_t cur_gid;
+int fd = -1;
+
+cur_uid = geteuid();
+cur_gid = getegid();
+
+if (setfsuid(request->data.uid) < 0) {
+return -errno;
+}
+if (setfsgid(request->data.gid) < 0) {
+fd = -errno;
+goto unset_uid;
+}
+
+fd = open(request->path.path, request->data.flags, request->data.mode);
+if (fd < 0) {
+fd = -errno;
+}
+setfsgid(cur_gid);
+unset_uid:
+setfsuid(cur_uid);
+return fd;
+}
+
 static void chroot_daemonize(int chroot_sock)
 {
 sigset_t sigset;
@@ -174,6 +204,12 @@ int v9fs_chroot(FsContext *fs_ctx)
 valid_fd = 1;
 }
 break;
+case T_CREATE:
+fd = chroot_do_create(&request);
+if (fd >= 0) {
+valid_fd = 1;
+}
+break;
 default:
 fd = -1;
 break;
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 8c187d7..aa8ebff 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -62,6 +62,27 @@ static int passthrough_open(FsContext *fs_ctx, const char 
*path, int flags)
 return fd;
 }
 
+static int passthrough_create(FsContext *fs_ctx, const char *path, int flags,
+FsCred *credp)
+{
+V9fsFileObjectRequest request;
+int fd;
+
+fd = fill_fileobjectrequest(&request, path, credp);
+if (fd < 0) {
+errno = -1;
+return -1;
+}
+request.data.flags = flags;
+request.data.type = T_CREATE;
+fd = v9fs_request(fs_ctx, &request);
+if (fd < 0) {
+errno = -fd;
+fd = -1;
+}
+return fd;
+}
+
 static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
 {
 int err;
@@ -386,8 +407,7 @@ static int local_open2(FsContext *fs_ctx, const char *path, 
int flags,
 serrno = errno;
 goto err_end;
 }
-} else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
-   (fs_ctx->fs_sm == SM_NONE)) {
+} else if (fs_ctx->fs_sm == SM_NONE) {
 fd = open(rpath(fs_ctx, path), flags, credp->fc_mode);
 if (fd == -1) {
 return fd;
@@ -397,6 +417,8 @@ static int local_open2(FsContext *fs_ctx, const char *path, 
int flags,
 serrno = errno;
 goto err_end;
 }
+} else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+fd = passthrough_create(fs_ctx, path, flags, credp);
 }
 return fd;
 
-- 
1.7.3.4




[Qemu-devel] [V7 PATCH 7/9] virtio-9p: Support for creating special files

2011-03-04 Thread M. Mohan Kumar
Add both chroot worker and qemu side interfaces to create special files
(directory, device nodes, links and symbolic links)

Signed-off-by: M. Mohan Kumar 
---
 hw/9pfs/virtio-9p-chroot-worker.c |   52 
 hw/9pfs/virtio-9p-chroot.c|   23 +
 hw/9pfs/virtio-9p-chroot.h|1 +
 hw/9pfs/virtio-9p-local.c |   97 +
 4 files changed, 142 insertions(+), 31 deletions(-)

diff --git a/hw/9pfs/virtio-9p-chroot-worker.c 
b/hw/9pfs/virtio-9p-chroot-worker.c
index cdcb303..fcc0be1 100644
--- a/hw/9pfs/virtio-9p-chroot-worker.c
+++ b/hw/9pfs/virtio-9p-chroot-worker.c
@@ -115,6 +115,52 @@ unset_uid:
 return fd;
 }
 
+/*
+ * Create directory, symbolic link, link, device node and regular files
+ * Similar to create, but it does not return the fd of created object
+ * Returns 0 as file descriptor on success and -errno on failure
+ */
+static int chroot_do_create_special(V9fsFileObjectRequest *request)
+{
+int cur_uid, cur_gid;
+int retval = -1;
+
+cur_uid = geteuid();
+cur_gid = getegid();
+
+if (setfsuid(request->data.uid) < 0) {
+return -errno;
+}
+if (setfsgid(request->data.gid) < 0) {
+retval = -errno;
+goto unset_uid;
+}
+
+switch (request->data.type) {
+case T_MKDIR:
+retval = mkdir(request->path.path, request->data.mode);
+break;
+case T_SYMLINK:
+retval = symlink(request->path.old_path, request->path.path);
+break;
+case T_LINK:
+retval = link(request->path.old_path, request->path.path);
+break;
+default:
+retval = mknod(request->path.path, request->data.mode,
+request->data.dev);
+break;
+}
+
+if (retval < 0) {
+retval = -errno;
+}
+setfsgid(cur_gid);
+unset_uid:
+setfsuid(cur_uid);
+return retval;
+}
+
 static void chroot_daemonize(int chroot_sock)
 {
 sigset_t sigset;
@@ -210,6 +256,12 @@ int v9fs_chroot(FsContext *fs_ctx)
 valid_fd = 1;
 }
 break;
+case T_MKDIR:
+case T_SYMLINK:
+case T_LINK:
+case T_MKNOD:
+fd = chroot_do_create_special(&request);
+break;
 default:
 fd = -1;
 break;
diff --git a/hw/9pfs/virtio-9p-chroot.c b/hw/9pfs/virtio-9p-chroot.c
index 0c91db6..ff0a53e 100644
--- a/hw/9pfs/virtio-9p-chroot.c
+++ b/hw/9pfs/virtio-9p-chroot.c
@@ -102,3 +102,26 @@ unlock:
 qemu_mutex_unlock(&fs_ctx->chroot_mutex);
 return fd;
 }
+
+/* Return 0 on success or -errno on error */
+int v9fs_create_special(FsContext *fs_ctx, V9fsFileObjectRequest *request)
+{
+int retval, sock_error;
+qemu_mutex_lock(&fs_ctx->chroot_mutex);
+if (fs_ctx->chroot_ioerror) {
+retval = -EIO;
+goto unlock;
+}
+if (v9fs_write_request(fs_ctx->chroot_socket, request) < 0) {
+fs_ctx->chroot_ioerror = 1;
+retval = -EIO;
+goto unlock;
+}
+retval = v9fs_receivefd(fs_ctx->chroot_socket, &sock_error);
+if (retval < 0 && sock_error) {
+fs_ctx->chroot_ioerror = 1;
+}
+unlock:
+qemu_mutex_unlock(&fs_ctx->chroot_mutex);
+return retval;
+}
diff --git a/hw/9pfs/virtio-9p-chroot.h b/hw/9pfs/virtio-9p-chroot.h
index 6f676e9..a7f60e2 100644
--- a/hw/9pfs/virtio-9p-chroot.h
+++ b/hw/9pfs/virtio-9p-chroot.h
@@ -40,5 +40,6 @@ typedef struct V9fsFileObjectRequest
 
 int v9fs_chroot(FsContext *fs_ctx);
 int v9fs_request(FsContext *fs_ctx, V9fsFileObjectRequest *or);
+int v9fs_create_special(FsContext *fs_ctx, V9fsFileObjectRequest *request);
 
 #endif /* _QEMU_VIRTIO_9P_CHROOT_H */
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index aa8ebff..904ee71 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -83,6 +83,32 @@ static int passthrough_create(FsContext *fs_ctx, const char 
*path, int flags,
 return fd;
 }
 
+static int passthrough_create_special(FsContext *fs_ctx, const char *oldpath,
+const char *path, FsCred *credp, int type)
+{
+V9fsFileObjectRequest request;
+int retval;
+
+retval = fill_fileobjectrequest(&request, path, credp);
+if (retval < 0) {
+return retval;
+}
+request.data.type = type;
+if (oldpath) {
+request.data.oldpath_len = strlen(oldpath);
+if (strlen(oldpath) >= PATH_MAX) {
+return -ENAMETOOLONG;
+}
+strcpy(request.path.old_path, oldpath);
+}
+retval = v9fs_create_special(fs_ctx, &request);
+if (retval < 0) {
+errno = -retval;
+retval = -1;
+}
+return retval;
+}
+
 static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
 {
 int err;
@@ -300,8 +326,7 @@ static int local_mknod(FsContext *fs_ctx, const char *path, 
FsCred *credp)
 serrno = errno;
 goto err_end;
 }
-} else if ((fs_ctx->fs_sm == SM

[Qemu-devel] [V7 PATCH 9/9] virtio-9p: Chroot environment for other functions

2011-03-04 Thread M. Mohan Kumar
Add chroot functionality for systemcalls that can operate on a file
using relative directory file descriptor.

Signed-off-by: M. Mohan Kumar 
---
 hw/9pfs/virtio-9p-local.c |  229 +++--
 1 files changed, 199 insertions(+), 30 deletions(-)

diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 864334d..cb94ab7 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Helper routine to fill V9fsFileObjectRequest structure */
 static int fill_fileobjectrequest(V9fsFileObjectRequest *request,
@@ -109,14 +110,39 @@ static int passthrough_create_special(FsContext *fs_ctx, 
const char *oldpath,
 return retval;
 }
 
+/*
+ * Returns file descriptor of dirname(path)
+ * This fd can be used by *at functions
+ */
+static int get_dirfd(FsContext *fs_ctx, const char *path)
+{
+V9fsFileObjectRequest request;
+int fd;
+char *dpath = qemu_strdup(path);
+
+fd = fill_fileobjectrequest(&request, dirname(dpath), NULL);
+if (fd < 0) {
+return fd;
+}
+request.data.type = T_OPEN;
+fd = v9fs_request(fs_ctx, &request);
+qemu_free(dpath);
+if (fd < 0) {
+errno = -fd;
+fd = -1;
+}
+return fd;
+}
+
 static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
 {
 int err;
-err =  lstat(rpath(fs_ctx, path), stbuf);
-if (err) {
-return err;
-}
+
 if (fs_ctx->fs_sm == SM_MAPPED) {
+err =  lstat(rpath(fs_ctx, path), stbuf);
+if (err) {
+return err;
+}
 /* Actual credentials are part of extended attrs */
 uid_t tmp_uid;
 gid_t tmp_gid;
@@ -138,6 +164,27 @@ static int local_lstat(FsContext *fs_ctx, const char 
*path, struct stat *stbuf)
 sizeof(dev_t)) > 0) {
 stbuf->st_rdev = tmp_dev;
 }
+} else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+int pfd, serrno = 0;
+char *tmp_path;
+
+pfd = get_dirfd(fs_ctx, path);
+if (pfd < 0) {
+return -1;
+}
+tmp_path = qemu_strdup(path);
+err = fstatat(pfd, basename(tmp_path), stbuf, AT_SYMLINK_NOFOLLOW);
+if (err < 0) {
+serrno = errno;
+}
+close(pfd);
+qemu_free(tmp_path);
+errno = serrno;
+} else {
+err =  lstat(rpath(fs_ctx, path), stbuf);
+if (err) {
+return err;
+}
 }
 return err;
 }
@@ -202,9 +249,23 @@ static ssize_t local_readlink(FsContext *fs_ctx, const 
char *path,
 } while (tsize == -1 && errno == EINTR);
 close(fd);
 return tsize;
-} else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
-   (fs_ctx->fs_sm == SM_NONE)) {
+} else if (fs_ctx->fs_sm == SM_NONE) {
 tsize = readlink(rpath(fs_ctx, path), buf, bufsz);
+} else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+int pfd, serrno = 0;
+char *tmp_path;
+pfd = get_dirfd(fs_ctx, path);
+if (pfd < 0) {
+return -1;
+}
+tmp_path = qemu_strdup(path);
+tsize = readlinkat(pfd, basename(tmp_path), buf, bufsz);
+if (tsize < 0) {
+serrno = 0;
+}
+close(pfd);
+qemu_free(tmp_path);
+errno = serrno;
 }
 return tsize;
 }
@@ -296,8 +357,23 @@ static int local_chmod(FsContext *fs_ctx, const char 
*path, FsCred *credp)
 {
 if (fs_ctx->fs_sm == SM_MAPPED) {
 return local_set_xattr(rpath(fs_ctx, path), credp);
-} else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||
-   (fs_ctx->fs_sm == SM_NONE)) {
+} else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+int pfd, err, serrno = 0;
+char *tmp_path;
+pfd = get_dirfd(fs_ctx, path);
+if (pfd < 0) {
+return -1;
+}
+tmp_path = qemu_strdup(path);
+err = fchmodat(pfd, basename(tmp_path), credp->fc_mode, 0);
+if (err == -1) {
+serrno = errno;
+}
+qemu_free(tmp_path);
+close(pfd);
+errno = serrno;
+return err;
+} else if (fs_ctx->fs_sm == SM_NONE) {
 return chmod(rpath(fs_ctx, path), credp->fc_mode);
 }
 return -1;
@@ -545,53 +621,146 @@ static int local_link(FsContext *fs_ctx, const char 
*oldpath,
 
 static int local_truncate(FsContext *ctx, const char *path, off_t size)
 {
-return truncate(rpath(ctx, path), size);
+if (ctx->fs_sm == SM_PASSTHROUGH) {
+int fd, retval;
+fd = passthrough_open(ctx, path, O_RDWR);
+if (fd < 0) {
+return -1;
+}
+retval = ftruncate(fd, size);
+close(fd);
+return retval;
+} else {
+return truncate(rpath(ctx, path), size);
+}
 }
 
 static int local_rename(FsContext *ctx, const char *oldpath,
 const char *newpath)
 {
-char *t

[Qemu-devel] [PATCH 08/15] x86: Save/restore PAT MSR

2011-03-04 Thread Jan Kiszka
Signed-off-by: Jan Kiszka 
---
 target-i386/machine.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/target-i386/machine.c b/target-i386/machine.c
index d78eceb..6384f54 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -491,6 +491,8 @@ static const VMStateDescription vmstate_cpu = {
 VMSTATE_UINT64_V(xcr0, CPUState, 12),
 VMSTATE_UINT64_V(xstate_bv, CPUState, 12),
 VMSTATE_YMMH_REGS_VARS(ymmh_regs, CPUState, CPU_NB_REGS, 12),
+
+VMSTATE_UINT64_V(pat, CPUState, 13),
 VMSTATE_END_OF_LIST()
 /* The above list is not sorted /wrt version numbers, watch out! */
 },
-- 
1.7.1




[Qemu-devel] [PATCH 07/15] x86: Properly reset PAT MSR

2011-03-04 Thread Jan Kiszka
Conforming to the Intel spec, set the power-on value of PAT also on
reset, but save it across INIT.

Signed-off-by: Jan Kiszka 
---
 target-i386/cpu.h|4 ++--
 target-i386/cpuid.c  |1 -
 target-i386/helper.c |5 +
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index d0eae75..c7047d5 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -685,8 +685,6 @@ typedef struct CPUX86State {
 
 uint64_t tsc;
 
-uint64_t pat;
-
 uint64_t mcg_status;
 
 /* exception/interrupt handling */
@@ -707,6 +705,8 @@ typedef struct CPUX86State {
 
 CPU_COMMON
 
+uint64_t pat;
+
 /* processor features (e.g. for CPUID insn) */
 uint32_t cpuid_level;
 uint32_t cpuid_vendor1;
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 5382a28..814d13e 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -847,7 +847,6 @@ int cpu_x86_register (CPUX86State *env, const char 
*cpu_model)
 env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 
16);
 env->cpuid_version |= def->stepping;
 env->cpuid_features = def->features;
-env->pat = 0x0007040600070406ULL;
 env->cpuid_ext_features = def->ext_features;
 env->cpuid_ext2_features = def->ext2_features;
 env->cpuid_ext3_features = def->ext3_features;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index a08309f..d15fca5 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -99,6 +99,8 @@ void cpu_reset(CPUX86State *env)
 
 env->mxcsr = 0x1f80;
 
+env->pat = 0x0007040600070406ULL;
+
 memset(env->dr, 0, sizeof(env->dr));
 env->dr[6] = DR6_FIXED_1;
 env->dr[7] = DR7_FIXED_1;
@@ -1280,8 +1282,11 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 void do_cpu_init(CPUState *env)
 {
 int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
+uint64_t pat = env->pat;
+
 cpu_reset(env);
 env->interrupt_request = sipi;
+env->pat = pat;
 apic_init_reset(env->apic_state);
 env->halted = !cpu_is_bsp(env);
 }
-- 
1.7.1




[Qemu-devel] [PATCH 00/15] [uq/master] Patch queue, part V (the rest)

2011-03-04 Thread Jan Kiszka
This series catches "all the rest" to prepare QEMU's KVM support for
merging with qemu-kvm. IOW, once these bits here are applied, qemu-kvm
can switch its infrastructure to upstream and is effectively only adding
own bits for in-kernel irqchip and device assignment support.

Topics of this series are:
 - support for optimized interrupt handling by hooking cpu_interrupt
 - another preparational step for in-kernel irqchip support
 - x86: Do not leave halt if interrupts are disabled
 - mark VCPU state dirty on creation (fixed deadlock on early hw_error)
 - complete KVM support for PAT MSR, some related improvements for TCG
 - further consolidation of inner kvm_cpu_exec loop
 - expose VCPU host thread ID via "info cpus" and "query-cpus"

Please review.

CC: Alexander Graf 
CC: Riku Voipio 

Jan Kiszka (15):
  Break up user and system cpu_interrupt implementations
  Redirect cpu_interrupt to callback handler
  kvm: Install optimized interrupt handlers
  kvm: Add in-kernel irqchip awareness to cpu_thread_is_idle
  kvm: x86: Do not leave halt if interrupts are disabled
  kvm: Mark VCPU state dirty on creation
  x86: Properly reset PAT MSR
  x86: Save/restore PAT MSR
  kvm: x86: Synchronize PAT MSR with the kernel
  kvm: Consider EXIT_DEBUG unknown without CAP_SET_GUEST_DEBUG
  kvm: Rework inner loop of kvm_cpu_exec
  kvm: Align kvm_arch_handle_exit to kvm_cpu_exec changes
  kvm: x86: Reorder functions in kvm.c
  kvm: x86: Push kvm_arch_debug to kvm_arch_handle_exit
  Expose thread_id in info cpus

 cpu-all.h |   14 -
 cpu-defs.h|1 +
 cpus.c|5 +-
 exec.c|   21 +--
 kvm-all.c |   46 ---
 kvm.h |2 -
 monitor.c |4 +
 os-posix.c|   10 +++
 os-win32.c|5 ++
 osdep.h   |1 +
 qmp-commands.hx   |3 +
 target-i386/cpu.h |4 +-
 target-i386/cpuid.c   |1 -
 target-i386/helper.c  |5 ++
 target-i386/kvm.c |  146 +++--
 target-i386/machine.c |2 +
 target-ppc/kvm.c  |8 +-
 target-s390x/kvm.c|5 ++
 18 files changed, 180 insertions(+), 103 deletions(-)




[Qemu-devel] [PATCH 03/15] kvm: Install optimized interrupt handlers

2011-03-04 Thread Jan Kiszka
KVM only requires to set the raised IRQ in CPUState and, if the user
space irqchip is used, to kick the receiving vcpu if it is remote.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 226843c..c460d45 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -650,6 +650,20 @@ static CPUPhysMemoryClient kvm_cpu_phys_memory_client = {
 .log_stop = kvm_log_stop,
 };
 
+static void kvm_handle_interrupt(CPUState *env, int mask)
+{
+env->interrupt_request |= mask;
+
+if (!qemu_cpu_self(env)) {
+qemu_cpu_kick(env);
+}
+}
+
+static void kvm_handle_interrupt_kernel_irqchip(CPUState *env, int mask)
+{
+env->interrupt_request |= mask;
+}
+
 int kvm_init(void)
 {
 static const char upgrade_note[] =
@@ -758,6 +772,9 @@ int kvm_init(void)
 
 s->many_ioeventfds = kvm_check_many_ioeventfds();
 
+cpu_interrupt_handler = kvm_irqchip_in_kernel() ?
+kvm_handle_interrupt_kernel_irqchip : kvm_handle_interrupt;
+
 return 0;
 
 err:
-- 
1.7.1




[Qemu-devel] [PATCH 15/15] Expose thread_id in info cpus

2011-03-04 Thread Jan Kiszka
Based on patch by Glauber Costa:

To allow management applications like libvirt to apply CPU affinities to
the VCPU threads, expose their ID via info cpus. This patch provides the
pre-existing and used interface from qemu-kvm.

Signed-off-by: Jan Kiszka 
---
 cpu-defs.h  |1 +
 cpus.c  |2 ++
 exec.c  |3 +++
 monitor.c   |4 
 os-posix.c  |   10 ++
 os-win32.c  |5 +
 osdep.h |1 +
 qmp-commands.hx |3 +++
 8 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 2b59fa6..db48a7a 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -203,6 +203,7 @@ typedef struct CPUWatchpoint {
 int nr_cores;  /* number of cores within this CPU package */\
 int nr_threads;/* number of threads within this CPU */  \
 int running; /* Nonzero if cpu is currently running(usermode).  */  \
+int thread_id;  \
 /* user data */ \
 void *opaque;   \
 \
diff --git a/cpus.c b/cpus.c
index 66f6b5a..30fe568 100644
--- a/cpus.c
+++ b/cpus.c
@@ -810,6 +810,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 
 qemu_mutex_lock(&qemu_global_mutex);
 qemu_thread_self(env->thread);
+env->thread_id = qemu_get_thread_id();
 
 r = kvm_init_vcpu(env);
 if (r < 0) {
@@ -851,6 +852,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 /* signal CPU creation */
 qemu_mutex_lock(&qemu_global_mutex);
 for (env = first_cpu; env != NULL; env = env->next_cpu) {
+env->thread_id = qemu_get_thread_id();
 env->created = 1;
 }
 qemu_cond_signal(&qemu_cpu_cond);
diff --git a/exec.c b/exec.c
index a733acd..0b7a7b2 100644
--- a/exec.c
+++ b/exec.c
@@ -638,6 +638,9 @@ void cpu_exec_init(CPUState *env)
 env->numa_node = 0;
 QTAILQ_INIT(&env->breakpoints);
 QTAILQ_INIT(&env->watchpoints);
+#ifndef CONFIG_USER_ONLY
+env->thread_id = qemu_get_thread_id();
+#endif
 *penv = env;
 #if defined(CONFIG_USER_ONLY)
 cpu_list_unlock();
diff --git a/monitor.c b/monitor.c
index ae20927..481572d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -897,6 +897,9 @@ static void print_cpu_iter(QObject *obj, void *opaque)
 monitor_printf(mon, " (halted)");
 }
 
+monitor_printf(mon, " thread_id=%" PRId64 " ",
+   qdict_get_int(cpu, "thread_id"));
+
 monitor_printf(mon, "\n");
 }
 
@@ -941,6 +944,7 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data)
 #elif defined(TARGET_MIPS)
 qdict_put(cpu, "PC", qint_from_int(env->active_tc.PC));
 #endif
+qdict_put(cpu, "thread_id", qint_from_int(env->thread_id));
 
 qlist_append(cpu_list, cpu);
 }
diff --git a/os-posix.c b/os-posix.c
index 38c29d1..7971f86 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -41,6 +41,7 @@
 
 #ifdef CONFIG_LINUX
 #include 
+#include 
 #endif
 
 #ifdef CONFIG_EVENTFD
@@ -382,3 +383,12 @@ int qemu_create_pidfile(const char *filename)
 
 return 0;
 }
+
+int qemu_get_thread_id(void)
+{
+#if defined (__linux__)
+return syscall(SYS_gettid);
+#else
+return getpid();
+#endif
+}
diff --git a/os-win32.c b/os-win32.c
index b214e6a..dd5517e 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -264,3 +264,8 @@ int qemu_create_pidfile(const char *filename)
 }
 return 0;
 }
+
+int qemu_get_thread_id(void)
+{
+return GetCurrentThreadId();
+}
diff --git a/osdep.h b/osdep.h
index 27eedcf..748df54 100644
--- a/osdep.h
+++ b/osdep.h
@@ -130,5 +130,6 @@ void qemu_vfree(void *ptr);
 int qemu_madvise(void *addr, size_t len, int advice);
 
 int qemu_create_pidfile(const char *filename);
+int qemu_get_thread_id(void);
 
 #endif
diff --git a/qmp-commands.hx b/qmp-commands.hx
index df40a3d..1f72a8d 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1194,6 +1194,7 @@ Return a json-array. Each CPU is represented by a 
json-object, which contains:
  "nip": PPC (json-int)
  "pc" and "npc": sparc (json-int)
  "PC": mips (json-int)
+- "thread_id": ID of the underlying host thread (json-int)
 
 Example:
 
@@ -1205,12 +1206,14 @@ Example:
 "current":true,
 "halted":false,
 "pc":3227107138
+"thread_id":3134
  },
  {
 "CPU":1,
 "current":false,
 "halted":true,
 "pc":7108165
+"thread_id":3135
  }
   ]
}
-- 
1.7.1




[Qemu-devel] [PATCH 05/15] kvm: x86: Do not leave halt if interrupts are disabled

2011-03-04 Thread Jan Kiszka
When an external interrupt is pending but IF is cleared, we must not
leave the halt state prematurely.

Signed-off-by: Jan Kiszka 
---
 target-i386/kvm.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 7b7105d..6efa491 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1590,7 +1590,9 @@ int kvm_arch_process_async_events(CPUState *env)
 return 0;
 }
 
-if (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI)) {
+if (((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env->eflags & IF_MASK)) ||
+(env->interrupt_request & CPU_INTERRUPT_NMI)) {
 env->halted = 0;
 }
 if (env->interrupt_request & CPU_INTERRUPT_INIT) {
-- 
1.7.1




[Qemu-devel] [PATCH 06/15] kvm: Mark VCPU state dirty on creation

2011-03-04 Thread Jan Kiszka
This avoids that early cpu_synchronize_state calls try to retrieve an
uninitialized state from the kernel. That even causes a deadlock if
io-thread is enabled.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index c460d45..07a1a9c 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -211,6 +211,7 @@ int kvm_init_vcpu(CPUState *env)
 
 env->kvm_fd = ret;
 env->kvm_state = s;
+env->kvm_vcpu_dirty = 1;
 
 mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
 if (mmap_size < 0) {
-- 
1.7.1




[Qemu-devel] [PATCH 01/15] Break up user and system cpu_interrupt implementations

2011-03-04 Thread Jan Kiszka
Both have only two lines in common, and we will convert the system
service into a callback which is of no use for user mode operation.

Signed-off-by: Jan Kiszka 
CC: Riku Voipio 
---
 exec.c |   14 ++
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/exec.c b/exec.c
index 9308a97..09235bf 100644
--- a/exec.c
+++ b/exec.c
@@ -1627,6 +1627,7 @@ static void cpu_unlink_tb(CPUState *env)
 spin_unlock(&interrupt_lock);
 }
 
+#ifndef CONFIG_USER_ONLY
 /* mask must never be zero, except for A20 change call */
 void cpu_interrupt(CPUState *env, int mask)
 {
@@ -1635,7 +1636,6 @@ void cpu_interrupt(CPUState *env, int mask)
 old_mask = env->interrupt_request;
 env->interrupt_request |= mask;
 
-#ifndef CONFIG_USER_ONLY
 /*
  * If called from iothread context, wake the target cpu in
  * case its halted.
@@ -1644,21 +1644,27 @@ void cpu_interrupt(CPUState *env, int mask)
 qemu_cpu_kick(env);
 return;
 }
-#endif
 
 if (use_icount) {
 env->icount_decr.u16.high = 0x;
-#ifndef CONFIG_USER_ONLY
 if (!can_do_io(env)
 && (mask & ~old_mask) != 0) {
 cpu_abort(env, "Raised interrupt while not in I/O function");
 }
-#endif
 } else {
 cpu_unlink_tb(env);
 }
 }
 
+#else /* CONFIG_USER_ONLY */
+
+void cpu_interrupt(CPUState *env, int mask)
+{
+env->interrupt_request |= mask;
+cpu_unlink_tb(env);
+}
+#endif /* CONFIG_USER_ONLY */
+
 void cpu_reset_interrupt(CPUState *env, int mask)
 {
 env->interrupt_request &= ~mask;
-- 
1.7.1




[Qemu-devel] [PATCH 13/15] kvm: x86: Reorder functions in kvm.c

2011-03-04 Thread Jan Kiszka
Required for next patch which will access guest debug services from
kvm_arch_handle_exit. No functional changes.

Signed-off-by: Jan Kiszka 
---
 target-i386/kvm.c |  108 ++--
 1 files changed, 54 insertions(+), 54 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index b43a85c..103c86d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1624,60 +1624,6 @@ static int kvm_handle_halt(CPUState *env)
 return 0;
 }
 
-static bool host_supports_vmx(void)
-{
-uint32_t ecx, unused;
-
-host_cpuid(1, 0, &unused, &unused, &ecx, &unused);
-return ecx & CPUID_EXT_VMX;
-}
-
-#define VMX_INVALID_GUEST_STATE 0x8021
-
-int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
-{
-uint64_t code;
-int ret;
-
-switch (run->exit_reason) {
-case KVM_EXIT_HLT:
-DPRINTF("handle_hlt\n");
-ret = kvm_handle_halt(env);
-break;
-case KVM_EXIT_SET_TPR:
-ret = 0;
-break;
-case KVM_EXIT_FAIL_ENTRY:
-code = run->fail_entry.hardware_entry_failure_reason;
-fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n",
-code);
-if (host_supports_vmx() && code == VMX_INVALID_GUEST_STATE) {
-fprintf(stderr,
-"\nIf you're runnning a guest on an Intel machine without "
-"unrestricted mode\n"
-"support, the failure can be most likely due to the guest "
-"entering an invalid\n"
-"state for Intel VT. For example, the guest maybe running "
-"in big real mode\n"
-"which is not supported on less recent Intel processors."
-"\n\n");
-}
-ret = -1;
-break;
-case KVM_EXIT_EXCEPTION:
-fprintf(stderr, "KVM: exception %d exit (error code 0x%x)\n",
-run->ex.exception, run->ex.error_code);
-ret = -1;
-break;
-default:
-fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
-ret = -1;
-break;
-}
-
-return ret;
-}
-
 #ifdef KVM_CAP_SET_GUEST_DEBUG
 int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
 {
@@ -1860,6 +1806,60 @@ void kvm_arch_update_guest_debug(CPUState *env, struct 
kvm_guest_debug *dbg)
 }
 #endif /* KVM_CAP_SET_GUEST_DEBUG */
 
+static bool host_supports_vmx(void)
+{
+uint32_t ecx, unused;
+
+host_cpuid(1, 0, &unused, &unused, &ecx, &unused);
+return ecx & CPUID_EXT_VMX;
+}
+
+#define VMX_INVALID_GUEST_STATE 0x8021
+
+int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
+{
+uint64_t code;
+int ret;
+
+switch (run->exit_reason) {
+case KVM_EXIT_HLT:
+DPRINTF("handle_hlt\n");
+ret = kvm_handle_halt(env);
+break;
+case KVM_EXIT_SET_TPR:
+ret = 0;
+break;
+case KVM_EXIT_FAIL_ENTRY:
+code = run->fail_entry.hardware_entry_failure_reason;
+fprintf(stderr, "KVM: entry failed, hardware error 0x%" PRIx64 "\n",
+code);
+if (host_supports_vmx() && code == VMX_INVALID_GUEST_STATE) {
+fprintf(stderr,
+"\nIf you're runnning a guest on an Intel machine without "
+"unrestricted mode\n"
+"support, the failure can be most likely due to the guest "
+"entering an invalid\n"
+"state for Intel VT. For example, the guest maybe running "
+"in big real mode\n"
+"which is not supported on less recent Intel processors."
+"\n\n");
+}
+ret = -1;
+break;
+case KVM_EXIT_EXCEPTION:
+fprintf(stderr, "KVM: exception %d exit (error code 0x%x)\n",
+run->ex.exception, run->ex.error_code);
+ret = -1;
+break;
+default:
+fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
+ret = -1;
+break;
+}
+
+return ret;
+}
+
 bool kvm_arch_stop_on_emulation_error(CPUState *env)
 {
 return !(env->cr[0] & CR0_PE_MASK) ||
-- 
1.7.1




[Qemu-devel] [PATCH 10/15] kvm: Consider EXIT_DEBUG unknown without CAP_SET_GUEST_DEBUG

2011-03-04 Thread Jan Kiszka
Without KVM_CAP_SET_GUEST_DEBUG, we neither motivate the kernel to
report KVM_EXIT_DEBUG nor do we expect such exits. So fall through to
the arch code which will simply report an unknown exit reason.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 07a1a9c..2952499 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -992,17 +992,17 @@ int kvm_cpu_exec(CPUState *env)
 ret = kvm_handle_internal_error(env, run);
 break;
 #endif
+#ifdef KVM_CAP_SET_GUEST_DEBUG
 case KVM_EXIT_DEBUG:
 DPRINTF("kvm_exit_debug\n");
-#ifdef KVM_CAP_SET_GUEST_DEBUG
 if (kvm_arch_debug(&run->debug.arch)) {
 ret = EXCP_DEBUG;
 goto out;
 }
 /* re-enter, this exception was guest-internal */
 ret = 1;
-#endif /* KVM_CAP_SET_GUEST_DEBUG */
 break;
+#endif /* KVM_CAP_SET_GUEST_DEBUG */
 default:
 DPRINTF("kvm_arch_handle_exit\n");
 ret = kvm_arch_handle_exit(env, run);
-- 
1.7.1




[Qemu-devel] [PATCH 11/15] kvm: Rework inner loop of kvm_cpu_exec

2011-03-04 Thread Jan Kiszka
Let kvm_cpu_exec return EXCP_* values consistently and generate those
codes already inside its inner loop. This means we will now re-enter the
kernel while ret == 0.

Update kvm_handle_internal_error accordingly, but keep
kvm_arch_handle_exit untouched, it will be converted in a separate step.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c |   26 ++
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 2952499..cc652cf 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -848,7 +848,7 @@ static int kvm_handle_internal_error(CPUState *env, struct 
kvm_run *run)
 fprintf(stderr, "emulation failure\n");
 if (!kvm_arch_stop_on_emulation_error(env)) {
 cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
-return 0;
+return EXCP_INTERRUPT;
 }
 }
 /* FIXME: Should trigger a qmp message to let management know
@@ -947,7 +947,7 @@ int kvm_cpu_exec(CPUState *env)
 
 if (ret == -EINTR || ret == -EAGAIN) {
 DPRINTF("io window exit\n");
-ret = 0;
+ret = EXCP_INTERRUPT;
 break;
 }
 
@@ -956,7 +956,6 @@ int kvm_cpu_exec(CPUState *env)
 abort();
 }
 
-ret = 0; /* exit loop */
 switch (run->exit_reason) {
 case KVM_EXIT_IO:
 DPRINTF("handle_io\n");
@@ -965,7 +964,7 @@ int kvm_cpu_exec(CPUState *env)
   run->io.direction,
   run->io.size,
   run->io.count);
-ret = 1;
+ret = 0;
 break;
 case KVM_EXIT_MMIO:
 DPRINTF("handle_mmio\n");
@@ -973,14 +972,16 @@ int kvm_cpu_exec(CPUState *env)
run->mmio.data,
run->mmio.len,
run->mmio.is_write);
-ret = 1;
+ret = 0;
 break;
 case KVM_EXIT_IRQ_WINDOW_OPEN:
 DPRINTF("irq_window_open\n");
+ret = EXCP_INTERRUPT;
 break;
 case KVM_EXIT_SHUTDOWN:
 DPRINTF("shutdown\n");
 qemu_system_reset_request();
+ret = EXCP_INTERRUPT;
 break;
 case KVM_EXIT_UNKNOWN:
 fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",
@@ -997,28 +998,29 @@ int kvm_cpu_exec(CPUState *env)
 DPRINTF("kvm_exit_debug\n");
 if (kvm_arch_debug(&run->debug.arch)) {
 ret = EXCP_DEBUG;
-goto out;
+break;
 }
 /* re-enter, this exception was guest-internal */
-ret = 1;
+ret = 0;
 break;
 #endif /* KVM_CAP_SET_GUEST_DEBUG */
 default:
 DPRINTF("kvm_arch_handle_exit\n");
 ret = kvm_arch_handle_exit(env, run);
+if (ret == 0) {
+ret = EXCP_INTERRUPT;
+} else if (ret > 0) {
+ret = 0;
+}
 break;
 }
-} while (ret > 0);
+} while (ret == 0);
 
 if (ret < 0) {
 cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
 vm_stop(VMSTOP_PANIC);
 }
-ret = EXCP_INTERRUPT;
 
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-out:
-#endif
 env->exit_request = 0;
 cpu_single_env = NULL;
 return ret;
-- 
1.7.1




[Qemu-devel] Re: [V7 PATCH 6/9] virtio-9p: Create support in chroot environment

2011-03-04 Thread Stefan Hajnoczi
On Fri, Mar 4, 2011 at 9:25 AM, M. Mohan Kumar  wrote:
> +static int passthrough_create(FsContext *fs_ctx, const char *path, int flags,
> +                    FsCred *credp)
> +{
> +    V9fsFileObjectRequest request;
> +    int fd;
> +
> +    fd = fill_fileobjectrequest(&request, path, credp);
> +    if (fd < 0) {
> +        errno = -1;
> +        return -1;
> +    }

I think it should be errno = fd since fill_fileobjectrequest() returns
an -errno.

Stefan



[Qemu-devel] [PATCH 12/15] kvm: Align kvm_arch_handle_exit to kvm_cpu_exec changes

2011-03-04 Thread Jan Kiszka
Make the return code of kvm_arch_handle_exit directly usable for
kvm_cpu_exec. This is straightforward for x86 and ppc, just s390
would require more work. Avoid this for now by pushing the return code
translation logic into s390's kvm_arch_handle_exit.

Signed-off-by: Jan Kiszka 
CC: Alexander Graf 
---
 kvm-all.c  |5 -
 target-i386/kvm.c  |8 
 target-ppc/kvm.c   |8 
 target-s390x/kvm.c |5 +
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index cc652cf..d643dc7 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1007,11 +1007,6 @@ int kvm_cpu_exec(CPUState *env)
 default:
 DPRINTF("kvm_arch_handle_exit\n");
 ret = kvm_arch_handle_exit(env, run);
-if (ret == 0) {
-ret = EXCP_INTERRUPT;
-} else if (ret > 0) {
-ret = 0;
-}
 break;
 }
 } while (ret == 0);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index bfc8d66..b43a85c 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1618,10 +1618,10 @@ static int kvm_handle_halt(CPUState *env)
   (env->eflags & IF_MASK)) &&
 !(env->interrupt_request & CPU_INTERRUPT_NMI)) {
 env->halted = 1;
-return 0;
+return EXCP_HLT;
 }
 
-return 1;
+return 0;
 }
 
 static bool host_supports_vmx(void)
@@ -1637,7 +1637,7 @@ static bool host_supports_vmx(void)
 int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
 {
 uint64_t code;
-int ret = 0;
+int ret;
 
 switch (run->exit_reason) {
 case KVM_EXIT_HLT:
@@ -1645,7 +1645,7 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run 
*run)
 ret = kvm_handle_halt(env);
 break;
 case KVM_EXIT_SET_TPR:
-ret = 1;
+ret = 0;
 break;
 case KVM_EXIT_FAIL_ENTRY:
 code = run->fail_entry.hardware_entry_failure_reason;
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 6c99a16..593eb98 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -271,7 +271,7 @@ static int kvmppc_handle_halt(CPUState *env)
 env->exception_index = EXCP_HLT;
 }
 
-return 1;
+return 0;
 }
 
 /* map dcr access to existing qemu dcr emulation */
@@ -280,7 +280,7 @@ static int kvmppc_handle_dcr_read(CPUState *env, uint32_t 
dcrn, uint32_t *data)
 if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0)
 fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn);
 
-return 1;
+return 0;
 }
 
 static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data)
@@ -288,12 +288,12 @@ static int kvmppc_handle_dcr_write(CPUState *env, 
uint32_t dcrn, uint32_t data)
 if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0)
 fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn);
 
-return 1;
+return 0;
 }
 
 int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
 {
-int ret = 0;
+int ret;
 
 switch (run->exit_reason) {
 case KVM_EXIT_DCR:
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 5673a95..4761d5d 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -496,6 +496,11 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run 
*run)
 break;
 }
 
+if (ret == 0) {
+ret = EXCP_INTERRUPT;
+} else if (ret > 0) {
+ret = 0;
+}
 return ret;
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH 14/15] kvm: x86: Push kvm_arch_debug to kvm_arch_handle_exit

2011-03-04 Thread Jan Kiszka
There are no generic bits remaining in the handling of KVM_EXIT_DEBUG.
So push its logic completely into arch hands, i.e. only x86 so far.

Signed-off-by: Jan Kiszka 
---
 kvm-all.c |   11 ---
 kvm.h |2 --
 target-i386/kvm.c |   25 -
 3 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index d643dc7..a534c06 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -993,17 +993,6 @@ int kvm_cpu_exec(CPUState *env)
 ret = kvm_handle_internal_error(env, run);
 break;
 #endif
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-case KVM_EXIT_DEBUG:
-DPRINTF("kvm_exit_debug\n");
-if (kvm_arch_debug(&run->debug.arch)) {
-ret = EXCP_DEBUG;
-break;
-}
-/* re-enter, this exception was guest-internal */
-ret = 0;
-break;
-#endif /* KVM_CAP_SET_GUEST_DEBUG */
 default:
 DPRINTF("kvm_arch_handle_exit\n");
 ret = kvm_arch_handle_exit(env, run);
diff --git a/kvm.h b/kvm.h
index 7bc04e0..d565dba 100644
--- a/kvm.h
+++ b/kvm.h
@@ -136,8 +136,6 @@ struct kvm_sw_breakpoint {
 
 QTAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint);
 
-int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info);
-
 struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
  target_ulong pc);
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 103c86d..4258a5d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1731,31 +1731,31 @@ void kvm_arch_remove_all_hw_breakpoints(void)
 
 static CPUWatchpoint hw_watchpoint;
 
-int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
+static int kvm_handle_debug(struct kvm_debug_exit_arch *arch_info)
 {
-int handle = 0;
+int ret = 0;
 int n;
 
 if (arch_info->exception == 1) {
 if (arch_info->dr6 & (1 << 14)) {
 if (cpu_single_env->singlestep_enabled) {
-handle = 1;
+ret = EXCP_DEBUG;
 }
 } else {
 for (n = 0; n < 4; n++) {
 if (arch_info->dr6 & (1 << n)) {
 switch ((arch_info->dr7 >> (16 + n*4)) & 0x3) {
 case 0x0:
-handle = 1;
+ret = EXCP_DEBUG;
 break;
 case 0x1:
-handle = 1;
+ret = EXCP_DEBUG;
 cpu_single_env->watchpoint_hit = &hw_watchpoint;
 hw_watchpoint.vaddr = hw_breakpoint[n].addr;
 hw_watchpoint.flags = BP_MEM_WRITE;
 break;
 case 0x3:
-handle = 1;
+ret = EXCP_DEBUG;
 cpu_single_env->watchpoint_hit = &hw_watchpoint;
 hw_watchpoint.vaddr = hw_breakpoint[n].addr;
 hw_watchpoint.flags = BP_MEM_ACCESS;
@@ -1765,17 +1765,18 @@ int kvm_arch_debug(struct kvm_debug_exit_arch 
*arch_info)
 }
 }
 } else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc)) {
-handle = 1;
+ret = EXCP_DEBUG;
 }
-if (!handle) {
+if (ret == 0) {
 cpu_synchronize_state(cpu_single_env);
 assert(cpu_single_env->exception_injected == -1);
 
+/* pass to guest */
 cpu_single_env->exception_injected = arch_info->exception;
 cpu_single_env->has_error_code = 0;
 }
 
-return handle;
+return ret;
 }
 
 void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
@@ -1851,6 +1852,12 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run 
*run)
 run->ex.exception, run->ex.error_code);
 ret = -1;
 break;
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+case KVM_EXIT_DEBUG:
+DPRINTF("kvm_exit_debug\n");
+ret = kvm_handle_debug(&run->debug.arch);
+break;
+#endif /* KVM_CAP_SET_GUEST_DEBUG */
 default:
 fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
 ret = -1;
-- 
1.7.1




[Qemu-devel] [PATCH 04/15] kvm: Add in-kernel irqchip awareness to cpu_thread_is_idle

2011-03-04 Thread Jan Kiszka
With in-kernel irqchip support enabled, the vcpu threads sleep in kernel
space while halted. Account for this difference in cpu_thread_is_idle.

Signed-off-by: Jan Kiszka 
---
 cpus.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/cpus.c b/cpus.c
index 0f33945..66f6b5a 100644
--- a/cpus.c
+++ b/cpus.c
@@ -147,7 +147,8 @@ static bool cpu_thread_is_idle(CPUState *env)
 if (env->stopped || !vm_running) {
 return true;
 }
-if (!env->halted || qemu_cpu_has_work(env)) {
+if (!env->halted || qemu_cpu_has_work(env) ||
+(kvm_enabled() && kvm_irqchip_in_kernel())) {
 return false;
 }
 return true;
-- 
1.7.1




[Qemu-devel] [PATCH 09/15] kvm: x86: Synchronize PAT MSR with the kernel

2011-03-04 Thread Jan Kiszka
Signed-off-by: Jan Kiszka 
---
 target-i386/kvm.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 6efa491..bfc8d66 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -861,6 +861,7 @@ static int kvm_put_msrs(CPUState *env, int level)
 kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
 kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
 kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
+kvm_msr_entry_set(&msrs[n++], MSR_PAT, env->pat);
 if (has_msr_star) {
 kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
 }
@@ -1113,6 +1114,7 @@ static int kvm_get_msrs(CPUState *env)
 msrs[n++].index = MSR_IA32_SYSENTER_CS;
 msrs[n++].index = MSR_IA32_SYSENTER_ESP;
 msrs[n++].index = MSR_IA32_SYSENTER_EIP;
+msrs[n++].index = MSR_PAT;
 if (has_msr_star) {
 msrs[n++].index = MSR_STAR;
 }
@@ -1168,6 +1170,9 @@ static int kvm_get_msrs(CPUState *env)
 case MSR_IA32_SYSENTER_EIP:
 env->sysenter_eip = msrs[i].data;
 break;
+case MSR_PAT:
+env->pat = msrs[i].data;
+break;
 case MSR_STAR:
 env->star = msrs[i].data;
 break;
-- 
1.7.1




[Qemu-devel] [PATCH 02/15] Redirect cpu_interrupt to callback handler

2011-03-04 Thread Jan Kiszka
This allows to override the interrupt handling of QEMU in system mode.
KVM will make use of it to set optimized handlers.

Signed-off-by: Jan Kiszka 
---
 cpu-all.h |   14 +-
 exec.c|4 +++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 4f4631d..5835cfa 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -790,7 +790,19 @@ extern CPUState *cpu_single_env;
 #define CPU_INTERRUPT_SIPI   0x800 /* SIPI pending. */
 #define CPU_INTERRUPT_MCE0x1000 /* (x86 only) MCE pending. */
 
-void cpu_interrupt(CPUState *s, int mask);
+#ifndef CONFIG_USER_ONLY
+typedef void (*CPUInterruptHandler)(CPUState *, int);
+
+extern CPUInterruptHandler cpu_interrupt_handler;
+
+static inline void cpu_interrupt(CPUState *s, int mask)
+{
+cpu_interrupt_handler(s, mask);
+}
+#else /* USER_ONLY */
+void cpu_interrupt(CPUState *env, int mask);
+#endif /* USER_ONLY */
+
 void cpu_reset_interrupt(CPUState *env, int mask);
 
 void cpu_exit(CPUState *s);
diff --git a/exec.c b/exec.c
index 09235bf..a733acd 100644
--- a/exec.c
+++ b/exec.c
@@ -1629,7 +1629,7 @@ static void cpu_unlink_tb(CPUState *env)
 
 #ifndef CONFIG_USER_ONLY
 /* mask must never be zero, except for A20 change call */
-void cpu_interrupt(CPUState *env, int mask)
+static void tcg_handle_interrupt(CPUState *env, int mask)
 {
 int old_mask;
 
@@ -1656,6 +1656,8 @@ void cpu_interrupt(CPUState *env, int mask)
 }
 }
 
+CPUInterruptHandler cpu_interrupt_handler = tcg_handle_interrupt;
+
 #else /* CONFIG_USER_ONLY */
 
 void cpu_interrupt(CPUState *env, int mask)
-- 
1.7.1




[Qemu-devel] Re: [V7 PATCH 3/9] virtio-9p: Provide chroot worker side interfaces

2011-03-04 Thread Stefan Hajnoczi
On Fri, Mar 4, 2011 at 9:25 AM, M. Mohan Kumar  wrote:
> +static int chroot_do_open(V9fsFileObjectRequest *request)
> +{
> +    int fd;
> +    fd = open(request->path.path, request->data.flags);
> +    if (fd < 0) {
> +        fd = -errno;
> +    }
> +    return fd;
> +}

How do access checks work without fsuid/fsgid being set?

Stefan



[Qemu-devel] Re: [V7 PATCH 7/9] virtio-9p: Support for creating special files

2011-03-04 Thread Stefan Hajnoczi
On Fri, Mar 4, 2011 at 9:25 AM, M. Mohan Kumar  wrote:
> +static int chroot_do_create_special(V9fsFileObjectRequest *request)
> +{
> +    int cur_uid, cur_gid;
> +    int retval = -1;
> +
> +    cur_uid = geteuid();
> +    cur_gid = getegid();
> +
> +    if (setfsuid(request->data.uid) < 0) {
> +        return -errno;
> +    }
> +    if (setfsgid(request->data.gid) < 0) {
> +        retval = -errno;
> +        goto unset_uid;
> +    }
> +
> +    switch (request->data.type) {
> +    case T_MKDIR:
> +        retval = mkdir(request->path.path, request->data.mode);
> +        break;
> +    case T_SYMLINK:
> +        retval = symlink(request->path.old_path, request->path.path);
> +        break;
> +    case T_LINK:
> +        retval = link(request->path.old_path, request->path.path);
> +        break;
> +    default:
> +        retval = mknod(request->path.path, request->data.mode,
> +                        request->data.dev);
> +        break;
> +    }
> +
> +    if (retval < 0) {
> +        retval = -errno;
> +    }
> +    setfsgid(cur_gid);
> +unset_uid:
> +    setfsuid(cur_uid);
> +    return retval;
> +}

It would be nice to take this one step further and move file create
and open here too.  The prototype we need is:

static int chroot_handle_request(V9fsFileObjectRequest *request, int *fd)
{
*fd = -1;

It returns 0 on success or -errno and *fd >= 0 if a file descriptor
was opened and -1 otherwise.

This function becomes the main request processing function called from
v9fs_chroot() and the switch statement there can be eliminated.

Sending the response back to QEMU then gets a cleaned up prototype:
chroot_sendfd(int chroot_sock, int result, int fd) where result is 0
on success or -errno and fd >= 0 if present or -1 if not.

> +int v9fs_create_special(FsContext *fs_ctx, V9fsFileObjectRequest *request)
> +{
> +    int retval, sock_error;
> +    qemu_mutex_lock(&fs_ctx->chroot_mutex);
> +    if (fs_ctx->chroot_ioerror) {
> +        retval = -EIO;
> +        goto unlock;
> +    }
> +    if (v9fs_write_request(fs_ctx->chroot_socket, request) < 0) {
> +        fs_ctx->chroot_ioerror = 1;
> +        retval = -EIO;
> +        goto unlock;
> +    }
> +    retval = v9fs_receivefd(fs_ctx->chroot_socket, &sock_error);
> +    if (retval < 0 && sock_error) {
> +        fs_ctx->chroot_ioerror = 1;
> +    }
> +unlock:
> +    qemu_mutex_unlock(&fs_ctx->chroot_mutex);
> +    return retval;
> +}

This function is a duplicate of v9fs_request().  Can't there be just
one function?

Stefan



Re: [Qemu-devel] [PATCH] vnc: tight: Fix crash after 2GB of output

2011-03-04 Thread Michael Tokarev
04.03.2011 11:56, Corentin Chary wrote:
>>>
>>> bytes = zstream->total_out - previous_out;
> 
> Good catch
> 
>> total_out isn't used by zlib internally, so if the resulting
>> "total" counter is not needed in qemu, we can just zero-out
>> the total_out in this function before calling zlib, and
>> use the resulting value directly as "bytes", without
>> saving its previous value in previous_out.  Something like
>> the attached patch does.
> 
> If you're certain that total_out is not used by zlib, could you also
> send a patch for zlib encoding please ? (vnc-enc-zlib.c)
> Thanks,

Yes, I noticed this too (the same code is in enc-zlib), and mentioned
this in my previous email.

The attached slightly different patch fixes both places and fixes
them for good (hopefully anyway).  Runtime-tested for the tight
case, but honestly, I didn't wait for 2G of output ;)

Thanks!

/mjt
fix 2Gb integer overflow in in VNC tight and zlib encodings

As found by Roland Dreier  (excellent
catch!), when amount of VNC compressed data produced by zlib
and sent to client exceeds 2Gb, integer overflow occurs because
currently, we calculate amount of data produced at each step by
comparing saved total_out with new total_out, and total_out is
something which grows without bounds.  Compare it with previous
avail_out instead of total_out, and leave total_out alone.

The same code is used in vnc-enc-tight.c and vnc-enc-zlib.c,
so fix both cases.

There, there's no actual need to save previous_out value, since
capacity-offset (which is how that value is calculated) stays
the same so it can be recalculated again after call to deflate(),
but whole thing becomes less readable this way.

Reported-by: Roland Dreier 
Signed-off-by: Michael Tokarev 

diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 2522936..87fdf35 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -868,8 +868,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
 zstream->avail_in = vs->tight.tight.offset;
 zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset;
 zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset;
+previous_out = zstream->avail_out;
 zstream->data_type = Z_BINARY;
-previous_out = zstream->total_out;
 
 /* start encoding */
 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -878,7 +878,8 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
 }
 
 vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out;
-bytes = zstream->total_out - previous_out;
+/* ...how much data has actually been produced by deflate() */
+bytes = previous_out - zstream->avail_out;
 
 tight_send_compact_size(vs, bytes);
 vnc_write(vs, vs->tight.zlib.buffer, bytes);
diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
index 3c6e6ab..e32e4cd 100644
--- a/ui/vnc-enc-zlib.c
+++ b/ui/vnc-enc-zlib.c
@@ -103,8 +103,8 @@ static int vnc_zlib_stop(VncState *vs)
 zstream->avail_in = vs->zlib.zlib.offset;
 zstream->next_out = vs->output.buffer + vs->output.offset;
 zstream->avail_out = vs->output.capacity - vs->output.offset;
+previous_out = zstream->avail_out;
 zstream->data_type = Z_BINARY;
-previous_out = zstream->total_out;
 
 // start encoding
 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -113,7 +113,7 @@ static int vnc_zlib_stop(VncState *vs)
 }
 
 vs->output.offset = vs->output.capacity - zstream->avail_out;
-return zstream->total_out - previous_out;
+return previous_out - zstream->avail_out;
 }
 
 int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)


[Qemu-devel] Re: [V7 PATCH 9/9] virtio-9p: Chroot environment for other functions

2011-03-04 Thread Stefan Hajnoczi
On Fri, Mar 4, 2011 at 9:25 AM, M. Mohan Kumar  wrote:
> Add chroot functionality for systemcalls that can operate on a file
> using relative directory file descriptor.
>
> Signed-off-by: M. Mohan Kumar 
> ---
>  hw/9pfs/virtio-9p-local.c |  229 
> +++--
>  1 files changed, 199 insertions(+), 30 deletions(-)

Is this code supposed to build on non-Linux hosts?  If so, then please
confirm that the *at() system calls used are standard and available on
other hosts (e.g. FreeBSD, Darwin, Solaris).

> +/*
> + * Returns file descriptor of dirname(path)
> + * This fd can be used by *at functions
> + */
> +static int get_dirfd(FsContext *fs_ctx, const char *path)
> +{
> +    V9fsFileObjectRequest request;
> +    int fd;
> +    char *dpath = qemu_strdup(path);
> +
> +    fd = fill_fileobjectrequest(&request, dirname(dpath), NULL);
> +    if (fd < 0) {
> +        return fd;
> +    }

Leaks dpath, fails to set errno, and does not return -1.

> @@ -545,53 +621,146 @@ static int local_link(FsContext *fs_ctx, const char 
> *oldpath,
>
>  static int local_truncate(FsContext *ctx, const char *path, off_t size)
>  {
> -    return truncate(rpath(ctx, path), size);
> +    if (ctx->fs_sm == SM_PASSTHROUGH) {
> +        int fd, retval;
> +        fd = passthrough_open(ctx, path, O_RDWR);
> +        if (fd < 0) {
> +            return -1;
> +        }
> +        retval = ftruncate(fd, size);
> +        close(fd);
> +        return retval;

This is an example of where errno is not guaranteed to be preserved.
When ftruncate(2) fails close(2) is allowed to affect errno and we
cannot rely on it holding the ftruncate(2) error code.  Please check
for other cases of this.

>  static int local_rename(FsContext *ctx, const char *oldpath,
>                         const char *newpath)
>  {
> -    char *tmp;
> -    int err;
> -
> -    tmp = qemu_strdup(rpath(ctx, oldpath));
> +    int err, serrno = 0;
>
> -    err = rename(tmp, rpath(ctx, newpath));
> -    if (err == -1) {
> -        int serrno = errno;
> -        qemu_free(tmp);
> +    if (ctx->fs_sm == SM_PASSTHROUGH) {
> +        int opfd, npfd;
> +        char *old_tmppath, *new_tmppath;
> +        opfd = get_dirfd(ctx, oldpath);
> +        if (opfd < 0) {
> +            return -1;
> +        }
> +        npfd = get_dirfd(ctx, newpath);
> +        if (npfd < 0) {
> +            close(opfd);
> +            return -1;
> +        }
> +        old_tmppath = qemu_strdup(oldpath);
> +        new_tmppath = qemu_strdup(newpath);
> +        err = renameat(opfd, basename(old_tmppath),
> +                        npfd, basename(new_tmppath));
> +        if (err == -1) {
> +            serrno = errno;
> +        }
> +        close(npfd);
> +        close(opfd);
> +        qemu_free(old_tmppath);
> +        qemu_free(new_tmppath);
>         errno = serrno;

Why can't this be done as a chroot worker operation in a single syscall?

> -static int local_utimensat(FsContext *s, const char *path,
> -                           const struct timespec *buf)
> +static int local_utimensat(FsContext *fs_ctx, const char *path,
> +                const struct timespec *buf)
>  {
> -    return qemu_utimensat(AT_FDCWD, rpath(s, path), buf, 
> AT_SYMLINK_NOFOLLOW);
> +    if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
> +        int fd, retval;
> +        fd = passthrough_open(fs_ctx, path, O_RDONLY | O_NONBLOCK);

This follows symlinks but the SM_PASSTHROUGH case below does not?

> +        if (fd < 0) {
> +            return -1;
> +        }
> +        retval = futimens(fd, buf);
> +        close(fd);
> +        return retval;
> +    } else {
> +        return utimensat(AT_FDCWD, rpath(fs_ctx, path), buf,
> +                        AT_SYMLINK_NOFOLLOW);
> +    }
>  }
>
> -static int local_remove(FsContext *ctx, const char *path)
> -{
> -    return remove(rpath(ctx, path));
> +static int local_remove(FsContext *fs_ctx, const char *path)
> + {
> +    if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
> +        int pfd, err, serrno, flags;
> +        char *old_path;
> +        struct stat stbuf;
> +        pfd = get_dirfd(fs_ctx, path);
> +        if (pfd < 0) {
> +            return -1;
> +        }
> +        old_path = qemu_strdup(path);
> +        err = fstatat(pfd, basename(old_path), &stbuf, AT_SYMLINK_NOFOLLOW);
> +        if (err < 0) {

old_path and pfd are leaked.

> +            return -1;
> +        }
> +        serrno = flags = 0;
> +        if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
> +            flags = AT_REMOVEDIR;
> +        } else {
> +            flags = 0;
> +        }
> +        err = unlinkat(pfd, basename(old_path), flags);
> +        if (err == -1) {
> +            serrno = errno;
> +        }
> +        qemu_free(old_path);
> +        close(pfd);
> +        errno = serrno;
> +        return err;

Why is SM_PASSTHROUGH so complicated...

> +    } else {
> +        return remove(rpath(fs_ctx, path));

...but this so simple?

Could we just send a remove operation to the chr

[Qemu-devel] [Bug 551545] Re: PXE netboot not booting localboot from virtio-disk

2011-03-04 Thread Reinhard Tartler
lucid-updates and lucid-proposed ship the same package and from the
changelog I cannot see what change would be related to this big.

I've just confirmed by testing that the bug still applies to the most
uptodate packages that are available for lucid.

** Changed in: qemu-kvm (Ubuntu)
   Status: Incomplete => Triaged

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/551545

Title:
  PXE netboot not booting localboot from virtio-disk

Status in QEMU:
  New
Status in “qemu-kvm” package in Ubuntu:
  Triaged
Status in “qemu-kvm” package in Fedora:
  Unknown

Bug description:
  Binary package hint: qemu-kvm

  lsb_release -rd
  Description:  Ubuntu lucid (development branch)
  Release:  10.04

  apt-cache policy qemu-kvm
  qemu-kvm:
Installiert: 0.12.3+noroms-0ubuntu3
Kandidat: 0.12.3+noroms-0ubuntu3
Versions-Tabelle:
   *** 0.12.3+noroms-0ubuntu3 0
  500 http://intranet/ubuntu/ lucid/main Packages
  100 /var/lib/dpkg/status

  Description of the problem:

  Starting a guest like this:

  vdekvm \
-m 256M \
-cpu host \
-smp 1 \
-name karmic \
-boot order=nc \
-drive file=/dev/vg01/test,if=virtio,boot=on,cache=none \
-net nic,vlan=0,macaddr=00:2f:8d:b6:cf:d0,model=virtio \
-net vde,vlan=0,sock=/var/run/vde2/vde0.ctl \
-watchdog i6300esb \
-vnc :0 \
-serial telnet:localhost:23,server,nowait \
-monitor tcp:127.0.0.1:12000,server,nowait \
-runas kvmguest

  On "telnet localhost" you can see that the following boot-menu
  appears:

  - Boot Menu -
  =

  local
  rescue

  It is loaded from this pxelinux.cfg/default file:

  SERIAL 0 9600n8

  DISPLAY boot.txt

  TIMEOUT 120
  DEFAULT local
  PROMPT 1

  LABEL local
localboot 0

  LABEL rescue
kernel lucid
append initrd=lucid-initrd.gz rescue/enable=true -- quiet 
console=ttyS0,9600n8

  
  After the timeout, the guest tries to boot, but fails and reloads the boot 
menu. This is an endless loop, until I break it or choose the rescue menu entry.

  I would expect that it boots from first virtio-disk

  ProblemType: Bug
  DistroRelease: Ubuntu 10.04
  Package: qemu-kvm 0.12.3+noroms-0ubuntu3
  ProcVersionSignature: Ubuntu 2.6.32-18.27-generic 2.6.32.10+drm33.1
  Uname: Linux 2.6.32-18-generic x86_64
  Architecture: amd64
  Date: Tue Mar 30 11:40:59 2010
  ExecutablePath: /usr/bin/qemu-system-x86_64
  MachineType: MICRO-STAR INTERANTIONAL CO.,LTD MS-7368
  ProcCmdLine: root=UUID=0d27271c-feaa-40d9-bbbd-baff4ca1d3cc rw init=/bin/bash
  ProcEnviron:
   LANG=de_DE.UTF-8
   SHELL=/bin/bash
  SourcePackage: qemu-kvm
  dmi.bios.date: 10/31/2007
  dmi.bios.vendor: American Megatrends Inc.
  dmi.bios.version: V1.5B2
  dmi.board.asset.tag: To Be Filled By O.E.M.
  dmi.board.name: MS-7368
  dmi.board.vendor: MICRO-STAR INTERANTIONAL CO.,LTD
  dmi.board.version: 1.0
  dmi.chassis.asset.tag: To Be Filled By O.E.M.
  dmi.chassis.type: 3
  dmi.chassis.vendor: To Be Filled By O.E.M.
  dmi.chassis.version: To Be Filled By O.E.M.
  dmi.modalias: 
dmi:bvnAmericanMegatrendsInc.:bvrV1.5B2:bd10/31/2007:svnMICRO-STARINTERANTIONALCO.,LTD:pnMS-7368:pvr1.0:rvnMICRO-STARINTERANTIONALCO.,LTD:rnMS-7368:rvr1.0:cvnToBeFilledByO.E.M.:ct3:cvrToBeFilledByO.E.M.:
  dmi.product.name: MS-7368
  dmi.product.version: 1.0
  dmi.sys.vendor: MICRO-STAR INTERANTIONAL CO.,LTD



Re: [Qemu-devel] [PATCH] vnc: tight: Fix crash after 2GB of output

2011-03-04 Thread Roland Dreier
On Thu, Mar 3, 2011 at 11:34 PM, Michael Tokarev  wrote:
>> The fix for this is simple: keep previous_out as a uLong too, which
>> avoids any problems with sign conversion or truncation.
>
> This looks wrong to me.  On 32bit x86 uLong is 32bits.  Yes
> it's unsigned there, but it's still 32bits.  And sure thing
> it _will_ overflow again, not at 2Gb but now at 4Gb, and the
> next total_out will start from zero again, so that now bytes
> will be a large integer again because "next" (new total_out)
> will be less than "current" (previous_out).

Actually there is no problem with overflow of unsigned long.
The C standard says that unsigned arithmetic is simply done
modulo the size of the integer, so when total_out reaches
4GB, things will just wrap around (and the difference
between "nearby" values will still be the correct, small
value).  For example, if previous were (4GB - 5) and
then total_out had 1000 added to it, total_out would
end up as 995, and total_out - previous would be 1000.

In other words I'm pretty sure my fix works on 32 bits too.

However your fix using avail_out is probably better anyway,
and your latest patch fixes both instances of the bug, so
we might as well go with that.

Thanks,
 - R.



[Qemu-devel] Re: [PATCH] vnc: Fix stack corruption and other bitmap related bugs

2011-03-04 Thread Stefan Weil

Am 04.03.2011 10:02, schrieb Corentin Chary:

On Thu, Mar 3, 2011 at 9:37 PM, Stefan Weil  wrote:

Commit bc2429b9174ac2d3c56b7fd35884b0d89ec7fb02 introduced
a severe bug (stack corruption).

bitmap_clear was called with a wrong argument
which caused out-of-bound writes to the local variable width_mask.

This bug was detected with QEMU running on windows.
It also occurs with wine:

*** stack smashing detected ***:  terminated
wine: Unhandled illegal instruction at address 0x6115c7 (thread 
0009), starting debugger...


The bug is not windows specific!

Instead of fixing the wrong parameter value, bitmap_clear(), bitmap_set
and width_mask were removed, and bitmap_intersect() was replaced by
!bitmap_empty(). The new operation is much shorter and equivalent to
the old operations.

The declarations of the dirty bitmaps in vnc.h were also wrong for 64 bit
hosts because of a rounding effect: for these hosts, VNC_MAX_WIDTH is no
longer a multiple of (16 * BITS_PER_LONG), so the rounded value of
VNC_DIRTY_WORDS was too small.

Fix both declarations by using the macro which is designed for this
purpose.

Cc: Corentin Chary 
Cc: Wen Congyang 
Cc: Gerhard Wiesinger 
Cc: Anthony Liguori 
Signed-off-by: Stefan Weil 
---
 ui/vnc.c |6 +-
 ui/vnc.h |9 ++---
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 610f884..34dc0cd 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2383,7 +2383,6 @@ static int 
vnc_refresh_server_surface(VncDisplay *vd)

uint8_t *guest_row;
uint8_t *server_row;
int cmp_bytes;
-unsigned long width_mask[VNC_DIRTY_WORDS];
VncState *vs;
int has_dirty = 0;

@@ -2399,14 +2398,11 @@ static int 
vnc_refresh_server_surface(VncDisplay *vd)

 * Check and copy modified bits from guest to server surface.
 * Update server dirty map.
 */
-bitmap_set(width_mask, 0, (ds_get_width(vd->ds) / 16));
-bitmap_clear(width_mask, (ds_get_width(vd->ds) / 16),
- VNC_DIRTY_WORDS * BITS_PER_LONG);
cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
guest_row  = vd->guest.ds->data;
server_row = vd->server->data;
for (y = 0; y < vd->guest.ds->height; y++) {
-if (bitmap_intersects(vd->guest.dirty[y], width_mask, 
VNC_DIRTY_WORDS)) {

+if (!bitmap_empty(vd->guest.dirty[y], VNC_DIRTY_BITS)) {
int x;
uint8_t *guest_ptr;
uint8_t *server_ptr;
diff --git a/ui/vnc.h b/ui/vnc.h
index 8a1e7b9..f10c5dc 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -79,9 +79,12 @@ typedef void VncSendHextileTile(VncState *vs,
void *last_fg,
int *has_bg, int *has_fg);

+/* VNC_MAX_WIDTH must be a multiple of 16. */
 #define VNC_MAX_WIDTH 2560
 #define VNC_MAX_HEIGHT 2048
-#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * BITS_PER_LONG))
+
+/* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */
+#define VNC_DIRTY_BITS (VNC_MAX_WIDTH / 16)

 #define VNC_STAT_RECT  64
 #define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
@@ -114,7 +117,7 @@ typedef struct VncRectStat VncRectStat;
 struct VncSurface
 {
struct timeval last_freq_check;
-unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
+DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16);
VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
DisplaySurface *ds;
 };
@@ -234,7 +237,7 @@ struct VncState
int csock;

DisplayState *ds;
-unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
+DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS);
uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
   * vnc-jobs-async.c */

--
1.7.2.3




Hi,
Thanks, this patch is a lot cleaner that my early port to new
bitmap/bitops operations.
This patch fix all previous bugs, but not the
framebuffer_update_request + !incremental bug right ?


Hi,

I think so, but I'm not sure about the framebuffer_update_request bug.

At least my patch fixes the most urgent failures (stack corruption),
so I hope it will be applied to git master asap.

There remain more vnc related bugs. Just a short summary of those
which I am aware of:

* Screen update in tight mode has problems (wrong colors, parts missing).

* The threaded vnc server obviously has reentrancy problems (corruption
  of malloc'ed memory. I also noticed memory leaks but maybe these were
  fixed by a patch whcih I noticed on qemu-devel recently.

* The vnc server should not abort connections when it gets unknown commands.

* In reverse mode, the gui is no longer accessible if the vnc listener 
terminates.


Regards,
Stefan




[Qemu-devel] Fedora Virt Status

2011-03-04 Thread Justin M. Forbes
Fedora 14
- We have 90 open bugs, 9 of which have fixes in awaiting updates.
- 4 bugs have been closed in the last week

Fedora 15
- Upcoming Deadlines:
  2011-03-15  Software Translation Deadline
  2011-03-22  Beta Change Deadline Features 100% Complete
  2011-04-05  Beta Release
  2011-04-25  Final Change Deadline
  2011-04-26  Compose 'Final' RC
  2011-05-10  Fedora 15 Final Release

- Virtualization Test Day is coming up on Thursday, April 14th.  Please
  mark your calendars, and join us for testing and bug hunting.  The more
  we can uncover before release, the better off we are.

- There are currently 59 bugs open against rawhide/F15.

 == Updates Needing review ==
  The following packages are in updates-testing and need review and karma as
  appropriate:

  F13:
  - qemu-0.13.0-1.fc13
A large number of bug fixes and many patches dropped that have been
upstreamed.

  F15:
  - qemu-0.14.0-2.fc15
Updated to 0.14.0 final release and re-enabled cris and sparc emulation

  == Virt Preview Repository ==
  The virt-preview repository is now active for F14 users wishing to run the
  latest F15 virt packages on their stable F14 systems.  F13 virt-preview users
  will still get the latest F14 packages.  For details on how to run enable 
  virt-preview, please see:
  https://fedoraproject.org/wiki/Virtualization_Preview_Repository

  == Bugs of importance: ==
- 679179 Openbios-ppc subpackage disappeared
  openbios is not building correctly on ppc right now.  This has to be fixed
  as openbios-ppc is an install dependency for qemu-system-ppc

- 681220 Virtual machines using the qxl driver crash
  Reports of qemu crashing when using the qxl driver with spice.  A patch
  has been posted and will make the next build.




Re: [Qemu-devel] [PATCH] vnc: tight: Fix crash after 2GB of output

2011-03-04 Thread Roland Dreier
On Fri, Mar 4, 2011 at 8:59 AM, Roland Dreier  wrote:
> Actually there is no problem with overflow of unsigned long.
> The C standard says that unsigned arithmetic is simply done
> modulo the size of the integer, so when total_out reaches
> 4GB, things will just wrap around (and the difference
> between "nearby" values will still be the correct, small
> value).  For example, if previous were (4GB - 5) and
> then total_out had 1000 added to it, total_out would
> end up as 995, and total_out - previous would be 1000.

Additionally, thinking about this further, I realize that
amusingly enough, the old code also works on 32-bit:
the bug occurred because when we put a value above
2GB in a (32-bit) int, it became a signed quantity,
which then became a gigantic value when promoted
back to an unsigned (64-bit) long, which causes the
subtraction to get the wrong value.  On 32-bit, the
promotion from signed 32-bit to unsigned 32-bit
doesn't lead to the wrong difference.

 - R.



[Qemu-devel] Re: [fedora-virt] Fedora Virt Status

2011-03-04 Thread Richard W.M. Jones
On Fri, Mar 04, 2011 at 12:45:54PM -0600, Justin M. Forbes wrote:
>   F15:
>   - qemu-0.14.0-2.fc15
> Updated to 0.14.0 final release and re-enabled cris and sparc emulation

A change in the command-line parsing code in qemu-img causes
virt-make-fs to break (because of a latent bug in virt-make-fs).  Here
is the upstream fix:

http://git.annexia.org/?p=libguestfs.git;a=commitdiff;h=eda9826d25336bcf661700270c580d4d62128750

I haven't (yet) backported this to F15.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw



[Qemu-devel] [PATCH v2 0/2] ARM: Add Versatile Express board model

2011-03-04 Thread Peter Maydell
This patchset adds support for the ARM Versatile Express board
with Cortex-A9 daughterboard. It's based on some vexpress modelling
work done by Bahadir Balban and Amit Mahajan at B Labs, overhauled
and cleaned up by me (thanks to them for making that work available).

The patchset depends on the MMC cleanup work I posted last week:
http://www.mail-archive.com/qemu-devel@nongnu.org/msg56148.html
as it wants to wire up the MMC status lines.

Changes since v1:
 bump the vmstate version on arm_sysctl, as suggested by Juan Quintela

Peter Maydell (2):
  hw/arm_sysctl.c: Add the Versatile Express system registers
  hw/vexpress.c: Add model of ARM Versatile Express board

 Makefile.target |1 +
 hw/arm_sysctl.c |   65 +++-
 hw/vexpress.c   |  238 +++
 3 files changed, 302 insertions(+), 2 deletions(-)
 create mode 100644 hw/vexpress.c




[Qemu-devel] [PATCH v2 1/2] hw/arm_sysctl.c: Add the Versatile Express system registers

2011-03-04 Thread Peter Maydell
Add support for the Versatile Express SYS_CFG registers, which provide
a generic means of reading or writing configuration information from
various parts of the board. We only implement shutdown and reset.

Also make the RESETCTL register RAZ/WI on Versatile Express rather
than reset the board. Other system registers are generally the same
as Versatile and Realview.

This includes a VMState version number bump for arm_sysctl,
since we have new register state to preserve.

Signed-off-by: Peter Maydell 
---
 hw/arm_sysctl.c |   65 +-
 1 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 799b007..e4a17f5 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -27,12 +27,15 @@ typedef struct {
 uint32_t resetlevel;
 uint32_t proc_id;
 uint32_t sys_mci;
+uint32_t sys_cfgdata;
+uint32_t sys_cfgctrl;
+uint32_t sys_cfgstat;
 } arm_sysctl_state;
 
 static const VMStateDescription vmstate_arm_sysctl = {
 .name = "realview_sysctl",
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (VMStateField[]) {
 VMSTATE_UINT32(leds, arm_sysctl_state),
 VMSTATE_UINT16(lockval, arm_sysctl_state),
@@ -41,6 +44,9 @@ static const VMStateDescription vmstate_arm_sysctl = {
 VMSTATE_UINT32(flags, arm_sysctl_state),
 VMSTATE_UINT32(nvflags, arm_sysctl_state),
 VMSTATE_UINT32(resetlevel, arm_sysctl_state),
+VMSTATE_UINT32(sys_cfgdata, arm_sysctl_state),
+VMSTATE_UINT32(sys_cfgctrl, arm_sysctl_state),
+VMSTATE_UINT32(sys_cfgstat, arm_sysctl_state),
 VMSTATE_END_OF_LIST()
 }
 };
@@ -53,6 +59,7 @@ static const VMStateDescription vmstate_arm_sysctl = {
 #define BOARD_ID_EB 0x140
 #define BOARD_ID_PBA8 0x178
 #define BOARD_ID_PBX 0x182
+#define BOARD_ID_VEXPRESS 0x190
 
 static int board_id(arm_sysctl_state *s)
 {
@@ -104,6 +111,10 @@ static uint32_t arm_sysctl_read(void *opaque, 
target_phys_addr_t offset)
 case 0x38: /* NVFLAGS */
 return s->nvflags;
 case 0x40: /* RESETCTL */
+if (board_id(s) == BOARD_ID_VEXPRESS) {
+/* reserved: RAZ/WI */
+return 0;
+}
 return s->resetlevel;
 case 0x44: /* PCICTL */
 return 1;
@@ -142,7 +153,23 @@ static uint32_t arm_sysctl_read(void *opaque, 
target_phys_addr_t offset)
 case 0xcc: /* SYS_TEST_OSC3 */
 case 0xd0: /* SYS_TEST_OSC4 */
 return 0;
+case 0xa0: /* SYS_CFGDATA */
+if (board_id(s) != BOARD_ID_VEXPRESS) {
+goto bad_reg;
+}
+return s->sys_cfgdata;
+case 0xa4: /* SYS_CFGCTRL */
+if (board_id(s) != BOARD_ID_VEXPRESS) {
+goto bad_reg;
+}
+return s->sys_cfgctrl;
+case 0xa8: /* SYS_CFGSTAT */
+if (board_id(s) != BOARD_ID_VEXPRESS) {
+goto bad_reg;
+}
+return s->sys_cfgstat;
 default:
+bad_reg:
 printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);
 return 0;
 }
@@ -190,6 +217,10 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 s->nvflags &= ~val;
 break;
 case 0x40: /* RESETCTL */
+if (board_id(s) == BOARD_ID_VEXPRESS) {
+/* reserved: RAZ/WI */
+break;
+}
 if (s->lockval == LOCK_VALUE) {
 s->resetlevel = val;
 if (val & 0x100)
@@ -216,7 +247,37 @@ static void arm_sysctl_write(void *opaque, 
target_phys_addr_t offset,
 case 0x98: /* OSCRESET3 */
 case 0x9c: /* OSCRESET4 */
 break;
+case 0xa0: /* SYS_CFGDATA */
+if (board_id(s) != BOARD_ID_VEXPRESS) {
+goto bad_reg;
+}
+s->sys_cfgdata = val;
+return;
+case 0xa4: /* SYS_CFGCTRL */
+if (board_id(s) != BOARD_ID_VEXPRESS) {
+goto bad_reg;
+}
+s->sys_cfgctrl = val & ~(3 << 18);
+s->sys_cfgstat = 1;/* complete */
+switch (s->sys_cfgctrl) {
+case 0xc080:/* SYS_CFG_SHUTDOWN to motherboard */
+qemu_system_shutdown_request();
+break;
+case 0xc090:/* SYS_CFG_REBOOT to motherboard */
+qemu_system_reset_request();
+break;
+default:
+s->sys_cfgstat |= 2;/* error */
+}
+return;
+case 0xa8: /* SYS_CFGSTAT */
+if (board_id(s) != BOARD_ID_VEXPRESS) {
+goto bad_reg;
+}
+s->sys_cfgstat = val & 3;
+return;
 default:
+bad_reg:
 printf ("arm_sysctl_write: Bad register offset 0x%x\n", (int)offset);
 return;
 }
-- 
1.7.1




[Qemu-devel] [PATCH v2 2/2] hw/vexpress.c: Add model of ARM Versatile Express board

2011-03-04 Thread Peter Maydell
Add a model of the ARM Versatile Express board (with A9MPx4
daughterboard).

Signed-off-by: Peter Maydell 
---
 Makefile.target |1 +
 hw/vexpress.c   |  238 +++
 2 files changed, 239 insertions(+), 0 deletions(-)
 create mode 100644 hw/vexpress.c

diff --git a/Makefile.target b/Makefile.target
index 220589e..949bd4e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -315,6 +315,7 @@ obj-arm-y += framebuffer.o
 obj-arm-y += syborg.o syborg_fb.o syborg_interrupt.o syborg_keyboard.o
 obj-arm-y += syborg_serial.o syborg_timer.o syborg_pointer.o syborg_rtc.o
 obj-arm-y += syborg_virtio.o
+obj-arm-y += vexpress.o
 
 obj-sh4-y = shix.o r2d.o sh7750.o sh7750_regnames.o tc58128.o
 obj-sh4-y += sh_timer.o sh_serial.o sh_intc.o sh_pci.o sm501.o
diff --git a/hw/vexpress.c b/hw/vexpress.c
new file mode 100644
index 000..1ed3578
--- /dev/null
+++ b/hw/vexpress.c
@@ -0,0 +1,238 @@
+/*
+ * ARM Versatile Express emulation.
+ *
+ * Copyright (c) 2010 - 2011 B Labs Ltd.
+ * Copyright (c) 2011 Linaro Limited
+ * Written by Bahadir Balban, Amit Mahajan, Peter Maydell
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see .
+ */
+
+#include "sysbus.h"
+#include "arm-misc.h"
+#include "primecell.h"
+#include "devices.h"
+#include "net.h"
+#include "sysemu.h"
+#include "boards.h"
+
+#define SMP_BOOT_ADDR 0xe000
+
+#define VEXPRESS_BOARD_ID 0x8e0
+
+static struct arm_boot_info vexpress_binfo = {
+.smp_loader_start = SMP_BOOT_ADDR,
+};
+
+static void secondary_cpu_reset(void *opaque)
+{
+  CPUState *env = opaque;
+
+  cpu_reset(env);
+  /* Set entry point for secondary CPUs.  This assumes we're using
+ the init code from arm_boot.c.  Real hardware resets all CPUs
+ the same.  */
+  env->regs[15] = SMP_BOOT_ADDR;
+}
+
+static void vexpress_a9_init(ram_addr_t ram_size,
+ const char *boot_device,
+ const char *kernel_filename, const char *kernel_cmdline,
+ const char *initrd_filename, const char *cpu_model)
+{
+CPUState *env = NULL;
+ram_addr_t ram_offset, vram_offset, sram_offset;
+DeviceState *dev, *sysctl;
+SysBusDevice *busdev;
+qemu_irq *irqp;
+qemu_irq pic[64];
+int n;
+qemu_irq cpu_irq[4];
+uint32_t proc_id;
+uint32_t sys_id;
+ram_addr_t low_ram_size, vram_size, sram_size;
+
+if (!cpu_model) {
+cpu_model = "cortex-a9";
+}
+
+for (n = 0; n < smp_cpus; n++) {
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+irqp = arm_pic_init_cpu(env);
+cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+if (n > 0) {
+qemu_register_reset(secondary_cpu_reset, env);
+}
+}
+
+if (ram_size > 0x4000) {
+/* 1GB is the maximum the address space permits */
+fprintf(stderr, "vexpress: cannot model more than 1GB RAM\n");
+exit(1);
+}
+
+ram_offset = qemu_ram_alloc(NULL, "vexpress.highmem", ram_size);
+low_ram_size = ram_size;
+if (low_ram_size > 0x400) {
+low_ram_size = 0x400;
+}
+/* RAM is from 0x6000 upwards. The bottom 64MB of the
+ * address space should in theory be remappable to various
+ * things including ROM or RAM; we always map the RAM there.
+ */
+cpu_register_physical_memory(0x0, low_ram_size, ram_offset | IO_MEM_RAM);
+cpu_register_physical_memory(0x6000, ram_size,
+ ram_offset | IO_MEM_RAM);
+
+/* 0x1e00 A9MPCore (SCU) private memory region */
+dev = qdev_create(NULL, "a9mpcore_priv");
+qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
+qdev_init_nofail(dev);
+busdev = sysbus_from_qdev(dev);
+vexpress_binfo.smp_priv_base = 0x1e00;
+sysbus_mmio_map(busdev, 0, vexpress_binfo.smp_priv_base);
+for (n = 0; n < smp_cpus; n++) {
+sysbus_connect_irq(busdev, n, cpu_irq[n]);
+}
+/* Interrupts [42:0] are from the motherboard;
+ * [47:43] are reserved; [63:48] are daughterboard
+ * peripherals. Note that some documentation numbers
+ * external interrupts starting from 32 (because the
+ * A9MP has internal interrupts 0..31).
+ */
+for (n = 0; n < 64; n++) {
+pic[n] = qdev_get_gpio_in(dev, n);
+}
+
+/* Motherboard peripherals CS7 : 0x1000 .. 0x1002 */

Re: [Qemu-devel] [PATCH] vnc: tight: Fix crash after 2GB of output

2011-03-04 Thread Corentin Chary
On Fri, Mar 4, 2011 at 12:46 PM, Michael Tokarev  wrote:
> 04.03.2011 11:56, Corentin Chary wrote:

     bytes = zstream->total_out - previous_out;
>>
>> Good catch
>>
>>> total_out isn't used by zlib internally, so if the resulting
>>> "total" counter is not needed in qemu, we can just zero-out
>>> the total_out in this function before calling zlib, and
>>> use the resulting value directly as "bytes", without
>>> saving its previous value in previous_out.  Something like
>>> the attached patch does.
>>
>> If you're certain that total_out is not used by zlib, could you also
>> send a patch for zlib encoding please ? (vnc-enc-zlib.c)
>> Thanks,
>
> Yes, I noticed this too (the same code is in enc-zlib), and mentioned
> this in my previous email.
>
> The attached slightly different patch fixes both places and fixes
> them for good (hopefully anyway).  Runtime-tested for the tight
> case, but honestly, I didn't wait for 2G of output ;)
>
> Thanks!
>
> /mjt
>

Could you re-send it inline (not as an attachment), and CC Anthony ?
Thanks,

-- 
Corentin Chary
http://xf.iksaif.net



[Qemu-devel] [PATCH][STABLE-0.14] vnc: tight: Fix crash after 2GB of output

2011-03-04 Thread Michael Tokarev
05.03.2011 00:08, Corentin Chary wrote:
> On Fri, Mar 4, 2011 at 12:46 PM, Michael Tokarev  wrote:
[]
>> The attached slightly different patch fixes both places and fixes
>> them for good (hopefully anyway).  Runtime-tested for the tight
>> case, but honestly, I didn't wait for 2G of output ;)
>>
> Could you re-send it inline (not as an attachment), and CC Anthony ?

What's wrong with using an attachment?  The whole email can be
fed into patch(1) (or git-am, whatever) and either will do the
job.  But here it goes, anyway, with one possible caveat - I'm
not sure anymore it will apply, since now I used cut-n-paste.

/mjt



fix 2Gb integer overflow in in VNC tight and zlib encodings

As found by Roland Dreier  (excellent
catch!), when amount of VNC compressed data produced by zlib
and sent to client exceeds 2Gb, integer overflow occurs because
currently, we calculate amount of data produced at each step by
comparing saved total_out with new total_out, and total_out is
something which grows without bounds.  Compare it with previous
avail_out instead of total_out, and leave total_out alone.

The same code is used in vnc-enc-tight.c and vnc-enc-zlib.c,
so fix both cases.

There, there's no actual need to save previous_out value, since
capacity-offset (which is how that value is calculated) stays
the same so it can be recalculated again after call to deflate(),
but whole thing becomes less readable this way.

Reported-by: Roland Dreier 
Signed-off-by: Michael Tokarev 

diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 2522936..87fdf35 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -868,8 +868,8 @@ static int tight_compress_data(VncState *vs, int stream_id, 
size_t bytes,
 zstream->avail_in = vs->tight.tight.offset;
 zstream->next_out = vs->tight.zlib.buffer + vs->tight.zlib.offset;
 zstream->avail_out = vs->tight.zlib.capacity - vs->tight.zlib.offset;
+previous_out = zstream->avail_out;
 zstream->data_type = Z_BINARY;
-previous_out = zstream->total_out;

 /* start encoding */
 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -878,7 +878,8 @@ static int tight_compress_data(VncState *vs, int stream_id, 
size_t bytes,
 }

 vs->tight.zlib.offset = vs->tight.zlib.capacity - zstream->avail_out;
-bytes = zstream->total_out - previous_out;
+/* ...how much data has actually been produced by deflate() */
+bytes = previous_out - zstream->avail_out;

 tight_send_compact_size(vs, bytes);
 vnc_write(vs, vs->tight.zlib.buffer, bytes);
diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
index 3c6e6ab..e32e4cd 100644
--- a/ui/vnc-enc-zlib.c
+++ b/ui/vnc-enc-zlib.c
@@ -103,8 +103,8 @@ static int vnc_zlib_stop(VncState *vs)
 zstream->avail_in = vs->zlib.zlib.offset;
 zstream->next_out = vs->output.buffer + vs->output.offset;
 zstream->avail_out = vs->output.capacity - vs->output.offset;
+previous_out = zstream->avail_out;
 zstream->data_type = Z_BINARY;
-previous_out = zstream->total_out;

 // start encoding
 if (deflate(zstream, Z_SYNC_FLUSH) != Z_OK) {
@@ -113,7 +113,7 @@ static int vnc_zlib_stop(VncState *vs)
 }

 vs->output.offset = vs->output.capacity - zstream->avail_out;
-return zstream->total_out - previous_out;
+return previous_out - zstream->avail_out;
 }

 int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)



[Qemu-devel] accessing host system

2011-03-04 Thread Don Raikes
Hello,

I am new to qemu, but have a specific application in mind.

I want to use a qemu emulated knopix system on a usb key to do diagnostics on a 
running windows system.

Is there a way for me to access things like the host system's memory to get a 
dump of it, host system hardware configuration so I can gain a map of what 
hardware is in the system, and/or what processes are running on the host system?

I know how to do all this from a system that has been rebooted and is running 
from a linux liveCd, but I want to make this a plug-and-play test system.

Any info would be greatly appreciated.

-- 
Sincerely, 

HYPERLINK "http://www.oracle.com"; \nOracle
Donald Raikes | Accessibility Specialist
Phone: HYPERLINK "tel:+16028246213"+16028246213 | Mobile: HYPERLINK 
"tel:+15202717608"+15202717608 | VOIP: HYPERLINK "tel:+16028246213"+16028246213 
Oracle JDeveloper Quality Assurance
| Tucson, Arizona 

HYPERLINK "http://www.oracle.com/commitment"; \nGreen Oracle  Oracle is 
committed to developing practices and products that help protect the 
environment