Re: [Qemu-devel] AArch64: QEMU fails in swapcontext

2014-04-18 Thread Mian M. Hamayun


On 18/04/2014 16:44, Richard Henderson wrote:

On 04/18/2014 07:00 AM, Mian M. Hamayun wrote:

Hello Peter & All,

I am trying to figure out a problem in qemu on aarch64 (with kvm enabled). I
have found this problem in many different versions of qemu
(v2.0.0-rc3/rc2/rc1/rc0, master 2d03b49), and I believe that either I am
missing something common in all of these versions or its a genuine bug in qemu
on aarch64.

The problem is triggered by virtqueue_notify() function (in virtio_ring.c) from
the guest kernel and fails in the qemu_coroutine_new() while trying to do the
swapcontext(&old_uc, &uc) (see coroutine-ucontext.c:164). The
sigsetjmp(old_env, 0) just before the swapcontext() call seems to work fine, as
it returns 0, and then we invoke the swapcontext().

The host kernel reports:
"qemu-system-aar[596]: bad frame in sys_rt_sigreturn: pc=004462e0
sp=7f8020f000" and kills the qemu process due to segmentation fault. The
pc=004462e0 is for the coroutine_trampoline() but we don't actually reach it,
when this particular crash happens.

Just to give you an idea of the code I am talking about:

$~/qemu[master]$ git blame -L 159,166 coroutine-ucontext.c
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 159) makecontext(&uc,
(void (*)(void))coroutine_trampoline,
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 160) 2,
arg.i[0], arg.i[1]);
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 161)
6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 162) /* swapcontext() in,
siglongjmp() back out */
6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 163) if
(!sigsetjmp(old_env, 0)) {
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 164)
swapcontext(&old_uc, &uc);
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 165) }
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 166) return &co->base;

My qemu configure/run commands are:

./configure --target-list=aarch64-softmmu   \
 --cross-prefix=aarch64-linux-gnu-   \
 --enable-fdt *--enable-kvm* --disable-werror  \
 --audio-drv-list="" --static

./qemu-system-aarch64 \
 *-enable-kvm* -nographic -kernel Image\
 -drive if=none,file=disk_oe64.img,id=fs \
 -device virtio-blk-device,drive=fs  \
 -m 1024 -M virt -cpu host   \
 -append "earlyprintk console=ttyAMA0 mem=1024M rootwait root=/dev/vda rw
init=/bin/sh"

Any ideas/comments on how to resolve this issue?

Note that a patch has just gone into glibc to rewrite setcontext et al for
aarch64.  I'd try using git glibc before looking too much deeper.


r~

It seems right to me as well, as the setcontext related bug (for 
aarch64) has recently been posted/fixed in glibc:

https://sourceware.org/bugzilla/show_bug.cgi?id=16629

I have also tested the example posted at: 
https://sourceware.org/bugzilla/attachment.cgi?id=7435

and I get the following output on x86_64:

start f2
start f1
finish f2
finish f1
{ss_sp: (nil), ss_flags: 2, ss_size: 0}
{ss_sp: (nil), ss_flags: 2, ss_size: 0}

and this one on AArch64:

start f2
start f1
finish f2
finish f1
{ss_sp: (nil), ss_flags: 2, ss_size: 0}
*{ss_sp: 0x7ff7e723f0, ss_flags: 0, ss_size: 8192}*

I will first look into updating my glibc for AArch64 before coming back 
to qemu.


Thanks for your support,
Hamayun



[Qemu-devel] AArch64: QEMU fails in swapcontext

2014-04-18 Thread Mian M. Hamayun

Hello Peter & All,

I am trying to figure out a problem in qemu on aarch64 (with kvm 
enabled). I have found this problem in many different versions of qemu 
(v2.0.0-rc3/rc2/rc1/rc0, master 2d03b49), and I believe that either I am 
missing something common in all of these versions or its a genuine bug 
in qemu on aarch64.


The problem is triggered by virtqueue_notify() function (in 
virtio_ring.c) from the guest kernel and fails in the 
qemu_coroutine_new() while trying to do the swapcontext(&old_uc, &uc) 
(see coroutine-ucontext.c:164). The sigsetjmp(old_env, 0) just before 
the swapcontext() call seems to work fine, as it returns 0, and then we 
invoke the swapcontext().


The host kernel reports:
"qemu-system-aar[596]: bad frame in sys_rt_sigreturn: pc=004462e0 
sp=7f8020f000" and kills the qemu process due to segmentation fault. The 
pc=004462e0 is for the coroutine_trampoline() but we don't actually 
reach it, when this particular crash happens.


Just to give you an idea of the code I am talking about:

$~/qemu[master]$ git blame -L 159,166 coroutine-ucontext.c
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 159) makecontext(&uc, 
(void (*)(void))coroutine_trampoline,
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 160) 
2, arg.i[0], arg.i[1]);

00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 161)
6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 162) /* swapcontext() 
in, siglongjmp() back out */
6ab7e546 (Peter Maydell 2013-02-20 15:21:09 + 163) if 
(!sigsetjmp(old_env, 0)) {
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 164) 
swapcontext(&old_uc, &uc);

00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 165) }
00dccaf1 (Kevin Wolf2011-01-17 16:08:14 + 166) return &co->base;

My qemu configure/run commands are:

./configure --target-list=aarch64-softmmu   \
--cross-prefix=aarch64-linux-gnu-   \
--enable-fdt *--enable-kvm* --disable-werror  \
--audio-drv-list="" --static

./qemu-system-aarch64 \
*-enable-kvm* -nographic -kernel Image\
-drive if=none,file=disk_oe64.img,id=fs \
-device virtio-blk-device,drive=fs  \
-m 1024 -M virt -cpu host   \
-append "earlyprintk console=ttyAMA0 mem=1024M rootwait 
root=/dev/vda rw init=/bin/sh"


Any ideas/comments on how to resolve this issue?

Best Regards,
Hamayun



[Qemu-devel] [PATCH v4 7/7] Add vhost-user reconnection

2013-12-20 Thread Mian M. Hamayun
From: Antonios Motakis 

At runtime vhost-user netdev will detect if the vhost backend is up or down.
Upon disconnection it will set link_down accordingly and notify virtio-net.

Signed-off-by: Antonios Motakis 
Signed-off-by: Nikolay Nikolaev 
---
 hw/net/vhost_net.c| 16 +++
 hw/virtio/vhost-backend.c | 28 ++--
 include/hw/virtio/vhost-backend.h |  2 ++
 include/net/vhost_net.h   |  1 +
 net/vhost-user.c  | 56 +++
 5 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index e42f4d6..56c218e 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -304,6 +304,17 @@ void vhost_net_virtqueue_mask(VHostNetState *net, 
VirtIODevice *dev,
 vhost_virtqueue_mask(&net->dev, dev, idx, mask);
 }
 
+int vhost_net_link_status(VHostNetState *net)
+{
+int r = 0;
+
+if (net->dev.vhost_ops->vhost_status) {
+r = net->dev.vhost_ops->vhost_status(&net->dev);
+}
+
+return r;
+}
+
 VHostNetState *get_vhost_net(NetClientState *nc)
 {
 VHostNetState *vhost_net = 0;
@@ -372,6 +383,11 @@ void vhost_net_virtqueue_mask(VHostNetState *net, 
VirtIODevice *dev,
 {
 }
 
+int vhost_net_link_status(VHostNetState *net)
+{
+return 0;
+}
+
 VHostNetState *get_vhost_net(NetClientState *nc)
 {
 return 0;
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 17f59ec..10f813b 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -171,6 +171,10 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned 
long int request,
 
 assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
 
+if (fd < 0) {
+return 0;
+}
+
 msg.request = vhost_user_request_translate(request);
 msg.flags = 0;
 
@@ -254,9 +258,25 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned 
long int request,
 }
 }
 
+/* mark the backend non operational */
+if (result < 0) {
+fprintf(stderr, "%s: Connection break detected\n", __func__);
+vhost_user_cleanup(dev);
+return 0;
+}
+
 return result;
 }
 
+static int vhost_user_status(struct vhost_dev *dev)
+{
+uint64_t features = 0;
+
+vhost_user_call(dev, VHOST_GET_FEATURES, &features);
+
+return (dev->control >= 0);
+}
+
 static int vhost_user_init(struct vhost_dev *dev, const char *devpath)
 {
 int fd = -1;
@@ -316,11 +336,13 @@ fail:
 
 static int vhost_user_cleanup(struct vhost_dev *dev)
 {
-int r;
+int r = 0;
 
 assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
 
-r = close(dev->control);
+if (dev->control >= 0) {
+r = close(dev->control);
+}
 dev->control = -1;
 
 return r;
@@ -329,6 +351,7 @@ static int vhost_user_cleanup(struct vhost_dev *dev)
 static const VhostOps user_ops = {
 .backend_type = VHOST_BACKEND_TYPE_USER,
 .vhost_call = vhost_user_call,
+.vhost_status = vhost_user_status,
 .vhost_backend_init = vhost_user_init,
 .vhost_backend_cleanup = vhost_user_cleanup
 };
@@ -361,6 +384,7 @@ static int vhost_kernel_cleanup(struct vhost_dev *dev)
 static const VhostOps kernel_ops = {
 .backend_type = VHOST_BACKEND_TYPE_KERNEL,
 .vhost_call = vhost_kernel_call,
+.vhost_status = 0,
 .vhost_backend_init = vhost_kernel_init,
 .vhost_backend_cleanup = vhost_kernel_cleanup
 };
diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index ef87ffa..f2b4a6c 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -22,12 +22,14 @@ struct vhost_dev;
 
 typedef int (*vhost_call)(struct vhost_dev *dev, unsigned long int request,
  void *arg);
+typedef int (*vhost_status)(struct vhost_dev *dev);
 typedef int (*vhost_backend_init)(struct vhost_dev *dev, const char *devpath);
 typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
 
 typedef struct VhostOps {
 VhostBackendType backend_type;
 vhost_call vhost_call;
+vhost_status vhost_status;
 vhost_backend_init vhost_backend_init;
 vhost_backend_cleanup vhost_backend_cleanup;
 } VhostOps;
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index abd3d0b..6390907 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -31,5 +31,6 @@ void vhost_net_ack_features(VHostNetState *net, unsigned 
features);
 bool vhost_net_virtqueue_pending(VHostNetState *net, int n);
 void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev,
   int idx, bool mask);
+int vhost_net_link_status(VHostNetState *net);
 VHostNetState *get_vhost_net(NetClientState *nc);
 #endif
diff --git a/net/vhost-user.c b/net/vhost-user.c
index 6fd5afc..56f7dd4 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -12,6 +12,7 @@
 #include "net/vhost_net.h"
 #include "net/vhost-user.h"
 #include "

[Qemu-devel] [PATCH v4 4/7] Add domain socket communication for vhost-user backend

2013-12-20 Thread Mian M. Hamayun
From: Antonios Motakis 

Add structures for passing vhost-user messages over a unix domain socket.
This is the equivalent to the existing vhost-kernel ioctls.

Connect to the named unix domain socket. The system call sendmsg
is used for communication. To be able to pass file descriptors
between processes - we use SCM_RIGHTS type in the message control header.

Signed-off-by: Antonios Motakis 
Signed-off-by: Nikolay Nikolaev 
---
 hw/virtio/vhost-backend.c | 167 --
 1 file changed, 161 insertions(+), 6 deletions(-)

diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 847809f..96d3bf0 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -14,30 +14,185 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+
+#define VHOST_MEMORY_MAX_NREGIONS8
+
+typedef enum VhostUserRequest {
+VHOST_USER_NONE = 0,
+VHOST_USER_GET_FEATURES = 1,
+VHOST_USER_SET_FEATURES = 2,
+VHOST_USER_SET_OWNER = 3,
+VHOST_USER_RESET_OWNER = 4,
+VHOST_USER_SET_MEM_TABLE = 5,
+VHOST_USER_SET_LOG_BASE = 6,
+VHOST_USER_SET_LOG_FD = 7,
+VHOST_USER_SET_VRING_NUM = 8,
+VHOST_USER_SET_VRING_ADDR = 9,
+VHOST_USER_SET_VRING_BASE = 10,
+VHOST_USER_GET_VRING_BASE = 11,
+VHOST_USER_SET_VRING_KICK = 12,
+VHOST_USER_SET_VRING_CALL = 13,
+VHOST_USER_SET_VRING_ERR = 14,
+VHOST_USER_NET_SET_BACKEND = 15,
+VHOST_USER_MAX
+} VhostUserRequest;
+
+typedef struct VhostUserMemoryRegion {
+__u64 guest_phys_addr;
+__u64 memory_size;
+__u64 userspace_addr;
+} VhostUserMemoryRegion;
+
+typedef struct VhostUserMemory {
+__u32 nregions;
+VhostUserMemoryRegion regions[VHOST_MEMORY_MAX_NREGIONS];
+} VhostUserMemory;
+
+typedef struct VhostUserMsg {
+VhostUserRequest request;
+
+int flags;
+union {
+uint64_tu64;
+int fd;
+struct vhost_vring_state state;
+struct vhost_vring_addr addr;
+struct vhost_vring_file file;
+
+VhostUserMemory memory;
+};
+} VhostUserMsg;
+
+static int vhost_user_recv(int fd, VhostUserMsg *msg)
+{
+ssize_t r = read(fd, msg, sizeof(VhostUserMsg));
+
+return (r == sizeof(VhostUserMsg)) ? 0 : -1;
+}
+
+static int vhost_user_send_fds(int fd, const VhostUserMsg *msg, int *fds,
+size_t fd_num)
+{
+int r;
+
+struct msghdr msgh;
+struct iovec iov[1];
+
+size_t fd_size = fd_num * sizeof(int);
+char control[CMSG_SPACE(fd_size)];
+struct cmsghdr *cmsg;
+
+memset(&msgh, 0, sizeof(msgh));
+memset(control, 0, sizeof(control));
+
+/* set the payload */
+iov[0].iov_base = (void *) msg;
+iov[0].iov_len = sizeof(VhostUserMsg);
+
+msgh.msg_iov = iov;
+msgh.msg_iovlen = 1;
+
+if (fd_num) {
+msgh.msg_control = control;
+msgh.msg_controllen = sizeof(control);
+
+cmsg = CMSG_FIRSTHDR(&msgh);
+
+cmsg->cmsg_len = CMSG_LEN(fd_size);
+cmsg->cmsg_level = SOL_SOCKET;
+cmsg->cmsg_type = SCM_RIGHTS;
+memcpy(CMSG_DATA(cmsg), fds, fd_size);
+} else {
+msgh.msg_control = 0;
+msgh.msg_controllen = 0;
+}
+
+do {
+r = sendmsg(fd, &msgh, 0);
+} while (r < 0 && errno == EINTR);
+
+if (r < 0) {
+fprintf(stderr, "Failed to send msg(%d), reason: %s\n",
+msg->request, strerror(errno));
+} else {
+r = 0;
+}
+
+return r;
+}
 
 static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
 void *arg)
 {
+int fd = dev->control;
+VhostUserMsg msg;
+int result = 0, need_reply = 0;
+int fds[VHOST_MEMORY_MAX_NREGIONS];
+size_t fd_num = 0;
+
 assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
-fprintf(stderr, "vhost_user_call not implemented\n");
 
-return -1;
+switch (request) {
+default:
+fprintf(stderr, "vhost-user trying to send unhandled ioctl\n");
+return -1;
+break;
+}
+
+result = vhost_user_send_fds(fd, &msg, fds, fd_num);
+
+if (!result && need_reply) {
+result = vhost_user_recv(fd, &msg);
+if (!result) {
+switch (request) {
+default:
+break;
+}
+}
+}
+
+return result;
 }
 
 static int vhost_user_init(struct vhost_dev *dev, const char *devpath)
 {
+int fd = -1;
+struct sockaddr_un un;
+size_t len;
+
 assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
-fprintf(stderr, "vhost_user_init not implemented\n");
 
-return -1;
+/* Create the socket */
+fd = socket(AF_UNIX, SOCK_STREAM, 0);
+if (fd == -1) {
+perror("socket");
+return -1;
+}
+
+un.sun_family = AF_UNIX;
+strcpy(un.sun_path, devpath);
+
+len = sizeof(un.sun_family) + strlen(devpath);
+
+/* Connect */
+if (connect(fd, (struct sockaddr *) &un, len) == -1) {
+perror("connect")

[Qemu-devel] [PATCH v4 5/7] Add vhost-user calls implementation

2013-12-20 Thread Mian M. Hamayun
From: Antonios Motakis 

Each ioctl request of vhost-kernel has a vhost-user message equivalent,
which is sent over the control socket.

The general approach is to copy the data from the supplied argument
pointer to a designated field in the message. If a file descriptor is
to be passed, it should be placed in the fds array for inclusion in
the sendmsg control header.

VHOST_SET_MEM_TABLE ignores the supplied vhost_memory structure and scans
the global ram_list for ram blocks with a valid fd field set. This would
be set when the -mem-path option with shared=on property is used.

Signed-off-by: Antonios Motakis 
Signed-off-by: Nikolay Nikolaev 
---
 hw/virtio/vhost-backend.c | 137 +-
 1 file changed, 134 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 96d3bf0..17f59ec 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -19,6 +19,7 @@
 #include 
 
 #define VHOST_MEMORY_MAX_NREGIONS8
+#define VHOST_USER_SOCKTO(1000) /* msec */
 
 typedef enum VhostUserRequest {
 VHOST_USER_NONE = 0,
@@ -66,6 +67,40 @@ typedef struct VhostUserMsg {
 };
 } VhostUserMsg;
 
+static unsigned long int ioctl_to_vhost_user_request[VHOST_USER_MAX] = {
+-1, /* VHOST_USER_NONE */
+VHOST_GET_FEATURES, /* VHOST_USER_GET_FEATURES */
+VHOST_SET_FEATURES, /* VHOST_USER_SET_FEATURES */
+VHOST_SET_OWNER, /* VHOST_USER_SET_OWNER */
+VHOST_RESET_OWNER, /* VHOST_USER_RESET_OWNER */
+VHOST_SET_MEM_TABLE, /* VHOST_USER_SET_MEM_TABLE */
+VHOST_SET_LOG_BASE, /* VHOST_USER_SET_LOG_BASE */
+VHOST_SET_LOG_FD, /* VHOST_USER_SET_LOG_FD */
+VHOST_SET_VRING_NUM, /* VHOST_USER_SET_VRING_NUM */
+VHOST_SET_VRING_ADDR, /* VHOST_USER_SET_VRING_ADDR */
+VHOST_SET_VRING_BASE, /* VHOST_USER_SET_VRING_BASE */
+VHOST_GET_VRING_BASE, /* VHOST_USER_GET_VRING_BASE */
+VHOST_SET_VRING_KICK, /* VHOST_USER_SET_VRING_KICK */
+VHOST_SET_VRING_CALL, /* VHOST_USER_SET_VRING_CALL */
+VHOST_SET_VRING_ERR, /* VHOST_USER_SET_VRING_ERR */
+VHOST_NET_SET_BACKEND /* VHOST_USER_NET_SET_BACKEND */
+};
+
+static int vhost_user_cleanup(struct vhost_dev *dev);
+
+static VhostUserRequest vhost_user_request_translate(unsigned long int request)
+{
+VhostUserRequest idx;
+
+for (idx = 0; idx < VHOST_USER_MAX; idx++) {
+if (ioctl_to_vhost_user_request[idx] == request) {
+break;
+}
+}
+
+return (idx == VHOST_USER_MAX) ? VHOST_USER_NONE : idx;
+}
+
 static int vhost_user_recv(int fd, VhostUserMsg *msg)
 {
 ssize_t r = read(fd, msg, sizeof(VhostUserMsg));
@@ -129,13 +164,74 @@ static int vhost_user_call(struct vhost_dev *dev, 
unsigned long int request,
 {
 int fd = dev->control;
 VhostUserMsg msg;
+RAMBlock *block = 0;
 int result = 0, need_reply = 0;
 int fds[VHOST_MEMORY_MAX_NREGIONS];
 size_t fd_num = 0;
 
 assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
 
+msg.request = vhost_user_request_translate(request);
+msg.flags = 0;
+
 switch (request) {
+case VHOST_GET_FEATURES:
+case VHOST_GET_VRING_BASE:
+need_reply = 1;
+break;
+
+case VHOST_SET_FEATURES:
+case VHOST_SET_LOG_BASE:
+msg.u64 = *((uint64_t *) arg);
+break;
+
+case VHOST_SET_OWNER:
+case VHOST_RESET_OWNER:
+break;
+
+case VHOST_SET_MEM_TABLE:
+QTAILQ_FOREACH(block, &ram_list.blocks, next)
+{
+if (block->fd > 0) {
+msg.memory.regions[fd_num].userspace_addr = (__u64) 
block->host;
+msg.memory.regions[fd_num].memory_size = block->length;
+msg.memory.regions[fd_num].guest_phys_addr = block->offset;
+fds[fd_num++] = block->fd;
+}
+}
+
+msg.memory.nregions = fd_num;
+
+if (!fd_num) {
+fprintf(stderr, "Failed initializing vhost-user memory map\n"
+"consider -mem-path and -mem-prealloc options\n");
+return -1;
+}
+break;
+
+case VHOST_SET_LOG_FD:
+msg.fd = *((int *) arg);
+break;
+
+case VHOST_SET_VRING_NUM:
+case VHOST_SET_VRING_BASE:
+memcpy(&msg.state, arg, sizeof(struct vhost_vring_state));
+break;
+
+case VHOST_SET_VRING_ADDR:
+memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr));
+break;
+
+case VHOST_SET_VRING_KICK:
+case VHOST_SET_VRING_CALL:
+case VHOST_SET_VRING_ERR:
+case VHOST_NET_SET_BACKEND:
+memcpy(&msg.file, arg, sizeof(struct vhost_vring_file));
+if (msg.file.fd > 0) {
+fds[0] = msg.file.fd;
+fd_num = 1;
+}
+break;
 default:
 fprintf(stderr, "vhost-user trying to send unhandled ioctl\n");
 return -1;
@@ -148,7 +244,11 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned 
long int request,
 re

[Qemu-devel] [PATCH v4 1/7] Convert -mem-path to QemuOpts and add prealloc, share and unlink properties

2013-12-20 Thread Mian M. Hamayun
From: Antonios Motakis 

Extend -mem-path with additional properties:

 - prealloc=on|off - default off, same as -mem-prealloc
 - share=on|off - default off, memory is mmapped with MAP_SHARED flag
 - unlink=on|off - default on, inlink the file after openinng it

Signed-off-by: Antonios Motakis 
Signed-off-by: Nikolay Nikolaev 
---
 exec.c | 57 +-
 include/exec/cpu-all.h |  3 ---
 qemu-options.hx| 10 +++--
 vl.c   | 41 +++-
 4 files changed, 91 insertions(+), 20 deletions(-)

diff --git a/exec.c b/exec.c
index 7e49e8e..30f4019 100644
--- a/exec.c
+++ b/exec.c
@@ -957,6 +957,7 @@ void qemu_mutex_unlock_ramlist(void)
 #include 
 
 #define HUGETLBFS_MAGIC   0x958458f6
+#define MIN_HUGE_PAGE_SIZE(2*1024*1024)
 
 static long gethugepagesize(const char *path)
 {
@@ -972,8 +973,9 @@ static long gethugepagesize(const char *path)
 return 0;
 }
 
-if (fs.f_type != HUGETLBFS_MAGIC)
-fprintf(stderr, "Warning: path not on HugeTLBFS: %s\n", path);
+if (fs.f_type != HUGETLBFS_MAGIC) {
+return 0;
+}
 
 return fs.f_bsize;
 }
@@ -994,11 +996,14 @@ static void *file_ram_alloc(RAMBlock *block,
 char *c;
 void *area;
 int fd;
+int flags;
 unsigned long hpagesize;
+QemuOpts *opts;
+unsigned int mem_prealloc = 0, mem_share = 0, mem_unlink = 1;
 
 hpagesize = gethugepagesize(path);
 if (!hpagesize) {
-return NULL;
+hpagesize = MIN_HUGE_PAGE_SIZE;
 }
 
 if (memory < hpagesize) {
@@ -1010,6 +1015,14 @@ static void *file_ram_alloc(RAMBlock *block,
 return NULL;
 }
 
+/* Fill config options */
+opts = qemu_opts_find(qemu_find_opts("mem-path"), NULL);
+if (opts) {
+mem_prealloc = qemu_opt_get_bool(opts, "prealloc", 0);
+mem_share = qemu_opt_get_bool(opts, "share", 0);
+mem_unlink = qemu_opt_get_bool(opts, "unlink", 1);
+}
+
 /* Make name safe to use with mkstemp by replacing '/' with '_'. */
 sanitized_name = g_strdup(block->mr->name);
 for (c = sanitized_name; *c != '\0'; c++) {
@@ -1017,20 +1030,28 @@ static void *file_ram_alloc(RAMBlock *block,
 *c = '_';
 }
 
-filename = g_strdup_printf("%s/qemu_back_mem.%s.XX", path,
-   sanitized_name);
+filename = g_strdup_printf("%s/qemu_back_mem.%s%s", path, sanitized_name,
+   (mem_unlink) ? ".XX" : "");
 g_free(sanitized_name);
 
-fd = mkstemp(filename);
+if (mem_unlink) {
+fd = mkstemp(filename);
+} else {
+fd = open(filename, O_CREAT | O_RDWR | O_EXCL,
+S_IRWXU | S_IRWXG | S_IRWXO);
+}
 if (fd < 0) {
-perror("unable to create backing store for hugepages");
+perror("unable to create guest RAM backing store");
 g_free(filename);
 return NULL;
 }
-unlink(filename);
+
+if (mem_unlink) {
+unlink(filename);
+}
 g_free(filename);
 
-memory = (memory+hpagesize-1) & ~(hpagesize-1);
+memory = (memory + hpagesize - 1) & ~(hpagesize - 1);
 
 /*
  * ftruncate is not supported by hugetlbfs in older
@@ -1041,7 +1062,8 @@ static void *file_ram_alloc(RAMBlock *block,
 if (ftruncate(fd, memory))
 perror("ftruncate");
 
-area = mmap(0, memory, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+flags = mem_share ? MAP_SHARED : MAP_PRIVATE;
+area = mmap(0, memory, PROT_READ | PROT_WRITE, flags, fd, 0);
 if (area == MAP_FAILED) {
 perror("file_ram_alloc: can't mmap RAM pages");
 close(fd);
@@ -1211,11 +1233,18 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, 
void *host,
MemoryRegion *mr)
 {
 RAMBlock *block, *new_block;
+QemuOpts *opts;
+const char *mem_path = 0;
 
 size = TARGET_PAGE_ALIGN(size);
 new_block = g_malloc0(sizeof(*new_block));
 new_block->fd = -1;
 
+opts = qemu_opts_find(qemu_find_opts("mem-path"), NULL);
+if (opts) {
+mem_path = qemu_opt_get(opts, "path");
+}
+
 /* This assumes the iothread lock is taken here too.  */
 qemu_mutex_lock_ramlist();
 new_block->mr = mr;
@@ -1348,6 +1377,14 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 ram_addr_t offset;
 int flags;
 void *area, *vaddr;
+QemuOpts *opts;
+unsigned int mem_prealloc = 0;
+
+/* Fill config options */
+opts = qemu_opts_find(qemu_find_opts("mem-path"), NULL);
+if (opts) {
+mem_prealloc = qemu_opt_get_bool(opts, "prealloc", 0);
+}
 
 QTAILQ_FOREACH(block, &ram_list.blocks, next) {
 offset = addr - block->offset;
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index b6998f0..4f8e989 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -467,9 +467,6 @@ typedef struct RAMList {
 } RAMList;
 extern RAML

[Qemu-devel] [PATCH v4 3/7] Add vhost-user skeleton

2013-12-20 Thread Mian M. Hamayun
From: Antonios Motakis 

Add empty vhost_call, init and cleanup for the vhost-user backend.

Signed-off-by: Antonios Motakis 
Signed-off-by: Nikolay Nikolaev 
---
 hw/net/vhost_net.c| 57 ++-
 hw/virtio/vhost-backend.c | 35 
 include/hw/virtio/vhost-backend.h |  3 ++-
 include/net/vhost_net.h   | 13 -
 net/tap.c | 16 ++-
 5 files changed, 91 insertions(+), 33 deletions(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 4aaf0b4..3614e6c 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -91,43 +91,51 @@ static int vhost_net_get_fd(NetClientState *backend)
 }
 }
 
-struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
- bool force)
+struct vhost_net *vhost_net_init(VhostNetOptions *options)
 {
-int r;
+int r = -1;
 struct vhost_net *net = g_malloc(sizeof *net);
-if (!backend) {
-fprintf(stderr, "vhost-net requires backend to be setup\n");
+
+if (!options->net_backend) {
+fprintf(stderr, "vhost-net requires net backend to be setup\n");
 goto fail;
 }
-r = vhost_net_get_fd(backend);
-if (r < 0) {
-goto fail;
+
+if (options->backend_type == VHOST_BACKEND_TYPE_KERNEL) {
+r = vhost_net_get_fd(options->net_backend);
+if (r < 0) {
+goto fail;
+}
+
+net->dev.backend_features =
+tap_has_vnet_hdr(options->net_backend) ? 0 :
+(1 << VHOST_NET_F_VIRTIO_NET_HDR);
 }
-net->nc = backend;
-net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :
-(1 << VHOST_NET_F_VIRTIO_NET_HDR);
+
+net->nc = options->net_backend;
 net->backend = r;
 
 net->dev.nvqs = 2;
 net->dev.vqs = net->vqs;
 
-r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net",
-   VHOST_BACKEND_TYPE_KERNEL, force);
+r = vhost_dev_init(&net->dev, options->devfd, options->devpath,
+   options->backend_type, options->force);
 if (r < 0) {
 goto fail;
 }
-if (!tap_has_vnet_hdr_len(backend,
-  sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
-net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
-}
-if (~net->dev.features & net->dev.backend_features) {
-fprintf(stderr, "vhost lacks feature mask %" PRIu64 " for backend\n",
-(uint64_t)(~net->dev.features & net->dev.backend_features));
-vhost_dev_cleanup(&net->dev);
-goto fail;
+if (options->backend_type == VHOST_BACKEND_TYPE_KERNEL) {
+if (!tap_has_vnet_hdr_len(options->net_backend,
+sizeof(struct virtio_net_hdr_mrg_rxbuf))) {
+net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
+}
+if (~net->dev.features & net->dev.backend_features) {
+fprintf(stderr, "vhost lacks feature mask %" PRIu64
+   " for backend\n",
+   (uint64_t)(~net->dev.features & net->dev.backend_features));
+vhost_dev_cleanup(&net->dev);
+goto fail;
+}
 }
-
 /* Set sane init value. Override when guest acks. */
 vhost_net_ack_features(net, 0);
 return net;
@@ -286,8 +294,7 @@ void vhost_net_virtqueue_mask(VHostNetState *net, 
VirtIODevice *dev,
 vhost_virtqueue_mask(&net->dev, dev, idx, mask);
 }
 #else
-struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,
- bool force)
+struct vhost_net *vhost_net_init(VhostNetOptions *options)
 {
 error_report("vhost-net support is not compiled in");
 return NULL;
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 2a9a1ec..847809f 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -15,6 +15,38 @@
 #include 
 #include 
 
+static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
+void *arg)
+{
+assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
+fprintf(stderr, "vhost_user_call not implemented\n");
+
+return -1;
+}
+
+static int vhost_user_init(struct vhost_dev *dev, const char *devpath)
+{
+assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
+fprintf(stderr, "vhost_user_init not implemented\n");
+
+return -1;
+}
+
+static int vhost_user_cleanup(struct vhost_dev *dev)
+{
+assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER);
+fprintf(stderr, "vhost_user_cleanup not implemented\n");
+
+return -1;
+}
+
+static const VhostOps user_ops = {
+.backend_type = VHOST_BACKEND_TYPE_USER,
+.vhost_call = vhost_user_call,
+.vhost_backend_init = vhost_user_init,
+.vhost_backend_cleanup = vhost_user_cleanup
+};
+
 static int vhost_kernel_call(struct vhost_dev *dev, unsigned long int request,
 

[Qemu-devel] [PATCH v4 6/7] Add new vhost-user netdev backend

2013-12-20 Thread Mian M. Hamayun
From: Antonios Motakis 

Add a new QEMU netdev backend that is intended to invoke vhost_net
with the vhost-user backend. Also decouple virtio-net from the tap
backend.

Signed-off-by: Antonios Motakis 
Signed-off-by: Nikolay Nikolaev 
---
 hmp-commands.hx  |   4 +-
 hw/net/vhost_net.c   |  66 ++--
 hw/net/virtio-net.c  |  42 --
 hw/virtio/vhost.c|   1 -
 include/net/vhost-user.h |  17 
 include/net/vhost_net.h  |   1 +
 net/Makefile.objs|   2 +-
 net/clients.h|   3 ++
 net/hub.c|   1 +
 net/net.c|   2 +
 net/vhost-user.c | 111 +++
 qapi-schema.json |  18 +++-
 qemu-options.hx  |   3 ++
 13 files changed, 227 insertions(+), 44 deletions(-)
 create mode 100644 include/net/vhost-user.h
 create mode 100644 net/vhost-user.c

diff --git a/hmp-commands.hx b/hmp-commands.hx
index ebe8e78..d5a3774 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1190,7 +1190,7 @@ ETEXI
 {
 .name   = "host_net_add",
 .args_type  = "device:s,opts:s?",
-.params = "tap|user|socket|vde|netmap|dump [options]",
+.params = "tap|user|socket|vde|netmap|vhost-user|dump [options]",
 .help   = "add host VLAN client",
 .mhandler.cmd = net_host_device_add,
 },
@@ -1218,7 +1218,7 @@ ETEXI
 {
 .name   = "netdev_add",
 .args_type  = "netdev:O",
-.params = 
"[user|tap|socket|hubport|netmap],id=str[,prop=value][,...]",
+.params = 
"[user|tap|socket|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
 .help   = "add host network device",
 .mhandler.cmd = hmp_netdev_add,
 },
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 3614e6c..e42f4d6 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -15,6 +15,7 @@
 
 #include "net/net.h"
 #include "net/tap.h"
+#include "net/vhost-user.h"
 
 #include "hw/virtio/virtio-net.h"
 #include "net/vhost_net.h"
@@ -174,15 +175,20 @@ static int vhost_net_start_one(struct vhost_net *net,
 goto fail_start;
 }
 
-net->nc->info->poll(net->nc, false);
-qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
-file.fd = net->backend;
-for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
-const VhostOps *vhost_ops = net->dev.vhost_ops;
-r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
-if (r < 0) {
-r = -errno;
-goto fail;
+if (net->nc->info->poll) {
+net->nc->info->poll(net->nc, false);
+}
+
+if (net->nc->info->type == NET_CLIENT_OPTIONS_KIND_TAP) {
+qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
+file.fd = net->backend;
+for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
+const VhostOps *vhost_ops = net->dev.vhost_ops;
+r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
+if (r < 0) {
+r = -errno;
+goto fail;
+}
 }
 }
 return 0;
@@ -193,7 +199,9 @@ fail:
 int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->nc->info->poll(net->nc, true);
+if (net->nc->info->poll) {
+net->nc->info->poll(net->nc, true);
+}
 vhost_dev_stop(&net->dev, dev);
 fail_start:
 vhost_dev_disable_notifiers(&net->dev, dev);
@@ -215,7 +223,9 @@ static void vhost_net_stop_one(struct vhost_net *net,
 int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
-net->nc->info->poll(net->nc, true);
+if (net->nc->info->poll) {
+net->nc->info->poll(net->nc, true);
+}
 vhost_dev_stop(&net->dev, dev);
 vhost_dev_disable_notifiers(&net->dev, dev);
 }
@@ -235,7 +245,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
 }
 
 for (i = 0; i < total_queues; i++) {
-r = vhost_net_start_one(tap_get_vhost_net(ncs[i].peer), dev, i * 2);
+r = vhost_net_start_one(get_vhost_net(ncs[i].peer), dev, i * 2);
 
 if (r < 0) {
 goto err;
@@ -252,7 +262,7 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
 
 err:
 while (--i >= 0) {
-vhost_net_stop_one(tap_get_vhost_net(ncs[i].peer), dev);
+vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
 }
 return r;
 }
@@ -273,7 +283,7 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
 assert(r >= 0);
 
 for (i = 0; i < total_queues; i++) {
-vhost_net_stop_one(tap_get_vhost_net(ncs[i].peer), dev);
+vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
 }
 }
 
@@ -293,6 +303,29 @@ void vhost_net_virtqueue_mask(VHostNetState *net, 
VirtIODevice *dev,
 {
 vhost_virtqueue_mask(&net->dev, dev, idx, mask);
 }
+
+

[Qemu-devel] [PATCH v4 0/7] Vhost and vhost-net support for userspace based backends

2013-12-20 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

In this patch series we would like to introduce our approach for putting a
virtio-net backend in an external userspace process. Our eventual target is to
run the network backend in the Snabbswitch ethernet switch, while receiving
traffic from a guest inside QEMU/KVM which runs an unmodified virtio-net
implementation.

For this, we are working into extending vhost to allow equivalent functionality
for userspace. Vhost already passes control of the data plane of virtio-net to
the host kernel; we want to realize a similar model, but for userspace.

In this patch series the concept of a vhost-backend is introduced.

We define two vhost backend types - vhost-kernel and vhost-user. The former is
the interface to the current kernel module implementation. Its control plane is
ioctl based. The data plane is the kernel directly accessing the QEMU allocated,
guest memory.

In the new vhost-user backend, the control plane is based on communication
between QEMU and another userspace process using a unix domain socket. This
allows to implement a virtio backend for a guest running in QEMU, inside the
other userspace process.

We change -mem-path to QemuOpts and add prealloc, share and unlink as properties
to it. HugeTLBFS requirements of -mem-path are relaxed, so any valid path can
be used now. The new properties allow more fine grained control over the guest
RAM backing store.

The data path is realized by directly accessing the vrings and the buffer data
off the guest's memory.

The current user of vhost-user is only vhost-net. We add new netdev backend
that is intended to initialize vhost-net with vhost-user backend.

Example usage:

qemu -m 1024 -mem-path /hugetlbfs,prealloc=on,share=on \
 -netdev type=vhost-user,id=net0,file=/path/to/sock \
 -device virtio-net-pci,netdev=net0

Changes from v3:
 - Convert -mem-path to QemuOpts with prealloc, share and unlink properties
 - Set 1 sec timeout when read/write to the unix domain socket
 - Fix file descriptor leak

Changes from v2:
 - Reconnect when the backend disappears

Changes from v1:
 - Implementation of vhost-user netdev backend
 - Code improvements

Antonios Motakis (7):
  Convert -mem-path to QemuOpts and add prealloc,share and unlink
properties
  Decouple vhost from kernel interface
  Add vhost-user skeleton
  Add domain socket communication for vhost-user backend
  Add vhost-user calls implementation
  Add new vhost-user netdev backend
  Add vhost-user reconnection

 exec.c|  57 +-
 hmp-commands.hx   |   4 +-
 hw/net/vhost_net.c| 144 ++
 hw/net/virtio-net.c   |  42 ++--
 hw/scsi/vhost-scsi.c  |  13 +-
 hw/virtio/Makefile.objs   |   2 +-
 hw/virtio/vhost-backend.c | 409 ++
 hw/virtio/vhost.c |  46 +++--
 include/exec/cpu-all.h|   3 -
 include/hw/virtio/vhost-backend.h |  40 
 include/hw/virtio/vhost.h |   4 +-
 include/net/vhost-user.h  |  17 ++
 include/net/vhost_net.h   |  15 +-
 net/Makefile.objs |   2 +-
 net/clients.h |   3 +
 net/hub.c |   1 +
 net/net.c |   2 +
 net/tap.c |  16 +-
 net/vhost-user.c  | 167 
 qapi-schema.json  |  18 +-
 qemu-options.hx   |  13 +-
 vl.c  |  41 +++-
 22 files changed, 935 insertions(+), 124 deletions(-)
 create mode 100644 hw/virtio/vhost-backend.c
 create mode 100644 include/hw/virtio/vhost-backend.h
 create mode 100644 include/net/vhost-user.h
 create mode 100644 net/vhost-user.c

-- 
1.8.3.2




[Qemu-devel] [PATCH v4 2/7] Decouple vhost from kernel interface

2013-12-20 Thread Mian M. Hamayun
From: Antonios Motakis 

We introduce the concept of vhost-backend, which can be either vhost-kernel
or vhost-user. The existing vhost interface to the kernel is abstracted
behind the vhost-kernel backend.

We replace all direct ioctls to the kernel with a vhost_call to the backend.
vhost dev->control is referenced only in the vhost-backend (ioctl, open, close).

Signed-off-by: Antonios Motakis 
Signed-off-by: Nikolay Nikolaev 
---
 hw/net/vhost_net.c| 13 +---
 hw/scsi/vhost-scsi.c  | 13 +---
 hw/virtio/Makefile.objs   |  2 +-
 hw/virtio/vhost-backend.c | 64 +++
 hw/virtio/vhost.c | 47 ++--
 include/hw/virtio/vhost-backend.h | 37 ++
 include/hw/virtio/vhost.h |  4 ++-
 7 files changed, 147 insertions(+), 33 deletions(-)
 create mode 100644 hw/virtio/vhost-backend.c
 create mode 100644 include/hw/virtio/vhost-backend.h

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 006576d..4aaf0b4 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -27,7 +27,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -113,7 +112,8 @@ struct vhost_net *vhost_net_init(NetClientState *backend, 
int devfd,
 net->dev.nvqs = 2;
 net->dev.vqs = net->vqs;
 
-r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net", force);
+r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net",
+   VHOST_BACKEND_TYPE_KERNEL, force);
 if (r < 0) {
 goto fail;
 }
@@ -170,7 +170,8 @@ static int vhost_net_start_one(struct vhost_net *net,
 qemu_set_fd_handler(net->backend, NULL, NULL, NULL);
 file.fd = net->backend;
 for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
-r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
+const VhostOps *vhost_ops = net->dev.vhost_ops;
+r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
 if (r < 0) {
 r = -errno;
 goto fail;
@@ -180,7 +181,8 @@ static int vhost_net_start_one(struct vhost_net *net,
 fail:
 file.fd = -1;
 while (file.index-- > 0) {
-int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
+const VhostOps *vhost_ops = net->dev.vhost_ops;
+int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
 net->nc->info->poll(net->nc, true);
@@ -201,7 +203,8 @@ static void vhost_net_stop_one(struct vhost_net *net,
 }
 
 for (file.index = 0; file.index < net->dev.nvqs; ++file.index) {
-int r = ioctl(net->dev.control, VHOST_NET_SET_BACKEND, &file);
+const VhostOps *vhost_ops = net->dev.vhost_ops;
+int r = vhost_ops->vhost_call(&net->dev, VHOST_NET_SET_BACKEND, &file);
 assert(r >= 0);
 }
 net->nc->info->poll(net->nc, true);
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 3983a5b..3faff65 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -27,12 +27,13 @@
 static int vhost_scsi_set_endpoint(VHostSCSI *s)
 {
 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
+const VhostOps *vhost_ops = s->dev.vhost_ops;
 struct vhost_scsi_target backend;
 int ret;
 
 memset(&backend, 0, sizeof(backend));
 pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
-ret = ioctl(s->dev.control, VHOST_SCSI_SET_ENDPOINT, &backend);
+ret = vhost_ops->vhost_call(&s->dev, VHOST_SCSI_SET_ENDPOINT, &backend);
 if (ret < 0) {
 return -errno;
 }
@@ -43,10 +44,11 @@ static void vhost_scsi_clear_endpoint(VHostSCSI *s)
 {
 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
 struct vhost_scsi_target backend;
+const VhostOps *vhost_ops = s->dev.vhost_ops;
 
 memset(&backend, 0, sizeof(backend));
 pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn);
-ioctl(s->dev.control, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
+vhost_ops->vhost_call(&s->dev, VHOST_SCSI_CLEAR_ENDPOINT, &backend);
 }
 
 static int vhost_scsi_start(VHostSCSI *s)
@@ -55,13 +57,15 @@ static int vhost_scsi_start(VHostSCSI *s)
 VirtIODevice *vdev = VIRTIO_DEVICE(s);
 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
 VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+const VhostOps *vhost_ops = s->dev.vhost_ops;
 
 if (!k->set_guest_notifiers) {
 error_report("binding does not support guest notifiers");
 return -ENOSYS;
 }
 
-ret = ioctl(s->dev.control, VHOST_SCSI_GET_ABI_VERSION, &abi_version);
+ret = vhost_ops->vhost_call(&s->dev,
+VHOST_SCSI_GET_ABI_VERSION, &abi_version);
 if (ret < 0) {
 return -errno;
 }
@@ -227,7 +231,8 @@ static void vhost_scsi_realize(DeviceState *dev, Error 
**errp)
 s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs);
 s->dev.vq_index = 0;
 
-re

Re: [Qemu-devel] [PATCH v3 02/11] AARCH64: add a57core

2013-09-30 Thread Mian M. Hamayun


On 28/09/2013 02:16, Peter Maydell wrote:

On 28 September 2013 00:53, Andreas Färber  wrote:

Hi,

Am 27.09.2013 12:10, schrieb Mian M. Hamayun:

From: John Rigby 

Just an copy of a15 with a57 substituting a15 for now.

I had previously gently nack'ed this patch - conversions are still
queued on qom-next currently though. Having PMM's kernel load patches
now, I'll try if I can still get this posted today.

It's also already had a strong nak from me because it's not
really an A57 model. We should be using 'cpu host'
until there's a public TRM for a real A57 model.

-- PMM


I agree with your concerns and feedback but as I remember from our last
KVM/ARM telco, we agreed that I should not wait for the -cpu host support
to become available and post the next patch series anyways.

Also there are multiple patches under review for providing the -cpu host
or equivalent support in QEMU and/or KVM such as the one posted by Peter
Maydell and another CPU=Host patch from Anup Patel. We will update our patch
series, once we have consensus on which implementation to actually use for
providing the -cpu host support.

--
Hamayun




[Qemu-devel] [PATCH v3 03/11] AARCH64: Add A57 CPU to default AArch64 configuration and enable KVM

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

Introduce the A57 cpu to the default AArch64 configuration and enable KVM for
64-bit guests only.

Signed-off-by: Mian M. Hamayun 
---
 configure   | 2 +-
 default-configs/aarch64-softmmu.mak | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 2b83936..7298b69 100755
--- a/configure
+++ b/configure
@@ -4481,7 +4481,7 @@ case "$target_name" in
   *)
 esac
 case "$target_name" in
-  arm|i386|x86_64|ppcemb|ppc|ppc64|s390x)
+  arm|aarch64|i386|x86_64|ppcemb|ppc|ppc64|s390x)
 # Make sure the target and host cpus are compatible
 if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
   \( "$target_name" = "$cpu" -o \
diff --git a/default-configs/aarch64-softmmu.mak 
b/default-configs/aarch64-softmmu.mak
index 175362f..0eb3d96 100644
--- a/default-configs/aarch64-softmmu.mak
+++ b/default-configs/aarch64-softmmu.mak
@@ -37,6 +37,7 @@ CONFIG_USB_MUSB=y
 CONFIG_ARM11MPCORE=y
 CONFIG_A9MPCORE=y
 CONFIG_A15MPCORE=y
+CONFIG_A57MPCORE=y
 
 CONFIG_ARM_GIC=y
 CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
-- 
1.8.1.2




[Qemu-devel] [PATCH v3 05/11] AARCH64: Add AARCH64 CPU initialization, get and put registers support

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

The cpu init function tries to initialize with all possible cpu types, as
KVM does not provide a means to detect the real cpu type and simply refuses
to initialize on cpu type mis-match. By using the loop based init function,
we avoid the need to modify code if the underlying platform is different,
such as Fast Models instead of Foundation Models.

Get and Put Registers deal with the basic state of AARCH64 CPUs.

Signed-off-by: Mian M. Hamayun 
---
 target-arm/kvm_64.c | 106 ++--
 1 file changed, 103 insertions(+), 3 deletions(-)

diff --git a/target-arm/kvm_64.c b/target-arm/kvm_64.c
index a6af968..9685727 100644
--- a/target-arm/kvm_64.c
+++ b/target-arm/kvm_64.c
@@ -18,19 +18,119 @@
 #include "sysemu/kvm.h"
 #include "kvm_arm.h"
 
+#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
+KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
+
+static uint32_t kvm_arm_targets[KVM_ARM_NUM_TARGETS] = {
+KVM_ARM_TARGET_AEM_V8,
+KVM_ARM_TARGET_FOUNDATION_V8,
+KVM_ARM_TARGET_CORTEX_A57
+};
+
 int kvm_arch_init_vcpu(CPUState *cs)
 {
-return 0;
+struct kvm_vcpu_init init;
+int ret, i;
+
+memset(init.features, 0, sizeof(init.features));
+/* Find an appropriate target CPU type.
+ * KVM does not provide means to detect the host CPU type on aarch64,
+ * and simply refuses to initialize, if the CPU type mis-matches;
+ * so we try each possible CPU type on aarch64 before giving up! */
+for (i = 0; i < KVM_ARM_NUM_TARGETS; ++i) {
+init.target = kvm_arm_targets[i];
+ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+if (!ret)
+break;
+}
+
+return ret;
 }
 
 int kvm_arch_put_registers(CPUState *cs, int level)
 {
-return 0;
+struct kvm_one_reg reg;
+int i;
+int ret;
+
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+
+for (i = 0; i < ARRAY_SIZE(env->xregs); i++) {
+reg.id = AARCH64_CORE_REG(regs.regs[i]);
+reg.addr = (uintptr_t) &env->xregs[i];
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+}
+
+reg.id = AARCH64_CORE_REG(regs.sp);
+reg.addr = (uintptr_t) &env->xregs[31];
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+reg.id = AARCH64_CORE_REG(regs.pstate);
+reg.addr = (uintptr_t) &env->pstate;
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+reg.id = AARCH64_CORE_REG(regs.pc);
+reg.addr = (uintptr_t) &env->pc;
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+/* TODO: Set Rest of Registers */
+return ret;
 }
 
 int kvm_arch_get_registers(CPUState *cs)
 {
-return 0;
+struct kvm_one_reg reg;
+int i;
+int ret;
+
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+
+for (i = 0; i < ARRAY_SIZE(env->xregs); i++) {
+reg.id = AARCH64_CORE_REG(regs.regs[i]);
+reg.addr = (uintptr_t) &env->xregs[i];
+ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+}
+
+reg.id = AARCH64_CORE_REG(regs.sp);
+reg.addr = (uintptr_t) &env->xregs[31];
+ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+reg.id = AARCH64_CORE_REG(regs.pstate);
+reg.addr = (uintptr_t) &env->pstate;
+ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+reg.id = AARCH64_CORE_REG(regs.pc);
+reg.addr = (uintptr_t) &env->pc;
+ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+/* TODO: Set Rest of Registers */
+return ret;
 }
 
 void kvm_arch_reset_vcpu(CPUState *cs)
-- 
1.8.1.2




[Qemu-devel] [PATCH v3 04/11] AARCH64: Separate 32-bit specific code from common KVM hooks

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This commit separates the 32-bit (ARMv7) specific KVM hooks from
the common code. It also adds the stub functions for 64-bit (ARMv8).

The makefile objects are also tweaked accordingly to compile code
either of ARMv7 or ARMv8 depending on the AARCH64 variable.

Signed-off-by: Mian M. Hamayun 
---
 target-arm/Makefile.objs |   5 +
 target-arm/kvm.c | 363 
 target-arm/kvm_32.c  | 382 +++
 target-arm/kvm_64.c  |  39 +
 4 files changed, 426 insertions(+), 363 deletions(-)
 create mode 100644 target-arm/kvm_32.c
 create mode 100644 target-arm/kvm_64.c

diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index 6453f5c..4b37d29 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -1,6 +1,11 @@
 obj-y += arm-semi.o
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-$(CONFIG_KVM) += kvm.o
+ifeq ($(TARGET_AARCH64),y)
+obj-$(CONFIG_KVM) += kvm_64.o
+else
+obj-$(CONFIG_KVM) += kvm_32.o
+endif
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += translate.o op_helper.o helper.o cpu.o
 obj-y += neon_helper.o iwmmxt_helper.o
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index b92e00d..8e608c9 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -50,130 +50,6 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
 return cpu->cpu_index;
 }
 
-static bool reg_syncs_via_tuple_list(uint64_t regidx)
-{
-/* Return true if the regidx is a register we should synchronize
- * via the cpreg_tuples array (ie is not a core reg we sync by
- * hand in kvm_arch_get/put_registers())
- */
-switch (regidx & KVM_REG_ARM_COPROC_MASK) {
-case KVM_REG_ARM_CORE:
-case KVM_REG_ARM_VFP:
-return false;
-default:
-return true;
-}
-}
-
-static int compare_u64(const void *a, const void *b)
-{
-return *(uint64_t *)a - *(uint64_t *)b;
-}
-
-int kvm_arch_init_vcpu(CPUState *cs)
-{
-struct kvm_vcpu_init init;
-int i, ret, arraylen;
-uint64_t v;
-struct kvm_one_reg r;
-struct kvm_reg_list rl;
-struct kvm_reg_list *rlp;
-ARMCPU *cpu = ARM_CPU(cs);
-
-init.target = KVM_ARM_TARGET_CORTEX_A15;
-memset(init.features, 0, sizeof(init.features));
-ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
-if (ret) {
-return ret;
-}
-/* Query the kernel to make sure it supports 32 VFP
- * registers: QEMU's "cortex-a15" CPU is always a
- * VFP-D32 core. The simplest way to do this is just
- * to attempt to read register d31.
- */
-r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | 31;
-r.addr = (uintptr_t)(&v);
-ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
-if (ret == -ENOENT) {
-return -EINVAL;
-}
-
-/* Populate the cpreg list based on the kernel's idea
- * of what registers exist (and throw away the TCG-created list).
- */
-rl.n = 0;
-ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, &rl);
-if (ret != -E2BIG) {
-return ret;
-}
-rlp = g_malloc(sizeof(struct kvm_reg_list) + rl.n * sizeof(uint64_t));
-rlp->n = rl.n;
-ret = kvm_vcpu_ioctl(cs, KVM_GET_REG_LIST, rlp);
-if (ret) {
-goto out;
-}
-/* Sort the list we get back from the kernel, since cpreg_tuples
- * must be in strictly ascending order.
- */
-qsort(&rlp->reg, rlp->n, sizeof(rlp->reg[0]), compare_u64);
-
-for (i = 0, arraylen = 0; i < rlp->n; i++) {
-if (!reg_syncs_via_tuple_list(rlp->reg[i])) {
-continue;
-}
-switch (rlp->reg[i] & KVM_REG_SIZE_MASK) {
-case KVM_REG_SIZE_U32:
-case KVM_REG_SIZE_U64:
-break;
-default:
-fprintf(stderr, "Can't handle size of register in kernel list\n");
-ret = -EINVAL;
-goto out;
-}
-
-arraylen++;
-}
-
-cpu->cpreg_indexes = g_renew(uint64_t, cpu->cpreg_indexes, arraylen);
-cpu->cpreg_values = g_renew(uint64_t, cpu->cpreg_values, arraylen);
-cpu->cpreg_vmstate_indexes = g_renew(uint64_t, cpu->cpreg_vmstate_indexes,
- arraylen);
-cpu->cpreg_vmstate_values = g_renew(uint64_t, cpu->cpreg_vmstate_values,
-arraylen);
-cpu->cpreg_array_len = arraylen;
-cpu->cpreg_vmstate_array_len = arraylen;
-
-for (i = 0, arraylen = 0; i < rlp->n; i++) {
-uint64_t regidx = rlp->reg[i];
-if (!reg_syncs_via_tuple_list(regidx)) {
-continue;
-}
-cpu->cpreg_indexes[arraylen] = regidx;
-arraylen++;
-}
-assert(cpu->cpreg_array_len == arraylen);
-
-if (!write_kvmstate_to_list(cpu)) {
-/* Shouldn't happen unless kernel is inconsistent about
- * wh

[Qemu-devel] [PATCH v3 02/11] AARCH64: add a57core

2013-09-27 Thread Mian M. Hamayun
From: John Rigby 

Just an copy of a15 with a57 substituting a15 for now.

Signed-off-by: John Rigby 
Signed-off-by: Mian M. Hamayun 
---
 hw/cpu/Makefile.objs |   1 +
 hw/cpu/a57mpcore.c   | 122 +++
 target-arm/cpu.c |   9 
 3 files changed, 132 insertions(+)
 create mode 100644 hw/cpu/a57mpcore.c

diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
index df287c1..22e9567 100644
--- a/hw/cpu/Makefile.objs
+++ b/hw/cpu/Makefile.objs
@@ -1,5 +1,6 @@
 obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
 obj-$(CONFIG_A9MPCORE) += a9mpcore.o
 obj-$(CONFIG_A15MPCORE) += a15mpcore.o
+obj-$(CONFIG_A57MPCORE) += a57mpcore.o
 obj-$(CONFIG_ICC_BUS) += icc_bus.o
 
diff --git a/hw/cpu/a57mpcore.c b/hw/cpu/a57mpcore.c
new file mode 100644
index 000..4be277f
--- /dev/null
+++ b/hw/cpu/a57mpcore.c
@@ -0,0 +1,122 @@
+/*
+ * Cortex-A57MPCore internal peripheral emulation.
+ *
+ * Copyright (c) 2012 Linaro Limited.
+ * Written by Peter Maydell.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/sysbus.h"
+#include "sysemu/kvm.h"
+
+/* A57MP private memory region.  */
+
+#define TYPE_A57MPCORE_PRIV "a57mpcore_priv"
+#define A57MPCORE_PRIV(obj) \
+OBJECT_CHECK(A57MPPrivState, (obj), TYPE_A57MPCORE_PRIV)
+
+typedef struct A57MPPrivState {
+/*< private >*/
+SysBusDevice parent_obj;
+/*< public >*/
+
+uint32_t num_cpu;
+uint32_t num_irq;
+MemoryRegion container;
+DeviceState *gic;
+} A57MPPrivState;
+
+static void a57mp_priv_set_irq(void *opaque, int irq, int level)
+{
+A57MPPrivState *s = (A57MPPrivState *)opaque;
+qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+}
+
+static int a57mp_priv_init(SysBusDevice *dev)
+{
+A57MPPrivState *s = A57MPCORE_PRIV(dev);
+SysBusDevice *busdev;
+const char *gictype = "arm_gic";
+
+if (kvm_irqchip_in_kernel()) {
+gictype = "kvm-arm-gic";
+}
+
+s->gic = qdev_create(NULL, gictype);
+qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+qdev_prop_set_uint32(s->gic, "revision", 2);
+qdev_init_nofail(s->gic);
+busdev = SYS_BUS_DEVICE(s->gic);
+
+/* Pass through outbound IRQ lines from the GIC */
+sysbus_pass_irq(dev, busdev);
+
+/* Pass through inbound GPIO lines to the GIC */
+qdev_init_gpio_in(DEVICE(dev), a57mp_priv_set_irq, s->num_irq - 32);
+
+/* Memory map (addresses are offsets from PERIPHBASE):
+ *  0x-0x0fff -- reserved
+ *  0x1000-0x1fff -- GIC Distributor
+ *  0x2000-0x2fff -- GIC CPU interface
+ *  0x4000-0x4fff -- GIC virtual interface control (not modelled)
+ *  0x5000-0x5fff -- GIC virtual interface control (not modelled)
+ *  0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
+ */
+memory_region_init(&s->container, OBJECT(s),
+   "a57mp-priv-container", 0x8000);
+memory_region_add_subregion(&s->container, 0x1000,
+sysbus_mmio_get_region(busdev, 0));
+memory_region_add_subregion(&s->container, 0x2000,
+sysbus_mmio_get_region(busdev, 1));
+
+sysbus_init_mmio(dev, &s->container);
+return 0;
+}
+
+static Property a57mp_priv_properties[] = {
+DEFINE_PROP_UINT32("num-cpu", A57MPPrivState, num_cpu, 1),
+/* The Cortex-A57MP may have anything from 0 to 224 external interrupt
+ * IRQ lines (with another 32 internal). We default to 128+32, which
+ * is the number provided by the Cortex-A57MP test chip in the
+ * Versatile Express A57 development board.
+ * Other boards may differ and should set this property appropriately.
+ */
+DEFINE_PROP_UINT32("num-irq", A57MPPrivState, num_irq, 160),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void a57mp_priv_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+k->init = a57mp_priv_init;
+dc->props = a57mp_priv_properties;
+/* We currently have no savable state */
+}
+
+static const TypeInfo a57mp_priv_info = {
+.name  

[Qemu-devel] [PATCH v3 00/11] AARCH64 support on machvirt machine model using KVM

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This is the v3 of patch series that implements KVM support in QEMU for the ARMv8
Cortex A57 CPU. It depends on the recently mainlined AArch64 preparation patch
series and machvirt patches version v7, and uses the already available KVM 
in-kernel GIC support. 
This implementation supports both 64-bit and 32-bit guests on AARCH64.

As a reference, KVM Tool and the AArch64 bootwrapper were used, as well as
public documentation from ARM. The following work has been tested with SMP
capabilities for both 64 and 32-bit guests, under ARMv8 Fast and Foundation 
Models (Open Embedded userspace with an emulated MMC).

The v1 of this patch series related to AArch64 CPU model for Versatile Express
was sponsored by Huawei, and developed in collaboration between Huawei
Technologies Duesseldorf GmbH - European Research Center Munich (ERC) and
Virtual Open Systems.

A working tree of this implementation is available on the "kvm-aarch64-v3"
branch of the following github repository.

https://github.com/virtualopensystems/qemu/tree/kvm-aarch64-v3

Summary of Changes:

Changes v2 -> v3
 * Based on AArch64 Preparation Patchset (mainlined) and machvirt patch version 
v7
 * 32 and 64-bit KVM hooks have been separated into kvm_32.c and kvm_64.c, 
whereas
   common code resides in kvm.c
 * SMP support is now implemented using PSCI method instead of the boot 
injection
   mechanism, as implemented in the previous versions
 * 32-bit SMP guest support is now available

Changes v1 -> v2
 * Based on AArch64 Preparation Patchset V5 and machvirt patches.
 * Implemented for Machvirt Machine Model.
 * Architecture-specific CPU initialization code improved. Removed hardcoding
   from register set/get loops and introduced CPU target type array to find
   appropriate ARMv8 CPU type supported by KVM.
 * Disable the PSCI method in case of AArch64 and use the spin-table method
   instead for booting secondary CPUs.
 * 32-bit guest support still missing

v1
 * Based on AArch64 Preparation Patchset V4
 * Implemented for Versatile Express Machine Model
 * Support for SMP using bootcode injection
 * No 32-bit guest support

John Rigby (2):
  ARM: arm64 kvm headers from kernel arm64-kvm tree
  AARCH64: add a57core

Mian M. Hamayun (9):
  AARCH64: Add A57 CPU to default AArch64 configuration and enable KVM
  AARCH64: Separate 32-bit specific code from common KVM hooks
  AARCH64: Add AARCH64 CPU initialization, get and put registers support
  target-arm: Parameterize the bootloader selection and setup mechanism
  AARCH64: Add boot support for aarch64 processor
  AARCH64: Enable SMP support for aarch64 processors using PSCI method
  AARCH64: Enable configure support for 32-bit guests on AARCH64
  AARCH64: Add flags and boot parameters for 32-bit guests on AARCH64
  AARCH64: Add 32-bit mode selection parameter

 configure   |   3 +-
 default-configs/aarch64-softmmu.mak |   1 +
 hw/arm/boot.c   | 147 --
 hw/arm/virt.c   |   8 +
 hw/cpu/Makefile.objs|   1 +
 hw/cpu/a57mpcore.c  | 122 
 linux-headers/asm-arm64/kvm.h   | 168 
 linux-headers/asm-arm64/kvm_para.h  |   1 +
 linux-headers/linux/kvm.h   |   1 +
 qemu-options.hx |   8 +
 target-arm/Makefile.objs|   5 +
 target-arm/cpu.c|  18 +-
 target-arm/kvm.c| 363 --
 target-arm/kvm_32.c | 382 
 target-arm/kvm_64.c | 146 ++
 vl.c|   4 +
 16 files changed, 997 insertions(+), 381 deletions(-)
 create mode 100644 hw/cpu/a57mpcore.c
 create mode 100644 linux-headers/asm-arm64/kvm.h
 create mode 100644 linux-headers/asm-arm64/kvm_para.h
 create mode 100644 target-arm/kvm_32.c
 create mode 100644 target-arm/kvm_64.c

-- 
1.8.1.2




[Qemu-devel] [PATCH v3 10/11] AARCH64: Add flags and boot parameters for 32-bit guests on AARCH64

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This commit adds the necessary flags and kernel load address to enable
booting of 32-bit guests on AArch64 processors.

The actual enable/disable mechanism is not included in this commit,
which should tweak the value of env->aarch64 variable for this purpose.

Signed-off-by: Mian M. Hamayun 
---
 hw/arm/boot.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index ddafd3b..2cfa9bf 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -20,6 +20,10 @@
 #define KERNEL_ARGS_ADDR 0x100
 
 #ifdef TARGET_AARCH64
+#define COMPAT_PSR_F_BIT0x0040
+#define COMPAT_PSR_I_BIT0x0080
+#define COMPAT_PSR_MODE_SVC 0x0013
+
 static uint32_t bootloader_arm64[] = {
 0x58c0,/* ldr  x0, 18 ; Load the lower 32-bits of DTB */
 0xaa1f03e1,/* mov  x1, xzr */
@@ -144,7 +148,8 @@ static void setup_boot_env(ARMCPU *cpu)
 }
 else {
 /* AARCH32 Mode */
-/* TODO: Specify Kernel Load Address for AARCH32 */
+kernel_load_addr = 0x8000;
+setup_boot_env_32();
 }
 #else
 /* ARMv7 */
@@ -431,7 +436,7 @@ static void do_cpu_reset(void *opaque)
 if(env->aarch64) {
 env->pstate = PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | 
PSR_MODE_EL1h;
 } else {
-hw_error("AArch32 mode is currently not supported\n");
+env->pstate = COMPAT_PSR_I_BIT | COMPAT_PSR_F_BIT | 
COMPAT_PSR_MODE_SVC;
 }
 env->xregs[0] =  0;
 env->xregs[1] = -1;
-- 
1.8.1.2




[Qemu-devel] [PATCH v3 09/11] AARCH64: Enable configure support for 32-bit guests on AARCH64

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

Signed-off-by: Mian M. Hamayun 
---
 configure | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configure b/configure
index 7298b69..dbaf56f 100755
--- a/configure
+++ b/configure
@@ -4485,6 +4485,7 @@ case "$target_name" in
 # Make sure the target and host cpus are compatible
 if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
   \( "$target_name" = "$cpu" -o \
+  \( "$target_name" = "arm" -a "$cpu" = "aarch64" \) -o \
   \( "$target_name" = "ppcemb" -a "$cpu" = "ppc" \) -o \
   \( "$target_name" = "ppc64"  -a "$cpu" = "ppc" \) -o \
   \( "$target_name" = "ppc"-a "$cpu" = "ppc64" \) -o \
-- 
1.8.1.2




[Qemu-devel] [PATCH v3 08/11] AARCH64: Enable SMP support for aarch64 processors using PSCI method

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

We enable SMP support for aarch64 processors using the PSCI method,
by setting the appropriate CPU feature flags at initilializtion time.

Secondary boot code for non-aarch64 processors is disabled in case
of compilation for aarch64.

Signed-off-by: Mian M. Hamayun 
---
 hw/arm/boot.c   | 4 
 target-arm/kvm_64.c | 7 +++
 2 files changed, 11 insertions(+)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 0471eb8..ddafd3b 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -157,6 +157,7 @@ static void setup_boot_env(ARMCPU *cpu)
 static void default_write_secondary(ARMCPU *cpu,
 const struct arm_boot_info *info)
 {
+#ifndef TARGET_AARCH64
 int n;
 smpboot[smpboot_array_size - 1] = info->smp_bootreg_addr;
 smpboot[smpboot_array_size - 2] = info->gic_cpu_if_addr;
@@ -171,15 +172,18 @@ static void default_write_secondary(ARMCPU *cpu,
 rom_add_blob_fixed("smpboot", smpboot,
smpboot_array_size * sizeof(uint32_t),
info->smp_loader_start);
+#endif
 }
 
 static void default_reset_secondary(ARMCPU *cpu,
 const struct arm_boot_info *info)
 {
+#ifndef TARGET_AARCH64
 CPUARMState *env = &cpu->env;
 
 stl_phys_notdirty(info->smp_bootreg_addr, 0);
 env->regs[15] = info->smp_loader_start;
+#endif
 }
 
 #define WRITE_WORD(p, value) do { \
diff --git a/target-arm/kvm_64.c b/target-arm/kvm_64.c
index 9685727..146b7c4 100644
--- a/target-arm/kvm_64.c
+++ b/target-arm/kvm_64.c
@@ -27,12 +27,19 @@ static uint32_t kvm_arm_targets[KVM_ARM_NUM_TARGETS] = {
 KVM_ARM_TARGET_CORTEX_A57
 };
 
+#define ARM_VCPU_FEATURE_FLAGS(cpuid, is_aarch32)  \
+((!!(cpuid) << KVM_ARM_VCPU_POWER_OFF) | (is_aarch32 << 
KVM_ARM_VCPU_EL1_32BIT))
+
 int kvm_arch_init_vcpu(CPUState *cs)
 {
 struct kvm_vcpu_init init;
 int ret, i;
 
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+
 memset(init.features, 0, sizeof(init.features));
+init.features[0] = ARM_VCPU_FEATURE_FLAGS(cs->cpu_index, !env->aarch64);
 /* Find an appropriate target CPU type.
  * KVM does not provide means to detect the host CPU type on aarch64,
  * and simply refuses to initialize, if the CPU type mis-matches;
-- 
1.8.1.2




[Qemu-devel] [PATCH v3 06/11] target-arm: Parameterize the bootloader selection and setup mechanism

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This commit replaces the constant indices used in bootloaders, such as for
specifying the Board ID and kernel arguments with variable parameters.
This change is used as mechanism to minimize code changes for different
bootloaders, for example different bootloaders will be used for different
architectures (ARMv7 vs. ARMv8).

Similary pointers are introduced to select appropriate bootloaders for boot
and secondary cpus.

Signed-off-by: Mian M. Hamayun 
---
 hw/arm/boot.c | 81 ---
 1 file changed, 66 insertions(+), 15 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 967397b..4c1170e 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -18,10 +18,9 @@
 #include "qemu/config-file.h"
 
 #define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x0001
 
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
-static uint32_t bootloader[] = {
+static uint32_t bootloader_arm32[] = {
   0xe3a0, /* mov r0, #0 */
   0xe59f1004, /* ldr r1, [pc, #4] */
   0xe59f2004, /* ldr r2, [pc, #4] */
@@ -48,7 +47,7 @@ static uint32_t bootloader[] = {
 #define DSB_INSN 0xf57ff04f
 #define CP15_DSB_INSN 0xee070f9a /* mcr cp15, 0, r0, c7, c10, 4 */
 
-static uint32_t smpboot[] = {
+static uint32_t smpboot_arm32[] = {
   0xe59f2028, /* ldr r2, gic_cpu_if */
   0xe59f0028, /* ldr r0, startaddr */
   0xe3a01001, /* mov r1, #1 */
@@ -65,13 +64,60 @@ static uint32_t smpboot[] = {
   0   /* bootreg: Boot register address is held here */
 };
 
+/*
+ * The bootloaders to be used are referenced by the following pointers
+ * An appropriate bootloader is selected depending on the architecture
+ * i.e. ARMv7, ARMv8 (AARCH64 and AARCH32)
+ */
+static uint32_t *bootloader = NULL;
+static uint32_t  bootloader_array_size = 0;
+
+static uint32_t *smpboot = NULL;
+static uint32_t  smpboot_array_size = 0;
+
+/*
+ * An index gives the location in the bootloader array, where we put the board
+ * ID, kernel arguments and kernel entry addresses. These are different for
+ * ARMv7 and ARMv8 bootloaders defined above.
+ */
+static uint32_t kernel_boardid_index = 0;
+static uint32_t kernel_args_index= 0;
+static uint32_t kernel_entry_index   = 0;
+
+/*
+ * Similarly, the kernel loading address also depends on the architecture,
+ * i.e. its different for ARMv7, ARMv8 (AARCH64 and AARCH32)
+ */
+static uint32_t kernel_load_addr = 0x0;
+
+static void setup_boot_env_32(void)
+{
+bootloader = bootloader_arm32;
+bootloader_array_size = ARRAY_SIZE(bootloader_arm32);
+smpboot = smpboot_arm32;
+smpboot_array_size = ARRAY_SIZE(smpboot_arm32);
+
+kernel_boardid_index = bootloader_array_size - 3;
+kernel_args_index= bootloader_array_size - 2;
+kernel_entry_index   = bootloader_array_size - 1;
+return;
+}
+
+static void setup_boot_env(ARMCPU *cpu)
+{
+/* ARMv7 */
+kernel_load_addr = 0x0001;
+setup_boot_env_32();
+return;
+}
+
 static void default_write_secondary(ARMCPU *cpu,
 const struct arm_boot_info *info)
 {
 int n;
-smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
-smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
-for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
+smpboot[smpboot_array_size - 1] = info->smp_bootreg_addr;
+smpboot[smpboot_array_size - 2] = info->gic_cpu_if_addr;
+for (n = 0; n < smpboot_array_size; n++) {
 /* Replace DSB with the pre-v7 DSB if necessary. */
 if (!arm_feature(&cpu->env, ARM_FEATURE_V7) &&
 smpboot[n] == DSB_INSN) {
@@ -79,7 +125,8 @@ static void default_write_secondary(ARMCPU *cpu,
 }
 smpboot[n] = tswap32(smpboot[n]);
 }
-rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
+rom_add_blob_fixed("smpboot", smpboot,
+   smpboot_array_size * sizeof(uint32_t),
info->smp_loader_start);
 }
 
@@ -360,6 +407,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 hwaddr entry;
 int big_endian;
 
+/* Select the bootloader to use and setup array indices, kernel entry etc 
*/
+setup_boot_env(cpu);
+
 /* Load the kernel.  */
 if (!info->kernel_filename) {
 fprintf(stderr, "Kernel image must be specified\n");
@@ -406,9 +456,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
   &is_linux);
 }
 if (kernel_size < 0) {
-entry = info->loader_start + KERNEL_LOAD_ADDR;
+entry = info->loader_start + kernel_load_addr;
 kernel_size = load_image_targphys(info->kernel_filename, entry,
-  info->ram_size - KERNEL_LOAD_ADDR);
+  info->ram_size - kernel_load_addr);
   

[Qemu-devel] [PATCH v3 07/11] AARCH64: Add boot support for aarch64 processor

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This commit adds support for booting a single AArch64 CPU by setting
appropriate registers. The bootloader includes placehoders for Board-ID
that are used to implement uniform indexing across different bootloaders.
We also introduce Cortex-A57 to virt platform.

Signed-off-by: Mian M. Hamayun 
---
 hw/arm/boot.c | 57 +
 hw/arm/virt.c |  8 
 2 files changed, 65 insertions(+)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 4c1170e..0471eb8 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -19,6 +19,23 @@
 
 #define KERNEL_ARGS_ADDR 0x100
 
+#ifdef TARGET_AARCH64
+static uint32_t bootloader_arm64[] = {
+0x58c0,/* ldr  x0, 18 ; Load the lower 32-bits of DTB */
+0xaa1f03e1,/* mov  x1, xzr */
+0xaa1f03e2,/* mov  x2, xzr */
+0xaa1f03e3,/* mov  x3, xzr */
+0x5884,/* ldr  x4, 20 ; Load the lower 32-bits of kernel entry 
*/
+0xd61f0080,/* br   x4 ; Jump to the kernel entry point */
+0x,/* .word @DTB Lower 32-bits */
+0x,/* .word @DTB Higher 32-bits */
+0x,/* .word @Kernel Entry Lower 32-bits */
+0x,/* .word @Kernel Entry Higher 32-bits */
+0x,/* .word @Board ID Lower 32-bits -- Placeholder */
+0x /* .word @Board ID Higher 32-bits -- Placeholder */
+};
+#endif
+
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
 static uint32_t bootloader_arm32[] = {
   0xe3a0, /* mov r0, #0 */
@@ -103,11 +120,37 @@ static void setup_boot_env_32(void)
 return;
 }
 
+#ifdef TARGET_AARCH64
+static void setup_boot_env_64(void)
+{
+bootloader = bootloader_arm64;
+bootloader_array_size = ARRAY_SIZE(bootloader_arm64);
+
+kernel_args_index= bootloader_array_size - 6;
+kernel_entry_index   = bootloader_array_size - 4;
+kernel_boardid_index = bootloader_array_size - 2;
+return;
+}
+#endif
+
 static void setup_boot_env(ARMCPU *cpu)
 {
+#ifdef TARGET_AARCH64
+CPUARMState *env = &cpu->env;
+if(env->aarch64) {
+/* AARCH64 Mode */
+kernel_load_addr = 0x0008;
+setup_boot_env_64();
+}
+else {
+/* AARCH32 Mode */
+/* TODO: Specify Kernel Load Address for AARCH32 */
+}
+#else
 /* ARMv7 */
 kernel_load_addr = 0x0001;
 setup_boot_env_32();
+#endif
 return;
 }
 
@@ -380,8 +423,22 @@ static void do_cpu_reset(void *opaque)
 env->regs[15] = info->entry & 0xfffe;
 env->thumb = info->entry & 1;
 } else {
+#ifdef TARGET_AARCH64
+if(env->aarch64) {
+env->pstate = PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | 
PSR_MODE_EL1h;
+} else {
+hw_error("AArch32 mode is currently not supported\n");
+}
+env->xregs[0] =  0;
+env->xregs[1] = -1;
+#endif
 if (CPU(cpu) == first_cpu) {
+#ifdef TARGET_AARCH64
+env->xregs[2] = bootloader[kernel_args_index];
+env->pc = info->loader_start;
+#else
 env->regs[15] = info->loader_start;
+#endif
 if (!info->dtb_filename) {
 if (old_param) {
 set_kernel_args_old(info);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 448a0e5..8043fd4 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -118,6 +118,14 @@ static VirtBoardInfo machines[] = {
 .memmap = a15memmap,
 .irqmap = a15irqmap,
 },
+{
+.cpu_model = "cortex-a57",
+.cpu_compatible = "arm,arm-v8",
+.qdevname = "a57mpcore_priv",
+.gic_compatible = "arm,cortex-a15-gic",
+.memmap = a15memmap,
+.irqmap = a15irqmap,
+},
 };
 
 static VirtBoardInfo *find_machine_info(const char *cpu)
-- 
1.8.1.2




[Qemu-devel] [PATCH v3 11/11] AARCH64: Add 32-bit mode selection parameter

2013-09-27 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This commit introduces a commandline argument to select the
AARCH64 or AARCH32 mode for processor initilization.

Signed-off-by: Mian M. Hamayun 
---
 qemu-options.hx  | 8 
 target-arm/cpu.c | 9 +++--
 vl.c | 4 
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 5dc8b75..a2dab99 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -72,6 +72,14 @@ STEXI
 Select CPU model (@code{-cpu help} for list and additional feature selection)
 ETEXI
 
+DEF("aarch32-mode", 0, QEMU_OPTION_aarch32_mode, \
+"-aarch32-mode   enable aarch32 mode support on aarch64\n", QEMU_ARCH_ARM)
+STEXI
+@item -aarch32-mode
+@findex -aarch32-mode
+Enable aarch32 guest support on aarch64.
+ETEXI
+
 DEF("smp", HAS_ARG, QEMU_OPTION_smp,
 "-smp 
[cpus=]n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets]\n"
 "set the number of CPUs to 'n' [default=1]\n"
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 5d811b9..56e8e56 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -27,6 +27,8 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/kvm.h"
 
+extern int aarch32_mode;
+
 static void arm_cpu_set_pc(CPUState *cs, vaddr value)
 {
 ARMCPU *cpu = ARM_CPU(cs);
@@ -85,8 +87,11 @@ static void arm_cpu_reset(CPUState *s)
 }
 
 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
-/* 64 bit CPUs always start in 64 bit mode */
-env->aarch64 = 1;
+if(aarch32_mode) {
+env->aarch64 = 0;  /* Boot a 32-bit Guest */
+} else {
+env->aarch64 = 1;  /* Boot a 64-bit Guest */
+}
 }
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/vl.c b/vl.c
index 4e709d5..e0f2cf3 100644
--- a/vl.c
+++ b/vl.c
@@ -207,6 +207,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
 CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
 int win2k_install_hack = 0;
 int singlestep = 0;
+int aarch32_mode = 0;
 int smp_cpus = 1;
 int max_cpus = 0;
 int smp_cores = 1;
@@ -3113,6 +3114,9 @@ int main(int argc, char **argv, char **envp)
 case QEMU_OPTION_dtb:
 qemu_opts_set(qemu_find_opts("machine"), 0, "dtb", optarg);
 break;
+case QEMU_OPTION_aarch32_mode:
+aarch32_mode = 1;
+break;
 case QEMU_OPTION_cdrom:
 drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS);
 break;
-- 
1.8.1.2




[Qemu-devel] [PATCH v3 01/11] ARM: arm64 kvm headers from kernel arm64-kvm tree

2013-09-27 Thread Mian M. Hamayun
From: John Rigby 

Also add the KVM_REG_ARM64 register type to linux/kvm header file.

Signed-off-by: John Rigby 
Signed-off-by: Mian M. Hamayun 
---
 linux-headers/asm-arm64/kvm.h  | 168 +
 linux-headers/asm-arm64/kvm_para.h |   1 +
 linux-headers/linux/kvm.h  |   1 +
 3 files changed, 170 insertions(+)
 create mode 100644 linux-headers/asm-arm64/kvm.h
 create mode 100644 linux-headers/asm-arm64/kvm_para.h

diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
new file mode 100644
index 000..5031f42
--- /dev/null
+++ b/linux-headers/asm-arm64/kvm.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier 
+ *
+ * Derived from arch/arm/include/uapi/asm/kvm.h:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall 
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_KVM_H__
+#define __ARM_KVM_H__
+
+#define KVM_SPSR_EL1   0
+#define KVM_SPSR_SVC   KVM_SPSR_EL1
+#define KVM_SPSR_ABT   1
+#define KVM_SPSR_UND   2
+#define KVM_SPSR_IRQ   3
+#define KVM_SPSR_FIQ   4
+#define KVM_NR_SPSR5
+
+#ifndef __ASSEMBLY__
+#include 
+#include 
+
+#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_IRQ_LINE
+
+#define KVM_REG_SIZE(id)   \
+   (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
+struct kvm_regs {
+   struct user_pt_regs regs;   /* sp = sp_el0 */
+
+   __u64   sp_el1;
+   __u64   elr_el1;
+
+   __u64   spsr[KVM_NR_SPSR];
+
+   struct user_fpsimd_state fp_regs;
+};
+
+/* Supported Processor Types */
+#define KVM_ARM_TARGET_AEM_V8  0
+#define KVM_ARM_TARGET_FOUNDATION_V8   1
+#define KVM_ARM_TARGET_CORTEX_A57  2
+
+#define KVM_ARM_NUM_TARGETS3
+
+/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
+#define KVM_ARM_DEVICE_TYPE_SHIFT  0
+#define KVM_ARM_DEVICE_TYPE_MASK   (0x << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_ID_SHIFT16
+#define KVM_ARM_DEVICE_ID_MASK (0x << KVM_ARM_DEVICE_ID_SHIFT)
+
+/* Supported device IDs */
+#define KVM_ARM_DEVICE_VGIC_V2 0
+
+/* Supported VGIC address types  */
+#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
+#define KVM_VGIC_V2_ADDR_TYPE_CPU  1
+
+#define KVM_VGIC_V2_DIST_SIZE  0x1000
+#define KVM_VGIC_V2_CPU_SIZE   0x2000
+
+#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
+#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
+
+struct kvm_vcpu_init {
+   __u32 target;
+   __u32 features[7];
+};
+
+struct kvm_sregs {
+};
+
+struct kvm_fpu {
+};
+
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+struct kvm_sync_regs {
+};
+
+struct kvm_arch_memory_slot {
+};
+
+/* If you need to interpret the index values, here is the key: */
+#define KVM_REG_ARM_COPROC_MASK0x0FFF
+#define KVM_REG_ARM_COPROC_SHIFT   16
+
+/* Normal registers are mapped as coprocessor 16. */
+#define KVM_REG_ARM_CORE   (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 
sizeof(__u32))
+
+/* Some registers need more space to represent values. */
+#define KVM_REG_ARM_DEMUX  (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_DEMUX_ID_MASK  0xFF00
+#define KVM_REG_ARM_DEMUX_ID_SHIFT 8
+#define KVM_REG_ARM_DEMUX_ID_CCSIDR(0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
+#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00FF
+#define KVM_REG_ARM_DEMUX_VAL_SHIFT0
+
+/* AArch64 system registers */
+#define KVM_REG_ARM64_SYSREG   (0x0013 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM64_SYSREG_OP0_MASK  0xc000
+#define KVM_REG_ARM64_SYSREG_OP0_SHIFT 14
+#define KVM_REG_ARM64_SYSREG_OP1_MASK  0x3800
+#define KVM_REG_ARM64_SYSREG_OP1_SHIFT 11
+#define KVM_REG_ARM64_SYSREG_CRN_MASK  0x0780
+#define KVM_REG_ARM64_SYSREG_CRN_SHIFT 7
+#define KVM_REG_ARM64_SYSREG_CRM_MASK  0x0078
+#define KVM_REG_ARM64_SYSREG_CRM_SHIFT 3
+#define KVM_REG_ARM64_SYSREG_OP2_MASK  0x0007
+#define KVM_REG_ARM64_SYSREG_OP2_SHIFT 0
+
+/* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_TYPE_SHIFT 24
+#define KVM_ARM_I

Re: [Qemu-devel] [PATCH v2 7/7] AARCH64: Use the spin-table method for booting secondary processors in machvirt

2013-08-09 Thread Mian M. Hamayun

On 09/08/2013 16:34, Peter Maydell wrote:

On 23 July 2013 10:33, Mian M. Hamayun  wrote:

From: "Mian M. Hamayun" 

As the SMP bootloader uses a spin-table to wait for the cpu_release_addr, we
disable the PSCI method for AArch64 in machvirt and use spin-table instead.

Marc Z says we should be using PSCI for secondary CPU boot for aarch64,
same as for aarch32.


OK, we will look into this as well.
Thanks!



Re: [Qemu-devel] [PATCH v2 3/7] AARCH64: Add aarch64 CPU initialization, get and put registers support

2013-08-09 Thread Mian M. Hamayun

On 09/08/2013 15:24, Peter Maydell wrote:

On 23 July 2013 10:33, Mian M. Hamayun  wrote:

From: "Mian M. Hamayun" 

The cpu init function tries to initialize with all possible cpu types, as
KVM does not provide a means to detect the real cpu type and simply refuses
to initialize on cpu type mis-match. By using the loop based init function,
we avoid the need to modify code if the underlying platform is different,
such as Fast Models instead of Foundation Models.

Get and Put Registers deal with the basic state of Aarch64 CPUs for the moment.

Signed-off-by: Mian M. Hamayun 

Conflicts:

 target-arm/kvm.c

Conflicts:

 target-arm/cpu.c

This sort of Conflicts note shouldn't be in a commit message.

Agreed, will remove it in the next revision.



---
  linux-headers/linux/kvm.h |1 +
  target-arm/kvm.c  |  125 +
  2 files changed, 126 insertions(+)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index c614070..4df5292 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -783,6 +783,7 @@ struct kvm_dirty_tlb {
  #define KVM_REG_IA64   0x3000ULL
  #define KVM_REG_ARM0x4000ULL
  #define KVM_REG_S390   0x5000ULL
+#define KVM_REG_ARM64  0x6000ULL

  #define KVM_REG_SIZE_SHIFT 52
  #define KVM_REG_SIZE_MASK  0x00f0ULL

Updates to the linux-headers/ files need to:
  * be a separate patch
  * be the result of running scripts/update-linux-headers.sh
on an upstream mainline kernel or kvm-next kernel tree
  * include the kernel tree/commit hash in the commit message

Agreed, will do it like this.



diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index b92e00d..c96b871 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -32,6 +32,11 @@
  #error mismatch between cpu.h and KVM header definitions
  #endif

+#ifdef TARGET_AARCH64
+#define AARCH64_CORE_REG(x)   (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
+ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
+#endif
+
  const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
  KVM_CAP_LAST_INFO
  };
@@ -50,6 +55,33 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
  return cpu->cpu_index;
  }

+#ifdef TARGET_AARCH64

This set of #ifdefs is pretty messy. I suggest splitting kvm.c
into three:
   target-arm/kvm.c   -- anything common to both 32 and 64 bit
   target-arm/kvm32.c -- non-TARGET_AARCH64 functions
   target-arm/kvm64.c -- TARGET_AARCH64 functions

and have target-arm/Makefile.objs build only one of kvm32.c
or kvm64.c depending on whether TARGET_AARCH64 is set.

My initial intuition was to separate 32 and 64 bit versions, but as
many functions are common, so I decided to use #ifdefs instead.
btw, I have a similar situation in hw/arm/boot.c as well.



+/* Find an appropriate target CPU type.
+ * KVM does not provide means to detect the host CPU type on aarch64,
+ * and simply refuses to initialize, if the CPU type mis-matches;
+ * so we try each possible CPU type on aarch64 before giving up! */
+for (i = 0; i < KVM_ARM_NUM_TARGETS; ++i) {
+init.target = kvm_arm_targets[i];
+ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+if (!ret)
+break;
+}

We definitely don't want to do this -- see my notes on
'-cpu host' in another email thread.  (We should make sure
we coordinate who of you or Linaro is going to do the
-cpu host support, incidentally.)

I tend to agree with this proposition as well. But the point that I don't
understand is how something is acceptable in kvmtool and not in the
qemu. If this implementation lets us use the 64-bit architecture in the
current state of affairs, then why not use it. We can always replace
this particular part, when the -cpu host support becomes available, right ?

Hamayun




[Qemu-devel] [PATCH v2 7/7] AARCH64: Use the spin-table method for booting secondary processors in machvirt

2013-07-23 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

As the SMP bootloader uses a spin-table to wait for the cpu_release_addr, we
disable the PSCI method for AArch64 in machvirt and use spin-table instead.

The CPU_RELEASE_OFFSET is introduced in machvirt and is to calculate the
cpu_release_addr by addition of this value to the memory base address, and this
value is updated in the smp bootloader using the smp_bootreg_addr board info
parameter.

Tested-by: Alexander Spyridakis 
Signed-off-by: Mian M. Hamayun 
---
 hw/arm/virt.c |   14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 8a2bdc7..44ab59d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -52,6 +52,7 @@
 #define IO_LEN 0x000f
 
 #if defined(TARGET_AARCH64)
+#define CPU_RELEASE_OFFSET 0xfff8
 #define DEFAULT_CPU_MODEL "cortex-a57"
 #elif defined(TARGET_ARM)
 #define DEFAULT_CPU_MODEL "cortex-a15"
@@ -170,7 +171,7 @@ static void *initial_fdt(struct machine_info *mi)
 qemu_devtree_setprop_cell(fdt, "/soc", "#interrupt-cells", 0x1);
 
 /* No PSCI for TCG yet */
-#ifdef CONFIG_KVM
+#if defined (CONFIG_KVM) && !defined(TARGET_AARCH64)
 if (kvm_enabled()) {
 qemu_devtree_add_subnode(fdt, "/psci");
 qemu_devtree_setprop_string(fdt, "/psci", "compatible", "arm,psci");
@@ -234,7 +235,14 @@ static void fdt_add_cpu_nodes(void *fdt, struct 
machine_info *mi, int smp_cpus)
 mi->cpu_compatible);
 
 if (smp_cpus > 1) {
+#if defined(TARGET_AARCH64)
+qemu_devtree_setprop_string(fdt, cpu_name, "enable-method",
+"spin-table");
+qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr",
+(mi->mem_base + CPU_RELEASE_OFFSET));
+#else
 qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", 
"psci");
+#endif
 }
 
 qemu_devtree_setprop_cell(fdt, cpu_name, "reg", cpu);
@@ -437,6 +445,10 @@ static void machvirt_init(QEMUMachineInitArgs *args)
 machvirt_binfo.nb_cpus = smp_cpus;
 machvirt_binfo.board_id = -1;
 machvirt_binfo.loader_start = mi->mem_base;
+machvirt_binfo.smp_loader_start = mi->mem_base + 0x1000;
+#if defined(TARGET_AARCH64)
+machvirt_binfo.smp_bootreg_addr = mi->mem_base + CPU_RELEASE_OFFSET;
+#endif
 machvirt_binfo.get_dtb = machvirt_dtb;
 arm_load_kernel(arm_env_get_cpu(first_cpu), &machvirt_binfo);
 }
-- 
1.7.9.5




[Qemu-devel] [PATCH v2 3/7] AARCH64: Add aarch64 CPU initialization, get and put registers support

2013-07-23 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

The cpu init function tries to initialize with all possible cpu types, as
KVM does not provide a means to detect the real cpu type and simply refuses
to initialize on cpu type mis-match. By using the loop based init function,
we avoid the need to modify code if the underlying platform is different,
such as Fast Models instead of Foundation Models.

Get and Put Registers deal with the basic state of Aarch64 CPUs for the moment.

Signed-off-by: Mian M. Hamayun 

Conflicts:

target-arm/kvm.c

Conflicts:

target-arm/cpu.c
---
 linux-headers/linux/kvm.h |1 +
 target-arm/kvm.c  |  125 +
 2 files changed, 126 insertions(+)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index c614070..4df5292 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -783,6 +783,7 @@ struct kvm_dirty_tlb {
 #define KVM_REG_IA64   0x3000ULL
 #define KVM_REG_ARM0x4000ULL
 #define KVM_REG_S390   0x5000ULL
+#define KVM_REG_ARM64  0x6000ULL
 
 #define KVM_REG_SIZE_SHIFT 52
 #define KVM_REG_SIZE_MASK  0x00f0ULL
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index b92e00d..c96b871 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -32,6 +32,11 @@
 #error mismatch between cpu.h and KVM header definitions
 #endif
 
+#ifdef TARGET_AARCH64
+#define AARCH64_CORE_REG(x)   (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
+ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
+#endif
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
 };
@@ -50,6 +55,33 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
 return cpu->cpu_index;
 }
 
+#ifdef TARGET_AARCH64
+static uint32_t kvm_arm_targets[KVM_ARM_NUM_TARGETS] = {
+KVM_ARM_TARGET_AEM_V8,
+KVM_ARM_TARGET_FOUNDATION_V8,
+KVM_ARM_TARGET_CORTEX_A57
+};
+
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+struct kvm_vcpu_init init;
+int ret, i;
+
+memset(init.features, 0, sizeof(init.features));
+/* Find an appropriate target CPU type.
+ * KVM does not provide means to detect the host CPU type on aarch64,
+ * and simply refuses to initialize, if the CPU type mis-matches;
+ * so we try each possible CPU type on aarch64 before giving up! */
+for (i = 0; i < KVM_ARM_NUM_TARGETS; ++i) {
+init.target = kvm_arm_targets[i];
+ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+if (!ret)
+break;
+}
+
+return ret;
+}
+#else
 static bool reg_syncs_via_tuple_list(uint64_t regidx)
 {
 /* Return true if the regidx is a register we should synchronize
@@ -173,6 +205,7 @@ out:
 g_free(rlp);
 return ret;
 }
+#endif
 
 /* We track all the KVM devices which need their memory addresses
  * passing to the kernel in a list of these structures.
@@ -339,6 +372,7 @@ typedef struct Reg {
 int offset;
 } Reg;
 
+#ifndef TARGET_AARCH64
 #define COREREG(KERNELNAME, QEMUFIELD)   \
 {\
 KVM_REG_ARM | KVM_REG_SIZE_U32 | \
@@ -402,7 +436,52 @@ static const Reg regs[] = {
 VFPSYSREG(FPINST),
 VFPSYSREG(FPINST2),
 };
+#endif
 
+#ifdef TARGET_AARCH64
+int kvm_arch_put_registers(CPUState *cs, int level)
+{
+struct kvm_one_reg reg;
+int i;
+int ret;
+
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+
+for (i = 0; i < ARRAY_SIZE(env->xregs); i++) {
+reg.id = AARCH64_CORE_REG(regs.regs[i]);
+reg.addr = (uintptr_t) &env->xregs[i];
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+}
+
+reg.id = AARCH64_CORE_REG(regs.sp);
+reg.addr = (uintptr_t) &env->xregs[31];
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+reg.id = AARCH64_CORE_REG(regs.pstate);
+reg.addr = (uintptr_t) &env->pstate;
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+reg.id = AARCH64_CORE_REG(regs.pc);
+reg.addr = (uintptr_t) &env->pc;
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+
+/* TODO: Set Rest of Registers */
+return ret;
+}
+#else
 int kvm_arch_put_registers(CPUState *cs, int level)
 {
 ARMCPU *cpu = ARM_CPU(cs);
@@ -488,7 +567,52 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 
 return ret;
 }
+#endif
 
+#ifdef TARGET_AARCH64
+int kvm_arch_get_registers(CPUState *cs)
+{
+struct kvm_one_reg reg;
+int i;
+int ret;
+
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+
+for (i = 0; i < ARRAY_SIZE(env->xregs); i++) {
+reg.id = AARCH64_CORE_REG(regs.regs[i]);
+ 

[Qemu-devel] [PATCH v2 5/7] AARCH64: Disable the non-aarch64 specific reset code

2013-07-23 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This commit disables the co-processor registers reset code for KVM, when
compiling for AArch64 cpus.

Signed-off-by: Mian M. Hamayun 
---
 target-arm/kvm.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index c96b871..5909d75 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -700,6 +700,7 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
 
 void kvm_arch_reset_vcpu(CPUState *cs)
 {
+#ifndef TARGET_AARCH64
 /* Feed the kernel back its initial register state */
 ARMCPU *cpu = ARM_CPU(cs);
 
@@ -709,6 +710,7 @@ void kvm_arch_reset_vcpu(CPUState *cs)
 if (!write_list_to_kvmstate(cpu)) {
 abort();
 }
+#endif
 }
 
 bool kvm_arch_stop_on_emulation_error(CPUState *cs)
-- 
1.7.9.5




[Qemu-devel] [PATCH v2 4/7] AARCH64: Add boot support for aarch64 processor

2013-07-23 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This version supports booting of a single Aarch64 CPU by setting appropriate
registers. The bootloader includes placehoders for Board-ID that are used to
implementing uniform indexing across different bootloaders. The same macro
names are used with different values when compiling for different processors.

Signed-off-by: Mian M. Hamayun 

Conflicts:

hw/arm/boot.c
---
 hw/arm/boot.c |   44 +++-
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 7cca2b3..b9b0beb 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -18,7 +18,33 @@
 #include "qemu/config-file.h"
 
 #define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x0001
+
+#ifdef TARGET_AARCH64
+#define KERNEL_LOAD_ADDR0x0008
+#define KERNEL_ARGS_INDEX   6
+#define KERNEL_ENTRY_INDEX  8
+#define KERNEL_BOARDID_INDEX10
+
+static uint32_t bootloader[] = {
+0x58c0,/* ldr  x0, 18 ; Load the lower 32-bits of DTB */
+0xaa1f03e1,/* mov  x1, xzr */
+0xaa1f03e2,/* mov  x2, xzr */
+0xaa1f03e3,/* mov  x3, xzr */
+0x5884,/* ldr  x4, 20 ; Load the lower 32-bits of kernel entry 
*/
+0xd61f0080,/* br   x4 ; Jump to the kernel entry point */
+0x,/* .word @DTB Lower 32-bits */
+0x,/* .word @DTB Higher 32-bits */
+0x,/* .word @Kernel Entry Lower 32-bits */
+0x,/* .word @Kernel Entry Higher 32-bits */
+0x,/* .word @Board ID Lower 32-bits -- Placeholder */
+0x /* .word @Board ID Higher 32-bits -- Placeholder */
+};
+
+#else
+#define KERNEL_LOAD_ADDR0x0001
+#define KERNEL_BOARDID_INDEX4
+#define KERNEL_ARGS_INDEX   5
+#define KERNEL_ENTRY_INDEX  6
 
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
 static uint32_t bootloader[] = {
@@ -30,6 +56,7 @@ static uint32_t bootloader[] = {
   0, /* Address of kernel args.  Set by integratorcp_init.  */
   0  /* Kernel entry point.  Set by integratorcp_init.  */
 };
+#endif
 
 /* Handling for secondary CPU boot in a multicore system.
  * Unlike the uniprocessor/primary CPU boot, this is platform
@@ -341,8 +368,15 @@ static void do_cpu_reset(void *opaque)
 env->regs[15] = info->entry & 0xfffe;
 env->thumb = info->entry & 1;
 } else {
+#ifdef TARGET_AARCH64
+env->pstate = PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | 
PSR_MODE_EL1h;
+#endif
 if (env == first_cpu) {
+#ifdef TARGET_AARCH64
+env->pc = info->loader_start;
+#else
 env->regs[15] = info->loader_start;
+#endif
 if (!info->dtb_filename) {
 if (old_param) {
 set_kernel_args_old(info);
@@ -447,7 +481,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 }
 info->initrd_size = initrd_size;
 
-bootloader[4] = info->board_id;
+bootloader[KERNEL_BOARDID_INDEX] = info->board_id;
 
 /* for device tree boot, we pass the DTB directly in r2. Otherwise
  * we point to the kernel args.
@@ -462,9 +496,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 if (load_dtb(dtb_start, info)) {
 exit(1);
 }
-bootloader[5] = dtb_start;
+bootloader[KERNEL_ARGS_INDEX] = dtb_start;
 } else {
-bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;
+bootloader[KERNEL_ARGS_INDEX] = info->loader_start + 
KERNEL_ARGS_ADDR;
 if (info->ram_size >= (1ULL << 32)) {
 fprintf(stderr, "qemu: RAM size must be less than 4GB to boot"
 " Linux kernel using ATAGS (try passing a device tree"
@@ -472,7 +506,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 exit(1);
 }
 }
-bootloader[6] = entry;
+bootloader[KERNEL_ENTRY_INDEX] = entry;
 for (n = 0; n < sizeof(bootloader) / 4; n++) {
 bootloader[n] = tswap32(bootloader[n]);
 }
-- 
1.7.9.5




[Qemu-devel] [PATCH v2 6/7] AARCH64: Add SMP support for aarch64 processors

2013-07-23 Thread Mian M. Hamayun
From: Alexander Spyridakis 

AArch64 uses a cpu-release-addr memory location (defined in the dts) as
a way to inform secondary CPUs where to jump to and enter their holding
pen. Inject a very simple bootloader that polls this memory location,
until the primary CPU sets it to the right address.

Signed-off-by: Alexander Spyridakis 
---
 hw/arm/boot.c |   20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index b9b0beb..efbd984 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -17,6 +17,8 @@
 #include "sysemu/device_tree.h"
 #include "qemu/config-file.h"
 
+#define DSB_INSN 0xf57ff04f
+#define CP15_DSB_INSN 0xee070f9a /* mcr cp15, 0, r0, c7, c10, 4 */
 #define KERNEL_ARGS_ADDR 0x100
 
 #ifdef TARGET_AARCH64
@@ -40,6 +42,16 @@ static uint32_t bootloader[] = {
 0x /* .word @Board ID Higher 32-bits -- Placeholder */
 };
 
+static uint32_t smpboot[] = {
+0x18c5, /* ldr w5, =mbox_value - mbox value for secondary CPUs */
+0xf94000a4, /* 1: ldr  x4, [x5] - Read address to jump to */
+0xb4e4, /* cbz x4, 1b - Check if mbox value is zero, if yes retry */
+0xd61f0080, /* br  x4 - Branch to given address */
+0x0,/* padding word */
+0x0,/* gic_cpu_if_addr */
+0x8000fff8  /* mbox_value: default mbox value (aka cpu_release_addr) */
+};
+
 #else
 #define KERNEL_LOAD_ADDR0x0001
 #define KERNEL_BOARDID_INDEX4
@@ -56,7 +68,6 @@ static uint32_t bootloader[] = {
   0, /* Address of kernel args.  Set by integratorcp_init.  */
   0  /* Kernel entry point.  Set by integratorcp_init.  */
 };
-#endif
 
 /* Handling for secondary CPU boot in a multicore system.
  * Unlike the uniprocessor/primary CPU boot, this is platform
@@ -72,8 +83,6 @@ static uint32_t bootloader[] = {
  * for an interprocessor interrupt and polling a configurable
  * location for the kernel secondary CPU entry point.
  */
-#define DSB_INSN 0xf57ff04f
-#define CP15_DSB_INSN 0xee070f9a /* mcr cp15, 0, r0, c7, c10, 4 */
 
 static uint32_t smpboot[] = {
   0xe59f2028, /* ldr r2, gic_cpu_if */
@@ -91,6 +100,7 @@ static uint32_t smpboot[] = {
   0,  /* gic_cpu_if: base address of GIC CPU interface */
   0   /* bootreg: Boot register address is held here */
 };
+#endif
 
 static void default_write_secondary(ARMCPU *cpu,
 const struct arm_boot_info *info)
@@ -115,8 +125,12 @@ static void default_reset_secondary(ARMCPU *cpu,
 {
 CPUARMState *env = &cpu->env;
 
+#ifdef TARGET_AARCH64
+env->pc = info->smp_loader_start;
+#else
 stl_phys_notdirty(info->smp_bootreg_addr, 0);
 env->regs[15] = info->smp_loader_start;
+#endif
 }
 
 #define WRITE_WORD(p, value) do { \
-- 
1.7.9.5




[Qemu-devel] [PATCH v2 0/7] AARCH64 support on machvirt machine model using KVM

2013-07-23 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This is the v2 of patch series that implements KVM support in QEMU for the ARMv8
Cortex A57 CPU. It depends on the previously submitted AArch64 preparation patch
series v5 and machvirt patches, and uses the already available KVM in-kernel GIC
support. Current implementation for 64-bit guests only, and 32-bit guest support
will be introduced in near future.

As a reference, KVM Tool and the AArch64 bootwrapper were used, as well as
public documentation from ARM. The following work has been tested with SMP
capabilities, under ARMv8 Fast and Foundation Models (Open Embedded userspace
with an emulated MMC).

The v1 of this patch series related to AArch64 CPU model for Versatile Express
was sponsored by Huawei, and developed in collaboration between Huawei
Technologies Duesseldorf GmbH - European Research Center Munich (ERC) and
Virtual Open Systems.

A working tree of this implementation is available on the "kvm-aarch64-v2"
branch of the following github repository.

https://github.com/virtualopensystems/qemu/tree/kvm-aarch64-v2

Summary of Changes:

Changes v1 -> v2
 * Based on AArch64 Preparation Patchset V5 and machvirt patches.
 * Implemented for Machvirt Machine Model.
 * Architecture-specific CPU initialization code improved. Removed hardcoding
   from register set/get loops and introduced CPU target type array to find
   appropriate ARMv8 CPU type supported by KVM.
 * Disable the PSCI method in case of AArch64 and use the spin-table method
   instead for booting secondary CPUs.
 * 32-bit guest support still missing

v1
 * Based on AArch64 Preparation Patchset V4
 * Implemented for Versatile Express Machine Model
 * Support for SMP using bootcode injection
 * No 32-bit guest support

Alexander Spyridakis (1):
  AARCH64: Add SMP support for aarch64 processors

Mian M. Hamayun (6):
  AARCH64: Add A57 CPU to default AArch64 configuration and enable KVM
  Add the additional parent parameter to memory region init calls
  AARCH64: Add aarch64 CPU initialization, get and put registers
support
  AARCH64: Add boot support for aarch64 processor
  AARCH64: Disable the non-aarch64 specific reset code
  AARCH64: Use the spin-table method for booting secondary processors
in machvirt

 configure   |2 +-
 default-configs/aarch64-softmmu.mak |3 +-
 hw/arm/boot.c   |   62 +++--
 hw/arm/virt.c   |   16 -
 hw/cpu/a57mpcore.c  |2 +-
 linux-headers/linux/kvm.h   |1 +
 target-arm/kvm.c|  127 +++
 7 files changed, 201 insertions(+), 12 deletions(-)

-- 
1.7.9.5




[Qemu-devel] [PATCH v2 2/7] Add the additional parent parameter to memory region init calls

2013-07-23 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

The memory region init calls require an additional parent parameter, so
introduce a null parent parameter to make it happy.

Signed-off-by: Mian M. Hamayun 
---
 hw/arm/virt.c  |2 +-
 hw/cpu/a57mpcore.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 97712d7..8a2bdc7 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -407,7 +407,7 @@ static void machvirt_init(QEMUMachineInitArgs *args)
 }
 fdt_add_cpu_nodes(virt_fdt, mi, smp_cpus);
 
-memory_region_init_ram(ram, "mach-virt.ram", ram_size);
+memory_region_init_ram(ram, NULL, "mach-virt.ram", ram_size);
 vmstate_register_ram_global(ram);
 memory_region_add_subregion(sysmem, mi->mem_base, ram);
 
diff --git a/hw/cpu/a57mpcore.c b/hw/cpu/a57mpcore.c
index 2923a2a..1ab6dc0 100644
--- a/hw/cpu/a57mpcore.c
+++ b/hw/cpu/a57mpcore.c
@@ -70,7 +70,7 @@ static int a57mp_priv_init(SysBusDevice *dev)
  *  0x5000-0x5fff -- GIC virtual interface control (not modelled)
  *  0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
  */
-memory_region_init(&s->container, "a57mp-priv-container", 0x8000);
+memory_region_init(&s->container, NULL, "a57mp-priv-container", 0x8000);
 memory_region_add_subregion(&s->container, 0x1000,
 sysbus_mmio_get_region(busdev, 0));
 memory_region_add_subregion(&s->container, 0x2000,
-- 
1.7.9.5




[Qemu-devel] [PATCH v2 1/7] AARCH64: Add A57 CPU to default AArch64 configuration and enable KVM

2013-07-23 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

Introduce the A57 cpu to the default AArch64 configuration and enable KVM for
64-bit guests only.

Signed-off-by: Mian M. Hamayun 
---
 configure   |2 +-
 default-configs/aarch64-softmmu.mak |3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 2f83771..021c1dd 100755
--- a/configure
+++ b/configure
@@ -4293,7 +4293,7 @@ case "$target_name" in
   *)
 esac
 case "$target_name" in
-  arm|i386|x86_64|ppcemb|ppc|ppc64|s390x)
+  arm|aarch64|i386|x86_64|ppcemb|ppc|ppc64|s390x)
 # Make sure the target and host cpus are compatible
 if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
   \( "$target_name" = "$cpu" -o \
diff --git a/default-configs/aarch64-softmmu.mak 
b/default-configs/aarch64-softmmu.mak
index 27cbe3d..00c8bdd 100644
--- a/default-configs/aarch64-softmmu.mak
+++ b/default-configs/aarch64-softmmu.mak
@@ -1,4 +1,4 @@
-# Default configuration for arm-softmmu
+# Default configuration for aarch64-softmmu
 
 include pci.mak
 include usb.mak
@@ -37,6 +37,7 @@ CONFIG_USB_MUSB=y
 CONFIG_ARM9MPCORE=y
 CONFIG_ARM11MPCORE=y
 CONFIG_ARM15MPCORE=y
+CONFIG_ARM57MPCORE=y
 
 CONFIG_ARM_GIC=y
 CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
-- 
1.7.9.5




Re: [Qemu-devel] [PATCH 0/6][RFC] AArch64 support for Versatile Express using KVM

2013-07-01 Thread Mian M. Hamayun
At the time we started working on AArch64, we were not certain that our 
implementation would be published in near future. Now that this is 
cleared up we are more than happy to coordinate together.

On 28 June 2013 14:04, Andreas Färber  wrote:

I had been looking into that tree myself, and apart from John's
Linux'ish "ARM: " prefixes rather than our usual "target-arm: " (part of
which you forgot to fix before sending a PULL), I am really opposed to
copying A15MPCore_priv for A57.

I agree that just copying A15 is wrong (among other things, we
should be modelling the hardware, not just "this seems to make
KVM not barf"). That's one of the reasons I hadn't sent the patch
set out yet.

Initially we thought about this aspect too, but in order to get started, 
we made the choice to continue using the already available A15 part as 
is. Obviously this is an RFC patch series and we would like to have your 
opinion on how we can proceed from here, based on the working solution 
that we have now, although we may have some differences from the real 
hardware.

Also I would really prefer to have the is_aarch64() helper operate on
ARMCPU rather than CPUARMState. QOM cast removal is underway to make
that more efficient.

Is there a 32-bit aarch64 register in ARMv8 to be accessed by TCG? If
not, the field should be in ARMCPU and a bool rather than uint32_t.

This also needs looking at, yes.

-- PMM

--
Hamayun




Re: [Qemu-devel] [PATCH 3/6] Added Aarch64 CPU Initialization, Get and Put Registers Support.

2013-06-29 Thread Mian M. Hamayun


On 06/28/2013 02:43 PM, Alexander Graf wrote:

On 28.06.2013, at 14:11, Mian M. Hamayun wrote:


diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index c614070..4df5292 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -783,6 +783,7 @@ struct kvm_dirty_tlb {
#define KVM_REG_IA640x3000ULL
#define KVM_REG_ARM 0x4000ULL
#define KVM_REG_S3900x5000ULL
+#define KVM_REG_ARM64  0x6000ULL

#define KVM_REG_SIZE_SHIFT  52
#define KVM_REG_SIZE_MASK   0x00f0ULL

This should be part of your header update patch.
Just to make sure that we understand it correctly, do you mean that this 
macro definition should be moved to the arm64 specific header that we 
include in another patch series ? or keep this change in the same file 
and do it along with the header inclusion in a single patch ?

+#ifdef TARGET_AARCH64
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+struct kvm_vcpu_init init;
+int ret;
+
+/* Try initializing with Foundation Models */
+init.target = KVM_ARM_TARGET_FOUNDATION_V8;
+memset(init.features, 0, sizeof(init.features));
+ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+if (ret) {
+/* Retry initializing with Fast Models */
+init.target = KVM_ARM_TARGET_AEM_V8;
+ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);

Not sure I understand this part. Do we have different CPU types for the 
different models? If so, they'd be different -cpu parameters, with -cpu host 
picking the same as the host's.
KVM tool does a very similar thing, using a loop and tries to initialize 
supported processors types and gets done when it succeeds with anyone of 
them. We could include a similar implementation in the next revision.

+{
+struct kvm_one_reg reg;
+int i;
+int ret;
+
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+
+for (i = 0; i < 31; i++) {

s/31/ARRAY_SIZE(...)/

Agreed, we should avoid hard-coding as much as possible.

+reg.id = AARCH64_CORE_REG(regs.regs[i]);
+reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[i]);

reg.addr = (uintptr_t)&env->xregs[i];
Our implementation was influenced by the existing 
kvm_arch_get_registers() implementation for the A15 CPU, with slight 
differences. Anyways, we will include the proposed change in the next 
revision.


--
Hamayun




[Qemu-devel] [PATCH 3/6] Added Aarch64 CPU Initialization, Get and Put Registers Support.

2013-06-28 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

The init function tries to initialize with Foundation models first and on
failure retries initializing on Fast Models.

Get and Put Registers deal with the basic state of Aarch64 CPUs for the moment.

Signed-off-by: Mian M. Hamayun 
---
 linux-headers/linux/kvm.h |1 +
 target-arm/cpu.c  |8 +++
 target-arm/cpu.h  |1 +
 target-arm/kvm.c  |  120 +
 4 files changed, 130 insertions(+)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index c614070..4df5292 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -783,6 +783,7 @@ struct kvm_dirty_tlb {
 #define KVM_REG_IA64   0x3000ULL
 #define KVM_REG_ARM0x4000ULL
 #define KVM_REG_S390   0x5000ULL
+#define KVM_REG_ARM64  0x6000ULL
 
 #define KVM_REG_SIZE_SHIFT 52
 #define KVM_REG_SIZE_MASK  0x00f0ULL
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 496a59f..34eba77 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -601,6 +601,13 @@ static void cortex_a15_initfn(Object *obj)
 define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
 }
 
+static void cortex_a57_initfn(Object *obj)
+{
+ARMCPU *cpu = ARM_CPU(obj);
+set_feature(&cpu->env, ARM_FEATURE_V8);
+cpu->env.aarch64 = 1;  /* We force 64-bit mode for guests */
+}
+
 static void ti925t_initfn(Object *obj)
 {
 ARMCPU *cpu = ARM_CPU(obj);
@@ -781,6 +788,7 @@ static const ARMCPUInfo arm_cpus[] = {
 { .name = "cortex-a8",   .initfn = cortex_a8_initfn },
 { .name = "cortex-a9",   .initfn = cortex_a9_initfn },
 { .name = "cortex-a15",  .initfn = cortex_a15_initfn },
+{ .name = "cortex-a57",  .initfn = cortex_a57_initfn },
 { .name = "ti925t",  .initfn = ti925t_initfn },
 { .name = "sa1100",  .initfn = sa1100_initfn },
 { .name = "sa1110",  .initfn = sa1110_initfn },
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index cd42814..f1cae7f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -410,6 +410,7 @@ enum arm_features {
 ARM_FEATURE_V6,
 ARM_FEATURE_V6K,
 ARM_FEATURE_V7,
+ARM_FEATURE_V8,
 ARM_FEATURE_THUMB2,
 ARM_FEATURE_MPU,/* Only has Memory Protection Unit, not full MMU.  */
 ARM_FEATURE_VFP3,
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 27dcab9..0125f16 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -23,6 +23,11 @@
 #include "cpu.h"
 #include "hw/arm/arm.h"
 
+#ifdef TARGET_AARCH64
+#define AARCH64_CORE_REG(x)   (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
+ KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
+#endif
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
 };
@@ -41,6 +46,28 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
 return cpu->cpu_index;
 }
 
+#ifdef TARGET_AARCH64
+int kvm_arch_init_vcpu(CPUState *cs)
+{
+struct kvm_vcpu_init init;
+int ret;
+
+/* Try initializing with Foundation Models */
+init.target = KVM_ARM_TARGET_FOUNDATION_V8;
+memset(init.features, 0, sizeof(init.features));
+ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+if (ret) {
+/* Retry initializing with Fast Models */
+init.target = KVM_ARM_TARGET_AEM_V8;
+ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init);
+if (ret) {
+return ret;
+}
+}
+
+return ret;
+}
+#else
 int kvm_arch_init_vcpu(CPUState *cs)
 {
 struct kvm_vcpu_init init;
@@ -67,6 +94,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 return ret;
 }
+#endif
 
 /* We track all the KVM devices which need their memory addresses
  * passing to the kernel in a list of these structures.
@@ -159,6 +187,7 @@ typedef struct Reg {
 int offset;
 } Reg;
 
+#ifndef TARGET_AARCH64
 #define COREREG(KERNELNAME, QEMUFIELD)   \
 {\
 KVM_REG_ARM | KVM_REG_SIZE_U32 | \
@@ -239,7 +268,52 @@ static const Reg regs[] = {
 VFPSYSREG(FPINST),
 VFPSYSREG(FPINST2),
 };
+#endif
+
+#ifdef TARGET_AARCH64
+int kvm_arch_put_registers(CPUState *cs, int level)
+{
+struct kvm_one_reg reg;
+int i;
+int ret;
+
+ARMCPU *cpu = ARM_CPU(cs);
+CPUARMState *env = &cpu->env;
+
+for (i = 0; i < 31; i++) {
+reg.id = AARCH64_CORE_REG(regs.regs[i]);
+reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[i]);
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return ret;
+}
+}
+
+reg.id = AARCH64_CORE_REG(regs.sp);
+reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[31]);
+ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®);
+if (ret) {
+return re

[Qemu-devel] [PATCH 0/6][RFC] AArch64 support for Versatile Express using KVM

2013-06-28 Thread Mian M. Hamayun
This patch series implements KVM support in QEMU for the ARMv8 Cortex 
A57 CPU.
It depends on the previously submitted AArch64 Preparation Patchset V4, 
and uses

as a base, the existing Versatile Express machine model and the already
available KVM in-kernel GIC support.

As a reference, KVM Tool and the AArch64 bootwrapper were used, as well as
public documentation from ARM. The following work has been tested with SMP
capabilities, under ARMv8 Fast Models and the Foundation model (Open 
Embedded

userspace with an emulated MMC).

The work has been sponsored by Huawei, and developed in collaboration with
Huawei Technologies Duesseldorf GmbH, European Research Center Munich (ERC).
A working tree of this implementation is available on the "kvm-aarch64" 
branch

of the following github repository.

https://github.com/virtualopensystems/qemu.git

Summary of Patches:

[PATCH 1/6] Added aarch64 configure support and default
[PATCH 2/6] Added KVM Headers from KVM Tool
[PATCH 3/6] Added Aarch64 CPU Initialization, Get and Put Registers
[PATCH 4/6] Added the Versatile Express Machine Model for A57
[PATCH 5/6] Added Boot Support for Aarch64 Processor.
[PATCH 6/6] Added SMP for Aarch64 Processors.





[Qemu-devel] [PATCH 6/6] Added SMP for Aarch64 Processors.

2013-06-28 Thread Mian M. Hamayun
From: Alexander Spyridakis 

AArch64 uses a cpu-release-addr memory location (defined in the dts) as
a way to inform secondary CPUs where to jump to and enter their holding
pen. Inject a very simple bootloader that polls this memory location,
until the primary CPU sets it to the right address.

Signed-off-by: Alexander Spyridakis 
---
 hw/arm/boot.c |   20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 94e628b..f7a97d1 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -17,6 +17,8 @@
 #include "sysemu/device_tree.h"
 #include "qemu/config-file.h"
 
+#define DSB_INSN 0xf57ff04f
+#define CP15_DSB_INSN 0xee070f9a /* mcr cp15, 0, r0, c7, c10, 4 */
 #define KERNEL_ARGS_ADDR 0x100
 
 #ifdef TARGET_AARCH64
@@ -40,6 +42,16 @@ static uint32_t bootloader[] = {
 0x /* .word @Board ID Higher 32-bits -- Placeholder */
 };
 
+static uint32_t smpboot[] = {
+  0x1885, /* ldr w5, =0x8000fff8 - mbox value for secondary CPUs */
+  0xf94000a4, /* 1: ldr x4, [x5] - Read address to jump to */
+  0xb4e4, /* cbz x4, 1b - Check if mbox value is zero, if yes retry */
+  0xd61f0080, /* br x4 - Branch to given address */
+  0x8000fff8, /* mbox value */
+  0,
+  0
+};
+
 #else
 #define KERNEL_LOAD_ADDR0x0001
 #define KERNEL_BOARDID_INDEX4
@@ -56,7 +68,6 @@ static uint32_t bootloader[] = {
   0, /* Address of kernel args.  Set by integratorcp_init.  */
   0  /* Kernel entry point.  Set by integratorcp_init.  */
 };
-#endif
 
 /* Handling for secondary CPU boot in a multicore system.
  * Unlike the uniprocessor/primary CPU boot, this is platform
@@ -72,8 +83,6 @@ static uint32_t bootloader[] = {
  * for an interprocessor interrupt and polling a configurable
  * location for the kernel secondary CPU entry point.
  */
-#define DSB_INSN 0xf57ff04f
-#define CP15_DSB_INSN 0xee070f9a /* mcr cp15, 0, r0, c7, c10, 4 */
 
 static uint32_t smpboot[] = {
   0xe59f2028, /* ldr r2, gic_cpu_if */
@@ -91,6 +100,7 @@ static uint32_t smpboot[] = {
   0,  /* gic_cpu_if: base address of GIC CPU interface */
   0   /* bootreg: Boot register address is held here */
 };
+#endif
 
 static void default_write_secondary(ARMCPU *cpu,
 const struct arm_boot_info *info)
@@ -115,8 +125,12 @@ static void default_reset_secondary(ARMCPU *cpu,
 {
 CPUARMState *env = &cpu->env;
 
+#ifdef TARGET_AARCH64
+env->pc = info->smp_loader_start;
+#else
 stl_phys_notdirty(info->smp_bootreg_addr, 0);
 env->regs[15] = info->smp_loader_start;
+#endif
 }
 
 #define WRITE_WORD(p, value) do { \
-- 
1.7.9.5




[Qemu-devel] [PATCH 5/6] Added Boot Support for Aarch64 Processor.

2013-06-28 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

This version supports booting of a single Aarch64 CPU by setting appropriate
registers. The bootloader includes placehoders for Board-ID that are used to
implementing uniform indexing across different bootloaders.
The same macro names are used with different values when compiling for different
processors.

Signed-off-by: Mian M. Hamayun 
---
 hw/arm/boot.c |   45 +++--
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index defcf15..94e628b 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -18,7 +18,33 @@
 #include "qemu/config-file.h"
 
 #define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x0001
+
+#ifdef TARGET_AARCH64
+#define KERNEL_LOAD_ADDR0x0008
+#define KERNEL_ARGS_INDEX   6
+#define KERNEL_ENTRY_INDEX  8
+#define KERNEL_BOARDID_INDEX10
+
+static uint32_t bootloader[] = {
+0x58c0,/* ldr  x0, 18 <_start+0x18> */
+0xaa1f03e1,/* mov  x1, xzr */
+0xaa1f03e2,/* mov  x2, xzr */
+0xaa1f03e3,/* mov  x3, xzr */
+0x5884,/* ldr  x4, 20 <_start+0x20> */
+0xd61f0080,/* br   x4 */
+0x,/* .word @DTB Lower 32-bits */
+0x,/* .word @DTB Higher 32-bits */
+0x,/* .word @Kernel Entry Lower 32-bits */
+0x,/* .word @Kernel Entry Higher 32-bits */
+0x,/* .word @Board ID Lower 32-bits -- Placeholder */
+0x /* .word @Board ID Higher 32-bits -- Placeholder */
+};
+
+#else
+#define KERNEL_LOAD_ADDR0x0001
+#define KERNEL_BOARDID_INDEX4
+#define KERNEL_ARGS_INDEX   5
+#define KERNEL_ENTRY_INDEX  6
 
 /* The worlds second smallest bootloader.  Set r0-r2, then jump to kernel.  */
 static uint32_t bootloader[] = {
@@ -30,6 +56,7 @@ static uint32_t bootloader[] = {
   0, /* Address of kernel args.  Set by integratorcp_init.  */
   0  /* Kernel entry point.  Set by integratorcp_init.  */
 };
+#endif
 
 /* Handling for secondary CPU boot in a multicore system.
  * Unlike the uniprocessor/primary CPU boot, this is platform
@@ -239,7 +266,6 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo)
 fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename);
 return -1;
 }
-
 fdt = load_device_tree(filename, &size);
 if (!fdt) {
 fprintf(stderr, "Couldn't open dtb file %s\n", filename);
@@ -322,8 +348,15 @@ static void do_cpu_reset(void *opaque)
 env->regs[15] = info->entry & 0xfffe;
 env->thumb = info->entry & 1;
 } else {
+#ifdef TARGET_AARCH64
+env->pstate = PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | 
PSR_MODE_EL1h;
+#endif
 if (env == first_cpu) {
+#ifdef TARGET_AARCH64
+env->pc = info->loader_start;
+#else
 env->regs[15] = info->loader_start;
+#endif
 if (!info->dtb_filename) {
 if (old_param) {
 set_kernel_args_old(info);
@@ -428,7 +461,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 }
 info->initrd_size = initrd_size;
 
-bootloader[4] = info->board_id;
+bootloader[KERNEL_BOARDID_INDEX] = info->board_id;
 
 /* for device tree boot, we pass the DTB directly in r2. Otherwise
  * we point to the kernel args.
@@ -443,9 +476,9 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 if (load_dtb(dtb_start, info)) {
 exit(1);
 }
-bootloader[5] = dtb_start;
+bootloader[KERNEL_ARGS_INDEX] = dtb_start;
 } else {
-bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;
+bootloader[KERNEL_ARGS_INDEX] = info->loader_start + 
KERNEL_ARGS_ADDR;
 if (info->ram_size >= (1ULL << 32)) {
 fprintf(stderr, "qemu: RAM size must be less than 4GB to boot"
 " Linux kernel using ATAGS (try passing a device tree"
@@ -453,7 +486,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
*info)
 exit(1);
 }
 }
-bootloader[6] = entry;
+bootloader[KERNEL_ENTRY_INDEX] = entry;
 for (n = 0; n < sizeof(bootloader) / 4; n++) {
 bootloader[n] = tswap32(bootloader[n]);
 }
-- 
1.7.9.5




[Qemu-devel] [PATCH 4/6] Added the Versatile Express Machine Model for A57

2013-06-28 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

The vexpress model for A57 is based on the A15 machine model with a few
changes in the daughterboard initialization (using a subset of A15
functionality). The A57 daughterboard init also shares the A15MPCore
private memory region with A15 daughterboard init function.

Signed-off-by: Mian M. Hamayun 
---
 hw/arm/vexpress.c |   91 +
 1 file changed, 91 insertions(+)

diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index a077c62..e8070f3 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -393,6 +393,74 @@ static const VEDBoardInfo a15_daughterboard = {
 .init = a15_daughterboard_init,
 };
 
+static void a57_daughterboard_init(const VEDBoardInfo *daughterboard,
+   ram_addr_t ram_size,
+   const char *cpu_model,
+   qemu_irq *pic)
+{
+int n;
+MemoryRegion *sysmem = get_system_memory();
+MemoryRegion *ram = g_new(MemoryRegion, 1);
+qemu_irq cpu_irq[4];
+DeviceState *dev;
+SysBusDevice *busdev;
+
+if (!cpu_model) {
+cpu_model = "cortex-a57";
+}
+
+for (n = 0; n < smp_cpus; n++) {
+ARMCPU *cpu;
+qemu_irq *irqp;
+
+cpu = cpu_arm_init(cpu_model);
+if (!cpu) {
+fprintf(stderr, "Unable to find CPU definition\n");
+exit(1);
+}
+irqp = arm_pic_init_cpu(cpu);
+cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+}
+
+{
+/* We have to use a separate 64 bit variable here to avoid the gcc
+ * "comparison is always false due to limited range of data type"
+ * warning if we are on a host where ram_addr_t is 32 bits.
+ */
+uint64_t rsz = ram_size;
+if (rsz > (30ULL * 1024 * 1024 * 1024)) {
+fprintf(stderr, "vexpress-a57: cannot model more than 30GB RAM\n");
+exit(1);
+}
+}
+
+memory_region_init_ram(ram, "vexpress.lowmem", ram_size);
+vmstate_register_ram_global(ram);
+/* RAM is from 0x8000 upwards; there is no low-memory alias for it. */
+memory_region_add_subregion(sysmem, 0x8000, ram);
+
+/* 0x2c00 A15MPCore private memory region (GIC) */
+dev = qdev_create(NULL, "a15mpcore_priv");
+qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
+qdev_init_nofail(dev);
+busdev = SYS_BUS_DEVICE(dev);
+sysbus_mmio_map(busdev, 0, 0x2c00);
+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 there
+ * are internal interrupts 0..31).
+ */
+for (n = 0; n < 64; n++) {
+pic[n] = qdev_get_gpio_in(dev, n);
+}
+
+/* A57 daughterboard peripherals: not modeled */
+}
+
 static void vexpress_common_init(const VEDBoardInfo *daughterboard,
  QEMUMachineInitArgs *args)
 {
@@ -522,6 +590,14 @@ static void vexpress_common_init(const VEDBoardInfo 
*daughterboard,
 arm_load_kernel(arm_env_get_cpu(first_cpu), &vexpress_binfo);
 }
 
+static const VEDBoardInfo a57_daughterboard = {
+.motherboard_map = motherboard_aseries_map,
+.loader_start = 0x8000,
+.gic_cpu_if_addr = 0x2c002000,
+.proc_id = 0x14000237,
+.init = a57_daughterboard_init,
+};
+
 static void vexpress_a9_init(QEMUMachineInitArgs *args)
 {
 vexpress_common_init(&a9_daughterboard, args);
@@ -532,6 +608,11 @@ static void vexpress_a15_init(QEMUMachineInitArgs *args)
 vexpress_common_init(&a15_daughterboard, args);
 }
 
+static void vexpress_a57_init(QEMUMachineInitArgs *args)
+{
+vexpress_common_init(&a57_daughterboard, args);
+}
+
 static QEMUMachine vexpress_a9_machine = {
 .name = "vexpress-a9",
 .desc = "ARM Versatile Express for Cortex-A9",
@@ -550,10 +631,20 @@ static QEMUMachine vexpress_a15_machine = {
 DEFAULT_MACHINE_OPTIONS,
 };
 
+static QEMUMachine vexpress_a57_machine = {
+.name = "vexpress-a57",
+.desc = "ARM Versatile Express for Cortex-A57",
+.init = vexpress_a57_init,
+.block_default_type = IF_SCSI,
+.max_cpus = 4,
+DEFAULT_MACHINE_OPTIONS,
+};
+
 static void vexpress_machine_init(void)
 {
 qemu_register_machine(&vexpress_a9_machine);
 qemu_register_machine(&vexpress_a15_machine);
+qemu_register_machine(&vexpress_a57_machine);
 }
 
 machine_init(vexpress_machine_init);
-- 
1.7.9.5




[Qemu-devel] [PATCH 2/6] Added KVM Headers from KVM Tool

2013-06-28 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

Signed-off-by: Mian M. Hamayun 
---
 linux-headers/asm-arm64/kvm.h  |  168 
 linux-headers/asm-arm64/kvm_para.h |1 +
 2 files changed, 169 insertions(+)
 create mode 100644 linux-headers/asm-arm64/kvm.h
 create mode 100644 linux-headers/asm-arm64/kvm_para.h

diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
new file mode 100644
index 000..5031f42
--- /dev/null
+++ b/linux-headers/asm-arm64/kvm.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2012,2013 - ARM Ltd
+ * Author: Marc Zyngier 
+ *
+ * Derived from arch/arm/include/uapi/asm/kvm.h:
+ * Copyright (C) 2012 - Virtual Open Systems and Columbia University
+ * Author: Christoffer Dall 
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ARM_KVM_H__
+#define __ARM_KVM_H__
+
+#define KVM_SPSR_EL1   0
+#define KVM_SPSR_SVC   KVM_SPSR_EL1
+#define KVM_SPSR_ABT   1
+#define KVM_SPSR_UND   2
+#define KVM_SPSR_IRQ   3
+#define KVM_SPSR_FIQ   4
+#define KVM_NR_SPSR5
+
+#ifndef __ASSEMBLY__
+#include 
+#include 
+
+#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_IRQ_LINE
+
+#define KVM_REG_SIZE(id)   \
+   (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
+
+struct kvm_regs {
+   struct user_pt_regs regs;   /* sp = sp_el0 */
+
+   __u64   sp_el1;
+   __u64   elr_el1;
+
+   __u64   spsr[KVM_NR_SPSR];
+
+   struct user_fpsimd_state fp_regs;
+};
+
+/* Supported Processor Types */
+#define KVM_ARM_TARGET_AEM_V8  0
+#define KVM_ARM_TARGET_FOUNDATION_V8   1
+#define KVM_ARM_TARGET_CORTEX_A57  2
+
+#define KVM_ARM_NUM_TARGETS3
+
+/* KVM_ARM_SET_DEVICE_ADDR ioctl id encoding */
+#define KVM_ARM_DEVICE_TYPE_SHIFT  0
+#define KVM_ARM_DEVICE_TYPE_MASK   (0x << KVM_ARM_DEVICE_TYPE_SHIFT)
+#define KVM_ARM_DEVICE_ID_SHIFT16
+#define KVM_ARM_DEVICE_ID_MASK (0x << KVM_ARM_DEVICE_ID_SHIFT)
+
+/* Supported device IDs */
+#define KVM_ARM_DEVICE_VGIC_V2 0
+
+/* Supported VGIC address types  */
+#define KVM_VGIC_V2_ADDR_TYPE_DIST 0
+#define KVM_VGIC_V2_ADDR_TYPE_CPU  1
+
+#define KVM_VGIC_V2_DIST_SIZE  0x1000
+#define KVM_VGIC_V2_CPU_SIZE   0x2000
+
+#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
+#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */
+
+struct kvm_vcpu_init {
+   __u32 target;
+   __u32 features[7];
+};
+
+struct kvm_sregs {
+};
+
+struct kvm_fpu {
+};
+
+struct kvm_guest_debug_arch {
+};
+
+struct kvm_debug_exit_arch {
+};
+
+struct kvm_sync_regs {
+};
+
+struct kvm_arch_memory_slot {
+};
+
+/* If you need to interpret the index values, here is the key: */
+#define KVM_REG_ARM_COPROC_MASK0x0FFF
+#define KVM_REG_ARM_COPROC_SHIFT   16
+
+/* Normal registers are mapped as coprocessor 16. */
+#define KVM_REG_ARM_CORE   (0x0010 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_CORE_REG(name) (offsetof(struct kvm_regs, name) / 
sizeof(__u32))
+
+/* Some registers need more space to represent values. */
+#define KVM_REG_ARM_DEMUX  (0x0011 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM_DEMUX_ID_MASK  0xFF00
+#define KVM_REG_ARM_DEMUX_ID_SHIFT 8
+#define KVM_REG_ARM_DEMUX_ID_CCSIDR(0x00 << KVM_REG_ARM_DEMUX_ID_SHIFT)
+#define KVM_REG_ARM_DEMUX_VAL_MASK 0x00FF
+#define KVM_REG_ARM_DEMUX_VAL_SHIFT0
+
+/* AArch64 system registers */
+#define KVM_REG_ARM64_SYSREG   (0x0013 << KVM_REG_ARM_COPROC_SHIFT)
+#define KVM_REG_ARM64_SYSREG_OP0_MASK  0xc000
+#define KVM_REG_ARM64_SYSREG_OP0_SHIFT 14
+#define KVM_REG_ARM64_SYSREG_OP1_MASK  0x3800
+#define KVM_REG_ARM64_SYSREG_OP1_SHIFT 11
+#define KVM_REG_ARM64_SYSREG_CRN_MASK  0x0780
+#define KVM_REG_ARM64_SYSREG_CRN_SHIFT 7
+#define KVM_REG_ARM64_SYSREG_CRM_MASK  0x0078
+#define KVM_REG_ARM64_SYSREG_CRM_SHIFT 3
+#define KVM_REG_ARM64_SYSREG_OP2_MASK  0x0007
+#define KVM_REG_ARM64_SYSREG_OP2_SHIFT 0
+
+/* KVM_IRQ_LINE irq field index values */
+#define KVM_ARM_IRQ_TYPE_SHIFT 24
+#define KVM_ARM_IRQ_TYPE_MASK  0xff
+#define KVM_ARM_IRQ_VCPU_SHIFT 16
+#define KVM_ARM_IRQ_VCPU_MASK  0xff
+#d

[Qemu-devel] [PATCH 1/6] Added aarch64 configure support and default configuration

2013-06-28 Thread Mian M. Hamayun
From: "Mian M. Hamayun" 

Signed-off-by: Mian M. Hamayun 
---
 configure   |3 +-
 default-configs/aarch64-softmmu.mak |   83 +++
 2 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 default-configs/aarch64-softmmu.mak

diff --git a/configure b/configure
index b247e5b..ddec40d 100755
--- a/configure
+++ b/configure
@@ -4293,10 +4293,11 @@ case "$target_name" in
   *)
 esac
 case "$target_name" in
-  arm|i386|x86_64|ppcemb|ppc|ppc64|s390x)
+  arm|aarch64|i386|x86_64|ppcemb|ppc|ppc64|s390x)
 # Make sure the target and host cpus are compatible
 if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \
   \( "$target_name" = "$cpu" -o \
+  \( "$target_name" = "arm"-a "$cpu" = "aarch64"   \) -o \
   \( "$target_name" = "ppcemb" -a "$cpu" = "ppc" \) -o \
   \( "$target_name" = "ppc64"  -a "$cpu" = "ppc" \) -o \
   \( "$target_name" = "ppc"-a "$cpu" = "ppc64" \) -o \
diff --git a/default-configs/aarch64-softmmu.mak 
b/default-configs/aarch64-softmmu.mak
new file mode 100644
index 000..00c8bdd
--- /dev/null
+++ b/default-configs/aarch64-softmmu.mak
@@ -0,0 +1,83 @@
+# Default configuration for aarch64-softmmu
+
+include pci.mak
+include usb.mak
+CONFIG_GDBSTUB_XML=y
+CONFIG_VGA=y
+CONFIG_ISA_MMIO=y
+CONFIG_NAND=y
+CONFIG_ECC=y
+CONFIG_SERIAL=y
+CONFIG_PTIMER=y
+CONFIG_SD=y
+CONFIG_MAX7310=y
+CONFIG_WM8750=y
+CONFIG_TWL92230=y
+CONFIG_TSC2005=y
+CONFIG_LM832X=y
+CONFIG_TMP105=y
+CONFIG_STELLARIS=y
+CONFIG_STELLARIS_INPUT=y
+CONFIG_STELLARIS_ENET=y
+CONFIG_SSD0303=y
+CONFIG_SSD0323=y
+CONFIG_ADS7846=y
+CONFIG_MAX111X=y
+CONFIG_SSI=y
+CONFIG_SSI_SD=y
+CONFIG_SSI_M25P80=y
+CONFIG_LAN9118=y
+CONFIG_SMC91C111=y
+CONFIG_DS1338=y
+CONFIG_PFLASH_CFI01=y
+CONFIG_PFLASH_CFI02=y
+CONFIG_MICRODRIVE=y
+CONFIG_USB_MUSB=y
+
+CONFIG_ARM9MPCORE=y
+CONFIG_ARM11MPCORE=y
+CONFIG_ARM15MPCORE=y
+CONFIG_ARM57MPCORE=y
+
+CONFIG_ARM_GIC=y
+CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
+CONFIG_ARM_TIMER=y
+CONFIG_ARM_MPTIMER=y
+CONFIG_PL011=y
+CONFIG_PL022=y
+CONFIG_PL031=y
+CONFIG_PL041=y
+CONFIG_PL050=y
+CONFIG_PL061=y
+CONFIG_PL080=y
+CONFIG_PL110=y
+CONFIG_PL181=y
+CONFIG_PL190=y
+CONFIG_PL310=y
+CONFIG_PL330=y
+CONFIG_CADENCE=y
+CONFIG_XGMAC=y
+CONFIG_EXYNOS4=y
+CONFIG_PXA2XX=y
+CONFIG_BITBANG_I2C=y
+CONFIG_FRAMEBUFFER=y
+CONFIG_XILINX_SPIPS=y
+
+CONFIG_A9SCU=y
+CONFIG_MARVELL_88W8618=y
+CONFIG_OMAP=y
+CONFIG_TSC210X=y
+CONFIG_BLIZZARD=y
+CONFIG_ONENAND=y
+CONFIG_TUSB6010=y
+CONFIG_IMX=y
+CONFIG_MAINSTONE=y
+CONFIG_NSERIES=y
+CONFIG_REALVIEW=y
+CONFIG_ZAURUS=y
+CONFIG_ZYNQ=y
+
+CONFIG_VERSATILE_PCI=y
+CONFIG_VERSATILE_I2C=y
+
+CONFIG_SDHCI=y
-- 
1.7.9.5




[Qemu-devel] Cross-Compiling Qemu for Aarch64?

2013-05-16 Thread Mian M. Hamayun

Hello Everyone,

I am currently trying to compile qemu for Aarch64 but so far I haven't 
been able to configure qemu for this purpose.
My first objective is to just configure and cross-compile qemu for 
Aarch64, which is currently blocked by the qemu's dependency on 
cross-compiled "glib-2.12".

For example, when I use the following configure command:

./configure --cross-prefix=aarch64-linux-gnu- --target-list=arm-softmmu 
--enable-fdt --static


I get the following error:
ERROR: glib-2.12 required to compile QEMU

This is a well-known dependency and the following pages are linked to 
this issue (directly or indirectly) and I have tried all of them without 
any success:


https://bugs.launchpad.net/linaro-oe/+bug/1097561
http://people.debian.org/~wookey/bootstrap.html
http://wiki.xen.org/wiki/Xen_ARM_with_Virtualization_Extensions/CrossCompiling
https://wiki.linaro.org/Platform/DevPlatform/CrossCompile/arm64bootstrap

I have also tried the latest git repository from John Rigby but I get 
the same error:

https://git.linaro.org/gitweb?p=people/jcrigby/qemu-aarch64.git;a=summary

Anyways, I want to know how we can resolve this dependency ?

Some of you might suggest to cross-compile the glib-2.12 from sources 
found at:

http://www.linuxfromscratch.org/blfs/view/6.3/general/glib2.html
http://www.gtk.org/api/2.6/glib/glib-cross-compiling.html

but even this option doesn't work for me as the apparent lacking support 
for Aarch64 in "glib-2.12".

I have used the following configure command:
./configure --prefix=/my/prefix/path --host=aarch64-linux-gnu 
--cache-file=aarch64.cache


with the following aarch64.cache file contents:
glib_cv_long_long_format=I64
glib_cv_stack_grows=no

Any pointers and/or directions for a possible solution will be highly 
appreciated.


Thanks in advance,
Hamayun