diff --git a/Makefile.objs b/Makefile.objs
index 4f5392a..8298d32 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -390,6 +390,8 @@ trace-nested-$(CONFIG_TRACE_UST) += ust.o
 
 trace-nested-$(CONFIG_TRACE_DTRACE) += dtrace.o
 
+trace-nested-y += control.o
+
 trace-obj-y += $(addprefix trace/, $(trace-nested-y))
 
 ######################################################################
diff --git a/docs/tracing.txt b/docs/tracing.txt
index 017ff59..963d002 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -129,6 +129,10 @@ This functionality is also provided through monitor commands:
 * trace-event NAME on|off
   Enable/disable a given trace event.
 
+The "-trace events=<file>" command line argument can be used to enable the
+events listed in <file> from the very beginning of the program. This file must
+contain one event name per line.
+
 == Trace backends ==
 
 The "tracetool" script automates tedious trace event code generation and also
diff --git a/qemu-config.c b/qemu-config.c
index f67d3a5..cd519ec 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -308,6 +308,9 @@ static QemuOptsList qemu_trace_opts = {
     .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
     .desc = {
         {
+            .name = "events",
+            .type = QEMU_OPT_STRING,
+        },{
             .name = "file",
             .type = QEMU_OPT_STRING,
         },
diff --git a/qemu-options.hx b/qemu-options.hx
index d6421b9..91144d9 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2433,17 +2433,29 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
 option will prevent QEMU from loading these configuration files at startup.
 ETEXI
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
-    "-trace\n"
-    "                Specify a trace file to log traces to\n",
+    "-trace [events=<file>][,file=<file>]\n"
+    "                specify tracing options\n",
     QEMU_ARCH_ALL)
 STEXI
-HXCOMM This line is not accurate, as the option is backend-specific but HX does
-HXCOMM not support conditional compilation of text.
-@item -trace
+HXCOMM This line is not accurate, as some sub-options are backend-specific but
+HXCOMM HX does not support conditional compilation of text.
+@item -trace [events=@var{file}][,file=@var{file}]
 @findex -trace
-Specify a trace file to log output traces to.
 
-This option is available only when using the @var{simple} tracing backend.
+Specify tracing options.
+
+@table @option
+@item events=@var{file}
+Immediately enable events listed in @var{file}.
+The file must contain one event name (as listed in the @var{trace-events} file)
+per line.
+
+This option is only available when using the @var{simple} tracing backend.
+@item file=@var{file}
+Log output traces to @var{file}.
+
+This option is only available when using the @var{simple} tracing backend.
+@end table
 ETEXI
 
 HXCOMM This is the last statement. Insert new options before this line!
diff --git a/trace/control.c b/trace/control.c
new file mode 100644
index 0000000..1f43a8a
--- /dev/null
+++ b/trace/control.c
@@ -0,0 +1,41 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "trace/control.h"
+
+
+void trace_config_init_events (const char *fname)
+{
+    if (fname == NULL) {
+        return;
+    }
+
+    FILE *fp = fopen(fname, "r");
+    if (!fp) {
+        fprintf(stderr, "could not open trace events file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+    char line_buf[1024];
+    while (fgets(line_buf, sizeof(line_buf), fp)) {
+        size_t len = strlen(line_buf);
+        if (len > 1) {              /* skip empty lines */
+            line_buf[len - 1] = '\0';
+            if (!trace_event_set_state(line_buf, true)) {
+                fprintf(stderr, "qemu: error: trace event '%s' does not exist\n", line_buf);
+                exit(1);
+            }
+        }
+    }
+    if (fclose(fp) != 0) {
+        fprintf(stderr, "qemu: error: closing file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+}
diff --git a/trace/control.h b/trace/control.h
index 29876a5..b57fff7 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -29,4 +29,6 @@ bool trace_config_init (void);
  */
 bool trace_config_init_file (const char *file);
 
+void trace_config_init_events (const char *fname);
+
 #endif  /* TRACE_CONTROL_H */
diff --git a/vl.c b/vl.c
index ed2db9a..755be99 100644
--- a/vl.c
+++ b/vl.c
@@ -2946,6 +2946,10 @@ int main(int argc, char **argv, char **envp)
                             popt->name);
                     exit(1);
                 }
+                const char *trace_events = qemu_opt_get(opts, "events");
+                if (trace_events) {
+                    trace_config_init_events(trace_events);
+                }
                 break;
             }
             case QEMU_OPTION_readconfig:
