Merge branch 'arm-devs.next' of git://git.linaro.org/people/pmaydell/qemu-arm
authorBlue Swirl <blauwirbel@gmail.com>
Sat, 20 Apr 2013 11:39:08 +0000 (11:39 +0000)
committerBlue Swirl <blauwirbel@gmail.com>
Sat, 20 Apr 2013 11:39:08 +0000 (11:39 +0000)
* 'arm-devs.next' of git://git.linaro.org/people/pmaydell/qemu-arm:
  hw/versatile_pci: Drop unnecessary vpb_pci_config_addr()
  versatile_pci: Expose PCI memory space to system
  arm/realview: Fix mapping of PCI regions
  versatile_pci: Implement the PCI controller's control registers
  versatile_pci: Implement the correct PCI IRQ mapping
  versatile_pci: Put the host bridge PCI device at slot 29
  versatile_pci: Use separate PCI I/O space rather than system I/O space
  versatile_pci: Change to subclassing TYPE_PCI_HOST_BRIDGE
  versatile_pci: Update to realize and instance init functions
  versatile_pci: Expose PCI I/O region on Versatile PB
  versatile_pci: Fix hardcoded tabs

39 files changed:
block/ssh.c
cpus.c
default-configs/pci.mak
docs/specs/pci-testdev.txt [new file with mode: 0644]
hw/arm/armv7m.c
hw/arm/boot.c
hw/arm/musicpal.c
hw/arm/nseries.c
hw/arm/omap1.c
hw/audio/marvell_88w8618.c
hw/block/m25p80.c
hw/display/pxa2xx_lcd.c
hw/dma/pxa2xx_dma.c
hw/dma/xilinx_axidma.c
hw/gpio/zaurus.c
hw/microblaze/boot.c
hw/misc/Makefile.objs
hw/misc/macio/mac_dbdma.c
hw/misc/milkymist-pfpu.c
hw/misc/pci-testdev.c [new file with mode: 0644]
hw/net/mcf_fec.c
hw/ppc/ppc405_boards.c
hw/ppc/virtex_ml507.c
include/hw/pci/pci.h
include/hw/virtio/virtio.h
include/qemu/bswap.h
include/sysemu/kvm.h
kvm-all.c
kvm-stub.c
linux-user/syscall.c
scripts/kvm/vmxcap
target-arm/cpu-qom.h
target-arm/cpu.c
target-arm/cpu.h
target-arm/machine.c
target-arm/translate.c
target-i386/cpu.h
target-i386/kvm.c
target-i386/machine.c

index 8f78e2e4b9cf868f428a57d91556275dbaf28c45..93a8b53ffd34b9e5c7fbb1097870e502fa94ea35 100644 (file)
@@ -109,7 +109,7 @@ static void ssh_state_free(BDRVSSHState *s)
 /* Wrappers around error_report which make sure to dump as much
  * information from libssh2 as possible.
  */
-static void
+static void GCC_FMT_ATTR(2, 3)
 session_error_report(BDRVSSHState *s, const char *fs, ...)
 {
     va_list args;
@@ -132,7 +132,7 @@ session_error_report(BDRVSSHState *s, const char *fs, ...)
     error_printf("\n");
 }
 
-static void
+static void GCC_FMT_ATTR(2, 3)
 sftp_error_report(BDRVSSHState *s, const char *fs, ...)
 {
     va_list args;
@@ -387,15 +387,13 @@ static int check_host_key(BDRVSSHState *s, const char *host, int port,
     }
 
     /* host_key_check=md5:xx:yy:zz:... */
-    if (strlen(host_key_check) >= 4 &&
-        strncmp(host_key_check, "md5:", 4) == 0) {
+    if (strncmp(host_key_check, "md5:", 4) == 0) {
         return check_host_key_hash(s, &host_key_check[4],
                                    LIBSSH2_HOSTKEY_HASH_MD5, 16);
     }
 
     /* host_key_check=sha1:xx:yy:zz:... */
-    if (strlen(host_key_check) >= 5 &&
-        strncmp(host_key_check, "sha1:", 5) == 0) {
+    if (strncmp(host_key_check, "sha1:", 5) == 0) {
         return check_host_key_hash(s, &host_key_check[5],
                                    LIBSSH2_HOSTKEY_HASH_SHA1, 20);
     }
diff --git a/cpus.c b/cpus.c
index c15ff6c5fee824c3c7a28664dfce2820d7915fef..5a98a370df92bebb3f634d00af3c78a42fc3c7c2 100644 (file)
--- a/cpus.c
+++ b/cpus.c
@@ -865,7 +865,7 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
         CONTEXT tcgContext;
 
         if (SuspendThread(cpu->hThread) == (DWORD)-1) {
-            fprintf(stderr, "qemu:%s: GetLastError:%d\n", __func__,
+            fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__,
                     GetLastError());
             exit(1);
         }
@@ -881,7 +881,7 @@ static void qemu_cpu_kick_thread(CPUState *cpu)
         cpu_signal(0);
 
         if (ResumeThread(cpu->hThread) == (DWORD)-1) {
-            fprintf(stderr, "qemu:%s: GetLastError:%d\n", __func__,
+            fprintf(stderr, "qemu:%s: GetLastError:%lu\n", __func__,
                     GetLastError());
             exit(1);
         }
index f5f100ecb0d5361ef11c6a9aea5cd666aa8dcdff..b608f31c9a9d1d9c4f15f0a72b66db295817f934 100644 (file)
@@ -24,3 +24,4 @@ CONFIG_SERIAL=y
 CONFIG_SERIAL_PCI=y
 CONFIG_IPACK=y
 CONFIG_WDT_IB6300ESB=y
+CONFIG_PCI_TESTDEV=y
diff --git a/docs/specs/pci-testdev.txt b/docs/specs/pci-testdev.txt
new file mode 100644 (file)
index 0000000..128ae22
--- /dev/null
@@ -0,0 +1,26 @@
+pci-test is a device used for testing low level IO
+
+device implements up to two BARs: BAR0 and BAR1.
+Each BAR can be memory or IO. Guests must detect
+BAR type and act accordingly.
+
+Each BAR size is up to 4K bytes.
+Each BAR starts with the following header:
+
+typedef struct PCITestDevHdr {
+    uint8_t test;  <- write-only, starts a given test number
+    uint8_t width_type; <- read-only, type and width of access for a given test.
+                           1,2,4 for byte,word or long write.
+                           any other value if test not supported on this BAR
+    uint8_t pad0[2];
+    uint32_t offset; <- read-only, offset in this BAR for a given test
+    uint32_t data;    <- read-only, data to use for a given test
+    uint32_t count;  <- for debugging. number of writes detected.
+    uint8_t name[]; <- for debugging. 0-terminated ASCII string.
+} PCITestDevHdr;
+
+All registers are little endian.
+
+device is expected to always implement tests 0 to N on each BAR, and to add new
+tests with higher numbers.  In this way a guest can scan test numbers until it
+detects an access type that it does not support on this BAR, then stop.
index 2ae357676007851b2d0ec7a218c346c2d96dc876..93422bc7beedac74531f990bf33374fda618e679 100644 (file)
@@ -56,7 +56,7 @@ static uint32_t bitband_readw(void *opaque, hwaddr offset)
     addr = bitband_addr(opaque, offset) & ~1;
     mask = (1 << ((offset >> 2) & 15));
     mask = tswap16(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
+    cpu_physical_memory_read(addr, &v, 2);
     return (v & mask) != 0;
 }
 
@@ -69,12 +69,12 @@ static void bitband_writew(void *opaque, hwaddr offset,
     addr = bitband_addr(opaque, offset) & ~1;
     mask = (1 << ((offset >> 2) & 15));
     mask = tswap16(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 2);
+    cpu_physical_memory_read(addr, &v, 2);
     if (value & 1)
         v |= mask;
     else
         v &= ~mask;
-    cpu_physical_memory_write(addr, (uint8_t *)&v, 2);
+    cpu_physical_memory_write(addr, &v, 2);
 }
 
 static uint32_t bitband_readl(void *opaque, hwaddr offset)
@@ -85,7 +85,7 @@ static uint32_t bitband_readl(void *opaque, hwaddr offset)
     addr = bitband_addr(opaque, offset) & ~3;
     mask = (1 << ((offset >> 2) & 31));
     mask = tswap32(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
+    cpu_physical_memory_read(addr, &v, 4);
     return (v & mask) != 0;
 }
 
@@ -98,12 +98,12 @@ static void bitband_writel(void *opaque, hwaddr offset,
     addr = bitband_addr(opaque, offset) & ~3;
     mask = (1 << ((offset >> 2) & 31));
     mask = tswap32(mask);
-    cpu_physical_memory_read(addr, (uint8_t *)&v, 4);
+    cpu_physical_memory_read(addr, &v, 4);
     if (value & 1)
         v |= mask;
     else
         v &= ~mask;
-    cpu_physical_memory_write(addr, (uint8_t *)&v, 4);
+    cpu_physical_memory_write(addr, &v, 4);
 }
 
 static const MemoryRegionOps bitband_ops = {
index e9c09454ac55fffa92e72d5457bfe9a3dfb67f18..f451529fced1e84d9faca15035978a53d2cc4861 100644 (file)
@@ -128,7 +128,7 @@ static void set_kernel_args(const struct arm_boot_info *info)
         int cmdline_size;
 
         cmdline_size = strlen(info->kernel_cmdline);
-        cpu_physical_memory_write(p + 8, (void *)info->kernel_cmdline,
+        cpu_physical_memory_write(p + 8, info->kernel_cmdline,
                                   cmdline_size + 1);
         cmdline_size = (cmdline_size >> 2) + 1;
         WRITE_WORD(p, cmdline_size + 2);
@@ -219,7 +219,7 @@ static void set_kernel_args_old(const struct arm_boot_info *info)
     }
     s = info->kernel_cmdline;
     if (s) {
-        cpu_physical_memory_write(p, (void *)s, strlen(s) + 1);
+        cpu_physical_memory_write(p, s, strlen(s) + 1);
     } else {
         WRITE_WORD(p, 0);
     }
index 31586c652ef4852d4420e61b7c8b522adfd3f60f..f33ba9a03951f903477ef29599f1390efd7702f2 100644 (file)
@@ -170,12 +170,12 @@ static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc)
     cpu_to_le16s(&desc->buffer_size);
     cpu_to_le32s(&desc->buffer);
     cpu_to_le32s(&desc->next);
-    cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_write(addr, desc, sizeof(*desc));
 }
 
 static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
 {
-    cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_read(addr, desc, sizeof(*desc));
     le32_to_cpus(&desc->cmdstat);
     le16_to_cpus(&desc->bytes);
     le16_to_cpus(&desc->buffer_size);
@@ -229,12 +229,12 @@ static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
     cpu_to_le16s(&desc->bytes);
     cpu_to_le32s(&desc->buffer);
     cpu_to_le32s(&desc->next);
-    cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_write(addr, desc, sizeof(*desc));
 }
 
 static void eth_tx_desc_get(uint32_t addr, mv88w8618_tx_desc *desc)
 {
-    cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc));
+    cpu_physical_memory_read(addr, desc, sizeof(*desc));
     le32_to_cpus(&desc->cmdstat);
     le16_to_cpus(&desc->res);
     le16_to_cpus(&desc->bytes);
index 4976438ae6187ee86aae02ef7818cdea49791490..f6c9dc09ef6a5217730d32cd075bdbf117b76a12 100644 (file)
@@ -970,7 +970,7 @@ static void n800_gpmc_init(struct n800_s *s)
             (4 << 0);          /* BASEADDRESS */
 
     cpu_physical_memory_write(0x6800a078,              /* GPMC_CONFIG7_0 */
-                    (void *) &config7, sizeof(config7));
+                              &config7, sizeof(config7));
 }
 
 /* Setup sequence done by the bootloader */
@@ -982,7 +982,7 @@ static void n8x0_boot_init(void *opaque)
     /* PRCM setup */
 #define omap_writel(addr, val) \
     buf = (val);                       \
-    cpu_physical_memory_write(addr, (void *) &buf, sizeof(buf))
+    cpu_physical_memory_write(addr, &buf, sizeof(buf))
 
     omap_writel(0x48008060, 0x41);             /* PRCM_CLKSRC_CTRL */
     omap_writel(0x48008070, 1);                        /* PRCM_CLKOUT_CTRL */
index f59f0f291a2d7d856d7c8c8116864225cda4d467..c06c642acc982fa9e7538098896ebce717a67fb1 100644 (file)
@@ -31,7 +31,7 @@ uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
     uint8_t ret;
 
     OMAP_8B_REG(addr);
-    cpu_physical_memory_read(addr, (void *) &ret, 1);
+    cpu_physical_memory_read(addr, &ret, 1);
     return ret;
 }
 
@@ -41,7 +41,7 @@ void omap_badwidth_write8(void *opaque, hwaddr addr,
     uint8_t val8 = value;
 
     OMAP_8B_REG(addr);
-    cpu_physical_memory_write(addr, (void *) &val8, 1);
+    cpu_physical_memory_write(addr, &val8, 1);
 }
 
 uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
@@ -49,7 +49,7 @@ uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
     uint16_t ret;
 
     OMAP_16B_REG(addr);
-    cpu_physical_memory_read(addr, (void *) &ret, 2);
+    cpu_physical_memory_read(addr, &ret, 2);
     return ret;
 }
 
@@ -59,7 +59,7 @@ void omap_badwidth_write16(void *opaque, hwaddr addr,
     uint16_t val16 = value;
 
     OMAP_16B_REG(addr);
-    cpu_physical_memory_write(addr, (void *) &val16, 2);
+    cpu_physical_memory_write(addr, &val16, 2);
 }
 
 uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
@@ -67,7 +67,7 @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
     uint32_t ret;
 
     OMAP_32B_REG(addr);
-    cpu_physical_memory_read(addr, (void *) &ret, 4);
+    cpu_physical_memory_read(addr, &ret, 4);
     return ret;
 }
 
@@ -75,7 +75,7 @@ void omap_badwidth_write32(void *opaque, hwaddr addr,
                 uint32_t value)
 {
     OMAP_32B_REG(addr);
-    cpu_physical_memory_write(addr, (void *) &value, 4);
+    cpu_physical_memory_write(addr, &value, 4);
 }
 
 /* MPU OS timers */
index f9b68fd3112259ddcbda47a6211277778ac0d8a3..de06dfd7d2e397bc46840ed897121433767f4426 100644 (file)
@@ -77,8 +77,7 @@ static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in)
     if (block_size > 4096) {
         return;
     }
-    cpu_physical_memory_read(s->target_buffer + s->play_pos, (void *)buf,
-                             block_size);
+    cpu_physical_memory_read(s->target_buffer + s->play_pos, buf, block_size);
     mem_buffer = buf;
     if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
         if (s->playback_mode & MP_AUDIO_MONO) {
index efcc7f4c839b8b45bc73a578fc43369220a925cc..b3ca19ae520268ef22b572b9566f64c46bd4d3fa 100644 (file)
@@ -24,7 +24,6 @@
 #include "hw/hw.h"
 #include "sysemu/blockdev.h"
 #include "hw/ssi.h"
-#include "hw/devices.h"
 
 #ifndef M25P80_ERR_DEBUG
 #define M25P80_ERR_DEBUG 0
index 12d9cd28087fed403d33fd70e27efbbfb5579e4d..76276cf7f118c3a21da64553328c6fce8fecd338 100644 (file)
@@ -315,7 +315,7 @@ static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
             continue;
         }
 
-        cpu_physical_memory_read(descptr, (void *)&desc, sizeof(desc));
+        cpu_physical_memory_read(descptr, &desc, sizeof(desc));
         s->dma_ch[i].descriptor = tswap32(desc.fdaddr);
         s->dma_ch[i].source = tswap32(desc.fsaddr);
         s->dma_ch[i].id = tswap32(desc.fidr);
index 6e4c1f6d62303f8371a4085c234bccdab1d7589c..b60569fd88c720492f82b9ffa734a3316a2cca53 100644 (file)
@@ -151,7 +151,7 @@ static inline void pxa2xx_dma_descriptor_fetch(
     if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST))
         daddr += 32;
 
-    cpu_physical_memory_read(daddr, (uint8_t *) desc, 16);
+    cpu_physical_memory_read(daddr, desc, 16);
     s->chan[ch].descr = desc[DDADR];
     s->chan[ch].src = desc[DSADR];
     s->chan[ch].dest = desc[DTADR];
index 1c237622107daf2cdd1d35aef8d32efb77aa502c..bc62664daa18e5708a50ac2b87f557d351c66c47 100644 (file)
@@ -197,7 +197,7 @@ static void stream_desc_load(struct Stream *s, hwaddr addr)
 {
     struct SDesc *d = &s->desc;
 
-    cpu_physical_memory_read(addr, (void *) d, sizeof *d);
+    cpu_physical_memory_read(addr, d, sizeof *d);
 
     /* Convert from LE into host endianness.  */
     d->buffer_address = le64_to_cpu(d->buffer_address);
@@ -215,7 +215,7 @@ static void stream_desc_store(struct Stream *s, hwaddr addr)
     d->nxtdesc = cpu_to_le64(d->nxtdesc);
     d->control = cpu_to_le32(d->control);
     d->status = cpu_to_le32(d->status);
-    cpu_physical_memory_write(addr, (void *) d, sizeof *d);
+    cpu_physical_memory_write(addr, d, sizeof *d);
 }
 
 static void stream_update_irq(struct Stream *s)
index d853ea1310a0a13c36fb1b762a3971604a0405e1..c6cdef32122c4e457ec3d4820be64fb46f2c37c8 100644 (file)
@@ -287,6 +287,6 @@ static struct QEMU_PACKED sl_param_info {
 
 void sl_bootparam_write(hwaddr ptr)
 {
-    cpu_physical_memory_write(ptr, (void *)&zaurus_bootparam,
+    cpu_physical_memory_write(ptr, &zaurus_bootparam,
                               sizeof(struct sl_param_info));
 }
index 23cb11d70e69c5a8000997aac7824a1b1c080c42..e543d886b83048ef1767d99dd6140246ee482b93 100644 (file)
@@ -80,7 +80,7 @@ static int microblaze_load_dtb(hwaddr addr,
         }
     }
 
-    cpu_physical_memory_write(addr, (void *)fdt, fdt_size);
+    cpu_physical_memory_write(addr, fdt, fdt_size);
 #else
     /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
        to the kernel.  */
index 03699c3365af0d430d8cc08a552607c169d1e362..11b18a41963d3b5ccbc421698f2ec5ca419e548c 100644 (file)
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_TMP105) += tmp105.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
 common-obj-$(CONFIG_SGA) += sga.o
 common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
+common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o
 
 obj-$(CONFIG_VMPORT) += vmport.o
 
index a2363bbdf291a0524c76623f8bc0d3db82565424..2fc7f87bb6fb51cf0404b8031a5429cf57535ce7 100644 (file)
@@ -192,7 +192,7 @@ static void dbdma_cmdptr_load(DBDMA_channel *ch)
     DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n",
                   ch->regs[DBDMA_CMDPTR_LO]);
     cpu_physical_memory_read(ch->regs[DBDMA_CMDPTR_LO],
-                             (uint8_t*)&ch->current, sizeof(dbdma_cmd));
+                             &ch->current, sizeof(dbdma_cmd));
 }
 
 static void dbdma_cmdptr_save(DBDMA_channel *ch)
@@ -203,7 +203,7 @@ static void dbdma_cmdptr_save(DBDMA_channel *ch)
                   le16_to_cpu(ch->current.xfer_status),
                   le16_to_cpu(ch->current.res_count));
     cpu_physical_memory_write(ch->regs[DBDMA_CMDPTR_LO],
-                              (uint8_t*)&ch->current, sizeof(dbdma_cmd));
+                              &ch->current, sizeof(dbdma_cmd));
 }
 
 static void kill_channel(DBDMA_channel *ch)
@@ -454,7 +454,7 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
         return;
     }
 
-    cpu_physical_memory_read(addr, (uint8_t*)&val, len);
+    cpu_physical_memory_read(addr, &val, len);
 
     if (len == 2)
         val = (val << 16) | (current->cmd_dep & 0x0000ffff);
@@ -499,7 +499,7 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
     else if (len == 1)
         val >>= 24;
 
-    cpu_physical_memory_write(addr, (uint8_t*)&val, len);
+    cpu_physical_memory_write(addr, &val, len);
 
     if (conditional_wait(ch))
         goto wait;
index ad44b4db22f6b964745dd5058c63e0d35fc4a960..fe1b0395504f1a913b1fbeef67d6a8a144860ab8 100644 (file)
@@ -228,8 +228,8 @@ static int pfpu_decode_insn(MilkymistPFPUState *s)
         hwaddr dma_ptr =
             get_dma_address(s->regs[R_MESHBASE],
                     s->gp_regs[GPR_X], s->gp_regs[GPR_Y]);
-        cpu_physical_memory_write(dma_ptr, (uint8_t *)&a, 4);
-        cpu_physical_memory_write(dma_ptr + 4, (uint8_t *)&b, 4);
+        cpu_physical_memory_write(dma_ptr, &a, 4);
+        cpu_physical_memory_write(dma_ptr + 4, &b, 4);
         s->regs[R_LASTDMA] = dma_ptr + 4;
         D_EXEC(qemu_log("VECTOUT a=%08x b=%08x dma=%08x\n", a, b, dma_ptr));
         trace_milkymist_pfpu_vectout(a, b, dma_ptr);
diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c
new file mode 100644 (file)
index 0000000..71ce5a3
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * QEMU PCI test device
+ *
+ * Copyright (c) 2012 Red Hat Inc.
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ *
+ * 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/hw.h"
+#include "hw/pci/pci.h"
+#include "qemu/event_notifier.h"
+#include "qemu/osdep.h"
+
+typedef struct PCITestDevHdr {
+    uint8_t test;
+    uint8_t width;
+    uint8_t pad0[2];
+    uint32_t offset;
+    uint8_t data;
+    uint8_t pad1[3];
+    uint32_t count;
+    uint8_t name[];
+} PCITestDevHdr;
+
+typedef struct IOTest {
+    MemoryRegion *mr;
+    EventNotifier notifier;
+    bool hasnotifier;
+    unsigned size;
+    bool match_data;
+    PCITestDevHdr *hdr;
+    unsigned bufsize;
+} IOTest;
+
+#define IOTEST_DATAMATCH 0xFA
+#define IOTEST_NOMATCH   0xCE
+
+#define IOTEST_IOSIZE 128
+#define IOTEST_MEMSIZE 2048
+
+static const char *iotest_test[] = {
+    "no-eventfd",
+    "wildcard-eventfd",
+    "datamatch-eventfd"
+};
+
+static const char *iotest_type[] = {
+    "mmio",
+    "portio"
+};
+
+#define IOTEST_TEST(i) (iotest_test[((i) % ARRAY_SIZE(iotest_test))])
+#define IOTEST_TYPE(i) (iotest_type[((i) / ARRAY_SIZE(iotest_test))])
+#define IOTEST_MAX_TEST (ARRAY_SIZE(iotest_test))
+#define IOTEST_MAX_TYPE (ARRAY_SIZE(iotest_type))
+#define IOTEST_MAX (IOTEST_MAX_TEST * IOTEST_MAX_TYPE)
+
+enum {
+    IOTEST_ACCESS_NAME,
+    IOTEST_ACCESS_DATA,
+    IOTEST_ACCESS_MAX,
+};
+
+#define IOTEST_ACCESS_TYPE uint8_t
+#define IOTEST_ACCESS_WIDTH (sizeof(uint8_t))
+
+typedef struct PCITestDevState {
+    PCIDevice dev;
+    MemoryRegion mmio;
+    MemoryRegion portio;
+    IOTest *tests;
+    int current;
+} PCITestDevState;
+
+#define IOTEST_IS_MEM(i) (strcmp(IOTEST_TYPE(i), "portio"))
+#define IOTEST_REGION(d, i) (IOTEST_IS_MEM(i) ?  &(d)->mmio : &(d)->portio)
+#define IOTEST_SIZE(i) (IOTEST_IS_MEM(i) ? IOTEST_MEMSIZE : IOTEST_IOSIZE)
+#define IOTEST_PCI_BAR(i) (IOTEST_IS_MEM(i) ? PCI_BASE_ADDRESS_SPACE_MEMORY : \
+                           PCI_BASE_ADDRESS_SPACE_IO)
+
+static int pci_testdev_start(IOTest *test)
+{
+    test->hdr->count = 0;
+    if (!test->hasnotifier) {
+        return 0;
+    }
+    event_notifier_test_and_clear(&test->notifier);
+    memory_region_add_eventfd(test->mr,
+                              le32_to_cpu(test->hdr->offset),
+                              test->size,
+                              test->match_data,
+                              test->hdr->data,
+                              &test->notifier);
+    return 0;
+}
+
+static void pci_testdev_stop(IOTest *test)
+{
+    if (!test->hasnotifier) {
+        return;
+    }
+    memory_region_del_eventfd(test->mr,
+                              le32_to_cpu(test->hdr->offset),
+                              test->size,
+                              test->match_data,
+                              test->hdr->data,
+                              &test->notifier);
+}
+
+static void
+pci_testdev_reset(PCITestDevState *d)
+{
+    if (d->current == -1) {
+        return;
+    }
+    pci_testdev_stop(&d->tests[d->current]);
+    d->current = -1;
+}
+
+static void pci_testdev_inc(IOTest *test, unsigned inc)
+{
+    uint32_t c = le32_to_cpu(test->hdr->count);
+    test->hdr->count = cpu_to_le32(c + inc);
+}
+
+static void
+pci_testdev_write(void *opaque, hwaddr addr, uint64_t val,
+                  unsigned size, int type)
+{
+    PCITestDevState *d = opaque;
+    IOTest *test;
+    int t, r;
+
+    if (addr == offsetof(PCITestDevHdr, test)) {
+        pci_testdev_reset(d);
+        if (val >= IOTEST_MAX_TEST) {
+            return;
+        }
+        t = type * IOTEST_MAX_TEST + val;
+        r = pci_testdev_start(&d->tests[t]);
+        if (r < 0) {
+            return;
+        }
+        d->current = t;
+        return;
+    }
+    if (d->current < 0) {
+        return;
+    }
+    test = &d->tests[d->current];
+    if (addr != le32_to_cpu(test->hdr->offset)) {
+        return;
+    }
+    if (test->match_data && test->size != size) {
+        return;
+    }
+    if (test->match_data && val != test->hdr->data) {
+        return;
+    }
+    pci_testdev_inc(test, 1);
+}
+
+static uint64_t
+pci_testdev_read(void *opaque, hwaddr addr, unsigned size)
+{
+    PCITestDevState *d = opaque;
+    const char *buf;
+    IOTest *test;
+    if (d->current < 0) {
+        return 0;
+    }
+    test = &d->tests[d->current];
+    buf = (const char *)test->hdr;
+    if (addr + size >= test->bufsize) {
+        return 0;
+    }
+    if (test->hasnotifier) {
+        event_notifier_test_and_clear(&test->notifier);
+    }
+    return buf[addr];
+}
+
+static void
+pci_testdev_mmio_write(void *opaque, hwaddr addr, uint64_t val,
+                       unsigned size)
+{
+    pci_testdev_write(opaque, addr, val, size, 0);
+}
+
+static void
+pci_testdev_pio_write(void *opaque, hwaddr addr, uint64_t val,
+                       unsigned size)
+{
+    pci_testdev_write(opaque, addr, val, size, 1);
+}
+
+static const MemoryRegionOps pci_testdev_mmio_ops = {
+    .read = pci_testdev_read,
+    .write = pci_testdev_mmio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+static const MemoryRegionOps pci_testdev_pio_ops = {
+    .read = pci_testdev_read,
+    .write = pci_testdev_pio_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 1,
+    },
+};
+
+static int pci_testdev_init(PCIDevice *pci_dev)
+{
+    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, pci_dev);
+    uint8_t *pci_conf;
+    char *name;
+    int r, i;
+
+    pci_conf = d->dev.config;
+
+    pci_conf[PCI_INTERRUPT_PIN] = 0; /* no interrupt pin */
+
+    memory_region_init_io(&d->mmio, &pci_testdev_mmio_ops, d,
+                          "pci-testdev-mmio", IOTEST_MEMSIZE * 2);
+    memory_region_init_io(&d->portio, &pci_testdev_pio_ops, d,
+                          "pci-testdev-portio", IOTEST_IOSIZE * 2);
+    pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
+    pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio);
+
+    d->current = -1;
+    d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests);
+    for (i = 0; i < IOTEST_MAX; ++i) {
+        IOTest *test = &d->tests[i];
+        name = g_strdup_printf("%s-%s", IOTEST_TYPE(i), IOTEST_TEST(i));
+        test->bufsize = sizeof(PCITestDevHdr) + strlen(name) + 1;
+        test->hdr = g_malloc0(test->bufsize);
+        memcpy(test->hdr->name, name, strlen(name) + 1);
+        g_free(name);
+        test->hdr->offset = cpu_to_le32(IOTEST_SIZE(i) + i * IOTEST_ACCESS_WIDTH);
+        test->size = IOTEST_ACCESS_WIDTH;
+        test->match_data = strcmp(IOTEST_TEST(i), "wildcard-eventfd");
+        test->hdr->test = i;
+        test->hdr->data = test->match_data ? IOTEST_DATAMATCH : IOTEST_NOMATCH;
+        test->hdr->width = IOTEST_ACCESS_WIDTH;
+        test->mr = IOTEST_REGION(d, i);
+        if (!strcmp(IOTEST_TEST(i), "no-eventfd")) {
+            test->hasnotifier = false;
+            continue;
+        }
+        r = event_notifier_init(&test->notifier, 0);
+        assert(r >= 0);
+        test->hasnotifier = true;
+    }
+
+    return 0;
+}
+
+static void
+pci_testdev_uninit(PCIDevice *dev)
+{
+    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev, dev);
+    int i;
+
+    pci_testdev_reset(d);
+    for (i = 0; i < IOTEST_MAX; ++i) {
+        if (d->tests[i].hasnotifier) {
+            event_notifier_cleanup(&d->tests[i].notifier);
+        }
+        g_free(d->tests[i].hdr);
+    }
+    g_free(d->tests);
+    memory_region_destroy(&d->mmio);
+    memory_region_destroy(&d->portio);
+}
+
+static void qdev_pci_testdev_reset(DeviceState *dev)
+{
+    PCITestDevState *d = DO_UPCAST(PCITestDevState, dev.qdev, dev);
+    pci_testdev_reset(d);
+}
+
+static void pci_testdev_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_testdev_init;
+    k->exit = pci_testdev_uninit;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT;
+    k->device_id = PCI_DEVICE_ID_REDHAT_TEST;
+    k->revision = 0x00;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->desc = "PCI Test Device";
+    dc->reset = qdev_pci_testdev_reset;
+}
+
+static const TypeInfo pci_testdev_info = {
+    .name          = "pci-testdev",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCITestDevState),
+    .class_init    = pci_testdev_class_init,
+};
+
+static void pci_testdev_register_types(void)
+{
+    type_register_static(&pci_testdev_info);
+}
+
+type_init(pci_testdev_register_types)
index 9b6805267d3dd0e0eca08387a9cb13309ce02a57..2ef5a0d73dcdfeebad703d8df0e26018c069b382 100644 (file)
@@ -108,7 +108,7 @@ typedef struct {
 
 static void mcf_fec_read_bd(mcf_fec_bd *bd, uint32_t addr)
 {
-    cpu_physical_memory_read(addr, (uint8_t *)bd, sizeof(*bd));
+    cpu_physical_memory_read(addr, bd, sizeof(*bd));
     be16_to_cpus(&bd->flags);
     be16_to_cpus(&bd->length);
     be32_to_cpus(&bd->data);
@@ -120,7 +120,7 @@ static void mcf_fec_write_bd(mcf_fec_bd *bd, uint32_t addr)
     tmp.flags = cpu_to_be16(bd->flags);
     tmp.length = cpu_to_be16(bd->length);
     tmp.data = cpu_to_be32(bd->data);
-    cpu_physical_memory_write(addr, (uint8_t *)&tmp, sizeof(tmp));
+    cpu_physical_memory_write(addr, &tmp, sizeof(tmp));
 }
 
 static void mcf_fec_update(mcf_fec_state *s)
index 8e56b16648f8085c5d643c14f041454cd072670c..f0c7ee9abd5891d40b6b47e8e48f0efd135e5e4f 100644 (file)
@@ -337,7 +337,7 @@ static void ref405ep_init(QEMUMachineInitArgs *args)
         if (kernel_cmdline != NULL) {
             len = strlen(kernel_cmdline);
             bdloc -= ((len + 255) & ~255);
-            cpu_physical_memory_write(bdloc, (void *)kernel_cmdline, len + 1);
+            cpu_physical_memory_write(bdloc, kernel_cmdline, len + 1);
             env->gpr[6] = bdloc;
             env->gpr[7] = bdloc + len;
         } else {
index 6728ba7ea08aab3741e6e66e940f82606c13ed89..1b4ce760e69d7acbcde3692d79e7e22ceb0687ff 100644 (file)
@@ -161,7 +161,7 @@ static int xilinx_load_device_tree(hwaddr addr,
     r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
     if (r < 0)
         fprintf(stderr, "couldn't set /chosen/bootargs\n");
-    cpu_physical_memory_write (addr, (void *)fdt, fdt_size);
+    cpu_physical_memory_write(addr, fdt, fdt_size);
 #else
     /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob
        to the kernel.  */
index 05315c0475e892d5d3b949341726411e2fe71398..7053d5bb4b6e45fbe426a5978f82b2a4caae22a9 100644 (file)
@@ -85,6 +85,7 @@
 #define PCI_DEVICE_ID_REDHAT_SERIAL      0x0002
 #define PCI_DEVICE_ID_REDHAT_SERIAL2     0x0003
 #define PCI_DEVICE_ID_REDHAT_SERIAL4     0x0004
+#define PCI_DEVICE_ID_REDHAT_TEST        0x0005
 #define PCI_DEVICE_ID_REDHAT_QXL         0x0100
 
 #define FMT_PCIBUS                      PRIx64
index b21e5c2b9d030e3f15df14ff81e773316487856c..d3f14366dcdf2a9c4eb8c57b13cf249d4147ea39 100644 (file)
@@ -258,7 +258,6 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
                               uint32_t host_features);
 typedef struct virtio_serial_conf virtio_serial_conf;
 VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *serial);
-VirtIODevice *virtio_balloon_init(DeviceState *dev);
 typedef struct VirtIOSCSIConf VirtIOSCSIConf;
 VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *conf);
 typedef struct VirtIORNGConf VirtIORNGConf;
@@ -270,7 +269,6 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
 
 void virtio_net_exit(VirtIODevice *vdev);
 void virtio_serial_exit(VirtIODevice *vdev);
-void virtio_balloon_exit(VirtIODevice *vdev);
 void virtio_scsi_exit(VirtIODevice *vdev);
 void virtio_rng_exit(VirtIODevice *vdev);
 
index d3af35d1d9d2bc27752bf63fa28b382618046bc2..14a5f657ce5d6bcc088fc52d42c4c6149b171d89 100644 (file)
@@ -4,6 +4,7 @@
 #include "config-host.h"
 #include <inttypes.h>
 #include <limits.h>
+#include <string.h>
 #include "fpu/softfloat.h"
 
 #ifdef CONFIG_MACHINE_BSWAP_H
index 495e6f8dbd8570eb813363e48a1e2af2d17811e9..75bd7d99343284106f0e312e7f1b1b560e504cb4 100644 (file)
@@ -283,10 +283,6 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
 #endif
 
 #endif
-int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign,
-                           uint32_t size);
-
-int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
 
 int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
 int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
index fc4e17c8bb909635bb324d299cc588031f0cacf8..2d927217bd64aa756736d833fec08fa471aac314 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -500,6 +500,66 @@ int kvm_check_extension(KVMState *s, unsigned int extension)
     return ret;
 }
 
+static int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val,
+                                  bool assign, uint32_t size, bool datamatch)
+{
+    int ret;
+    struct kvm_ioeventfd iofd;
+
+    iofd.datamatch = datamatch ? val : 0;
+    iofd.addr = addr;
+    iofd.len = size;
+    iofd.flags = 0;
+    iofd.fd = fd;
+
+    if (!kvm_enabled()) {
+        return -ENOSYS;
+    }
+
+    if (datamatch) {
+        iofd.flags |= KVM_IOEVENTFD_FLAG_DATAMATCH;
+    }
+    if (!assign) {
+        iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
+    }
+
+    ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd);
+
+    if (ret < 0) {
+        return -errno;
+    }
+
+    return 0;
+}
+
+static int kvm_set_ioeventfd_pio(int fd, uint16_t addr, uint16_t val,
+                                 bool assign, uint32_t size, bool datamatch)
+{
+    struct kvm_ioeventfd kick = {
+        .datamatch = datamatch ? val : 0,
+        .addr = addr,
+        .flags = KVM_IOEVENTFD_FLAG_PIO,
+        .len = size,
+        .fd = fd,
+    };
+    int r;
+    if (!kvm_enabled()) {
+        return -ENOSYS;
+    }
+    if (datamatch) {
+        kick.flags |= KVM_IOEVENTFD_FLAG_DATAMATCH;
+    }
+    if (!assign) {
+        kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
+    }
+    r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
+    if (r < 0) {
+        return r;
+    }
+    return 0;
+}
+
+
 static int kvm_check_many_ioeventfds(void)
 {
     /* Userspace can use ioeventfd for io notification.  This requires a host
@@ -517,7 +577,7 @@ static int kvm_check_many_ioeventfds(void)
         if (ioeventfds[i] < 0) {
             break;
         }
-        ret = kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, true);
+        ret = kvm_set_ioeventfd_pio(ioeventfds[i], 0, i, true, 2, true);
         if (ret < 0) {
             close(ioeventfds[i]);
             break;
@@ -528,7 +588,7 @@ static int kvm_check_many_ioeventfds(void)
     ret = i == ARRAY_SIZE(ioeventfds);
 
     while (i-- > 0) {
-        kvm_set_ioeventfd_pio_word(ioeventfds[i], 0, i, false);
+        kvm_set_ioeventfd_pio(ioeventfds[i], 0, i, false, 2, true);
         close(ioeventfds[i]);
     }
     return ret;
@@ -748,10 +808,8 @@ static void kvm_mem_ioeventfd_add(MemoryListener *listener,
     int fd = event_notifier_get_fd(e);
     int r;
 
-    assert(match_data && section->size <= 8);
-
     r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
-                               data, true, section->size);
+                               data, true, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -766,7 +824,7 @@ static void kvm_mem_ioeventfd_del(MemoryListener *listener,
     int r;
 
     r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
-                               data, false, section->size);
+                               data, false, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -780,10 +838,8 @@ static void kvm_io_ioeventfd_add(MemoryListener *listener,
     int fd = event_notifier_get_fd(e);
     int r;
 
-    assert(match_data && section->size == 2);
-
-    r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
-                                   data, true);
+    r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space,
+                              data, true, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -798,8 +854,8 @@ static void kvm_io_ioeventfd_del(MemoryListener *listener,
     int fd = event_notifier_get_fd(e);
     int r;
 
-    r = kvm_set_ioeventfd_pio_word(fd, section->offset_within_address_space,
-                                   data, false);
+    r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space,
+                              data, false, section->size, match_data);
     if (r < 0) {
         abort();
     }
@@ -1967,59 +2023,6 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
 
     return r;
 }
-
-int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, bool assign,
-                           uint32_t size)
-{
-    int ret;
-    struct kvm_ioeventfd iofd;
-
-    iofd.datamatch = val;
-    iofd.addr = addr;
-    iofd.len = size;
-    iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH;
-    iofd.fd = fd;
-
-    if (!kvm_enabled()) {
-        return -ENOSYS;
-    }
-
-    if (!assign) {
-        iofd.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
-    }
-
-    ret = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &iofd);
-
-    if (ret < 0) {
-        return -errno;
-    }
-
-    return 0;
-}
-
-int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
-{
-    struct kvm_ioeventfd kick = {
-        .datamatch = val,
-        .addr = addr,
-        .len = 2,
-        .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO,
-        .fd = fd,
-    };
-    int r;
-    if (!kvm_enabled()) {
-        return -ENOSYS;
-    }
-    if (!assign) {
-        kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
-    }
-    r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
-    if (r < 0) {
-        return r;
-    }
-    return 0;
-}
-
 int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
 {
     return kvm_arch_on_sigbus_vcpu(cpu, code, addr);
index 723a813735cfadac8a4fe22114856f0901d81e36..5f52186ae713c777d3ac5051ca7e21786eb5d0cc 100644 (file)
@@ -101,16 +101,6 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
 }
 #endif
 
-int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
-{
-    return -ENOSYS;
-}
-
-int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign, uint32_t len)
-{
-    return -ENOSYS;
-}
-
 int kvm_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
 {
     return 1;
index 1f07621ffe2d00febfa016f3f9ab475a1f6c663a..c705960d7e3e5b1cfae1fb5a91537c241f2ba123 100644 (file)
@@ -914,7 +914,7 @@ static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
     for (i = 0; i < nw; i++) {
         v = 0;
         for (j = 0; j < TARGET_ABI_BITS; j++) {
-            v |= ((FD_ISSET(k, fds) != 0) << j);
+            v |= ((abi_ulong)(FD_ISSET(k, fds) != 0) << j);
             k++;
         }
         __put_user(v, &target_fds[i]);
@@ -2764,7 +2764,7 @@ static inline abi_long do_semop(int semid, abi_long ptr, unsigned nsops)
     if (target_to_host_sembuf(sops, ptr, nsops))
         return -TARGET_EFAULT;
 
-    return semop(semid, sops, nsops);
+    return get_errno(semop(semid, sops, nsops));
 }
 
 struct target_msqid_ds
@@ -6957,7 +6957,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_semop
     case TARGET_NR_semop:
-        ret = get_errno(do_semop(arg1, arg2, arg3));
+        ret = do_semop(arg1, arg2, arg3);
         break;
 #endif
 #ifdef TARGET_NR_semctl
@@ -7743,12 +7743,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             if (gidsetsize == 0)
                 break;
             if (!is_error(ret)) {
-                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0);
+                target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * sizeof(target_id), 0);
                 if (!target_grouplist)
                     goto efault;
                 for(i = 0;i < ret; i++)
                     target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
-                unlock_user(target_grouplist, arg2, gidsetsize * 2);
+                unlock_user(target_grouplist, arg2, gidsetsize * sizeof(target_id));
             }
         }
         break;
@@ -7760,7 +7760,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             int i;
             if (gidsetsize) {
                 grouplist = alloca(gidsetsize * sizeof(gid_t));
-                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1);
+                target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * sizeof(target_id), 1);
                 if (!target_grouplist) {
                     ret = -TARGET_EFAULT;
                     goto fail;
index 0b23f7795a32ccf36c64e130d2319fa28d6a6117..c90eda497afd4f0355e48d530dde1ae0f2ce9431 100755 (executable)
@@ -27,9 +27,9 @@ MSR_IA32_VMX_VMFUNC = 0x491
 class msr(object):
     def __init__(self):
         try:
-            self.f = file('/dev/cpu/0/msr')
+            self.f = open('/dev/cpu/0/msr', 'r', 0)
         except:
-            self.f = file('/dev/msr0')
+            self.f = open('/dev/msr0', 'r', 0)
     def read(self, index, default = None):
         import struct
         self.f.seek(index)
@@ -96,6 +96,19 @@ class Misc(object):
             print '  %-40s %s' % (self.bits[bits], fmt(v))
 
 controls = [
+    Misc(
+        name = 'Basic VMX Information',
+        bits = {
+            (0, 31): 'Revision',
+            (32,44): 'VMCS size',
+            48: 'VMCS restricted to 32 bit addresses',
+            49: 'Dual-monitor support',
+            (50, 53): 'VMCS memory type',
+            54: 'INS/OUTS instruction information',
+            55: 'IA32_VMX_TRUE_*_CTLS support',
+            },
+        msr = MSR_IA32_VMX_BASIC,
+        ),
     Control(
         name = 'pin-based controls',
         bits = {
@@ -103,6 +116,7 @@ controls = [
             3: 'NMI exiting',
             5: 'Virtual NMIs',
             6: 'Activate VMX-preemption timer',
+            7: 'Process posted interrupts',
             },
         cap_msr = MSR_IA32_VMX_PINBASED_CTLS,
         true_cap_msr = MSR_IA32_VMX_TRUE_PINBASED_CTLS,
@@ -143,15 +157,19 @@ controls = [
             0: 'Virtualize APIC accesses',
             1: 'Enable EPT',
             2: 'Descriptor-table exiting',
+            3: 'Enable RDTSCP',
             4: 'Virtualize x2APIC mode',
             5: 'Enable VPID',
             6: 'WBINVD exiting',
             7: 'Unrestricted guest',
+            8: 'APIC register emulation',
             9: 'Virtual interrupt delivery',
             10: 'PAUSE-loop exiting',
             11: 'RDRAND exiting',
             12: 'Enable INVPCID',
             13: 'Enable VM functions',
+            14: 'VMCS shadowing',
+            18: 'EPT-violation #VE'
             },
         cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2,
         ),
@@ -196,10 +214,12 @@ controls = [
             6: 'HLT activity state',
             7: 'Shutdown activity state',
             8: 'Wait-for-SIPI activity state',
+            15: 'IA32_SMBASE support',
             (16,24): 'Number of CR3-target values',
             (25,27): 'MSR-load/store count recommenation',
             28: 'IA32_SMM_MONITOR_CTL[2] can be set to 1',
-            (32,62): 'MSEG revision identifier',
+            29: 'VMWRITE to VM-exit information fields',
+            (32,63): 'MSEG revision identifier',
             },
         msr = MSR_IA32_VMX_MISC_CTLS,
         ),
index 25895509befb5f9cd4c0a62c5ccbad7c9071d56f..12fcefe0c693fc36a53c0b49f4308cae56dccf47 100644 (file)
@@ -111,6 +111,10 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
 
 #define ENV_OFFSET offsetof(ARMCPU, env)
 
+#ifndef CONFIG_USER_ONLY
+extern const struct VMStateDescription vmstate_arm_cpu;
+#endif
+
 void register_cp_regs_for_features(ARMCPU *cpu);
 
 void arm_cpu_do_interrupt(CPUState *cpu);
index a1e90939d671983b300593855fe08dc663152029..496a59f5c0936d14c2875e6430c06ef5a3c4103a 100644 (file)
@@ -814,6 +814,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = arm_cpu_class_by_name;
     cc->do_interrupt = arm_cpu_do_interrupt;
+    cpu_class_set_vmsd(cc, &vmstate_arm_cpu);
 }
 
 static void cpu_register(const ARMCPUInfo *info)
index 2b972212095d0819c5e2a12e322bf8fa82c97d74..54384446b4d1735236c568b97532e7726b97e2e6 100644 (file)
@@ -640,8 +640,6 @@ static inline CPUARMState *cpu_init(const char *cpu_model)
 #define cpu_signal_handler cpu_arm_signal_handler
 #define cpu_list arm_cpu_list
 
-#define CPU_SAVE_VERSION 9
-
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
index 68dca7ffb2b6c5bf2a77a4c3561d844b97dad600..4dd057c4889d85cc1156484e7c455a0c4f53cdc2 100644 (file)
 #include "hw/hw.h"
 #include "hw/boards.h"
 
-void cpu_save(QEMUFile *f, void *opaque)
+static bool vfp_needed(void *opaque)
 {
-    int i;
-    CPUARMState *env = (CPUARMState *)opaque;
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    for (i = 0; i < 16; i++) {
-        qemu_put_be32(f, env->regs[i]);
-    }
-    qemu_put_be32(f, cpsr_read(env));
-    qemu_put_be32(f, env->spsr);
-    for (i = 0; i < 6; i++) {
-        qemu_put_be32(f, env->banked_spsr[i]);
-        qemu_put_be32(f, env->banked_r13[i]);
-        qemu_put_be32(f, env->banked_r14[i]);
-    }
-    for (i = 0; i < 5; i++) {
-        qemu_put_be32(f, env->usr_regs[i]);
-        qemu_put_be32(f, env->fiq_regs[i]);
-    }
-    qemu_put_be32(f, env->cp15.c0_cpuid);
-    qemu_put_be32(f, env->cp15.c0_cssel);
-    qemu_put_be32(f, env->cp15.c1_sys);
-    qemu_put_be32(f, env->cp15.c1_coproc);
-    qemu_put_be32(f, env->cp15.c1_xscaleauxcr);
-    qemu_put_be32(f, env->cp15.c1_scr);
-    qemu_put_be32(f, env->cp15.c2_base0);
-    qemu_put_be32(f, env->cp15.c2_base0_hi);
-    qemu_put_be32(f, env->cp15.c2_base1);
-    qemu_put_be32(f, env->cp15.c2_base1_hi);
-    qemu_put_be32(f, env->cp15.c2_control);
-    qemu_put_be32(f, env->cp15.c2_mask);
-    qemu_put_be32(f, env->cp15.c2_base_mask);
-    qemu_put_be32(f, env->cp15.c2_data);
-    qemu_put_be32(f, env->cp15.c2_insn);
-    qemu_put_be32(f, env->cp15.c3);
-    qemu_put_be32(f, env->cp15.c5_insn);
-    qemu_put_be32(f, env->cp15.c5_data);
-    for (i = 0; i < 8; i++) {
-        qemu_put_be32(f, env->cp15.c6_region[i]);
-    }
-    qemu_put_be32(f, env->cp15.c6_insn);
-    qemu_put_be32(f, env->cp15.c6_data);
-    qemu_put_be32(f, env->cp15.c7_par);
-    qemu_put_be32(f, env->cp15.c7_par_hi);
-    qemu_put_be32(f, env->cp15.c9_insn);
-    qemu_put_be32(f, env->cp15.c9_data);
-    qemu_put_be32(f, env->cp15.c9_pmcr);
-    qemu_put_be32(f, env->cp15.c9_pmcnten);
-    qemu_put_be32(f, env->cp15.c9_pmovsr);
-    qemu_put_be32(f, env->cp15.c9_pmxevtyper);
-    qemu_put_be32(f, env->cp15.c9_pmuserenr);
-    qemu_put_be32(f, env->cp15.c9_pminten);
-    qemu_put_be32(f, env->cp15.c13_fcse);
-    qemu_put_be32(f, env->cp15.c13_context);
-    qemu_put_be32(f, env->cp15.c13_tls1);
-    qemu_put_be32(f, env->cp15.c13_tls2);
-    qemu_put_be32(f, env->cp15.c13_tls3);
-    qemu_put_be32(f, env->cp15.c15_cpar);
-    qemu_put_be32(f, env->cp15.c15_power_control);
-    qemu_put_be32(f, env->cp15.c15_diagnostic);
-    qemu_put_be32(f, env->cp15.c15_power_diagnostic);
-
-    qemu_put_be64(f, env->features);
-
-    if (arm_feature(env, ARM_FEATURE_VFP)) {
-        for (i = 0;  i < 16; i++) {
-            CPU_DoubleU u;
-            u.d = env->vfp.regs[i];
-            qemu_put_be32(f, u.l.upper);
-            qemu_put_be32(f, u.l.lower);
-        }
-        for (i = 0; i < 16; i++) {
-            qemu_put_be32(f, env->vfp.xregs[i]);
-        }
+    return arm_feature(env, ARM_FEATURE_VFP);
+}
 
-        /* TODO: Should use proper FPSCR access functions.  */
-        qemu_put_be32(f, env->vfp.vec_len);
-        qemu_put_be32(f, env->vfp.vec_stride);
-
-        if (arm_feature(env, ARM_FEATURE_VFP3)) {
-            for (i = 16;  i < 32; i++) {
-                CPU_DoubleU u;
-                u.d = env->vfp.regs[i];
-                qemu_put_be32(f, u.l.upper);
-                qemu_put_be32(f, u.l.lower);
-            }
-        }
-    }
+static int get_fpscr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+    uint32_t val = qemu_get_be32(f);
 
-    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
-        for (i = 0; i < 16; i++) {
-            qemu_put_be64(f, env->iwmmxt.regs[i]);
-        }
-        for (i = 0; i < 16; i++) {
-            qemu_put_be32(f, env->iwmmxt.cregs[i]);
-        }
-    }
+    vfp_set_fpscr(env, val);
+    return 0;
+}
 
-    if (arm_feature(env, ARM_FEATURE_M)) {
-        qemu_put_be32(f, env->v7m.other_sp);
-        qemu_put_be32(f, env->v7m.vecbase);
-        qemu_put_be32(f, env->v7m.basepri);
-        qemu_put_be32(f, env->v7m.control);
-        qemu_put_be32(f, env->v7m.current_sp);
-        qemu_put_be32(f, env->v7m.exception);
-    }
+static void put_fpscr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
-        qemu_put_be32(f, env->teecr);
-        qemu_put_be32(f, env->teehbr);
-    }
+    qemu_put_be32(f, vfp_get_fpscr(env));
 }
 
-int cpu_load(QEMUFile *f, void *opaque, int version_id)
+static const VMStateInfo vmstate_fpscr = {
+    .name = "fpscr",
+    .get = get_fpscr,
+    .put = put_fpscr,
+};
+
+static const VMStateDescription vmstate_vfp = {
+    .name = "cpu/vfp",
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
+    .fields = (VMStateField[]) {
+        VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 32),
+        /* The xregs array is a little awkward because element 1 (FPSCR)
+         * requires a specific accessor, so we have to split it up in
+         * the vmstate:
+         */
+        VMSTATE_UINT32(env.vfp.xregs[0], ARMCPU),
+        VMSTATE_UINT32_SUB_ARRAY(env.vfp.xregs, ARMCPU, 2, 14),
+        {
+            .name = "fpscr",
+            .version_id = 0,
+            .size = sizeof(uint32_t),
+            .info = &vmstate_fpscr,
+            .flags = VMS_SINGLE,
+            .offset = 0,
+        },
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static bool iwmmxt_needed(void *opaque)
 {
-    CPUARMState *env = (CPUARMState *)opaque;
-    int i;
-    uint32_t val;
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    if (version_id != CPU_SAVE_VERSION)
-        return -EINVAL;
+    return arm_feature(env, ARM_FEATURE_IWMMXT);
+}
 
-    for (i = 0; i < 16; i++) {
-        env->regs[i] = qemu_get_be32(f);
-    }
-    val = qemu_get_be32(f);
-    /* Avoid mode switch when restoring CPSR.  */
-    env->uncached_cpsr = val & CPSR_M;
-    cpsr_write(env, val, 0xffffffff);
-    env->spsr = qemu_get_be32(f);
-    for (i = 0; i < 6; i++) {
-        env->banked_spsr[i] = qemu_get_be32(f);
-        env->banked_r13[i] = qemu_get_be32(f);
-        env->banked_r14[i] = qemu_get_be32(f);
-    }
-    for (i = 0; i < 5; i++) {
-        env->usr_regs[i] = qemu_get_be32(f);
-        env->fiq_regs[i] = qemu_get_be32(f);
-    }
-    env->cp15.c0_cpuid = qemu_get_be32(f);
-    env->cp15.c0_cssel = qemu_get_be32(f);
-    env->cp15.c1_sys = qemu_get_be32(f);
-    env->cp15.c1_coproc = qemu_get_be32(f);
-    env->cp15.c1_xscaleauxcr = qemu_get_be32(f);
-    env->cp15.c1_scr = qemu_get_be32(f);
-    env->cp15.c2_base0 = qemu_get_be32(f);
-    env->cp15.c2_base0_hi = qemu_get_be32(f);
-    env->cp15.c2_base1 = qemu_get_be32(f);
-    env->cp15.c2_base1_hi = qemu_get_be32(f);
-    env->cp15.c2_control = qemu_get_be32(f);
-    env->cp15.c2_mask = qemu_get_be32(f);
-    env->cp15.c2_base_mask = qemu_get_be32(f);
-    env->cp15.c2_data = qemu_get_be32(f);
-    env->cp15.c2_insn = qemu_get_be32(f);
-    env->cp15.c3 = qemu_get_be32(f);
-    env->cp15.c5_insn = qemu_get_be32(f);
-    env->cp15.c5_data = qemu_get_be32(f);
-    for (i = 0; i < 8; i++) {
-        env->cp15.c6_region[i] = qemu_get_be32(f);
+static const VMStateDescription vmstate_iwmmxt = {
+    .name = "cpu/iwmmxt",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16),
+        VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16),
+        VMSTATE_END_OF_LIST()
     }
-    env->cp15.c6_insn = qemu_get_be32(f);
-    env->cp15.c6_data = qemu_get_be32(f);
-    env->cp15.c7_par = qemu_get_be32(f);
-    env->cp15.c7_par_hi = qemu_get_be32(f);
-    env->cp15.c9_insn = qemu_get_be32(f);
-    env->cp15.c9_data = qemu_get_be32(f);
-    env->cp15.c9_pmcr = qemu_get_be32(f);
-    env->cp15.c9_pmcnten = qemu_get_be32(f);
-    env->cp15.c9_pmovsr = qemu_get_be32(f);
-    env->cp15.c9_pmxevtyper = qemu_get_be32(f);
-    env->cp15.c9_pmuserenr = qemu_get_be32(f);
-    env->cp15.c9_pminten = qemu_get_be32(f);
-    env->cp15.c13_fcse = qemu_get_be32(f);
-    env->cp15.c13_context = qemu_get_be32(f);
-    env->cp15.c13_tls1 = qemu_get_be32(f);
-    env->cp15.c13_tls2 = qemu_get_be32(f);
-    env->cp15.c13_tls3 = qemu_get_be32(f);
-    env->cp15.c15_cpar = qemu_get_be32(f);
-    env->cp15.c15_power_control = qemu_get_be32(f);
-    env->cp15.c15_diagnostic = qemu_get_be32(f);
-    env->cp15.c15_power_diagnostic = qemu_get_be32(f);
-
-    env->features = qemu_get_be64(f);
-
-    if (arm_feature(env, ARM_FEATURE_VFP)) {
-        for (i = 0;  i < 16; i++) {
-            CPU_DoubleU u;
-            u.l.upper = qemu_get_be32(f);
-            u.l.lower = qemu_get_be32(f);
-            env->vfp.regs[i] = u.d;
-        }
-        for (i = 0; i < 16; i++) {
-            env->vfp.xregs[i] = qemu_get_be32(f);
-        }
+};
 
-        /* TODO: Should use proper FPSCR access functions.  */
-        env->vfp.vec_len = qemu_get_be32(f);
-        env->vfp.vec_stride = qemu_get_be32(f);
-
-        if (arm_feature(env, ARM_FEATURE_VFP3)) {
-            for (i = 16;  i < 32; i++) {
-                CPU_DoubleU u;
-                u.l.upper = qemu_get_be32(f);
-                u.l.lower = qemu_get_be32(f);
-                env->vfp.regs[i] = u.d;
-            }
-        }
-    }
+static bool m_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
 
-    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
-        for (i = 0; i < 16; i++) {
-            env->iwmmxt.regs[i] = qemu_get_be64(f);
-        }
-        for (i = 0; i < 16; i++) {
-            env->iwmmxt.cregs[i] = qemu_get_be32(f);
-        }
-    }
+    return arm_feature(env, ARM_FEATURE_M);
+}
 
-    if (arm_feature(env, ARM_FEATURE_M)) {
-        env->v7m.other_sp = qemu_get_be32(f);
-        env->v7m.vecbase = qemu_get_be32(f);
-        env->v7m.basepri = qemu_get_be32(f);
-        env->v7m.control = qemu_get_be32(f);
-        env->v7m.current_sp = qemu_get_be32(f);
-        env->v7m.exception = qemu_get_be32(f);
-    }
+const VMStateDescription vmstate_m = {
+    .name = "cpu/m",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(env.v7m.other_sp, ARMCPU),
+        VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
+        VMSTATE_UINT32(env.v7m.basepri, ARMCPU),
+        VMSTATE_UINT32(env.v7m.control, ARMCPU),
+        VMSTATE_INT32(env.v7m.current_sp, ARMCPU),
+        VMSTATE_INT32(env.v7m.exception, ARMCPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static bool thumb2ee_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    return arm_feature(env, ARM_FEATURE_THUMB2EE);
+}
 
-    if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
-        env->teecr = qemu_get_be32(f);
-        env->teehbr = qemu_get_be32(f);
+static const VMStateDescription vmstate_thumb2ee = {
+    .name = "cpu/thumb2ee",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(env.teecr, ARMCPU),
+        VMSTATE_UINT32(env.teehbr, ARMCPU),
+        VMSTATE_END_OF_LIST()
     }
+};
 
+static int get_cpsr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+    uint32_t val = qemu_get_be32(f);
+
+    /* Avoid mode switch when restoring CPSR */
+    env->uncached_cpsr = val & CPSR_M;
+    cpsr_write(env, val, 0xffffffff);
     return 0;
 }
+
+static void put_cpsr(QEMUFile *f, void *opaque, size_t size)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    qemu_put_be32(f, cpsr_read(env));
+}
+
+static const VMStateInfo vmstate_cpsr = {
+    .name = "cpsr",
+    .get = get_cpsr,
+    .put = put_cpsr,
+};
+
+const VMStateDescription vmstate_arm_cpu = {
+    .name = "cpu",
+    .version_id = 11,
+    .minimum_version_id = 11,
+    .minimum_version_id_old = 11,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16),
+        {
+            .name = "cpsr",
+            .version_id = 0,
+            .size = sizeof(uint32_t),
+            .info = &vmstate_cpsr,
+            .flags = VMS_SINGLE,
+            .offset = 0,
+        },
+        VMSTATE_UINT32(env.spsr, ARMCPU),
+        VMSTATE_UINT32_ARRAY(env.banked_spsr, ARMCPU, 6),
+        VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 6),
+        VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 6),
+        VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5),
+        VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5),
+        VMSTATE_UINT32(env.cp15.c0_cpuid, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c0_cssel, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_sys, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_coproc, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_xscaleauxcr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c1_scr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base0, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base0_hi, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base1, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base1_hi, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_control, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_mask, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_base_mask, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_data, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c2_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c3, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c5_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c5_data, ARMCPU),
+        VMSTATE_UINT32_ARRAY(env.cp15.c6_region, ARMCPU, 8),
+        VMSTATE_UINT32(env.cp15.c6_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c6_data, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c7_par, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c7_par_hi, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_insn, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_data, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmcr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmcnten, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmovsr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmxevtyper, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pmuserenr, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c9_pminten, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_fcse, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_context, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_tls1, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_tls2, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c13_tls3, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_cpar, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_ticonfig, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_i_max, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_i_min, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_threadid, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_power_control, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_diagnostic, ARMCPU),
+        VMSTATE_UINT32(env.cp15.c15_power_diagnostic, ARMCPU),
+        VMSTATE_UINT32(env.exclusive_addr, ARMCPU),
+        VMSTATE_UINT32(env.exclusive_val, ARMCPU),
+        VMSTATE_UINT32(env.exclusive_high, ARMCPU),
+        VMSTATE_UINT64(env.features, ARMCPU),
+        VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection[]) {
+        {
+            .vmsd = &vmstate_vfp,
+            .needed = vfp_needed,
+        } , {
+            .vmsd = &vmstate_iwmmxt,
+            .needed = iwmmxt_needed,
+        } , {
+            .vmsd = &vmstate_m,
+            .needed = m_needed,
+        } , {
+            .vmsd = &vmstate_thumb2ee,
+            .needed = thumb2ee_needed,
+        } , {
+            /* empty */
+        }
+    }
+};
index 35a21be931c85e4df04813ca87a2fa55cf8b6ffa..a1b7b8c1a8fc07d68b4413d9076839c6d8fc7765 100644 (file)
@@ -6762,6 +6762,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
             }
             ARCH(6);
             gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
+            return;
         } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
             /* rfe */
             int32_t offset;
index cf1b05c28c5dbdba30daf3202ac5af95b69c3e71..a1614e8e50bad6bec98c7418ebd0cf2ee43d6aa6 100644 (file)
@@ -803,6 +803,7 @@ typedef struct CPUX86State {
 #endif
     uint64_t system_time_msr;
     uint64_t wall_clock_msr;
+    uint64_t steal_time_msr;
     uint64_t async_pf_en_msr;
     uint64_t pv_eoi_en_msr;
 
index 397afebecbb3dd9ac3b44c7a4702b83ba3df4c91..0e7cc8113f6e2b13aff32c336caba6c685f1b0b3 100644 (file)
@@ -68,6 +68,7 @@ static bool has_msr_tsc_deadline;
 static bool has_msr_async_pf_en;
 static bool has_msr_pv_eoi_en;
 static bool has_msr_misc_enable;
+static bool has_msr_kvm_steal_time;
 static int lm_capable_kernel;
 
 bool kvm_allows_irq0_override(void)
@@ -507,6 +508,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
     has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI);
 
+    has_msr_kvm_steal_time = c->eax & (1 << KVM_FEATURE_STEAL_TIME);
+
     cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
 
     for (i = 0; i <= limit; i++) {
@@ -1107,6 +1110,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
             kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN,
                               env->pv_eoi_en_msr);
         }
+        if (has_msr_kvm_steal_time) {
+            kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
+                              env->steal_time_msr);
+        }
         if (hyperv_hypercall_available()) {
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
@@ -1360,6 +1367,9 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (has_msr_pv_eoi_en) {
         msrs[n++].index = MSR_KVM_PV_EOI_EN;
     }
+    if (has_msr_kvm_steal_time) {
+        msrs[n++].index = MSR_KVM_STEAL_TIME;
+    }
 
     if (env->mcg_cap) {
         msrs[n++].index = MSR_MCG_STATUS;
@@ -1445,6 +1455,9 @@ static int kvm_get_msrs(X86CPU *cpu)
         case MSR_KVM_PV_EOI_EN:
             env->pv_eoi_en_msr = msrs[i].data;
             break;
+        case MSR_KVM_STEAL_TIME:
+            env->steal_time_msr = msrs[i].data;
+            break;
         }
     }
 
index ee85e574354b712d9ab295167e536af63076b5a2..3659db9e94431ae5c7aa428a121fb245eb3886ab 100644 (file)
@@ -292,6 +292,24 @@ static bool pv_eoi_msr_needed(void *opaque)
     return cpu->env.pv_eoi_en_msr != 0;
 }
 
+static bool steal_time_msr_needed(void *opaque)
+{
+    CPUX86State *cpu = opaque;
+
+    return cpu->steal_time_msr != 0;
+}
+
+static const VMStateDescription vmstate_steal_time_msr = {
+    .name = "cpu/steal_time_msr",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT64(steal_time_msr, CPUX86State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_async_pf_msr = {
     .name = "cpu/async_pf_msr",
     .version_id = 1,
@@ -502,6 +520,9 @@ const VMStateDescription vmstate_x86_cpu = {
         } , {
             .vmsd = &vmstate_pv_eoi_msr,
             .needed = pv_eoi_msr_needed,
+        } , {
+            .vmsd = &vmstate_steal_time_msr,
+            .needed = steal_time_msr_needed,
         } , {
             .vmsd = &vmstate_fpop_ip_dp,
             .needed = fpop_ip_dp_needed,