/* * Expects va args : (int elem_num, const char __user *s) * Element size is implicit (sizeof(char)). */ static char *ltt_serialize_fs_data(char *buffer, char *str, struct ltt_serialize_closure *closure, void *serialize_private, int align, const char *fmt, va_list *args) { int elem_size; int elem_num; const char __user *s; unsigned long noncopy; elem_num = va_arg(*args, int); s = va_arg(*args, const char __user *); elem_size = sizeof(*s); if (align) str += ltt_align((long)str, sizeof(int)); if (buffer) *(int*)str = elem_num; str += sizeof(int); if (elem_num > 0) { /* No alignment required for char */ if (buffer) { noncopy = __copy_from_user_inatomic(str, s, elem_num*elem_size); memset(str+(elem_num*elem_size)-noncopy, 0, noncopy); } str += (elem_num*elem_size); } /* Following alignment for genevent compatibility */ if (align) str += ltt_align((long)str, sizeof(void*)); return str; }
size_t ltt_write_event_header_slow(struct ltt_chanbuf_alloc *bufa, struct ltt_chan_alloc *chana, long buf_offset, u16 eID, u32 event_size, u64 tsc, unsigned int rflags) { struct ltt_event_header header; u16 small_size; switch (rflags) { case LTT_RFLAG_ID_SIZE_TSC: header.id_time = 29 << LTT_TSC_BITS; break; case LTT_RFLAG_ID_SIZE: header.id_time = 30 << LTT_TSC_BITS; break; case LTT_RFLAG_ID: header.id_time = 31 << LTT_TSC_BITS; break; default: WARN_ON_ONCE(1); header.id_time = 0; } header.id_time |= (u32)tsc & LTT_TSC_MASK; ltt_relay_write(bufa, chana, buf_offset, &header, sizeof(header)); buf_offset += sizeof(header); switch (rflags) { case LTT_RFLAG_ID_SIZE_TSC: small_size = (u16)min_t(u32, event_size, LTT_MAX_SMALL_SIZE); ltt_relay_write(bufa, chana, buf_offset, &eID, sizeof(u16)); buf_offset += sizeof(u16); ltt_relay_write(bufa, chana, buf_offset, &small_size, sizeof(u16)); buf_offset += sizeof(u16); if (small_size == LTT_MAX_SMALL_SIZE) { ltt_relay_write(bufa, chana, buf_offset, &event_size, sizeof(u32)); buf_offset += sizeof(u32); } buf_offset += ltt_align(buf_offset, sizeof(u64)); ltt_relay_write(bufa, chana, buf_offset, &tsc, sizeof(u64)); buf_offset += sizeof(u64); break; case LTT_RFLAG_ID_SIZE: small_size = (u16)min_t(u32, event_size, LTT_MAX_SMALL_SIZE); ltt_relay_write(bufa, chana, buf_offset, &eID, sizeof(u16)); buf_offset += sizeof(u16); ltt_relay_write(bufa, chana, buf_offset, &small_size, sizeof(u16)); buf_offset += sizeof(u16); if (small_size == LTT_MAX_SMALL_SIZE) { ltt_relay_write(bufa, chana, buf_offset, &event_size, sizeof(u32)); buf_offset += sizeof(u32); } break; case LTT_RFLAG_ID: ltt_relay_write(bufa, chana, buf_offset, &eID, sizeof(u16)); buf_offset += sizeof(u16); break; } return buf_offset; }