[PATCH 1 of 3] Remove use of bit fields in kvm trace structure

Jerone Young
2008-06-20T04:24:01Z

2 files changed, 21 insertions(+), 11 deletions(-)
include/linux/kvm.h | 10 +++++++---
virt/kvm/kvm_trace.c | 22 ++++++++++++++--------

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>

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 {
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,15 @@ 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;
+
+ /* set event id */
+ rec.rec_val = 0x0fffffff & va_arg(*args, u32);

- rec.event = va_arg(*args, u32);
vcpu = va_arg(*args, struct kvm_vcpu *);
rec.pid = current->tgid;
rec.vcpu_id = vcpu->vcpu_id;
@@ -67,21 +70,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 |= 0x80000000 & (p->cycle_in << 31);
+
+ /* set extra data num */
+ rec.rec_val |= 0x70000000 & (extra << 28);

- if (rec.cycle_in) {
+ 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);
}