aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Ehrhardt <ehrhardt@linux.vnet.ibm.com>2008-07-14 08:00:00 -0400
committerAvi Kivity <avi@qumranet.com>2008-10-15 04:15:14 -0400
commite32c8f2c0720fb21c6f4a5f6ccbebdadc878f707 (patch)
tree75329603864952437757705781520dc52906b51c
parent80e31d4f61f69d0e480ae092cda0e590d6a30aeb (diff)
KVM: kvmtrace: Remove use of bit fields in kvm trace structure
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 <jyoung5@us.ibm.com> Signed-off-by: Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--include/linux/kvm.h17
-rw-r--r--virt/kvm/kvm_trace.c17
2 files changed, 23 insertions, 11 deletions
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 8a3ceadb136..8a16b083df2 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -311,9 +311,13 @@ struct kvm_s390_interrupt {
311 311
312/* This structure represents a single trace buffer record. */ 312/* This structure represents a single trace buffer record. */
313struct kvm_trace_rec { 313struct kvm_trace_rec {
314 __u32 event:28; 314 /* variable rec_val
315 __u32 extra_u32:3; 315 * is split into:
316 __u32 cycle_in:1; 316 * bits 0 - 27 -> event id
317 * bits 28 -30 -> number of extra data args of size u32
318 * bits 31 -> binary indicator for if tsc is in record
319 */
320 __u32 rec_val;
317 __u32 pid; 321 __u32 pid;
318 __u32 vcpu_id; 322 __u32 vcpu_id;
319 union { 323 union {
@@ -327,6 +331,13 @@ struct kvm_trace_rec {
327 } u; 331 } u;
328}; 332};
329 333
334#define TRACE_REC_EVENT_ID(val) \
335 (0x0fffffff & (val))
336#define TRACE_REC_NUM_DATA_ARGS(val) \
337 (0x70000000 & ((val) << 28))
338#define TRACE_REC_TCS(val) \
339 (0x80000000 & ((val) << 31))
340
330#define KVMIO 0xAE 341#define KVMIO 0xAE
331 342
332/* 343/*
diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
index 58141f31ea8..9acb78b3cc9 100644
--- a/virt/kvm/kvm_trace.c
+++ b/virt/kvm/kvm_trace.c
@@ -54,12 +54,13 @@ static void kvm_add_trace(void *probe_private, void *call_data,
54 struct kvm_trace *kt = kvm_trace; 54 struct kvm_trace *kt = kvm_trace;
55 struct kvm_trace_rec rec; 55 struct kvm_trace_rec rec;
56 struct kvm_vcpu *vcpu; 56 struct kvm_vcpu *vcpu;
57 int i, extra, size; 57 int i, size;
58 u32 extra;
58 59
59 if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING)) 60 if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING))
60 return; 61 return;
61 62
62 rec.event = va_arg(*args, u32); 63 rec.rec_val = TRACE_REC_EVENT_ID(va_arg(*args, u32));
63 vcpu = va_arg(*args, struct kvm_vcpu *); 64 vcpu = va_arg(*args, struct kvm_vcpu *);
64 rec.pid = current->tgid; 65 rec.pid = current->tgid;
65 rec.vcpu_id = vcpu->vcpu_id; 66 rec.vcpu_id = vcpu->vcpu_id;
@@ -67,21 +68,21 @@ static void kvm_add_trace(void *probe_private, void *call_data,
67 extra = va_arg(*args, u32); 68 extra = va_arg(*args, u32);
68 WARN_ON(!(extra <= KVM_TRC_EXTRA_MAX)); 69 WARN_ON(!(extra <= KVM_TRC_EXTRA_MAX));
69 extra = min_t(u32, extra, KVM_TRC_EXTRA_MAX); 70 extra = min_t(u32, extra, KVM_TRC_EXTRA_MAX);
70 rec.extra_u32 = extra;
71 71
72 rec.cycle_in = p->cycle_in; 72 rec.rec_val |= TRACE_REC_TCS(p->cycle_in)
73 | TRACE_REC_NUM_DATA_ARGS(extra);
73 74
74 if (rec.cycle_in) { 75 if (p->cycle_in) {
75 rec.u.cycle.cycle_u64 = get_cycles(); 76 rec.u.cycle.cycle_u64 = get_cycles();
76 77
77 for (i = 0; i < rec.extra_u32; i++) 78 for (i = 0; i < extra; i++)
78 rec.u.cycle.extra_u32[i] = va_arg(*args, u32); 79 rec.u.cycle.extra_u32[i] = va_arg(*args, u32);
79 } else { 80 } else {
80 for (i = 0; i < rec.extra_u32; i++) 81 for (i = 0; i < extra; i++)
81 rec.u.nocycle.extra_u32[i] = va_arg(*args, u32); 82 rec.u.nocycle.extra_u32[i] = va_arg(*args, u32);
82 } 83 }
83 84
84 size = calc_rec_size(rec.cycle_in, rec.extra_u32 * sizeof(u32)); 85 size = calc_rec_size(p->cycle_in, extra * sizeof(u32));
85 relay_write(kt->rchan, &rec, size); 86 relay_write(kt->rchan, &rec, size);
86} 87}
87 88