{
        struct common_audit_data *ad = a;
        audit_log_format(ab, "avc:  %s ",
-                        ad->selinux_audit_data->denied ? "denied" : "granted");
-       avc_dump_av(ab, ad->selinux_audit_data->tclass,
-                       ad->selinux_audit_data->audited);
+                        ad->selinux_audit_data->slad->denied ? "denied" : "granted");
+       avc_dump_av(ab, ad->selinux_audit_data->slad->tclass,
+                       ad->selinux_audit_data->slad->audited);
        audit_log_format(ab, " for ");
 }
 
 {
        struct common_audit_data *ad = a;
        audit_log_format(ab, " ");
-       avc_dump_query(ab, ad->selinux_audit_data->ssid,
-                          ad->selinux_audit_data->tsid,
-                          ad->selinux_audit_data->tclass);
+       avc_dump_query(ab, ad->selinux_audit_data->slad->ssid,
+                          ad->selinux_audit_data->slad->tsid,
+                          ad->selinux_audit_data->slad->tclass);
 }
 
 /* This is the slow part of avc audit with big stack footprint */
 {
        struct common_audit_data stack_data;
        struct selinux_audit_data sad = {0,};
+       struct selinux_late_audit_data slad;
 
        if (!a) {
                a = &stack_data;
            (flags & MAY_NOT_BLOCK))
                return -ECHILD;
 
-       a->selinux_audit_data->tclass = tclass;
-       a->selinux_audit_data->requested = requested;
-       a->selinux_audit_data->ssid = ssid;
-       a->selinux_audit_data->tsid = tsid;
-       a->selinux_audit_data->audited = audited;
-       a->selinux_audit_data->denied = denied;
+       slad.tclass = tclass;
+       slad.requested = requested;
+       slad.ssid = ssid;
+       slad.tsid = tsid;
+       slad.audited = audited;
+       slad.denied = denied;
+
+       a->selinux_audit_data->slad = &slad;
        a->lsm_pre_audit = avc_audit_pre_callback;
        a->lsm_post_audit = avc_audit_post_callback;
        common_lsm_audit(a);
 
        unsigned int frees;
 };
 
-struct selinux_audit_data {
+/*
+ * We only need this data after we have decided to send an audit message.
+ */
+struct selinux_late_audit_data {
        u32 ssid;
        u32 tsid;
        u16 tclass;
        u32 requested;
        u32 audited;
        u32 denied;
+       int result;
+};
+
+/*
+ * We collect this at the beginning or during an selinux security operation
+ */
+struct selinux_audit_data {
        /*
         * auditdeny is a bit tricky and unintuitive.  See the
         * comments in avc.c for it's meaning and usage.
         */
        u32 auditdeny;
-       int result;
+       struct selinux_late_audit_data *slad;
 };
 
 /*