From 6411dd13349a6430dcefec7b96986ad0b8c6e7ff Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Mon, 11 Jan 2016 18:30:36 +0100 Subject: [PATCH 01/13] trace: drop trailing empty strings Also fix a typo in the virtio_balloon_handle_output() trace while here. [The double-quoting was a limitation of the old tracetool.sh script. The modern tracetool.py script does not require double-quotes at the end of the line. See commit cf85cf8e972f3ad79f203be4edb7968d6e052293 ("trace: Format strings must begin/end with double quotes"). --Stefan] Signed-off-by: Greg Kurz Reviewed-by: Eric Blake Reviewed-by: Markus Armbruster Message-id: 20160111173036.24764.59878.stgit@bahia.huguette.org Signed-off-by: Stefan Hajnoczi --- trace-events | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/trace-events b/trace-events index deb4d808bd..d57e1c344a 100644 --- a/trace-events +++ b/trace-events @@ -143,7 +143,7 @@ cpu_out(unsigned int addr, char size, unsigned int val) "addr %#x(%c) value %u" # balloon.c # Since requests are raised via monitor, not many tracepoints are needed. balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu" -virtio_balloon_handle_output(const char *name, uint64_t gpa) "setion name: %s gpa: %"PRIx64"" +virtio_balloon_handle_output(const char *name, uint64_t gpa) "section name: %s gpa: %"PRIx64 virtio_balloon_get_config(uint32_t num_pages, uint32_t acutal) "num_pages: %d acutal: %d" virtio_balloon_set_config(uint32_t acutal, uint32_t oldacutal) "acutal: %d oldacutal: %d" virtio_balloon_to_target(uint64_t target, uint32_t num_pages) "balloon target: %"PRIx64" num_pages: %d" @@ -683,7 +683,7 @@ grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" valu # hw/char/grlib_apbuart.c grlib_apbuart_event(int event) "event:%d" grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x" -grlib_apbuart_readl_unknown(uint64_t addr) "addr 0x%"PRIx64"" +grlib_apbuart_readl_unknown(uint64_t addr) "addr 0x%"PRIx64 # hw/sparc/leon3.c leon3_set_irq(int intno) "Set CPU IRQ %d" @@ -748,10 +748,10 @@ mptsas_config_sas_phy(void *dev, int address, int port, int phy_handle, int dev_ megasas_init_firmware(uint64_t pa) "pa %" PRIx64 " " megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at %" PRIx64 " len %d head %" PRIx64 " tail %" PRIx64 " flags %x" megasas_initq_map_failed(int frame) "scmd %d: failed to map queue" -megasas_initq_mapped(uint64_t pa) "queue already mapped at %" PRIx64 "" +megasas_initq_mapped(uint64_t pa) "queue already mapped at %" PRIx64 megasas_initq_mismatch(int queue_len, int fw_cmds) "queue size %d max fw cmds %d" megasas_qf_mapped(unsigned int index) "skip mapped frame %x" -megasas_qf_new(unsigned int index, uint64_t frame) "frame %x addr %" PRIx64 "" +megasas_qf_new(unsigned int index, uint64_t frame) "frame %x addr %" PRIx64 megasas_qf_busy(unsigned long pa) "all frames busy for frame %lx" megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t context, unsigned int head, unsigned int tail, int busy) "frame %x count %d context %" PRIx64 " head %x tail %x busy %d" megasas_qf_update(unsigned int head, unsigned int tail, unsigned int busy) "head %x tail %x busy %d" @@ -805,7 +805,7 @@ megasas_dcmd_pd_list_query(int cmd, int flags) "scmd %d: query flags %x" megasas_dcmd_reset_ld(int cmd, int target_id) "scmd %d: dev %d" megasas_dcmd_unsupported(int cmd, unsigned long size) "scmd %d: set properties len %ld" megasas_abort_frame(int cmd, int abort_cmd) "scmd %d: frame %x" -megasas_abort_no_cmd(int cmd, uint64_t context) "scmd %d: no active command for frame context %" PRIx64 "" +megasas_abort_no_cmd(int cmd, uint64_t context) "scmd %d: no active command for frame context %" PRIx64 megasas_abort_invalid_context(int cmd, uint64_t context, int abort_cmd) "scmd %d: invalid frame context %" PRIx64 " for abort frame %x" megasas_reset(int fw_state) "firmware state %x" megasas_init(int sges, int cmds, const char *mode) "Using %d sges, %d cmds, %s mode" @@ -898,7 +898,7 @@ milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08 mipsnet_send(uint32_t size) "sending len=%u" mipsnet_receive(uint32_t size) "receiving len=%u" mipsnet_read(uint64_t addr, uint32_t val) "read addr=0x%" PRIx64 " val=0x%x" -mipsnet_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64 "" +mipsnet_write(uint64_t addr, uint64_t val) "write addr=0x%" PRIx64 " val=0x%" PRIx64 mipsnet_irq(uint32_t isr, uint32_t intctl) "set irq to %d (%02x)" # hw/isa/pc87312.c @@ -912,8 +912,8 @@ pc87312_info_serial(int n, uint32_t base, uint32_t irq) "id=%d, base 0x%x, irq % # hw/scsi/vmw_pvscsi.c pvscsi_ring_init_data(uint32_t txr_len_log2, uint32_t rxr_len_log2) "TX/RX rings logarithms set to %d/%d" pvscsi_ring_init_msg(uint32_t len_log2) "MSG ring logarithm set to %d" -pvscsi_ring_flush_cmp(uint64_t filled_cmp_ptr) "new production counter of completion ring is 0x%"PRIx64"" -pvscsi_ring_flush_msg(uint64_t filled_cmp_ptr) "new production counter of message ring is 0x%"PRIx64"" +pvscsi_ring_flush_cmp(uint64_t filled_cmp_ptr) "new production counter of completion ring is 0x%"PRIx64 +pvscsi_ring_flush_msg(uint64_t filled_cmp_ptr) "new production counter of message ring is 0x%"PRIx64 pvscsi_update_irq_level(bool raise, uint64_t mask, uint64_t status) "interrupt level set to %d (MASK: 0x%"PRIx64", STATUS: 0x%"PRIx64")" pvscsi_update_irq_msi(void) "sending MSI notification" pvscsi_cmp_ring_put(unsigned long addr) "got completion descriptor 0x%lx" @@ -925,7 +925,7 @@ pvscsi_command_complete_not_found(uint32_t tag) "can't find request for tag 0x%x pvscsi_command_complete_data_run(void) "not all data required for command transferred" pvscsi_command_complete_sense_len(int len) "sense information length is %d bytes" pvscsi_convert_sglist(uint64_t context, unsigned long addr, uint32_t resid) "element: ctx: 0x%"PRIx64" addr: 0x%lx, len: %ul" -pvscsi_process_req_descr(uint8_t cmd, uint64_t ctx) "SCSI cmd 0x%x, ctx: 0x%"PRIx64"" +pvscsi_process_req_descr(uint8_t cmd, uint64_t ctx) "SCSI cmd 0x%x, ctx: 0x%"PRIx64 pvscsi_process_req_descr_unknown_device(void) "command directed to unknown device rejected" pvscsi_process_req_descr_invalid_dir(void) "command with invalid transfer direction rejected" pvscsi_process_io(unsigned long addr) "got descriptor 0x%lx" @@ -933,15 +933,15 @@ pvscsi_on_cmd_noimpl(const char* cmd) "unimplemented command %s ignored" pvscsi_on_cmd_reset_dev(uint32_t tgt, int lun, void* dev) "PVSCSI_CMD_RESET_DEVICE[target %u lun %d (dev 0x%p)]" pvscsi_on_cmd_arrived(const char* cmd) "command %s arrived" pvscsi_on_cmd_abort(uint64_t ctx, uint32_t tgt) "command PVSCSI_CMD_ABORT_CMD for ctx 0x%"PRIx64", target %u" -pvscsi_on_cmd_unknown(uint64_t cmd_id) "unknown command %"PRIx64"" +pvscsi_on_cmd_unknown(uint64_t cmd_id) "unknown command %"PRIx64 pvscsi_on_cmd_unknown_data(uint32_t data) "data for unknown command 0x:%x" -pvscsi_io_write(const char* cmd, uint64_t val) "%s write: %"PRIx64"" -pvscsi_io_write_unknown(unsigned long addr, unsigned sz, uint64_t val) "unknown write address: 0x%lx size: %u bytes value: 0x%"PRIx64"" -pvscsi_io_read(const char* cmd, uint64_t status) "%s read: 0x%"PRIx64"" +pvscsi_io_write(const char* cmd, uint64_t val) "%s write: %"PRIx64 +pvscsi_io_write_unknown(unsigned long addr, unsigned sz, uint64_t val) "unknown write address: 0x%lx size: %u bytes value: 0x%"PRIx64 +pvscsi_io_read(const char* cmd, uint64_t status) "%s read: 0x%"PRIx64 pvscsi_io_read_unknown(unsigned long addr, unsigned sz) "unknown read address: 0x%lx size: %u bytes" pvscsi_init_msi_fail(int res) "failed to initialize MSI, error %d" pvscsi_state(const char* state) "starting %s ..." -pvscsi_tx_rings_ppn(const char* label, uint64_t ppn) "%s page: %"PRIx64"" +pvscsi_tx_rings_ppn(const char* label, uint64_t ppn) "%s page: %"PRIx64 pvscsi_tx_rings_num_pages(const char* label, uint32_t num) "Number of %s pages: %u" # xen-hvm.c @@ -1077,10 +1077,10 @@ v9fs_rerror(uint16_t tag, uint8_t id, int err) "tag %d id %d err %d" v9fs_version(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s" v9fs_version_return(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s" v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) "tag %u id %u fid %d afid %d uname %s aname %s" -v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d type %d version %d path %"PRId64"" +v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d type %d version %d path %"PRId64 v9fs_stat(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d" v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length) "tag %d id %d stat={mode %d atime %d mtime %d length %"PRId64"}" -v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag %d id %d fid %d request_mask %"PRIu64"" +v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag %d id %d fid %d request_mask %"PRIu64 v9fs_getattr_return(uint16_t tag, uint8_t id, uint64_t result_mask, uint32_t mode, uint32_t uid, uint32_t gid) "tag %d id %d getattr={result_mask %"PRId64" mode %u uid %u gid %u}" v9fs_walk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, uint16_t nwnames) "tag %d id %d fid %d newfid %d nwnames %d" v9fs_walk_return(uint16_t tag, uint8_t id, uint16_t nwnames, void* qids) "tag %d id %d nwnames %d qids %p" @@ -1106,14 +1106,14 @@ v9fs_remove(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d" v9fs_wstat(uint16_t tag, uint8_t id, int32_t fid, int32_t mode, int32_t atime, int32_t mtime) "tag %u id %u fid %d stat={mode %d atime %d mtime %d}" v9fs_mknod(uint16_t tag, uint8_t id, int32_t fid, int mode, int major, int minor) "tag %d id %d fid %d mode %d major %d minor %d" v9fs_mknod_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d qid={type %d version %d path %"PRId64"}" -v9fs_lock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length) "tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64"" +v9fs_lock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length) "tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64 v9fs_lock_return(uint16_t tag, uint8_t id, int8_t status) "tag %d id %d status %d" -v9fs_getlock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length)"tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64"" +v9fs_getlock(uint16_t tag, uint8_t id, int32_t fid, uint8_t type, uint64_t start, uint64_t length)"tag %d id %d fid %d type %d start %"PRIu64" length %"PRIu64 v9fs_getlock_return(uint16_t tag, uint8_t id, uint8_t type, uint64_t start, uint64_t length, uint32_t proc_id) "tag %d id %d type %d start %"PRIu64" length %"PRIu64" proc_id %u" v9fs_mkdir(uint16_t tag, uint8_t id, int32_t fid, char* name, int mode, uint32_t gid) "tag %u id %u fid %d name %s mode %d gid %u" v9fs_mkdir_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int err) "tag %u id %u qid={type %d version %d path %"PRId64"} err %d" v9fs_xattrwalk(uint16_t tag, uint8_t id, int32_t fid, int32_t newfid, char* name) "tag %d id %d fid %d newfid %d name %s" -v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size) "tag %d id %d size %"PRId64"" +v9fs_xattrwalk_return(uint16_t tag, uint8_t id, int64_t size) "tag %d id %d size %"PRId64 v9fs_xattrcreate(uint16_t tag, uint8_t id, int32_t fid, char* name, int64_t size, int flags) "tag %d id %d fid %d name %s size %"PRId64" flags %d" v9fs_readlink(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d" v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name %s" @@ -1121,12 +1121,12 @@ v9fs_readlink_return(uint16_t tag, uint8_t id, char* target) "tag %d id %d name # target-sparc/mmu_helper.c mmu_helper_dfault(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DFAULT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d" mmu_helper_dprot(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DPROT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d" -mmu_helper_dmiss(uint64_t address, uint64_t context) "DMISS at %"PRIx64" context %"PRIx64"" -mmu_helper_tfault(uint64_t address, uint64_t context) "TFAULT at %"PRIx64" context %"PRIx64"" -mmu_helper_tmiss(uint64_t address, uint64_t context) "TMISS at %"PRIx64" context %"PRIx64"" -mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64"" -mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64"" -mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context) "Translate at %"PRIx64" -> %"PRIx64", mmu_idx=%d tl=%d primary context=%"PRIx64" secondary context=%"PRIx64"" +mmu_helper_dmiss(uint64_t address, uint64_t context) "DMISS at %"PRIx64" context %"PRIx64 +mmu_helper_tfault(uint64_t address, uint64_t context) "TFAULT at %"PRIx64" context %"PRIx64 +mmu_helper_tmiss(uint64_t address, uint64_t context) "TMISS at %"PRIx64" context %"PRIx64 +mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64 +mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64 +mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context) "Translate at %"PRIx64" -> %"PRIx64", mmu_idx=%d tl=%d primary context=%"PRIx64" secondary context=%"PRIx64 # target-sparc/int64_helper.c int_helper_set_softint(uint32_t softint) "new %08x" @@ -1281,7 +1281,7 @@ qemu_file_fclose(void) "" get_queued_page(const char *block_name, uint64_t tmp_offset, uint64_t ram_addr) "%s/%" PRIx64 " ram_addr=%" PRIx64 get_queued_page_not_dirty(const char *block_name, uint64_t tmp_offset, uint64_t ram_addr, int sent) "%s/%" PRIx64 " ram_addr=%" PRIx64 " (sent=%d)" migration_bitmap_sync_start(void) "" -migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64"" +migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64 migration_throttle(void) "" ram_load_postcopy_loop(uint64_t addr, int flags) "@%" PRIx64 " %x" ram_postcopy_send_discard_bitmap(void) "" @@ -1295,7 +1295,7 @@ qxl_create_guest_primary_rest(int qid, int32_t stride, uint32_t type, uint32_t f qxl_destroy_primary(int qid) "%d" qxl_enter_vga_mode(int qid) "%d" qxl_exit_vga_mode(int qid) "%d" -qxl_hard_reset(int qid, int64_t loadvm) "%d loadvm=%"PRId64"" +qxl_hard_reset(int qid, int64_t loadvm) "%d loadvm=%"PRId64 qxl_interface_async_complete_io(int qid, uint32_t current_async, void *cookie) "%d current=%d cookie=%p" qxl_interface_attach_worker(int qid) "%d" qxl_interface_get_init_info(int qid) "%d" @@ -1819,15 +1819,15 @@ qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const vhost_user_event(const char *chr, int event) "chr: %s got event: %d" # linux-user/signal.c -user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64"" -user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64"" -user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64"" -user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64"" +user_setup_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64 +user_setup_rt_frame(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64 +user_do_rt_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64 +user_do_sigreturn(void *env, uint64_t frame_addr) "env=%p frame_addr=%"PRIx64 user_force_sig(void *env, int target_sig, int host_sig) "env=%p signal %d (host %d)" user_handle_signal(void *env, int target_sig) "env=%p signal %d" user_host_signal(void *env, int host_sig, int target_sig) "env=%p signal %d (target %d(" user_queue_signal(void *env, int target_sig) "env=%p signal %d" -user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr %"PRIx64 " current psw.addr %"PRIx64"" +user_s390x_restore_sigregs(void *env, uint64_t sc_psw_addr, uint64_t env_psw_addr) "env=%p frame psw.addr %"PRIx64 " current psw.addr %"PRIx64 # io/task.c qio_task_new(void *task, void *source, void *func, void *opaque) "Task new task=%p source=%p func=%p opaque=%p" From 2c140f5f2c245603c0123956eb6abf20b998b501 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Mon, 8 Feb 2016 16:03:03 -0800 Subject: [PATCH 02/13] trace: docs: "simple" backend does support strings The simple tracing backend has supported strings for more than three years (62bab73213ba885426a781eb2741670b9f3cae36). Signed-off-by: Hollis Blanchard Message-id: 1454976185-30095-1-git-send-email-hollis_blanchard@mentor.com Signed-off-by: Stefan Hajnoczi --- docs/tracing.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/tracing.txt b/docs/tracing.txt index 3853a6ad8a..f2f553bd4c 100644 --- a/docs/tracing.txt +++ b/docs/tracing.txt @@ -172,9 +172,6 @@ source tree. It may not be as powerful as platform-specific or third-party trace backends but it is portable. This is the recommended trace backend unless you have specific needs for more advanced backends. -The "simple" backend currently does not capture string arguments, it simply -records the char* pointer value instead of the string that is pointed to. - === Ftrace === The "ftrace" backend writes trace data to ftrace marker. This effectively From 23d92d68e72503dfb9fa1dba89f02f5488377b6c Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Mon, 8 Feb 2016 16:03:04 -0800 Subject: [PATCH 03/13] trace: split subpage MMIOs into their own trace events. Previously, a single MMIO could trigger the memory_region_ops tracepoint twice: once on its way into subpage ops, then later on its way into the model's ops. Also, the fields previously called "addr" are actually offsets into the memory region. Rename them to "offset" while we're editing the tracepoint definitions. Signed-off-by: Hollis Blanchard Message-id: 1454976185-30095-2-git-send-email-hollis_blanchard@mentor.com Signed-off-by: Stefan Hajnoczi --- memory.c | 36 ++++++++++++++++++++++++++++++------ trace-events | 6 ++++-- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/memory.c b/memory.c index 0dd9695aec..86ffd5342e 100644 --- a/memory.c +++ b/memory.c @@ -383,7 +383,11 @@ static MemTxResult memory_region_oldmmio_read_accessor(MemoryRegion *mr, uint64_t tmp; tmp = mr->ops->old_mmio.read[ctz32(size)](mr->opaque, addr); - trace_memory_region_ops_read(mr, addr, tmp, size); + if (mr->subpage) { + trace_memory_region_subpage_read(mr, addr, tmp, size); + } else { + trace_memory_region_ops_read(mr, addr, tmp, size); + } *value |= (tmp & mask) << shift; return MEMTX_OK; } @@ -399,7 +403,11 @@ static MemTxResult memory_region_read_accessor(MemoryRegion *mr, uint64_t tmp; tmp = mr->ops->read(mr->opaque, addr, size); - trace_memory_region_ops_read(mr, addr, tmp, size); + if (mr->subpage) { + trace_memory_region_subpage_read(mr, addr, tmp, size); + } else { + trace_memory_region_ops_read(mr, addr, tmp, size); + } *value |= (tmp & mask) << shift; return MEMTX_OK; } @@ -416,7 +424,11 @@ static MemTxResult memory_region_read_with_attrs_accessor(MemoryRegion *mr, MemTxResult r; r = mr->ops->read_with_attrs(mr->opaque, addr, &tmp, size, attrs); - trace_memory_region_ops_read(mr, addr, tmp, size); + if (mr->subpage) { + trace_memory_region_subpage_read(mr, addr, tmp, size); + } else { + trace_memory_region_ops_read(mr, addr, tmp, size); + } *value |= (tmp & mask) << shift; return r; } @@ -432,7 +444,11 @@ static MemTxResult memory_region_oldmmio_write_accessor(MemoryRegion *mr, uint64_t tmp; tmp = (*value >> shift) & mask; - trace_memory_region_ops_write(mr, addr, tmp, size); + if (mr->subpage) { + trace_memory_region_subpage_write(mr, addr, tmp, size); + } else { + trace_memory_region_ops_write(mr, addr, tmp, size); + } mr->ops->old_mmio.write[ctz32(size)](mr->opaque, addr, tmp); return MEMTX_OK; } @@ -448,7 +464,11 @@ static MemTxResult memory_region_write_accessor(MemoryRegion *mr, uint64_t tmp; tmp = (*value >> shift) & mask; - trace_memory_region_ops_write(mr, addr, tmp, size); + if (mr->subpage) { + trace_memory_region_subpage_write(mr, addr, tmp, size); + } else { + trace_memory_region_ops_write(mr, addr, tmp, size); + } mr->ops->write(mr->opaque, addr, tmp, size); return MEMTX_OK; } @@ -464,7 +484,11 @@ static MemTxResult memory_region_write_with_attrs_accessor(MemoryRegion *mr, uint64_t tmp; tmp = (*value >> shift) & mask; - trace_memory_region_ops_write(mr, addr, tmp, size); + if (mr->subpage) { + trace_memory_region_subpage_write(mr, addr, tmp, size); + } else { + trace_memory_region_ops_write(mr, addr, tmp, size); + } return mr->ops->write_with_attrs(mr->opaque, addr, tmp, size, attrs); } diff --git a/trace-events b/trace-events index d57e1c344a..021211dfff 100644 --- a/trace-events +++ b/trace-events @@ -1620,8 +1620,10 @@ disable exec_tb_exit(void *next_tb, unsigned int flags) "tb:%p flags=%x" translate_block(void *tb, uintptr_t pc, uint8_t *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p" # memory.c -memory_region_ops_read(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u" -memory_region_ops_write(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u" +memory_region_ops_read(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" +memory_region_ops_write(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" +memory_region_subpage_read(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" +memory_region_subpage_write(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" # qom/object.c object_dynamic_cast_assert(const char *type, const char *target, const char *file, int line, const char *func) "%s->%s (%s:%d:%s)" From 4779dc1d19f0e3e20d2d4843b988c72b9235bbe0 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Mon, 8 Feb 2016 16:03:05 -0800 Subject: [PATCH 04/13] trace: use addresses instead of offsets in memory tracepoints When memory_region_ops tracepoints are enabled, calculate and record the absolute address being accessed. Otherwise, we only get offsets into the memory region instead of addresses. [Fixed "offset" -> "addr" in trace event format strings. --Stefan] Signed-off-by: Hollis Blanchard Message-id: 1454976185-30095-3-git-send-email-hollis_blanchard@mentor.com Signed-off-by: Stefan Hajnoczi --- memory.c | 44 ++++++++++++++++++++++++++++++++------------ trace-events | 4 ++-- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/memory.c b/memory.c index 86ffd5342e..013c2ed531 100644 --- a/memory.c +++ b/memory.c @@ -372,6 +372,20 @@ static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size) } } +static hwaddr memory_region_to_absolute_addr(MemoryRegion *mr, hwaddr offset) +{ + MemoryRegion *root; + hwaddr abs_addr = offset; + + abs_addr += mr->addr; + for (root = mr; root->container; ) { + root = root->container; + abs_addr += root->addr; + } + + return abs_addr; +} + static MemTxResult memory_region_oldmmio_read_accessor(MemoryRegion *mr, hwaddr addr, uint64_t *value, @@ -385,8 +399,9 @@ static MemTxResult memory_region_oldmmio_read_accessor(MemoryRegion *mr, tmp = mr->ops->old_mmio.read[ctz32(size)](mr->opaque, addr); if (mr->subpage) { trace_memory_region_subpage_read(mr, addr, tmp, size); - } else { - trace_memory_region_ops_read(mr, addr, tmp, size); + } else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) { + hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr); + trace_memory_region_ops_read(mr, abs_addr, tmp, size); } *value |= (tmp & mask) << shift; return MEMTX_OK; @@ -405,8 +420,9 @@ static MemTxResult memory_region_read_accessor(MemoryRegion *mr, tmp = mr->ops->read(mr->opaque, addr, size); if (mr->subpage) { trace_memory_region_subpage_read(mr, addr, tmp, size); - } else { - trace_memory_region_ops_read(mr, addr, tmp, size); + } else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) { + hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr); + trace_memory_region_ops_read(mr, abs_addr, tmp, size); } *value |= (tmp & mask) << shift; return MEMTX_OK; @@ -426,8 +442,9 @@ static MemTxResult memory_region_read_with_attrs_accessor(MemoryRegion *mr, r = mr->ops->read_with_attrs(mr->opaque, addr, &tmp, size, attrs); if (mr->subpage) { trace_memory_region_subpage_read(mr, addr, tmp, size); - } else { - trace_memory_region_ops_read(mr, addr, tmp, size); + } else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) { + hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr); + trace_memory_region_ops_read(mr, abs_addr, tmp, size); } *value |= (tmp & mask) << shift; return r; @@ -446,8 +463,9 @@ static MemTxResult memory_region_oldmmio_write_accessor(MemoryRegion *mr, tmp = (*value >> shift) & mask; if (mr->subpage) { trace_memory_region_subpage_write(mr, addr, tmp, size); - } else { - trace_memory_region_ops_write(mr, addr, tmp, size); + } else if (TRACE_MEMORY_REGION_OPS_WRITE_ENABLED) { + hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr); + trace_memory_region_ops_write(mr, abs_addr, tmp, size); } mr->ops->old_mmio.write[ctz32(size)](mr->opaque, addr, tmp); return MEMTX_OK; @@ -466,8 +484,9 @@ static MemTxResult memory_region_write_accessor(MemoryRegion *mr, tmp = (*value >> shift) & mask; if (mr->subpage) { trace_memory_region_subpage_write(mr, addr, tmp, size); - } else { - trace_memory_region_ops_write(mr, addr, tmp, size); + } else if (TRACE_MEMORY_REGION_OPS_WRITE_ENABLED) { + hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr); + trace_memory_region_ops_write(mr, abs_addr, tmp, size); } mr->ops->write(mr->opaque, addr, tmp, size); return MEMTX_OK; @@ -486,8 +505,9 @@ static MemTxResult memory_region_write_with_attrs_accessor(MemoryRegion *mr, tmp = (*value >> shift) & mask; if (mr->subpage) { trace_memory_region_subpage_write(mr, addr, tmp, size); - } else { - trace_memory_region_ops_write(mr, addr, tmp, size); + } else if (TRACE_MEMORY_REGION_OPS_WRITE_ENABLED) { + hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr); + trace_memory_region_ops_write(mr, abs_addr, tmp, size); } return mr->ops->write_with_attrs(mr->opaque, addr, tmp, size, attrs); } diff --git a/trace-events b/trace-events index 021211dfff..6fba6cc474 100644 --- a/trace-events +++ b/trace-events @@ -1620,8 +1620,8 @@ disable exec_tb_exit(void *next_tb, unsigned int flags) "tb:%p flags=%x" translate_block(void *tb, uintptr_t pc, uint8_t *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p" # memory.c -memory_region_ops_read(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" -memory_region_ops_write(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" +memory_region_ops_read(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u" +memory_region_ops_write(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u" memory_region_subpage_read(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" memory_region_subpage_write(void *mr, uint64_t offset, uint64_t value, unsigned size) "mr %p offset %#"PRIx64" value %#"PRIx64" size %u" From 62cb4145bbc71fcb9754034655a6c7327905efc4 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Tue, 9 Feb 2016 19:49:05 +0300 Subject: [PATCH 05/13] vl: fix tracing initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit we should call trace_init_backends() before trace_init_file() for CONFIG_TRACE_SIMPLE There is no difference for other cases. This problem was introduced by the commit commit 41fc57e44ed64cd4ab5393d83624afd897dabd4f Author: Paolo Bonzini Date: Thu Jan 7 16:55:24 2016 +0300 trace: split trace_init_file out of trace_init_backends 'make check' was failed as a result if configured with --enable-trace-backends=simple Spotted by Alex Bennée. Signed-off-by: Denis V. Lunev Reviewed-by: Alex Bennée Tested-by: Alex Bennée Tested-by: Christian Borntraeger Message-id: 1455036545-14870-1-git-send-email-den@openvz.org CC: Alex Bennée CC: Paolo Bonzini CC: Stefan Hajnoczi Signed-off-by: Stefan Hajnoczi --- vl.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/vl.c b/vl.c index b87e29268c..adeddd98a6 100644 --- a/vl.c +++ b/vl.c @@ -4081,6 +4081,9 @@ int main(int argc, char **argv, char **envp) exit(0); } + if (!trace_init_backends()) { + exit(1); + } trace_init_file(trace_file); /* Open the logfile at this point and set the log mask if necessary. @@ -4101,10 +4104,6 @@ int main(int argc, char **argv, char **envp) qemu_set_log(0); } - if (!trace_init_backends()) { - exit(1); - } - /* If no data_dir is specified then try to find it relative to the executable path. */ if (data_dir_idx < ARRAY_SIZE(data_dir)) { From 3596f524d4257ede23f68b7005c4548660db463a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:04 +0100 Subject: [PATCH 06/13] trace: Extend API to manage event arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lets the user manage event arguments as a list, and simplifies argument concatenation. Signed-off-by: Lluís Vilanova Reviewed-by: Eric Blake Message-id: 145641858432.30295.3069911069472672646.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 181675f00e..0663e7f3d1 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -50,9 +50,14 @@ class Arguments: Parameters ---------- args : - List of (type, name) tuples. + List of (type, name) tuples or Arguments objects. """ - self._args = args + self._args = [] + for arg in args: + if isinstance(arg, Arguments): + self._args.extend(arg._args) + else: + self._args.append(arg) def copy(self): """Create a new copy.""" @@ -83,6 +88,12 @@ class Arguments: res.append((arg_type, identifier)) return Arguments(res) + def __getitem__(self, index): + if isinstance(index, slice): + return Arguments(self._args[index]) + else: + return self._args[index] + def __iter__(self): """Iterate over the (type, name) pairs.""" return iter(self._args) From 56797b1fbce86b3844cec753100a7260b9132a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:10 +0100 Subject: [PATCH 07/13] trace: Remove unnecessary intermediate event copies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current code forces the use of a chain of ".original" dereferences, which looks odd. Signed-off-by: Lluís Vilanova Message-id: 145641858988.30295.7223459456488075843.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 5 ++--- scripts/tracetool/format/events_h.py | 4 ++-- scripts/tracetool/format/tcg_h.py | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 0663e7f3d1..26878f4173 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -6,7 +6,7 @@ Machinery for generating tracing-related intermediate files. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -288,13 +288,12 @@ def _read_events(fobj): if atrans == aorig: args_trans.append(atrans) event_trans.args = Arguments(args_trans) - event_trans = event_trans.copy() event_exec = event.copy() event_exec.name += "_exec" event_exec.properties += ["tcg-exec"] event_exec.fmt = event.fmt[1] - event_exec = event_exec.transform(tracetool.transform.TCG_2_HOST) + event_exec.args = event_exec.args.transform(tracetool.transform.TCG_2_HOST) new_event = [event_trans, event_exec] event.event_trans, event.event_exec = new_event diff --git a/scripts/tracetool/format/events_h.py b/scripts/tracetool/format/events_h.py index 9f114a3497..bbfaa5bd1f 100644 --- a/scripts/tracetool/format/events_h.py +++ b/scripts/tracetool/format/events_h.py @@ -6,7 +6,7 @@ trace/generated-events.h """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -43,7 +43,7 @@ def generate(events, backend): if "tcg-trans" in e.properties: # a single define for the two "sub-events" out('#define TRACE_%(name)s_ENABLED %(enabled)d', - name=e.original.original.name.upper(), + name=e.original.name.upper(), enabled=enabled) out('#define TRACE_%s_ENABLED %d' % (e.name.upper(), enabled)) diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py index f676b66622..0d2cf797fa 100644 --- a/scripts/tracetool/format/tcg_h.py +++ b/scripts/tracetool/format/tcg_h.py @@ -6,7 +6,7 @@ Generate .h file for TCG code generation. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -36,7 +36,7 @@ def generate(events, backend): continue # get the original event definition - e = e.original.original + e = e.original out('static inline void %(name_tcg)s(%(args)s)', '{', From 1bcea73e13b2b059d0cb3301aeaca43e5656ef57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:15 +0100 Subject: [PATCH 08/13] tcg: Add type for vCPU pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the 'TCGv_env' type for pointers to 'CPUArchState' objects. The tracing infrastructure later needs to differentiate between regular pointers and pointers to vCPUs. Also changes all targets to use the new 'TCGv_env' type instead of the generic 'TCGv_ptr'. As of now, the change is merely cosmetic ('TCGv_env' translates into 'TCGv_ptr'), but that could change in the future to enforce the difference. Note that a 'TCGv_env' type (for 'CPUState') is not added, since all helpers currently receive the architecture-specific pointer ('CPUArchState'). Signed-off-by: Lluís Vilanova Acked-by: Richard Henderson Message-id: 145641859552.30295.7821536833590725201.stgit@localhost Signed-off-by: Stefan Hajnoczi --- target-alpha/translate.c | 2 +- target-arm/translate.c | 2 +- target-arm/translate.h | 2 +- target-cris/translate.c | 2 +- target-i386/translate.c | 2 +- target-lm32/translate.c | 2 +- target-m68k/translate.c | 2 +- target-microblaze/translate.c | 2 +- target-mips/translate.c | 2 +- target-moxie/translate.c | 2 +- target-openrisc/translate.c | 2 +- target-ppc/translate.c | 2 +- target-s390x/translate.c | 2 +- target-sh4/translate.c | 2 +- target-sparc/translate.c | 5 +++-- target-tilegx/translate.c | 2 +- target-tricore/translate.c | 2 +- target-unicore32/translate.c | 2 +- target-xtensa/translate.c | 2 +- tcg/tcg.h | 1 + 20 files changed, 22 insertions(+), 20 deletions(-) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 7b798b0d0a..5b86992dd3 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -93,7 +93,7 @@ typedef enum { } ExitStatus; /* global register indexes */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_std_ir[31]; static TCGv cpu_fir[31]; static TCGv cpu_pc; diff --git a/target-arm/translate.c b/target-arm/translate.c index 413f7de686..c29c47f006 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -56,7 +56,7 @@ #define IS_USER(s) (s->user) #endif -TCGv_ptr cpu_env; +TCGv_env cpu_env; /* We reuse the same 64-bit temporaries for efficiency. */ static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; static TCGv_i32 cpu_R[16]; diff --git a/target-arm/translate.h b/target-arm/translate.h index 53ef971058..82e3f6bf06 100644 --- a/target-arm/translate.h +++ b/target-arm/translate.h @@ -70,7 +70,7 @@ typedef struct DisasCompare { } DisasCompare; /* Share the TCG temporaries common between 32 and 64 bit modes. */ -extern TCGv_ptr cpu_env; +extern TCGv_env cpu_env; extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF; extern TCGv_i64 cpu_exclusive_addr; extern TCGv_i64 cpu_exclusive_val; diff --git a/target-cris/translate.c b/target-cris/translate.c index 2a283e03e2..a73176c118 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -60,7 +60,7 @@ #define CC_MASK_NZVC 0xf #define CC_MASK_RNZV 0x10e -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_R[16]; static TCGv cpu_PR[16]; static TCGv cc_x; diff --git a/target-i386/translate.c b/target-i386/translate.c index 9171929fc7..53dee79afd 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -65,7 +65,7 @@ //#define MACRO_TEST 1 /* global register indexes */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_A0; static TCGv cpu_cc_dst, cpu_cc_src, cpu_cc_src2, cpu_cc_srcT; static TCGv_i32 cpu_cc_op; diff --git a/target-lm32/translate.c b/target-lm32/translate.c index 38779939db..256a51f849 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -44,7 +44,7 @@ #define MEM_INDEX 0 -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_R[32]; static TCGv cpu_pc; static TCGv cpu_ie; diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 085cb6a56c..7560c3a808 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -50,7 +50,7 @@ static TCGv_i32 cpu_halted; static TCGv_i32 cpu_exception_index; -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static char cpu_reg_names[3*8*3 + 5*4]; static TCGv cpu_dregs[8]; diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 296c4d7bf8..f944965a14 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -46,7 +46,7 @@ (((src) >> start) & ((1 << (end - start + 1)) - 1)) static TCGv env_debug; -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_R[32]; static TCGv cpu_SR[18]; static TCGv env_imm; diff --git a/target-mips/translate.c b/target-mips/translate.c index a16656931b..12ed8208d0 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1355,7 +1355,7 @@ enum { }; /* global register indices */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; static TCGv cpu_dspctrl, btarget, bcond; diff --git a/target-moxie/translate.c b/target-moxie/translate.c index bc860a5257..a437e2ab60 100644 --- a/target-moxie/translate.c +++ b/target-moxie/translate.c @@ -56,7 +56,7 @@ enum { static TCGv cpu_pc; static TCGv cpu_gregs[16]; -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cc_a, cc_b; #include "exec/gen-icount.h" diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index d25324e82e..5d0ab442a8 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -53,7 +53,7 @@ typedef struct DisasContext { uint32_t delayed_branch; } DisasContext; -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_sr; static TCGv cpu_R[32]; static TCGv cpu_pc; diff --git a/target-ppc/translate.c b/target-ppc/translate.c index ecc85f0e6d..e402ff9203 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -49,7 +49,7 @@ /* Code translation helpers */ /* global register indexes */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static char cpu_reg_names[10*3 + 22*4 /* GPR */ + 10*4 + 22*5 /* SPE GPRh */ + 10*4 + 22*5 /* FPR */ diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 82e11658f3..c871ef2bb3 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -37,7 +37,7 @@ #include "exec/cpu_ldst.h" /* global register indexes */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; #include "exec/gen-icount.h" #include "exec/helper-proto.h" diff --git a/target-sh4/translate.c b/target-sh4/translate.c index e35d1750a4..7c189680a7 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -61,7 +61,7 @@ enum { }; /* global register indexes */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_gregs[24]; static TCGv cpu_sr, cpu_sr_m, cpu_sr_q, cpu_sr_t; static TCGv cpu_pc, cpu_ssr, cpu_spc, cpu_gbr; diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 00d61ee16a..58572c34cf 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -39,7 +39,8 @@ according to jump_pc[T2] */ /* global register indexes */ -static TCGv_ptr cpu_env, cpu_regwptr; +static TCGv_env cpu_env; +static TCGv_ptr cpu_regwptr; static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst; static TCGv_i32 cpu_cc_op; static TCGv_i32 cpu_psr; @@ -2291,7 +2292,7 @@ static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs) } #ifndef CONFIG_USER_ONLY -static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env) +static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env) { TCGv_i32 r_tl = tcg_temp_new_i32(); diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index 7073aba9c1..03918ebd5d 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -32,7 +32,7 @@ #define FMT64X "%016" PRIx64 -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_pc; static TCGv cpu_regs[TILEGX_R_COUNT]; diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 6d7f55359b..d13e5c8c62 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -47,7 +47,7 @@ static TCGv cpu_PSW_SV; static TCGv cpu_PSW_AV; static TCGv cpu_PSW_SAV; /* CPU env */ -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; #include "exec/gen-icount.h" diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index 1dd086d11b..39af3af05f 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -48,7 +48,7 @@ typedef struct DisasContext { conditional executions state has been updated. */ #define DISAS_SYSCALL 5 -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv_i32 cpu_R[32]; /* FIXME: These should be removed. */ diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index fd03603e35..9894488469 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -74,7 +74,7 @@ typedef struct DisasContext { unsigned cpenable; } DisasContext; -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv_i32 cpu_pc; static TCGv_i32 cpu_R[16]; static TCGv_i32 cpu_FR[16]; diff --git a/tcg/tcg.h b/tcg/tcg.h index c45329a7cb..e7983beaee 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -308,6 +308,7 @@ typedef tcg_target_ulong TCGArg; typedef struct TCGv_i32_d *TCGv_i32; typedef struct TCGv_i64_d *TCGv_i64; typedef struct TCGv_ptr_d *TCGv_ptr; +typedef TCGv_ptr TCGv_env; static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(intptr_t i) { From 5d4e1a1081d3f1ec2908ff0eaebe312389971ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:21 +0100 Subject: [PATCH 09/13] tcg: Move definition of type TCGv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The target-dependant type TCGv must be defined in "tcg/tcg.h" before including the tracing helper wrappers in "tcg/tcg-op.h". It also makes more sense to define it here, where other TCG types are defined too. Signed-off-by: Lluís Vilanova Message-id: 145641860129.30295.17554707227384022653.stgit@localhost Signed-off-by: Stefan Hajnoczi --- tcg/tcg-op.h | 2 -- tcg/tcg.h | 7 +++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 4e20dc1a6b..c446d3dc72 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -756,7 +756,6 @@ static inline void tcg_gen_exit_tb(uintptr_t val) void tcg_gen_goto_tb(unsigned idx); #if TARGET_LONG_BITS == 32 -#define TCGv TCGv_i32 #define tcg_temp_new() tcg_temp_new_i32() #define tcg_global_reg_new tcg_global_reg_new_i32 #define tcg_global_mem_new tcg_global_mem_new_i32 @@ -768,7 +767,6 @@ void tcg_gen_goto_tb(unsigned idx); #define tcg_gen_qemu_ld_tl tcg_gen_qemu_ld_i32 #define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32 #else -#define TCGv TCGv_i64 #define tcg_temp_new() tcg_temp_new_i64() #define tcg_global_reg_new tcg_global_reg_new_i64 #define tcg_global_mem_new tcg_global_mem_new_i64 diff --git a/tcg/tcg.h b/tcg/tcg.h index e7983beaee..b83f76351c 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -309,6 +309,13 @@ typedef struct TCGv_i32_d *TCGv_i32; typedef struct TCGv_i64_d *TCGv_i64; typedef struct TCGv_ptr_d *TCGv_ptr; typedef TCGv_ptr TCGv_env; +#if TARGET_LONG_BITS == 32 +#define TCGv TCGv_i32 +#elif TARGET_LONG_BITS == 64 +#define TCGv TCGv_i64 +#else +#error Unhandled TARGET_LONG_BITS value +#endif static inline TCGv_i32 QEMU_ARTIFICIAL MAKE_TCGV_I32(intptr_t i) { From bc9beb47c7822628cf7028ba177b390eabbe88a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:27 +0100 Subject: [PATCH 10/13] trace: Add helper function to cast event arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lluís Vilanova Message-id: 145641860680.30295.1873612736245870753.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 26878f4173..9e02f73e20 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -121,6 +121,10 @@ class Arguments: """List of argument types.""" return [ type_ for type_, _ in self._args ] + def casted(self): + """List of argument names casted to their type.""" + return ["(%s)%s" % (type_, name) for type_, name in self._args] + def transform(self, *trans): """Return a new Arguments instance with transformed types. From b23197f9cf2f221a6cc6272d36852f4f70cf9c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:32 +0100 Subject: [PATCH 11/13] typedefs: Add CPUState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lluís Vilanova Message-id: 145641861239.30295.8564457138934628740.stgit@localhost Signed-off-by: Stefan Hajnoczi --- include/qemu/typedefs.h | 1 + include/qom/cpu.h | 1 - stubs/target-get-monitor-def.c | 3 +-- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 6ed91b4968..9a5ead69a1 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -18,6 +18,7 @@ typedef struct BusState BusState; typedef struct CharDriverState CharDriverState; typedef struct CompatProperty CompatProperty; typedef struct CPUAddressSpace CPUAddressSpace; +typedef struct CPUState CPUState; typedef struct DeviceListener DeviceListener; typedef struct DeviceState DeviceState; typedef struct DisplayChangeListener DisplayChangeListener; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 1df7cb4073..7052eee7b7 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -62,7 +62,6 @@ typedef uint64_t vaddr; #define CPU_CLASS(class) OBJECT_CLASS_CHECK(CPUClass, (class), TYPE_CPU) #define CPU_GET_CLASS(obj) OBJECT_GET_CLASS(CPUClass, (obj), TYPE_CPU) -typedef struct CPUState CPUState; typedef struct CPUWatchpoint CPUWatchpoint; typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, diff --git a/stubs/target-get-monitor-def.c b/stubs/target-get-monitor-def.c index 013e6571e5..4d1033d12d 100644 --- a/stubs/target-get-monitor-def.c +++ b/stubs/target-get-monitor-def.c @@ -20,10 +20,9 @@ */ #include "qemu/osdep.h" +#include "qemu/typedefs.h" #include "stdint.h" -typedef struct CPUState CPUState; - int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval); int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval) From 3d211d9f4dbee7483f092c287ef20d8336100445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 17:43:38 +0100 Subject: [PATCH 12/13] trace: Add 'vcpu' event property to trace guest vCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This property identifies events that trace vCPU-specific information. It adds a "CPUState*" argument to events with the property, identifying the vCPU raising the event. TCG translation events also have a "TCGv_env" implicit argument that is later used as the "CPUState*" argument at execution time. Signed-off-by: Lluís Vilanova Message-id: 145641861797.30295.6991314023181842105.stgit@localhost Signed-off-by: Stefan Hajnoczi --- docs/tracing.txt | 41 +++++++++++ scripts/tracetool/__init__.py | 11 ++- scripts/tracetool/format/h.py | 3 +- scripts/tracetool/format/tcg_h.py | 31 +++++--- scripts/tracetool/format/tcg_helper_c.py | 45 +++++++++--- scripts/tracetool/format/tcg_helper_h.py | 7 +- .../tracetool/format/tcg_helper_wrapper_h.py | 5 +- scripts/tracetool/format/ust_events_c.py | 1 + scripts/tracetool/transform.py | 4 +- scripts/tracetool/vcpu.py | 70 +++++++++++++++++++ trace/control.h | 3 +- 11 files changed, 189 insertions(+), 32 deletions(-) create mode 100644 scripts/tracetool/vcpu.py diff --git a/docs/tracing.txt b/docs/tracing.txt index f2f553bd4c..3182ee82ad 100644 --- a/docs/tracing.txt +++ b/docs/tracing.txt @@ -344,3 +344,44 @@ This will immediately call: and will generate the TCG code to call: void trace_foo(uint8_t a1, uint32_t a2); + +=== "vcpu" === + +Identifies events that trace vCPU-specific information. It implicitly adds a +"CPUState*" argument, and extends the tracing print format to show the vCPU +information. If used together with the "tcg" property, it adds a second +"TCGv_env" argument that must point to the per-target global TCG register that +points to the vCPU when guest code is executed (usually the "cpu_env" variable). + +The following example events: + + foo(uint32_t a) "a=%x" + vcpu bar(uint32_t a) "a=%x" + tcg vcpu baz(uint32_t a) "a=%x", "a=%x" + +Can be used as: + + #include "trace-tcg.h" + + CPUArchState *env; + TCGv_ptr cpu_env; + + void some_disassembly_func(...) + { + /* trace emitted at this point */ + trace_foo(0xd1); + /* trace emitted at this point */ + trace_bar(ENV_GET_CPU(env), 0xd2); + /* trace emitted at this point (env) and when guest code is executed (cpu_env) */ + trace_baz_tcg(ENV_GET_CPU(env), cpu_env, 0xd3); + } + +If the translating vCPU has address 0xc1 and code is later executed by vCPU +0xc2, this would be an example output: + + // at guest code translation + foo a=0xd1 + bar cpu=0xc1 a=0xd2 + baz_trans cpu=0xc1 a=0xd3 + // at guest code execution + baz_exec cpu=0xc2 a=0xd3 diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 9e02f73e20..23caba08e9 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -161,7 +161,7 @@ class Event(object): "(?:(?:(?P\".+),)?\s*(?P\".+))?" "\s*") - _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec"]) + _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"]) def __init__(self, name, props, fmt, args, orig=None): """ @@ -230,7 +230,13 @@ class Event(object): if "tcg" in props and isinstance(fmt, str): raise ValueError("Events with 'tcg' property must have two formats") - return Event(name, props, fmt, args) + event = Event(name, props, fmt, args) + + # add implicit arguments when using the 'vcpu' property + import tracetool.vcpu + event = tracetool.vcpu.transform_event(event) + + return event def __repr__(self): """Evaluable string representation for this object.""" @@ -285,6 +291,7 @@ def _read_events(fobj): event_trans.name += "_trans" event_trans.properties += ["tcg-trans"] event_trans.fmt = event.fmt[0] + # ignore TCG arguments args_trans = [] for atrans, aorig in zip( event_trans.transform(tracetool.transform.TCG_2_HOST).args, diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index 9b3943002c..2bd68a218e 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -6,7 +6,7 @@ trace/generated-tracers.h """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -23,6 +23,7 @@ def generate(events, backend): '#define TRACE__GENERATED_TRACERS_H', '', '#include "qemu-common.h"', + '#include "qemu/typedefs.h"', '') backend.generate_begin(events) diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/tcg_h.py index 0d2cf797fa..006eaa897c 100644 --- a/scripts/tracetool/format/tcg_h.py +++ b/scripts/tracetool/format/tcg_h.py @@ -13,7 +13,18 @@ __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@linux.vnet.ibm.com" -from tracetool import out +from tracetool import out, Arguments +import tracetool.vcpu + + +def vcpu_transform_args(args): + assert len(args) == 1 + return Arguments([ + args, + # NOTE: this name must be kept in sync with the one in "tcg_h" + # NOTE: Current helper code uses TCGv_env (CPUArchState*) + ("TCGv_env", "__tcg_" + args.names()[0]), + ]) def generate(events, backend): @@ -35,21 +46,21 @@ def generate(events, backend): if "tcg-trans" not in e.properties: continue - # get the original event definition - e = e.original - out('static inline void %(name_tcg)s(%(args)s)', '{', - name_tcg=e.api(e.QEMU_TRACE_TCG), - args=e.args) + name_tcg=e.original.api(e.QEMU_TRACE_TCG), + args=tracetool.vcpu.transform_args("tcg_h", e.original)) if "disable" not in e.properties: + args_trans = e.original.event_trans.args + args_exec = tracetool.vcpu.transform_args( + "tcg_helper_c", e.original.event_exec, "wrapper") out(' %(name_trans)s(%(argnames_trans)s);', ' gen_helper_%(name_exec)s(%(argnames_exec)s);', - name_trans=e.event_trans.api(e.QEMU_TRACE), - name_exec=e.event_exec.api(e.QEMU_TRACE), - argnames_trans=", ".join(e.event_trans.args.names()), - argnames_exec=", ".join(e.event_exec.args.names())) + name_trans=e.original.event_trans.api(e.QEMU_TRACE), + name_exec=e.original.event_exec.api(e.QEMU_TRACE), + argnames_trans=", ".join(args_trans.names()), + argnames_exec=", ".join(args_exec.names())) out('}') diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/format/tcg_helper_c.py index afd6e98537..a089b0bf05 100644 --- a/scripts/tracetool/format/tcg_helper_c.py +++ b/scripts/tracetool/format/tcg_helper_c.py @@ -6,15 +6,38 @@ Generate trace/generated-helpers.c. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@linux.vnet.ibm.com" -from tracetool import out +from tracetool import Arguments, out from tracetool.transform import * +import tracetool.vcpu + + +def vcpu_transform_args(args, mode): + assert len(args) == 1 + # NOTE: this name must be kept in sync with the one in "tcg_h" + args = Arguments([(args.types()[0], "__tcg_" + args.names()[0])]) + if mode == "code": + return Arguments([ + # Does cast from helper requirements to tracing types + ("CPUState *", "ENV_GET_CPU(%s)" % args.names()[0]), + ]) + else: + args = Arguments([ + # NOTE: Current helper code uses TCGv_env (CPUArchState*) + ("CPUArchState *", args.names()[0]), + ]) + if mode == "header": + return args + elif mode == "wrapper": + return args.transform(HOST_2_TCG) + else: + assert False def generate(events, backend): @@ -34,18 +57,18 @@ def generate(events, backend): if "tcg-exec" not in e.properties: continue - # tracetool.generate always transforms types to host - e_args = e.original.args + e_args_api = tracetool.vcpu.transform_args( + "tcg_helper_c", e.original, "header").transform( + HOST_2_TCG_COMPAT, TCG_2_TCG_HELPER_DEF) + e_args_call = tracetool.vcpu.transform_args( + "tcg_helper_c", e, "code") - values = ["(%s)%s" % (t, n) - for t, n in e.args.transform(TCG_2_TCG_HELPER_DEF)] - - out('void %(name_tcg)s(%(args)s)', + out('void %(name_tcg)s(%(args_api)s)', '{', - ' %(name)s(%(values)s);', + ' %(name)s(%(args_call)s);', '}', name_tcg="helper_%s_proxy" % e.api(), name=e.api(), - args=e_args.transform(HOST_2_TCG_COMPAT, TCG_2_TCG_HELPER_DEF), - values=", ".join(values), + args_api=e_args_api, + args_call=", ".join(e_args_call.casted()), ) diff --git a/scripts/tracetool/format/tcg_helper_h.py b/scripts/tracetool/format/tcg_helper_h.py index a8ba7ba8e3..dc76c15ebc 100644 --- a/scripts/tracetool/format/tcg_helper_h.py +++ b/scripts/tracetool/format/tcg_helper_h.py @@ -6,7 +6,7 @@ Generate trace/generated-helpers.h. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -15,6 +15,7 @@ __email__ = "stefanha@linux.vnet.ibm.com" from tracetool import out from tracetool.transform import * +import tracetool.vcpu def generate(events, backend): @@ -29,11 +30,9 @@ def generate(events, backend): if "tcg-exec" not in e.properties: continue - # tracetool.generate always transforms types to host - e_args = e.original.args - # TCG helper proxy declaration fmt = "DEF_HELPER_FLAGS_%(argc)d(%(name)s, %(flags)svoid%(types)s)" + e_args = tracetool.vcpu.transform_args("tcg_helper_c", e.original, "header") args = e_args.transform(HOST_2_TCG_COMPAT, HOST_2_TCG, TCG_2_TCG_HELPER_DECL) types = ", ".join(args.types()) diff --git a/scripts/tracetool/format/tcg_helper_wrapper_h.py b/scripts/tracetool/format/tcg_helper_wrapper_h.py index cac5a878f9..020f4422a9 100644 --- a/scripts/tracetool/format/tcg_helper_wrapper_h.py +++ b/scripts/tracetool/format/tcg_helper_wrapper_h.py @@ -6,7 +6,7 @@ Generate trace/generated-helpers-wrappers.h. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -15,6 +15,7 @@ __email__ = "stefanha@linux.vnet.ibm.com" from tracetool import out from tracetool.transform import * +import tracetool.vcpu def generate(events, backend): @@ -33,7 +34,7 @@ def generate(events, backend): continue # tracetool.generate always transforms types to host - e_args = e.original.args + e_args = tracetool.vcpu.transform_args("tcg_helper_c", e.original, "wrapper") # mixed-type to TCG helper bridge args_tcg_compat = e_args.transform(HOST_2_TCG_COMPAT) diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py index 9967c7a82e..bf0b334362 100644 --- a/scripts/tracetool/format/ust_events_c.py +++ b/scripts/tracetool/format/ust_events_c.py @@ -32,4 +32,5 @@ def generate(events, backend): ' */', '#pragma GCC diagnostic ignored "-Wredundant-decls"', '', + '#include "qemu/typedefs.h"', '#include "generated-ust-provider.h"') diff --git a/scripts/tracetool/transform.py b/scripts/tracetool/transform.py index fc5e679ed4..e18b05315e 100644 --- a/scripts/tracetool/transform.py +++ b/scripts/tracetool/transform.py @@ -6,7 +6,7 @@ Type-transformation rules. """ __author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__copyright__ = "Copyright 2012-2016, Lluís Vilanova " __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" @@ -98,6 +98,7 @@ HOST_2_TCG = { "uint32_t": "TCGv_i32", "uint64_t": "TCGv_i64", "void *" : "TCGv_ptr", + "CPUArchState *": "TCGv_env", None: _host_2_tcg, } @@ -130,6 +131,7 @@ TCG_2_TCG_HELPER_DECL = { "TCGv_ptr": "ptr", "TCGv_i32": "i32", "TCGv_i64": "i64", + "TCGv_env": "env", None: _tcg_2_tcg_helper_decl_error, } diff --git a/scripts/tracetool/vcpu.py b/scripts/tracetool/vcpu.py new file mode 100644 index 0000000000..452c7f589d --- /dev/null +++ b/scripts/tracetool/vcpu.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Generic management for the 'vcpu' property. + +""" + +__author__ = "Lluís Vilanova " +__copyright__ = "Copyright 2016, Lluís Vilanova " +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefanha@linux.vnet.ibm.com" + + +from tracetool import Arguments, try_import + + +def transform_event(event): + """Transform event to comply with the 'vcpu' property (if present).""" + if "vcpu" in event.properties: + # events with 'tcg-trans' and 'tcg-exec' are auto-generated from + # already-patched events + assert "tcg-trans" not in event.properties + assert "tcg-exec" not in event.properties + + event.args = Arguments([("CPUState *", "__cpu"), event.args]) + if "tcg" in event.properties: + fmt = "\"cpu=%p \"" + event.fmt = [fmt + event.fmt[0], + fmt + event.fmt[1]] + else: + fmt = "\"cpu=%p \"" + event.fmt = fmt + event.fmt + return event + + +def transform_args(format, event, *args, **kwargs): + """Transforms the arguments to suit the specified format. + + The format module must implement function 'vcpu_args', which receives the + implicit arguments added by the 'vcpu' property, and must return suitable + arguments for the given format. + + The function is only called for events with the 'vcpu' property. + + Parameters + ========== + format : str + Format module name. + event : Event + args, kwargs + Passed to 'vcpu_transform_args'. + + Returns + ======= + Arguments + The transformed arguments, including the non-implicit ones. + + """ + if "vcpu" in event.properties: + ok, func = try_import("tracetool.format." + format, + "vcpu_transform_args") + assert ok + assert func + return Arguments([func(event.args[:1], *args, **kwargs), + event.args[1:]]) + else: + return event.args diff --git a/trace/control.h b/trace/control.h index d5bc86e5f1..f0fe535804 100644 --- a/trace/control.h +++ b/trace/control.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2014 Lluís Vilanova + * Copyright (C) 2011-2016 Lluís Vilanova * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -11,6 +11,7 @@ #define TRACE__CONTROL_H #include "qemu-common.h" +#include "qemu/typedefs.h" #include "trace/generated-events.h" From 4ade0541de712fbf151ac7a2403613a1dbdb25b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Date: Thu, 25 Feb 2016 14:06:30 +0100 Subject: [PATCH 13/13] trace: Add a proper API to manage auto-generated events from the 'tcg' property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Formalizes the existence of the 'event_trans' and 'event_exec' event attributes, which until now were monkey-patched only when necessary. Signed-off-by: Lluís Vilanova Message-id: 145640558759.20978.6374959404425591089.stgit@localhost Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 23caba08e9..be24039c5e 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -163,7 +163,8 @@ class Event(object): _VALID_PROPS = set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu"]) - def __init__(self, name, props, fmt, args, orig=None): + def __init__(self, name, props, fmt, args, orig=None, + event_trans=None, event_exec=None): """ Parameters ---------- @@ -176,13 +177,19 @@ class Event(object): args : Arguments Event arguments. orig : Event or None - Original Event before transformation. + Original Event before transformation/generation. + event_trans : Event or None + Generated translation-time event ("tcg" property). + event_exec : Event or None + Generated execution-time event ("tcg" property). """ self.name = name self.properties = props self.fmt = fmt self.args = args + self.event_trans = event_trans + self.event_exec = event_exec if orig is None: self.original = weakref.ref(self) @@ -198,7 +205,7 @@ class Event(object): def copy(self): """Create a new copy.""" return Event(self.name, list(self.properties), self.fmt, - self.args.copy(), self) + self.args.copy(), self, self.event_trans, self.event_exec) @staticmethod def build(line_str):