* qemu-char fixes

* SCSI fixes (including CVE-2015-5158)
 * RCU fixes
 * Framebuffer logic to set DIRTY_MEMORY_VGA
 * Fix compiler warning for --disable-vnc
 * qemu-doc fixes
 * x86 TCG pasto fix
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQEcBAABCAAGBQJVsihAAAoJEL/70l94x66DXccIAJqoO5t7b8nA3W1gkJBJxgUy
 OPAEP7N+v1qZNtYtbmC0p29JaaMPiauNnOQGYQ/hRj3Ccv3bcWg4gbhlxHdjZT5e
 fh5aYxZr4K0D8dWbnFhGuvATiaiddfwRB3YCDx2CW1DPgL2xwzdwmYNXPvpnA2hj
 3LDqC74v3lppCRpKPa4//xvpkwz0SJrJjbxvKBPRdVSAi8ovRJF27ArM2bVXYpYS
 uWhXxhqw0Sx6nqZoz+EpfRsHHirGtsj8iGxGgRre3kqFTLYmjtg0wSBrSvCU3Eaw
 1kmceS7ggJq82mIOFnjYE1Sf+JPOySSieHdKEPDEWezsQkBzBsQ9KaSQJnmLCa8=
 =0FIR
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging

* qemu-char fixes
* SCSI fixes (including CVE-2015-5158)
* RCU fixes
* Framebuffer logic to set DIRTY_MEMORY_VGA
* Fix compiler warning for --disable-vnc
* qemu-doc fixes
* x86 TCG pasto fix

# gpg: Signature made Fri Jul 24 12:57:52 2015 BST using RSA key ID 78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini/tags/for-upstream:
  target-i386/FPU: a misprint in helper_fistll_ST0
  qemu-doc: fix typos
  framebuffer: set DIRTY_MEMORY_VGA on RAM that is used for the framebuffer
  memory: count number of active VGA logging clients
  vl: Fix compiler warning for builds without VNC
  scsi: Handle no media case for scsi_get_configuration
  rcu: actually register threads that have RCU read-side critical sections
  scsi: fix buffer overflow in scsi_req_parse_cdb (CVE-2015-5158)
  vnc: fix memory leak
  qemu-char: Fix missed data on unix socket
  qemu-char: handle EINTR for TCP character devices
  exec.c: Use atomic_rcu_read() to access dispatch in memory_region_section_get_iotlb()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-07-24 13:07:10 +01:00
commit f793d97e45
23 changed files with 216 additions and 70 deletions

6
cpus.c
View File

@ -954,6 +954,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
CPUState *cpu = arg;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
@ -995,6 +997,8 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
sigset_t waitset;
int r;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_thread_get_self(cpu->thread);
cpu->thread_id = qemu_get_thread_id();
@ -1034,6 +1038,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
rcu_register_thread();
qemu_mutex_lock_iothread();
qemu_tcg_init_cpu_signals();
qemu_thread_get_self(cpu->thread);

5
exec.c
View File

@ -954,7 +954,10 @@ hwaddr memory_region_section_get_iotlb(CPUState *cpu,
iotlb |= PHYS_SECTION_ROM;
}
} else {
iotlb = section - section->address_space->dispatch->map.sections;
AddressSpaceDispatch *d;
d = atomic_rcu_read(&section->address_space->dispatch);
iotlb = section - d->map.sections;
iotlb += xlat;
}

View File

@ -21,12 +21,40 @@
#include "ui/console.h"
#include "framebuffer.h"
void framebuffer_update_memory_section(
MemoryRegionSection *mem_section,
MemoryRegion *root,
hwaddr base,
unsigned rows,
unsigned src_width)
{
hwaddr src_len = (hwaddr)rows * src_width;
if (mem_section->mr) {
memory_region_set_log(mem_section->mr, false, DIRTY_MEMORY_VGA);
memory_region_unref(mem_section->mr);
mem_section->mr = NULL;
}
*mem_section = memory_region_find(root, base, src_len);
if (!mem_section->mr) {
return;
}
if (int128_get64(mem_section->size) < src_len ||
!memory_region_is_ram(mem_section->mr)) {
memory_region_unref(mem_section->mr);
mem_section->mr = NULL;
return;
}
memory_region_set_log(mem_section->mr, true, DIRTY_MEMORY_VGA);
}
/* Render an image from a shared memory framebuffer. */
void framebuffer_update_display(
DisplaySurface *ds,
MemoryRegion *address_space,
hwaddr base,
MemoryRegionSection *mem_section,
int cols, /* Width in pixels. */
int rows, /* Height in pixels. */
int src_width, /* Length of source line, in bytes. */
@ -41,51 +69,33 @@ void framebuffer_update_display(
hwaddr src_len;
uint8_t *dest;
uint8_t *src;
uint8_t *src_base;
int first, last = 0;
int dirty;
int i;
ram_addr_t addr;
MemoryRegionSection mem_section;
MemoryRegion *mem;
i = *first_row;
*first_row = -1;
src_len = src_width * rows;
mem_section = memory_region_find(address_space, base, src_len);
mem = mem_section.mr;
if (int128_get64(mem_section.size) != src_len ||
!memory_region_is_ram(mem_section.mr)) {
goto out;
mem = mem_section->mr;
if (!mem) {
return;
}
assert(mem);
assert(mem_section.offset_within_address_space == base);
memory_region_sync_dirty_bitmap(mem);
if (!memory_region_is_logging(mem, DIRTY_MEMORY_VGA)) {
invalidate = true;
}
src_base = cpu_physical_memory_map(base, &src_len, 0);
/* If we can't map the framebuffer then bail. We could try harder,
but it's not really worth it as dirty flag tracking will probably
already have failed above. */
if (!src_base)
goto out;
if (src_len != src_width * rows) {
cpu_physical_memory_unmap(src_base, src_len, 0, 0);
goto out;
}
src = src_base;
addr = mem_section->offset_within_region;
src = memory_region_get_ram_ptr(mem) + addr;
dest = surface_data(ds);
if (dest_col_pitch < 0)
if (dest_col_pitch < 0) {
dest -= dest_col_pitch * (cols - 1);
}
if (dest_row_pitch < 0) {
dest -= dest_row_pitch * (rows - 1);
}
first = -1;
addr = mem_section.offset_within_region;
addr += i * src_width;
src += i * src_width;
@ -104,14 +114,11 @@ void framebuffer_update_display(
src += src_width;
dest += dest_row_pitch;
}
cpu_physical_memory_unmap(src_base, src_len, 0, 0);
if (first < 0) {
goto out;
return;
}
memory_region_reset_dirty(mem, mem_section.offset_within_region, src_len,
memory_region_reset_dirty(mem, mem_section->offset_within_region, src_len,
DIRTY_MEMORY_VGA);
*first_row = first;
*last_row = last;
out:
memory_region_unref(mem);
}

View File

@ -7,10 +7,50 @@
typedef void (*drawfn)(void *, uint8_t *, const uint8_t *, int, int);
/* framebuffer_update_memory_section: Update framebuffer
* #MemoryRegionSection, for example if the framebuffer is switched to
* a different memory area.
*
* @mem_section: Output #MemoryRegionSection, to be passed to
* framebuffer_update_display().
* @root: #MemoryRegion within which the framebuffer lies
* @base: Base address of the framebuffer within @root.
* @rows: Height of the screen.
* @src_width: Number of bytes in framebuffer memory between two rows.
*/
void framebuffer_update_memory_section(
MemoryRegionSection *mem_section,
MemoryRegion *root,
hwaddr base,
unsigned rows,
unsigned src_width);
/* framebuffer_update_display: Draw the framebuffer on a surface.
*
* @ds: #DisplaySurface to draw to.
* @mem_section: #MemoryRegionSection provided by
* framebuffer_update_memory_section().
* @cols: Width the screen.
* @rows: Height of the screen.
* @src_width: Number of bytes in framebuffer memory between two rows.
* @dest_row_pitch: Number of bytes in the surface data between two rows.
* Negative if the framebuffer is stored in the opposite order (e.g.
* bottom-to-top) compared to the framebuffer.
* @dest_col_pitch: Number of bytes in the surface data between two pixels.
* Negative if the framebuffer is stored in the opposite order (e.g.
* right-to-left) compared to the framebuffer.
* @invalidate: True if the function should redraw the whole screen
* without checking the DIRTY_MEMORY_VGA dirty bitmap.
* @fn: Drawing function to be called for each row that has to be drawn.
* @opaque: Opaque pointer passed to @fn.
* @first_row: Pointer to an integer, receives the number of the first row
* that was drawn (either the first dirty row, or 0 if @invalidate is true).
* @last_row: Pointer to an integer, receives the number of the last row that
* was drawn (either the last dirty row, or @rows-1 if @invalidate is true).
*/
void framebuffer_update_display(
DisplaySurface *ds,
MemoryRegion *address_space,
hwaddr base,
MemoryRegionSection *mem_section,
int cols,
int rows,
int src_width,

View File

@ -71,6 +71,7 @@ struct MilkymistVgafbState {
SysBusDevice parent_obj;
MemoryRegion regs_region;
MemoryRegionSection fbsection;
QemuConsole *con;
int invalidate;
@ -91,6 +92,7 @@ static void vgafb_update_display(void *opaque)
MilkymistVgafbState *s = opaque;
SysBusDevice *sbd;
DisplaySurface *surface = qemu_console_surface(s->con);
int src_width;
int first = 0;
int last = 0;
drawfn fn;
@ -129,11 +131,18 @@ static void vgafb_update_display(void *opaque)
break;
}
framebuffer_update_display(surface, sysbus_address_space(sbd),
s->regs[R_BASEADDRESS] + s->fb_offset,
src_width = s->regs[R_HRES] * 2;
if (s->invalidate) {
framebuffer_update_memory_section(&s->fbsection,
sysbus_address_space(sbd),
s->regs[R_BASEADDRESS] + s->fb_offset,
s->regs[R_VRES], src_width);
}
framebuffer_update_display(surface, &s->fbsection,
s->regs[R_HRES],
s->regs[R_VRES],
s->regs[R_HRES] * 2,
src_width,
dest_width,
0,
s->invalidate,

View File

@ -25,6 +25,7 @@
struct omap_lcd_panel_s {
MemoryRegion *sysmem;
MemoryRegion iomem;
MemoryRegionSection fbsection;
qemu_irq irq;
QemuConsole *con;
@ -215,12 +216,19 @@ static void omap_update_display(void *opaque)
step = width * bpp >> 3;
linesize = surface_stride(surface);
framebuffer_update_display(surface, omap_lcd->sysmem,
frame_base, width, height,
if (omap_lcd->invalidate) {
framebuffer_update_memory_section(&omap_lcd->fbsection,
omap_lcd->sysmem, frame_base,
height, step);
}
framebuffer_update_display(surface, &omap_lcd->fbsection,
width, height,
step, linesize, 0,
omap_lcd->invalidate,
draw_line, omap_lcd->palette,
&first, &last);
if (first >= 0) {
dpy_gfx_update(omap_lcd->con, 0, first, width, last - first + 1);
}

View File

@ -46,6 +46,7 @@ typedef struct PL110State {
SysBusDevice parent_obj;
MemoryRegion iomem;
MemoryRegionSection fbsection;
QemuConsole *con;
int version;
@ -238,12 +239,20 @@ static void pl110_update_display(void *opaque)
}
dest_width *= s->cols;
first = 0;
framebuffer_update_display(surface, sysbus_address_space(sbd),
s->upbase, s->cols, s->rows,
if (s->invalidate) {
framebuffer_update_memory_section(&s->fbsection,
sysbus_address_space(sbd),
s->upbase,
s->rows, src_width);
}
framebuffer_update_display(surface, &s->fbsection,
s->cols, s->rows,
src_width, dest_width, 0,
s->invalidate,
fn, s->palette,
&first, &last);
if (first >= 0) {
dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1);
}

View File

@ -35,6 +35,7 @@ struct DMAChannel {
struct PXA2xxLCDState {
MemoryRegion *sysmem;
MemoryRegion iomem;
MemoryRegionSection fbsection;
qemu_irq irq;
int irqlevel;
@ -687,8 +688,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
dest_width = s->xres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, dest_width, s->dest_width,
s->invalidated,
fn, s->dma_ch[0].palette, miny, maxy);
@ -715,8 +719,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
dest_width = s->yres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, s->dest_width, -dest_width,
s->invalidated,
fn, s->dma_ch[0].palette,
@ -747,8 +754,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
dest_width = s->xres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, -dest_width, -s->dest_width,
s->invalidated,
fn, s->dma_ch[0].palette, miny, maxy);
@ -778,8 +788,11 @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
dest_width = s->yres * s->dest_width;
*miny = 0;
framebuffer_update_display(surface, s->sysmem,
addr, s->xres, s->yres,
if (s->invalidated) {
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
addr, s->yres, src_width);
}
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
src_width, -s->dest_width, dest_width,
s->invalidated,
fn, s->dma_ch[0].palette,

View File

@ -1239,10 +1239,15 @@ int scsi_cdb_length(uint8_t *buf) {
int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf)
{
int rc;
int len;
cmd->lba = -1;
cmd->len = scsi_cdb_length(buf);
len = scsi_cdb_length(buf);
if (len < 0) {
return -1;
}
cmd->len = len;
switch (dev->type) {
case TYPE_TAPE:
rc = scsi_req_stream_xfer(cmd, dev, buf);

View File

@ -765,6 +765,9 @@ static inline bool media_is_dvd(SCSIDiskState *s)
if (!blk_is_inserted(s->qdev.conf.blk)) {
return false;
}
if (s->tray_open) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
return nb_sectors > CD_MAX_SECTORS;
}
@ -778,6 +781,9 @@ static inline bool media_is_cd(SCSIDiskState *s)
if (!blk_is_inserted(s->qdev.conf.blk)) {
return false;
}
if (s->tray_open) {
return false;
}
blk_get_geometry(s->qdev.conf.blk, &nb_sectors);
return nb_sectors <= CD_MAX_SECTORS;
}
@ -975,7 +981,15 @@ static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)
if (s->qdev.type != TYPE_ROM) {
return -1;
}
current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM;
if (media_is_dvd(s)) {
current = MMC_PROFILE_DVD_ROM;
} else if (media_is_cd(s)) {
current = MMC_PROFILE_CD_ROM;
} else {
current = MMC_PROFILE_NONE;
}
memset(outbuf, 0, 40);
stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */
stw_be_p(&outbuf[6], current);

View File

@ -180,6 +180,7 @@ struct MemoryRegion {
bool warning_printed; /* For reservations */
bool flush_coalesced_mmio;
bool global_locking;
uint8_t vga_logging_count;
MemoryRegion *alias;
hwaddr alias_offset;
int32_t priority;

View File

@ -18,6 +18,7 @@
#include "sysemu/iothread.h"
#include "qmp-commands.h"
#include "qemu/error-report.h"
#include "qemu/rcu.h"
typedef ObjectClass IOThreadClass;
@ -31,6 +32,8 @@ static void *iothread_run(void *opaque)
IOThread *iothread = opaque;
bool blocking;
rcu_register_thread();
qemu_mutex_lock(&iothread->init_done_lock);
iothread->thread_id = qemu_get_thread_id();
qemu_cond_signal(&iothread->init_done_cond);
@ -45,6 +48,8 @@ static void *iothread_run(void *opaque)
}
aio_context_release(iothread->ctx);
}
rcu_unregister_thread();
return NULL;
}

View File

@ -1433,8 +1433,15 @@ void memory_region_notify_iommu(MemoryRegion *mr,
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
{
uint8_t mask = 1 << client;
uint8_t old_logging;
assert(client == DIRTY_MEMORY_VGA);
old_logging = mr->vga_logging_count;
mr->vga_logging_count += log ? 1 : -1;
if (!!old_logging == !!mr->vga_logging_count) {
return;
}
memory_region_transaction_begin();
mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask);
memory_region_update_pending |= mr->enabled;

View File

@ -22,6 +22,7 @@
#include "block/block.h"
#include "qapi/qmp/qerror.h"
#include "qemu/sockets.h"
#include "qemu/rcu.h"
#include "migration/block.h"
#include "qemu/thread.h"
#include "qmp-commands.h"
@ -917,6 +918,8 @@ static void *migration_thread(void *opaque)
int64_t start_time = initial_time;
bool old_vm_running = false;
rcu_register_thread();
qemu_savevm_state_header(s->file);
qemu_savevm_state_begin(s->file, &s->params);
@ -1016,6 +1019,7 @@ static void *migration_thread(void *opaque)
qemu_bh_schedule(s->cleanup_bh);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
}

View File

@ -807,7 +807,8 @@ static gboolean io_watch_poll_prepare(GSource *source, gint *timeout_)
}
if (now_active) {
iwp->src = g_io_create_watch(iwp->channel, G_IO_IN | G_IO_ERR | G_IO_HUP);
iwp->src = g_io_create_watch(iwp->channel,
G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
g_source_attach(iwp->src, NULL);
} else {
@ -2797,7 +2798,10 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
#ifdef MSG_CMSG_CLOEXEC
flags |= MSG_CMSG_CLOEXEC;
#endif
ret = recvmsg(s->fd, &msg, flags);
do {
ret = recvmsg(s->fd, &msg, flags);
} while (ret == -1 && errno == EINTR);
if (ret > 0 && s->is_unix) {
unix_process_msgfd(chr, &msg);
}
@ -2808,7 +2812,13 @@ static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
static ssize_t tcp_chr_recv(CharDriverState *chr, char *buf, size_t len)
{
TCPCharDriver *s = chr->opaque;
return qemu_recv(s->fd, buf, len, 0);
ssize_t ret;
do {
ret = qemu_recv(s->fd, buf, len, 0);
} while (ret == -1 && socket_error() == EINTR);
return ret;
}
#endif
@ -2847,12 +2857,6 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
uint8_t buf[READ_BUF_LEN];
int len, size;
if (cond & G_IO_HUP) {
/* connection closed */
tcp_chr_disconnect(chr);
return TRUE;
}
if (!s->connected || s->max_size <= 0) {
return TRUE;
}
@ -2860,7 +2864,9 @@ static gboolean tcp_chr_read(GIOChannel *chan, GIOCondition cond, void *opaque)
if (len > s->max_size)
len = s->max_size;
size = tcp_chr_recv(chr, (void *)buf, len);
if (size == 0) {
if (size == 0 ||
(size < 0 &&
socket_error() != EAGAIN && socket_error() != EWOULDBLOCK)) {
/* connection closed */
tcp_chr_disconnect(chr);
} else if (size > 0) {

View File

@ -1061,7 +1061,7 @@ type is assumed.
@var{server} specifies the server where the volume file specification for
the given volume resides. This can be either hostname, ipv4 address
or ipv6 address. ipv6 address needs to be within square brackets [ ].
If transport type is unix, then @var{server} field should not be specifed.
If transport type is unix, then @var{server} field should not be specified.
Instead @var{socket} field needs to be populated with the path to unix domain
socket.

View File

@ -206,7 +206,7 @@ STEXI
@item -boot [order=@var{drives}][,once=@var{drives}][,menu=on|off][,splash=@var{sp_name}][,splash-time=@var{sp_time}][,reboot-timeout=@var{rb_timeout}][,strict=on|off]
@findex -boot
Specify boot order @var{drives} as a string of drive letters. Valid
drive letters depend on the target achitecture. The x86 PC uses: a, b
drive letters depend on the target architecture. The x86 PC uses: a, b
(floppy 1 and 2), c (first hard disk), d (first CD-ROM), n-p (Etherboot
from network adapter 1-4), hard disk boot is the default. To apply a
particular boot order only on the first startup, specify it via

View File

@ -440,7 +440,7 @@ translator cannot deduce statically).
@section Direct block chaining
After each translated basic block is executed, QEMU uses the simulated
Program Counter (PC) and other cpu state informations (such as the CS
Program Counter (PC) and other cpu state information (such as the CS
segment base value) to find the next basic block.
In order to accelerate the most common cases where the new simulated PC

View File

@ -272,7 +272,7 @@ int64_t helper_fistll_ST0(CPUX86State *env)
old_exp_flags = get_float_exception_flags(&env->fp_status);
set_float_exception_flags(0, &env->fp_status);
val = floatx80_to_int32(ST0, &env->fp_status);
val = floatx80_to_int64(ST0, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) {
val = 0x8000000000000000ULL;
}

View File

@ -108,6 +108,8 @@ static void *rcu_q_reader(void *arg)
long long n_reads_local = 0;
struct list_element *el;
rcu_register_thread();
*(struct rcu_reader_data **)arg = &rcu_reader;
atomic_inc(&nthreadsrunning);
while (goflag == GOFLAG_INIT) {
@ -129,6 +131,8 @@ static void *rcu_q_reader(void *arg)
qemu_mutex_lock(&counts_mutex);
n_reads += n_reads_local;
qemu_mutex_unlock(&counts_mutex);
rcu_unregister_thread();
return NULL;
}

View File

@ -2520,7 +2520,7 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
size_t i, pwlen;
unsigned char key[8];
time_t now = time(NULL);
QCryptoCipher *cipher;
QCryptoCipher *cipher = NULL;
Error *err = NULL;
if (!vs->vd->password) {
@ -2573,6 +2573,8 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len)
start_client_init(vs);
}
qcrypto_cipher_free(cipher);
return 0;
reject:
@ -2584,6 +2586,7 @@ reject:
}
vnc_flush(vs);
vnc_client_error(vs);
qcrypto_cipher_free(cipher);
return 0;
}

View File

@ -216,6 +216,8 @@ static void *call_rcu_thread(void *opaque)
{
struct rcu_head *node;
rcu_register_thread();
for (;;) {
int tries = 0;
int n = atomic_read(&rcu_call_count);

2
vl.c
View File

@ -2061,7 +2061,6 @@ static void select_vgahw (const char *p)
static DisplayType select_display(const char *p)
{
Error *err = NULL;
const char *opts;
DisplayType display = DT_DEFAULT;
@ -2130,6 +2129,7 @@ static DisplayType select_display(const char *p)
} else if (strstart(p, "vnc", &opts)) {
#ifdef CONFIG_VNC
if (*opts == '=') {
Error *err = NULL;
if (vnc_parse(opts + 1, &err) == NULL) {
error_report_err(err);
exit(1);