2 files changed, 30 insertions(+), 11 deletions(-) include/linux/kvm.h | 17 ++++++++++++++--- virt/kvm/kvm_trace.c | 24 ++++++++++++++++--------
*Updates: Create global definitions for setting trace records as opposed to explicitly setting them inside of a function. This patch fixes kvmtrace use on big endian systems. When using bit fields the compiler will lay data out in the wrong order expected when laid down into a file. This fixes it by using one variable instead of using bit fields. Signed-off-by: Jerone Young <[EMAIL PROTECTED]> diff --git a/include/linux/kvm.h b/include/linux/kvm.h --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -311,9 +311,13 @@ struct kvm_s390_interrupt { /* This structure represents a single trace buffer record. */ struct kvm_trace_rec { - __u32 event:28; - __u32 extra_u32:3; - __u32 cycle_in:1; + /* variable rec_val + * is split into: + * bits 0 - 27 -> event id + * bits 28 -30 -> number of extra data args of size u32 + * bits 31 -> binary indicator for if tsc is in record + */ + __u32 rec_val; __u32 pid; __u32 vcpu_id; union { @@ -326,6 +330,13 @@ struct kvm_trace_rec { } nocycle; } u; } __attribute__((packed)); + +#define TRACE_REC_EVENT_ID (val) \ + (0x0fffffff & (val)) +#define TRACE_REC_NUM_DATA_ARGS (val) \ + (0x70000000 & (val << 28)) +#define TRACE_REC_TCS (val) \ + (0x80000000 & (val << 31)) #define KVMIO 0xAE diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c --- a/virt/kvm/kvm_trace.c +++ b/virt/kvm/kvm_trace.c @@ -54,12 +54,17 @@ static void kvm_add_trace(void *probe_pr struct kvm_trace *kt = kvm_trace; struct kvm_trace_rec rec; struct kvm_vcpu *vcpu; - int i, extra, size; + int i, size; + u32 extra; if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING)) return; - rec.event = va_arg(*args, u32); + rec.rec_val = 0; + + /* set event id */ + rec.rec_val |= TRACE_REC_EVENT_ID(va_arg(*args, u32)); + vcpu = va_arg(*args, struct kvm_vcpu *); rec.pid = current->tgid; rec.vcpu_id = vcpu->vcpu_id; @@ -67,21 +72,24 @@ static void kvm_add_trace(void *probe_pr extra = va_arg(*args, u32); WARN_ON(!(extra <= KVM_TRC_EXTRA_MAX)); extra = min_t(u32, extra, KVM_TRC_EXTRA_MAX); - rec.extra_u32 = extra; - rec.cycle_in = p->cycle_in; + /* set inidicator for tcs record */ + rec.rec_val |= TRACE_REC_TCS(p->cycle_in); - if (rec.cycle_in) { + /* set extra data num */ + rec.rec_val |= TRACE_REC_NUM_DATA_ARGS(extra); + + if (p->cycle_in) { rec.u.cycle.cycle_u64 = get_cycles(); - for (i = 0; i < rec.extra_u32; i++) + for (i = 0; i < extra; i++) rec.u.cycle.extra_u32[i] = va_arg(*args, u32); } else { - for (i = 0; i < rec.extra_u32; i++) + for (i = 0; i < extra; i++) rec.u.nocycle.extra_u32[i] = va_arg(*args, u32); } - size = calc_rec_size(rec.cycle_in, rec.extra_u32 * sizeof(u32)); + size = calc_rec_size(p->cycle_in, extra * sizeof(u32)); relay_write(kt->rchan, &rec, size); } -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html