diff --git a/tools/xentrace/formats b/tools/xentrace/formats
index 8b31780..c1f584f 100644
--- a/tools/xentrace/formats
+++ b/tools/xentrace/formats
@@ -79,6 +79,13 @@
 0x00022805  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  rtds:sched_tasklet
 0x00022806  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  rtds:schedule      [ cpu[16]:tasklet[8]:idle[4]:tickled[4] = %(1)08x ]
 
+0x00022A01  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  null:pick_cpu      [ dom:vcpu = 0x%(1)08x, new_cpu = %(2)d ]
+0x00022A02  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  null:assign        [ dom:vcpu = 0x%(1)08x, cpu = %(2)d ]
+0x00022A03  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  null:deassign      [ dom:vcpu = 0x%(1)08x, cpu = %(2)d ]
+0x00022A04  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  null:migrate       [ dom:vcpu = 0x%(1)08x, new_cpu:cpu = 0x%(2)08x ]
+0x00022A05  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  null:schedule      [ cpu[16]:tasklet[16] = %(1)08x, dom:vcpu = 0x%(2)08x ]
+0x00022A06  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  null:sched_tasklet
+
 0x00041001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  domain_create   [ dom = 0x%(1)08x ]
 0x00041002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  domain_destroy  [ dom = 0x%(1)08x ]
 
diff --git a/tools/xentrace/xenalyze.c b/tools/xentrace/xenalyze.c
index fa608ad..24cce2a 100644
--- a/tools/xentrace/xenalyze.c
+++ b/tools/xentrace/xenalyze.c
@@ -7968,6 +7968,71 @@ void sched_process(struct pcpu_info *p)
                        r->tickled ? ", tickled" : ", not tickled");
             }
             break;
+        case TRC_SCHED_CLASS_EVT(SNULL, 1): /* PICKED_CPU */
+            if (opt.dump_all) {
+                struct {
+                    uint16_t vcpuid, domid;
+                    uint32_t new_cpu;
+                } *r = (typeof(r))ri->d;
+
+                printf(" %s null:picked_cpu d%uv%u, cpu %u\n",
+                       ri->dump_header, r->domid, r->vcpuid, r->new_cpu);
+            }
+            break;
+        case TRC_SCHED_CLASS_EVT(SNULL, 2): /* VCPU_ASSIGN */
+            if (opt.dump_all) {
+                struct {
+                    uint16_t vcpuid, domid;
+                    uint32_t cpu;
+                } *r = (typeof(r))ri->d;
+
+                printf(" %s null:vcpu_assign d%uv%u to cpu %u\n",
+                       ri->dump_header, r->domid, r->vcpuid, r->cpu);
+            }
+            break;
+        case TRC_SCHED_CLASS_EVT(SNULL, 3): /* VCPU_DEASSIGN */
+            if (opt.dump_all) {
+                struct {
+                    uint16_t vcpuid, domid;
+                    uint32_t cpu;
+                } *r = (typeof(r))ri->d;
+
+                printf(" %s null:vcpu_deassign d%uv%u from cpu %u\n",
+                       ri->dump_header, r->domid, r->vcpuid, r->cpu);
+            }
+            break;
+        case TRC_SCHED_CLASS_EVT(SNULL, 4): /* MIGRATE */
+            if (opt.dump_all) {
+                struct {
+                    uint16_t vcpuid, domid;
+                    uint16_t cpu, new_cpu;
+                } *r = (typeof(r))ri->d;
+
+                printf(" %s null:migrate d%uv%u, cpu %u, new_cpu %u\n",
+                       ri->dump_header, r->domid, r->vcpuid,
+                       r->cpu, r->new_cpu);
+            }
+            break;
+        case TRC_SCHED_CLASS_EVT(SNULL, 5): /* SCHEDULE */
+            if (opt.dump_all) {
+                struct {
+                    uint16_t tasklet, cpu;
+                    int16_t vcpuid, domid;
+                } *r = (typeof(r))ri->d;
+
+                printf(" %s null:schedule cpu %u%s",
+                       ri->dump_header, r->cpu,
+                       r->tasklet ? ", tasklet scheduled" : "");
+                if (r->vcpuid != -1)
+                    printf(", vcpu d%uv%d\n", r->domid, r->vcpuid);
+                else
+                    printf(", no vcpu\n");
+            }
+            break;
+        case TRC_SCHED_CLASS_EVT(SNULL, 6): /* TASKLET */
+            if (opt.dump_all)
+                printf(" %s null:sched_tasklet\n", ri->dump_header);
+            break;
         default:
             process_generic(ri);
         }
