Lines Matching full:decoder

48 static int pt_blk_status(const struct pt_block_decoder *decoder, int flags)  in pt_blk_status()  argument
52 if (!decoder) in pt_blk_status()
55 status = decoder->status; in pt_blk_status()
62 if (!decoder->enabled) in pt_blk_status()
69 if ((status & pts_eos) && !decoder->process_event) in pt_blk_status()
75 static void pt_blk_reset(struct pt_block_decoder *decoder) in pt_blk_reset() argument
77 if (!decoder) in pt_blk_reset()
80 decoder->mode = ptem_unknown; in pt_blk_reset()
81 decoder->ip = 0ull; in pt_blk_reset()
82 decoder->status = 0; in pt_blk_reset()
83 decoder->enabled = 0; in pt_blk_reset()
84 decoder->process_event = 0; in pt_blk_reset()
85 decoder->speculative = 0; in pt_blk_reset()
86 decoder->process_insn = 0; in pt_blk_reset()
87 decoder->bound_paging = 0; in pt_blk_reset()
88 decoder->bound_vmcs = 0; in pt_blk_reset()
89 decoder->bound_ptwrite = 0; in pt_blk_reset()
91 memset(&decoder->event, 0, sizeof(decoder->event)); in pt_blk_reset()
92 pt_retstack_init(&decoder->retstack); in pt_blk_reset()
93 pt_asid_init(&decoder->asid); in pt_blk_reset()
96 /* Initialize the query decoder flags based on our flags. */
111 int pt_blk_decoder_init(struct pt_block_decoder *decoder, in pt_blk_decoder_init() argument
117 if (!decoder) in pt_blk_decoder_init()
124 /* The user supplied decoder flags. */ in pt_blk_decoder_init()
125 decoder->flags = config.flags; in pt_blk_decoder_init()
127 /* Set the flags we need for the query decoder we use. */ in pt_blk_decoder_init()
128 errcode = pt_blk_init_qry_flags(&config.flags, &decoder->flags); in pt_blk_decoder_init()
132 errcode = pt_qry_decoder_init(&decoder->query, &config); in pt_blk_decoder_init()
136 pt_image_init(&decoder->default_image, NULL); in pt_blk_decoder_init()
137 decoder->image = &decoder->default_image; in pt_blk_decoder_init()
139 errcode = pt_msec_cache_init(&decoder->scache); in pt_blk_decoder_init()
143 pt_blk_reset(decoder); in pt_blk_decoder_init()
148 void pt_blk_decoder_fini(struct pt_block_decoder *decoder) in pt_blk_decoder_fini() argument
150 if (!decoder) in pt_blk_decoder_fini()
153 pt_msec_cache_fini(&decoder->scache); in pt_blk_decoder_fini()
154 pt_image_fini(&decoder->default_image); in pt_blk_decoder_fini()
155 pt_qry_decoder_fini(&decoder->query); in pt_blk_decoder_fini()
161 struct pt_block_decoder *decoder; in pt_blk_alloc_decoder() local
164 decoder = malloc(sizeof(*decoder)); in pt_blk_alloc_decoder()
165 if (!decoder) in pt_blk_alloc_decoder()
168 errcode = pt_blk_decoder_init(decoder, config); in pt_blk_alloc_decoder()
170 free(decoder); in pt_blk_alloc_decoder()
174 return decoder; in pt_blk_alloc_decoder()
177 void pt_blk_free_decoder(struct pt_block_decoder *decoder) in pt_blk_free_decoder() argument
179 if (!decoder) in pt_blk_free_decoder()
182 pt_blk_decoder_fini(decoder); in pt_blk_free_decoder()
183 free(decoder); in pt_blk_free_decoder()
195 static int pt_blk_tick(struct pt_block_decoder *decoder, uint64_t ip) in pt_blk_tick() argument
202 if (!decoder) in pt_blk_tick()
206 if (!decoder->enabled) in pt_blk_tick()
220 if (decoder->process_event) in pt_blk_tick()
223 errcode = pt_qry_time(&decoder->query, &tsc, &lost_mtc, &lost_cyc); in pt_blk_tick()
230 ev = &decoder->event; in pt_blk_tick()
249 decoder->process_event = 1; in pt_blk_tick()
258 static int pt_blk_indirect_branch(struct pt_block_decoder *decoder, in pt_blk_indirect_branch() argument
264 if (!decoder) in pt_blk_indirect_branch()
267 evip = decoder->ip; in pt_blk_indirect_branch()
269 status = pt_qry_indirect_branch(&decoder->query, ip); in pt_blk_indirect_branch()
273 if (decoder->flags.variant.block.enable_tick_events) { in pt_blk_indirect_branch()
274 errcode = pt_blk_tick(decoder, evip); in pt_blk_indirect_branch()
286 static int pt_blk_cond_branch(struct pt_block_decoder *decoder, int *taken) in pt_blk_cond_branch() argument
290 if (!decoder) in pt_blk_cond_branch()
293 status = pt_qry_cond_branch(&decoder->query, taken); in pt_blk_cond_branch()
297 if (decoder->flags.variant.block.enable_tick_events) { in pt_blk_cond_branch()
298 errcode = pt_blk_tick(decoder, decoder->ip); in pt_blk_cond_branch()
306 static int pt_blk_start(struct pt_block_decoder *decoder, int status) in pt_blk_start() argument
308 if (!decoder) in pt_blk_start()
314 decoder->status = status; in pt_blk_start()
316 decoder->enabled = 1; in pt_blk_start()
326 return pt_blk_proceed_trailing_event(decoder, NULL); in pt_blk_start()
329 static int pt_blk_sync_reset(struct pt_block_decoder *decoder) in pt_blk_sync_reset() argument
331 if (!decoder) in pt_blk_sync_reset()
334 pt_blk_reset(decoder); in pt_blk_sync_reset()
339 int pt_blk_sync_forward(struct pt_block_decoder *decoder) in pt_blk_sync_forward() argument
343 if (!decoder) in pt_blk_sync_forward()
346 errcode = pt_blk_sync_reset(decoder); in pt_blk_sync_forward()
350 status = pt_qry_sync_forward(&decoder->query, &decoder->ip); in pt_blk_sync_forward()
352 return pt_blk_start(decoder, status); in pt_blk_sync_forward()
355 int pt_blk_sync_backward(struct pt_block_decoder *decoder) in pt_blk_sync_backward() argument
359 if (!decoder) in pt_blk_sync_backward()
362 errcode = pt_blk_sync_reset(decoder); in pt_blk_sync_backward()
366 status = pt_qry_sync_backward(&decoder->query, &decoder->ip); in pt_blk_sync_backward()
368 return pt_blk_start(decoder, status); in pt_blk_sync_backward()
371 int pt_blk_sync_set(struct pt_block_decoder *decoder, uint64_t offset) in pt_blk_sync_set() argument
375 if (!decoder) in pt_blk_sync_set()
378 errcode = pt_blk_sync_reset(decoder); in pt_blk_sync_set()
382 status = pt_qry_sync_set(&decoder->query, &decoder->ip, offset); in pt_blk_sync_set()
384 return pt_blk_start(decoder, status); in pt_blk_sync_set()
387 int pt_blk_get_offset(const struct pt_block_decoder *decoder, uint64_t *offset) in pt_blk_get_offset() argument
389 if (!decoder) in pt_blk_get_offset()
392 return pt_qry_get_offset(&decoder->query, offset); in pt_blk_get_offset()
395 int pt_blk_get_sync_offset(const struct pt_block_decoder *decoder, in pt_blk_get_sync_offset() argument
398 if (!decoder) in pt_blk_get_sync_offset()
401 return pt_qry_get_sync_offset(&decoder->query, offset); in pt_blk_get_sync_offset()
404 struct pt_image *pt_blk_get_image(struct pt_block_decoder *decoder) in pt_blk_get_image() argument
406 if (!decoder) in pt_blk_get_image()
409 return decoder->image; in pt_blk_get_image()
412 int pt_blk_set_image(struct pt_block_decoder *decoder, struct pt_image *image) in pt_blk_set_image() argument
414 if (!decoder) in pt_blk_set_image()
418 image = &decoder->default_image; in pt_blk_set_image()
420 decoder->image = image; in pt_blk_set_image()
425 pt_blk_get_config(const struct pt_block_decoder *decoder) in pt_blk_get_config() argument
427 if (!decoder) in pt_blk_get_config()
430 return pt_qry_get_config(&decoder->query); in pt_blk_get_config()
433 int pt_blk_time(struct pt_block_decoder *decoder, uint64_t *time, in pt_blk_time() argument
436 if (!decoder || !time) in pt_blk_time()
439 return pt_qry_time(&decoder->query, time, lost_mtc, lost_cyc); in pt_blk_time()
442 int pt_blk_core_bus_ratio(struct pt_block_decoder *decoder, uint32_t *cbr) in pt_blk_core_bus_ratio() argument
444 if (!decoder || !cbr) in pt_blk_core_bus_ratio()
447 return pt_qry_core_bus_ratio(&decoder->query, cbr); in pt_blk_core_bus_ratio()
450 int pt_blk_asid(const struct pt_block_decoder *decoder, struct pt_asid *asid, in pt_blk_asid() argument
453 if (!decoder || !asid) in pt_blk_asid()
456 return pt_asid_to_user(asid, &decoder->asid, size); in pt_blk_asid()
468 static inline int pt_blk_fetch_event(struct pt_block_decoder *decoder) in pt_blk_fetch_event() argument
472 if (!decoder) in pt_blk_fetch_event()
475 if (decoder->process_event) in pt_blk_fetch_event()
478 if (!(decoder->status & pts_event_pending)) in pt_blk_fetch_event()
481 status = pt_qry_event(&decoder->query, &decoder->event, in pt_blk_fetch_event()
482 sizeof(decoder->event)); in pt_blk_fetch_event()
486 decoder->process_event = 1; in pt_blk_fetch_event()
487 decoder->status = status; in pt_blk_fetch_event()
541 * Does not update @decoder->status. The caller is expected to do that.
545 * Returns -pte_internal if @pip, @decoder, @insn, or @iext are NULL.
548 static int pt_blk_next_ip(uint64_t *pip, struct pt_block_decoder *decoder, in pt_blk_next_ip() argument
554 if (!pip || !decoder || !insn || !iext) in pt_blk_next_ip()
567 status = pt_blk_cond_branch(decoder, &taken); in pt_blk_next_ip()
584 status = pt_blk_cond_branch(decoder, &taken); in pt_blk_next_ip()
598 errcode = pt_retstack_pop(&decoder->retstack, pip); in pt_blk_next_ip()
631 return pt_blk_indirect_branch(decoder, pip); in pt_blk_next_ip()
641 static int pt_blk_proceed_with_trace(struct pt_block_decoder *decoder, in pt_blk_proceed_with_trace() argument
647 if (!decoder) in pt_blk_proceed_with_trace()
650 status = pt_blk_next_ip(&decoder->ip, decoder, insn, iext); in pt_blk_proceed_with_trace()
654 /* Preserve the query decoder's response which indicates upcoming in pt_blk_proceed_with_trace()
657 decoder->status = status; in pt_blk_proceed_with_trace()
702 static inline int pt_blk_log_call(struct pt_block_decoder *decoder, in pt_blk_log_call() argument
706 if (!decoder || !insn || !iext) in pt_blk_log_call()
719 return pt_retstack_push(&decoder->retstack, insn->ip + insn->size); in pt_blk_log_call()
724 * Tries to decode the instruction at @decoder->ip and, on success, adds it to
738 static int pt_blk_proceed_one_insn(struct pt_block_decoder *decoder, in pt_blk_proceed_one_insn() argument
748 if (!decoder || !block || !pinsn || !piext) in pt_blk_proceed_one_insn()
763 insn.mode = decoder->mode; in pt_blk_proceed_one_insn()
764 insn.ip = decoder->ip; in pt_blk_proceed_one_insn()
766 status = pt_insn_decode(&insn, &iext, decoder->image, &decoder->asid); in pt_blk_proceed_one_insn()
788 status = pt_blk_log_call(decoder, &insn, &iext); in pt_blk_proceed_one_insn()
816 * Update @decoder->ip to point to the last IP that was reached. If we fail due
824 static int pt_blk_proceed_to_insn(struct pt_block_decoder *decoder, in pt_blk_proceed_to_insn() argument
833 if (!decoder || !insn || !predicate) in pt_blk_proceed_to_insn()
837 status = pt_blk_proceed_one_insn(decoder, block, insn, iext); in pt_blk_proceed_to_insn()
849 status = pt_insn_next_ip(&decoder->ip, insn, iext); in pt_blk_proceed_to_insn()
859 if ((decoder->flags.variant.block.end_on_call && in pt_blk_proceed_to_insn()
861 (decoder->flags.variant.block.end_on_jump && in pt_blk_proceed_to_insn()
878 * Update @decoder->ip to point to the last IP that was reached. If we fail due
886 static int pt_blk_proceed_to_ip(struct pt_block_decoder *decoder, in pt_blk_proceed_to_ip() argument
892 if (!decoder || !insn) in pt_blk_proceed_to_ip()
899 if (decoder->ip == ip) in pt_blk_proceed_to_ip()
902 status = pt_blk_proceed_one_insn(decoder, block, insn, iext); in pt_blk_proceed_to_ip()
907 status = pt_insn_next_ip(&decoder->ip, insn, iext); in pt_blk_proceed_to_ip()
920 if ((decoder->flags.variant.block.end_on_call && in pt_blk_proceed_to_ip()
922 (decoder->flags.variant.block.end_on_jump && in pt_blk_proceed_to_ip()
924 return (decoder->ip == ip ? 1 : 0); in pt_blk_proceed_to_ip()
937 * Update @decoder->ip to point to the last IP that was reached.
945 static int pt_blk_proceed_to_ip_with_trace(struct pt_block_decoder *decoder, in pt_blk_proceed_to_ip_with_trace() argument
958 status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, ip); in pt_blk_proceed_to_ip_with_trace()
965 return pt_blk_proceed_with_trace(decoder, &insn, &iext); in pt_blk_proceed_to_ip_with_trace()
1004 static int pt_blk_proceed_skl014(struct pt_block_decoder *decoder, in pt_blk_proceed_skl014() argument
1011 if (!decoder || !block || !insn || !iext) in pt_blk_proceed_skl014()
1014 addr_filter = &decoder->query.config.addr_filter; in pt_blk_proceed_skl014()
1018 status = pt_blk_proceed_to_insn(decoder, block, insn, iext, in pt_blk_proceed_skl014()
1050 decoder->ip = ip; in pt_blk_proceed_skl014()
1058 if ((decoder->flags.variant.block.end_on_call && in pt_blk_proceed_skl014()
1060 (decoder->flags.variant.block.end_on_jump && in pt_blk_proceed_skl014()
1079 static int pt_blk_proceed_to_disabled(struct pt_block_decoder *decoder, in pt_blk_proceed_to_disabled() argument
1085 if (!decoder || !block || !ev) in pt_blk_proceed_to_disabled()
1097 if (decoder->query.config.addr_filter.config.addr_cfg && in pt_blk_proceed_to_disabled()
1098 decoder->query.config.errata.skl014) in pt_blk_proceed_to_disabled()
1099 return pt_blk_proceed_skl014(decoder, block, insn, in pt_blk_proceed_to_disabled()
1108 return pt_blk_proceed_to_insn(decoder, block, insn, iext, in pt_blk_proceed_to_disabled()
1111 return pt_blk_proceed_to_ip(decoder, block, insn, iext, in pt_blk_proceed_to_disabled()
1117 * On a synchronous disable, @decoder->ip still points to the instruction to
1125 static int pt_blk_set_disable_resume_ip(struct pt_block_decoder *decoder, in pt_blk_set_disable_resume_ip() argument
1128 if (!decoder || !insn) in pt_blk_set_disable_resume_ip()
1134 decoder->ip = insn->ip + insn->size; in pt_blk_set_disable_resume_ip()
1138 decoder->ip = 0ull; in pt_blk_set_disable_resume_ip()
1155 static int pt_blk_proceed_to_async_paging(struct pt_block_decoder *decoder, in pt_blk_proceed_to_async_paging() argument
1161 if (!decoder || !ev) in pt_blk_proceed_to_async_paging()
1168 status = pt_blk_proceed_to_ip_with_trace(decoder, block, in pt_blk_proceed_to_async_paging()
1174 return (decoder->ip == ev->variant.async_paging.ip ? 1 : 0); in pt_blk_proceed_to_async_paging()
1187 static int pt_blk_proceed_to_async_vmcs(struct pt_block_decoder *decoder, in pt_blk_proceed_to_async_vmcs() argument
1193 if (!decoder || !ev) in pt_blk_proceed_to_async_vmcs()
1200 status = pt_blk_proceed_to_ip_with_trace(decoder, block, in pt_blk_proceed_to_async_vmcs()
1206 return (decoder->ip == ev->variant.async_vmcs.ip ? 1 : 0); in pt_blk_proceed_to_async_vmcs()
1219 static int pt_blk_proceed_to_exec_mode(struct pt_block_decoder *decoder, in pt_blk_proceed_to_exec_mode() argument
1225 if (!decoder || !ev) in pt_blk_proceed_to_exec_mode()
1232 status = pt_blk_proceed_to_ip_with_trace(decoder, block, in pt_blk_proceed_to_exec_mode()
1238 return (decoder->ip == ev->variant.exec_mode.ip ? 1 : 0); in pt_blk_proceed_to_exec_mode()
1256 static int pt_blk_proceed_to_ptwrite(struct pt_block_decoder *decoder, in pt_blk_proceed_to_ptwrite() argument
1277 * the last instruction in the current block and @decoder->ip will point in pt_blk_proceed_to_ptwrite()
1281 status = pt_blk_proceed_to_insn(decoder, block, insn, iext, in pt_blk_proceed_to_ptwrite()
1293 status = pt_blk_proceed_to_ip(decoder, block, insn, iext, in pt_blk_proceed_to_ptwrite()
1298 /* We reached the PTWRITE instruction and @decoder->ip points to in pt_blk_proceed_to_ptwrite()
1305 status = pt_blk_proceed_one_insn(decoder, block, insn, iext); in pt_blk_proceed_to_ptwrite()
1322 static int pt_blk_handle_erratum_skd022(struct pt_block_decoder *decoder, in pt_blk_handle_erratum_skd022() argument
1329 if (!decoder || !ev) in pt_blk_handle_erratum_skd022()
1332 insn.mode = decoder->mode; in pt_blk_handle_erratum_skd022()
1335 errcode = pt_insn_decode(&insn, &iext, decoder->image, &decoder->asid); in pt_blk_handle_erratum_skd022()
1367 static int pt_blk_postpone_insn(struct pt_block_decoder *decoder, in pt_blk_postpone_insn() argument
1371 if (!decoder || !insn || !iext) in pt_blk_postpone_insn()
1375 if (decoder->process_insn) in pt_blk_postpone_insn()
1378 decoder->process_insn = 1; in pt_blk_postpone_insn()
1379 decoder->insn = *insn; in pt_blk_postpone_insn()
1380 decoder->iext = *iext; in pt_blk_postpone_insn()
1382 return pt_blk_status(decoder, pts_event_pending); in pt_blk_postpone_insn()
1385 /* Remove any postponed instruction from @decoder.
1389 static int pt_blk_clear_postponed_insn(struct pt_block_decoder *decoder) in pt_blk_clear_postponed_insn() argument
1391 if (!decoder) in pt_blk_clear_postponed_insn()
1394 decoder->process_insn = 0; in pt_blk_clear_postponed_insn()
1395 decoder->bound_paging = 0; in pt_blk_clear_postponed_insn()
1396 decoder->bound_vmcs = 0; in pt_blk_clear_postponed_insn()
1397 decoder->bound_ptwrite = 0; in pt_blk_clear_postponed_insn()
1404 * If an instruction has been postponed in @decoder, proceed past it.
1408 static int pt_blk_proceed_postponed_insn(struct pt_block_decoder *decoder) in pt_blk_proceed_postponed_insn() argument
1412 if (!decoder) in pt_blk_proceed_postponed_insn()
1416 if (!decoder->process_insn) in pt_blk_proceed_postponed_insn()
1420 if (!decoder->enabled) in pt_blk_proceed_postponed_insn()
1421 return pt_blk_clear_postponed_insn(decoder); in pt_blk_proceed_postponed_insn()
1423 status = pt_insn_next_ip(&decoder->ip, &decoder->insn, &decoder->iext); in pt_blk_proceed_postponed_insn()
1428 status = pt_blk_proceed_with_trace(decoder, &decoder->insn, in pt_blk_proceed_postponed_insn()
1429 &decoder->iext); in pt_blk_proceed_postponed_insn()
1434 return pt_blk_clear_postponed_insn(decoder); in pt_blk_proceed_postponed_insn()
1455 static int pt_blk_proceed_event(struct pt_block_decoder *decoder, in pt_blk_proceed_event() argument
1463 if (!decoder || !decoder->process_event || !block) in pt_blk_proceed_event()
1466 ev = &decoder->event; in pt_blk_proceed_event()
1472 status = pt_blk_proceed_to_disabled(decoder, block, &insn, in pt_blk_proceed_event()
1482 status = pt_blk_set_disable_resume_ip(decoder, &insn); in pt_blk_proceed_event()
1490 status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, in pt_blk_proceed_event()
1495 if (decoder->query.config.errata.skd022) { in pt_blk_proceed_event()
1496 status = pt_blk_handle_erratum_skd022(decoder, ev); in pt_blk_proceed_event()
1504 return pt_blk_proceed_event(decoder, block); in pt_blk_proceed_event()
1511 status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, in pt_blk_proceed_event()
1519 if (!decoder->enabled) in pt_blk_proceed_event()
1522 status = pt_blk_proceed_to_insn(decoder, block, &insn, &iext, in pt_blk_proceed_event()
1530 decoder->bound_paging = 1; in pt_blk_proceed_event()
1532 return pt_blk_postpone_insn(decoder, &insn, &iext); in pt_blk_proceed_event()
1535 status = pt_blk_proceed_to_async_paging(decoder, block, ev); in pt_blk_proceed_event()
1542 if (!decoder->enabled) in pt_blk_proceed_event()
1545 status = pt_blk_proceed_to_insn(decoder, block, &insn, &iext, in pt_blk_proceed_event()
1553 decoder->bound_vmcs = 1; in pt_blk_proceed_event()
1555 return pt_blk_postpone_insn(decoder, &insn, &iext); in pt_blk_proceed_event()
1558 status = pt_blk_proceed_to_async_vmcs(decoder, block, ev); in pt_blk_proceed_event()
1568 status = pt_blk_proceed_to_exec_mode(decoder, block, ev); in pt_blk_proceed_event()
1578 status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, in pt_blk_proceed_event()
1589 if (!decoder->enabled || ev->ip_suppressed) in pt_blk_proceed_event()
1592 status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, in pt_blk_proceed_event()
1600 if (!decoder->enabled || ev->ip_suppressed) in pt_blk_proceed_event()
1603 status = pt_blk_proceed_to_ip(decoder, block, &insn, &iext, in pt_blk_proceed_event()
1615 if (!decoder->enabled) in pt_blk_proceed_event()
1618 status = pt_blk_proceed_to_ptwrite(decoder, block, &insn, in pt_blk_proceed_event()
1626 decoder->bound_ptwrite = 1; in pt_blk_proceed_event()
1628 return pt_blk_postpone_insn(decoder, &insn, &iext); in pt_blk_proceed_event()
1636 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_event()
1648 * block. This only updates @decoder's internal state, though.
1652 static int pt_blk_proceed_no_event_uncached(struct pt_block_decoder *decoder, in pt_blk_proceed_no_event_uncached() argument
1659 if (!decoder || !block) in pt_blk_proceed_no_event_uncached()
1669 status = pt_blk_proceed_to_insn(decoder, block, &insn, &iext, in pt_blk_proceed_no_event_uncached()
1675 return pt_blk_proceed_with_trace(decoder, &insn, &iext); in pt_blk_proceed_no_event_uncached()
1760 /* Proceed to the next instruction and fill the block cache for @decoder->ip.
1775 pt_blk_proceed_no_event_fill_cache(struct pt_block_decoder *decoder, in pt_blk_proceed_no_event_fill_cache() argument
1788 if (!decoder || !steps) in pt_blk_proceed_no_event_fill_cache()
1796 status = pt_blk_proceed_one_insn(decoder, block, &insn, &iext); in pt_blk_proceed_no_event_fill_cache()
1806 status = pt_insn_next_ip(&decoder->ip, &insn, &iext); in pt_blk_proceed_no_event_fill_cache()
1871 return pt_blk_proceed_with_trace(decoder, &insn, &iext); in pt_blk_proceed_no_event_fill_cache()
1875 nip = decoder->ip; in pt_blk_proceed_no_event_fill_cache()
1893 * @decoder->flags.variant.block.end_on_call is set, though. in pt_blk_proceed_no_event_fill_cache()
1945 decoder->flags.variant.block.end_on_jump) in pt_blk_proceed_no_event_fill_cache()
1981 status = pt_blk_proceed_no_event_fill_cache(decoder, block, in pt_blk_proceed_no_event_fill_cache()
2052 * We were not able to decode the instruction at @decoder->ip in @decoder's
2061 static int pt_blk_proceed_truncated(struct pt_block_decoder *decoder, in pt_blk_proceed_truncated() argument
2068 if (!decoder || !block) in pt_blk_proceed_truncated()
2074 insn.mode = decoder->mode; in pt_blk_proceed_truncated()
2075 insn.ip = decoder->ip; in pt_blk_proceed_truncated()
2077 errcode = pt_insn_decode(&insn, &iext, decoder->image, &decoder->asid); in pt_blk_proceed_truncated()
2092 errcode = pt_blk_log_call(decoder, &insn, &iext); in pt_blk_proceed_truncated()
2101 errcode = pt_insn_next_ip(&decoder->ip, &insn, &iext); in pt_blk_proceed_truncated()
2106 return pt_blk_proceed_with_trace(decoder, &insn, &iext); in pt_blk_proceed_truncated()
2124 * block. This only updates @decoder's internal state, though.
2128 static int pt_blk_proceed_no_event_cached(struct pt_block_decoder *decoder, in pt_blk_proceed_no_event_cached() argument
2138 if (!decoder || !block) in pt_blk_proceed_no_event_cached()
2141 offset = pt_msec_unmap(msec, decoder->ip); in pt_blk_proceed_no_event_cached()
2148 return pt_blk_proceed_no_event_fill_cache(decoder, block, in pt_blk_proceed_no_event_cached()
2172 nip = decoder->ip + (uint64_t) (int64_t) bce.displacement; in pt_blk_proceed_no_event_cached()
2174 return pt_blk_proceed_no_event_uncached(decoder, block); in pt_blk_proceed_no_event_cached()
2195 decoder->ip = nip; in pt_blk_proceed_no_event_cached()
2218 return pt_blk_proceed_no_event_cached(decoder, block, bcache, in pt_blk_proceed_no_event_cached()
2237 * the instruction at @decoder->ip. in pt_blk_proceed_no_event_cached()
2243 status = pt_blk_cond_branch(decoder, &taken); in pt_blk_proceed_no_event_cached()
2247 /* Preserve the query decoder's response which indicates in pt_blk_proceed_no_event_cached()
2250 decoder->status = status; in pt_blk_proceed_no_event_cached()
2252 ip = decoder->ip; in pt_blk_proceed_no_event_cached()
2272 decoder->ip = ip + bce.isize; in pt_blk_proceed_no_event_cached()
2281 /* We need to decode the instruction at @decoder->ip and decide in pt_blk_proceed_no_event_cached()
2292 insn.ip = decoder->ip; in pt_blk_proceed_no_event_cached()
2299 return pt_blk_proceed_truncated(decoder, block); in pt_blk_proceed_no_event_cached()
2306 status = pt_blk_log_call(decoder, &insn, &iext); in pt_blk_proceed_no_event_cached()
2315 status = pt_insn_next_ip(&decoder->ip, &insn, &iext); in pt_blk_proceed_no_event_cached()
2323 return pt_blk_proceed_with_trace(decoder, &insn, &iext); in pt_blk_proceed_no_event_cached()
2332 if ((decoder->flags.variant.block.end_on_call && in pt_blk_proceed_no_event_cached()
2334 (decoder->flags.variant.block.end_on_jump && in pt_blk_proceed_no_event_cached()
2343 if (!pt_blk_is_in_section(msec, decoder->ip)) in pt_blk_proceed_no_event_cached()
2346 return pt_blk_proceed_no_event_cached(decoder, block, bcache, in pt_blk_proceed_no_event_cached()
2359 ip = decoder->ip; in pt_blk_proceed_no_event_cached()
2383 status = pt_retstack_push(&decoder->retstack, ip); in pt_blk_proceed_no_event_cached()
2387 status = pt_blk_indirect_branch(decoder, &decoder->ip); in pt_blk_proceed_no_event_cached()
2391 /* Preserve the query decoder's response which indicates in pt_blk_proceed_no_event_cached()
2394 decoder->status = status; in pt_blk_proceed_no_event_cached()
2405 status = pt_blk_cond_branch(decoder, &taken); in pt_blk_proceed_no_event_cached()
2413 status = pt_blk_indirect_branch(decoder, &decoder->ip); in pt_blk_proceed_no_event_cached()
2417 /* Preserve the query decoder's response which indicates in pt_blk_proceed_no_event_cached()
2420 decoder->status = status; in pt_blk_proceed_no_event_cached()
2424 /* Preserve the query decoder's response which indicates in pt_blk_proceed_no_event_cached()
2427 decoder->status = status; in pt_blk_proceed_no_event_cached()
2435 return pt_retstack_pop(&decoder->retstack, &decoder->ip); in pt_blk_proceed_no_event_cached()
2454 status = pt_blk_indirect_branch(decoder, &decoder->ip); in pt_blk_proceed_no_event_cached()
2458 /* Preserve the query decoder's response which indicates in pt_blk_proceed_no_event_cached()
2461 decoder->status = status; in pt_blk_proceed_no_event_cached()
2468 static int pt_blk_msec_fill(struct pt_block_decoder *decoder, in pt_blk_msec_fill() argument
2475 if (!decoder || !pmsec) in pt_blk_msec_fill()
2478 isid = pt_msec_cache_fill(&decoder->scache, &msec, decoder->image, in pt_blk_msec_fill()
2479 &decoder->asid, decoder->ip); in pt_blk_msec_fill()
2496 static inline int pt_blk_msec_lookup(struct pt_block_decoder *decoder, in pt_blk_msec_lookup() argument
2501 if (!decoder) in pt_blk_msec_lookup()
2504 isid = pt_msec_cache_read(&decoder->scache, pmsec, decoder->image, in pt_blk_msec_lookup()
2505 decoder->ip); in pt_blk_msec_lookup()
2510 return pt_blk_msec_fill(decoder, pmsec); in pt_blk_msec_lookup()
2525 * block. This only updates @decoder's internal state, though.
2529 static int pt_blk_proceed_no_event(struct pt_block_decoder *decoder, in pt_blk_proceed_no_event() argument
2537 if (!decoder || !block) in pt_blk_proceed_no_event()
2540 isid = pt_blk_msec_lookup(decoder, &msec); in pt_blk_proceed_no_event()
2548 return pt_blk_proceed_no_event_uncached(decoder, block); in pt_blk_proceed_no_event()
2565 return pt_blk_proceed_no_event_uncached(decoder, block); in pt_blk_proceed_no_event()
2567 return pt_blk_proceed_no_event_cached(decoder, block, bcache, msec); in pt_blk_proceed_no_event()
2575 static int pt_blk_proceed(struct pt_block_decoder *decoder, in pt_blk_proceed() argument
2580 status = pt_blk_fetch_event(decoder); in pt_blk_proceed()
2585 return pt_blk_proceed_event(decoder, block); in pt_blk_proceed()
2591 if (!decoder->enabled) { in pt_blk_proceed()
2592 if (decoder->status & pts_eos) in pt_blk_proceed()
2598 status = pt_blk_proceed_no_event(decoder, block); in pt_blk_proceed()
2602 return pt_blk_proceed_trailing_event(decoder, block); in pt_blk_proceed()
2621 static int pt_blk_handle_erratum_bdm64(struct pt_block_decoder *decoder, in pt_blk_handle_erratum_bdm64() argument
2629 if (!decoder || !block || !ev) in pt_blk_handle_erratum_bdm64()
2647 status = pt_insn_decode(&insn, &iext, decoder->image, &decoder->asid); in pt_blk_handle_erratum_bdm64()
2659 status = pt_insn_range_is_contiguous(decoder->ip, ev->variant.tsx.ip, in pt_blk_handle_erratum_bdm64()
2660 decoder->mode, decoder->image, in pt_blk_handle_erratum_bdm64()
2661 &decoder->asid, bdm64_max_steps); in pt_blk_handle_erratum_bdm64()
2671 decoder->ip = ev->variant.tsx.ip; in pt_blk_handle_erratum_bdm64()
2684 static inline int pt_blk_postpone_trailing_tsx(struct pt_block_decoder *decoder, in pt_blk_postpone_trailing_tsx() argument
2690 if (!decoder || !ev) in pt_blk_postpone_trailing_tsx()
2696 if (block && decoder->query.config.errata.bdm64) { in pt_blk_postpone_trailing_tsx()
2697 status = pt_blk_handle_erratum_bdm64(decoder, block, ev); in pt_blk_postpone_trailing_tsx()
2702 if (decoder->ip != ev->variant.tsx.ip) in pt_blk_postpone_trailing_tsx()
2708 /* Proceed with events that bind to the current decoder IP.
2722 static int pt_blk_proceed_trailing_event(struct pt_block_decoder *decoder, in pt_blk_proceed_trailing_event() argument
2728 if (!decoder) in pt_blk_proceed_trailing_event()
2731 status = pt_blk_fetch_event(decoder); in pt_blk_proceed_trailing_event()
2736 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2740 return pt_blk_status(decoder, 0); in pt_blk_proceed_trailing_event()
2743 ev = &decoder->event; in pt_blk_proceed_trailing_event()
2749 if (!decoder->process_insn) in pt_blk_proceed_trailing_event()
2754 pt_insn_changes_cr3(&decoder->insn, &decoder->iext)) in pt_blk_proceed_trailing_event()
2755 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2763 status = pt_insn_next_ip(&decoder->ip, &decoder->insn, in pt_blk_proceed_trailing_event()
2764 &decoder->iext); in pt_blk_proceed_trailing_event()
2769 status = pt_blk_set_disable_resume_ip(decoder, in pt_blk_proceed_trailing_event()
2770 &decoder->insn); in pt_blk_proceed_trailing_event()
2774 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2778 status = pt_blk_clear_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2784 decoder->ip == ev->variant.disabled.ip) in pt_blk_proceed_trailing_event()
2785 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2791 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2795 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2799 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2803 if (decoder->ip != ev->variant.async_disabled.at) in pt_blk_proceed_trailing_event()
2806 if (decoder->query.config.errata.skd022) { in pt_blk_proceed_trailing_event()
2807 status = pt_blk_handle_erratum_skd022(decoder, ev); in pt_blk_proceed_trailing_event()
2821 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2825 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2829 if (decoder->ip != ev->variant.async_branch.from) in pt_blk_proceed_trailing_event()
2832 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2836 if (!decoder->enabled) in pt_blk_proceed_trailing_event()
2837 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2845 if (!decoder->process_insn || decoder->bound_paging) in pt_blk_proceed_trailing_event()
2852 if (!pt_insn_binds_to_pip(&decoder->insn, &decoder->iext)) in pt_blk_proceed_trailing_event()
2858 decoder->bound_paging = 1; in pt_blk_proceed_trailing_event()
2860 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2864 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2869 decoder->ip != ev->variant.async_paging.ip) in pt_blk_proceed_trailing_event()
2872 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2876 if (!decoder->enabled) in pt_blk_proceed_trailing_event()
2877 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2885 if (!decoder->process_insn || decoder->bound_vmcs) in pt_blk_proceed_trailing_event()
2892 if (!pt_insn_binds_to_vmcs(&decoder->insn, &decoder->iext)) in pt_blk_proceed_trailing_event()
2898 decoder->bound_vmcs = 1; in pt_blk_proceed_trailing_event()
2900 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2904 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2909 decoder->ip != ev->variant.async_vmcs.ip) in pt_blk_proceed_trailing_event()
2912 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2916 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2920 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2924 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2929 decoder->ip != ev->variant.exec_mode.ip) in pt_blk_proceed_trailing_event()
2932 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2936 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2940 status = pt_blk_postpone_trailing_tsx(decoder, block, ev); in pt_blk_proceed_trailing_event()
2948 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2952 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2956 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2960 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2964 if (!ev->ip_suppressed && decoder->enabled && in pt_blk_proceed_trailing_event()
2965 decoder->ip != ev->variant.exstop.ip) in pt_blk_proceed_trailing_event()
2968 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2972 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2976 if (!ev->ip_suppressed && decoder->enabled && in pt_blk_proceed_trailing_event()
2977 decoder->ip != ev->variant.mwait.ip) in pt_blk_proceed_trailing_event()
2980 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2985 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
2989 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
2993 if (!decoder->enabled) in pt_blk_proceed_trailing_event()
2994 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
3001 if (!decoder->process_insn || decoder->bound_ptwrite) in pt_blk_proceed_trailing_event()
3009 !pt_insn_is_ptwrite(&decoder->insn, &decoder->iext)) in pt_blk_proceed_trailing_event()
3015 decoder->bound_ptwrite = 1; in pt_blk_proceed_trailing_event()
3017 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
3023 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
3027 return pt_blk_status(decoder, pts_event_pending); in pt_blk_proceed_trailing_event()
3031 status = pt_blk_proceed_postponed_insn(decoder); in pt_blk_proceed_trailing_event()
3035 return pt_blk_status(decoder, 0); in pt_blk_proceed_trailing_event()
3038 int pt_blk_next(struct pt_block_decoder *decoder, struct pt_block *ublock, in pt_blk_next() argument
3044 if (!decoder || !ublock) in pt_blk_next()
3060 pblock->ip = decoder->ip; in pt_blk_next()
3061 pblock->mode = decoder->mode; in pt_blk_next()
3062 if (decoder->speculative) in pt_blk_next()
3066 status = pt_blk_proceed(decoder, pblock); in pt_blk_next()
3079 static int pt_blk_process_enabled(struct pt_block_decoder *decoder, in pt_blk_process_enabled() argument
3082 if (!decoder || !ev) in pt_blk_process_enabled()
3094 if (decoder->enabled) in pt_blk_process_enabled()
3097 decoder->ip = ev->variant.enabled.ip; in pt_blk_process_enabled()
3098 decoder->enabled = 1; in pt_blk_process_enabled()
3099 decoder->process_event = 0; in pt_blk_process_enabled()
3108 static int pt_blk_process_disabled(struct pt_block_decoder *decoder, in pt_blk_process_disabled() argument
3111 if (!decoder || !ev) in pt_blk_process_disabled()
3119 if (!decoder->enabled) in pt_blk_process_disabled()
3122 /* We preserve @decoder->ip. This is where we expect tracing to resume in pt_blk_process_disabled()
3126 decoder->enabled = 0; in pt_blk_process_disabled()
3127 decoder->process_event = 0; in pt_blk_process_disabled()
3136 static int pt_blk_process_async_branch(struct pt_block_decoder *decoder, in pt_blk_process_async_branch() argument
3139 if (!decoder || !ev) in pt_blk_process_async_branch()
3147 if (!decoder->enabled) in pt_blk_process_async_branch()
3153 decoder->ip = ev->variant.async_branch.to; in pt_blk_process_async_branch()
3154 decoder->process_event = 0; in pt_blk_process_async_branch()
3163 static int pt_blk_process_paging(struct pt_block_decoder *decoder, in pt_blk_process_paging() argument
3169 if (!decoder || !ev) in pt_blk_process_paging()
3173 if (decoder->asid.cr3 != cr3) { in pt_blk_process_paging()
3174 errcode = pt_msec_cache_invalidate(&decoder->scache); in pt_blk_process_paging()
3178 decoder->asid.cr3 = cr3; in pt_blk_process_paging()
3181 decoder->process_event = 0; in pt_blk_process_paging()
3190 static int pt_blk_process_vmcs(struct pt_block_decoder *decoder, in pt_blk_process_vmcs() argument
3196 if (!decoder || !ev) in pt_blk_process_vmcs()
3200 if (decoder->asid.vmcs != vmcs) { in pt_blk_process_vmcs()
3201 errcode = pt_msec_cache_invalidate(&decoder->scache); in pt_blk_process_vmcs()
3205 decoder->asid.vmcs = vmcs; in pt_blk_process_vmcs()
3208 decoder->process_event = 0; in pt_blk_process_vmcs()
3217 static int pt_blk_process_overflow(struct pt_block_decoder *decoder, in pt_blk_process_overflow() argument
3220 if (!decoder || !ev) in pt_blk_process_overflow()
3236 decoder->enabled = 0; in pt_blk_process_overflow()
3237 decoder->ip = 0ull; in pt_blk_process_overflow()
3242 decoder->enabled = 1; in pt_blk_process_overflow()
3243 decoder->ip = ev->variant.overflow.ip; in pt_blk_process_overflow()
3252 decoder->speculative = 0; in pt_blk_process_overflow()
3253 decoder->process_event = 0; in pt_blk_process_overflow()
3262 static int pt_blk_process_exec_mode(struct pt_block_decoder *decoder, in pt_blk_process_exec_mode() argument
3267 if (!decoder || !ev) in pt_blk_process_exec_mode()
3272 if (ev->status_update && decoder->enabled && in pt_blk_process_exec_mode()
3273 decoder->mode != ptem_unknown && decoder->mode != mode) in pt_blk_process_exec_mode()
3276 decoder->mode = mode; in pt_blk_process_exec_mode()
3277 decoder->process_event = 0; in pt_blk_process_exec_mode()
3286 static int pt_blk_process_tsx(struct pt_block_decoder *decoder, in pt_blk_process_tsx() argument
3289 if (!decoder || !ev) in pt_blk_process_tsx()
3292 decoder->speculative = ev->variant.tsx.speculative; in pt_blk_process_tsx()
3293 decoder->process_event = 0; in pt_blk_process_tsx()
3302 static int pt_blk_process_stop(struct pt_block_decoder *decoder, in pt_blk_process_stop() argument
3305 if (!decoder || !ev) in pt_blk_process_stop()
3313 if (decoder->enabled) in pt_blk_process_stop()
3316 decoder->process_event = 0; in pt_blk_process_stop()
3321 int pt_blk_event(struct pt_block_decoder *decoder, struct pt_event *uevent, in pt_blk_event() argument
3327 if (!decoder || !uevent) in pt_blk_event()
3331 if (!decoder->process_event) in pt_blk_event()
3334 ev = &decoder->event; in pt_blk_event()
3341 if (ev->variant.enabled.ip == decoder->ip) in pt_blk_event()
3344 status = pt_blk_process_enabled(decoder, ev); in pt_blk_event()
3351 if (decoder->ip != ev->variant.async_disabled.at) in pt_blk_event()
3357 status = pt_blk_process_disabled(decoder, ev); in pt_blk_event()
3364 if (decoder->ip != ev->variant.async_branch.from) in pt_blk_event()
3367 status = pt_blk_process_async_branch(decoder, ev); in pt_blk_event()
3375 decoder->ip != ev->variant.async_paging.ip) in pt_blk_event()
3380 status = pt_blk_process_paging(decoder, ev); in pt_blk_event()
3388 decoder->ip != ev->variant.async_vmcs.ip) in pt_blk_event()
3393 status = pt_blk_process_vmcs(decoder, ev); in pt_blk_event()
3400 status = pt_blk_process_overflow(decoder, ev); in pt_blk_event()
3408 decoder->ip != ev->variant.exec_mode.ip) in pt_blk_event()
3411 status = pt_blk_process_exec_mode(decoder, ev); in pt_blk_event()
3418 if (!ev->ip_suppressed && decoder->ip != ev->variant.tsx.ip) in pt_blk_event()
3421 status = pt_blk_process_tsx(decoder, ev); in pt_blk_event()
3428 status = pt_blk_process_stop(decoder, ev); in pt_blk_event()
3435 if (!ev->ip_suppressed && decoder->enabled && in pt_blk_event()
3436 decoder->ip != ev->variant.exstop.ip) in pt_blk_event()
3439 decoder->process_event = 0; in pt_blk_event()
3443 if (!ev->ip_suppressed && decoder->enabled && in pt_blk_event()
3444 decoder->ip != ev->variant.mwait.ip) in pt_blk_event()
3447 decoder->process_event = 0; in pt_blk_event()
3456 decoder->process_event = 0; in pt_blk_event()
3472 return pt_blk_proceed_trailing_event(decoder, NULL); in pt_blk_event()