Skip to content

Commit aae0d6e

Browse files
committed
kvm: decode data written to and read from I/O ports
With the "-e kvm=vcpu+" option, strace now decodes data written to and read from I/O ports. * src/kvm.c (kvm_run_structure_decode_io): Decode data written to or read from I/O ports as a byte array. (kvm_run_structure_decode_main): Add struct vcpu_info as a new parameter and pass it down to kvm_run_structure_decode_io(). (kvm_run_structure_decode): Pass a struct vcpu_info object to kvm_run_structure_decode_main. * tests/ioctl_kvm_run_common.c (run_kvm): Allocate buffer for run_before dynamically and copy entire mmap'ed region to the buffer. * tests/ioctl_kvm_run_auxstr_vcpu_more.c (print_kvm_run_more): Print data written to or read from I/O ports. Signed-off-by: Masatake YAMATO <yamato@redhat.com>
1 parent 96d7f83 commit aae0d6e

3 files changed

Lines changed: 26 additions & 7 deletions

File tree

src/kvm.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ kvm_ioctl(struct tcb *const tcp, const unsigned int code, const kernel_ulong_t a
454454

455455
static void
456456
kvm_run_structure_decode_io(struct tcb *tcp,
457-
struct kvm_run *state)
457+
struct kvm_run *state, struct vcpu_info *info)
458458
{
459459
tprints_field_name("io");
460460
tprint_struct_begin();
@@ -467,6 +467,18 @@ kvm_run_structure_decode_io(struct tcb *tcp,
467467
PRINT_FIELD_U(state->io, count);
468468
tprint_struct_next();
469469
PRINT_FIELD_0X(state->io, data_offset);
470+
471+
if (info) {
472+
unsigned long data = info->mmap_addr + state->io.data_offset;
473+
unsigned long data_len = state->io.size * state->io.count;
474+
unsigned char buf;
475+
476+
tprint_struct_next();
477+
tprints_field_name("data");
478+
print_array(tcp, data, data_len, &buf, sizeof(buf), tfetch_mem,
479+
print_xint_array_member, NULL);
480+
}
481+
470482
tprint_struct_end();
471483
}
472484

@@ -489,6 +501,7 @@ kvm_run_structure_decode_mmio(struct tcb *tcp,
489501
static void
490502
kvm_run_structure_decode_main(struct tcb *tcp,
491503
struct kvm_run *state,
504+
struct vcpu_info *info,
492505
const char *auxstr)
493506
{
494507
tprint_struct_begin();
@@ -527,7 +540,7 @@ kvm_run_structure_decode_main(struct tcb *tcp,
527540

528541
switch (state->exit_reason) {
529542
case KVM_EXIT_IO:
530-
DECODE_UNION(kvm_run_structure_decode_io(tcp, state));
543+
DECODE_UNION(kvm_run_structure_decode_io(tcp, state, info));
531544
break;
532545
case KVM_EXIT_MMIO:
533546
DECODE_UNION(kvm_run_structure_decode_mmio(tcp, state));
@@ -552,7 +565,7 @@ kvm_run_structure_decode(struct tcb * tcp)
552565
tprints_string(" VCPU< ");
553566
const char *auxstr = xlookup(kvm_exit_reason,
554567
tcp->vcpu_entering->exit_reason);
555-
kvm_run_structure_decode_main(tcp, tcp->vcpu_entering,
568+
kvm_run_structure_decode_main(tcp, tcp->vcpu_entering, info,
556569
auxstr);
557570
}
558571

@@ -567,7 +580,7 @@ kvm_run_structure_decode(struct tcb * tcp)
567580
tprintf_string(" VCPU:%d> ", info->cpuid);
568581
else
569582
tprints_string(" VCPU> ");
570-
kvm_run_structure_decode_main(tcp, tcp->vcpu_leaving,
583+
kvm_run_structure_decode_main(tcp, tcp->vcpu_leaving, info,
571584
tcp->auxstr);
572585
}
573586

tests/ioctl_kvm_run_auxstr_vcpu_more.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,16 @@ print_kvm_run_more(const char *prefix, const char *reason_str, const struct kvm_
3636
switch (run->exit_reason) {
3737
case KVM_EXIT_IO:
3838
printf(", {io={direction=%s"
39-
", size=%u, port=%#04x, count=%u, data_offset=%#016llx}}",
39+
", size=%u, port=%#04x, count=%u, data_offset=%#016llx",
4040
run->io.direction == KVM_EXIT_IO_IN
4141
? "KVM_EXIT_IO_IN" : "KVM_EXIT_IO_OUT",
4242
run->io.size, run->io.port,
4343
run->io.count, run->io.data_offset);
44+
fputs(", data=[", stdout);
45+
for (unsigned long i = 0; i < (run->io.size * run->io.count); ++i)
46+
printf("%s0x%x", i == 0? "" : ", ",
47+
((unsigned char *)run + run->io.data_offset)[i]);
48+
fputs("]}}", stdout);
4449
break;
4550
case KVM_EXIT_MMIO:
4651
printf(", {mmio={phys_addr=%#016llx"

tests/ioctl_kvm_run_common.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,10 +226,11 @@ run_kvm(const int vcpu_fd, struct kvm_run *const run, const size_t mmap_size,
226226
const char *p = "\n";
227227

228228
/* Repeatedly run code and handle VM exits. */
229+
struct kvm_run *run_before = tail_alloc(mmap_size);
229230
for (;;) {
230-
const struct kvm_run run_before = *run;
231+
memcpy(run_before, run, mmap_size);
231232
KVM_IOCTL(vcpu_fd, KVM_RUN, NULL);
232-
print_KVM_RUN(vcpu_fd, vcpu_dev, &run_before, run);
233+
print_KVM_RUN(vcpu_fd, vcpu_dev, run_before, run);
233234

234235
switch (run->exit_reason) {
235236
case KVM_EXIT_HLT:

0 commit comments

Comments
 (0)