* allow building QEMU without TCG or KVM support (Anthony)
* update AMD IOMMU copyright (David) * compilation fixes for GCC and BSDs (Alexey, David, Paolo, Philippe) * coalesced I/O bugfix (Jagannathan) * Processor Tracing cpuid fix (Luwei) * Kconfig fixes (Paolo, David) * Cleanups (Paolo, Wei) * PVH vs. multiboot fix (Stefano) * LSI bugfixes (Sven) * elf2dmp Coverity fix (Victor) * scsi-disk fix (Zhengui) * authorization support for chardev TLS (Daniel) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJchojQAAoJEL/70l94x66DWbEH/Rdhyh1Yrd0qDTEUzHiWvDKA ZrNnvmgXkxbH4JxkrkmDVIfftPSvlY3ZA1I3S+VQsvgq9Pz2w3rMcS3syaCK4pyw YFHMhutYvLmXiYgKyygD+ysaxtcC/vXDS3k7QpFDu/4OULZi6Fxe7/lMYRiFeiIt olUNFeyCa6ckJ+TrSu83PSeIX0AVHOxP5FQrI7RupZimeSARFUy/Swkw+bzeeVKp mfD8bxzhdPQd+3dMPG2kW9QS8G/QlDL+EMI0q9WUrGPxxpMBK5Gz4QMrjLyjSuO/ 7xdV3AntXlPxTTo1+m01Vn7PmutS3YgolHVx2HxVA4zvXZUpa5jlQllEHhigjrY= =7nFp -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging * allow building QEMU without TCG or KVM support (Anthony) * update AMD IOMMU copyright (David) * compilation fixes for GCC and BSDs (Alexey, David, Paolo, Philippe) * coalesced I/O bugfix (Jagannathan) * Processor Tracing cpuid fix (Luwei) * Kconfig fixes (Paolo, David) * Cleanups (Paolo, Wei) * PVH vs. multiboot fix (Stefano) * LSI bugfixes (Sven) * elf2dmp Coverity fix (Victor) * scsi-disk fix (Zhengui) * authorization support for chardev TLS (Daniel) # gpg: Signature made Mon 11 Mar 2019 16:12:00 GMT # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # 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: (31 commits) qemugdb: fix licensing chardev: add support for authorization for TLS clients qom: cpu: destroy work_mutex in cpu_common_finalize exec.c: refactor function flatview_add_to_dispatch() lsi: 810/895A are always little endian lsi: return dfifo value lsi: use SCSI phase names instead of numbers in trace lsi: use enum type for s->msg_action lsi: use enum type for s->waiting lsi: use ldn_le_p()/stn_le_p() scsi-disk: Fix crash if request is invaild or disk is no medium configure: Disable W^X on OpenBSD oslib-posix: Ignore fcntl("/dev/null", F_SETFL, O_NONBLOCK) failure accel: Allow to build QEMU without TCG or KVM support build: clean trace/generated-helpers.c build: remove unnecessary assignments from Makefile.target build: get rid of target-obj-y update copyright notice lsi: check if SIGP bit is already set in Wait reselect lsi: implement basic SBCL functionality ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
377b155bde
|
@ -13,7 +13,7 @@ authz-obj-y = authz/
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# block-obj-y is code used by both qemu system emulation and qemu-img
|
# block-obj-y is code used by both qemu system emulation and qemu-img
|
||||||
|
|
||||||
block-obj-y += nbd/
|
block-obj-y = nbd/
|
||||||
block-obj-y += block.o blockjob.o job.o
|
block-obj-y += block.o blockjob.o job.o
|
||||||
block-obj-y += block/ scsi/
|
block-obj-y += block/ scsi/
|
||||||
block-obj-y += qemu-io-cmds.o
|
block-obj-y += qemu-io-cmds.o
|
||||||
|
@ -101,7 +101,6 @@ version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o
|
||||||
######################################################################
|
######################################################################
|
||||||
# tracing
|
# tracing
|
||||||
util-obj-y += trace/
|
util-obj-y += trace/
|
||||||
target-obj-y += trace/
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# guest agent
|
# guest agent
|
||||||
|
|
|
@ -105,6 +105,8 @@ all: $(PROGS) stap
|
||||||
# Dummy command so that make thinks it has done something
|
# Dummy command so that make thinks it has done something
|
||||||
@true
|
@true
|
||||||
|
|
||||||
|
obj-y += trace/
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# cpu emulator library
|
# cpu emulator library
|
||||||
obj-y += exec.o
|
obj-y += exec.o
|
||||||
|
@ -173,13 +175,7 @@ endif # CONFIG_SOFTMMU
|
||||||
dummy := $(call unnest-vars,,obj-y)
|
dummy := $(call unnest-vars,,obj-y)
|
||||||
all-obj-y := $(obj-y)
|
all-obj-y := $(obj-y)
|
||||||
|
|
||||||
target-obj-y :=
|
|
||||||
block-obj-y :=
|
|
||||||
common-obj-y :=
|
|
||||||
chardev-obj-y :=
|
|
||||||
include $(SRC_PATH)/Makefile.objs
|
include $(SRC_PATH)/Makefile.objs
|
||||||
dummy := $(call unnest-vars,,target-obj-y)
|
|
||||||
target-obj-y-save := $(target-obj-y)
|
|
||||||
dummy := $(call unnest-vars,.., \
|
dummy := $(call unnest-vars,.., \
|
||||||
authz-obj-y \
|
authz-obj-y \
|
||||||
block-obj-y \
|
block-obj-y \
|
||||||
|
@ -191,9 +187,7 @@ dummy := $(call unnest-vars,.., \
|
||||||
io-obj-y \
|
io-obj-y \
|
||||||
common-obj-y \
|
common-obj-y \
|
||||||
common-obj-m)
|
common-obj-m)
|
||||||
target-obj-y := $(target-obj-y-save)
|
|
||||||
all-obj-y += $(common-obj-y)
|
all-obj-y += $(common-obj-y)
|
||||||
all-obj-y += $(target-obj-y)
|
|
||||||
all-obj-y += $(qom-obj-y)
|
all-obj-y += $(qom-obj-y)
|
||||||
all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
|
all-obj-$(CONFIG_SOFTMMU) += $(authz-obj-y)
|
||||||
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
|
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) $(chardev-obj-y)
|
||||||
|
@ -228,6 +222,7 @@ clean: clean-target
|
||||||
rm -f *.a *~ $(PROGS)
|
rm -f *.a *~ $(PROGS)
|
||||||
rm -f $(shell find . -name '*.[od]')
|
rm -f $(shell find . -name '*.[od]')
|
||||||
rm -f hmp-commands.h gdbstub-xml.c
|
rm -f hmp-commands.h gdbstub-xml.c
|
||||||
|
rm -f trace/generated-helpers.c trace/generated-helpers.c-timestamp
|
||||||
ifdef CONFIG_TRACE_SYSTEMTAP
|
ifdef CONFIG_TRACE_SYSTEMTAP
|
||||||
rm -f *.stp
|
rm -f *.stp
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -91,7 +91,9 @@ void configure_accelerator(MachineState *ms, const char *progname)
|
||||||
#elif defined(CONFIG_KVM)
|
#elif defined(CONFIG_KVM)
|
||||||
accel = "kvm";
|
accel = "kvm";
|
||||||
#else
|
#else
|
||||||
#error "No default accelerator available"
|
error_report("No accelerator selected and"
|
||||||
|
" no default accelerator available");
|
||||||
|
exit(1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,8 @@ static const unsigned iscsi_retry_times[] = {8, 32, 128, 512, 2048, 8192, 32768}
|
||||||
* unallocated. */
|
* unallocated. */
|
||||||
#define ISCSI_CHECKALLOC_THRES 64
|
#define ISCSI_CHECKALLOC_THRES 64
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
static void
|
static void
|
||||||
iscsi_bh_cb(void *p)
|
iscsi_bh_cb(void *p)
|
||||||
{
|
{
|
||||||
|
@ -172,6 +174,8 @@ iscsi_schedule_bh(IscsiAIOCB *acb)
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void iscsi_co_generic_bh_cb(void *opaque)
|
static void iscsi_co_generic_bh_cb(void *opaque)
|
||||||
{
|
{
|
||||||
struct IscsiTask *iTask = opaque;
|
struct IscsiTask *iTask = opaque;
|
||||||
|
@ -290,6 +294,8 @@ static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
/* Called (via iscsi_service) with QemuMutex held. */
|
/* Called (via iscsi_service) with QemuMutex held. */
|
||||||
static void
|
static void
|
||||||
iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
|
iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
|
||||||
|
@ -338,6 +344,7 @@ static const AIOCBInfo iscsi_aiocb_info = {
|
||||||
.cancel_async = iscsi_aio_cancel,
|
.cancel_async = iscsi_aio_cancel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void iscsi_process_read(void *arg);
|
static void iscsi_process_read(void *arg);
|
||||||
static void iscsi_process_write(void *arg);
|
static void iscsi_process_write(void *arg);
|
||||||
|
|
|
@ -59,6 +59,7 @@ typedef struct {
|
||||||
QIONetListener *listener;
|
QIONetListener *listener;
|
||||||
GSource *hup_source;
|
GSource *hup_source;
|
||||||
QCryptoTLSCreds *tls_creds;
|
QCryptoTLSCreds *tls_creds;
|
||||||
|
char *tls_authz;
|
||||||
TCPChardevState state;
|
TCPChardevState state;
|
||||||
int max_size;
|
int max_size;
|
||||||
int do_telnetopt;
|
int do_telnetopt;
|
||||||
|
@ -807,7 +808,7 @@ static void tcp_chr_tls_init(Chardev *chr)
|
||||||
if (s->is_listen) {
|
if (s->is_listen) {
|
||||||
tioc = qio_channel_tls_new_server(
|
tioc = qio_channel_tls_new_server(
|
||||||
s->ioc, s->tls_creds,
|
s->ioc, s->tls_creds,
|
||||||
NULL, /* XXX Use an ACL */
|
s->tls_authz,
|
||||||
&err);
|
&err);
|
||||||
} else {
|
} else {
|
||||||
tioc = qio_channel_tls_new_client(
|
tioc = qio_channel_tls_new_client(
|
||||||
|
@ -1055,6 +1056,7 @@ static void char_socket_finalize(Object *obj)
|
||||||
if (s->tls_creds) {
|
if (s->tls_creds) {
|
||||||
object_unref(OBJECT(s->tls_creds));
|
object_unref(OBJECT(s->tls_creds));
|
||||||
}
|
}
|
||||||
|
g_free(s->tls_authz);
|
||||||
|
|
||||||
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
|
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
|
||||||
}
|
}
|
||||||
|
@ -1242,6 +1244,11 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sock->has_tls_authz && !sock->has_tls_creds) {
|
||||||
|
error_setg(errp, "'tls_authz' option requires 'tls_creds' option");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Validate any options which have a dependancy on client vs server */
|
/* Validate any options which have a dependancy on client vs server */
|
||||||
if (!sock->has_server || sock->server) {
|
if (!sock->has_server || sock->server) {
|
||||||
if (sock->has_reconnect) {
|
if (sock->has_reconnect) {
|
||||||
|
@ -1320,6 +1327,7 @@ static void qmp_chardev_open_socket(Chardev *chr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s->tls_authz = g_strdup(sock->tls_authz);
|
||||||
|
|
||||||
s->addr = addr = socket_address_flatten(sock->addr);
|
s->addr = addr = socket_address_flatten(sock->addr);
|
||||||
|
|
||||||
|
@ -1399,6 +1407,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend,
|
||||||
sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
|
sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0);
|
||||||
sock->has_tls_creds = qemu_opt_get(opts, "tls-creds");
|
sock->has_tls_creds = qemu_opt_get(opts, "tls-creds");
|
||||||
sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
|
sock->tls_creds = g_strdup(qemu_opt_get(opts, "tls-creds"));
|
||||||
|
sock->has_tls_authz = qemu_opt_get(opts, "tls-authz");
|
||||||
|
sock->tls_authz = g_strdup(qemu_opt_get(opts, "tls-authz"));
|
||||||
|
|
||||||
addr = g_new0(SocketAddressLegacy, 1);
|
addr = g_new0(SocketAddressLegacy, 1);
|
||||||
if (path) {
|
if (path) {
|
||||||
|
|
|
@ -880,6 +880,9 @@ QemuOptsList qemu_chardev_opts = {
|
||||||
},{
|
},{
|
||||||
.name = "tls-creds",
|
.name = "tls-creds",
|
||||||
.type = QEMU_OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
|
},{
|
||||||
|
.name = "tls-authz",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
},{
|
},{
|
||||||
.name = "websocket",
|
.name = "websocket",
|
||||||
.type = QEMU_OPT_BOOL,
|
.type = QEMU_OPT_BOOL,
|
||||||
|
|
13
configure
vendored
13
configure
vendored
|
@ -1836,7 +1836,7 @@ fi
|
||||||
# Consult white-list to determine whether to enable werror
|
# Consult white-list to determine whether to enable werror
|
||||||
# by default. Only enable by default for git builds
|
# by default. Only enable by default for git builds
|
||||||
if test -z "$werror" ; then
|
if test -z "$werror" ; then
|
||||||
if test -d "$source_path/.git" && \
|
if test -e "$source_path/.git" && \
|
||||||
{ test "$linux" = "yes" || test "$mingw32" = "yes"; }; then
|
{ test "$linux" = "yes" || test "$mingw32" = "yes"; }; then
|
||||||
werror="yes"
|
werror="yes"
|
||||||
else
|
else
|
||||||
|
@ -5903,6 +5903,17 @@ if test "$mingw32" = "yes" ; then
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Disable OpenBSD W^X if available
|
||||||
|
if test "$tcg" = "yes" && test "$targetos" = "OpenBSD"; then
|
||||||
|
cat > $TMPC <<EOF
|
||||||
|
int main(void) { return 0; }
|
||||||
|
EOF
|
||||||
|
wx_ldflags="-Wl,-z,wxneeded"
|
||||||
|
if compile_prog "" "$wx_ldflags"; then
|
||||||
|
QEMU_LDFLAGS="$QEMU_LDFLAGS $wx_ldflags"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
qemu_confdir=$sysconfdir$confsuffix
|
qemu_confdir=$sysconfdir$confsuffix
|
||||||
qemu_moddir=$libdir$confsuffix
|
qemu_moddir=$libdir$confsuffix
|
||||||
qemu_datadir=$datadir$confsuffix
|
qemu_datadir=$datadir$confsuffix
|
||||||
|
|
|
@ -524,6 +524,12 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nt_start_addr) {
|
||||||
|
eprintf("Failed to find NT kernel image\n");
|
||||||
|
err = 1;
|
||||||
|
goto out_ps;
|
||||||
|
}
|
||||||
|
|
||||||
printf("KernBase = 0x%016"PRIx64", signature is \'%.2s\'\n", KernBase,
|
printf("KernBase = 0x%016"PRIx64", signature is \'%.2s\'\n", KernBase,
|
||||||
(char *)nt_start_addr);
|
(char *)nt_start_addr);
|
||||||
|
|
||||||
|
|
42
exec.c
42
exec.c
|
@ -1599,35 +1599,49 @@ static void register_multipage(FlatView *fv,
|
||||||
phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
|
phys_page_set(d, start_addr >> TARGET_PAGE_BITS, num_pages, section_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The range in *section* may look like this:
|
||||||
|
*
|
||||||
|
* |s|PPPPPPP|s|
|
||||||
|
*
|
||||||
|
* where s stands for subpage and P for page.
|
||||||
|
*/
|
||||||
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section)
|
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section)
|
||||||
{
|
{
|
||||||
MemoryRegionSection now = *section, remain = *section;
|
MemoryRegionSection remain = *section;
|
||||||
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
|
Int128 page_size = int128_make64(TARGET_PAGE_SIZE);
|
||||||
|
|
||||||
if (now.offset_within_address_space & ~TARGET_PAGE_MASK) {
|
/* register first subpage */
|
||||||
uint64_t left = TARGET_PAGE_ALIGN(now.offset_within_address_space)
|
if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
|
||||||
- now.offset_within_address_space;
|
uint64_t left = TARGET_PAGE_ALIGN(remain.offset_within_address_space)
|
||||||
|
- remain.offset_within_address_space;
|
||||||
|
|
||||||
|
MemoryRegionSection now = remain;
|
||||||
now.size = int128_min(int128_make64(left), now.size);
|
now.size = int128_min(int128_make64(left), now.size);
|
||||||
register_subpage(fv, &now);
|
register_subpage(fv, &now);
|
||||||
} else {
|
if (int128_eq(remain.size, now.size)) {
|
||||||
now.size = int128_zero();
|
return;
|
||||||
}
|
}
|
||||||
while (int128_ne(remain.size, now.size)) {
|
|
||||||
remain.size = int128_sub(remain.size, now.size);
|
remain.size = int128_sub(remain.size, now.size);
|
||||||
remain.offset_within_address_space += int128_get64(now.size);
|
remain.offset_within_address_space += int128_get64(now.size);
|
||||||
remain.offset_within_region += int128_get64(now.size);
|
remain.offset_within_region += int128_get64(now.size);
|
||||||
now = remain;
|
}
|
||||||
if (int128_lt(remain.size, page_size)) {
|
|
||||||
register_subpage(fv, &now);
|
/* register whole pages */
|
||||||
} else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
|
if (int128_ge(remain.size, page_size)) {
|
||||||
now.size = page_size;
|
MemoryRegionSection now = remain;
|
||||||
register_subpage(fv, &now);
|
|
||||||
} else {
|
|
||||||
now.size = int128_and(now.size, int128_neg(page_size));
|
now.size = int128_and(now.size, int128_neg(page_size));
|
||||||
register_multipage(fv, &now);
|
register_multipage(fv, &now);
|
||||||
|
if (int128_eq(remain.size, now.size)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
remain.size = int128_sub(remain.size, now.size);
|
||||||
|
remain.offset_within_address_space += int128_get64(now.size);
|
||||||
|
remain.offset_within_region += int128_get64(now.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* register last subpage */
|
||||||
|
register_subpage(fv, &remain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_flush_coalesced_mmio_buffer(void)
|
void qemu_flush_coalesced_mmio_buffer(void)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* QEMU emulation of AMD IOMMU (AMD-Vi)
|
* QEMU emulation of AMD IOMMU (AMD-Vi)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Eduard - Gabriel Munteanu
|
* Copyright (C) 2011 Eduard - Gabriel Munteanu
|
||||||
* Copyright (C) 2015 David Kiarie, <davidkiarie4@gmail.com>
|
* Copyright (C) 2015, 2016 David Kiarie Kahurani
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* QEMU emulation of an AMD IOMMU (AMD-Vi)
|
* QEMU emulation of an AMD IOMMU (AMD-Vi)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Eduard - Gabriel Munteanu
|
* Copyright (C) 2011 Eduard - Gabriel Munteanu
|
||||||
* Copyright (C) 2015 David Kiarie, <davidkiarie4@gmail.com>
|
* Copyright (C) 2015, 2016 David Kiarie Kahurani
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
18
hw/i386/pc.c
18
hw/i386/pc.c
|
@ -136,6 +136,7 @@ GlobalProperty pc_compat_3_1[] = {
|
||||||
{ "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" },
|
{ "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" },
|
||||||
{ "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
|
{ "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
|
||||||
{ "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" },
|
{ "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" },
|
||||||
|
{ TYPE_X86_CPU, "x-intel-pt-auto-level", "off" },
|
||||||
};
|
};
|
||||||
const size_t pc_compat_3_1_len = G_N_ELEMENTS(pc_compat_3_1);
|
const size_t pc_compat_3_1_len = G_N_ELEMENTS(pc_compat_3_1);
|
||||||
|
|
||||||
|
@ -1209,6 +1210,17 @@ static void load_linux(PCMachineState *pcms,
|
||||||
if (ldl_p(header+0x202) == 0x53726448) {
|
if (ldl_p(header+0x202) == 0x53726448) {
|
||||||
protocol = lduw_p(header+0x206);
|
protocol = lduw_p(header+0x206);
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
|
* This could be a multiboot kernel. If it is, let's stop treating it
|
||||||
|
* like a Linux kernel.
|
||||||
|
* Note: some multiboot images could be in the ELF format (the same of
|
||||||
|
* PVH), so we try multiboot first since we check the multiboot magic
|
||||||
|
* header before to load it.
|
||||||
|
*/
|
||||||
|
if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename,
|
||||||
|
kernel_cmdline, kernel_size, header)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Check if the file is an uncompressed kernel file (ELF) and load it,
|
* Check if the file is an uncompressed kernel file (ELF) and load it,
|
||||||
* saving the PVH entry point used by the x86/HVM direct boot ABI.
|
* saving the PVH entry point used by the x86/HVM direct boot ABI.
|
||||||
|
@ -1262,12 +1274,6 @@ static void load_linux(PCMachineState *pcms,
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* This looks like a multiboot kernel. If it is, let's stop
|
|
||||||
treating it like a Linux kernel. */
|
|
||||||
if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename,
|
|
||||||
kernel_cmdline, kernel_size, header)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
protocol = 0;
|
protocol = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,9 @@ config SPIKE
|
||||||
|
|
||||||
config RISCV_VIRT
|
config RISCV_VIRT
|
||||||
bool
|
bool
|
||||||
|
imply PCI_DEVICES
|
||||||
|
imply TEST_DEVICES
|
||||||
|
select PCI
|
||||||
select HART
|
select HART
|
||||||
select SERIAL
|
select SERIAL
|
||||||
select VIRTIO_MMIO
|
select VIRTIO_MMIO
|
||||||
|
|
|
@ -160,6 +160,11 @@ static const char *names[] = {
|
||||||
#define LSI_CCNTL1_DDAC 0x08
|
#define LSI_CCNTL1_DDAC 0x08
|
||||||
#define LSI_CCNTL1_ZMOD 0x80
|
#define LSI_CCNTL1_ZMOD 0x80
|
||||||
|
|
||||||
|
#define LSI_SBCL_ATN 0x08
|
||||||
|
#define LSI_SBCL_BSY 0x20
|
||||||
|
#define LSI_SBCL_ACK 0x40
|
||||||
|
#define LSI_SBCL_REQ 0x80
|
||||||
|
|
||||||
/* Enable Response to Reselection */
|
/* Enable Response to Reselection */
|
||||||
#define LSI_SCID_RRE 0x60
|
#define LSI_SCID_RRE 0x60
|
||||||
|
|
||||||
|
@ -189,6 +194,20 @@ typedef struct lsi_request {
|
||||||
QTAILQ_ENTRY(lsi_request) next;
|
QTAILQ_ENTRY(lsi_request) next;
|
||||||
} lsi_request;
|
} lsi_request;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LSI_NOWAIT, /* SCRIPTS are running or stopped */
|
||||||
|
LSI_WAIT_RESELECT, /* Wait Reselect instruction has been issued */
|
||||||
|
LSI_DMA_SCRIPTS, /* processing DMA from lsi_execute_script */
|
||||||
|
LSI_DMA_IN_PROGRESS, /* DMA operation is in progress */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LSI_MSG_ACTION_COMMAND = 0,
|
||||||
|
LSI_MSG_ACTION_DISCONNECT = 1,
|
||||||
|
LSI_MSG_ACTION_DOUT = 2,
|
||||||
|
LSI_MSG_ACTION_DIN = 3,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
PCIDevice parent_obj;
|
PCIDevice parent_obj;
|
||||||
|
@ -202,15 +221,9 @@ typedef struct {
|
||||||
|
|
||||||
int carry; /* ??? Should this be an a visible register somewhere? */
|
int carry; /* ??? Should this be an a visible register somewhere? */
|
||||||
int status;
|
int status;
|
||||||
/* Action to take at the end of a MSG IN phase.
|
|
||||||
0 = COMMAND, 1 = disconnect, 2 = DATA OUT, 3 = DATA IN. */
|
|
||||||
int msg_action;
|
int msg_action;
|
||||||
int msg_len;
|
int msg_len;
|
||||||
uint8_t msg[LSI_MAX_MSGIN_LEN];
|
uint8_t msg[LSI_MAX_MSGIN_LEN];
|
||||||
/* 0 if SCRIPTS are running or stopped.
|
|
||||||
* 1 if a Wait Reselect instruction has been issued.
|
|
||||||
* 2 if processing DMA from lsi_execute_script.
|
|
||||||
* 3 if a DMA operation is in progress. */
|
|
||||||
int waiting;
|
int waiting;
|
||||||
SCSIBus bus;
|
SCSIBus bus;
|
||||||
int current_lun;
|
int current_lun;
|
||||||
|
@ -258,6 +271,7 @@ typedef struct {
|
||||||
uint8_t sdid;
|
uint8_t sdid;
|
||||||
uint8_t ssid;
|
uint8_t ssid;
|
||||||
uint8_t sfbr;
|
uint8_t sfbr;
|
||||||
|
uint8_t sbcl;
|
||||||
uint8_t stest1;
|
uint8_t stest1;
|
||||||
uint8_t stest2;
|
uint8_t stest2;
|
||||||
uint8_t stest3;
|
uint8_t stest3;
|
||||||
|
@ -283,8 +297,7 @@ typedef struct {
|
||||||
uint8_t sbr;
|
uint8_t sbr;
|
||||||
uint32_t adder;
|
uint32_t adder;
|
||||||
|
|
||||||
/* Script ram is stored as 32-bit words in host byteorder. */
|
uint8_t script_ram[2048 * sizeof(uint32_t)];
|
||||||
uint32_t script_ram[2048];
|
|
||||||
} LSIState;
|
} LSIState;
|
||||||
|
|
||||||
#define TYPE_LSI53C810 "lsi53c810"
|
#define TYPE_LSI53C810 "lsi53c810"
|
||||||
|
@ -293,6 +306,22 @@ typedef struct {
|
||||||
#define LSI53C895A(obj) \
|
#define LSI53C895A(obj) \
|
||||||
OBJECT_CHECK(LSIState, (obj), TYPE_LSI53C895A)
|
OBJECT_CHECK(LSIState, (obj), TYPE_LSI53C895A)
|
||||||
|
|
||||||
|
static const char *scsi_phases[] = {
|
||||||
|
"DOUT",
|
||||||
|
"DIN",
|
||||||
|
"CMD",
|
||||||
|
"STATUS",
|
||||||
|
"RSVOUT",
|
||||||
|
"RSVIN",
|
||||||
|
"MSGOUT",
|
||||||
|
"MSGIN"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *scsi_phase_name(int phase)
|
||||||
|
{
|
||||||
|
return scsi_phases[phase & PHASE_MASK];
|
||||||
|
}
|
||||||
|
|
||||||
static inline int lsi_irq_on_rsl(LSIState *s)
|
static inline int lsi_irq_on_rsl(LSIState *s)
|
||||||
{
|
{
|
||||||
return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
|
return (s->sien0 & LSI_SIST0_RSL) && (s->scid & LSI_SCID_RRE);
|
||||||
|
@ -315,9 +344,9 @@ static void lsi_soft_reset(LSIState *s)
|
||||||
trace_lsi_reset();
|
trace_lsi_reset();
|
||||||
s->carry = 0;
|
s->carry = 0;
|
||||||
|
|
||||||
s->msg_action = 0;
|
s->msg_action = LSI_MSG_ACTION_COMMAND;
|
||||||
s->msg_len = 0;
|
s->msg_len = 0;
|
||||||
s->waiting = 0;
|
s->waiting = LSI_NOWAIT;
|
||||||
s->dsa = 0;
|
s->dsa = 0;
|
||||||
s->dnad = 0;
|
s->dnad = 0;
|
||||||
s->dbc = 0;
|
s->dbc = 0;
|
||||||
|
@ -356,6 +385,7 @@ static void lsi_soft_reset(LSIState *s)
|
||||||
s->socl = 0;
|
s->socl = 0;
|
||||||
s->sdid = 0;
|
s->sdid = 0;
|
||||||
s->ssid = 0;
|
s->ssid = 0;
|
||||||
|
s->sbcl = 0;
|
||||||
s->stest1 = 0;
|
s->stest1 = 0;
|
||||||
s->stest2 = 0;
|
s->stest2 = 0;
|
||||||
s->stest3 = 0;
|
s->stest3 = 0;
|
||||||
|
@ -530,6 +560,8 @@ static void lsi_script_dma_interrupt(LSIState *s, int stat)
|
||||||
|
|
||||||
static inline void lsi_set_phase(LSIState *s, int phase)
|
static inline void lsi_set_phase(LSIState *s, int phase)
|
||||||
{
|
{
|
||||||
|
s->sbcl &= ~PHASE_MASK;
|
||||||
|
s->sbcl |= phase | LSI_SBCL_REQ;
|
||||||
s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
|
s->sstat1 = (s->sstat1 & ~PHASE_MASK) | phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,10 +588,10 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase)
|
||||||
static void lsi_resume_script(LSIState *s)
|
static void lsi_resume_script(LSIState *s)
|
||||||
{
|
{
|
||||||
if (s->waiting != 2) {
|
if (s->waiting != 2) {
|
||||||
s->waiting = 0;
|
s->waiting = LSI_NOWAIT;
|
||||||
lsi_execute_script(s);
|
lsi_execute_script(s);
|
||||||
} else {
|
} else {
|
||||||
s->waiting = 0;
|
s->waiting = LSI_NOWAIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,6 +599,7 @@ static void lsi_disconnect(LSIState *s)
|
||||||
{
|
{
|
||||||
s->scntl1 &= ~LSI_SCNTL1_CON;
|
s->scntl1 &= ~LSI_SCNTL1_CON;
|
||||||
s->sstat1 &= ~PHASE_MASK;
|
s->sstat1 &= ~PHASE_MASK;
|
||||||
|
s->sbcl = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lsi_bad_selection(LSIState *s, uint32_t id)
|
static void lsi_bad_selection(LSIState *s, uint32_t id)
|
||||||
|
@ -674,7 +707,7 @@ static void lsi_reselect(LSIState *s, lsi_request *p)
|
||||||
trace_lsi_reselect(id);
|
trace_lsi_reselect(id);
|
||||||
s->scntl1 |= LSI_SCNTL1_CON;
|
s->scntl1 |= LSI_SCNTL1_CON;
|
||||||
lsi_set_phase(s, PHASE_MI);
|
lsi_set_phase(s, PHASE_MI);
|
||||||
s->msg_action = p->out ? 2 : 3;
|
s->msg_action = p->out ? LSI_MSG_ACTION_DOUT : LSI_MSG_ACTION_DIN;
|
||||||
s->current->dma_len = p->pending;
|
s->current->dma_len = p->pending;
|
||||||
lsi_add_msg_byte(s, 0x80);
|
lsi_add_msg_byte(s, 0x80);
|
||||||
if (s->current->tag & LSI_TAG_VALID) {
|
if (s->current->tag & LSI_TAG_VALID) {
|
||||||
|
@ -735,7 +768,7 @@ static int lsi_queue_req(LSIState *s, SCSIRequest *req, uint32_t len)
|
||||||
Since no interrupt stacking is implemented in the emulation, it
|
Since no interrupt stacking is implemented in the emulation, it
|
||||||
is also required that there are no pending interrupts waiting
|
is also required that there are no pending interrupts waiting
|
||||||
for service from the device driver. */
|
for service from the device driver. */
|
||||||
if (s->waiting == 1 ||
|
if (s->waiting == LSI_WAIT_RESELECT ||
|
||||||
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
|
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON) &&
|
||||||
!(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
|
!(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) {
|
||||||
/* Reselect device. */
|
/* Reselect device. */
|
||||||
|
@ -780,7 +813,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
|
||||||
int out;
|
int out;
|
||||||
|
|
||||||
assert(req->hba_private);
|
assert(req->hba_private);
|
||||||
if (s->waiting == 1 || req->hba_private != s->current ||
|
if (s->waiting == LSI_WAIT_RESELECT || req->hba_private != s->current ||
|
||||||
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
|
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
|
||||||
if (lsi_queue_req(s, req, len)) {
|
if (lsi_queue_req(s, req, len)) {
|
||||||
return;
|
return;
|
||||||
|
@ -794,7 +827,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
|
||||||
s->current->dma_len = len;
|
s->current->dma_len = len;
|
||||||
s->command_complete = 1;
|
s->command_complete = 1;
|
||||||
if (s->waiting) {
|
if (s->waiting) {
|
||||||
if (s->waiting == 1 || s->dbc == 0) {
|
if (s->waiting == LSI_WAIT_RESELECT || s->dbc == 0) {
|
||||||
lsi_resume_script(s);
|
lsi_resume_script(s);
|
||||||
} else {
|
} else {
|
||||||
lsi_do_dma(s, out);
|
lsi_do_dma(s, out);
|
||||||
|
@ -845,7 +878,7 @@ static void lsi_do_command(LSIState *s)
|
||||||
lsi_add_msg_byte(s, 4); /* DISCONNECT */
|
lsi_add_msg_byte(s, 4); /* DISCONNECT */
|
||||||
/* wait data */
|
/* wait data */
|
||||||
lsi_set_phase(s, PHASE_MI);
|
lsi_set_phase(s, PHASE_MI);
|
||||||
s->msg_action = 1;
|
s->msg_action = LSI_MSG_ACTION_DISCONNECT;
|
||||||
lsi_queue_command(s);
|
lsi_queue_command(s);
|
||||||
} else {
|
} else {
|
||||||
/* wait command complete */
|
/* wait command complete */
|
||||||
|
@ -866,7 +899,7 @@ static void lsi_do_status(LSIState *s)
|
||||||
s->sfbr = status;
|
s->sfbr = status;
|
||||||
pci_dma_write(PCI_DEVICE(s), s->dnad, &status, 1);
|
pci_dma_write(PCI_DEVICE(s), s->dnad, &status, 1);
|
||||||
lsi_set_phase(s, PHASE_MI);
|
lsi_set_phase(s, PHASE_MI);
|
||||||
s->msg_action = 1;
|
s->msg_action = LSI_MSG_ACTION_DISCONNECT;
|
||||||
lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
|
lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -889,16 +922,16 @@ static void lsi_do_msgin(LSIState *s)
|
||||||
/* ??? Check if ATN (not yet implemented) is asserted and maybe
|
/* ??? Check if ATN (not yet implemented) is asserted and maybe
|
||||||
switch to PHASE_MO. */
|
switch to PHASE_MO. */
|
||||||
switch (s->msg_action) {
|
switch (s->msg_action) {
|
||||||
case 0:
|
case LSI_MSG_ACTION_COMMAND:
|
||||||
lsi_set_phase(s, PHASE_CMD);
|
lsi_set_phase(s, PHASE_CMD);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case LSI_MSG_ACTION_DISCONNECT:
|
||||||
lsi_disconnect(s);
|
lsi_disconnect(s);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case LSI_MSG_ACTION_DOUT:
|
||||||
lsi_set_phase(s, PHASE_DO);
|
lsi_set_phase(s, PHASE_DO);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case LSI_MSG_ACTION_DIN:
|
||||||
lsi_set_phase(s, PHASE_DI);
|
lsi_set_phase(s, PHASE_DI);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1050,7 +1083,7 @@ bad:
|
||||||
qemu_log_mask(LOG_UNIMP, "Unimplemented message 0x%02x\n", msg);
|
qemu_log_mask(LOG_UNIMP, "Unimplemented message 0x%02x\n", msg);
|
||||||
lsi_set_phase(s, PHASE_MI);
|
lsi_set_phase(s, PHASE_MI);
|
||||||
lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */
|
lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */
|
||||||
s->msg_action = 0;
|
s->msg_action = LSI_MSG_ACTION_COMMAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LSI_BUF_SIZE 4096
|
#define LSI_BUF_SIZE 4096
|
||||||
|
@ -1084,7 +1117,7 @@ static void lsi_wait_reselect(LSIState *s)
|
||||||
lsi_reselect(s, p);
|
lsi_reselect(s, p);
|
||||||
}
|
}
|
||||||
if (s->current == NULL) {
|
if (s->current == NULL) {
|
||||||
s->waiting = 1;
|
s->waiting = LSI_WAIT_RESELECT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,8 +1217,9 @@ again:
|
||||||
s->ia = s->dsp - 12;
|
s->ia = s->dsp - 12;
|
||||||
}
|
}
|
||||||
if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
|
if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) {
|
||||||
trace_lsi_execute_script_blockmove_badphase(s->sstat1 & PHASE_MASK,
|
trace_lsi_execute_script_blockmove_badphase(
|
||||||
(insn >> 24) & 7);
|
scsi_phase_name(s->sstat1),
|
||||||
|
scsi_phase_name(insn >> 24));
|
||||||
lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
|
lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1193,16 +1227,16 @@ again:
|
||||||
s->dnad64 = addr_high;
|
s->dnad64 = addr_high;
|
||||||
switch (s->sstat1 & 0x7) {
|
switch (s->sstat1 & 0x7) {
|
||||||
case PHASE_DO:
|
case PHASE_DO:
|
||||||
s->waiting = 2;
|
s->waiting = LSI_DMA_SCRIPTS;
|
||||||
lsi_do_dma(s, 1);
|
lsi_do_dma(s, 1);
|
||||||
if (s->waiting)
|
if (s->waiting)
|
||||||
s->waiting = 3;
|
s->waiting = LSI_DMA_IN_PROGRESS;
|
||||||
break;
|
break;
|
||||||
case PHASE_DI:
|
case PHASE_DI:
|
||||||
s->waiting = 2;
|
s->waiting = LSI_DMA_SCRIPTS;
|
||||||
lsi_do_dma(s, 0);
|
lsi_do_dma(s, 0);
|
||||||
if (s->waiting)
|
if (s->waiting)
|
||||||
s->waiting = 3;
|
s->waiting = LSI_DMA_IN_PROGRESS;
|
||||||
break;
|
break;
|
||||||
case PHASE_CMD:
|
case PHASE_CMD:
|
||||||
lsi_do_command(s);
|
lsi_do_command(s);
|
||||||
|
@ -1217,8 +1251,8 @@ again:
|
||||||
lsi_do_msgin(s);
|
lsi_do_msgin(s);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %d\n",
|
qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %s\n",
|
||||||
s->sstat1 & PHASE_MASK);
|
scsi_phase_name(s->sstat1));
|
||||||
}
|
}
|
||||||
s->dfifo = s->dbc & 0xff;
|
s->dfifo = s->dbc & 0xff;
|
||||||
s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
|
s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3);
|
||||||
|
@ -1265,8 +1299,11 @@ again:
|
||||||
s->scntl1 |= LSI_SCNTL1_CON;
|
s->scntl1 |= LSI_SCNTL1_CON;
|
||||||
if (insn & (1 << 3)) {
|
if (insn & (1 << 3)) {
|
||||||
s->socl |= LSI_SOCL_ATN;
|
s->socl |= LSI_SOCL_ATN;
|
||||||
|
s->sbcl |= LSI_SBCL_ATN;
|
||||||
}
|
}
|
||||||
|
s->sbcl |= LSI_SBCL_BSY;
|
||||||
lsi_set_phase(s, PHASE_MO);
|
lsi_set_phase(s, PHASE_MO);
|
||||||
|
s->waiting = LSI_NOWAIT;
|
||||||
break;
|
break;
|
||||||
case 1: /* Disconnect */
|
case 1: /* Disconnect */
|
||||||
trace_lsi_execute_script_io_disconnect();
|
trace_lsi_execute_script_io_disconnect();
|
||||||
|
@ -1285,7 +1322,9 @@ again:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: /* Wait Reselect */
|
case 2: /* Wait Reselect */
|
||||||
if (!lsi_irq_on_rsl(s)) {
|
if (s->istat0 & LSI_ISTAT0_SIGP) {
|
||||||
|
s->dsp = s->dnad;
|
||||||
|
} else if (!lsi_irq_on_rsl(s)) {
|
||||||
lsi_wait_reselect(s);
|
lsi_wait_reselect(s);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1297,8 +1336,14 @@ again:
|
||||||
insn & (1 << 10) ? " CC" : "");
|
insn & (1 << 10) ? " CC" : "");
|
||||||
if (insn & (1 << 3)) {
|
if (insn & (1 << 3)) {
|
||||||
s->socl |= LSI_SOCL_ATN;
|
s->socl |= LSI_SOCL_ATN;
|
||||||
|
s->sbcl |= LSI_SBCL_ATN;
|
||||||
lsi_set_phase(s, PHASE_MO);
|
lsi_set_phase(s, PHASE_MO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (insn & (1 << 6)) {
|
||||||
|
s->sbcl |= LSI_SBCL_ACK;
|
||||||
|
}
|
||||||
|
|
||||||
if (insn & (1 << 9)) {
|
if (insn & (1 << 9)) {
|
||||||
qemu_log_mask(LOG_UNIMP,
|
qemu_log_mask(LOG_UNIMP,
|
||||||
"lsi_scsi: Target mode not implemented\n");
|
"lsi_scsi: Target mode not implemented\n");
|
||||||
|
@ -1314,7 +1359,13 @@ again:
|
||||||
insn & (1 << 10) ? " CC" : "");
|
insn & (1 << 10) ? " CC" : "");
|
||||||
if (insn & (1 << 3)) {
|
if (insn & (1 << 3)) {
|
||||||
s->socl &= ~LSI_SOCL_ATN;
|
s->socl &= ~LSI_SOCL_ATN;
|
||||||
|
s->sbcl &= ~LSI_SBCL_ATN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (insn & (1 << 6)) {
|
||||||
|
s->sbcl &= ~LSI_SBCL_ACK;
|
||||||
|
}
|
||||||
|
|
||||||
if (insn & (1 << 10))
|
if (insn & (1 << 10))
|
||||||
s->carry = 0;
|
s->carry = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -1429,10 +1480,8 @@ again:
|
||||||
cond = s->carry != 0;
|
cond = s->carry != 0;
|
||||||
}
|
}
|
||||||
if (cond == jmp && (insn & (1 << 17))) {
|
if (cond == jmp && (insn & (1 << 17))) {
|
||||||
trace_lsi_execute_script_tc_compp(
|
trace_lsi_execute_script_tc_compp(scsi_phase_name(s->sstat1),
|
||||||
(s->sstat1 & PHASE_MASK),
|
jmp ? '=' : '!', scsi_phase_name(insn >> 24));
|
||||||
jmp ? '=' : '!',
|
|
||||||
((insn >> 24) & 7));
|
|
||||||
cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
|
cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7);
|
||||||
}
|
}
|
||||||
if (cond == jmp && (insn & (1 << 18))) {
|
if (cond == jmp && (insn & (1 << 18))) {
|
||||||
|
@ -1519,7 +1568,7 @@ again:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (insn_processed > 10000 && !s->waiting) {
|
if (insn_processed > 10000 && s->waiting == LSI_NOWAIT) {
|
||||||
/* Some windows drivers make the device spin waiting for a memory
|
/* Some windows drivers make the device spin waiting for a memory
|
||||||
location to change. If we have been executed a lot of code then
|
location to change. If we have been executed a lot of code then
|
||||||
assume this is the case and force an unexpected device disconnect.
|
assume this is the case and force an unexpected device disconnect.
|
||||||
|
@ -1531,7 +1580,7 @@ again:
|
||||||
}
|
}
|
||||||
lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
|
lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
|
||||||
lsi_disconnect(s);
|
lsi_disconnect(s);
|
||||||
} else if (s->istat1 & LSI_ISTAT1_SRUN && !s->waiting) {
|
} else if (s->istat1 & LSI_ISTAT1_SRUN && s->waiting == LSI_NOWAIT) {
|
||||||
if (s->dcntl & LSI_DCNTL_SSM) {
|
if (s->dcntl & LSI_DCNTL_SSM) {
|
||||||
lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
|
lsi_script_dma_interrupt(s, LSI_DSTAT_SSI);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1591,9 +1640,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
|
||||||
ret = s->ssid;
|
ret = s->ssid;
|
||||||
break;
|
break;
|
||||||
case 0xb: /* SBCL */
|
case 0xb: /* SBCL */
|
||||||
/* ??? This is not correct. However it's (hopefully) only
|
ret = s->sbcl;
|
||||||
used for diagnostics, so should be ok. */
|
|
||||||
ret = 0;
|
|
||||||
break;
|
break;
|
||||||
case 0xc: /* DSTAT */
|
case 0xc: /* DSTAT */
|
||||||
ret = s->dstat | LSI_DSTAT_DFE;
|
ret = s->dstat | LSI_DSTAT_DFE;
|
||||||
|
@ -1641,7 +1688,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
|
||||||
break;
|
break;
|
||||||
CASE_GET_REG32(temp, 0x1c)
|
CASE_GET_REG32(temp, 0x1c)
|
||||||
case 0x20: /* DFIFO */
|
case 0x20: /* DFIFO */
|
||||||
ret = 0;
|
ret = s->dfifo;
|
||||||
break;
|
break;
|
||||||
case 0x21: /* CTEST4 */
|
case 0x21: /* CTEST4 */
|
||||||
ret = s->ctest4;
|
ret = s->ctest4;
|
||||||
|
@ -1864,9 +1911,9 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
|
||||||
s->istat0 &= ~LSI_ISTAT0_INTF;
|
s->istat0 &= ~LSI_ISTAT0_INTF;
|
||||||
lsi_update_irq(s);
|
lsi_update_irq(s);
|
||||||
}
|
}
|
||||||
if (s->waiting == 1 && val & LSI_ISTAT0_SIGP) {
|
if (s->waiting == LSI_WAIT_RESELECT && val & LSI_ISTAT0_SIGP) {
|
||||||
trace_lsi_awoken();
|
trace_lsi_awoken();
|
||||||
s->waiting = 0;
|
s->waiting = LSI_NOWAIT;
|
||||||
s->dsp = s->dnad;
|
s->dsp = s->dnad;
|
||||||
lsi_execute_script(s);
|
lsi_execute_script(s);
|
||||||
}
|
}
|
||||||
|
@ -2037,14 +2084,13 @@ static uint64_t lsi_mmio_read(void *opaque, hwaddr addr,
|
||||||
unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
LSIState *s = opaque;
|
LSIState *s = opaque;
|
||||||
|
|
||||||
return lsi_reg_readb(s, addr & 0xff);
|
return lsi_reg_readb(s, addr & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps lsi_mmio_ops = {
|
static const MemoryRegionOps lsi_mmio_ops = {
|
||||||
.read = lsi_mmio_read,
|
.read = lsi_mmio_read,
|
||||||
.write = lsi_mmio_write,
|
.write = lsi_mmio_write,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
.impl = {
|
.impl = {
|
||||||
.min_access_size = 1,
|
.min_access_size = 1,
|
||||||
.max_access_size = 1,
|
.max_access_size = 1,
|
||||||
|
@ -2055,35 +2101,20 @@ static void lsi_ram_write(void *opaque, hwaddr addr,
|
||||||
uint64_t val, unsigned size)
|
uint64_t val, unsigned size)
|
||||||
{
|
{
|
||||||
LSIState *s = opaque;
|
LSIState *s = opaque;
|
||||||
uint32_t newval;
|
stn_le_p(s->script_ram + addr, size, val);
|
||||||
uint32_t mask;
|
|
||||||
int shift;
|
|
||||||
|
|
||||||
newval = s->script_ram[addr >> 2];
|
|
||||||
shift = (addr & 3) * 8;
|
|
||||||
mask = ((uint64_t)1 << (size * 8)) - 1;
|
|
||||||
newval &= ~(mask << shift);
|
|
||||||
newval |= val << shift;
|
|
||||||
s->script_ram[addr >> 2] = newval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
|
static uint64_t lsi_ram_read(void *opaque, hwaddr addr,
|
||||||
unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
LSIState *s = opaque;
|
LSIState *s = opaque;
|
||||||
uint32_t val;
|
return ldn_le_p(s->script_ram + addr, size);
|
||||||
uint32_t mask;
|
|
||||||
|
|
||||||
val = s->script_ram[addr >> 2];
|
|
||||||
mask = ((uint64_t)1 << (size * 8)) - 1;
|
|
||||||
val >>= (addr & 3) * 8;
|
|
||||||
return val & mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const MemoryRegionOps lsi_ram_ops = {
|
static const MemoryRegionOps lsi_ram_ops = {
|
||||||
.read = lsi_ram_read,
|
.read = lsi_ram_read,
|
||||||
.write = lsi_ram_write,
|
.write = lsi_ram_write,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint64_t lsi_io_read(void *opaque, hwaddr addr,
|
static uint64_t lsi_io_read(void *opaque, hwaddr addr,
|
||||||
|
@ -2103,7 +2134,7 @@ static void lsi_io_write(void *opaque, hwaddr addr,
|
||||||
static const MemoryRegionOps lsi_io_ops = {
|
static const MemoryRegionOps lsi_io_ops = {
|
||||||
.read = lsi_io_read,
|
.read = lsi_io_read,
|
||||||
.write = lsi_io_write,
|
.write = lsi_io_write,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
.impl = {
|
.impl = {
|
||||||
.min_access_size = 1,
|
.min_access_size = 1,
|
||||||
.max_access_size = 1,
|
.max_access_size = 1,
|
||||||
|
@ -2143,7 +2174,7 @@ static int lsi_post_load(void *opaque, int version_id)
|
||||||
|
|
||||||
static const VMStateDescription vmstate_lsi_scsi = {
|
static const VMStateDescription vmstate_lsi_scsi = {
|
||||||
.name = "lsiscsi",
|
.name = "lsiscsi",
|
||||||
.version_id = 0,
|
.version_id = 1,
|
||||||
.minimum_version_id = 0,
|
.minimum_version_id = 0,
|
||||||
.pre_save = lsi_pre_save,
|
.pre_save = lsi_pre_save,
|
||||||
.post_load = lsi_post_load,
|
.post_load = lsi_post_load,
|
||||||
|
@ -2202,6 +2233,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
|
||||||
VMSTATE_UINT8(stime0, LSIState),
|
VMSTATE_UINT8(stime0, LSIState),
|
||||||
VMSTATE_UINT8(respid0, LSIState),
|
VMSTATE_UINT8(respid0, LSIState),
|
||||||
VMSTATE_UINT8(respid1, LSIState),
|
VMSTATE_UINT8(respid1, LSIState),
|
||||||
|
VMSTATE_UINT8_V(sbcl, LSIState, 1),
|
||||||
VMSTATE_UINT32(mmrs, LSIState),
|
VMSTATE_UINT32(mmrs, LSIState),
|
||||||
VMSTATE_UINT32(mmws, LSIState),
|
VMSTATE_UINT32(mmws, LSIState),
|
||||||
VMSTATE_UINT32(sfs, LSIState),
|
VMSTATE_UINT32(sfs, LSIState),
|
||||||
|
@ -2219,7 +2251,7 @@ static const VMStateDescription vmstate_lsi_scsi = {
|
||||||
VMSTATE_BUFFER_UNSAFE(scratch, LSIState, 0, 18 * sizeof(uint32_t)),
|
VMSTATE_BUFFER_UNSAFE(scratch, LSIState, 0, 18 * sizeof(uint32_t)),
|
||||||
VMSTATE_UINT8(sbr, LSIState),
|
VMSTATE_UINT8(sbr, LSIState),
|
||||||
|
|
||||||
VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 2048 * sizeof(uint32_t)),
|
VMSTATE_BUFFER_UNSAFE(script_ram, LSIState, 0, 8192),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -296,22 +296,15 @@ static void scsi_dma_complete(void *opaque, int ret)
|
||||||
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scsi_read_complete(void * opaque, int ret)
|
static void scsi_read_complete_noio(SCSIDiskReq *r, int ret)
|
||||||
{
|
{
|
||||||
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
uint32_t n;
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
|
||||||
int n;
|
|
||||||
|
|
||||||
assert(r->req.aiocb != NULL);
|
assert(r->req.aiocb == NULL);
|
||||||
r->req.aiocb = NULL;
|
if (scsi_disk_req_check_error(r, ret, false)) {
|
||||||
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
|
||||||
if (scsi_disk_req_check_error(r, ret, true)) {
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
|
||||||
trace_scsi_disk_read_complete(r->req.tag, r->qiov.size);
|
|
||||||
|
|
||||||
n = r->qiov.size / 512;
|
n = r->qiov.size / 512;
|
||||||
r->sector += n;
|
r->sector += n;
|
||||||
r->sector_count -= n;
|
r->sector_count -= n;
|
||||||
|
@ -319,6 +312,24 @@ static void scsi_read_complete(void * opaque, int ret)
|
||||||
|
|
||||||
done:
|
done:
|
||||||
scsi_req_unref(&r->req);
|
scsi_req_unref(&r->req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scsi_read_complete(void *opaque, int ret)
|
||||||
|
{
|
||||||
|
SCSIDiskReq *r = (SCSIDiskReq *)opaque;
|
||||||
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
|
||||||
|
|
||||||
|
assert(r->req.aiocb != NULL);
|
||||||
|
r->req.aiocb = NULL;
|
||||||
|
|
||||||
|
aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
|
if (ret < 0) {
|
||||||
|
block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
|
} else {
|
||||||
|
block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct);
|
||||||
|
trace_scsi_disk_read_complete(r->req.tag, r->qiov.size);
|
||||||
|
}
|
||||||
|
scsi_read_complete_noio(r, ret);
|
||||||
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
aio_context_release(blk_get_aio_context(s->qdev.conf.blk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,12 +406,12 @@ static void scsi_read_data(SCSIRequest *req)
|
||||||
scsi_req_ref(&r->req);
|
scsi_req_ref(&r->req);
|
||||||
if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
|
if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
|
||||||
trace_scsi_disk_read_data_invalid();
|
trace_scsi_disk_read_data_invalid();
|
||||||
scsi_read_complete(r, -EINVAL);
|
scsi_read_complete_noio(r, -EINVAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!blk_is_available(req->dev->conf.blk)) {
|
if (!blk_is_available(req->dev->conf.blk)) {
|
||||||
scsi_read_complete(r, -ENOMEDIUM);
|
scsi_read_complete_noio(r, -ENOMEDIUM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,7 +268,7 @@ lsi_memcpy(uint32_t dest, uint32_t src, int count) "memcpy dest 0x%"PRIx32" src
|
||||||
lsi_wait_reselect(void) "Wait Reselect"
|
lsi_wait_reselect(void) "Wait Reselect"
|
||||||
lsi_execute_script(uint32_t dsp, uint32_t insn, uint32_t addr) "SCRIPTS dsp=0x%"PRIx32" opcode 0x%"PRIx32" arg 0x%"PRIx32
|
lsi_execute_script(uint32_t dsp, uint32_t insn, uint32_t addr) "SCRIPTS dsp=0x%"PRIx32" opcode 0x%"PRIx32" arg 0x%"PRIx32
|
||||||
lsi_execute_script_blockmove_delayed(void) "Delayed select timeout"
|
lsi_execute_script_blockmove_delayed(void) "Delayed select timeout"
|
||||||
lsi_execute_script_blockmove_badphase(uint8_t phase, uint8_t expected) "Wrong phase got %d expected %d"
|
lsi_execute_script_blockmove_badphase(const char *phase, const char *expected) "Wrong phase got %s expected %s"
|
||||||
lsi_execute_script_io_alreadyreselected(void) "Already reselected, jumping to alternative address"
|
lsi_execute_script_io_alreadyreselected(void) "Already reselected, jumping to alternative address"
|
||||||
lsi_execute_script_io_selected(uint8_t id, const char *atn) "Selected target %d%s"
|
lsi_execute_script_io_selected(uint8_t id, const char *atn) "Selected target %d%s"
|
||||||
lsi_execute_script_io_disconnect(void) "Wait Disconnect"
|
lsi_execute_script_io_disconnect(void) "Wait Disconnect"
|
||||||
|
@ -278,8 +278,8 @@ lsi_execute_script_io_opcode(const char *opcode, int reg, const char *opname, ui
|
||||||
lsi_execute_script_tc_nop(void) "NOP"
|
lsi_execute_script_tc_nop(void) "NOP"
|
||||||
lsi_execute_script_tc_delayedselect_timeout(void) "Delayed select timeout"
|
lsi_execute_script_tc_delayedselect_timeout(void) "Delayed select timeout"
|
||||||
lsi_execute_script_tc_compc(int result) "Compare carry %d"
|
lsi_execute_script_tc_compc(int result) "Compare carry %d"
|
||||||
lsi_execute_script_tc_compp(uint8_t phase, int op, uint8_t insn_phase) "Compare phase %d %c= %d"
|
lsi_execute_script_tc_compp(const char *phase, char op, const char *insn_phase) "Compare phase %s %c= %s"
|
||||||
lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, int op, int result) "Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
|
lsi_execute_script_tc_compd(uint32_t sfbr, uint8_t mask, char op, int result) "Compare data 0x%"PRIx32" & 0x%x %c= 0x%x"
|
||||||
lsi_execute_script_tc_jump(uint32_t addr) "Jump to 0x%"PRIx32
|
lsi_execute_script_tc_jump(uint32_t addr) "Jump to 0x%"PRIx32
|
||||||
lsi_execute_script_tc_call(uint32_t addr) "Call 0x%"PRIx32
|
lsi_execute_script_tc_call(uint32_t addr) "Call 0x%"PRIx32
|
||||||
lsi_execute_script_tc_return(uint32_t addr) "Return to 0x%"PRIx32
|
lsi_execute_script_tc_return(uint32_t addr) "Return to 0x%"PRIx32
|
||||||
|
|
|
@ -262,7 +262,13 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req)
|
||||||
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
|
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */
|
||||||
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
|
req->resp.tmf.response = VIRTIO_SCSI_S_OK;
|
||||||
|
|
||||||
virtio_tswap32s(VIRTIO_DEVICE(s), &req->req.tmf.subtype);
|
/*
|
||||||
|
* req->req.tmf has the QEMU_PACKED attribute. Don't use virtio_tswap32s()
|
||||||
|
* to avoid compiler errors.
|
||||||
|
*/
|
||||||
|
req->req.tmf.subtype =
|
||||||
|
virtio_tswap32(VIRTIO_DEVICE(s), req->req.tmf.subtype);
|
||||||
|
|
||||||
switch (req->req.tmf.subtype) {
|
switch (req->req.tmf.subtype) {
|
||||||
case VIRTIO_SCSI_T_TMF_ABORT_TASK:
|
case VIRTIO_SCSI_T_TMF_ABORT_TASK:
|
||||||
case VIRTIO_SCSI_T_TMF_QUERY_TASK:
|
case VIRTIO_SCSI_T_TMF_QUERY_TASK:
|
||||||
|
|
|
@ -4,8 +4,9 @@ config VFIO
|
||||||
|
|
||||||
config VFIO_PCI
|
config VFIO_PCI
|
||||||
bool
|
bool
|
||||||
|
default y
|
||||||
select VFIO
|
select VFIO
|
||||||
depends on LINUX
|
depends on LINUX && PCI
|
||||||
|
|
||||||
config VFIO_CCW
|
config VFIO_CCW
|
||||||
bool
|
bool
|
||||||
|
|
5
memory.c
5
memory.c
|
@ -932,9 +932,7 @@ static void address_space_update_topology_pass(AddressSpace *as,
|
||||||
} else if (frold && frnew && flatrange_equal(frold, frnew)) {
|
} else if (frold && frnew && flatrange_equal(frold, frnew)) {
|
||||||
/* In both and unchanged (except logging may have changed) */
|
/* In both and unchanged (except logging may have changed) */
|
||||||
|
|
||||||
if (!adding) {
|
if (adding) {
|
||||||
flat_range_coalesced_io_del(frold, as);
|
|
||||||
} else {
|
|
||||||
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
|
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
|
||||||
if (frnew->dirty_log_mask & ~frold->dirty_log_mask) {
|
if (frnew->dirty_log_mask & ~frold->dirty_log_mask) {
|
||||||
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start,
|
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start,
|
||||||
|
@ -946,7 +944,6 @@ static void address_space_update_topology_pass(AddressSpace *as,
|
||||||
frold->dirty_log_mask,
|
frold->dirty_log_mask,
|
||||||
frnew->dirty_log_mask);
|
frnew->dirty_log_mask);
|
||||||
}
|
}
|
||||||
flat_range_coalesced_io_add(frnew, as);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++iold;
|
++iold;
|
||||||
|
|
|
@ -248,6 +248,11 @@
|
||||||
# @addr: socket address to listen on (server=true)
|
# @addr: socket address to listen on (server=true)
|
||||||
# or connect to (server=false)
|
# or connect to (server=false)
|
||||||
# @tls-creds: the ID of the TLS credentials object (since 2.6)
|
# @tls-creds: the ID of the TLS credentials object (since 2.6)
|
||||||
|
# @tls-authz: the ID of the QAuthZ authorization object against which
|
||||||
|
# the client's x509 distinguished name will be validated. This
|
||||||
|
# object is only resolved at time of use, so can be deleted
|
||||||
|
# and recreated on the fly while the chardev server is active.
|
||||||
|
# If missing, it will default to denying access (since 4.0)
|
||||||
# @server: create server socket (default: true)
|
# @server: create server socket (default: true)
|
||||||
# @wait: wait for incoming connection on server
|
# @wait: wait for incoming connection on server
|
||||||
# sockets (default: false).
|
# sockets (default: false).
|
||||||
|
@ -268,6 +273,7 @@
|
||||||
{ 'struct': 'ChardevSocket',
|
{ 'struct': 'ChardevSocket',
|
||||||
'data': { 'addr': 'SocketAddressLegacy',
|
'data': { 'addr': 'SocketAddressLegacy',
|
||||||
'*tls-creds': 'str',
|
'*tls-creds': 'str',
|
||||||
|
'*tls-authz' : 'str',
|
||||||
'*server': 'bool',
|
'*server': 'bool',
|
||||||
'*wait': 'bool',
|
'*wait': 'bool',
|
||||||
'*nodelay': 'bool',
|
'*nodelay': 'bool',
|
||||||
|
|
|
@ -2428,7 +2428,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
|
||||||
"-chardev null,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
|
"-chardev null,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
|
||||||
"-chardev socket,id=id[,host=host],port=port[,to=to][,ipv4][,ipv6][,nodelay][,reconnect=seconds]\n"
|
"-chardev socket,id=id[,host=host],port=port[,to=to][,ipv4][,ipv6][,nodelay][,reconnect=seconds]\n"
|
||||||
" [,server][,nowait][,telnet][,websocket][,reconnect=seconds][,mux=on|off]\n"
|
" [,server][,nowait][,telnet][,websocket][,reconnect=seconds][,mux=on|off]\n"
|
||||||
" [,logfile=PATH][,logappend=on|off][,tls-creds=ID] (tcp)\n"
|
" [,logfile=PATH][,logappend=on|off][,tls-creds=ID][,tls-authz=ID] (tcp)\n"
|
||||||
"-chardev socket,id=id,path=path[,server][,nowait][,telnet][,websocket][,reconnect=seconds]\n"
|
"-chardev socket,id=id,path=path[,server][,nowait][,telnet][,websocket][,reconnect=seconds]\n"
|
||||||
" [,mux=on|off][,logfile=PATH][,logappend=on|off] (unix)\n"
|
" [,mux=on|off][,logfile=PATH][,logappend=on|off] (unix)\n"
|
||||||
"-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr]\n"
|
"-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr]\n"
|
||||||
|
@ -2557,7 +2557,7 @@ The available backends are:
|
||||||
A void device. This device will not emit any data, and will drop any data it
|
A void device. This device will not emit any data, and will drop any data it
|
||||||
receives. The null backend does not take any options.
|
receives. The null backend does not take any options.
|
||||||
|
|
||||||
@item -chardev socket,id=@var{id}[,@var{TCP options} or @var{unix options}][,server][,nowait][,telnet][,websocket][,reconnect=@var{seconds}][,tls-creds=@var{id}]
|
@item -chardev socket,id=@var{id}[,@var{TCP options} or @var{unix options}][,server][,nowait][,telnet][,websocket][,reconnect=@var{seconds}][,tls-creds=@var{id}][,tls-authz=@var{id}]
|
||||||
|
|
||||||
Create a two-way stream socket, which can be either a TCP or a unix socket. A
|
Create a two-way stream socket, which can be either a TCP or a unix socket. A
|
||||||
unix socket will be created if @option{path} is specified. Behaviour is
|
unix socket will be created if @option{path} is specified. Behaviour is
|
||||||
|
@ -2583,6 +2583,12 @@ and specifies the id of the TLS credentials to use for the handshake. The
|
||||||
credentials must be previously created with the @option{-object tls-creds}
|
credentials must be previously created with the @option{-object tls-creds}
|
||||||
argument.
|
argument.
|
||||||
|
|
||||||
|
@option{tls-auth} provides the ID of the QAuthZ authorization object against
|
||||||
|
which the client's x509 distinguished name will be validated. This object is
|
||||||
|
only resolved at time of use, so can be deleted and recreated on the fly
|
||||||
|
while the chardev server is active. If missing, it will default to denying
|
||||||
|
access.
|
||||||
|
|
||||||
TCP and unix socket options are given below:
|
TCP and unix socket options are given below:
|
||||||
|
|
||||||
@table @option
|
@table @option
|
||||||
|
|
|
@ -380,6 +380,9 @@ static void cpu_common_initfn(Object *obj)
|
||||||
|
|
||||||
static void cpu_common_finalize(Object *obj)
|
static void cpu_common_finalize(Object *obj)
|
||||||
{
|
{
|
||||||
|
CPUState *cpu = CPU(obj);
|
||||||
|
|
||||||
|
qemu_mutex_destroy(&cpu->work_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t cpu_common_get_arch_id(CPUState *cpu)
|
static int64_t cpu_common_get_arch_id(CPUState *cpu)
|
||||||
|
|
|
@ -7,11 +7,8 @@
|
||||||
# Authors:
|
# Authors:
|
||||||
# Avi Kivity <avi@redhat.com>
|
# Avi Kivity <avi@redhat.com>
|
||||||
#
|
#
|
||||||
# This work is licensed under the terms of the GNU GPL, version 2. See
|
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||||
# the COPYING file in the top-level directory.
|
# later. See the COPYING file in the top-level directory.
|
||||||
#
|
|
||||||
# Contributions after 2012-01-13 are licensed under the terms of the
|
|
||||||
# GNU GPL, version 2 or (at your option) any later version.
|
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
# At the (gdb) prompt, type "source scripts/qemu-gdb.py".
|
# At the (gdb) prompt, type "source scripts/qemu-gdb.py".
|
||||||
|
|
|
@ -7,11 +7,8 @@
|
||||||
# Authors:
|
# Authors:
|
||||||
# Avi Kivity <avi@redhat.com>
|
# Avi Kivity <avi@redhat.com>
|
||||||
#
|
#
|
||||||
# This work is licensed under the terms of the GNU GPL, version 2. See
|
# This work is licensed under the terms of the GNU GPL, version 2
|
||||||
# the COPYING file in the top-level directory.
|
# or later. See the COPYING file in the top-level directory.
|
||||||
#
|
|
||||||
# Contributions after 2012-01-13 are licensed under the terms of the
|
|
||||||
# GNU GPL, version 2 or (at your option) any later version.
|
|
||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,8 @@
|
||||||
# Authors:
|
# Authors:
|
||||||
# Avi Kivity <avi@redhat.com>
|
# Avi Kivity <avi@redhat.com>
|
||||||
#
|
#
|
||||||
# This work is licensed under the terms of the GNU GPL, version 2. See
|
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||||
# the COPYING file in the top-level directory.
|
# later. See the COPYING file in the top-level directory.
|
||||||
#
|
|
||||||
# Contributions after 2012-01-13 are licensed under the terms of the
|
|
||||||
# GNU GPL, version 2 or (at your option) any later version.
|
|
||||||
|
|
||||||
# 'qemu mtree' -- display the memory hierarchy
|
# 'qemu mtree' -- display the memory hierarchy
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,8 @@
|
||||||
# Authors:
|
# Authors:
|
||||||
# Alex Bennée <alex.bennee@linaro.org>
|
# Alex Bennée <alex.bennee@linaro.org>
|
||||||
#
|
#
|
||||||
# This work is licensed under the terms of the GNU GPL, version 2. See
|
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||||
# the COPYING file in the top-level directory.
|
# later. See the COPYING file in the top-level directory.
|
||||||
#
|
|
||||||
# Contributions after 2012-01-13 are licensed under the terms of the
|
|
||||||
# GNU GPL, version 2 or (at your option) any later version.
|
|
||||||
|
|
||||||
# 'qemu tcg-lock-status' -- display the TCG lock status across threads
|
# 'qemu tcg-lock-status' -- display the TCG lock status across threads
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ obj-$(CONFIG_TCG) += translate.o
|
||||||
obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
|
obj-$(CONFIG_TCG) += bpt_helper.o cc_helper.o excp_helper.o fpu_helper.o
|
||||||
obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
|
obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o
|
||||||
obj-$(CONFIG_TCG) += seg_helper.o smm_helper.o svm_helper.o
|
obj-$(CONFIG_TCG) += seg_helper.o smm_helper.o svm_helper.o
|
||||||
|
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
||||||
ifeq ($(CONFIG_SOFTMMU),y)
|
ifeq ($(CONFIG_SOFTMMU),y)
|
||||||
obj-y += machine.o arch_memory_mapping.o arch_dump.o monitor.o
|
obj-y += machine.o arch_memory_mapping.o arch_dump.o monitor.o
|
||||||
obj-$(CONFIG_KVM) += kvm.o
|
obj-$(CONFIG_KVM) += kvm.o
|
||||||
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
|
||||||
obj-$(CONFIG_HYPERV) += hyperv.o
|
obj-$(CONFIG_HYPERV) += hyperv.o
|
||||||
obj-$(call lnot,$(CONFIG_HYPERV)) += hyperv-stub.o
|
obj-$(call lnot,$(CONFIG_HYPERV)) += hyperv-stub.o
|
||||||
ifeq ($(CONFIG_WIN32),y)
|
ifeq ($(CONFIG_WIN32),y)
|
||||||
|
|
|
@ -5031,6 +5031,13 @@ static void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
|
||||||
x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
|
x86_cpu_adjust_feat_level(cpu, FEAT_C000_0001_EDX);
|
||||||
x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
|
x86_cpu_adjust_feat_level(cpu, FEAT_SVM);
|
||||||
x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
|
x86_cpu_adjust_feat_level(cpu, FEAT_XSAVE);
|
||||||
|
|
||||||
|
/* Intel Processor Trace requires CPUID[0x14] */
|
||||||
|
if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT) &&
|
||||||
|
kvm_enabled() && cpu->intel_pt_auto_level) {
|
||||||
|
x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
|
||||||
|
}
|
||||||
|
|
||||||
/* SVM requires CPUID[0x8000000A] */
|
/* SVM requires CPUID[0x8000000A] */
|
||||||
if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
|
if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
|
||||||
x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
|
x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
|
||||||
|
@ -5824,6 +5831,8 @@ static Property x86_cpu_properties[] = {
|
||||||
DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
|
DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
|
||||||
DEFINE_PROP_BOOL("x-hv-synic-kvm-only", X86CPU, hyperv_synic_kvm_only,
|
DEFINE_PROP_BOOL("x-hv-synic-kvm-only", X86CPU, hyperv_synic_kvm_only,
|
||||||
false),
|
false),
|
||||||
|
DEFINE_PROP_BOOL("x-intel-pt-auto-level", X86CPU, intel_pt_auto_level,
|
||||||
|
true),
|
||||||
DEFINE_PROP_END_OF_LIST()
|
DEFINE_PROP_END_OF_LIST()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1454,6 +1454,9 @@ struct X86CPU {
|
||||||
/* Enable auto level-increase for all CPUID leaves */
|
/* Enable auto level-increase for all CPUID leaves */
|
||||||
bool full_cpuid_auto_level;
|
bool full_cpuid_auto_level;
|
||||||
|
|
||||||
|
/* Enable auto level-increase for Intel Processor Trace leave */
|
||||||
|
bool intel_pt_auto_level;
|
||||||
|
|
||||||
/* if true fill the top bits of the MTRR_PHYSMASKn variable range */
|
/* if true fill the top bits of the MTRR_PHYSMASKn variable range */
|
||||||
bool fill_mtrr_mask;
|
bool fill_mtrr_mask;
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ static void check_driver(const char *driver)
|
||||||
static void check_test(const char *test, const char *interface)
|
static void check_test(const char *test, const char *interface)
|
||||||
{
|
{
|
||||||
QOSGraphEdge *edge;
|
QOSGraphEdge *edge;
|
||||||
const char *full_name = g_strdup_printf("%s-tests/%s", interface, test);
|
char *full_name = g_strdup_printf("%s-tests/%s", interface, test);
|
||||||
|
|
||||||
qos_add_test(test, interface, testfunct, NULL);
|
qos_add_test(test, interface, testfunct, NULL);
|
||||||
g_assert_cmpint(qos_graph_has_machine(test), ==, FALSE);
|
g_assert_cmpint(qos_graph_has_machine(test), ==, FALSE);
|
||||||
|
@ -138,6 +138,7 @@ static void check_test(const char *test, const char *interface)
|
||||||
g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, TRUE);
|
g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, TRUE);
|
||||||
qos_graph_node_set_availability(full_name, FALSE);
|
qos_graph_node_set_availability(full_name, FALSE);
|
||||||
g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, FALSE);
|
g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, FALSE);
|
||||||
|
g_free(full_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void count_each_test(QOSGraphNode *path, int len)
|
static void count_each_test(QOSGraphNode *path, int len)
|
||||||
|
|
|
@ -36,7 +36,7 @@ $(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf
|
||||||
|
|
||||||
$(obj)/generated-helpers.o: $(obj)/generated-helpers.c
|
$(obj)/generated-helpers.o: $(obj)/generated-helpers.c
|
||||||
|
|
||||||
target-obj-y += generated-helpers.o
|
obj-y += generated-helpers.o
|
||||||
|
|
||||||
|
|
||||||
$(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
|
$(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
|
||||||
|
@ -55,5 +55,5 @@ $(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/
|
||||||
util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
|
util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
|
||||||
util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
|
util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
|
||||||
util-obj-y += control.o
|
util-obj-y += control.o
|
||||||
target-obj-y += control-target.o
|
obj-y += control-target.o
|
||||||
util-obj-y += qmp.o
|
util-obj-y += qmp.o
|
||||||
|
|
|
@ -244,7 +244,19 @@ void qemu_set_nonblock(int fd)
|
||||||
f = fcntl(fd, F_GETFL);
|
f = fcntl(fd, F_GETFL);
|
||||||
assert(f != -1);
|
assert(f != -1);
|
||||||
f = fcntl(fd, F_SETFL, f | O_NONBLOCK);
|
f = fcntl(fd, F_SETFL, f | O_NONBLOCK);
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
if (f == -1) {
|
||||||
|
/*
|
||||||
|
* Previous to OpenBSD 6.3, fcntl(F_SETFL) is not permitted on
|
||||||
|
* memory devices and sets errno to ENODEV.
|
||||||
|
* It's OK if we fail to set O_NONBLOCK on devices like /dev/null,
|
||||||
|
* because they will never block anyway.
|
||||||
|
*/
|
||||||
|
assert(errno == ENODEV);
|
||||||
|
}
|
||||||
|
#else
|
||||||
assert(f != -1);
|
assert(f != -1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int socket_set_fast_reuse(int fd)
|
int socket_set_fast_reuse(int fd)
|
||||||
|
|
Loading…
Reference in a new issue