chardev/baum: fix baum that releases brlapi twice (bsc#1060045) #15

Closed
liayan wants to merge 37 commits from opensuse-2.10 into opensuse-2.10
35 changed files with 662 additions and 56 deletions

View File

@@ -970,6 +970,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
S: Supported
F: include/hw/scsi/*
F: hw/scsi/*
F: tests/scsi-disk-test.c
F: tests/virtio-scsi-test.c
T: git git://github.com/bonzini/qemu.git scsi-next
@@ -1439,6 +1440,7 @@ F: qom/
X: qom/cpu.c
F: tests/check-qom-interface.c
F: tests/check-qom-proplist.c
F: tests/check-qom-props.c
F: tests/qom-test.c
QMP

View File

@@ -36,6 +36,10 @@ endif
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
STPFILES=
ifdef CONFIG_LINUX_USER
PROGS+=$(QEMU_PROG)-binfmt
endif
config-target.h: config-target.h-timestamp
config-target.h-timestamp: config-target.mak
@@ -121,6 +125,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \
obj-y += linux-user/
obj-y += gdbstub.o thunk.o user-exec.o user-exec-stub.o
obj-binfmt-y += linux-user/
endif #CONFIG_LINUX_USER
#########################################################
@@ -162,7 +168,11 @@ endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure.
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
ifdef CONFIG_LINUX_USER
dummy := $(call unnest-vars,,obj-y obj-binfmt-y)
else
dummy := $(call unnest-vars,,obj-y)
endif
all-obj-y := $(obj-y)
target-obj-y :=
@@ -203,6 +213,9 @@ ifdef CONFIG_DARWIN
$(call quiet-command,SetFile -a C $@,"SETFILE","$(TARGET_DIR)$@")
endif
$(QEMU_PROG)-binfmt: $(obj-binfmt-y)
$(call LINK,$^)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES),"GEN","$(TARGET_DIR)$@")

View File

@@ -643,6 +643,7 @@ static void baum_chr_open(Chardev *chr,
error_setg(errp, "brlapi__openConnection: %s",
brlapi_strerror(brlapi_error_location()));
g_free(handle);
baum->brlapi = NULL;
return;
}
baum->deferred_init = 0;

View File

@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define HW_POISON_H // avoid poison since we patch against rules it "enforces"
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qapi/error.h"

View File

@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define HW_POISON_H // avoid poison since we patch against rules it "enforces"
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
@@ -179,6 +180,15 @@ static void mux_chr_accept_input(Chardev *chr)
be->chr_read(be->opaque,
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
}
#if defined(TARGET_S390X)
/* We're still not able to sync producer and consumer, so let's wait a bit
and try again by then. */
if (d->prod[m] != d->cons[m]) {
qemu_mod_timer(d->accept_timer, qemu_get_clock_ns(vm_clock)
+ (int64_t)100000);
}
#endif
}
static int mux_chr_can_read(void *opaque)
@@ -314,6 +324,10 @@ static void qemu_chr_open_mux(Chardev *chr,
}
d->focus = -1;
#if defined(TARGET_S390X)
d->accept_timer = qemu_new_timer_ns(vm_clock,
(QEMUTimerCB*)mux_chr_accept_input, chr);
#endif
/* only default to opened state if we've realized the initial
* set of muxes
*/

View File

@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define HW_POISON_H // avoid poison since we patch against rules it "enforces"
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "monitor/monitor.h"

3
configure vendored
View File

@@ -2040,6 +2040,9 @@ if test "$seccomp" != "no" ; then
ppc|ppc64)
libseccomp_minver="2.3.0"
;;
s390|s390x)
libseccomp_minver="2.2.0"
;;
*)
libseccomp_minver=""
;;

2
exec.c
View File

@@ -1950,11 +1950,13 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr,
return NULL;
}
#ifndef TARGET_PPC
if (kvm_enabled() && !kvm_has_sync_mmu()) {
error_setg(errp,
"host lacks kvm mmu notifiers, -mem-path unsupported");
return NULL;
}
#endif
if (phys_mem_alloc != qemu_anon_ram_alloc) {
/*

View File

@@ -311,7 +311,7 @@ static const VMStateDescription vmstate_cpuhp_state = {
static const VMStateDescription vmstate_acpi = {
.name = "piix4_pm",
.version_id = 3,
.minimum_version_id = 3,
.minimum_version_id = 2, /* qemu-kvm */
.minimum_version_id_old = 1,
.load_state_old = acpi_load_old,
.post_load = vmstate_acpi_post_load,

View File

@@ -113,6 +113,7 @@ struct XenBlkDev {
int requests_finished;
unsigned int max_requests;
gboolean cache_unsafe;
/* Persistent grants extension */
gboolean feature_discard;
gboolean feature_persistent;
@@ -947,6 +948,16 @@ static void blk_parse_discard(struct XenBlkDev *blkdev)
}
}
static void blk_parse_cache_unsafe(struct XenBlkDev *blkdev)
{
int enable;
blkdev->cache_unsafe = false;
if (xenstore_read_be_int(&blkdev->xendev, "suse-diskcache-disable-flush", &enable) == 0)
blkdev->cache_unsafe = !!enable;
}
static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
@@ -1028,6 +1039,7 @@ static int blk_init(struct XenDevice *xendev)
MAX_RING_PAGE_ORDER);
blk_parse_discard(blkdev);
blk_parse_cache_unsafe(blkdev);
g_free(directiosafe);
return 0;
@@ -1083,6 +1095,9 @@ static int blk_connect(struct XenDevice *xendev)
qflags |= BDRV_O_UNMAP;
}
if (blkdev->cache_unsafe)
qflags |= BDRV_O_NO_FLUSH;
/* init qemu block driver */
index = (blkdev->xendev.dev - 202 * 256) / 16;
blkdev->dinfo = drive_get(IF_XEN, 0, index);

View File

@@ -789,7 +789,32 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
#define PC_COMPAT_0_15 \
PC_CPU_MODEL_IDS("0.15")
PC_CPU_MODEL_IDS("0.15")\
{\
.driver = "VGA",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "vmware-svga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "qxl-vga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "qxl",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "isa-cirrus-vga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "cirrus-vga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},
static void pc_i440fx_0_15_machine_options(MachineClass *m)
{

View File

@@ -258,6 +258,12 @@ static int pit_dispatch_post_load(void *opaque, int version_id)
return 0;
}
static bool is_qemu_kvm(void *opaque, int version_id)
{
/* HACK: We ignore incoming migration from upstream qemu */
return version_id < 3;
}
static const VMStateDescription vmstate_pit_common = {
.name = "i8254",
.version_id = 3,
@@ -267,6 +273,7 @@ static const VMStateDescription vmstate_pit_common = {
.pre_save = pit_dispatch_pre_save,
.post_load = pit_dispatch_post_load,
.fields = (VMStateField[]) {
VMSTATE_UNUSED_TEST(is_qemu_kvm, 4),
VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
vmstate_pit_channel, PITChannelState),

View File

@@ -36,6 +36,9 @@ typedef struct MuxChardev {
Chardev parent;
CharBackend *backends[MAX_MUX];
CharBackend chr;
#if defined(TARGET_S390X)
QEMUTimer *accept_timer;
#endif
int focus;
int mux_cnt;
int term_got_escape;

View File

@@ -6,3 +6,5 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
obj-$(TARGET_I386) += vm86.o
obj-$(TARGET_ARM) += arm/nwfpe/
obj-$(TARGET_M68K) += m68k-sim.o
obj-binfmt-y = binfmt.o

68
linux-user/binfmt.c Normal file
View File

@@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <libgen.h>
#include <string.h>
#include <stdlib.h>
#ifdef __x86_64__
#define ARCH_NAME "x86_64"
#endif
int main(int argc, char **argv, char **envp)
{
char *binfmt;
char **new_argv;
/*
* Check if our file name ends with -binfmt
*/
binfmt = argv[0] + strlen(argv[0]) - strlen("-binfmt");
if (strcmp(binfmt, "-binfmt")) {
fprintf(stderr, "%s: Invalid executable name\n", argv[0]);
exit(1);
}
if (argc < 3) {
fprintf(stderr, "%s: Please use me through binfmt with P flag\n",
argv[0]);
exit(1);
}
binfmt[0] = '\0';
/* Now argv[0] is the real qemu binary name */
#ifdef ARCH_NAME
{
char *hostbin;
char *guestarch;
int r;
guestarch = strrchr(argv[0], '-') ;
if (!guestarch) {
goto skip;
}
guestarch++;
r = asprintf(&hostbin, "/emul/" ARCH_NAME "-for-%s/%s", guestarch, argv[1]);
if ((r > 0) && !access(hostbin, X_OK)) {
/*
* We found a host binary replacement for the non-host binary. Let's
* use that instead!
*/
return execve(hostbin, &argv[2], envp);
}
}
skip:
#endif
new_argv = (char **)malloc((argc + 2) * sizeof(*new_argv));
if (argc > 3) {
memcpy(&new_argv[4], &argv[3], (argc - 3) * sizeof(*new_argv));
}
new_argv[0] = argv[0];
new_argv[1] = (char *)"-0";
new_argv[2] = argv[2];
new_argv[3] = argv[1];
new_argv[argc + 1] = NULL;
return execve(new_argv[0], new_argv, envp);
}

View File

@@ -196,10 +196,10 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
void target_set_brk(abi_ulong new_brk);
abi_long do_brk(abi_ulong new_brk);
void syscall_init(void);
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8);
abi_long do_syscall(void *cpu_env, int num, abi_ulong arg1,
abi_ulong arg2, abi_ulong arg3, abi_ulong arg4,
abi_ulong arg5, abi_ulong arg6, abi_ulong arg7,
abi_ulong arg8);
void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
extern THREAD CPUState *thread_cpu;
void cpu_loop(CPUArchState *env);

View File

@@ -560,6 +560,10 @@ static void QEMU_NORETURN dump_core_and_abort(int target_sig)
trace_user_force_sig(env, target_sig, host_sig);
gdb_signalled(env, target_sig);
if (target_sig == 6) {
goto no_core;
}
/* dump core if supported by target binary format */
if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
stop_all_tasks();
@@ -577,6 +581,8 @@ static void QEMU_NORETURN dump_core_and_abort(int target_sig)
target_sig, strsignal(host_sig), "core dumped" );
}
no_core:
/* The proper exit code for dying from an uncaught signal is
* -<signal>. The kernel doesn't allow exit() or _exit() to pass
* a negative value. To get the proper exit code we need to

View File

@@ -5080,6 +5080,11 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
uint32_t outbufsz;
int free_fm = 0;
if (1) {
/* XXX agraf: fiemap breaks for me */
return -TARGET_EINVAL;
}
assert(arg_type[0] == TYPE_PTR);
assert(ie->access == IOC_RW);
arg_type++;
@@ -5615,7 +5620,12 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
ie = ioctl_entries;
for(;;) {
if (ie->target_cmd == 0) {
gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
int i;
gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", (unsigned long)cmd, (unsigned int)(cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
for (i = 0; ioctl_entries[i].target_cmd; i++) {
if ((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)))
gemu_log("%p\t->\t%s (%x)\n", (void *)(unsigned long)ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
}
return -TARGET_ENOSYS;
}
if (ie->target_cmd == cmd)
@@ -5647,6 +5657,11 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
arg_type++;
target_size = thunk_type_size(arg_type, 0);
switch(ie->access) {
/* FIXME: actually the direction given in the ioctl should be
* correct so we can assume the communication is uni-directional.
* The alsa developers did not like this concept though and
* declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
/*
case IOC_R:
ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
@@ -5665,6 +5680,7 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
unlock_user(argptr, arg, 0);
ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
break;
*/
default:
case IOC_RW:
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
@@ -7461,6 +7477,25 @@ static int open_self_stat(void *cpu_env, int fd)
return 0;
}
static int open_cpuinfo(void *cpu_env, int fd)
{
dprintf(fd,
"Processor : ARMv7 Processor rev 5 (v7l)\n"
"BogoMIPS : 799.53\n"
"Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3\n"
"CPU implementer : 0x41\n"
"CPU architecture: 7\n"
"CPU variant : 0x2\n"
"CPU part : 0xc08\n"
"CPU revision : 5\n"
"\n"
"Hardware : Genesi Efika MX (Smarttop)\n"
"Revision : 51030\n"
"Serial : 0000000000000000\n");
return 0;
}
static int open_self_auxv(void *cpu_env, int fd)
{
CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
@@ -7575,6 +7610,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
{ "/proc/net/route", open_net_route, is_proc },
#endif
{ "cpuinfo", open_cpuinfo, is_proc_myself },
{ NULL, NULL, NULL }
};
@@ -7692,10 +7728,10 @@ static TargetFdTrans target_inotify_trans = {
/* do_syscall() should always have a single exit point at the end so
that actions, such as logging of syscall results, can be performed.
All errnos that do_syscall() returns must be -TARGET_<errcode>. */
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8)
abi_long do_syscall(void *cpu_env, int num, abi_ulong arg1,
abi_ulong arg2, abi_ulong arg3, abi_ulong arg4,
abi_ulong arg5, abi_ulong arg6, abi_ulong arg7,
abi_ulong arg8)
{
CPUState *cpu = ENV_GET_CPU(cpu_env);
abi_long ret;
@@ -8071,9 +8107,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_oldstat:
goto unimplemented;
#endif
case TARGET_NR_lseek:
ret = get_errno(lseek(arg1, arg2, arg3));
case TARGET_NR_lseek: {
off_t off = arg2;
if (arg3 != SEEK_SET) {
off = (abi_long)arg2;
}
ret = get_errno(lseek(arg1, off, arg3));
break;
}
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
/* Alpha specific */
case TARGET_NR_getxpid:
@@ -8950,6 +8991,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_gettimeofday:
{
struct timeval tv;
if(copy_from_user_timeval(&tv, arg1))
goto efault;
ret = get_errno(gettimeofday(&tv, NULL));
if (!is_error(ret)) {
if (copy_to_user_timeval(arg1, &tv))
@@ -10197,7 +10240,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
{
struct timespec ts, *pts;
if (arg3 >= 0) {
if ((abi_long)arg3 >= 0) {
/* Convert ms to secs, ns */
ts.tv_sec = arg3 / 1000;
ts.tv_nsec = (arg3 % 1000) * 1000000LL;

View File

@@ -133,7 +133,7 @@ struct ccw1 {
__u8 flags;
__u16 count;
__u32 cda;
} __attribute__ ((packed));
} __attribute__ ((packed, aligned(8)));
#define CCW_FLAG_DC 0x80
#define CCW_FLAG_CC 0x40

View File

@@ -43,7 +43,8 @@ static void free_range(void *range, void *dummy)
g_free(range);
}
static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
static int parse_str(StringInputVisitor *siv, const char *name, bool u64,
Error **errp)
{
char *str = (char *) siv->string;
long long start, end;
@@ -60,7 +61,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
do {
errno = 0;
start = strtoll(str, &endptr, 0);
if (u64) {
start = strtoull(str, &endptr, 0);
} else {
start = strtoll(str, &endptr, 0);
}
if (errno == 0 && endptr > str) {
if (*endptr == '\0') {
cur = g_malloc0(sizeof(*cur));
@@ -71,7 +76,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
} else if (*endptr == '-') {
str = endptr + 1;
errno = 0;
end = strtoll(str, &endptr, 0);
if (u64) {
end = strtoull(str, &endptr, 0);
} else {
end = strtoll(str, &endptr, 0);
}
if (errno == 0 && endptr > str && start <= end &&
(start > INT64_MAX - 65536 ||
end < start + 65536)) {
@@ -127,7 +136,7 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
assert(list);
siv->list = list;
if (parse_str(siv, name, errp) < 0) {
if (parse_str(siv, name, false, errp) < 0) {
*list = NULL;
return;
}
@@ -215,7 +224,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
{
StringInputVisitor *siv = to_siv(v);
if (parse_str(siv, name, errp) < 0) {
if (parse_str(siv, name, false, errp) < 0) {
return;
}
@@ -251,15 +260,43 @@ error:
static void parse_type_uint64(Visitor *v, const char *name, uint64_t *obj,
Error **errp)
{
/* FIXME: parse_type_int64 mishandles values over INT64_MAX */
int64_t i;
Error *err = NULL;
parse_type_int64(v, name, &i, &err);
if (err) {
error_propagate(errp, err);
} else {
*obj = i;
StringInputVisitor *siv = to_siv(v);
if (!siv->string) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"integer");
return;
}
parse_str(siv, name, true, errp);
if (!siv->ranges) {
goto error;
}
if (!siv->cur_range) {
Range *r;
siv->cur_range = g_list_first(siv->ranges);
if (!siv->cur_range) {
goto error;
}
r = siv->cur_range->data;
if (!r) {
goto error;
}
siv->cur = range_lob(r);
}
*obj = siv->cur;
siv->cur++;
return;
error:
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
"a uint64 value or range");
}
static void parse_type_size(Visitor *v, const char *name, uint64_t *obj,

View File

@@ -110,7 +110,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
*argend = 0;
if (strcmp(cmd, "deny") == 0) {
acl_rule = g_malloc(sizeof(*acl_rule));
acl_rule = calloc(1, sizeof(*acl_rule));
if (!acl_rule) {
fclose(f);
errno = ENOMEM;
return -1;
}
if (strcmp(arg, "all") == 0) {
acl_rule->type = ACL_DENY_ALL;
} else {
@@ -119,7 +124,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
}
QSIMPLEQ_INSERT_TAIL(acl_list, acl_rule, entry);
} else if (strcmp(cmd, "allow") == 0) {
acl_rule = g_malloc(sizeof(*acl_rule));
acl_rule = calloc(1, sizeof(*acl_rule));
if (!acl_rule) {
fclose(f);
errno = ENOMEM;
return -1;
}
if (strcmp(arg, "all") == 0) {
acl_rule->type = ACL_ALLOW_ALL;
} else {
@@ -413,6 +423,17 @@ int main(int argc, char **argv)
goto cleanup;
}
#ifndef CONFIG_LIBCAP
/* avoid sending the fd as root user if running suid to not fool
* peer credentials to daemons that dont expect that
*/
if (setuid(getuid()) < 0) {
fprintf(stderr, "Failed to drop privileges.\n");
ret = EXIT_FAILURE;
goto cleanup;
}
#endif
/* write fd to the domain socket */
if (send_fd(unixfd, fd) == -1) {
fprintf(stderr, "failed to write fd to unix socket: %s\n",
@@ -434,7 +455,7 @@ cleanup:
}
while ((acl_rule = QSIMPLEQ_FIRST(&acl_list)) != NULL) {
QSIMPLEQ_REMOVE_HEAD(&acl_list, entry);
g_free(acl_rule);
free(acl_rule);
}
return ret;

View File

@@ -52,6 +52,12 @@ SEABIOS_EXTRAVERSION="-prebuilt.qemu-project.org"
#
EFIROM ?= $(shell which EfiRom 2>/dev/null)
# NB: Certain SUSE qemu subpackages use date information, but we want
# reproducible builds, so we use a pre-determined timestamp, rather
# than the current timestamp to acheive consistent results build to
# build.
PACKAGING_TIMESTAMP = $(shell date -r ../VERSION +%s)
default:
@echo "nothing is build by default"
@echo "available build targets:"
@@ -106,7 +112,7 @@ build-lgplvgabios:
.PHONY: sgabios skiboot
sgabios:
$(MAKE) -C sgabios
$(MAKE) -C sgabios PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP)
cp sgabios/sgabios.bin ../pc-bios
@@ -126,18 +132,22 @@ efi-rom-%: build-pxe-roms build-efi-roms
build-pxe-roms:
$(MAKE) -C ipxe/src CONFIG=qemu \
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
CROSS_COMPILE=$(x86_64_cross_prefix) \
$(patsubst %,bin/%.rom,$(pxerom_targets))
build-efi-roms: build-pxe-roms
$(MAKE) -C ipxe/src CONFIG=qemu \
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
CROSS_COMPILE=$(x86_64_cross_prefix) \
$(patsubst %,bin-i386-efi/%.efidrv,$(pxerom_targets)) \
$(patsubst %,bin-x86_64-efi/%.efidrv,$(pxerom_targets))
slof:
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) qemu
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) \
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
qemu
cp SLOF/boot_rom.bin ../pc-bios/slof.bin
u-boot.e500:

View File

@@ -206,7 +206,7 @@ qemu_check_systemd() {
}
qemu_generate_register() {
echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS"
echo ":qemu-$cpu:M::$magic:$mask:$qemu:P$FLAGS"
}
qemu_register_interpreter() {
@@ -247,9 +247,9 @@ qemu_set_binfmts() {
continue
fi
qemu="$QEMU_PATH/qemu-$cpu"
qemu="$QEMU_PATH/qemu-$cpu-binfmt"
if [ "$cpu" = "i486" ] ; then
qemu="$QEMU_PATH/qemu-i386"
qemu="$QEMU_PATH/qemu-i386-binfmt"
fi
if [ "$host_family" != "$family" ] ; then
@@ -264,7 +264,7 @@ BINFMT_SET=qemu_register_interpreter
SYSTEMDDIR="/etc/binfmt.d"
DEBIANDIR="/usr/share/binfmts"
QEMU_PATH=/usr/local/bin
QEMU_PATH=/usr/bin
FLAGS=""
options=$(getopt -o ds:Q:e:hc: -l debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@")

View File

@@ -59,6 +59,27 @@ socreate(Slirp *slirp)
return(so);
}
/*
* Remove references to so from the given message queue.
*/
static void
soqfree(struct socket *so, struct quehead *qh)
{
struct mbuf *ifq;
for (ifq = (struct mbuf *) qh->qh_link;
(struct quehead *) ifq != qh;
ifq = ifq->ifq_next) {
if (ifq->ifq_so == so) {
struct mbuf *ifm;
ifq->ifq_so = NULL;
for (ifm = ifq->ifs_next; ifm != ifq; ifm = ifm->ifs_next) {
ifm->ifq_so = NULL;
}
}
}
}
/*
* remque and free a socket, clobber cache
*/
@@ -66,23 +87,9 @@ void
sofree(struct socket *so)
{
Slirp *slirp = so->slirp;
struct mbuf *ifm;
for (ifm = (struct mbuf *) slirp->if_fastq.qh_link;
(struct quehead *) ifm != &slirp->if_fastq;
ifm = ifm->ifq_next) {
if (ifm->ifq_so == so) {
ifm->ifq_so = NULL;
}
}
for (ifm = (struct mbuf *) slirp->if_batchq.qh_link;
(struct quehead *) ifm != &slirp->if_batchq;
ifm = ifm->ifq_next) {
if (ifm->ifq_so == so) {
ifm->ifq_so = NULL;
}
}
soqfree(so, &slirp->if_fastq);
soqfree(so, &slirp->if_batchq);
if (so->so_emu==EMU_RSH && so->extra) {
sofree(so->extra);

View File

@@ -1522,6 +1522,50 @@ static X86CPUDefinition builtin_x86_defs[] = {
.xlevel = 0x8000001A,
.model_id = "AMD Opteron 63xx class CPU",
},
{
.name = "EPYC",
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 23,
.model = 1,
.stepping = 2,
.features[FEAT_1_EDX] =
CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH |
CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE |
CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE |
CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE |
CPUID_VME | CPUID_FP87,
.features[FEAT_1_ECX] =
CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX |
CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT |
CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 |
CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
.features[FEAT_8000_0001_EDX] =
CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB |
CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX |
CPUID_EXT2_SYSCALL,
.features[FEAT_8000_0001_ECX] =
CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH |
CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM |
CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
.features[FEAT_7_0_EBX] =
CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED |
CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT |
CPUID_7_0_EBX_SHA_NI,
/* Missing: XSAVES (not supported by some Linux versions,
* including v4.1 to v4.12).
* KVM doesn't yet expose any XSAVES state save component.
*/
.features[FEAT_XSAVE] =
CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
CPUID_XSAVE_XGETBV1,
.features[FEAT_6_EAX] =
CPUID_6_EAX_ARAT,
.xlevel = 0x8000000A,
.model_id = "AMD EPYC Processor",
},
};
typedef struct PropValue {

View File

@@ -1500,7 +1500,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);
/* XXX: This value should match the one returned by CPUID
* and in exec.c */
# if defined(TARGET_X86_64)
# define TCG_PHYS_ADDR_BITS 40
# define TCG_PHYS_ADDR_BITS 42
# else
# define TCG_PHYS_ADDR_BITS 36
# endif

View File

@@ -113,6 +113,8 @@ check-unit-y += tests/check-qom-interface$(EXESUF)
gcov-files-check-qom-interface-y = qom/object.c
check-unit-y += tests/check-qom-proplist$(EXESUF)
gcov-files-check-qom-proplist-y = qom/object.c
check-unit-y += tests/check-qom-props$(EXESUF)
gcov-files-check-qom-props-y = qom/object.c
check-unit-y += tests/test-qemu-opts$(EXESUF)
gcov-files-test-qemu-opts-y = util/qemu-option.c
check-unit-y += tests/test-keyval$(EXESUF)
@@ -183,6 +185,8 @@ check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF)
gcov-files-virtio-y += hw/virtio/virtio-rng.c
check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF)
gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c
check-qtest-virtio-y += tests/scsi-disk-test$(EXESUF)
gcov-files-virtio-y += i386-softmmu/hw/scsi/scsi-disk.c
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
check-qtest-virtio-y += tests/virtio-9p-test$(EXESUF)
gcov-files-virtio-y += hw/9pfs/virtio-9p.c
@@ -571,6 +575,7 @@ tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
tests/check-qom-props$(EXESUF): tests/check-qom-props.o $(test-qom-obj-y)
tests/test-char$(EXESUF): tests/test-char.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y) $(chardev-obj-y)
tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
@@ -776,6 +781,7 @@ tests/postcopy-test$(EXESUF): tests/postcopy-test.o
tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o $(test-util-obj-y) \
$(qtest-obj-y) $(test-io-obj-y) $(libqos-virtio-obj-y) $(libqos-pc-obj-y) \
$(chardev-obj-y)
tests/scsi-disk-test$(EXESUF): tests/scsi-disk-test.o
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
tests/test-keyval$(EXESUF): tests/test-keyval.o $(test-util-obj-y) $(test-qapi-obj-y)

122
tests/check-qom-props.c Normal file
View File

@@ -0,0 +1,122 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
* Copyright (c) 2015 SUSE Linux GmbH
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Author: Daniel P. Berrange <berrange@redhat.com>
* Andreas Färber <afaerber@suse.com>
*/
#include "qemu/osdep.h"
#include <glib.h>
#include "qapi/visitor.h"
#include "qom/object.h"
#include "qemu/module.h"
#define TYPE_DUMMY "qemu-dummy"
typedef struct DummyObject DummyObject;
typedef struct DummyObjectClass DummyObjectClass;
#define DUMMY_OBJECT(obj) \
OBJECT_CHECK(DummyObject, (obj), TYPE_DUMMY)
struct DummyObject {
Object parent_obj;
uint64_t u64val;
};
struct DummyObjectClass {
ObjectClass parent_class;
};
static void dummy_set_uint64(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
uint64_t *ptr = (uint64_t *)opaque;
visit_type_uint64(v, name, ptr, errp);
}
static void dummy_get_uint64(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
uint64_t value = *(uint64_t *)opaque;
visit_type_uint64(v, name, &value, errp);
}
static void dummy_init(Object *obj)
{
DummyObject *dobj = DUMMY_OBJECT(obj);
object_property_add(obj, "u64val", "uint64",
dummy_get_uint64,
dummy_set_uint64,
NULL, &dobj->u64val, NULL);
}
static const TypeInfo dummy_info = {
.name = TYPE_DUMMY,
.parent = TYPE_OBJECT,
.instance_size = sizeof(DummyObject),
.instance_init = dummy_init,
.class_size = sizeof(DummyObjectClass),
};
static void test_dummy_uint64(void)
{
Error *err = NULL;
char *str;
DummyObject *dobj = DUMMY_OBJECT(object_new(TYPE_DUMMY));
g_assert(dobj->u64val == 0);
str = g_strdup_printf("%" PRIu64, UINT64_MAX);
object_property_parse(OBJECT(dobj), str, "u64val", &err);
g_free(str);
g_assert(!err);
g_assert_cmpint(dobj->u64val, ==, UINT64_MAX);
dobj->u64val = 0;
str = g_strdup_printf("0x%" PRIx64, UINT64_MAX);
object_property_parse(OBJECT(dobj), str, "u64val", &err);
g_free(str);
g_assert(!err);
g_assert_cmpint(dobj->u64val, ==, UINT64_MAX);
object_unref(OBJECT(dobj));
}
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
module_call_init(MODULE_INIT_QOM);
type_register_static(&dummy_info);
g_test_add_func("/qom/props/uint64", test_dummy_uint64);
return g_test_run();
}

82
tests/scsi-disk-test.c Normal file
View File

@@ -0,0 +1,82 @@
/*
* QTest testcase for SCSI disks
* See virtio-scsi-test for more integrated tests.
*
* Copyright (c) 2015 SUSE Linux GmbH
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include <glib.h>
#include "libqtest.h"
#include "qapi/qmp/qnum.h"
static void test_scsi_disk_common(const char *type, const char *id)
{
char *cmdline, *path;
QDict *response;
QNum *value;
cmdline = g_strdup_printf(
"-drive id=drv0,if=none,file=/dev/null,format=raw "
"-device virtio-scsi-pci,id=scsi0 "
"-device %s,id=%s,bus=scsi0.0,drive=drv0"
",wwn=0x%" PRIx64 ",port_wwn=0x%" PRIx64,
type, id, UINT64_MAX, UINT64_C(1) << 63);
qtest_start(cmdline);
g_free(cmdline);
path = g_strdup_printf("/machine/peripheral/%s", id);
response = qmp("{ 'execute': 'qom-get',"
" 'arguments': { 'path': %s,"
" 'property': 'wwn' } }",
path);
g_assert(response);
g_assert(qdict_haskey(response, "return"));
value = qobject_to_qnum(qdict_get(response, "return"));
g_assert_cmpint(qnum_get_uint(value), ==, UINT64_MAX);
response = qmp("{ 'execute': 'qom-get',"
" 'arguments': { 'path': %s,"
" 'property': 'port_wwn' } }",
path);
g_assert(response);
g_assert(qdict_haskey(response, "return"));
value = qobject_to_qnum(qdict_get(response, "return"));
g_assert_cmpint(qnum_get_uint(value), ==, UINT64_C(1) << 63);
g_free(path);
qtest_end();
}
static void test_scsi_disk(void)
{
test_scsi_disk_common("scsi-disk", "disk0");
}
static void test_scsi_hd(void)
{
test_scsi_disk_common("scsi-hd", "hd0");
}
static void test_scsi_cd(void)
{
test_scsi_disk_common("scsi-cd", "cd0");
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/scsi-disk/props", test_scsi_disk);
qtest_add_func("/scsi-hd/props", test_scsi_hd);
qtest_add_func("/scsi-cd/props", test_scsi_cd);
ret = g_test_run();
return ret;
}

View File

@@ -55,6 +55,14 @@ static void test_visitor_in_int(TestInputVisitorData *data,
v = visitor_input_test_init(data, "-42");
visit_type_int(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
visitor_input_teardown(data, unused);
value = INT64_MAX;
v = visitor_input_test_init(data, g_strdup_printf("%" PRId64, value));
visit_type_int(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
@@ -70,6 +78,27 @@ static void test_visitor_in_int(TestInputVisitorData *data,
error_free_or_abort(&err);
}
static void test_visitor_in_uint64(TestInputVisitorData *data,
const void *unused)
{
uint64_t res = 0, value = UINT64_MAX;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, g_strdup_printf("%" PRIu64, value));
visit_type_uint64(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, g_strdup_printf("0x%" PRIx64, value));
visit_type_uint64(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
}
static void check_ilist(Visitor *v, int64_t *expected, size_t n)
{
int64List *res = NULL;
@@ -356,6 +385,8 @@ int main(int argc, char **argv)
input_visitor_test_add("/string-visitor/input/int",
&in_visitor_data, test_visitor_in_int);
input_visitor_test_add("/string-visitor/input/uint64",
&in_visitor_data, test_visitor_in_uint64);
input_visitor_test_add("/string-visitor/input/intList",
&in_visitor_data, test_visitor_in_intList);
input_visitor_test_add("/string-visitor/input/bool",

View File

@@ -880,7 +880,7 @@ static void console_putchar(QemuConsole *s, int ch)
} else {
if (s->nb_esc_params < MAX_ESC_PARAMS)
s->nb_esc_params++;
if (ch == ';')
if (ch == ';' || ch == '?')
break;
trace_console_putchar_csi(s->esc_params[0], s->esc_params[1],
ch, s->nb_esc_params);

View File

@@ -1657,6 +1657,25 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
if (down)
vs->modifiers_state[keycode] ^= 1;
break;
default:
if (qemu_console_is_graphic(NULL)) {
/* record key 'down' info. Some client like tigervnc
* will send key down repeatedly if user pressing a
* a key for long time. In this case, we should add
* additional key up event before repeated key down,
* so that it can display the key multiple times.
*/
if (down) {
if (vs->modifiers_state[keycode]) {
/* add a key up event */
do_key_event(vs, 0, keycode, sym);
}
vs->modifiers_state[keycode] = 1;
} else {
vs->modifiers_state[keycode] = 0;
}
}
break;
}
/* Turn off the lock state sync logic if the client support the led

View File

@@ -78,6 +78,10 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* Maybe we're still holding the TB fiddling lock? */
tb_lock_reset();
/* XXX: locking issue */
if (is_write && h2g_valid(address)) {
switch (page_unprotect(h2g(address), pc)) {

View File

@@ -308,7 +308,12 @@ static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
qemu_mutex_init(&pool->lock);
qemu_cond_init(&pool->worker_stopped);
qemu_sem_init(&pool->sem, 0);
pool->max_threads = 64;
if (sizeof(pool) == 4) {
/* 32bit systems run out of virtual memory quickly */
pool->max_threads = 4;
} else {
pool->max_threads = 64;
}
pool->new_thread_bh = aio_bh_new(ctx, spawn_thread_bh_fn, pool);
QLIST_INIT(&pool->head);

12
vl.c
View File

@@ -26,6 +26,7 @@
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/uuid.h"
#include <sys/resource.h>
#ifdef CONFIG_SECCOMP
#include "sysemu/seccomp.h"
@@ -3035,6 +3036,7 @@ int main(int argc, char **argv, char **envp)
} BlockdevOptions_queue;
QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue
= QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
struct rlimit rlimit_as;
module_call_init(MODULE_INIT_TRACE);
@@ -3042,6 +3044,16 @@ int main(int argc, char **argv, char **envp)
qemu_init_cpu_loop();
qemu_mutex_lock_iothread();
/*
* Try to raise the soft address space limit.
* Default on SLES 11 SP2 is 80% of physical+swap memory.
*/
getrlimit(RLIMIT_AS, &rlimit_as);
if (rlimit_as.rlim_cur < rlimit_as.rlim_max) {
rlimit_as.rlim_cur = rlimit_as.rlim_max;
setrlimit(RLIMIT_AS, &rlimit_as);
}
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
qemu_init_exec_dir(argv[0]);