diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-03-11 18:26:37 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-03-11 18:26:37 +0000 |
commit | 377b155bde451d5ac545fbdcdfbf6ca17a4228f5 (patch) | |
tree | bb2acb6d1d3faae019898cadbcac17ec3b964a2f | |
parent | c8761809385db04513b87af321c5feec82475421 (diff) | |
parent | 328eb60dc1a19448b36eb63901ca0b8f87ed6f57 (diff) |
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>
-rw-r--r-- | Makefile.objs | 3 | ||||
-rw-r--r-- | Makefile.target | 11 | ||||
-rw-r--r-- | accel/accel.c | 4 | ||||
-rw-r--r-- | block/iscsi.c | 7 | ||||
-rw-r--r-- | chardev/char-socket.c | 12 | ||||
-rw-r--r-- | chardev/char.c | 3 | ||||
-rwxr-xr-x | configure | 13 | ||||
-rw-r--r-- | contrib/elf2dmp/main.c | 6 | ||||
-rw-r--r-- | exec.c | 48 | ||||
-rw-r--r-- | hw/i386/amd_iommu.c | 2 | ||||
-rw-r--r-- | hw/i386/amd_iommu.h | 2 | ||||
-rw-r--r-- | hw/i386/pc.c | 18 | ||||
-rw-r--r-- | hw/riscv/Kconfig | 3 | ||||
-rw-r--r-- | hw/scsi/lsi53c895a.c | 170 | ||||
-rw-r--r-- | hw/scsi/scsi-disk.c | 37 | ||||
-rw-r--r-- | hw/scsi/trace-events | 6 | ||||
-rw-r--r-- | hw/scsi/virtio-scsi.c | 8 | ||||
-rw-r--r-- | hw/vfio/Kconfig | 3 | ||||
-rw-r--r-- | memory.c | 5 | ||||
-rw-r--r-- | qapi/char.json | 6 | ||||
-rw-r--r-- | qemu-options.hx | 10 | ||||
-rw-r--r-- | qom/cpu.c | 3 | ||||
-rw-r--r-- | scripts/qemu-gdb.py | 7 | ||||
-rw-r--r-- | scripts/qemugdb/coroutine.py | 7 | ||||
-rw-r--r-- | scripts/qemugdb/mtree.py | 7 | ||||
-rw-r--r-- | scripts/qemugdb/tcg.py | 7 | ||||
-rw-r--r-- | target/i386/Makefile.objs | 2 | ||||
-rw-r--r-- | target/i386/cpu.c | 9 | ||||
-rw-r--r-- | target/i386/cpu.h | 3 | ||||
-rw-r--r-- | tests/test-qgraph.c | 3 | ||||
-rw-r--r-- | trace/Makefile.objs | 4 | ||||
-rw-r--r-- | util/oslib-posix.c | 12 |
32 files changed, 286 insertions, 155 deletions
diff --git a/Makefile.objs b/Makefile.objs index ef65a6c12e..31a84b7d41 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -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 += nbd/ +block-obj-y = nbd/ block-obj-y += block.o blockjob.o job.o block-obj-y += block/ scsi/ block-obj-y += qemu-io-cmds.o @@ -101,7 +101,6 @@ version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o ###################################################################### # tracing util-obj-y += trace/ -target-obj-y += trace/ ###################################################################### # guest agent diff --git a/Makefile.target b/Makefile.target index 40830c5646..d8048aab8f 100644 --- a/Makefile.target +++ b/Makefile.target @@ -105,6 +105,8 @@ all: $(PROGS) stap # Dummy command so that make thinks it has done something @true +obj-y += trace/ + ######################################################### # cpu emulator library obj-y += exec.o @@ -173,13 +175,7 @@ endif # CONFIG_SOFTMMU dummy := $(call unnest-vars,,obj-y) all-obj-y := $(obj-y) -target-obj-y := -block-obj-y := -common-obj-y := -chardev-obj-y := include $(SRC_PATH)/Makefile.objs -dummy := $(call unnest-vars,,target-obj-y) -target-obj-y-save := $(target-obj-y) dummy := $(call unnest-vars,.., \ authz-obj-y \ block-obj-y \ @@ -191,9 +187,7 @@ dummy := $(call unnest-vars,.., \ io-obj-y \ common-obj-y \ common-obj-m) -target-obj-y := $(target-obj-y-save) all-obj-y += $(common-obj-y) -all-obj-y += $(target-obj-y) all-obj-y += $(qom-obj-y) all-obj-$(CONFIG_SOFTMMU) += $(authz-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 $(shell find . -name '*.[od]') rm -f hmp-commands.h gdbstub-xml.c + rm -f trace/generated-helpers.c trace/generated-helpers.c-timestamp ifdef CONFIG_TRACE_SYSTEMTAP rm -f *.stp endif diff --git a/accel/accel.c b/accel/accel.c index 68b6d56323..0d5b370dfd 100644 --- a/accel/accel.c +++ b/accel/accel.c @@ -91,7 +91,9 @@ void configure_accelerator(MachineState *ms, const char *progname) #elif defined(CONFIG_KVM) accel = "kvm"; #else -#error "No default accelerator available" + error_report("No accelerator selected and" + " no default accelerator available"); + exit(1); #endif } } diff --git a/block/iscsi.c b/block/iscsi.c index a0c0084837..f31c612d53 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -145,6 +145,8 @@ static const unsigned iscsi_retry_times[] = {8, 32, 128, 512, 2048, 8192, 32768} * unallocated. */ #define ISCSI_CHECKALLOC_THRES 64 +#ifdef __linux__ + static void iscsi_bh_cb(void *p) { @@ -172,6 +174,8 @@ iscsi_schedule_bh(IscsiAIOCB *acb) qemu_bh_schedule(acb->bh); } +#endif + static void iscsi_co_generic_bh_cb(void *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. */ static void 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, }; +#endif static void iscsi_process_read(void *arg); static void iscsi_process_write(void *arg); diff --git a/chardev/char-socket.c b/chardev/char-socket.c index 6d287babfb..3916505d67 100644 --- a/chardev/char-socket.c +++ b/chardev/char-socket.c @@ -59,6 +59,7 @@ typedef struct { QIONetListener *listener; GSource *hup_source; QCryptoTLSCreds *tls_creds; + char *tls_authz; TCPChardevState state; int max_size; int do_telnetopt; @@ -807,7 +808,7 @@ static void tcp_chr_tls_init(Chardev *chr) if (s->is_listen) { tioc = qio_channel_tls_new_server( s->ioc, s->tls_creds, - NULL, /* XXX Use an ACL */ + s->tls_authz, &err); } else { tioc = qio_channel_tls_new_client( @@ -1055,6 +1056,7 @@ static void char_socket_finalize(Object *obj) if (s->tls_creds) { object_unref(OBJECT(s->tls_creds)); } + g_free(s->tls_authz); qemu_chr_be_event(chr, CHR_EVENT_CLOSED); } @@ -1242,6 +1244,11 @@ static bool qmp_chardev_validate_socket(ChardevSocket *sock, 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 */ if (!sock->has_server || sock->server) { 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); @@ -1399,6 +1407,8 @@ static void qemu_chr_parse_socket(QemuOpts *opts, ChardevBackend *backend, sock->reconnect = qemu_opt_get_number(opts, "reconnect", 0); sock->has_tls_creds = 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); if (path) { diff --git a/chardev/char.c b/chardev/char.c index f6d61fa5f8..514cd6b0c3 100644 --- a/chardev/char.c +++ b/chardev/char.c @@ -881,6 +881,9 @@ QemuOptsList qemu_chardev_opts = { .name = "tls-creds", .type = QEMU_OPT_STRING, },{ + .name = "tls-authz", + .type = QEMU_OPT_STRING, + },{ .name = "websocket", .type = QEMU_OPT_BOOL, },{ @@ -1836,7 +1836,7 @@ fi # Consult white-list to determine whether to enable werror # by default. Only enable by default for git builds if test -z "$werror" ; then - if test -d "$source_path/.git" && \ + if test -e "$source_path/.git" && \ { test "$linux" = "yes" || test "$mingw32" = "yes"; }; then werror="yes" else @@ -5903,6 +5903,17 @@ if test "$mingw32" = "yes" ; then done 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_moddir=$libdir$confsuffix qemu_datadir=$datadir$confsuffix diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c index 1a45eaf565..1bfeb89ba7 100644 --- a/contrib/elf2dmp/main.c +++ b/contrib/elf2dmp/main.c @@ -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, (char *)nt_start_addr); @@ -1599,35 +1599,49 @@ static void register_multipage(FlatView *fv, 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) { - MemoryRegionSection now = *section, remain = *section; + MemoryRegionSection remain = *section; Int128 page_size = int128_make64(TARGET_PAGE_SIZE); - if (now.offset_within_address_space & ~TARGET_PAGE_MASK) { - uint64_t left = TARGET_PAGE_ALIGN(now.offset_within_address_space) - - now.offset_within_address_space; + /* register first subpage */ + if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) { + 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); register_subpage(fv, &now); - } else { - now.size = int128_zero(); - } - while (int128_ne(remain.size, now.size)) { + 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); - now = remain; - if (int128_lt(remain.size, page_size)) { - register_subpage(fv, &now); - } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) { - now.size = page_size; - register_subpage(fv, &now); - } else { - now.size = int128_and(now.size, int128_neg(page_size)); - register_multipage(fv, &now); + } + + /* register whole pages */ + if (int128_ge(remain.size, page_size)) { + MemoryRegionSection now = remain; + now.size = int128_and(now.size, int128_neg(page_size)); + 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) diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 8ad707aba0..6eabdf9917 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -2,7 +2,7 @@ * QEMU emulation of AMD IOMMU (AMD-Vi) * * 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 * it under the terms of the GNU General Public License as published by diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index c52886f3ed..0ff9095f32 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -2,7 +2,7 @@ * QEMU emulation of an AMD IOMMU (AMD-Vi) * * 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 * it under the terms of the GNU General Public License as published by diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 42128183e9..c6d047b42b 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -136,6 +136,7 @@ GlobalProperty pc_compat_3_1[] = { { "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" }, { "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" }, { "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); @@ -1210,6 +1211,17 @@ static void load_linux(PCMachineState *pcms, protocol = lduw_p(header+0x206); } 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, * saving the PVH entry point used by the x86/HVM direct boot ABI. * If load_elfboot() is successful, populate the fw_cfg info. @@ -1262,12 +1274,6 @@ static void load_linux(PCMachineState *pcms, 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; } diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index e0ee3043a6..8c7fc1f31d 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -26,6 +26,9 @@ config SPIKE config RISCV_VIRT bool + imply PCI_DEVICES + imply TEST_DEVICES + select PCI select HART select SERIAL select VIRTIO_MMIO diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 89def1421f..da7239d94f 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -160,6 +160,11 @@ static const char *names[] = { #define LSI_CCNTL1_DDAC 0x08 #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 */ #define LSI_SCID_RRE 0x60 @@ -189,6 +194,20 @@ typedef struct lsi_request { QTAILQ_ENTRY(lsi_request) next; } 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 { /*< private >*/ PCIDevice parent_obj; @@ -202,15 +221,9 @@ typedef struct { int carry; /* ??? Should this be an a visible register somewhere? */ 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_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; SCSIBus bus; int current_lun; @@ -258,6 +271,7 @@ typedef struct { uint8_t sdid; uint8_t ssid; uint8_t sfbr; + uint8_t sbcl; uint8_t stest1; uint8_t stest2; uint8_t stest3; @@ -283,8 +297,7 @@ typedef struct { uint8_t sbr; uint32_t adder; - /* Script ram is stored as 32-bit words in host byteorder. */ - uint32_t script_ram[2048]; + uint8_t script_ram[2048 * sizeof(uint32_t)]; } LSIState; #define TYPE_LSI53C810 "lsi53c810" @@ -293,6 +306,22 @@ typedef struct { #define LSI53C895A(obj) \ 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) { 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(); s->carry = 0; - s->msg_action = 0; + s->msg_action = LSI_MSG_ACTION_COMMAND; s->msg_len = 0; - s->waiting = 0; + s->waiting = LSI_NOWAIT; s->dsa = 0; s->dnad = 0; s->dbc = 0; @@ -356,6 +385,7 @@ static void lsi_soft_reset(LSIState *s) s->socl = 0; s->sdid = 0; s->ssid = 0; + s->sbcl = 0; s->stest1 = 0; s->stest2 = 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) { + s->sbcl &= ~PHASE_MASK; + s->sbcl |= phase | LSI_SBCL_REQ; 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) { if (s->waiting != 2) { - s->waiting = 0; + s->waiting = LSI_NOWAIT; lsi_execute_script(s); } else { - s->waiting = 0; + s->waiting = LSI_NOWAIT; } } @@ -567,6 +599,7 @@ static void lsi_disconnect(LSIState *s) { s->scntl1 &= ~LSI_SCNTL1_CON; s->sstat1 &= ~PHASE_MASK; + s->sbcl = 0; } 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); s->scntl1 |= LSI_SCNTL1_CON; 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; lsi_add_msg_byte(s, 0x80); 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 is also required that there are no pending interrupts waiting 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) && !(s->istat0 & (LSI_ISTAT0_SIP | LSI_ISTAT0_DIP)))) { /* Reselect device. */ @@ -780,7 +813,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len) int out; 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))) { if (lsi_queue_req(s, req, len)) { return; @@ -794,7 +827,7 @@ static void lsi_transfer_data(SCSIRequest *req, uint32_t len) s->current->dma_len = len; s->command_complete = 1; if (s->waiting) { - if (s->waiting == 1 || s->dbc == 0) { + if (s->waiting == LSI_WAIT_RESELECT || s->dbc == 0) { lsi_resume_script(s); } else { lsi_do_dma(s, out); @@ -845,7 +878,7 @@ static void lsi_do_command(LSIState *s) lsi_add_msg_byte(s, 4); /* DISCONNECT */ /* wait data */ lsi_set_phase(s, PHASE_MI); - s->msg_action = 1; + s->msg_action = LSI_MSG_ACTION_DISCONNECT; lsi_queue_command(s); } else { /* wait command complete */ @@ -866,7 +899,7 @@ static void lsi_do_status(LSIState *s) s->sfbr = status; pci_dma_write(PCI_DEVICE(s), s->dnad, &status, 1); 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 */ } @@ -889,16 +922,16 @@ static void lsi_do_msgin(LSIState *s) /* ??? Check if ATN (not yet implemented) is asserted and maybe switch to PHASE_MO. */ switch (s->msg_action) { - case 0: + case LSI_MSG_ACTION_COMMAND: lsi_set_phase(s, PHASE_CMD); break; - case 1: + case LSI_MSG_ACTION_DISCONNECT: lsi_disconnect(s); break; - case 2: + case LSI_MSG_ACTION_DOUT: lsi_set_phase(s, PHASE_DO); break; - case 3: + case LSI_MSG_ACTION_DIN: lsi_set_phase(s, PHASE_DI); break; default: @@ -1050,7 +1083,7 @@ bad: qemu_log_mask(LOG_UNIMP, "Unimplemented message 0x%02x\n", msg); lsi_set_phase(s, PHASE_MI); lsi_add_msg_byte(s, 7); /* MESSAGE REJECT */ - s->msg_action = 0; + s->msg_action = LSI_MSG_ACTION_COMMAND; } #define LSI_BUF_SIZE 4096 @@ -1084,7 +1117,7 @@ static void lsi_wait_reselect(LSIState *s) lsi_reselect(s, p); } if (s->current == NULL) { - s->waiting = 1; + s->waiting = LSI_WAIT_RESELECT; } } @@ -1184,8 +1217,9 @@ again: s->ia = s->dsp - 12; } if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) { - trace_lsi_execute_script_blockmove_badphase(s->sstat1 & PHASE_MASK, - (insn >> 24) & 7); + trace_lsi_execute_script_blockmove_badphase( + scsi_phase_name(s->sstat1), + scsi_phase_name(insn >> 24)); lsi_script_scsi_interrupt(s, LSI_SIST0_MA, 0); break; } @@ -1193,16 +1227,16 @@ again: s->dnad64 = addr_high; switch (s->sstat1 & 0x7) { case PHASE_DO: - s->waiting = 2; + s->waiting = LSI_DMA_SCRIPTS; lsi_do_dma(s, 1); if (s->waiting) - s->waiting = 3; + s->waiting = LSI_DMA_IN_PROGRESS; break; case PHASE_DI: - s->waiting = 2; + s->waiting = LSI_DMA_SCRIPTS; lsi_do_dma(s, 0); if (s->waiting) - s->waiting = 3; + s->waiting = LSI_DMA_IN_PROGRESS; break; case PHASE_CMD: lsi_do_command(s); @@ -1217,8 +1251,8 @@ again: lsi_do_msgin(s); break; default: - qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %d\n", - s->sstat1 & PHASE_MASK); + qemu_log_mask(LOG_UNIMP, "lsi_scsi: Unimplemented phase %s\n", + scsi_phase_name(s->sstat1)); } s->dfifo = s->dbc & 0xff; s->ctest5 = (s->ctest5 & 0xfc) | ((s->dbc >> 8) & 3); @@ -1265,8 +1299,11 @@ again: s->scntl1 |= LSI_SCNTL1_CON; if (insn & (1 << 3)) { s->socl |= LSI_SOCL_ATN; + s->sbcl |= LSI_SBCL_ATN; } + s->sbcl |= LSI_SBCL_BSY; lsi_set_phase(s, PHASE_MO); + s->waiting = LSI_NOWAIT; break; case 1: /* Disconnect */ trace_lsi_execute_script_io_disconnect(); @@ -1285,8 +1322,10 @@ again: } break; case 2: /* Wait Reselect */ - if (!lsi_irq_on_rsl(s)) { - lsi_wait_reselect(s); + if (s->istat0 & LSI_ISTAT0_SIGP) { + s->dsp = s->dnad; + } else if (!lsi_irq_on_rsl(s)) { + lsi_wait_reselect(s); } break; case 3: /* Set */ @@ -1297,8 +1336,14 @@ again: insn & (1 << 10) ? " CC" : ""); if (insn & (1 << 3)) { s->socl |= LSI_SOCL_ATN; + s->sbcl |= LSI_SBCL_ATN; lsi_set_phase(s, PHASE_MO); } + + if (insn & (1 << 6)) { + s->sbcl |= LSI_SBCL_ACK; + } + if (insn & (1 << 9)) { qemu_log_mask(LOG_UNIMP, "lsi_scsi: Target mode not implemented\n"); @@ -1314,7 +1359,13 @@ again: insn & (1 << 10) ? " CC" : ""); if (insn & (1 << 3)) { s->socl &= ~LSI_SOCL_ATN; + s->sbcl &= ~LSI_SBCL_ATN; + } + + if (insn & (1 << 6)) { + s->sbcl &= ~LSI_SBCL_ACK; } + if (insn & (1 << 10)) s->carry = 0; break; @@ -1429,10 +1480,8 @@ again: cond = s->carry != 0; } if (cond == jmp && (insn & (1 << 17))) { - trace_lsi_execute_script_tc_compp( - (s->sstat1 & PHASE_MASK), - jmp ? '=' : '!', - ((insn >> 24) & 7)); + trace_lsi_execute_script_tc_compp(scsi_phase_name(s->sstat1), + jmp ? '=' : '!', scsi_phase_name(insn >> 24)); cond = (s->sstat1 & PHASE_MASK) == ((insn >> 24) & 7); } 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 location to change. If we have been executed a lot of code then 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_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) { lsi_script_dma_interrupt(s, LSI_DSTAT_SSI); } else { @@ -1591,9 +1640,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) ret = s->ssid; break; case 0xb: /* SBCL */ - /* ??? This is not correct. However it's (hopefully) only - used for diagnostics, so should be ok. */ - ret = 0; + ret = s->sbcl; break; case 0xc: /* DSTAT */ ret = s->dstat | LSI_DSTAT_DFE; @@ -1641,7 +1688,7 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) break; CASE_GET_REG32(temp, 0x1c) case 0x20: /* DFIFO */ - ret = 0; + ret = s->dfifo; break; case 0x21: /* 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; 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(); - s->waiting = 0; + s->waiting = LSI_NOWAIT; s->dsp = s->dnad; lsi_execute_script(s); } @@ -2037,14 +2084,13 @@ static uint64_t lsi_mmio_read(void *opaque, hwaddr addr, unsigned size) { LSIState *s = opaque; - return lsi_reg_readb(s, addr & 0xff); } static const MemoryRegionOps lsi_mmio_ops = { .read = lsi_mmio_read, .write = lsi_mmio_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, .impl = { .min_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) { LSIState *s = opaque; - uint32_t newval; - 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; + stn_le_p(s->script_ram + addr, size, val); } static uint64_t lsi_ram_read(void *opaque, hwaddr addr, unsigned size) { LSIState *s = opaque; - uint32_t val; - uint32_t mask; - - val = s->script_ram[addr >> 2]; - mask = ((uint64_t)1 << (size * 8)) - 1; - val >>= (addr & 3) * 8; - return val & mask; + return ldn_le_p(s->script_ram + addr, size); } static const MemoryRegionOps lsi_ram_ops = { .read = lsi_ram_read, .write = lsi_ram_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; 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 = { .read = lsi_io_read, .write = lsi_io_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, .impl = { .min_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 = { .name = "lsiscsi", - .version_id = 0, + .version_id = 1, .minimum_version_id = 0, .pre_save = lsi_pre_save, .post_load = lsi_post_load, @@ -2202,6 +2233,7 @@ static const VMStateDescription vmstate_lsi_scsi = { VMSTATE_UINT8(stime0, LSIState), VMSTATE_UINT8(respid0, LSIState), VMSTATE_UINT8(respid1, LSIState), + VMSTATE_UINT8_V(sbcl, LSIState, 1), VMSTATE_UINT32(mmrs, LSIState), VMSTATE_UINT32(mmws, 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_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() } }; diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index d4e83aef0e..e7e865ab3b 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -296,22 +296,15 @@ static void scsi_dma_complete(void *opaque, int ret) 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; - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - int n; + uint32_t n; - assert(r->req.aiocb != NULL); - r->req.aiocb = NULL; - aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); - if (scsi_disk_req_check_error(r, ret, true)) { + assert(r->req.aiocb == NULL); + if (scsi_disk_req_check_error(r, ret, false)) { 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; r->sector += n; r->sector_count -= n; @@ -319,6 +312,24 @@ static void scsi_read_complete(void * opaque, int ret) done: 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)); } @@ -395,12 +406,12 @@ static void scsi_read_data(SCSIRequest *req) scsi_req_ref(&r->req); if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { trace_scsi_disk_read_data_invalid(); - scsi_read_complete(r, -EINVAL); + scsi_read_complete_noio(r, -EINVAL); return; } if (!blk_is_available(req->dev->conf.blk)) { - scsi_read_complete(r, -ENOMEDIUM); + scsi_read_complete_noio(r, -ENOMEDIUM); return; } diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events index 29aaa752d1..09f3fc3086 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -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_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_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_selected(uint8_t id, const char *atn) "Selected target %d%s" 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_delayedselect_timeout(void) "Delayed select timeout" 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_compd(uint32_t sfbr, uint8_t mask, int op, int result) "Compare data 0x%"PRIx32" & 0x%x %c= 0x%x" +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, 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_call(uint32_t addr) "Call 0x%"PRIx32 lsi_execute_script_tc_return(uint32_t addr) "Return to 0x%"PRIx32 diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index ce99d288b0..839f120256 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -262,7 +262,13 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */ 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) { case VIRTIO_SCSI_T_TMF_ABORT_TASK: case VIRTIO_SCSI_T_TMF_QUERY_TASK: diff --git a/hw/vfio/Kconfig b/hw/vfio/Kconfig index ebda9fdf22..34da2a3cfd 100644 --- a/hw/vfio/Kconfig +++ b/hw/vfio/Kconfig @@ -4,8 +4,9 @@ config VFIO config VFIO_PCI bool + default y select VFIO - depends on LINUX + depends on LINUX && PCI config VFIO_CCW bool @@ -932,9 +932,7 @@ static void address_space_update_topology_pass(AddressSpace *as, } else if (frold && frnew && flatrange_equal(frold, frnew)) { /* In both and unchanged (except logging may have changed) */ - if (!adding) { - flat_range_coalesced_io_del(frold, as); - } else { + if (adding) { MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop); if (frnew->dirty_log_mask & ~frold->dirty_log_mask) { 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, frnew->dirty_log_mask); } - flat_range_coalesced_io_add(frnew, as); } ++iold; diff --git a/qapi/char.json b/qapi/char.json index 77ed847972..a6e81ac7bc 100644 --- a/qapi/char.json +++ b/qapi/char.json @@ -248,6 +248,11 @@ # @addr: socket address to listen on (server=true) # or connect to (server=false) # @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) # @wait: wait for incoming connection on server # sockets (default: false). @@ -268,6 +273,7 @@ { 'struct': 'ChardevSocket', 'data': { 'addr': 'SocketAddressLegacy', '*tls-creds': 'str', + '*tls-authz' : 'str', '*server': 'bool', '*wait': 'bool', '*nodelay': 'bool', diff --git a/qemu-options.hx b/qemu-options.hx index c74f99b265..7118d90352 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -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 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" - " [,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" " [,mux=on|off][,logfile=PATH][,logappend=on|off] (unix)\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 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 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} 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: @table @option @@ -380,6 +380,9 @@ static void cpu_common_initfn(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) diff --git a/scripts/qemu-gdb.py b/scripts/qemu-gdb.py index 690827e6fc..f2a305c42e 100644 --- a/scripts/qemu-gdb.py +++ b/scripts/qemu-gdb.py @@ -7,11 +7,8 @@ # Authors: # Avi Kivity <avi@redhat.com> # -# This work is licensed under the terms of the GNU GPL, version 2. 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. +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. # Usage: # At the (gdb) prompt, type "source scripts/qemu-gdb.py". diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py index 81f811ac00..41e079d0e2 100644 --- a/scripts/qemugdb/coroutine.py +++ b/scripts/qemugdb/coroutine.py @@ -7,11 +7,8 @@ # Authors: # Avi Kivity <avi@redhat.com> # -# This work is licensed under the terms of the GNU GPL, version 2. 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. +# This work is licensed under the terms of the GNU GPL, version 2 +# or later. See the COPYING file in the top-level directory. import gdb diff --git a/scripts/qemugdb/mtree.py b/scripts/qemugdb/mtree.py index e6791b7885..3030a60d3f 100644 --- a/scripts/qemugdb/mtree.py +++ b/scripts/qemugdb/mtree.py @@ -7,11 +7,8 @@ # Authors: # Avi Kivity <avi@redhat.com> # -# This work is licensed under the terms of the GNU GPL, version 2. 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. +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. # 'qemu mtree' -- display the memory hierarchy diff --git a/scripts/qemugdb/tcg.py b/scripts/qemugdb/tcg.py index 8c7f1d7454..18880fc9a7 100644 --- a/scripts/qemugdb/tcg.py +++ b/scripts/qemugdb/tcg.py @@ -8,11 +8,8 @@ # Authors: # Alex Bennée <alex.bennee@linaro.org> # -# This work is licensed under the terms of the GNU GPL, version 2. 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. +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. # 'qemu tcg-lock-status' -- display the TCG lock status across threads diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs index cb9c265525..48e0c28434 100644 --- a/target/i386/Makefile.objs +++ b/target/i386/Makefile.objs @@ -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) += 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-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o ifeq ($(CONFIG_SOFTMMU),y) obj-y += machine.o arch_memory_mapping.o arch_dump.o monitor.o obj-$(CONFIG_KVM) += kvm.o -obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o obj-$(CONFIG_HYPERV) += hyperv.o obj-$(call lnot,$(CONFIG_HYPERV)) += hyperv-stub.o ifeq ($(CONFIG_WIN32),y) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index d3aa6a815b..d90c01a059 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -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_SVM); 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] */ if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { 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_BOOL("x-hv-synic-kvm-only", X86CPU, hyperv_synic_kvm_only, false), + DEFINE_PROP_BOOL("x-intel-pt-auto-level", X86CPU, intel_pt_auto_level, + true), DEFINE_PROP_END_OF_LIST() }; diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 95112b9118..83fb522554 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1454,6 +1454,9 @@ struct X86CPU { /* Enable auto level-increase for all CPUID leaves */ 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 */ bool fill_mtrr_mask; diff --git a/tests/test-qgraph.c b/tests/test-qgraph.c index f6a6565e31..5c7e457075 100644 --- a/tests/test-qgraph.c +++ b/tests/test-qgraph.c @@ -122,7 +122,7 @@ static void check_driver(const char *driver) static void check_test(const char *test, const char *interface) { 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); 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); qos_graph_node_set_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) diff --git a/trace/Makefile.objs b/trace/Makefile.objs index afd571c3ec..c544509adf 100644 --- a/trace/Makefile.objs +++ b/trace/Makefile.objs @@ -36,7 +36,7 @@ $(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf $(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 @@ -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_FTRACE) += ftrace.o util-obj-y += control.o -target-obj-y += control-target.o +obj-y += control-target.o util-obj-y += qmp.o diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 37c5854b9c..326d92dcd2 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -244,7 +244,19 @@ void qemu_set_nonblock(int fd) f = fcntl(fd, F_GETFL); assert(f != -1); 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); +#endif } int socket_set_fast_reuse(int fd) |