aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2009-12-03 14:30:07 +0200
committerAvi Kivity <avi@redhat.com>2009-12-03 14:30:07 +0200
commit60b28da0dbc522aa0e892fd02e9af425d0713d4f (patch)
tree0c760fff969c2d4ae462d40569068321b1fc5d06
parentfafd46eff229834a15496051acb8880848fcd8eb (diff)
parent35bfc7324e2e6946c4113ada5db30553a1a7c40b (diff)
Merge commit 'v0.11.1' into stable-0.11qemu-kvm-0.11.1stable-0.11
* commit 'v0.11.1': Update version and changelog for 0.11.1 release fix I2C slave addressing Revert "vga: do not resize the screen on hw_invalidate" slirp: fix use-after-free Fix sparc.ld ELF codedump build failures kvm: Move KVM mp_state accessors to i386-specific code this patch fixes a typo where armv4l was incorrectly spelled arm4l, net: disable draining tap queue in one go pcnet: Restart poll timer on pcnet_start Sparc32: Fix lance mac99: fix segmentation fault on startup usb-linux.c: fix buffer overflow ARM host: fix generated blocks linking qemu serial: lost tx irqs (affecting FreeBSD's new uart(4) driver) exec-all.h: increase MAX_OP_PER_INSTR to 96 from 64 Conflicts: net.c Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--Changelog17
-rw-r--r--VERSION2
-rwxr-xr-xconfigure2
-rw-r--r--exec-all.h6
-rw-r--r--hw/i2c.c6
-rw-r--r--hw/pcnet.c1
-rw-r--r--hw/serial.c10
-rw-r--r--hw/sun4m.c1
-rw-r--r--hw/unin_pci.c2
-rw-r--r--hw/vga.c6
-rw-r--r--hw/vga_int.h1
-rw-r--r--kvm-all.c20
-rw-r--r--kvm.h3
-rw-r--r--linux-user/elfload.c59
-rw-r--r--net.c29
-rw-r--r--slirp/mbuf.c2
-rw-r--r--sparc.ld20
-rw-r--r--target-i386/kvm.c20
-rw-r--r--usb-linux.c12
19 files changed, 131 insertions, 88 deletions
diff --git a/Changelog b/Changelog
index 857cbb27e..2d594cdc9 100644
--- a/Changelog
+++ b/Changelog
@@ -1,3 +1,20 @@
+Version 0.11.1
+ - fix I2C slave addressing (Juha Riihimäki)
+ - Revert "vga: do not resize the screen on hw_invalidate" (Aurelien Jarno)
+ - slirp: fix use-after-free (Mark McLoughlin)
+ - Fix sparc.ld (Blue Swirl)
+ - ELF codedump build failures (Laurent Desnogues)
+ - kvm: Move KVM mp_state accessors to i386-specific code (Hollis Blanchard)
+ - fix configure script with armv4l cpu (Laurent Desnogues)
+ - net: disable draining tap queue in one go (Mark McLoughlin)
+ - pcnet: Restart poll timer on pcnet_start (Jan Kiszka)
+ - Sparc32: Fix lance (Blue Swirl)
+ - mac99: fix segmentation fault on startup (Aurelien Jarno)
+ - usb-linux.c: fix buffer overflow (Jim Paris)
+ - ARM host: fix generated blocks linking (Laurent Desnogues)
+ - qemu serial: lost tx irqs (affecting FreeBSD's new uart(4) driver (Juergen Lock)
+ - exec-all.h: increase MAX_OP_PER_INSTR to 96 from 64 (Aurelien Jarno)
+
version 0.11.0
- fix rtc polling mode (Bernhard Kauer)
- qcow2: order concurrent aio requests (Kevin Wolf)
diff --git a/VERSION b/VERSION
index d9df1bbc0..af88ba824 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.11.0
+0.11.1
diff --git a/configure b/configure
index 02afe65cd..35ce2e1e4 100755
--- a/configure
+++ b/configure
@@ -1638,7 +1638,7 @@ case "$cpu" in
i386|x86_64|alpha|cris|hppa|ia64|m68k|microbaze|mips|mips64|ppc|ppc64|s390|sparc|sparc64)
ARCH=$cpu
;;
- armv4b|arm4l)
+ armv4b|armv4l)
ARCH=arm
;;
*)
diff --git a/exec-all.h b/exec-all.h
index 31ab7ad93..6439e3cc7 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -34,7 +34,7 @@
typedef struct TranslationBlock TranslationBlock;
/* XXX: make safe guess about sizes */
-#define MAX_OP_PER_INSTR 64
+#define MAX_OP_PER_INSTR 96
/* A Call op needs up to 6 + 2N parameters (N = number of arguments). */
#define MAX_OPC_PARAM 10
#define OPC_BUF_SIZE 512
@@ -211,7 +211,9 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr
#endif
/* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
- *(uint32_t *)jmp_addr |= ((addr - (jmp_addr + 8)) >> 2) & 0xffffff;
+ *(uint32_t *)jmp_addr =
+ (*(uint32_t *)jmp_addr & ~0xffffff)
+ | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff);
#if QEMU_GNUC_PREREQ(4, 1)
__clear_cache((char *) jmp_addr, (char *) jmp_addr + 4);
diff --git a/hw/i2c.c b/hw/i2c.c
index 42a5d7a6b..16e511215 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -81,9 +81,11 @@ int i2c_start_transfer(i2c_bus *bus, int address, int recv)
i2c_slave *slave = NULL;
LIST_FOREACH(qdev, &bus->qbus.children, sibling) {
- slave = I2C_SLAVE_FROM_QDEV(qdev);
- if (slave->address == address)
+ i2c_slave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
+ if (candidate->address == address) {
+ slave = candidate;
break;
+ }
}
if (!slave)
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 22ab6beaf..008b71a53 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -936,6 +936,7 @@ static void pcnet_start(PCNetState *s)
s->csr[0] &= ~0x0004; /* clear STOP bit */
s->csr[0] |= 0x0002;
+ pcnet_poll_timer(s);
}
static void pcnet_stop(PCNetState *s)
diff --git a/hw/serial.c b/hw/serial.c
index d70504bb0..498f4a0a1 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -195,12 +195,10 @@ static void serial_update_irq(SerialState *s)
* this is not in the specification but is observed on existing
* hardware. */
tmp_iir = UART_IIR_CTI;
- } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) {
- if (!(s->fcr & UART_FCR_FE)) {
- tmp_iir = UART_IIR_RDI;
- } else if (s->recv_fifo.count >= s->recv_fifo.itl) {
- tmp_iir = UART_IIR_RDI;
- }
+ } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR) &&
+ (!(s->fcr & UART_FCR_FE) ||
+ s->recv_fifo.count >= s->recv_fifo.itl)) {
+ tmp_iir = UART_IIR_RDI;
} else if ((s->ier & UART_IER_THRI) && s->thr_ipending) {
tmp_iir = UART_IIR_THRI;
} else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) {
diff --git a/hw/sun4m.c b/hw/sun4m.c
index c810b3598..f39059588 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -374,6 +374,7 @@ static void lance_init(NICInfo *nd, target_phys_addr_t leaddr,
dev = qdev_create(NULL, "lance");
dev->nd = nd;
+ qdev_prop_set_ptr(dev, "dma", dma_opaque);
qdev_init(dev);
s = sysbus_from_qdev(dev);
sysbus_mmio_map(s, 0, leaddr);
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 0ad0cd391..ca8d9a5c0 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -234,7 +234,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic)
cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
d = pci_register_device(s->bus, "Uni-north AGP", sizeof(PCIDevice),
- 11 << 3, NULL, NULL);
+ 12 << 3, NULL, NULL);
pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP);
d->config[0x08] = 0x00; // revision
diff --git a/hw/vga.c b/hw/vga.c
index ec7a7c3a5..31bf36986 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1844,8 +1844,7 @@ static void vga_update_display(void *opaque)
if (ds_get_bits_per_pixel(s->ds) == 0) {
/* nothing to do */
} else {
- full_update = s->full_update;
- s->full_update = 0;
+ full_update = 0;
if (!(s->ar_index & 0x20)) {
graphic_mode = GMODE_BLANK;
} else {
@@ -1878,7 +1877,8 @@ static void vga_invalidate_display(void *opaque)
{
VGAState *s = (VGAState *)opaque;
- s->full_update = 1;
+ s->last_width = -1;
+ s->last_height = -1;
}
void vga_reset(void *opaque)
diff --git a/hw/vga_int.h b/hw/vga_int.h
index be174f3f3..1aaf5c547 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -158,7 +158,6 @@ typedef struct VGACommonState {
uint32_t last_width, last_height; /* in chars or pixels */
uint32_t last_scr_width, last_scr_height; /* in pixels */
uint32_t last_depth; /* in bits */
- uint8_t full_update;
uint8_t cursor_start, cursor_end;
uint32_t cursor_offset;
unsigned int (*rgb_to_pixel)(unsigned int r,
diff --git a/kvm-all.c b/kvm-all.c
index b4b5a35f4..5d9d0b6ef 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -194,26 +194,6 @@ err:
return ret;
}
-int kvm_put_mp_state(CPUState *env)
-{
- struct kvm_mp_state mp_state = { .mp_state = env->mp_state };
-
- return kvm_vcpu_ioctl(env, KVM_SET_MP_STATE, &mp_state);
-}
-
-int kvm_get_mp_state(CPUState *env)
-{
- struct kvm_mp_state mp_state;
- int ret;
-
- ret = kvm_vcpu_ioctl(env, KVM_GET_MP_STATE, &mp_state);
- if (ret < 0) {
- return ret;
- }
- env->mp_state = mp_state.mp_state;
- return 0;
-}
-
/*
* dirty pages logging control
*/
diff --git a/kvm.h b/kvm.h
index 0191752b3..c4f21ec31 100644
--- a/kvm.h
+++ b/kvm.h
@@ -74,9 +74,6 @@ int kvm_vm_ioctl(KVMState *s, int type, ...);
int kvm_vcpu_ioctl(CPUState *env, int type, ...);
-int kvm_get_mp_state(CPUState *env);
-int kvm_put_mp_state(CPUState *env);
-
/* Arch specific hooks */
int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 3a8268b78..dbadc51ec 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -134,13 +134,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
regs->rip = infop->entry;
}
-typedef target_ulong elf_greg_t;
+typedef target_ulong target_elf_greg_t;
typedef uint32_t target_uid_t;
typedef uint32_t target_gid_t;
typedef int32_t target_pid_t;
#define ELF_NREG 27
-typedef elf_greg_t elf_gregset_t[ELF_NREG];
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
/*
* Note that ELF_NREG should be 29 as there should be place for
@@ -149,7 +149,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NREG];
*
* See linux kernel: arch/x86/include/asm/elf.h
*/
-static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
{
(*regs)[0] = env->regs[15];
(*regs)[1] = env->regs[14];
@@ -211,13 +211,13 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
regs->edx = 0;
}
-typedef target_ulong elf_greg_t;
+typedef target_ulong target_elf_greg_t;
typedef uint16_t target_uid_t;
typedef uint16_t target_gid_t;
typedef int32_t target_pid_t;
#define ELF_NREG 17
-typedef elf_greg_t elf_gregset_t[ELF_NREG];
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
/*
* Note that ELF_NREG should be 19 as there should be place for
@@ -226,7 +226,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NREG];
*
* See linux kernel: arch/x86/include/asm/elf.h
*/
-static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
{
(*regs)[0] = env->regs[R_EBX];
(*regs)[1] = env->regs[R_ECX];
@@ -286,15 +286,15 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
regs->ARM_r10 = infop->start_data;
}
-typedef uint32_t elf_greg_t;
+typedef uint32_t target_elf_greg_t;
typedef uint16_t target_uid_t;
typedef uint16_t target_gid_t;
typedef int32_t target_pid_t;
#define ELF_NREG 18
-typedef elf_greg_t elf_gregset_t[ELF_NREG];
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
-static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env)
+static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUState *env)
{
(*regs)[0] = env->regs[0];
(*regs)[1] = env->regs[1];
@@ -1725,7 +1725,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
/*
* Definitions to generate Intel SVR4-like core files.
- * These mostly have the same names as the SVR4 types with "elf_"
+ * These mostly have the same names as the SVR4 types with "target_elf_"
* tacked on the front to prevent clashes with linux definitions,
* and the typedef forms have been avoided. This is mostly like
* the SVR4 structure, but more Linuxy, with things that Linux does
@@ -1745,9 +1745,9 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
* Next you define type of register set used for dumping. ELF specification
* says that it needs to be array of elf_greg_t that has size of ELF_NREG.
*
- * typedef <target_regtype> elf_greg_t;
+ * typedef <target_regtype> target_elf_greg_t;
* #define ELF_NREG <number of registers>
- * typedef elf_greg_t elf_gregset_t[ELF_NREG];
+ * typedef taret_elf_greg_t target_elf_gregset_t[ELF_NREG];
*
* Then define following types to match target types. Actual types can
* be found from linux kernel (arch/<ARCH>/include/asm/posix_types.h):
@@ -1759,7 +1759,8 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
* Last step is to implement target specific function that copies registers
* from given cpu into just specified register set. Prototype is:
*
- * static void elf_core_copy_regs(elf_gregset_t *regs, const CPUState *env);
+ * static void elf_core_copy_regs(taret_elf_gregset_t *regs,
+ * const CPUState *env);
*
* Parameters:
* regs - copy register values into here (allocated and zeroed by caller)
@@ -1779,14 +1780,14 @@ struct memelfnote {
size_t notesz;
};
-struct elf_siginfo {
+struct target_elf_siginfo {
int si_signo; /* signal number */
int si_code; /* extra code */
int si_errno; /* errno */
};
-struct elf_prstatus {
- struct elf_siginfo pr_info; /* Info associated with signal */
+struct target_elf_prstatus {
+ struct target_elf_siginfo pr_info; /* Info associated with signal */
short pr_cursig; /* Current signal */
target_ulong pr_sigpend; /* XXX */
target_ulong pr_sighold; /* XXX */
@@ -1798,13 +1799,13 @@ struct elf_prstatus {
struct target_timeval pr_stime; /* XXX System time */
struct target_timeval pr_cutime; /* XXX Cumulative user time */
struct target_timeval pr_cstime; /* XXX Cumulative system time */
- elf_gregset_t pr_reg; /* GP registers */
+ target_elf_gregset_t pr_reg; /* GP registers */
int pr_fpvalid; /* XXX */
};
#define ELF_PRARGSZ (80) /* Number of chars for args */
-struct elf_prpsinfo {
+struct target_elf_prpsinfo {
char pr_state; /* numeric process state */
char pr_sname; /* char for pr_state */
char pr_zomb; /* zombie */
@@ -1821,7 +1822,7 @@ struct elf_prpsinfo {
/* Here is the structure in which status of each thread is captured. */
struct elf_thread_status {
TAILQ_ENTRY(elf_thread_status) ets_link;
- struct elf_prstatus prstatus; /* NT_PRSTATUS */
+ struct target_elf_prstatus prstatus; /* NT_PRSTATUS */
#if 0
elf_fpregset_t fpu; /* NT_PRFPREG */
struct task_struct *thread;
@@ -1833,8 +1834,8 @@ struct elf_thread_status {
struct elf_note_info {
struct memelfnote *notes;
- struct elf_prstatus *prstatus; /* NT_PRSTATUS */
- struct elf_prpsinfo *psinfo; /* NT_PRPSINFO */
+ struct target_elf_prstatus *prstatus; /* NT_PRSTATUS */
+ struct target_elf_prpsinfo *psinfo; /* NT_PRPSINFO */
TAILQ_HEAD(thread_list_head, elf_thread_status) thread_list;
#if 0
@@ -1876,8 +1877,8 @@ static int vma_walker(void *priv, unsigned long start, unsigned long end,
static void fill_elf_header(struct elfhdr *, int, uint16_t, uint32_t);
static void fill_note(struct memelfnote *, const char *, int,
unsigned int, void *);
-static void fill_prstatus(struct elf_prstatus *, const TaskState *, int);
-static int fill_psinfo(struct elf_prpsinfo *, const TaskState *);
+static void fill_prstatus(struct target_elf_prstatus *, const TaskState *, int);
+static int fill_psinfo(struct target_elf_prpsinfo *, const TaskState *);
static void fill_auxv_note(struct memelfnote *, const TaskState *);
static void fill_elf_note_phdr(struct elf_phdr *, int, off_t);
static size_t note_size(const struct memelfnote *);
@@ -1891,10 +1892,10 @@ static int write_note(struct memelfnote *, int);
static int write_note_info(struct elf_note_info *, int);
#ifdef BSWAP_NEEDED
-static void bswap_prstatus(struct elf_prstatus *);
-static void bswap_psinfo(struct elf_prpsinfo *);
+static void bswap_prstatus(struct target_elf_prstatus *);
+static void bswap_psinfo(struct target_elf_prpsinfo *);
-static void bswap_prstatus(struct elf_prstatus *prstatus)
+static void bswap_prstatus(struct target_elf_prstatus *prstatus)
{
prstatus->pr_info.si_signo = tswapl(prstatus->pr_info.si_signo);
prstatus->pr_info.si_code = tswapl(prstatus->pr_info.si_code);
@@ -1911,7 +1912,7 @@ static void bswap_prstatus(struct elf_prstatus *prstatus)
prstatus->pr_fpvalid = tswap32(prstatus->pr_fpvalid);
}
-static void bswap_psinfo(struct elf_prpsinfo *psinfo)
+static void bswap_psinfo(struct target_elf_prpsinfo *psinfo)
{
psinfo->pr_flag = tswapl(psinfo->pr_flag);
psinfo->pr_uid = tswap16(psinfo->pr_uid);
@@ -2105,7 +2106,7 @@ static size_t note_size(const struct memelfnote *note)
return (note->notesz);
}
-static void fill_prstatus(struct elf_prstatus *prstatus,
+static void fill_prstatus(struct target_elf_prstatus *prstatus,
const TaskState *ts, int signr)
{
(void) memset(prstatus, 0, sizeof (*prstatus));
@@ -2120,7 +2121,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
#endif
}
-static int fill_psinfo(struct elf_prpsinfo *psinfo, const TaskState *ts)
+static int fill_psinfo(struct target_elf_prpsinfo *psinfo, const TaskState *ts)
{
char *filename, *base_filename;
unsigned int i, len;
diff --git a/net.c b/net.c
index a1c111140..effd9a25e 100644
--- a/net.c
+++ b/net.c
@@ -1453,27 +1453,24 @@ static void tap_send(void *opaque)
{
TAPState *s = opaque;
int size;
+ uint8_t *buf = s->buf;
- do {
- uint8_t *buf = s->buf;
-
- size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
- if (size <= 0) {
- break;
- }
+ size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
+ if (size <= 0) {
+ return;
+ }
#ifdef IFF_VNET_HDR
- if (s->has_vnet_hdr && !s->using_vnet_hdr) {
- buf += sizeof(struct virtio_net_hdr);
- size -= sizeof(struct virtio_net_hdr);
- }
+ if (s->has_vnet_hdr && !s->using_vnet_hdr) {
+ buf += sizeof(struct virtio_net_hdr);
+ size -= sizeof(struct virtio_net_hdr);
+ }
#endif
- size = qemu_send_packet_async(s->vc, buf, size, tap_send_completed);
- if (size == 0) {
- tap_read_poll(s, 0);
- }
- } while (size > 0);
+ size = qemu_send_packet_async(s->vc, buf, size, tap_send_completed);
+ if (size == 0) {
+ tap_read_poll(s, 0);
+ }
}
#ifdef TUNSETSNDBUF
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 7652fea19..87508ba01 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -95,8 +95,8 @@ m_free(struct mbuf *m)
* Either free() it or put it on the free list
*/
if (m->m_flags & M_DOFREE) {
- free(m);
m->slirp->mbuf_alloced--;
+ free(m);
} else if ((m->m_flags & M_FREELIST) == 0) {
insque(m,&m->slirp->m_freelist);
m->m_flags = M_FREELIST; /* Clobber other flags */
diff --git a/sparc.ld b/sparc.ld
index 26ab4151f..9d2363664 100644
--- a/sparc.ld
+++ b/sparc.ld
@@ -66,6 +66,26 @@ SECTIONS
.data1 : { *(.data1) }
.tdata : { *(.tdata) }
.tbss : { *(.tbss) }
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ }
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ }
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ }
.ctors :
{
*(.ctors)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index cfa5b80d5..6037b20f3 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -665,6 +665,26 @@ static int kvm_get_msrs(CPUState *env)
return 0;
}
+static int kvm_put_mp_state(CPUState *env)
+{
+ struct kvm_mp_state mp_state = { .mp_state = env->mp_state };
+
+ return kvm_vcpu_ioctl(env, KVM_SET_MP_STATE, &mp_state);
+}
+
+static int kvm_get_mp_state(CPUState *env)
+{
+ struct kvm_mp_state mp_state;
+ int ret;
+
+ ret = kvm_vcpu_ioctl(env, KVM_GET_MP_STATE, &mp_state);
+ if (ret < 0) {
+ return ret;
+ }
+ env->mp_state = mp_state.mp_state;
+ return 0;
+}
+
int kvm_arch_put_registers(CPUState *env)
{
int ret;
diff --git a/usb-linux.c b/usb-linux.c
index 043f6b6ba..eb1c5f071 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -115,7 +115,7 @@ struct ctrl_struct {
uint16_t offset;
uint8_t state;
struct usb_ctrlrequest req;
- uint8_t buffer[1024];
+ uint8_t buffer[2048];
};
typedef struct USBHostDevice {
@@ -552,6 +552,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
struct usbdevfs_urb *urb;
AsyncURB *aurb;
int ret, value, index;
+ int buffer_len;
/*
* Process certain standard device requests.
@@ -580,6 +581,13 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
/* The rest are asynchronous */
+ buffer_len = 8 + s->ctrl.len;
+ if (buffer_len > sizeof(s->ctrl.buffer)) {
+ fprintf(stderr, "husb: ctrl buffer too small (%u > %lu)\n",
+ buffer_len, sizeof(s->ctrl.buffer));
+ return USB_RET_STALL;
+ }
+
aurb = async_alloc();
aurb->hdev = s;
aurb->packet = p;
@@ -596,7 +604,7 @@ static int usb_host_handle_control(USBHostDevice *s, USBPacket *p)
urb->endpoint = p->devep;
urb->buffer = &s->ctrl.req;
- urb->buffer_length = 8 + s->ctrl.len;
+ urb->buffer_length = buffer_len;
urb->usercontext = s;