diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index e4368bb7..a793f8c0 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -84,16 +84,22 @@ static u64 hist_field_log2(struct hist_field *hist_field, void *event,
 {
 	struct hist_field *operand = hist_field->operands[0];
 
 	u64 val = operand->fn(operand, event, rbe);
 
 	return (u64) ilog2(roundup_pow_of_two(val));
 }
 
+static u64 hist_field_timestamp(struct hist_field *hist_field, void *event,
+				struct ring_buffer_event *rbe)
+{
+	return ring_buffer_event_time_stamp(rbe);
+}
+
 #define DEFINE_HIST_FIELD_FN(type)					\
 	static u64 hist_field_##type(struct hist_field *hist_field,	\
 				     void *event,			\
 				     struct ring_buffer_event *rbe)	\
 {									\
 	type *addr = (type *)(event + hist_field->field->offset);	\
 									\
 	return (u64)(unsigned long)*addr;				\
@@ -130,16 +136,17 @@ enum hist_field_flags {
 	HIST_FIELD_FL_STRING		= 1 << 2,
 	HIST_FIELD_FL_HEX		= 1 << 3,
 	HIST_FIELD_FL_SYM		= 1 << 4,
 	HIST_FIELD_FL_SYM_OFFSET	= 1 << 5,
 	HIST_FIELD_FL_EXECNAME		= 1 << 6,
 	HIST_FIELD_FL_SYSCALL		= 1 << 7,
 	HIST_FIELD_FL_STACKTRACE	= 1 << 8,
 	HIST_FIELD_FL_LOG2		= 1 << 9,
+	HIST_FIELD_FL_TIMESTAMP		= 1 << 10,
 };
 
 struct hist_trigger_attrs {
 	char		*keys_str;
 	char		*vals_str;
 	char		*sort_key_str;
 	char		*name;
 	bool		pause;
@@ -154,30 +161,33 @@ struct hist_trigger_data {
 	unsigned int			n_keys;
 	unsigned int			n_fields;
 	unsigned int			key_size;
 	struct tracing_map_sort_key	sort_keys[TRACING_MAP_SORT_KEYS_MAX];
 	unsigned int			n_sort_keys;
 	struct trace_event_file		*event_file;
 	struct hist_trigger_attrs	*attrs;
 	struct tracing_map		*map;
+	bool				enable_timestamps;
 };
 
 static const char *hist_field_name(struct hist_field *field,
 				   unsigned int level)
 {
 	const char *field_name = "";
 
 	if (level > 1)
 		return field_name;
 
 	if (field->field)
 		field_name = field->field->name;
 	else if (field->flags & HIST_FIELD_FL_LOG2)
 		field_name = hist_field_name(field->operands[0], ++level);
+	else if (field->flags & HIST_FIELD_FL_TIMESTAMP)
+		field_name = "common_timestamp";
 
 	if (field_name == NULL)
 		field_name = "";
 
 	return field_name;
 }
 
 static hist_field_fn_t select_value_fn(int field_size, int field_is_signed)
@@ -435,16 +445,22 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field,
 	if (flags & HIST_FIELD_FL_LOG2) {
 		unsigned long fl = flags & ~HIST_FIELD_FL_LOG2;
 		hist_field->fn = hist_field_log2;
 		hist_field->operands[0] = create_hist_field(field, fl);
 		hist_field->size = hist_field->operands[0]->size;
 		goto out;
 	}
 
+	if (flags & HIST_FIELD_FL_TIMESTAMP) {
+		hist_field->fn = hist_field_timestamp;
+		hist_field->size = sizeof(u64);
+		goto out;
+	}
+
 	if (WARN_ON_ONCE(!field))
 		goto out;
 
 	if (is_string_field(field)) {
 		flags |= HIST_FIELD_FL_STRING;
 
 		if (field->filter_type == FILTER_STATIC_STRING)
 			hist_field->fn = hist_field_string;
@@ -512,20 +528,25 @@ static int create_val_field(struct hist_trigger_data *hist_data,
 		if (strcmp(field_str, "hex") == 0)
 			flags |= HIST_FIELD_FL_HEX;
 		else {
 			ret = -EINVAL;
 			goto out;
 		}
 	}
 
-	field = trace_find_event_field(file->event_call, field_name);
-	if (!field || !field->size) {
-		ret = -EINVAL;
-		goto out;
+	if (strcmp(field_name, "common_timestamp") == 0) {
+		flags |= HIST_FIELD_FL_TIMESTAMP;
+		hist_data->enable_timestamps = true;
+	} else {
+		field = trace_find_event_field(file->event_call, field_name);
+		if (!field || !field->size) {
+			ret = -EINVAL;
+			goto out;
+		}
 	}
 
 	hist_data->fields[val_idx] = create_hist_field(field, flags);
 	if (!hist_data->fields[val_idx]) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
@@ -610,26 +631,32 @@ static int create_key_field(struct hist_trigger_data *hist_data,
 			else if (strcmp(field_str, "log2") == 0)
 				flags |= HIST_FIELD_FL_LOG2;
 			else {
 				ret = -EINVAL;
 				goto out;
 			}
 		}
 
-		field = trace_find_event_field(file->event_call, field_name);
-		if (!field || !field->size) {
-			ret = -EINVAL;
-			goto out;
-		}
+		if (strcmp(field_name, "common_timestamp") == 0) {
+			flags |= HIST_FIELD_FL_TIMESTAMP;
+			hist_data->enable_timestamps = true;
+			key_size = sizeof(u64);
+		} else {
+			field = trace_find_event_field(file->event_call, field_name);
+			if (!field || !field->size) {
+				ret = -EINVAL;
+				goto out;
+			}
 
-		if (is_string_field(field))
-			key_size = MAX_FILTER_STR_VAL;
-		else
-			key_size = field->size;
+			if (is_string_field(field))
+				key_size = MAX_FILTER_STR_VAL;
+			else
+				key_size = field->size;
+		}
 	}
 
 	hist_data->fields[key_idx] = create_hist_field(field, flags);
 	if (!hist_data->fields[key_idx]) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
@@ -815,16 +842,19 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data)
 		hist_field = hist_data->fields[i];
 		if (hist_field->flags & HIST_FIELD_FL_KEY) {
 			tracing_map_cmp_fn_t cmp_fn;
 
 			field = hist_field->field;
 
 			if (hist_field->flags & HIST_FIELD_FL_STACKTRACE)
 				cmp_fn = tracing_map_cmp_none;
+			else if (!field)
+				cmp_fn = tracing_map_cmp_num(hist_field->size,
+							     hist_field->is_signed);
 			else if (is_string_field(field))
 				cmp_fn = tracing_map_cmp_string;
 			else
 				cmp_fn = tracing_map_cmp_num(field->size,
 							     field->is_signed);
 			idx = tracing_map_add_key_field(map,
 							hist_field->offset,
 							cmp_fn);
@@ -1210,17 +1240,21 @@ static const char *get_hist_field_flags(struct hist_field *hist_field)
 
 	return flags_str;
 }
 
 static void hist_field_print(struct seq_file *m, struct hist_field *hist_field)
 {
 	const char *field_name = hist_field_name(hist_field, 0);
 
-	seq_printf(m, "%s", field_name);
+	if (hist_field->flags & HIST_FIELD_FL_TIMESTAMP)
+		seq_puts(m, "common_timestamp");
+	else if (field_name)
+		seq_printf(m, "%s", field_name);
+
 	if (hist_field->flags) {
 		const char *flags_str = get_hist_field_flags(hist_field);
 
 		if (flags_str)
 			seq_printf(m, ".%s", flags_str);
 	}
 }
 
@@ -1261,37 +1295,35 @@ static int event_hist_trigger_print(struct seq_file *m,
 			hist_field_print(m, hist_data->fields[i]);
 		}
 	}
 
 	seq_puts(m, ":sort=");
 
 	for (i = 0; i < hist_data->n_sort_keys; i++) {
 		struct tracing_map_sort_key *sort_key;
+		unsigned int idx;
 
 		sort_key = &hist_data->sort_keys[i];
+		idx = sort_key->field_idx;
+
+		if (WARN_ON(idx >= TRACING_MAP_FIELDS_MAX))
+			return -EINVAL;
 
 		if (i > 0)
 			seq_puts(m, ",");
 
-		if (sort_key->field_idx == HITCOUNT_IDX)
+		if (idx == HITCOUNT_IDX)
 			seq_puts(m, "hitcount");
-		else {
-			unsigned int idx = sort_key->field_idx;
-
-			if (WARN_ON(idx >= TRACING_MAP_FIELDS_MAX))
-				return -EINVAL;
-
+		else
 			hist_field_print(m, hist_data->fields[idx]);
-		}
 
 		if (sort_key->descending)
 			seq_puts(m, ".descending");
 	}
-
 	seq_printf(m, ":size=%u", (1 << hist_data->map->map_bits));
 
 	if (data->filter_str)
 		seq_printf(m, " if %s", data->filter_str);
 
 	if (data->paused)
 		seq_puts(m, " [paused]");
 	else
@@ -1449,16 +1481,20 @@ static bool hist_trigger_match(struct event_trigger_data *data,
 		key_field_test = hist_data_test->fields[i];
 
 		if (key_field->flags != key_field_test->flags)
 			return false;
 		if (!compatible_field(key_field->field, key_field_test->field))
 			return false;
 		if (key_field->offset != key_field_test->offset)
 			return false;
+		if (key_field->size != key_field_test->size)
+			return false;
+		if (key_field->is_signed != key_field_test->is_signed)
+			return false;
 	}
 
 	for (i = 0; i < hist_data->n_sort_keys; i++) {
 		sort_key = &hist_data->sort_keys[i];
 		sort_key_test = &hist_data_test->sort_keys[i];
 
 		if (sort_key->field_idx != sort_key_test->field_idx ||
 		    sort_key->descending != sort_key_test->descending)
@@ -1531,16 +1567,19 @@ static int hist_register_trigger(char *glob, struct event_trigger_ops *ops,
 			goto out;
 	}
 
 	list_add_rcu(&data->list, &file->triggers);
 	ret++;
 
 	update_cond_flag(file);
 
+	if (hist_data->enable_timestamps)
+		tracing_set_time_stamp_abs(file->tr, true);
+
 	if (trace_event_trigger_enable_disable(file, 1) < 0) {
 		list_del_rcu(&data->list);
 		update_cond_flag(file);
 		ret--;
 	}
  out:
 	return ret;
 }
@@ -1565,27 +1604,36 @@ static void hist_unregister_trigger(char *glob, struct event_trigger_ops *ops,
 			trace_event_trigger_enable_disable(file, 0);
 			update_cond_flag(file);
 			break;
 		}
 	}
 
 	if (unregistered && test->ops->free)
 		test->ops->free(test->ops, test);
+
+	if (hist_data->enable_timestamps) {
+		if (unregistered)
+			tracing_set_time_stamp_abs(file->tr, false);
+	}
 }
 
 static void hist_unreg_all(struct trace_event_file *file)
 {
 	struct event_trigger_data *test, *n;
+	struct hist_trigger_data *hist_data;
 
 	list_for_each_entry_safe(test, n, &file->triggers, list) {
 		if (test->cmd_ops->trigger_type == ETT_EVENT_HIST) {
+			hist_data = test->private_data;
 			list_del_rcu(&test->list);
 			trace_event_trigger_enable_disable(file, 0);
 			update_cond_flag(file);
+			if (hist_data->enable_timestamps)
+				tracing_set_time_stamp_abs(file->tr, false);
 			if (test->ops->free)
 				test->ops->free(test->ops, test);
 		}
 	}
 }
 
 static int event_hist_trigger_func(struct event_command *cmd_ops,
 				   struct trace_event_file *file,
