chardev/baum: fix baum that releases brlapi twice (bsc#1060045) #15
@@ -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
|
||||
|
||||
@@ -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)$@")
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
3
configure
vendored
@@ -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
2
exec.c
@@ -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) {
|
||||
/*
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
68
linux-user/binfmt.c
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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: -- "$@")
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
122
tests/check-qom-props.c
Normal 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
82
tests/scsi-disk-test.c
Normal 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;
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
19
ui/vnc.c
19
ui/vnc.c
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
12
vl.c
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user