diff --git a/MAINTAINERS b/MAINTAINERS
index 7cbcd7e60d..508ea1ee24 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -143,6 +143,16 @@ L: kvm@vger.kernel.org
 S: Supported
 F: target-i386/kvm.c
 
+Guest CPU Cores (Xen):
+----------------------
+
+X86
+M: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+L: xen-devel@lists.xensource.com
+S: Supported
+F: xen-*
+F: */xen*
+
 ARM Machines
 ------------
 Gumstix
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 74823a5ebf..e32bcf084c 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -317,7 +317,8 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
 {
     BDRVQcowState *s = bs->opaque;
     QCowSnapshot *sn;
-    int i, snapshot_index, l1_size2;
+    int i, snapshot_index;
+    int cur_l1_bytes, sn_l1_bytes;
 
     snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
     if (snapshot_index < 0)
@@ -330,14 +331,19 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
     if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0)
         goto fail;
 
-    s->l1_size = sn->l1_size;
-    l1_size2 = s->l1_size * sizeof(uint64_t);
+    cur_l1_bytes = s->l1_size * sizeof(uint64_t);
+    sn_l1_bytes = sn->l1_size * sizeof(uint64_t);
+
+    if (cur_l1_bytes > sn_l1_bytes) {
+        memset(s->l1_table + sn->l1_size, 0, cur_l1_bytes - sn_l1_bytes);
+    }
+
     /* copy the snapshot l1 table to the current l1 table */
     if (bdrv_pread(bs->file, sn->l1_table_offset,
-                   s->l1_table, l1_size2) != l1_size2)
+                   s->l1_table, sn_l1_bytes) < 0)
         goto fail;
     if (bdrv_pwrite_sync(bs->file, s->l1_table_offset,
-                    s->l1_table, l1_size2) < 0)
+                    s->l1_table, cur_l1_bytes) < 0)
         goto fail;
     for(i = 0;i < s->l1_size; i++) {
         be64_to_cpus(&s->l1_table[i]);
diff --git a/bsd-user/main.c b/bsd-user/main.c
index a63b8777fc..cc7d4a37ad 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -905,7 +905,8 @@ int main(int argc, char **argv)
         cpu_model = "any";
 #endif
     }
-    cpu_exec_init_all(0);
+    tcg_exec_init(0);
+    cpu_exec_init_all();
     /* NOTE: we need to init the CPU at this stage to get
        qemu_host_page_size */
     env = cpu_init(cpu_model);
diff --git a/configure b/configure
index 408d454759..0c67a4abd9 100755
--- a/configure
+++ b/configure
@@ -220,14 +220,14 @@ done
 # Using uname is really, really broken.  Once we have the right set of checks
 # we can eliminate it's usage altogether
 
-cc="${cross_prefix}${CC-gcc}"
-ar="${cross_prefix}${AR-ar}"
-objcopy="${cross_prefix}${OBJCOPY-objcopy}"
-ld="${cross_prefix}${LD-ld}"
-strip="${cross_prefix}${STRIP-strip}"
-windres="${cross_prefix}${WINDRES-windres}"
-pkg_config="${cross_prefix}${PKG_CONFIG-pkg-config}"
-sdl_config="${cross_prefix}${SDL_CONFIG-sdl-config}"
+cc="${CC-${cross_prefix}gcc}"
+ar="${AR-${cross_prefix}ar}"
+objcopy="${OBJCOPY-${cross_prefix}objcopy}"
+ld="${LD-${cross_prefix}ld}"
+strip="${STRIP-${cross_prefix}strip}"
+windres="${WINDRES-${cross_prefix}windres}"
+pkg_config="${PKG_CONFIG-${cross_prefix}pkg-config}"
+sdl_config="${SDL_CONFIG-${cross_prefix}sdl-config}"
 
 # default flags for all hosts
 QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
diff --git a/darwin-user/main.c b/darwin-user/main.c
index 72307adeb7..1a881a0a60 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -852,8 +852,8 @@ int main(int argc, char **argv)
 #error unsupported CPU
 #endif
     }
-    
-    cpu_exec_init_all(0);
+    tcg_exec_init(0);
+    cpu_exec_init_all();
     /* NOTE: we need to init the CPU at this stage to get
        qemu_host_page_size */
     env = cpu_init(cpu_model);
diff --git a/darwin-user/signal.c b/darwin-user/signal.c
index e2adca3918..c530227f1c 100644
--- a/darwin-user/signal.c
+++ b/darwin-user/signal.c
@@ -319,7 +319,6 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
 			void *set, CPUState *env)
 {
 	void *frame;
-	int i, err = 0;
 
     fprintf(stderr, "setup_frame %d\n", sig);
 	frame = get_sigframe(ka, env, sizeof(*frame));
diff --git a/exec.c b/exec.c
index 476b507e5e..719fff9a91 100644
--- a/exec.c
+++ b/exec.c
@@ -526,7 +526,8 @@ static void code_gen_alloc(unsigned long tb_size)
         }
     }
 #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \
-    || defined(__DragonFly__) || defined(__OpenBSD__)
+    || defined(__DragonFly__) || defined(__OpenBSD__) \
+    || defined(__NetBSD__)
     {
         int flags;
         void *addr = NULL;
@@ -570,16 +571,12 @@ static void code_gen_alloc(unsigned long tb_size)
 /* Must be called before using the QEMU cpus. 'tb_size' is the size
    (in bytes) allocated to the translation buffer. Zero means default
    size. */
-void cpu_exec_init_all(unsigned long tb_size)
+void tcg_exec_init(unsigned long tb_size)
 {
     cpu_gen_init();
     code_gen_alloc(tb_size);
     code_gen_ptr = code_gen_buffer;
     page_init();
-#if !defined(CONFIG_USER_ONLY)
-    memory_map_init();
-    io_mem_init();
-#endif
 #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
     /* There's no guest base to take into account, so go ahead and
        initialize the prologue now.  */
@@ -587,6 +584,19 @@ void cpu_exec_init_all(unsigned long tb_size)
 #endif
 }
 
+bool tcg_enabled(void)
+{
+    return code_gen_buffer != NULL;
+}
+
+void cpu_exec_init_all(void)
+{
+#if !defined(CONFIG_USER_ONLY)
+    memory_map_init();
+    io_mem_init();
+#endif
+}
+
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
 
 static int cpu_common_post_load(void *opaque, int version_id)
@@ -3818,7 +3828,7 @@ static void io_mem_init(void)
 static void memory_map_init(void)
 {
     system_memory = qemu_malloc(sizeof(*system_memory));
-    memory_region_init(system_memory, "system", UINT64_MAX);
+    memory_region_init(system_memory, "system", INT64_MAX);
     set_system_memory_map(system_memory);
 }
 
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index a29db9055d..e4847b7f93 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -87,6 +87,13 @@ static FILE *probe_splashfile(char *filename, int *file_sizep, int *file_typep)
     /* check magic ID */
     fseek(fp, 0L, SEEK_SET);
     fop_ret = fread(buf, 1, 2, fp);
+    if (fop_ret != 2) {
+        error_report("Could not read header from '%s': %s",
+                     filename, strerror(errno));
+        fclose(fp);
+        fp = NULL;
+        return fp;
+    }
     filehead_value = (buf[0] + (buf[1] << 8)) & 0xffff;
     if (filehead_value == 0xd8ff) {
         file_type = JPG_FILE;
@@ -181,6 +188,12 @@ static void fw_cfg_bootsplash(FWCfgState *s)
         boot_splash_filedata_size = file_size;
         fseek(fp, 0L, SEEK_SET);
         fop_ret = fread(boot_splash_filedata, 1, file_size, fp);
+        if (fop_ret != file_size) {
+            error_report("failed to read data from '%s'.",
+                         boot_splash_filename);
+            fclose(fp);
+            return;
+        }
         fclose(fp);
         /* insert data */
         if (file_type == JPG_FILE) {
diff --git a/hw/qdev.c b/hw/qdev.c
index b4ea8e13d1..6819537648 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -36,6 +36,7 @@ static bool qdev_hot_removed = false;
 
 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
 static BusState *main_system_bus;
+static void main_system_bus_create(void);
 
 DeviceInfo *device_info_list;
 
@@ -328,8 +329,7 @@ static int qdev_reset_one(DeviceState *dev, void *opaque)
 BusState *sysbus_get_default(void)
 {
     if (!main_system_bus) {
-        main_system_bus = qbus_create(&system_bus_info, NULL,
-                                      "main-system-bus");
+        main_system_bus_create();
     }
     return main_system_bus;
 }
@@ -784,6 +784,16 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
     return bus;
 }
 
+static void main_system_bus_create(void)
+{
+    /* assign main_system_bus before qbus_create_inplace()
+     * in order to make "if (bus != main_system_bus)" work */
+    main_system_bus = qemu_mallocz(system_bus_info.size);
+    main_system_bus->qdev_allocated = 1;
+    qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
+                        "main-system-bus");
+}
+
 void qbus_free(BusState *bus)
 {
     DeviceState *dev;
diff --git a/linux-user/main.c b/linux-user/main.c
index 6a8f4bdc11..8e15474329 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3117,7 +3117,8 @@ int main(int argc, char **argv, char **envp)
         cpu_model = "any";
 #endif
     }
-    cpu_exec_init_all(0);
+    tcg_exec_init(0);
+    cpu_exec_init_all();
     /* NOTE: we need to init the CPU at this stage to get
        qemu_host_page_size */
     env = cpu_init(cpu_model);
diff --git a/memory.c b/memory.c
index 5c6e63df3f..be891c6382 100644
--- a/memory.c
+++ b/memory.c
@@ -22,12 +22,17 @@ unsigned memory_region_transaction_depth = 0;
 
 typedef struct AddrRange AddrRange;
 
+/*
+ * Note using signed integers limits us to physical addresses at most
+ * 63 bits wide.  They are needed for negative offsetting in aliases
+ * (large MemoryRegion::alias_offset).
+ */
 struct AddrRange {
-    uint64_t start;
-    uint64_t size;
+    int64_t start;
+    int64_t size;
 };
 
-static AddrRange addrrange_make(uint64_t start, uint64_t size)
+static AddrRange addrrange_make(int64_t start, int64_t size)
 {
     return (AddrRange) { start, size };
 }
@@ -37,7 +42,7 @@ static bool addrrange_equal(AddrRange r1, AddrRange r2)
     return r1.start == r2.start && r1.size == r2.size;
 }
 
-static uint64_t addrrange_end(AddrRange r)
+static int64_t addrrange_end(AddrRange r)
 {
     return r.start + r.size;
 }
@@ -56,9 +61,9 @@ static bool addrrange_intersects(AddrRange r1, AddrRange r2)
 
 static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2)
 {
-    uint64_t start = MAX(r1.start, r2.start);
+    int64_t start = MAX(r1.start, r2.start);
     /* off-by-one arithmetic to prevent overflow */
-    uint64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1);
+    int64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1);
     return addrrange_make(start, end - start + 1);
 }
 
@@ -245,6 +250,10 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
 
 static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
 {
+    if (fr->dirty_log_mask) {
+        cpu_physical_sync_dirty_bitmap(fr->addr.start,
+                                       fr->addr.start + fr->addr.size);
+    }
     cpu_register_physical_memory(fr->addr.start, fr->addr.size,
                                  IO_MEM_UNASSIGNED);
 }
@@ -407,8 +416,8 @@ static void render_memory_region(FlatView *view,
     MemoryRegion *subregion;
     unsigned i;
     target_phys_addr_t offset_in_region;
-    uint64_t remain;
-    uint64_t now;
+    int64_t remain;
+    int64_t now;
     FlatRange fr;
     AddrRange tmp;
 
@@ -482,7 +491,7 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
 
     flatview_init(&view);
 
-    render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX));
+    render_memory_region(&view, mr, 0, addrrange_make(0, INT64_MAX));
     flatview_simplify(&view);
 
     return view;
diff --git a/migration.c b/migration.c
index 2a15b98db9..756fa6261f 100644
--- a/migration.c
+++ b/migration.c
@@ -292,18 +292,17 @@ int migrate_fd_cleanup(FdMigrationState *s)
             ret = -1;
         }
         s->file = NULL;
+    } else {
+        if (s->mon) {
+            monitor_resume(s->mon);
+        }
     }
 
-    if (s->fd != -1)
+    if (s->fd != -1) {
         close(s->fd);
-
-    /* Don't resume monitor until we've flushed all of the buffers */
-    if (s->mon) {
-        monitor_resume(s->mon);
+        s->fd = -1;
     }
 
-    s->fd = -1;
-
     return ret;
 }
 
@@ -330,9 +329,6 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
     if (ret == -EAGAIN) {
         qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
     } else if (ret < 0) {
-        if (s->mon) {
-            monitor_resume(s->mon);
-        }
         s->state = MIG_STATE_ERROR;
         notifier_list_notify(&migration_state_notifiers, NULL);
     }
@@ -458,6 +454,9 @@ int migrate_fd_close(void *opaque)
 {
     FdMigrationState *s = opaque;
 
+    if (s->mon) {
+        monitor_resume(s->mon);
+    }
     qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
     return s->close(s);
 }
diff --git a/net/socket.c b/net/socket.c
index 11fe5f383f..5cd0b9abf7 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -154,6 +154,12 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
     struct ip_mreq imr;
     int fd;
     int val, ret;
+#ifdef __OpenBSD__
+    unsigned char loop;
+#else
+    int loop;
+#endif
+
     if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) {
 	fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n",
 		inet_ntoa(mcastaddr->sin_addr),
@@ -197,9 +203,9 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr
     }
 
     /* Force mcast msgs to loopback (eg. several QEMUs in same host */
-    val = 1;
+    loop = 1;
     ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP,
-                   (const char *)&val, sizeof(val));
+                   (const char *)&loop, sizeof(loop));
     if (ret < 0) {
 	perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)");
 	goto fail;
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 2f3efdee03..4b6b3a41a0 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -28,6 +28,8 @@
 #include "qemu-error.h"
 
 #ifdef __NetBSD__
+#include <sys/ioctl.h>
+#include <net/if.h>
 #include <net/if_tap.h>
 #endif
 
@@ -40,8 +42,12 @@
 int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required)
 {
     int fd;
+#ifdef TAPGIFNAME
+    struct ifreq ifr;
+#else
     char *dev;
     struct stat s;
+#endif
 
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
     /* if no ifname is given, always start the search from tap0/tun0. */
@@ -77,14 +83,30 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
 #else
     TFR(fd = open("/dev/tap", O_RDWR));
     if (fd < 0) {
-        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
+        fprintf(stderr,
+            "warning: could not open /dev/tap: no virtual network emulation: %s\n",
+            strerror(errno));
         return -1;
     }
 #endif
 
-    fstat(fd, &s);
+#ifdef TAPGIFNAME
+    if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) {
+        fprintf(stderr, "warning: could not get tap name: %s\n",
+            strerror(errno));
+        return -1;
+    }
+    pstrcpy(ifname, ifname_size, ifr.ifr_name);
+#else
+    if (fstat(fd, &s) < 0) {
+        fprintf(stderr,
+            "warning: could not stat /dev/tap: no virtual network emulation: %s\n",
+            strerror(errno));
+        return -1;
+    }
     dev = devname(s.st_rdev, S_IFCHR);
     pstrcpy(ifname, ifname_size, dev);
+#endif
 
     if (*vnet_hdr) {
         /* BSD doesn't have IFF_VNET_HDR */
diff --git a/qemu-common.h b/qemu-common.h
index afbd04d321..0fdecf1ede 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -270,7 +270,10 @@ typedef struct QEMUSGList QEMUSGList;
 
 typedef uint64_t pcibus_t;
 
-void cpu_exec_init_all(unsigned long tb_size);
+void tcg_exec_init(unsigned long tb_size);
+bool tcg_enabled(void);
+
+void cpu_exec_init_all(void);
 
 /* CPU save/load.  */
 void cpu_save(QEMUFile *f, void *opaque);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 47e1991712..31199f6004 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -288,6 +288,14 @@ then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt) and if you use
 @kindex Ctrl-Alt-f
 Toggle full screen
 
+@item Ctrl-Alt-+
+@kindex Ctrl-Alt-+
+Enlarge the screen
+
+@item Ctrl-Alt--
+@kindex Ctrl-Alt--
+Shrink the screen
+
 @item Ctrl-Alt-u
 @kindex Ctrl-Alt-u
 Restore the screen's un-scaled dimensions
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index 820dee22b0..5d7b8acd1d 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -24,9 +24,9 @@
 
 #include "slirp.h"
 
-void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN])
+void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
 {
-    const in_addr_t broadcast_addr =
+    const uint32_t broadcast_addr =
         ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
     ArpTable *arptbl = &slirp->arp_table;
     int i;
@@ -60,29 +60,29 @@ void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN])
     arptbl->next_victim = (arptbl->next_victim + 1) % ARP_TABLE_SIZE;
 }
 
-bool arp_table_search(Slirp *slirp, int in_ip_addr,
+bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
                       uint8_t out_ethaddr[ETH_ALEN])
 {
-    const in_addr_t broadcast_addr =
+    const uint32_t broadcast_addr =
         ~slirp->vnetwork_mask.s_addr | slirp->vnetwork_addr.s_addr;
     ArpTable *arptbl = &slirp->arp_table;
     int i;
 
     DEBUG_CALL("arp_table_search");
-    DEBUG_ARG("ip = 0x%x", in_ip_addr);
+    DEBUG_ARG("ip = 0x%x", ip_addr);
 
     /* Check 0.0.0.0/8 invalid source-only addresses */
-    assert((in_ip_addr & htonl(~(0xf << 28))) != 0);
+    assert((ip_addr & htonl(~(0xf << 28))) != 0);
 
     /* If broadcast address */
-    if (in_ip_addr == 0xffffffff || in_ip_addr == broadcast_addr) {
+    if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) {
         /* return Ethernet broadcast address */
         memset(out_ethaddr, 0xff, ETH_ALEN);
         return 1;
     }
 
     for (i = 0; i < ARP_TABLE_SIZE; i++) {
-        if (arptbl->table[i].ar_sip == in_ip_addr) {
+        if (arptbl->table[i].ar_sip == ip_addr) {
             memcpy(out_ethaddr, arptbl->table[i].ar_sha,  ETH_ALEN);
             DEBUG_ARGS((dfd, " found hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
                         out_ethaddr[0], out_ethaddr[1], out_ethaddr[2],
diff --git a/slirp/if.c b/slirp/if.c
index 2d79e45bcd..2852396a4a 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -106,9 +106,6 @@ if_output(struct socket *so, struct mbuf *ifm)
 	ifs_init(ifm);
 	insque(ifm, ifq);
 
-        /* Expiration date = Now + 1 second */
-        ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL;
-
 diddit:
 	slirp->if_queued++;
 
@@ -157,9 +154,8 @@ diddit:
 void
 if_start(Slirp *slirp)
 {
+    uint64_t now = qemu_get_clock_ns(rt_clock);
     int requeued = 0;
-    uint64_t now;
-
 	struct mbuf *ifm, *ifqt;
 
 	DEBUG_CALL("if_start");
@@ -172,8 +168,6 @@ if_start(Slirp *slirp)
         if (!slirp_can_output(slirp->opaque))
             return;
 
-        now = qemu_get_clock_ns(rt_clock);
-
 	/*
 	 * See which queue to get next packet from
 	 * If there's something in the fastq, select it immediately
diff --git a/slirp/slirp.c b/slirp/slirp.c
index a86cc6eb2d..2c242ef4eb 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -738,6 +738,9 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
             slirp->client_ipaddr = iph->ip_dst;
             slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
             ifm->arp_requested = true;
+
+            /* Expire request and drop outgoing packet after 1 second */
+            ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL;
         }
         return 0;
     } else {
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 2a070e6126..dcf99d5ca4 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -208,9 +208,9 @@ typedef struct ArpTable {
     int next_victim;
 } ArpTable;
 
-void arp_table_add(Slirp *slirp, int ip_addr, uint8_t ethaddr[ETH_ALEN]);
+void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN]);
 
-bool arp_table_search(Slirp *slirp, int in_ip_addr,
+bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
                       uint8_t out_ethaddr[ETH_ALEN]);
 
 struct Slirp {
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 919be12a38..c2e7bb31ef 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -426,7 +426,7 @@ int cpu_alpha_exec(CPUAlphaState *s);
 int cpu_alpha_signal_handler(int host_signum, void *pinfo,
                              void *puc);
 int cpu_alpha_handle_mmu_fault (CPUState *env, uint64_t address, int rw,
-                                int mmu_idx, int is_softmmu);
+                                int mmu_idx);
 #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
 void do_interrupt (CPUState *env);
 
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 7049c80d5c..06d2565a5c 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -160,7 +160,7 @@ void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
 
 #if defined(CONFIG_USER_ONLY)
 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                                int mmu_idx, int is_softmmu)
+                                int mmu_idx)
 {
     env->exception_index = EXCP_MMFAULT;
     env->trap_arg0 = address;
@@ -316,7 +316,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 }
 
 int cpu_alpha_handle_mmu_fault(CPUState *env, target_ulong addr, int rw,
-                               int mmu_idx, int is_softmmu)
+                               int mmu_idx)
 {
     target_ulong phys;
     int prot, fail;
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index c2bb679090..38be2346e0 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -1344,7 +1344,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_alpha_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret != 0)) {
         do_restore_state(retaddr);
         /* Exception index and error code are already set */
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index adef42785c..f17fd6b32c 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -244,7 +244,7 @@ uint32_t do_arm_semihosting(CPUARMState *env);
 int cpu_arm_signal_handler(int host_signum, void *pinfo,
                            void *puc);
 int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmuu);
+                              int mmu_idx);
 #define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
 
 static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index ae4f334e40..1ee199d154 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -542,7 +542,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
     if (rw == 2) {
         env->exception_index = EXCP_PREFETCH_ABORT;
@@ -1254,7 +1254,7 @@ static inline int get_phys_addr(CPUState *env, uint32_t address,
 }
 
 int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
-                              int access_type, int mmu_idx, int is_softmmu)
+                              int access_type, int mmu_idx)
 {
     uint32_t phys_addr;
     target_ulong page_size;
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 57e4977cff..37b77e14e5 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -86,7 +86,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index ecb0df1d33..8ae0ce3ef3 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -226,7 +226,7 @@ static inline int cpu_mmu_index (CPUState *env)
 }
 
 int cpu_cris_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu);
+                              int mmu_idx);
 #define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-cris/helper.c b/target-cris/helper.c
index 962d214177..75f0035e6e 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -47,7 +47,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_cris_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-                             int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
 	env->exception_index = 0xaa;
 	env->pregs[PR_EDA] = address;
@@ -68,7 +68,7 @@ static void cris_shift_ccs(CPUState *env)
 }
 
 int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+                               int mmu_idx)
 {
 	struct cris_mmu_result res;
 	int prot, miss;
@@ -104,10 +104,9 @@ int cpu_cris_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                 r = 0;
 	}
 	if (r > 0)
-		D_LOG("%s returns %d irqreq=%x addr=%x"
-			  " phy=%x ismmu=%d vec=%x pc=%x\n", 
-			  __func__, r, env->interrupt_request, 
-			  address, res.phy, is_softmmu, res.bf_vec, env->pc);
+            D_LOG("%s returns %d irqreq=%x addr=%x phy=%x vec=%x pc=%x\n",
+                  __func__, r, env->interrupt_request, address, res.phy,
+                  res.bf_vec, env->pc);
 	return r;
 }
 
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index 246f08fcf6..0cfe1b1870 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -70,7 +70,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 
     D_LOG("%s pc=%x tpc=%x ra=%x\n", __func__, 
 	     env->pc, env->debug1, retaddr);
-    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index dd6c5fab3b..ae0e4b1438 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -889,7 +889,7 @@ void host_cpuid(uint32_t function, uint32_t count,
 
 /* helper.c */
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int mmu_idx, int is_softmmu);
+                             int is_write, int mmu_idx);
 #define cpu_handle_mmu_fault cpu_x86_handle_mmu_fault
 void cpu_x86_set_a20(CPUX86State *env, int a20_state);
 
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 182009a4c2..f8c8633d8b 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -546,7 +546,7 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write, int mmu_idx, int is_softmmu)
+                             int is_write, int mmu_idx)
 {
     /* user mode only emulation */
     is_write &= 1;
@@ -573,7 +573,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
    1  = generate PF fault
 */
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
-                             int is_write1, int mmu_idx, int is_softmmu)
+                             int is_write1, int mmu_idx)
 {
     uint64_t ptep, pte;
     target_ulong pde_addr, pte_addr;
@@ -1243,8 +1243,8 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
     cpu_exec_init(env);
     env->cpu_model_str = cpu_model;
 
-    /* init various static tables */
-    if (!inited) {
+    /* init various static tables used in TCG mode */
+    if (tcg_enabled() && !inited) {
         inited = 1;
         optimize_flags_init();
 #ifndef CONFIG_USER_ONLY
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 138093454d..1bbc3b56dc 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -5009,7 +5009,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_x86_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 876b5be2bd..037ef528ed 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -205,7 +205,7 @@ void cpu_lm32_set_phys_msb_ignore(CPUState *env, int value);
 #define CPU_SAVE_VERSION 1
 
 int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                            int mmu_idx, int is_softmmu);
+                              int mmu_idx);
 #define cpu_handle_mmu_fault cpu_lm32_handle_mmu_fault
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index e79428d8e0..48c402e31b 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -26,7 +26,7 @@
 #include "host-utils.h"
 
 int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
     int prot;
 
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 32b9a03c0e..557da6ce38 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -87,7 +87,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index e0f9b32014..0667f8214a 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -231,7 +231,7 @@ static inline int cpu_mmu_index (CPUState *env)
 }
 
 int cpu_m68k_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu);
+                              int mmu_idx);
 #define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index a936fe7b76..7ca75fb06d 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -344,7 +344,7 @@ void m68k_switch_sp(CPUM68KState *env)
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+                               int mmu_idx)
 {
     env->exception_index = EXCP_ACCESS;
     env->mmu.ar = address;
@@ -362,7 +362,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 }
 
 int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+                               int mmu_idx)
 {
     int prot;
 
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 764b6a08c6..c66fa0cf3d 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -66,7 +66,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 76f4fc4a7a..a81da629de 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -309,7 +309,7 @@ static inline int cpu_mmu_index (CPUState *env)
 }
 
 int cpu_mb_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                            int mmu_idx, int is_softmmu);
+                            int mmu_idx);
 #define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index 299259c3f0..2cf28022bd 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -37,7 +37,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_mb_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-                             int mmu_idx, int is_softmmu)
+                            int mmu_idx)
 {
     env->exception_index = 0xaa;
     cpu_dump_state(env, stderr, fprintf, 0);
@@ -47,7 +47,7 @@ int cpu_mb_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
 #else /* !CONFIG_USER_ONLY */
 
 int cpu_mb_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+                             int mmu_idx)
 {
     unsigned int hit;
     unsigned int mmu_available;
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index 189c59c9d6..8a7deac487 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -54,7 +54,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 030f499bfb..c5f70fa759 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -636,7 +636,7 @@ void cpu_mips_soft_irq(CPUState *env, int irq, int level);
 
 /* helper.c */
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu);
+                               int mmu_idx);
 #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
 void do_interrupt (CPUState *env);
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-mips/helper.c b/target-mips/helper.c
index ecf6182f56..024caa23c1 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -266,7 +266,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 #endif
 
 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+                               int mmu_idx)
 {
 #if !defined(CONFIG_USER_ONLY)
     target_phys_addr_t physical;
@@ -278,8 +278,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 #if 0
     log_cpu_state(env, 0);
 #endif
-    qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d smmu %d\n",
-              __func__, env->active_tc.PC, address, rw, mmu_idx, is_softmmu);
+    qemu_log("%s pc " TARGET_FMT_lx " ad " TARGET_FMT_lx " rw %d mmu_idx %d\n",
+              __func__, env->active_tc.PC, address, rw, mmu_idx);
 
     rw &= 1;
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 185ae40270..056011f1cc 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2017,7 +2017,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index d90336634d..024eb6f8ab 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1022,7 +1022,7 @@ void cpu_ppc_close (CPUPPCState *s);
 int cpu_ppc_signal_handler (int host_signum, void *pinfo,
                             void *puc);
 int cpu_ppc_handle_mmu_fault (CPUPPCState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu);
+                              int mmu_idx);
 #define cpu_handle_mmu_fault cpu_ppc_handle_mmu_fault
 #if !defined(CONFIG_USER_ONLY)
 int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong vaddr,
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 176128a3e2..789e6aa325 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -78,7 +78,7 @@ void (*cpu_ppc_hypercall)(CPUState *);
 
 #if defined(CONFIG_USER_ONLY)
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
     int exception, error_code;
 
@@ -1658,7 +1658,7 @@ static void booke206_update_mas_tlb_miss(CPUState *env, target_ulong address,
 
 /* Perform address translation */
 int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
     mmu_ctx_t ctx;
     int access_type;
@@ -3091,7 +3091,9 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
 
     env = qemu_mallocz(sizeof(CPUPPCState));
     cpu_exec_init(env);
-    ppc_translate_init();
+    if (tcg_enabled()) {
+        ppc_translate_init();
+    }
     env->cpu_model_str = cpu_model;
     cpu_ppc_register_internal(env, def);
 
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 6e100d987d..c5e0601292 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3725,7 +3725,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_ppc_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index d48a9b7a0c..f8f0c82c6f 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -280,7 +280,7 @@ void do_interrupt (CPUState *env);
 int cpu_s390x_signal_handler(int host_signum, void *pinfo,
                            void *puc);
 int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmuu);
+                                int mmu_idx);
 #define cpu_handle_mmu_fault cpu_s390x_handle_mmu_fault
 
 
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 1ce7079af7..db88603d7e 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -81,7 +81,7 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model)
 
     env = qemu_mallocz(sizeof(CPUS390XState));
     cpu_exec_init(env);
-    if (!inited) {
+    if (tcg_enabled() && !inited) {
         inited = 1;
         s390x_translate_init();
     }
@@ -110,10 +110,10 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu)
+                                int mmu_idx)
 {
-    /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d is_softmmu %d\n",
-            __FUNCTION__, address, rw, mmu_idx, is_softmmu); */
+    /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d\n",
+            __FUNCTION__, address, rw, mmu_idx); */
     env->exception_index = EXCP_ADDR;
     env->__excp_addr = address; /* FIXME: find out how this works on a real machine */
     return 1;
@@ -394,14 +394,14 @@ out:
 }
 
 int cpu_s390x_handle_mmu_fault (CPUState *env, target_ulong _vaddr, int rw,
-                                int mmu_idx, int is_softmmu)
+                                int mmu_idx)
 {
     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
     target_ulong vaddr, raddr;
     int prot;
 
-    DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d is_softmmu %d\n",
-            __FUNCTION__, _vaddr, rw, mmu_idx, is_softmmu);
+    DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n",
+            __FUNCTION__, _vaddr, rw, mmu_idx);
 
     _vaddr &= TARGET_PAGE_MASK;
     vaddr = _vaddr;
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 25a1e81ef4..b3ac630a6a 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -63,7 +63,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 00e32f2b10..7d7fdde019 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -194,7 +194,7 @@ int cpu_sh4_exec(CPUSH4State * s);
 int cpu_sh4_signal_handler(int host_signum, void *pinfo,
                            void *puc);
 int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
-			     int mmu_idx, int is_softmmu);
+                             int mmu_idx);
 #define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault
 void do_interrupt(CPUSH4State * env);
 
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 20e9b134d6..5a1e15e63d 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -34,7 +34,7 @@ void do_interrupt (CPUState *env)
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int mmu_idx, int is_softmmu)
+                             int mmu_idx)
 {
     env->tea = address;
     env->exception_index = -1;
@@ -440,7 +440,7 @@ static int get_physical_address(CPUState * env, target_ulong * physical,
 }
 
 int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
-			     int mmu_idx, int is_softmmu)
+                             int mmu_idx)
 {
     target_ulong physical;
     int prot, ret, access_type;
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 568bf0dba4..163858f560 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -64,7 +64,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
        generated code */
     saved_env = env;
     env = cpu_single_env;
-    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (ret) {
         /* now we have a real cpu fault */
         cpu_restore_state_from_retaddr(retaddr);
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index a51863cf07..8654f26a4e 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -490,7 +490,7 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model);
 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu);
+                               int mmu_idx);
 #define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault
 target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env);
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index efab885b83..47110a55ce 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -42,7 +42,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
 #if defined(CONFIG_USER_ONLY)
 
 int cpu_sparc_handle_mmu_fault(CPUState *env1, target_ulong address, int rw,
-                               int mmu_idx, int is_softmmu)
+                               int mmu_idx)
 {
     if (rw & 2)
         env1->exception_index = TT_TFAULT;
@@ -212,7 +212,7 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
     target_phys_addr_t paddr;
     target_ulong vaddr;
@@ -638,7 +638,7 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
 
 /* Perform address translation */
 int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
     target_ulong virt_addr, vaddr;
     target_phys_addr_t paddr;
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 5aeca2b06d..d1a8dd9939 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -4237,7 +4237,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     saved_env = env;
     env = cpu_single_env;
 
-    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
+    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (ret) {
         cpu_restore_state2(retaddr);
         cpu_loop_exit(env);
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 958fbc5a9d..dee67b334f 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1286,7 +1286,6 @@ static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
 }
 #endif
 
-/* XXX: potentially incorrect if dynamic npc */
 static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                       TCGv r_cond)
 {
@@ -1321,13 +1320,17 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
         } else {
             dc->pc = dc->npc;
             dc->jump_pc[0] = target;
-            dc->jump_pc[1] = dc->npc + 4;
-            dc->npc = JUMP_PC;
+            if (unlikely(dc->npc == DYNAMIC_PC)) {
+                dc->jump_pc[1] = DYNAMIC_PC;
+                tcg_gen_addi_tl(cpu_pc, cpu_npc, 4);
+            } else {
+                dc->jump_pc[1] = dc->npc + 4;
+                dc->npc = JUMP_PC;
+            }
         }
     }
 }
 
-/* XXX: potentially incorrect if dynamic npc */
 static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                       TCGv r_cond)
 {
@@ -1362,14 +1365,18 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
         } else {
             dc->pc = dc->npc;
             dc->jump_pc[0] = target;
-            dc->jump_pc[1] = dc->npc + 4;
-            dc->npc = JUMP_PC;
+            if (unlikely(dc->npc == DYNAMIC_PC)) {
+                dc->jump_pc[1] = DYNAMIC_PC;
+                tcg_gen_addi_tl(cpu_pc, cpu_npc, 4);
+            } else {
+                dc->jump_pc[1] = dc->npc + 4;
+                dc->npc = JUMP_PC;
+            }
         }
     }
 }
 
 #ifdef TARGET_SPARC64
-/* XXX: potentially incorrect if dynamic npc */
 static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
                           TCGv r_cond, TCGv r_reg)
 {
@@ -1384,8 +1391,13 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
     } else {
         dc->pc = dc->npc;
         dc->jump_pc[0] = target;
-        dc->jump_pc[1] = dc->npc + 4;
-        dc->npc = JUMP_PC;
+        if (unlikely(dc->npc == DYNAMIC_PC)) {
+            dc->jump_pc[1] = DYNAMIC_PC;
+            tcg_gen_addi_tl(cpu_pc, cpu_npc, 4);
+        } else {
+            dc->jump_pc[1] = dc->npc + 4;
+            dc->npc = JUMP_PC;
+        }
     }
 }
 
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 981760734f..b4e72cfa6e 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -130,7 +130,7 @@ CPUState *uc32_cpu_init(const char *cpu_model);
 int uc32_cpu_exec(CPUState *s);
 int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
 int uc32_cpu_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmuu);
+                              int mmu_idx);
 
 #define CPU_SAVE_VERSION 2
 
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index 02707d5857..8edfcb75be 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -104,7 +104,7 @@ void do_interrupt(CPUState *env)
 }
 
 int uc32_cpu_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
-                              int mmu_idx, int is_softmmu)
+                              int mmu_idx)
 {
     env->exception_index = UC32_EXCP_TRAP;
     env->cp0.c4_faultaddr = address;
diff --git a/tcg/optimize.c b/tcg/optimize.c
index a3bfa5e71d..7eb5eb1c70 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -185,12 +185,15 @@ static int op_to_movi(int op)
     }
 }
 
-static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src,
-                            int nb_temps, int nb_globals)
+static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, TCGArg dst,
+                            TCGArg src, int nb_temps, int nb_globals)
 {
         reset_temp(dst, nb_temps, nb_globals);
         assert(temps[src].state != TCG_TEMP_COPY);
-        if (src >= nb_globals) {
+        /* Don't try to copy if one of temps is a global or either one
+           is local and another is register */
+        if (src >= nb_globals && dst >= nb_globals &&
+            tcg_arg_is_local(s, src) == tcg_arg_is_local(s, dst)) {
             assert(temps[src].state != TCG_TEMP_CONST);
             if (temps[src].state != TCG_TEMP_HAS_COPY) {
                 temps[src].state = TCG_TEMP_HAS_COPY;
@@ -474,7 +477,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                     gen_opc_buf[op_index] = INDEX_op_nop;
                 } else {
                     gen_opc_buf[op_index] = op_to_mov(op);
-                    tcg_opt_gen_mov(gen_args, args[0], args[1],
+                    tcg_opt_gen_mov(s, gen_args, args[0], args[1],
                                     nb_temps, nb_globals);
                     gen_args += 2;
                     args += 3;
@@ -500,7 +503,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                     gen_opc_buf[op_index] = INDEX_op_nop;
                 } else {
                     gen_opc_buf[op_index] = op_to_mov(op);
-                    tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps,
+                    tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps,
                                     nb_globals);
                     gen_args += 2;
                     args += 3;
@@ -523,7 +526,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                 break;
             }
             if (temps[args[1]].state != TCG_TEMP_CONST) {
-                tcg_opt_gen_mov(gen_args, args[0], args[1],
+                tcg_opt_gen_mov(s, gen_args, args[0], args[1],
                                 nb_temps, nb_globals);
                 gen_args += 2;
                 args += 2;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index e76f9afecc..e2a7095bb5 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -410,6 +410,11 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void)
 void tcg_temp_free_i64(TCGv_i64 arg);
 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
 
+static inline bool tcg_arg_is_local(TCGContext *s, TCGArg arg)
+{
+    return s->temps[arg].temp_local;
+}
+
 #if defined(CONFIG_DEBUG_TCG)
 /* If you call tcg_clear_temp_count() at the start of a section of
  * code which is not supposed to leak any TCG temporaries, then
diff --git a/ui/sdl.c b/ui/sdl.c
index 6dbc5cb0ed..30cde8662e 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -39,15 +39,16 @@ static SDL_Surface *real_screen;
 static SDL_Surface *guest_screen = NULL;
 static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
 static int last_vm_running;
+static bool gui_saved_scaling;
+static int gui_saved_width;
+static int gui_saved_height;
 static int gui_saved_grab;
 static int gui_fullscreen;
 static int gui_noframe;
 static int gui_key_modifier_pressed;
 static int gui_keysym;
-static int gui_fullscreen_initial_grab;
 static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
 static uint8_t modifiers_state[256];
-static int width, height;
 static SDL_Cursor *sdl_cursor_normal;
 static SDL_Cursor *sdl_cursor_hidden;
 static int absolute_enabled = 0;
@@ -91,20 +92,21 @@ static void sdl_setdata(DisplayState *ds)
                                             ds->surface->pf.bmask, ds->surface->pf.amask);
 }
 
-static void do_sdl_resize(int new_width, int new_height, int bpp)
+static void do_sdl_resize(int width, int height, int bpp)
 {
     int flags;
 
     //    printf("resizing to %d %d\n", w, h);
 
-    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL|SDL_RESIZABLE;
-    if (gui_fullscreen)
+    flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
+    if (gui_fullscreen) {
         flags |= SDL_FULLSCREEN;
+    } else {
+        flags |= SDL_RESIZABLE;
+    }
     if (gui_noframe)
         flags |= SDL_NOFRAME;
 
-    width = new_width;
-    height = new_height;
     real_screen = SDL_SetVideoMode(width, height, bpp, flags);
     if (!real_screen) {
 	fprintf(stderr, "Could not open SDL display (%dx%dx%d): %s\n", width, 
@@ -447,7 +449,7 @@ static void sdl_show_cursor(void)
     if (!cursor_hide)
         return;
 
-    if (!kbd_mouse_is_absolute()) {
+    if (!kbd_mouse_is_absolute() || !is_graphic_console()) {
         SDL_ShowCursor(1);
         if (guest_cursor &&
                 (gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
@@ -485,32 +487,32 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
 {
     if (kbd_mouse_is_absolute()) {
         if (!absolute_enabled) {
-            sdl_hide_cursor();
-            if (gui_grab) {
-                sdl_grab_end();
-            }
+            sdl_grab_start();
             absolute_enabled = 1;
         }
     } else if (absolute_enabled) {
-	sdl_show_cursor();
-	absolute_enabled = 0;
+        sdl_grab_end();
+        absolute_enabled = 0;
     }
 }
 
 static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state)
 {
-    int buttons;
-    buttons = 0;
-    if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
+    int buttons = 0;
+
+    if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) {
         buttons |= MOUSE_EVENT_LBUTTON;
-    if (state & SDL_BUTTON(SDL_BUTTON_RIGHT))
+    }
+    if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) {
         buttons |= MOUSE_EVENT_RBUTTON;
-    if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
+    }
+    if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) {
         buttons |= MOUSE_EVENT_MBUTTON;
+    }
 
     if (kbd_mouse_is_absolute()) {
-       dx = x * 0x7FFF / (width - 1);
-       dy = y * 0x7FFF / (height - 1);
+        dx = x * 0x7FFF / (real_screen->w - 1);
+        dy = y * 0x7FFF / (real_screen->h - 1);
     } else if (guest_cursor) {
         x -= guest_x;
         y -= guest_y;
@@ -523,27 +525,331 @@ static void sdl_send_mouse_event(int dx, int dy, int dz, int x, int y, int state
     kbd_mouse_event(dx, dy, dz, buttons);
 }
 
+static void sdl_scale(DisplayState *ds, int width, int height)
+{
+    int bpp = real_screen->format->BitsPerPixel;
+
+    if (bpp != 16 && bpp != 32) {
+        bpp = 32;
+    }
+    do_sdl_resize(width, height, bpp);
+    scaling_active = 1;
+    if (!is_buffer_shared(ds->surface)) {
+        ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds),
+                                                 ds_get_height(ds));
+        dpy_resize(ds);
+    }
+}
+
 static void toggle_full_screen(DisplayState *ds)
 {
     gui_fullscreen = !gui_fullscreen;
-    do_sdl_resize(real_screen->w, real_screen->h, real_screen->format->BitsPerPixel);
     if (gui_fullscreen) {
+        gui_saved_width = real_screen->w;
+        gui_saved_height = real_screen->h;
+        gui_saved_scaling = scaling_active;
+
+        do_sdl_resize(ds_get_width(ds), ds_get_height(ds),
+                      ds_get_bits_per_pixel(ds));
         scaling_active = 0;
+
         gui_saved_grab = gui_grab;
         sdl_grab_start();
     } else {
-        if (!gui_saved_grab)
+        if (gui_saved_scaling) {
+            sdl_scale(ds, gui_saved_width, gui_saved_height);
+        } else {
+            do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
+        }
+        if (!gui_saved_grab || !is_graphic_console()) {
             sdl_grab_end();
+        }
     }
     vga_hw_invalidate();
     vga_hw_update();
 }
 
+static void absolute_mouse_grab(void)
+{
+    int mouse_x, mouse_y;
+
+    if (SDL_GetAppState() & SDL_APPINPUTFOCUS) {
+        SDL_GetMouseState(&mouse_x, &mouse_y);
+        if (mouse_x > 0 && mouse_x < real_screen->w - 1 &&
+            mouse_y > 0 && mouse_y < real_screen->h - 1) {
+            sdl_grab_start();
+        }
+    }
+}
+
+static void handle_keydown(DisplayState *ds, SDL_Event *ev)
+{
+    int mod_state;
+    int keycode;
+
+    if (alt_grab) {
+        mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
+                    (gui_grab_code | KMOD_LSHIFT);
+    } else if (ctrl_grab) {
+        mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
+    } else {
+        mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code;
+    }
+    gui_key_modifier_pressed = mod_state;
+
+    if (gui_key_modifier_pressed) {
+        keycode = sdl_keyevent_to_keycode(&ev->key);
+        switch (keycode) {
+        case 0x21: /* 'f' key on US keyboard */
+            toggle_full_screen(ds);
+            gui_keysym = 1;
+            break;
+        case 0x16: /* 'u' key on US keyboard */
+            if (scaling_active) {
+                scaling_active = 0;
+                sdl_resize(ds);
+                vga_hw_invalidate();
+                vga_hw_update();
+            }
+            gui_keysym = 1;
+            break;
+        case 0x02 ... 0x0a: /* '1' to '9' keys */
+            /* Reset the modifiers sent to the current console */
+            reset_keys();
+            console_select(keycode - 0x02);
+            gui_keysym = 1;
+            if (gui_fullscreen) {
+                break;
+            }
+            if (!is_graphic_console()) {
+                /* release grab if going to a text console */
+                if (gui_grab) {
+                    sdl_grab_end();
+                } else if (absolute_enabled) {
+                    sdl_show_cursor();
+                }
+            } else if (absolute_enabled) {
+                sdl_hide_cursor();
+                absolute_mouse_grab();
+            }
+            break;
+        case 0x1b: /* '+' */
+        case 0x35: /* '-' */
+            if (!gui_fullscreen) {
+                int width = MAX(real_screen->w + (keycode == 0x1b ? 50 : -50),
+                                160);
+                int height = (ds_get_height(ds) * width) / ds_get_width(ds);
+
+                sdl_scale(ds, width, height);
+                vga_hw_invalidate();
+                vga_hw_update();
+                gui_keysym = 1;
+            }
+        default:
+            break;
+        }
+    } else if (!is_graphic_console()) {
+        int keysym = 0;
+
+        if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
+            switch (ev->key.keysym.sym) {
+            case SDLK_UP:
+                keysym = QEMU_KEY_CTRL_UP;
+                break;
+            case SDLK_DOWN:
+                keysym = QEMU_KEY_CTRL_DOWN;
+                break;
+            case SDLK_LEFT:
+                keysym = QEMU_KEY_CTRL_LEFT;
+                break;
+            case SDLK_RIGHT:
+                keysym = QEMU_KEY_CTRL_RIGHT;
+                break;
+            case SDLK_HOME:
+                keysym = QEMU_KEY_CTRL_HOME;
+                break;
+            case SDLK_END:
+                keysym = QEMU_KEY_CTRL_END;
+                break;
+            case SDLK_PAGEUP:
+                keysym = QEMU_KEY_CTRL_PAGEUP;
+                break;
+            case SDLK_PAGEDOWN:
+                keysym = QEMU_KEY_CTRL_PAGEDOWN;
+                break;
+            default:
+                break;
+            }
+        } else {
+            switch (ev->key.keysym.sym) {
+            case SDLK_UP:
+                keysym = QEMU_KEY_UP;
+                break;
+            case SDLK_DOWN:
+                keysym = QEMU_KEY_DOWN;
+                break;
+            case SDLK_LEFT:
+                keysym = QEMU_KEY_LEFT;
+                break;
+            case SDLK_RIGHT:
+                keysym = QEMU_KEY_RIGHT;
+                break;
+            case SDLK_HOME:
+                keysym = QEMU_KEY_HOME;
+                break;
+            case SDLK_END:
+                keysym = QEMU_KEY_END;
+                break;
+            case SDLK_PAGEUP:
+                keysym = QEMU_KEY_PAGEUP;
+                break;
+            case SDLK_PAGEDOWN:
+                keysym = QEMU_KEY_PAGEDOWN;
+                break;
+            case SDLK_BACKSPACE:
+                keysym = QEMU_KEY_BACKSPACE;
+                break;
+            case SDLK_DELETE:
+                keysym = QEMU_KEY_DELETE;
+                break;
+            default:
+                break;
+            }
+        }
+        if (keysym) {
+            kbd_put_keysym(keysym);
+        } else if (ev->key.keysym.unicode != 0) {
+            kbd_put_keysym(ev->key.keysym.unicode);
+        }
+    }
+    if (is_graphic_console() && !gui_keysym) {
+        sdl_process_key(&ev->key);
+    }
+}
+
+static void handle_keyup(DisplayState *ds, SDL_Event *ev)
+{
+    int mod_state;
+
+    if (!alt_grab) {
+        mod_state = (ev->key.keysym.mod & gui_grab_code);
+    } else {
+        mod_state = (ev->key.keysym.mod & (gui_grab_code | KMOD_LSHIFT));
+    }
+    if (!mod_state && gui_key_modifier_pressed) {
+        gui_key_modifier_pressed = 0;
+        if (gui_keysym == 0) {
+            /* exit/enter grab if pressing Ctrl-Alt */
+            if (!gui_grab) {
+                /* If the application is not active, do not try to enter grab
+                 * state. It prevents 'SDL_WM_GrabInput(SDL_GRAB_ON)' from
+                 * blocking all the application (SDL bug). */
+                if (is_graphic_console() &&
+                    SDL_GetAppState() & SDL_APPACTIVE) {
+                    sdl_grab_start();
+                }
+            } else if (!gui_fullscreen) {
+                sdl_grab_end();
+            }
+            /* SDL does not send back all the modifiers key, so we must
+             * correct it. */
+            reset_keys();
+            return;
+        }
+        gui_keysym = 0;
+    }
+    if (is_graphic_console() && !gui_keysym) {
+        sdl_process_key(&ev->key);
+    }
+}
+
+static void handle_mousemotion(DisplayState *ds, SDL_Event *ev)
+{
+    int max_x, max_y;
+
+    if (is_graphic_console() &&
+        (kbd_mouse_is_absolute() || absolute_enabled)) {
+        max_x = real_screen->w - 1;
+        max_y = real_screen->h - 1;
+        if (gui_grab && (ev->motion.x == 0 || ev->motion.y == 0 ||
+            ev->motion.x == max_x || ev->motion.y == max_y)) {
+            sdl_grab_end();
+        }
+        if (!gui_grab && SDL_GetAppState() & SDL_APPINPUTFOCUS &&
+            (ev->motion.x > 0 && ev->motion.x < max_x &&
+            ev->motion.y > 0 && ev->motion.y < max_y)) {
+            sdl_grab_start();
+        }
+    }
+    if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) {
+        sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
+                             ev->motion.x, ev->motion.y, ev->motion.state);
+    }
+}
+
+static void handle_mousebutton(DisplayState *ds, SDL_Event *ev)
+{
+    int buttonstate = SDL_GetMouseState(NULL, NULL);
+    SDL_MouseButtonEvent *bev;
+    int dz;
+
+    if (!is_graphic_console()) {
+        return;
+    }
+
+    bev = &ev->button;
+    if (!gui_grab && !kbd_mouse_is_absolute()) {
+        if (ev->type == SDL_MOUSEBUTTONDOWN &&
+            (bev->button == SDL_BUTTON_LEFT)) {
+            /* start grabbing all events */
+            sdl_grab_start();
+        }
+    } else {
+        dz = 0;
+        if (ev->type == SDL_MOUSEBUTTONDOWN) {
+            buttonstate |= SDL_BUTTON(bev->button);
+        } else {
+            buttonstate &= ~SDL_BUTTON(bev->button);
+        }
+#ifdef SDL_BUTTON_WHEELUP
+        if (bev->button == SDL_BUTTON_WHEELUP &&
+            ev->type == SDL_MOUSEBUTTONDOWN) {
+            dz = -1;
+        } else if (bev->button == SDL_BUTTON_WHEELDOWN &&
+                   ev->type == SDL_MOUSEBUTTONDOWN) {
+            dz = 1;
+        }
+#endif
+        sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate);
+    }
+}
+
+static void handle_activation(DisplayState *ds, SDL_Event *ev)
+{
+    if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS &&
+        !ev->active.gain && !gui_fullscreen) {
+        sdl_grab_end();
+    }
+    if (!gui_grab && ev->active.gain && is_graphic_console() &&
+        (kbd_mouse_is_absolute() || absolute_enabled)) {
+        absolute_mouse_grab();
+    }
+    if (ev->active.state & SDL_APPACTIVE) {
+        if (ev->active.gain) {
+            /* Back to default interval */
+            dcl->gui_timer_interval = 0;
+            dcl->idle = 0;
+        } else {
+            /* Sleeping interval */
+            dcl->gui_timer_interval = 500;
+            dcl->idle = 1;
+        }
+    }
+}
+
 static void sdl_refresh(DisplayState *ds)
 {
     SDL_Event ev1, *ev = &ev1;
-    int mod_state;
-    int buttonstate = SDL_GetMouseState(NULL, NULL);
 
     if (last_vm_running != vm_running) {
         last_vm_running = vm_running;
@@ -559,191 +865,32 @@ static void sdl_refresh(DisplayState *ds)
             sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
             break;
         case SDL_KEYDOWN:
+            handle_keydown(ds, ev);
+            break;
         case SDL_KEYUP:
-            if (ev->type == SDL_KEYDOWN) {
-                if (alt_grab) {
-                    mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
-                                (gui_grab_code | KMOD_LSHIFT);
-                } else if (ctrl_grab) {
-                    mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
-                } else {
-                    mod_state = (SDL_GetModState() & gui_grab_code) ==
-                                gui_grab_code;
-                }
-                gui_key_modifier_pressed = mod_state;
-                if (gui_key_modifier_pressed) {
-                    int keycode;
-                    keycode = sdl_keyevent_to_keycode(&ev->key);
-                    switch(keycode) {
-                    case 0x21: /* 'f' key on US keyboard */
-                        toggle_full_screen(ds);
-                        gui_keysym = 1;
-                        break;
-                    case 0x16: /* 'u' key on US keyboard */
-                        scaling_active = 0;
-                        sdl_resize(ds);
-                        vga_hw_invalidate();
-                        vga_hw_update();
-                        break;
-                    case 0x02 ... 0x0a: /* '1' to '9' keys */
-                        /* Reset the modifiers sent to the current console */
-                        reset_keys();
-                        console_select(keycode - 0x02);
-                        if (!is_graphic_console()) {
-                            /* display grab if going to a text console */
-                            if (gui_grab)
-                                sdl_grab_end();
-                        }
-                        gui_keysym = 1;
-                        break;
-                    default:
-                        break;
-                    }
-                } else if (!is_graphic_console()) {
-                    int keysym;
-                    keysym = 0;
-                    if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
-                        switch(ev->key.keysym.sym) {
-                        case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break;
-                        case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break;
-                        case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break;
-                        case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break;
-                        case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
-                        case SDLK_END: keysym = QEMU_KEY_CTRL_END; break;
-                        case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
-                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
-                        default: break;
-                        }
-                    } else {
-                        switch(ev->key.keysym.sym) {
-                        case SDLK_UP: keysym = QEMU_KEY_UP; break;
-                        case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break;
-                        case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break;
-                        case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break;
-                        case SDLK_HOME: keysym = QEMU_KEY_HOME; break;
-                        case SDLK_END: keysym = QEMU_KEY_END; break;
-                        case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
-                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
-                        case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;
-                        case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
-                        default: break;
-                        }
-                    }
-                    if (keysym) {
-                        kbd_put_keysym(keysym);
-                    } else if (ev->key.keysym.unicode != 0) {
-                        kbd_put_keysym(ev->key.keysym.unicode);
-                    }
-                }
-            } else if (ev->type == SDL_KEYUP) {
-                if (!alt_grab) {
-                    mod_state = (ev->key.keysym.mod & gui_grab_code);
-                } else {
-                    mod_state = (ev->key.keysym.mod &
-                                 (gui_grab_code | KMOD_LSHIFT));
-                }
-                if (!mod_state) {
-                    if (gui_key_modifier_pressed) {
-                        gui_key_modifier_pressed = 0;
-                        if (gui_keysym == 0) {
-                            /* exit/enter grab if pressing Ctrl-Alt */
-                            if (!gui_grab) {
-                                /* if the application is not active,
-                                   do not try to enter grab state. It
-                                   prevents
-                                   'SDL_WM_GrabInput(SDL_GRAB_ON)'
-                                   from blocking all the application
-                                   (SDL bug). */
-                                if (SDL_GetAppState() & SDL_APPACTIVE)
-                                    sdl_grab_start();
-                            } else {
-                                sdl_grab_end();
-                            }
-                            /* SDL does not send back all the
-                               modifiers key, so we must correct it */
-                            reset_keys();
-                            break;
-                        }
-                        gui_keysym = 0;
-                    }
-                }
-            }
-            if (is_graphic_console() && !gui_keysym)
-                sdl_process_key(&ev->key);
+            handle_keyup(ds, ev);
             break;
         case SDL_QUIT:
-            if (!no_quit)
+            if (!no_quit) {
+                no_shutdown = 0;
                 qemu_system_shutdown_request();
+            }
             break;
         case SDL_MOUSEMOTION:
-            if (gui_grab || kbd_mouse_is_absolute() ||
-                absolute_enabled) {
-                sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
-                       ev->motion.x, ev->motion.y, ev->motion.state);
-            }
+            handle_mousemotion(ds, ev);
             break;
         case SDL_MOUSEBUTTONDOWN:
         case SDL_MOUSEBUTTONUP:
-            {
-                SDL_MouseButtonEvent *bev = &ev->button;
-                if (!gui_grab && !kbd_mouse_is_absolute()) {
-                    if (ev->type == SDL_MOUSEBUTTONDOWN &&
-                        (bev->button == SDL_BUTTON_LEFT)) {
-                        /* start grabbing all events */
-                        sdl_grab_start();
-                    }
-                } else {
-                    int dz;
-                    dz = 0;
-                    if (ev->type == SDL_MOUSEBUTTONDOWN) {
-                        buttonstate |= SDL_BUTTON(bev->button);
-                    } else {
-                        buttonstate &= ~SDL_BUTTON(bev->button);
-                    }
-#ifdef SDL_BUTTON_WHEELUP
-                    if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) {
-                        dz = -1;
-                    } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
-                        dz = 1;
-                    }
-#endif
-                    sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate);
-                }
-            }
+            handle_mousebutton(ds, ev);
             break;
         case SDL_ACTIVEEVENT:
-            if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS &&
-                !ev->active.gain && !gui_fullscreen_initial_grab) {
-                sdl_grab_end();
-            }
-            if (ev->active.state & SDL_APPACTIVE) {
-                if (ev->active.gain) {
-                    /* Back to default interval */
-                    dcl->gui_timer_interval = 0;
-                    dcl->idle = 0;
-                } else {
-                    /* Sleeping interval */
-                    dcl->gui_timer_interval = 500;
-                    dcl->idle = 1;
-                }
-            }
+            handle_activation(ds, ev);
             break;
-	case SDL_VIDEORESIZE:
-        {
-	    SDL_ResizeEvent *rev = &ev->resize;
-            int bpp = real_screen->format->BitsPerPixel;
-            if (bpp != 16 && bpp != 32)
-                bpp = 32;
-            do_sdl_resize(rev->w, rev->h, bpp);
-            scaling_active = 1;
-            if (!is_buffer_shared(ds->surface)) {
-                ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds), ds_get_height(ds));
-                dpy_resize(ds);
-            }
+        case SDL_VIDEORESIZE:
+            sdl_scale(ds, ev->resize.w, ev->resize.h);
             vga_hw_invalidate();
             vga_hw_update();
             break;
-        }
         default:
             break;
         }
@@ -865,6 +1012,11 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
         qemu_free(filename);
     }
 
+    if (full_screen) {
+        gui_fullscreen = 1;
+        sdl_grab_start();
+    }
+
     dcl = qemu_mallocz(sizeof(DisplayChangeListener));
     dcl->dpy_update = sdl_update;
     dcl->dpy_resize = sdl_resize;
@@ -894,9 +1046,4 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     sdl_cursor_normal = SDL_GetCursor();
 
     atexit(sdl_cleanup);
-    if (full_screen) {
-        gui_fullscreen = 1;
-        gui_fullscreen_initial_grab = 1;
-        sdl_grab_start();
-    }
 }
diff --git a/user-exec.c b/user-exec.c
index 14c0f251b4..abf688546e 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -102,7 +102,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
     }
 
     /* see if it is an MMU fault */
-    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
+    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX);
     if (ret < 0) {
         return 0; /* not an MMU fault */
     }
diff --git a/vl.c b/vl.c
index 426cea7c37..c7141274f7 100644
--- a/vl.c
+++ b/vl.c
@@ -265,6 +265,7 @@ int kvm_allowed = 0;
 int xen_allowed = 0;
 uint32_t xen_domid;
 enum xen_mode xen_mode = XEN_EMULATE;
+static int tcg_tb_size;
 
 static int default_serial = 1;
 static int default_parallel = 1;
@@ -1932,6 +1933,7 @@ static QEMUMachine *machine_parse(const char *name)
 
 static int tcg_init(void)
 {
+    tcg_exec_init(tcg_tb_size * 1024 * 1024);
     return 0;
 }
 
@@ -2092,7 +2094,6 @@ int main(int argc, char **argv, char **envp)
     const char *loadvm = NULL;
     QEMUMachine *machine;
     const char *cpu_model;
-    int tb_size;
     const char *pid_file = NULL;
     const char *incoming = NULL;
 #ifdef CONFIG_VNC
@@ -2132,7 +2133,6 @@ int main(int argc, char **argv, char **envp)
     nb_numa_nodes = 0;
     nb_nics = 0;
 
-    tb_size = 0;
     autostart= 1;
 
     /* first pass of option parsing */
@@ -2847,9 +2847,10 @@ int main(int argc, char **argv, char **envp)
                 configure_rtc(opts);
                 break;
             case QEMU_OPTION_tb_size:
-                tb_size = strtol(optarg, NULL, 0);
-                if (tb_size < 0)
-                    tb_size = 0;
+                tcg_tb_size = strtol(optarg, NULL, 0);
+                if (tcg_tb_size < 0) {
+                    tcg_tb_size = 0;
+                }
                 break;
             case QEMU_OPTION_icount:
                 icount_option = optarg;
@@ -3123,8 +3124,7 @@ int main(int argc, char **argv, char **envp)
         }
     }
 
-    /* init the dynamic translator */
-    cpu_exec_init_all(tb_size * 1024 * 1024);
+    cpu_exec_init_all();
 
     bdrv_init_with_whitelist();