--- /dev/null
+From bf8c7a978ba2ae5754a2d81f3137492066926f0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Sep 2022 00:20:12 -0700
+Subject: apparmor: combine common_audit_data and apparmor_audit_data
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit bd7bd201ca46c211c3ab251ca9854787d1331a2f ]
+
+Everywhere where common_audit_data is used apparmor audit_data is also
+used. We can simplify the code and drop the use of the aad macro
+everywhere by combining the two structures.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/audit.c | 70 +++++++++++++++----------------
+ security/apparmor/capability.c | 24 +++++------
+ security/apparmor/file.c | 68 +++++++++++++++---------------
+ security/apparmor/include/audit.h | 34 ++++++++-------
+ security/apparmor/include/net.h | 13 +++---
+ security/apparmor/include/perms.h | 4 +-
+ security/apparmor/ipc.c | 39 ++++++++---------
+ security/apparmor/lib.c | 47 +++++++++++----------
+ security/apparmor/lsm.c | 12 +++---
+ security/apparmor/mount.c | 41 +++++++++---------
+ security/apparmor/net.c | 44 +++++++++----------
+ security/apparmor/policy.c | 19 +++++----
+ security/apparmor/policy_unpack.c | 29 ++++++-------
+ security/apparmor/resource.c | 23 +++++-----
+ security/apparmor/task.c | 35 ++++++++--------
+ 15 files changed, 257 insertions(+), 245 deletions(-)
+
+diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
+index a3db0f8bd4f85..06ad6a8fcce18 100644
+--- a/security/apparmor/audit.c
++++ b/security/apparmor/audit.c
+@@ -85,37 +85,36 @@ static const char *const aa_class_names[] = {
+ /**
+ * audit_pre() - core AppArmor function.
+ * @ab: audit buffer to fill (NOT NULL)
+- * @ca: audit structure containing data to audit (NOT NULL)
++ * @va: audit structure containing data to audit (NOT NULL)
+ *
+- * Record common AppArmor audit data from @sa
++ * Record common AppArmor audit data from @va
+ */
+-static void audit_pre(struct audit_buffer *ab, void *ca)
++static void audit_pre(struct audit_buffer *ab, void *va)
+ {
+- struct common_audit_data *sa = ca;
++ struct apparmor_audit_data *ad = aad_of_va(va);
+
+ if (aa_g_audit_header) {
+ audit_log_format(ab, "apparmor=\"%s\"",
+- aa_audit_type[aad(sa)->type]);
++ aa_audit_type[ad->type]);
+ }
+
+- if (aad(sa)->op) {
+- audit_log_format(ab, " operation=\"%s\"", aad(sa)->op);
+- }
++ if (ad->op)
++ audit_log_format(ab, " operation=\"%s\"", ad->op);
+
+- if (aad(sa)->class)
++ if (ad->class)
+ audit_log_format(ab, " class=\"%s\"",
+- aad(sa)->class <= AA_CLASS_LAST ?
+- aa_class_names[aad(sa)->class] :
++ ad->class <= AA_CLASS_LAST ?
++ aa_class_names[ad->class] :
+ "unknown");
+
+- if (aad(sa)->info) {
+- audit_log_format(ab, " info=\"%s\"", aad(sa)->info);
+- if (aad(sa)->error)
+- audit_log_format(ab, " error=%d", aad(sa)->error);
++ if (ad->info) {
++ audit_log_format(ab, " info=\"%s\"", ad->info);
++ if (ad->error)
++ audit_log_format(ab, " error=%d", ad->error);
+ }
+
+- if (aad(sa)->label) {
+- struct aa_label *label = aad(sa)->label;
++ if (ad->label) {
++ struct aa_label *label = ad->label;
+
+ if (label_isprofile(label)) {
+ struct aa_profile *profile = labels_profile(label);
+@@ -134,43 +133,44 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
+ }
+ }
+
+- if (aad(sa)->name) {
++ if (ad->name) {
+ audit_log_format(ab, " name=");
+- audit_log_untrustedstring(ab, aad(sa)->name);
++ audit_log_untrustedstring(ab, ad->name);
+ }
+ }
+
+ /**
+ * aa_audit_msg - Log a message to the audit subsystem
+ * @type: audit type for the message
+- * @sa: audit event structure (NOT NULL)
++ * @ad: audit event structure (NOT NULL)
+ * @cb: optional callback fn for type specific fields (MAYBE NULL)
+ */
+-void aa_audit_msg(int type, struct common_audit_data *sa,
++void aa_audit_msg(int type, struct apparmor_audit_data *ad,
+ void (*cb) (struct audit_buffer *, void *))
+ {
+- aad(sa)->type = type;
+- common_lsm_audit(sa, audit_pre, cb);
++ ad->type = type;
++ common_lsm_audit(&ad->common, audit_pre, cb);
+ }
+
+ /**
+ * aa_audit - Log a profile based audit event to the audit subsystem
+ * @type: audit type for the message
+ * @profile: profile to check against (NOT NULL)
+- * @sa: audit event (NOT NULL)
++ * @ad: audit event (NOT NULL)
+ * @cb: optional callback fn for type specific fields (MAYBE NULL)
+ *
+ * Handle default message switching based off of audit mode flags
+ *
+ * Returns: error on failure
+ */
+-int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
++int aa_audit(int type, struct aa_profile *profile,
++ struct apparmor_audit_data *ad,
+ void (*cb) (struct audit_buffer *, void *))
+ {
+ AA_BUG(!profile);
+
+ if (type == AUDIT_APPARMOR_AUTO) {
+- if (likely(!aad(sa)->error)) {
++ if (likely(!ad->error)) {
+ if (AUDIT_MODE(profile) != AUDIT_ALL)
+ return 0;
+ type = AUDIT_APPARMOR_AUDIT;
+@@ -182,24 +182,24 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
+ if (AUDIT_MODE(profile) == AUDIT_QUIET ||
+ (type == AUDIT_APPARMOR_DENIED &&
+ AUDIT_MODE(profile) == AUDIT_QUIET_DENIED))
+- return aad(sa)->error;
++ return ad->error;
+
+ if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
+ type = AUDIT_APPARMOR_KILL;
+
+- aad(sa)->label = &profile->label;
++ ad->label = &profile->label;
+
+- aa_audit_msg(type, sa, cb);
++ aa_audit_msg(type, ad, cb);
+
+- if (aad(sa)->type == AUDIT_APPARMOR_KILL)
++ if (ad->type == AUDIT_APPARMOR_KILL)
+ (void)send_sig_info(SIGKILL, NULL,
+- sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ?
+- sa->u.tsk : current);
++ ad->common.type == LSM_AUDIT_DATA_TASK &&
++ ad->common.u.tsk ? ad->common.u.tsk : current);
+
+- if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED)
+- return complain_error(aad(sa)->error);
++ if (ad->type == AUDIT_APPARMOR_ALLOWED)
++ return complain_error(ad->error);
+
+- return aad(sa)->error;
++ return ad->error;
+ }
+
+ struct aa_audit_rule {
+diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
+index 326a51838ef28..58490cca035da 100644
+--- a/security/apparmor/capability.c
++++ b/security/apparmor/capability.c
+@@ -51,7 +51,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+
+ /**
+ * audit_caps - audit a capability
+- * @sa: audit data
++ * @as: audit data
+ * @profile: profile being tested for confinement (NOT NULL)
+ * @cap: capability tested
+ * @error: error code returned by test
+@@ -59,9 +59,9 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+ * Do auditing of capability and handle, audit/complain/kill modes switching
+ * and duplicate message elimination.
+ *
+- * Returns: 0 or sa->error on success, error code on failure
++ * Returns: 0 or ad->error on success, error code on failure
+ */
+-static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
++static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile,
+ int cap, int error)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+@@ -69,7 +69,7 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
+ struct audit_cache *ent;
+ int type = AUDIT_APPARMOR_AUTO;
+
+- aad(sa)->error = error;
++ ad->error = error;
+
+ if (likely(!error)) {
+ /* test if auditing is being forced */
+@@ -101,7 +101,7 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
+ }
+ put_cpu_var(audit_cache);
+
+- return aa_audit(type, profile, sa, audit_cb);
++ return aa_audit(type, profile, ad, audit_cb);
+ }
+
+ /**
+@@ -109,12 +109,12 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile,
+ * @profile: profile being enforced (NOT NULL, NOT unconfined)
+ * @cap: capability to test if allowed
+ * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
+- * @sa: audit data (MAY BE NULL indicating no auditing)
++ * @ad: audit data (MAY BE NULL indicating no auditing)
+ *
+ * Returns: 0 if allowed else -EPERM
+ */
+ static int profile_capable(struct aa_profile *profile, int cap,
+- unsigned int opts, struct common_audit_data *sa)
++ unsigned int opts, struct apparmor_audit_data *ad)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+@@ -132,10 +132,10 @@ static int profile_capable(struct aa_profile *profile, int cap,
+ /* audit the cap request in complain mode but note that it
+ * should be optional.
+ */
+- aad(sa)->info = "optional: no audit";
++ ad->info = "optional: no audit";
+ }
+
+- return audit_caps(sa, profile, cap, error);
++ return audit_caps(ad, profile, cap, error);
+ }
+
+ /**
+@@ -152,11 +152,11 @@ int aa_capable(struct aa_label *label, int cap, unsigned int opts)
+ {
+ struct aa_profile *profile;
+ int error = 0;
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, AA_CLASS_CAP, OP_CAPABLE);
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_CAP, AA_CLASS_CAP, OP_CAPABLE);
+
+- sa.u.cap = cap;
++ ad.common.u.cap = cap;
+ error = fn_for_each_confined(label, profile,
+- profile_capable(profile, cap, opts, &sa));
++ profile_capable(profile, cap, opts, &ad));
+
+ return error;
+ }
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index 698b124e649f6..9ea95fa18e7d5 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -44,33 +44,34 @@ static u32 map_mask_to_chr_mask(u32 mask)
+ static void file_audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+ kuid_t fsuid = current_fsuid();
+ char str[10];
+
+- if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
++ if (ad->request & AA_AUDIT_FILE_MASK) {
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+- map_mask_to_chr_mask(aad(sa)->request));
++ map_mask_to_chr_mask(ad->request));
+ audit_log_format(ab, " requested_mask=\"%s\"", str);
+ }
+- if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
++ if (ad->denied & AA_AUDIT_FILE_MASK) {
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+- map_mask_to_chr_mask(aad(sa)->denied));
++ map_mask_to_chr_mask(ad->denied));
+ audit_log_format(ab, " denied_mask=\"%s\"", str);
+ }
+- if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
++ if (ad->request & AA_AUDIT_FILE_MASK) {
+ audit_log_format(ab, " fsuid=%d",
+ from_kuid(&init_user_ns, fsuid));
+ audit_log_format(ab, " ouid=%d",
+- from_kuid(&init_user_ns, aad(sa)->fs.ouid));
++ from_kuid(&init_user_ns, ad->fs.ouid));
+ }
+
+- if (aad(sa)->peer) {
++ if (ad->peer) {
+ audit_log_format(ab, " target=");
+- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
+ FLAG_VIEW_SUBNS, GFP_KERNEL);
+- } else if (aad(sa)->fs.target) {
++ } else if (ad->fs.target) {
+ audit_log_format(ab, " target=");
+- audit_log_untrustedstring(ab, aad(sa)->fs.target);
++ audit_log_untrustedstring(ab, ad->fs.target);
+ }
+ }
+
+@@ -95,50 +96,49 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
+ kuid_t ouid, const char *info, int error)
+ {
+ int type = AUDIT_APPARMOR_AUTO;
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, AA_CLASS_FILE, op);
+-
+- sa.u.tsk = NULL;
+- aad(&sa)->request = request;
+- aad(&sa)->name = name;
+- aad(&sa)->fs.target = target;
+- aad(&sa)->peer = tlabel;
+- aad(&sa)->fs.ouid = ouid;
+- aad(&sa)->info = info;
+- aad(&sa)->error = error;
+- sa.u.tsk = NULL;
+-
+- if (likely(!aad(&sa)->error)) {
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_TASK, AA_CLASS_FILE, op);
++
++ ad.request = request;
++ ad.name = name;
++ ad.fs.target = target;
++ ad.peer = tlabel;
++ ad.fs.ouid = ouid;
++ ad.info = info;
++ ad.error = error;
++ ad.common.u.tsk = NULL;
++
++ if (likely(!ad.error)) {
+ u32 mask = perms->audit;
+
+ if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
+ mask = 0xffff;
+
+ /* mask off perms that are not being force audited */
+- aad(&sa)->request &= mask;
++ ad.request &= mask;
+
+- if (likely(!aad(&sa)->request))
++ if (likely(!ad.request))
+ return 0;
+ type = AUDIT_APPARMOR_AUDIT;
+ } else {
+ /* only report permissions that were denied */
+- aad(&sa)->request = aad(&sa)->request & ~perms->allow;
+- AA_BUG(!aad(&sa)->request);
++ ad.request = ad.request & ~perms->allow;
++ AA_BUG(!ad.request);
+
+- if (aad(&sa)->request & perms->kill)
++ if (ad.request & perms->kill)
+ type = AUDIT_APPARMOR_KILL;
+
+ /* quiet known rejects, assumes quiet and kill do not overlap */
+- if ((aad(&sa)->request & perms->quiet) &&
++ if ((ad.request & perms->quiet) &&
+ AUDIT_MODE(profile) != AUDIT_NOQUIET &&
+ AUDIT_MODE(profile) != AUDIT_ALL)
+- aad(&sa)->request &= ~perms->quiet;
++ ad.request &= ~perms->quiet;
+
+- if (!aad(&sa)->request)
+- return aad(&sa)->error;
++ if (!ad.request)
++ return ad.error;
+ }
+
+- aad(&sa)->denied = aad(&sa)->request & ~perms->allow;
+- return aa_audit(type, profile, &sa, file_audit_cb);
++ ad.denied = ad.request & ~perms->allow;
++ return aa_audit(type, profile, &ad, file_audit_cb);
+ }
+
+ static int path_name(const char *op, struct aa_label *label,
+diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
+index c328f07f11cd8..85931ec94e916 100644
+--- a/security/apparmor/include/audit.h
++++ b/security/apparmor/include/audit.h
+@@ -152,33 +152,35 @@ struct apparmor_audit_data {
+ unsigned long flags;
+ } mnt;
+ };
++
++ struct common_audit_data common;
+ };
+
+ /* macros for dealing with apparmor_audit_data structure */
+-#define aad(SA) ((SA)->apparmor_audit_data)
++#define aad(SA) (container_of(SA, struct apparmor_audit_data, common))
++#define aad_of_va(VA) aad((struct common_audit_data *)(VA))
++
+ #define DEFINE_AUDIT_DATA(NAME, T, C, X) \
+ /* TODO: cleanup audit init so we don't need _aad = {0,} */ \
+- struct apparmor_audit_data NAME ## _aad = { \
++ struct apparmor_audit_data NAME = { \
+ .class = (C), \
+ .op = (X), \
+- }; \
+- struct common_audit_data NAME = \
+- { \
+- .type = (T), \
+- .u.tsk = NULL, \
+- }; \
+- NAME.apparmor_audit_data = &(NAME ## _aad)
+-
+-void aa_audit_msg(int type, struct common_audit_data *sa,
++ .common.type = (T), \
++ .common.u.tsk = NULL, \
++ .common.apparmor_audit_data = &NAME, \
++ };
++
++void aa_audit_msg(int type, struct apparmor_audit_data *ad,
+ void (*cb) (struct audit_buffer *, void *));
+-int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa,
++int aa_audit(int type, struct aa_profile *profile,
++ struct apparmor_audit_data *ad,
+ void (*cb) (struct audit_buffer *, void *));
+
+-#define aa_audit_error(ERROR, SA, CB) \
++#define aa_audit_error(ERROR, AD, CB) \
+ ({ \
+- aad((SA))->error = (ERROR); \
+- aa_audit_msg(AUDIT_APPARMOR_ERROR, (SA), (CB)); \
+- aad((SA))->error; \
++ (AD)->error = (ERROR); \
++ aa_audit_msg(AUDIT_APPARMOR_ERROR, (AD), (CB)); \
++ (AD)->error; \
+ })
+
+
+diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
+index 6fa440b5daed8..a336e57864e89 100644
+--- a/security/apparmor/include/net.h
++++ b/security/apparmor/include/net.h
+@@ -61,9 +61,9 @@ struct aa_sk_ctx {
+ LSM_AUDIT_DATA_NONE, \
+ AA_CLASS_NET, \
+ OP); \
+- NAME.u.net = &(NAME ## _net); \
+- aad(&NAME)->net.type = (T); \
+- aad(&NAME)->net.protocol = (P)
++ NAME.common.u.net = &(NAME ## _net); \
++ NAME.net.type = (T); \
++ NAME.net.protocol = (P)
+
+ #define DEFINE_AUDIT_SK(NAME, OP, SK) \
+ DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type, \
+@@ -90,16 +90,17 @@ struct aa_secmark {
+ extern struct aa_sfs_entry aa_sfs_entry_network[];
+
+ void audit_net_cb(struct audit_buffer *ab, void *va);
+-int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
++int aa_profile_af_perm(struct aa_profile *profile,
++ struct apparmor_audit_data *ad,
+ u32 request, u16 family, int type);
+ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
+ int type, int protocol);
+ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
+- struct common_audit_data *sa,
++ struct apparmor_audit_data *ad,
+ u32 request,
+ struct sock *sk)
+ {
+- return aa_profile_af_perm(profile, sa, request, sk->sk_family,
++ return aa_profile_af_perm(profile, ad, request, sk->sk_family,
+ sk->sk_type);
+ }
+ int aa_sk_perm(const char *op, u32 request, struct sock *sk);
+diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
+index 797a7a00644d2..83534df8939fd 100644
+--- a/security/apparmor/include/perms.h
++++ b/security/apparmor/include/perms.h
+@@ -212,8 +212,8 @@ void aa_profile_match_label(struct aa_profile *profile,
+ int type, u32 request, struct aa_perms *perms);
+ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+ u32 request, int type, u32 *deny,
+- struct common_audit_data *sa);
++ struct apparmor_audit_data *ad);
+ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+- u32 request, struct common_audit_data *sa,
++ u32 request, struct apparmor_audit_data *ad,
+ void (*cb)(struct audit_buffer *, void *));
+ #endif /* __AA_PERM_H */
+diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
+index 5acde746775f7..f198b8d620a4f 100644
+--- a/security/apparmor/ipc.c
++++ b/security/apparmor/ipc.c
+@@ -52,31 +52,32 @@ static const char *audit_signal_mask(u32 mask)
+ static void audit_signal_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+- if (aad(sa)->request & AA_SIGNAL_PERM_MASK) {
++ if (ad->request & AA_SIGNAL_PERM_MASK) {
+ audit_log_format(ab, " requested_mask=\"%s\"",
+- audit_signal_mask(aad(sa)->request));
+- if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) {
++ audit_signal_mask(ad->request));
++ if (ad->denied & AA_SIGNAL_PERM_MASK) {
+ audit_log_format(ab, " denied_mask=\"%s\"",
+- audit_signal_mask(aad(sa)->denied));
++ audit_signal_mask(ad->denied));
+ }
+ }
+- if (aad(sa)->signal == SIGUNKNOWN)
++ if (ad->signal == SIGUNKNOWN)
+ audit_log_format(ab, "signal=unknown(%d)",
+- aad(sa)->unmappedsig);
+- else if (aad(sa)->signal < MAXMAPPED_SIGNAME)
+- audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]);
++ ad->unmappedsig);
++ else if (ad->signal < MAXMAPPED_SIGNAME)
++ audit_log_format(ab, " signal=%s", sig_names[ad->signal]);
+ else
+ audit_log_format(ab, " signal=rtmin+%d",
+- aad(sa)->signal - SIGRT_BASE);
++ ad->signal - SIGRT_BASE);
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+
+ static int profile_signal_perm(struct aa_profile *profile,
+ struct aa_label *peer, u32 request,
+- struct common_audit_data *sa)
++ struct apparmor_audit_data *ad)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+@@ -87,24 +88,24 @@ static int profile_signal_perm(struct aa_profile *profile,
+ !ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_SIGNAL))
+ return 0;
+
+- aad(sa)->peer = peer;
++ ad->peer = peer;
+ /* TODO: secondary cache check <profile, profile, perm> */
+ state = aa_dfa_next(rules->policy.dfa,
+ rules->policy.start[AA_CLASS_SIGNAL],
+- aad(sa)->signal);
++ ad->signal);
+ aa_label_match(profile, rules, peer, state, false, request, &perms);
+ aa_apply_modes_to_perms(profile, &perms);
+- return aa_check_perms(profile, &perms, request, sa, audit_signal_cb);
++ return aa_check_perms(profile, &perms, request, ad, audit_signal_cb);
+ }
+
+ int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
+ {
+ struct aa_profile *profile;
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_SIGNAL, OP_SIGNAL);
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_SIGNAL, OP_SIGNAL);
+
+- aad(&sa)->signal = map_signal_num(sig);
+- aad(&sa)->unmappedsig = sig;
++ ad.signal = map_signal_num(sig);
++ ad.unmappedsig = sig;
+ return xcheck_labels(sender, target, profile,
+- profile_signal_perm(profile, target, MAY_WRITE, &sa),
+- profile_signal_perm(profile, sender, MAY_READ, &sa));
++ profile_signal_perm(profile, target, MAY_WRITE, &ad),
++ profile_signal_perm(profile, sender, MAY_READ, &ad));
+ }
+diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
+index 8e1073477c096..d6b2750fd72e4 100644
+--- a/security/apparmor/lib.c
++++ b/security/apparmor/lib.c
+@@ -144,10 +144,10 @@ const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name,
+ void aa_info_message(const char *str)
+ {
+ if (audit_enabled) {
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL);
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL);
+
+- aad(&sa)->info = str;
+- aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL);
++ ad.info = str;
++ aa_audit_msg(AUDIT_APPARMOR_STATUS, &ad, NULL);
+ }
+ printk(KERN_INFO "AppArmor: %s\n", str);
+ }
+@@ -282,21 +282,22 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
+ static void aa_audit_perms_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+- if (aad(sa)->request) {
++ if (ad->request) {
+ audit_log_format(ab, " requested_mask=");
+- aa_audit_perm_mask(ab, aad(sa)->request, aa_file_perm_chrs,
++ aa_audit_perm_mask(ab, ad->request, aa_file_perm_chrs,
+ PERMS_CHRS_MASK, aa_file_perm_names,
+ PERMS_NAMES_MASK);
+ }
+- if (aad(sa)->denied) {
++ if (ad->denied) {
+ audit_log_format(ab, "denied_mask=");
+- aa_audit_perm_mask(ab, aad(sa)->denied, aa_file_perm_chrs,
++ aa_audit_perm_mask(ab, ad->denied, aa_file_perm_chrs,
+ PERMS_CHRS_MASK, aa_file_perm_names,
+ PERMS_NAMES_MASK);
+ }
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+
+@@ -350,21 +351,21 @@ void aa_profile_match_label(struct aa_profile *profile,
+ /* currently unused */
+ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+ u32 request, int type, u32 *deny,
+- struct common_audit_data *sa)
++ struct apparmor_audit_data *ad)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+ struct aa_perms perms;
+
+- aad(sa)->label = &profile->label;
+- aad(sa)->peer = &target->label;
+- aad(sa)->request = request;
++ ad->label = &profile->label;
++ ad->peer = &target->label;
++ ad->request = request;
+
+ aa_profile_match_label(profile, rules, &target->label, type, request,
+ &perms);
+ aa_apply_modes_to_perms(profile, &perms);
+ *deny |= request & perms.deny;
+- return aa_check_perms(profile, &perms, request, sa, aa_audit_perms_cb);
++ return aa_check_perms(profile, &perms, request, ad, aa_audit_perms_cb);
+ }
+
+ /**
+@@ -372,7 +373,7 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+ * @profile: profile being checked
+ * @perms: perms computed for the request
+ * @request: requested perms
+- * @sa: initialized audit structure (MAY BE NULL if not auditing)
++ * @ad: initialized audit structure (MAY BE NULL if not auditing)
+ * @cb: callback fn for type specific fields (MAY BE NULL)
+ *
+ * Returns: 0 if permission else error code
+@@ -385,7 +386,7 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+ * with a positive value.
+ */
+ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+- u32 request, struct common_audit_data *sa,
++ u32 request, struct apparmor_audit_data *ad,
+ void (*cb)(struct audit_buffer *, void *))
+ {
+ int type, error;
+@@ -394,7 +395,7 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+ if (likely(!denied)) {
+ /* mask off perms that are not being force audited */
+ request &= perms->audit;
+- if (!request || !sa)
++ if (!request || !ad)
+ return 0;
+
+ type = AUDIT_APPARMOR_AUDIT;
+@@ -413,16 +414,16 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+ error = -ENOENT;
+
+ denied &= ~perms->quiet;
+- if (!sa || !denied)
++ if (!ad || !denied)
+ return error;
+ }
+
+- if (sa) {
+- aad(sa)->label = &profile->label;
+- aad(sa)->request = request;
+- aad(sa)->denied = denied;
+- aad(sa)->error = error;
+- aa_audit_msg(type, sa, cb);
++ if (ad) {
++ ad->label = &profile->label;
++ ad->request = request;
++ ad->denied = denied;
++ ad->error = error;
++ aa_audit_msg(type, ad, cb);
+ }
+
+ if (type == AUDIT_APPARMOR_ALLOWED)
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 108eccc5ada58..fd7852a4737c7 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -662,7 +662,7 @@ static int apparmor_setprocattr(const char *name, void *value,
+ char *command, *largs = NULL, *args = value;
+ size_t arg_size;
+ int error;
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE,
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE,
+ OP_SETPROCATTR);
+
+ if (size == 0)
+@@ -722,11 +722,11 @@ static int apparmor_setprocattr(const char *name, void *value,
+ return error;
+
+ fail:
+- aad(&sa)->label = begin_current_label_crit_section();
+- aad(&sa)->info = name;
+- aad(&sa)->error = error = -EINVAL;
+- aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
+- end_current_label_crit_section(aad(&sa)->label);
++ ad.label = begin_current_label_crit_section();
++ ad.info = name;
++ ad.error = error = -EINVAL;
++ aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL);
++ end_current_label_crit_section(ad.label);
+ goto out;
+ }
+
+diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
+index cdfa430ae2161..3830bceff9c8b 100644
+--- a/security/apparmor/mount.c
++++ b/security/apparmor/mount.c
+@@ -86,27 +86,28 @@ static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags)
+ static void audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+- if (aad(sa)->mnt.type) {
++ if (ad->mnt.type) {
+ audit_log_format(ab, " fstype=");
+- audit_log_untrustedstring(ab, aad(sa)->mnt.type);
++ audit_log_untrustedstring(ab, ad->mnt.type);
+ }
+- if (aad(sa)->mnt.src_name) {
++ if (ad->mnt.src_name) {
+ audit_log_format(ab, " srcname=");
+- audit_log_untrustedstring(ab, aad(sa)->mnt.src_name);
++ audit_log_untrustedstring(ab, ad->mnt.src_name);
+ }
+- if (aad(sa)->mnt.trans) {
++ if (ad->mnt.trans) {
+ audit_log_format(ab, " trans=");
+- audit_log_untrustedstring(ab, aad(sa)->mnt.trans);
++ audit_log_untrustedstring(ab, ad->mnt.trans);
+ }
+- if (aad(sa)->mnt.flags) {
++ if (ad->mnt.flags) {
+ audit_log_format(ab, " flags=\"");
+- audit_mnt_flags(ab, aad(sa)->mnt.flags);
++ audit_mnt_flags(ab, ad->mnt.flags);
+ audit_log_format(ab, "\"");
+ }
+- if (aad(sa)->mnt.data) {
++ if (ad->mnt.data) {
+ audit_log_format(ab, " options=");
+- audit_log_untrustedstring(ab, aad(sa)->mnt.data);
++ audit_log_untrustedstring(ab, ad->mnt.data);
+ }
+ }
+
+@@ -134,7 +135,7 @@ static int audit_mount(struct aa_profile *profile, const char *op,
+ struct aa_perms *perms, const char *info, int error)
+ {
+ int audit_type = AUDIT_APPARMOR_AUTO;
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_MOUNT, op);
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_MOUNT, op);
+
+ if (likely(!error)) {
+ u32 mask = perms->audit;
+@@ -165,17 +166,17 @@ static int audit_mount(struct aa_profile *profile, const char *op,
+ return error;
+ }
+
+- aad(&sa)->name = name;
+- aad(&sa)->mnt.src_name = src_name;
+- aad(&sa)->mnt.type = type;
+- aad(&sa)->mnt.trans = trans;
+- aad(&sa)->mnt.flags = flags;
++ ad.name = name;
++ ad.mnt.src_name = src_name;
++ ad.mnt.type = type;
++ ad.mnt.trans = trans;
++ ad.mnt.flags = flags;
+ if (data && (perms->audit & AA_AUDIT_DATA))
+- aad(&sa)->mnt.data = data;
+- aad(&sa)->info = info;
+- aad(&sa)->error = error;
++ ad.mnt.data = data;
++ ad.info = info;
++ ad.error = error;
+
+- return aa_audit(audit_type, profile, &sa, audit_cb);
++ return aa_audit(audit_type, profile, &ad, audit_cb);
+ }
+
+ /**
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 788be1609a865..0c7304cd479c5 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -71,6 +71,7 @@ static const char * const net_mask_names[] = {
+ void audit_net_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+ if (address_family_names[sa->u.net->family])
+ audit_log_format(ab, " family=\"%s\"",
+@@ -78,35 +79,36 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
+ else
+ audit_log_format(ab, " family=\"unknown(%d)\"",
+ sa->u.net->family);
+- if (sock_type_names[aad(sa)->net.type])
++ if (sock_type_names[ad->net.type])
+ audit_log_format(ab, " sock_type=\"%s\"",
+- sock_type_names[aad(sa)->net.type]);
++ sock_type_names[ad->net.type]);
+ else
+ audit_log_format(ab, " sock_type=\"unknown(%d)\"",
+- aad(sa)->net.type);
+- audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol);
++ ad->net.type);
++ audit_log_format(ab, " protocol=%d", ad->net.protocol);
+
+- if (aad(sa)->request & NET_PERMS_MASK) {
++ if (ad->request & NET_PERMS_MASK) {
+ audit_log_format(ab, " requested_mask=");
+- aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0,
++ aa_audit_perm_mask(ab, ad->request, NULL, 0,
+ net_mask_names, NET_PERMS_MASK);
+
+- if (aad(sa)->denied & NET_PERMS_MASK) {
++ if (ad->denied & NET_PERMS_MASK) {
+ audit_log_format(ab, " denied_mask=");
+- aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0,
++ aa_audit_perm_mask(ab, ad->denied, NULL, 0,
+ net_mask_names, NET_PERMS_MASK);
+ }
+ }
+- if (aad(sa)->peer) {
++ if (ad->peer) {
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+ }
+
+ /* Generic af perm */
+-int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
+- u32 request, u16 family, int type)
++int aa_profile_af_perm(struct aa_profile *profile,
++ struct apparmor_audit_data *ad, u32 request, u16 family,
++ int type)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+@@ -130,17 +132,17 @@ int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa,
+ perms = *aa_lookup_perms(&rules->policy, state);
+ aa_apply_modes_to_perms(profile, &perms);
+
+- return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
++ return aa_check_perms(profile, &perms, request, ad, audit_net_cb);
+ }
+
+ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
+ int type, int protocol)
+ {
+ struct aa_profile *profile;
+- DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol);
++ DEFINE_AUDIT_NET(ad, op, NULL, family, type, protocol);
+
+ return fn_for_each_confined(label, profile,
+- aa_profile_af_perm(profile, &sa, request, family,
++ aa_profile_af_perm(profile, &ad, request, family,
+ type));
+ }
+
+@@ -155,10 +157,10 @@ static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
+
+ if (ctx->label != kernel_t && !unconfined(label)) {
+ struct aa_profile *profile;
+- DEFINE_AUDIT_SK(sa, op, sk);
++ DEFINE_AUDIT_SK(ad, op, sk);
+
+ error = fn_for_each_confined(label, profile,
+- aa_profile_af_sk_perm(profile, &sa, request, sk));
++ aa_profile_af_sk_perm(profile, &ad, request, sk));
+ }
+
+ return error;
+@@ -214,7 +216,7 @@ static int apparmor_secmark_init(struct aa_secmark *secmark)
+ }
+
+ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
+- struct common_audit_data *sa)
++ struct apparmor_audit_data *ad)
+ {
+ int i, ret;
+ struct aa_perms perms = { };
+@@ -245,17 +247,17 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid,
+
+ aa_apply_modes_to_perms(profile, &perms);
+
+- return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
++ return aa_check_perms(profile, &perms, request, ad, audit_net_cb);
+ }
+
+ int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
+ u32 secid, const struct sock *sk)
+ {
+ struct aa_profile *profile;
+- DEFINE_AUDIT_SK(sa, op, sk);
++ DEFINE_AUDIT_SK(ad, op, sk);
+
+ return fn_for_each_confined(label, profile,
+ aa_secmark_perm(profile, request, secid,
+- &sa));
++ &ad));
+ }
+ #endif
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index b9aaaac84d8a2..9a7dbe64f102b 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -723,10 +723,11 @@ static int replacement_allowed(struct aa_profile *profile, int noreplace,
+ static void audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+- if (aad(sa)->iface.ns) {
++ if (ad->iface.ns) {
+ audit_log_format(ab, " ns=");
+- audit_log_untrustedstring(ab, aad(sa)->iface.ns);
++ audit_log_untrustedstring(ab, ad->iface.ns);
+ }
+ }
+
+@@ -745,15 +746,15 @@ static int audit_policy(struct aa_label *label, const char *op,
+ const char *ns_name, const char *name,
+ const char *info, int error)
+ {
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, op);
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, op);
+
+- aad(&sa)->iface.ns = ns_name;
+- aad(&sa)->name = name;
+- aad(&sa)->info = info;
+- aad(&sa)->error = error;
+- aad(&sa)->label = label;
++ ad.iface.ns = ns_name;
++ ad.name = name;
++ ad.info = info;
++ ad.error = error;
++ ad.label = label;
+
+- aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, audit_cb);
++ aa_audit_msg(AUDIT_APPARMOR_STATUS, &ad, audit_cb);
+
+ return error;
+ }
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index b49201306753c..dbc83455d900e 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -34,17 +34,18 @@
+ static void audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+- if (aad(sa)->iface.ns) {
++ if (ad->iface.ns) {
+ audit_log_format(ab, " ns=");
+- audit_log_untrustedstring(ab, aad(sa)->iface.ns);
++ audit_log_untrustedstring(ab, ad->iface.ns);
+ }
+- if (aad(sa)->name) {
++ if (ad->name) {
+ audit_log_format(ab, " name=");
+- audit_log_untrustedstring(ab, aad(sa)->name);
++ audit_log_untrustedstring(ab, ad->name);
+ }
+- if (aad(sa)->iface.pos)
+- audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos);
++ if (ad->iface.pos)
++ audit_log_format(ab, " offset=%ld", ad->iface.pos);
+ }
+
+ /**
+@@ -63,18 +64,18 @@ static int audit_iface(struct aa_profile *new, const char *ns_name,
+ int error)
+ {
+ struct aa_profile *profile = labels_profile(aa_current_raw_label());
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL);
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL);
+ if (e)
+- aad(&sa)->iface.pos = e->pos - e->start;
+- aad(&sa)->iface.ns = ns_name;
++ ad.iface.pos = e->pos - e->start;
++ ad.iface.ns = ns_name;
+ if (new)
+- aad(&sa)->name = new->base.hname;
++ ad.name = new->base.hname;
+ else
+- aad(&sa)->name = name;
+- aad(&sa)->info = info;
+- aad(&sa)->error = error;
++ ad.name = name;
++ ad.info = info;
++ ad.error = error;
+
+- return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb);
++ return aa_audit(AUDIT_APPARMOR_STATUS, profile, &ad, audit_cb);
+ }
+
+ void __aa_loaddata_update(struct aa_loaddata *data, long revision)
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index 2bebc5d9e7411..b6b5e1bfe9a26 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -30,12 +30,13 @@ struct aa_sfs_entry aa_sfs_entry_rlimit[] = {
+ static void audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+ audit_log_format(ab, " rlimit=%s value=%lu",
+- rlim_names[aad(sa)->rlim.rlim], aad(sa)->rlim.max);
+- if (aad(sa)->peer) {
++ rlim_names[ad->rlim.rlim], ad->rlim.max);
++ if (ad->peer) {
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+ }
+@@ -49,22 +50,22 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+ * @info: info being auditing
+ * @error: error value
+ *
+- * Returns: 0 or sa->error else other error code on failure
++ * Returns: 0 or ad->error else other error code on failure
+ */
+ static int audit_resource(struct aa_profile *profile, unsigned int resource,
+ unsigned long value, struct aa_label *peer,
+ const char *info, int error)
+ {
+- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_RLIMITS,
++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_RLIMITS,
+ OP_SETRLIMIT);
+
+- aad(&sa)->rlim.rlim = resource;
+- aad(&sa)->rlim.max = value;
+- aad(&sa)->peer = peer;
+- aad(&sa)->info = info;
+- aad(&sa)->error = error;
++ ad.rlim.rlim = resource;
++ ad.rlim.max = value;
++ ad.peer = peer;
++ ad.info = info;
++ ad.error = error;
+
+- return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb);
++ return aa_audit(AUDIT_APPARMOR_AUTO, profile, &ad, audit_cb);
+ }
+
+ /**
+diff --git a/security/apparmor/task.c b/security/apparmor/task.c
+index 84d16a29bfcbc..8bd1f212215c4 100644
+--- a/security/apparmor/task.c
++++ b/security/apparmor/task.c
+@@ -208,18 +208,19 @@ static const char *audit_ptrace_mask(u32 mask)
+ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
++ struct apparmor_audit_data *ad = aad(sa);
+
+- if (aad(sa)->request & AA_PTRACE_PERM_MASK) {
++ if (ad->request & AA_PTRACE_PERM_MASK) {
+ audit_log_format(ab, " requested_mask=\"%s\"",
+- audit_ptrace_mask(aad(sa)->request));
++ audit_ptrace_mask(ad->request));
+
+- if (aad(sa)->denied & AA_PTRACE_PERM_MASK) {
++ if (ad->denied & AA_PTRACE_PERM_MASK) {
+ audit_log_format(ab, " denied_mask=\"%s\"",
+- audit_ptrace_mask(aad(sa)->denied));
++ audit_ptrace_mask(ad->denied));
+ }
+ }
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+
+@@ -227,51 +228,51 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
+ /* TODO: conditionals */
+ static int profile_ptrace_perm(struct aa_profile *profile,
+ struct aa_label *peer, u32 request,
+- struct common_audit_data *sa)
++ struct apparmor_audit_data *ad)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+ struct aa_perms perms = { };
+
+- aad(sa)->peer = peer;
++ ad->peer = peer;
+ aa_profile_match_label(profile, rules, peer, AA_CLASS_PTRACE, request,
+ &perms);
+ aa_apply_modes_to_perms(profile, &perms);
+- return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb);
++ return aa_check_perms(profile, &perms, request, ad, audit_ptrace_cb);
+ }
+
+ static int profile_tracee_perm(struct aa_profile *tracee,
+ struct aa_label *tracer, u32 request,
+- struct common_audit_data *sa)
++ struct apparmor_audit_data *ad)
+ {
+ if (profile_unconfined(tracee) || unconfined(tracer) ||
+ !ANY_RULE_MEDIATES(&tracee->rules, AA_CLASS_PTRACE))
+ return 0;
+
+- return profile_ptrace_perm(tracee, tracer, request, sa);
++ return profile_ptrace_perm(tracee, tracer, request, ad);
+ }
+
+ static int profile_tracer_perm(struct aa_profile *tracer,
+ struct aa_label *tracee, u32 request,
+- struct common_audit_data *sa)
++ struct apparmor_audit_data *ad)
+ {
+ if (profile_unconfined(tracer))
+ return 0;
+
+ if (ANY_RULE_MEDIATES(&tracer->rules, AA_CLASS_PTRACE))
+- return profile_ptrace_perm(tracer, tracee, request, sa);
++ return profile_ptrace_perm(tracer, tracee, request, ad);
+
+ /* profile uses the old style capability check for ptrace */
+ if (&tracer->label == tracee)
+ return 0;
+
+- aad(sa)->label = &tracer->label;
+- aad(sa)->peer = tracee;
+- aad(sa)->request = 0;
+- aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
++ ad->label = &tracer->label;
++ ad->peer = tracee;
++ ad->request = 0;
++ ad->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
+ CAP_OPT_NONE);
+
+- return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb);
++ return aa_audit(AUDIT_APPARMOR_AUTO, tracer, ad, audit_ptrace_cb);
+ }
+
+ /**
+--
+2.42.0
+
--- /dev/null
+From e0d838f05b6f88582e1c6b8dc29c7fcd9ce9499e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:39 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/audit.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 26c9ecb34f5f5fa43c041a220de01d7cbea97dd0 ]
+
+Fix kernel-doc warnings:
+
+security/apparmor/audit.c:150: warning: Function parameter or
+member 'type' not described in 'aa_audit_msg'
+
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/audit.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
+index 5a7978aa4b19e..a3db0f8bd4f85 100644
+--- a/security/apparmor/audit.c
++++ b/security/apparmor/audit.c
+@@ -142,6 +142,7 @@ static void audit_pre(struct audit_buffer *ab, void *ca)
+
+ /**
+ * aa_audit_msg - Log a message to the audit subsystem
++ * @type: audit type for the message
+ * @sa: audit event structure (NOT NULL)
+ * @cb: optional callback fn for type specific fields (MAYBE NULL)
+ */
+--
+2.42.0
+
--- /dev/null
+From b6cd9b4ada4e9bde21363488ef32f08e5a3c60d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:44 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/lib.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 8921482286116af193980f04f2f2755775a410a5 ]
+
+Fix kernel-doc warnings:
+
+security/apparmor/lib.c:33: warning: Excess function parameter
+'str' description in 'aa_free_str_table'
+security/apparmor/lib.c:33: warning: Function parameter or member
+'t' not described in 'aa_free_str_table'
+security/apparmor/lib.c:94: warning: Function parameter or
+member 'n' not described in 'skipn_spaces'
+security/apparmor/lib.c:390: warning: Excess function parameter
+'deny' description in 'aa_check_perms'
+
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lib.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
+index a630c951bb3b8..8e1073477c096 100644
+--- a/security/apparmor/lib.c
++++ b/security/apparmor/lib.c
+@@ -27,7 +27,7 @@ struct aa_perms allperms = { .allow = ALL_PERMS_MASK,
+
+ /**
+ * aa_free_str_table - free entries str table
+- * @str: the string table to free (MAYBE NULL)
++ * @t: the string table to free (MAYBE NULL)
+ */
+ void aa_free_str_table(struct aa_str_table *t)
+ {
+@@ -85,6 +85,7 @@ char *aa_split_fqname(char *fqname, char **ns_name)
+ /**
+ * skipn_spaces - Removes leading whitespace from @str.
+ * @str: The string to be stripped.
++ * @n: length of str to parse, will stop at \0 if encountered before n
+ *
+ * Returns a pointer to the first non-whitespace character in @str.
+ * if all whitespace will return NULL
+@@ -371,7 +372,6 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+ * @profile: profile being checked
+ * @perms: perms computed for the request
+ * @request: requested perms
+- * @deny: Returns: explicit deny set
+ * @sa: initialized audit structure (MAY BE NULL if not auditing)
+ * @cb: callback fn for type specific fields (MAY BE NULL)
+ *
+--
+2.42.0
+
--- /dev/null
+From 274b48aa36c1e1f1288375fff31d49a9eb40485f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:49 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/policy.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 25ff0ff2d6286928dc516c74b879809c691c2dd8 ]
+
+Fix kernel-doc warnings:
+
+security/apparmor/policy.c:294: warning: Function parameter or
+member 'proxy' not described in 'aa_alloc_profile'
+security/apparmor/policy.c:785: warning: Function parameter or
+member 'label' not described in 'aa_policy_view_capable'
+security/apparmor/policy.c:785: warning: Function parameter or
+member 'ns' not described in 'aa_policy_view_capable'
+security/apparmor/policy.c:847: warning: Function parameter or
+member 'ns' not described in 'aa_may_manage_policy'
+security/apparmor/policy.c:964: warning: Function parameter or
+member 'hname' not described in '__lookup_replace'
+security/apparmor/policy.c:964: warning: Function parameter or
+member 'info' not described in '__lookup_replace'
+security/apparmor/policy.c:964: warning: Function parameter or
+member 'noreplace' not described in '__lookup_replace'
+security/apparmor/policy.c:964: warning: Function parameter or
+member 'ns' not described in '__lookup_replace'
+security/apparmor/policy.c:964: warning: Function parameter or
+member 'p' not described in '__lookup_replace'
+
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index ec695a6caac7d..b9aaaac84d8a2 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -286,6 +286,7 @@ void aa_free_profile(struct aa_profile *profile)
+ /**
+ * aa_alloc_profile - allocate, initialize and return a new profile
+ * @hname: name of the profile (NOT NULL)
++ * @proxy: proxy to use OR null if to allocate a new one
+ * @gfp: allocation type
+ *
+ * Returns: refcount profile or NULL on failure
+@@ -775,8 +776,9 @@ static int policy_ns_capable(struct aa_label *label,
+
+ /**
+ * aa_policy_view_capable - check if viewing policy in at @ns is allowed
+- * label: label that is trying to view policy in ns
+- * ns: namespace being viewed by @label (may be NULL if @label's ns)
++ * @label: label that is trying to view policy in ns
++ * @ns: namespace being viewed by @label (may be NULL if @label's ns)
++ *
+ * Returns: true if viewing policy is allowed
+ *
+ * If @ns is NULL then the namespace being viewed is assumed to be the
+@@ -840,6 +842,7 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns)
+ /**
+ * aa_may_manage_policy - can the current task manage policy
+ * @label: label to check if it can manage policy
++ * @ns: namespace being managed by @label (may be NULL if @label's ns)
+ * @mask: contains the policy manipulation operation being done
+ *
+ * Returns: 0 if the task is allowed to manipulate policy else error
+@@ -951,11 +954,11 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new)
+
+ /**
+ * __lookup_replace - lookup replacement information for a profile
+- * @ns - namespace the lookup occurs in
+- * @hname - name of profile to lookup
+- * @noreplace - true if not replacing an existing profile
+- * @p - Returns: profile to be replaced
+- * @info - Returns: info string on why lookup failed
++ * @ns: namespace the lookup occurs in
++ * @hname: name of profile to lookup
++ * @noreplace: true if not replacing an existing profile
++ * @p: Returns - profile to be replaced
++ * @info: Returns - info string on why lookup failed
+ *
+ * Returns: profile to replace (no ref) on success else ptr error
+ */
+--
+2.42.0
+
--- /dev/null
+From 1fa4cbf9881993c63ffe88134a97c923d9434437 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:46 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/resource.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ Upstream commit 13c1748e217078d437727eef333cb0387d13bc0e ]
+
+Fix kernel-doc warnings:
+
+security/apparmor/resource.c:111: warning: Function parameter or
+member 'label' not described in 'aa_task_setrlimit'
+security/apparmor/resource.c:111: warning: Function parameter or
+member 'new_rlim' not described in 'aa_task_setrlimit'
+security/apparmor/resource.c:111: warning: Function parameter or
+member 'resource' not described in 'aa_task_setrlimit'
+security/apparmor/resource.c:111: warning: Function parameter or
+member 'task' not described in 'aa_task_setrlimit'
+
+Signed-off-by: Gaosheng Cui <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/resource.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index e859481648962..2bebc5d9e7411 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -97,10 +97,10 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
+
+ /**
+ * aa_task_setrlimit - test permission to set an rlimit
+- * @label - label confining the task (NOT NULL)
+- * @task - task the resource is being set on
+- * @resource - the resource being set
+- * @new_rlim - the new resource limit (NOT NULL)
++ * @label: label confining the task (NOT NULL)
++ * @task: task the resource is being set on
++ * @resource: the resource being set
++ * @new_rlim: the new resource limit (NOT NULL)
+ *
+ * Control raising the processes hard limit.
+ *
+--
+2.42.0
+
--- /dev/null
+From 9da47efe8ca49d251e3bd334c61d6bcdb215c51a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Sep 2023 03:35:22 -0700
+Subject: apparmor: Fix regression in mount mediation
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 157a3537d6bc28ceb9a11fc8cb67f2152d860146 ]
+
+commit 2db154b3ea8e ("vfs: syscall: Add move_mount(2) to move mounts around")
+
+introduced a new move_mount(2) system call and a corresponding new LSM
+security_move_mount hook but did not implement this hook for any
+existing LSM. This creates a regression for AppArmor mediation of
+mount. This patch provides a base mapping of the move_mount syscall to
+the existing mount mediation. In the future we may introduce
+additional mediations around the new mount calls.
+
+Fixes: 2db154b3ea8e ("vfs: syscall: Add move_mount(2) to move mounts around")
+CC: stable@vger.kernel.org
+Reported-by: Andreas Steinmetz <anstein99@googlemail.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/include/mount.h | 7 +++--
+ security/apparmor/lsm.c | 20 ++++++++++++--
+ security/apparmor/mount.c | 46 +++++++++++++++++++------------
+ 3 files changed, 51 insertions(+), 22 deletions(-)
+
+diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
+index 10c76f906a653..46834f8281794 100644
+--- a/security/apparmor/include/mount.h
++++ b/security/apparmor/include/mount.h
+@@ -38,9 +38,12 @@ int aa_mount_change_type(const struct cred *subj_cred,
+ struct aa_label *label, const struct path *path,
+ unsigned long flags);
+
++int aa_move_mount_old(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
++ const char *old_name);
+ int aa_move_mount(const struct cred *subj_cred,
+- struct aa_label *label, const struct path *path,
+- const char *old_name);
++ struct aa_label *label, const struct path *from_path,
++ const struct path *to_path);
+
+ int aa_new_mount(const struct cred *subj_cred,
+ struct aa_label *label, const char *dev_name,
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 60f95cc4532a8..6fdab1b5ede5c 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -607,8 +607,8 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path,
+ error = aa_mount_change_type(current_cred(), label,
+ path, flags);
+ else if (flags & MS_MOVE)
+- error = aa_move_mount(current_cred(), label, path,
+- dev_name);
++ error = aa_move_mount_old(current_cred(), label, path,
++ dev_name);
+ else
+ error = aa_new_mount(current_cred(), label, dev_name,
+ path, type, flags, data);
+@@ -618,6 +618,21 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path,
+ return error;
+ }
+
++static int apparmor_move_mount(const struct path *from_path,
++ const struct path *to_path)
++{
++ struct aa_label *label;
++ int error = 0;
++
++ label = __begin_current_label_crit_section();
++ if (!unconfined(label))
++ error = aa_move_mount(current_cred(), label, from_path,
++ to_path);
++ __end_current_label_crit_section(label);
++
++ return error;
++}
++
+ static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
+ {
+ struct aa_label *label;
+@@ -1240,6 +1255,7 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
+ LSM_HOOK_INIT(capget, apparmor_capget),
+ LSM_HOOK_INIT(capable, apparmor_capable),
+
++ LSM_HOOK_INIT(move_mount, apparmor_move_mount),
+ LSM_HOOK_INIT(sb_mount, apparmor_sb_mount),
+ LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
+ LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),
+diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
+index 2bb77aacc49ae..f2a114e540079 100644
+--- a/security/apparmor/mount.c
++++ b/security/apparmor/mount.c
+@@ -483,36 +483,46 @@ int aa_mount_change_type(const struct cred *subj_cred,
+ }
+
+ int aa_move_mount(const struct cred *subj_cred,
+- struct aa_label *label, const struct path *path,
+- const char *orig_name)
++ struct aa_label *label, const struct path *from_path,
++ const struct path *to_path)
+ {
+ struct aa_profile *profile;
+- char *buffer = NULL, *old_buffer = NULL;
+- struct path old_path;
++ char *to_buffer = NULL, *from_buffer = NULL;
+ int error;
+
+ AA_BUG(!label);
+- AA_BUG(!path);
++ AA_BUG(!from_path);
++ AA_BUG(!to_path);
++
++ to_buffer = aa_get_buffer(false);
++ from_buffer = aa_get_buffer(false);
++ error = -ENOMEM;
++ if (!to_buffer || !from_buffer)
++ goto out;
++ error = fn_for_each_confined(label, profile,
++ match_mnt(subj_cred, profile, to_path, to_buffer,
++ from_path, from_buffer,
++ NULL, MS_MOVE, NULL, false));
++out:
++ aa_put_buffer(to_buffer);
++ aa_put_buffer(from_buffer);
++
++ return error;
++}
++
++int aa_move_mount_old(const struct cred *subj_cred, struct aa_label *label,
++ const struct path *path, const char *orig_name)
++{
++ struct path old_path;
++ int error;
+
+ if (!orig_name || !*orig_name)
+ return -EINVAL;
+-
+ error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
+ if (error)
+ return error;
+
+- buffer = aa_get_buffer(false);
+- old_buffer = aa_get_buffer(false);
+- error = -ENOMEM;
+- if (!buffer || !old_buffer)
+- goto out;
+- error = fn_for_each_confined(label, profile,
+- match_mnt(subj_cred, profile, path, buffer, &old_path,
+- old_buffer,
+- NULL, MS_MOVE, NULL, false));
+-out:
+- aa_put_buffer(buffer);
+- aa_put_buffer(old_buffer);
++ error = aa_move_mount(subj_cred, label, &old_path, path);
+ path_put(&old_path);
+
+ return error;
+--
+2.42.0
+
--- /dev/null
+From 6868e7132f91ab9266f4c4f2ae645a42a5a089cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Sep 2022 20:48:48 -0700
+Subject: apparmor: pass cred through to audit info.
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 90c436a64a6e20482a9a613c47eb4af2e8a5328e ]
+
+The cred is needed to properly audit some messages, and will be needed
+in the future for uid conditional mediation. So pass it through to
+where the apparmor_audit_data struct gets defined.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/apparmorfs.c | 11 ++-
+ security/apparmor/capability.c | 5 +-
+ security/apparmor/domain.c | 97 +++++++++++-------
+ security/apparmor/file.c | 131 +++++++++++++++++--------
+ security/apparmor/include/audit.h | 1 +
+ security/apparmor/include/capability.h | 3 +-
+ security/apparmor/include/file.h | 17 ++--
+ security/apparmor/include/ipc.h | 4 +-
+ security/apparmor/include/mount.h | 21 ++--
+ security/apparmor/include/net.h | 6 +-
+ security/apparmor/include/policy.h | 9 +-
+ security/apparmor/include/resource.h | 3 +-
+ security/apparmor/include/task.h | 3 +-
+ security/apparmor/ipc.c | 14 ++-
+ security/apparmor/lsm.c | 85 +++++++++-------
+ security/apparmor/mount.c | 85 ++++++++++------
+ security/apparmor/net.c | 17 ++--
+ security/apparmor/policy.c | 33 ++++---
+ security/apparmor/resource.c | 23 +++--
+ security/apparmor/task.c | 31 +++---
+ 20 files changed, 388 insertions(+), 211 deletions(-)
+
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index bd6a910f65282..261cef4c622fb 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -423,7 +423,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
+ /* high level check about policy management - fine grained in
+ * below after unpack
+ */
+- error = aa_may_manage_policy(label, ns, mask);
++ error = aa_may_manage_policy(current_cred(), label, ns, mask);
+ if (error)
+ goto end_section;
+
+@@ -486,7 +486,8 @@ static ssize_t profile_remove(struct file *f, const char __user *buf,
+ /* high level check about policy management - fine grained in
+ * below after unpack
+ */
+- error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
++ error = aa_may_manage_policy(current_cred(), label, ns,
++ AA_MAY_REMOVE_POLICY);
+ if (error)
+ goto out;
+
+@@ -1805,7 +1806,8 @@ static int ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir,
+ int error;
+
+ label = begin_current_label_crit_section();
+- error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
++ error = aa_may_manage_policy(current_cred(), label, NULL,
++ AA_MAY_LOAD_POLICY);
+ end_current_label_crit_section(label);
+ if (error)
+ return error;
+@@ -1854,7 +1856,8 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
+ int error;
+
+ label = begin_current_label_crit_section();
+- error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
++ error = aa_may_manage_policy(current_cred(), label, NULL,
++ AA_MAY_LOAD_POLICY);
+ end_current_label_crit_section(label);
+ if (error)
+ return error;
+diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
+index 58490cca035da..2fb6a2ea0b998 100644
+--- a/security/apparmor/capability.c
++++ b/security/apparmor/capability.c
+@@ -140,6 +140,7 @@ static int profile_capable(struct aa_profile *profile, int cap,
+
+ /**
+ * aa_capable - test permission to use capability
++ * @subj_cread: cred we are testing capability against
+ * @label: label being tested for capability (NOT NULL)
+ * @cap: capability to be tested
+ * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated
+@@ -148,12 +149,14 @@ static int profile_capable(struct aa_profile *profile, int cap,
+ *
+ * Returns: 0 on success, or else an error code.
+ */
+-int aa_capable(struct aa_label *label, int cap, unsigned int opts)
++int aa_capable(const struct cred *subj_cred, struct aa_label *label,
++ int cap, unsigned int opts)
+ {
+ struct aa_profile *profile;
+ int error = 0;
+ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_CAP, AA_CLASS_CAP, OP_CAPABLE);
+
++ ad.subj_cred = subj_cred;
+ ad.common.u.cap = cap;
+ error = fn_for_each_confined(label, profile,
+ profile_capable(profile, cap, opts, &ad));
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
+index f3715cda59c52..543105cf7e334 100644
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -31,6 +31,7 @@
+
+ /**
+ * may_change_ptraced_domain - check if can change profile on ptraced task
++ * @cred: cred of task changing domain
+ * @to_label: profile to change to (NOT NULL)
+ * @info: message if there is an error
+ *
+@@ -39,28 +40,34 @@
+ *
+ * Returns: %0 or error if change not allowed
+ */
+-static int may_change_ptraced_domain(struct aa_label *to_label,
++static int may_change_ptraced_domain(const struct cred *to_cred,
++ struct aa_label *to_label,
+ const char **info)
+ {
+ struct task_struct *tracer;
+ struct aa_label *tracerl = NULL;
++ const struct cred *tracer_cred = NULL;
++
+ int error = 0;
+
+ rcu_read_lock();
+ tracer = ptrace_parent(current);
+- if (tracer)
++ if (tracer) {
+ /* released below */
+ tracerl = aa_get_task_label(tracer);
+-
++ tracer_cred = get_task_cred(tracer);
++ }
+ /* not ptraced */
+ if (!tracer || unconfined(tracerl))
+ goto out;
+
+- error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
++ error = aa_may_ptrace(tracer_cred, tracerl, to_cred, to_label,
++ PTRACE_MODE_ATTACH);
+
+ out:
+ rcu_read_unlock();
+ aa_put_label(tracerl);
++ put_cred(tracer_cred);
+
+ if (error)
+ *info = "ptrace prevents transition";
+@@ -619,7 +626,8 @@ static struct aa_label *x_to_label(struct aa_profile *profile,
+ return new;
+ }
+
+-static struct aa_label *profile_transition(struct aa_profile *profile,
++static struct aa_label *profile_transition(const struct cred *subj_cred,
++ struct aa_profile *profile,
+ const struct linux_binprm *bprm,
+ char *buffer, struct path_cond *cond,
+ bool *secure_exec)
+@@ -709,7 +717,8 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
+ }
+
+ audit:
+- aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, target, new,
++ aa_audit_file(subj_cred, profile, &perms, OP_EXEC, MAY_EXEC, name,
++ target, new,
+ cond->uid, info, error);
+ if (!new || nonewprivs) {
+ aa_put_label(new);
+@@ -719,7 +728,8 @@ static struct aa_label *profile_transition(struct aa_profile *profile,
+ return new;
+ }
+
+-static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
++static int profile_onexec(const struct cred *subj_cred,
++ struct aa_profile *profile, struct aa_label *onexec,
+ bool stack, const struct linux_binprm *bprm,
+ char *buffer, struct path_cond *cond,
+ bool *secure_exec)
+@@ -787,13 +797,15 @@ static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
+ }
+
+ audit:
+- return aa_audit_file(profile, &perms, OP_EXEC, AA_MAY_ONEXEC, xname,
++ return aa_audit_file(subj_cred, profile, &perms, OP_EXEC,
++ AA_MAY_ONEXEC, xname,
+ NULL, onexec, cond->uid, info, error);
+ }
+
+ /* ensure none ns domain transitions are correctly applied with onexec */
+
+-static struct aa_label *handle_onexec(struct aa_label *label,
++static struct aa_label *handle_onexec(const struct cred *subj_cred,
++ struct aa_label *label,
+ struct aa_label *onexec, bool stack,
+ const struct linux_binprm *bprm,
+ char *buffer, struct path_cond *cond,
+@@ -810,26 +822,28 @@ static struct aa_label *handle_onexec(struct aa_label *label,
+
+ if (!stack) {
+ error = fn_for_each_in_ns(label, profile,
+- profile_onexec(profile, onexec, stack,
++ profile_onexec(subj_cred, profile, onexec, stack,
+ bprm, buffer, cond, unsafe));
+ if (error)
+ return ERR_PTR(error);
+ new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
+ aa_get_newest_label(onexec),
+- profile_transition(profile, bprm, buffer,
++ profile_transition(subj_cred, profile, bprm,
++ buffer,
+ cond, unsafe));
+
+ } else {
+ /* TODO: determine how much we want to loosen this */
+ error = fn_for_each_in_ns(label, profile,
+- profile_onexec(profile, onexec, stack, bprm,
++ profile_onexec(subj_cred, profile, onexec, stack, bprm,
+ buffer, cond, unsafe));
+ if (error)
+ return ERR_PTR(error);
+ new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
+ aa_label_merge(&profile->label, onexec,
+ GFP_KERNEL),
+- profile_transition(profile, bprm, buffer,
++ profile_transition(subj_cred, profile, bprm,
++ buffer,
+ cond, unsafe));
+ }
+
+@@ -838,7 +852,8 @@ static struct aa_label *handle_onexec(struct aa_label *label,
+
+ /* TODO: get rid of GLOBAL_ROOT_UID */
+ error = fn_for_each_in_ns(label, profile,
+- aa_audit_file(profile, &nullperms, OP_CHANGE_ONEXEC,
++ aa_audit_file(subj_cred, profile, &nullperms,
++ OP_CHANGE_ONEXEC,
+ AA_MAY_ONEXEC, bprm->filename, NULL,
+ onexec, GLOBAL_ROOT_UID,
+ "failed to build target label", -ENOMEM));
+@@ -857,6 +872,7 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
+ {
+ struct aa_task_ctx *ctx;
+ struct aa_label *label, *new = NULL;
++ const struct cred *subj_cred;
+ struct aa_profile *profile;
+ char *buffer = NULL;
+ const char *info = NULL;
+@@ -869,6 +885,7 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
+ file_inode(bprm->file)->i_mode
+ };
+
++ subj_cred = current_cred();
+ ctx = task_ctx(current);
+ AA_BUG(!cred_label(bprm->cred));
+ AA_BUG(!ctx);
+@@ -895,11 +912,12 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
+
+ /* Test for onexec first as onexec override other x transitions. */
+ if (ctx->onexec)
+- new = handle_onexec(label, ctx->onexec, ctx->token,
++ new = handle_onexec(subj_cred, label, ctx->onexec, ctx->token,
+ bprm, buffer, &cond, &unsafe);
+ else
+ new = fn_label_build(label, profile, GFP_KERNEL,
+- profile_transition(profile, bprm, buffer,
++ profile_transition(subj_cred, profile, bprm,
++ buffer,
+ &cond, &unsafe));
+
+ AA_BUG(!new);
+@@ -934,7 +952,7 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
+
+ if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) {
+ /* TODO: test needs to be profile of label to new */
+- error = may_change_ptraced_domain(new, &info);
++ error = may_change_ptraced_domain(bprm->cred, new, &info);
+ if (error)
+ goto audit;
+ }
+@@ -971,7 +989,8 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
+
+ audit:
+ error = fn_for_each(label, profile,
+- aa_audit_file(profile, &nullperms, OP_EXEC, MAY_EXEC,
++ aa_audit_file(current_cred(), profile, &nullperms,
++ OP_EXEC, MAY_EXEC,
+ bprm->filename, NULL, new,
+ vfsuid_into_kuid(vfsuid), info, error));
+ aa_put_label(new);
+@@ -987,7 +1006,8 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
+ *
+ * Returns: label for hat transition OR ERR_PTR. Does NOT return NULL
+ */
+-static struct aa_label *build_change_hat(struct aa_profile *profile,
++static struct aa_label *build_change_hat(const struct cred *subj_cred,
++ struct aa_profile *profile,
+ const char *name, bool sibling)
+ {
+ struct aa_profile *root, *hat = NULL;
+@@ -1019,7 +1039,8 @@ static struct aa_label *build_change_hat(struct aa_profile *profile,
+ aa_put_profile(root);
+
+ audit:
+- aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
++ aa_audit_file(subj_cred, profile, &nullperms, OP_CHANGE_HAT,
++ AA_MAY_CHANGEHAT,
+ name, hat ? hat->base.hname : NULL,
+ hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
+ error);
+@@ -1035,7 +1056,8 @@ static struct aa_label *build_change_hat(struct aa_profile *profile,
+ *
+ * Returns: label for hat transition or ERR_PTR. Does not return NULL
+ */
+-static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
++static struct aa_label *change_hat(const struct cred *subj_cred,
++ struct aa_label *label, const char *hats[],
+ int count, int flags)
+ {
+ struct aa_profile *profile, *root, *hat = NULL;
+@@ -1111,7 +1133,8 @@ static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
+ */
+ /* TODO: get rid of GLOBAL_ROOT_UID */
+ if (count > 1 || COMPLAIN_MODE(profile)) {
+- aa_audit_file(profile, &nullperms, OP_CHANGE_HAT,
++ aa_audit_file(subj_cred, profile, &nullperms,
++ OP_CHANGE_HAT,
+ AA_MAY_CHANGEHAT, name, NULL, NULL,
+ GLOBAL_ROOT_UID, info, error);
+ }
+@@ -1120,7 +1143,8 @@ static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
+
+ build:
+ new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
+- build_change_hat(profile, name, sibling),
++ build_change_hat(subj_cred, profile, name,
++ sibling),
+ aa_get_label(&profile->label));
+ if (!new) {
+ info = "label build failed";
+@@ -1150,7 +1174,7 @@ static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
+ */
+ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
+ {
+- const struct cred *cred;
++ const struct cred *subj_cred;
+ struct aa_task_ctx *ctx = task_ctx(current);
+ struct aa_label *label, *previous, *new = NULL, *target = NULL;
+ struct aa_profile *profile;
+@@ -1159,8 +1183,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
+ int error = 0;
+
+ /* released below */
+- cred = get_current_cred();
+- label = aa_get_newest_cred_label(cred);
++ subj_cred = get_current_cred();
++ label = aa_get_newest_cred_label(subj_cred);
+ previous = aa_get_newest_label(ctx->previous);
+
+ /*
+@@ -1180,7 +1204,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
+ }
+
+ if (count) {
+- new = change_hat(label, hats, count, flags);
++ new = change_hat(subj_cred, label, hats, count, flags);
+ AA_BUG(!new);
+ if (IS_ERR(new)) {
+ error = PTR_ERR(new);
+@@ -1189,7 +1213,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
+ goto out;
+ }
+
+- error = may_change_ptraced_domain(new, &info);
++ /* target cred is the same as current except new label */
++ error = may_change_ptraced_domain(subj_cred, new, &info);
+ if (error)
+ goto fail;
+
+@@ -1242,7 +1267,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
+ aa_put_label(new);
+ aa_put_label(previous);
+ aa_put_label(label);
+- put_cred(cred);
++ put_cred(subj_cred);
+
+ return error;
+
+@@ -1252,7 +1277,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
+
+ fail:
+ fn_for_each_in_ns(label, profile,
+- aa_audit_file(profile, &perms, OP_CHANGE_HAT,
++ aa_audit_file(subj_cred, profile, &perms, OP_CHANGE_HAT,
+ AA_MAY_CHANGEHAT, NULL, NULL, target,
+ GLOBAL_ROOT_UID, info, error));
+
+@@ -1261,6 +1286,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags)
+
+
+ static int change_profile_perms_wrapper(const char *op, const char *name,
++ const struct cred *subj_cred,
+ struct aa_profile *profile,
+ struct aa_label *target, bool stack,
+ u32 request, struct aa_perms *perms)
+@@ -1275,7 +1301,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name,
+ rules->file.start[AA_CLASS_FILE],
+ perms);
+ if (error)
+- error = aa_audit_file(profile, perms, op, request, name,
++ error = aa_audit_file(subj_cred, profile, perms, op, request,
++ name,
+ NULL, target, GLOBAL_ROOT_UID, info,
+ error);
+
+@@ -1304,6 +1331,7 @@ int aa_change_profile(const char *fqname, int flags)
+ const char *auditname = fqname; /* retain leading & if stack */
+ bool stack = flags & AA_CHANGE_STACK;
+ struct aa_task_ctx *ctx = task_ctx(current);
++ const struct cred *subj_cred = get_current_cred();
+ int error = 0;
+ char *op;
+ u32 request;
+@@ -1381,6 +1409,7 @@ int aa_change_profile(const char *fqname, int flags)
+ */
+ error = fn_for_each_in_ns(label, profile,
+ change_profile_perms_wrapper(op, auditname,
++ subj_cred,
+ profile, target, stack,
+ request, &perms));
+ if (error)
+@@ -1391,7 +1420,7 @@ int aa_change_profile(const char *fqname, int flags)
+
+ check:
+ /* check if tracing task is allowed to trace target domain */
+- error = may_change_ptraced_domain(target, &info);
++ error = may_change_ptraced_domain(subj_cred, target, &info);
+ if (error && !fn_for_each_in_ns(label, profile,
+ COMPLAIN_MODE(profile)))
+ goto audit;
+@@ -1451,7 +1480,8 @@ int aa_change_profile(const char *fqname, int flags)
+
+ audit:
+ error = fn_for_each_in_ns(label, profile,
+- aa_audit_file(profile, &perms, op, request, auditname,
++ aa_audit_file(subj_cred,
++ profile, &perms, op, request, auditname,
+ NULL, new ? new : target,
+ GLOBAL_ROOT_UID, info, error));
+
+@@ -1459,6 +1489,7 @@ int aa_change_profile(const char *fqname, int flags)
+ aa_put_label(new);
+ aa_put_label(target);
+ aa_put_label(label);
++ put_cred(subj_cred);
+
+ return error;
+ }
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index 5bfa70a972071..6fd21324a097f 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -45,7 +45,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
+ {
+ struct common_audit_data *sa = va;
+ struct apparmor_audit_data *ad = aad(sa);
+- kuid_t fsuid = current_fsuid();
++ kuid_t fsuid = ad->subj_cred ? ad->subj_cred->fsuid : current_fsuid();
+ char str[10];
+
+ if (ad->request & AA_AUDIT_FILE_MASK) {
+@@ -77,6 +77,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
+
+ /**
+ * aa_audit_file - handle the auditing of file operations
++ * @subj_cred: cred of the subject
+ * @profile: the profile being enforced (NOT NULL)
+ * @perms: the permissions computed for the request (NOT NULL)
+ * @op: operation being mediated
+@@ -90,7 +91,8 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
+ *
+ * Returns: %0 or error on failure
+ */
+-int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
++int aa_audit_file(const struct cred *subj_cred,
++ struct aa_profile *profile, struct aa_perms *perms,
+ const char *op, u32 request, const char *name,
+ const char *target, struct aa_label *tlabel,
+ kuid_t ouid, const char *info, int error)
+@@ -98,6 +100,7 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
+ int type = AUDIT_APPARMOR_AUTO;
+ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_TASK, AA_CLASS_FILE, op);
+
++ ad.subj_cred = subj_cred;
+ ad.request = request;
+ ad.name = name;
+ ad.fs.target = target;
+@@ -141,7 +144,21 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
+ return aa_audit(type, profile, &ad, file_audit_cb);
+ }
+
+-static int path_name(const char *op, struct aa_label *label,
++/**
++ * is_deleted - test if a file has been completely unlinked
++ * @dentry: dentry of file to test for deletion (NOT NULL)
++ *
++ * Returns: true if deleted else false
++ */
++static inline bool is_deleted(struct dentry *dentry)
++{
++ if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
++ return true;
++ return false;
++}
++
++static int path_name(const char *op, const struct cred *subj_cred,
++ struct aa_label *label,
+ const struct path *path, int flags, char *buffer,
+ const char **name, struct path_cond *cond, u32 request)
+ {
+@@ -153,7 +170,8 @@ static int path_name(const char *op, struct aa_label *label,
+ labels_profile(label)->disconnected);
+ if (error) {
+ fn_for_each_confined(label, profile,
+- aa_audit_file(profile, &nullperms, op, request, *name,
++ aa_audit_file(subj_cred,
++ profile, &nullperms, op, request, *name,
+ NULL, NULL, cond->uid, info, error));
+ return error;
+ }
+@@ -207,9 +225,9 @@ aa_state_t aa_str_perms(struct aa_policydb *file_rules, aa_state_t start,
+ return state;
+ }
+
+-static int __aa_path_perm(const char *op, struct aa_profile *profile,
+- const char *name, u32 request,
+- struct path_cond *cond, int flags,
++static int __aa_path_perm(const char *op, const struct cred *subj_cred,
++ struct aa_profile *profile, const char *name,
++ u32 request, struct path_cond *cond, int flags,
+ struct aa_perms *perms)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+@@ -222,12 +240,14 @@ static int __aa_path_perm(const char *op, struct aa_profile *profile,
+ name, cond, perms);
+ if (request & ~perms->allow)
+ e = -EACCES;
+- return aa_audit_file(profile, perms, op, request, name, NULL, NULL,
++ return aa_audit_file(subj_cred,
++ profile, perms, op, request, name, NULL, NULL,
+ cond->uid, NULL, e);
+ }
+
+
+-static int profile_path_perm(const char *op, struct aa_profile *profile,
++static int profile_path_perm(const char *op, const struct cred *subj_cred,
++ struct aa_profile *profile,
+ const struct path *path, char *buffer, u32 request,
+ struct path_cond *cond, int flags,
+ struct aa_perms *perms)
+@@ -238,18 +258,19 @@ static int profile_path_perm(const char *op, struct aa_profile *profile,
+ if (profile_unconfined(profile))
+ return 0;
+
+- error = path_name(op, &profile->label, path,
++ error = path_name(op, subj_cred, &profile->label, path,
+ flags | profile->path_flags, buffer, &name, cond,
+ request);
+ if (error)
+ return error;
+- return __aa_path_perm(op, profile, name, request, cond, flags,
+- perms);
++ return __aa_path_perm(op, subj_cred, profile, name, request, cond,
++ flags, perms);
+ }
+
+ /**
+ * aa_path_perm - do permissions check & audit for @path
+ * @op: operation being checked
++ * @subj_cred: subject cred
+ * @label: profile being enforced (NOT NULL)
+ * @path: path to check permissions of (NOT NULL)
+ * @flags: any additional path flags beyond what the profile specifies
+@@ -258,7 +279,8 @@ static int profile_path_perm(const char *op, struct aa_profile *profile,
+ *
+ * Returns: %0 else error if access denied or other error
+ */
+-int aa_path_perm(const char *op, struct aa_label *label,
++int aa_path_perm(const char *op, const struct cred *subj_cred,
++ struct aa_label *label,
+ const struct path *path, int flags, u32 request,
+ struct path_cond *cond)
+ {
+@@ -273,8 +295,8 @@ int aa_path_perm(const char *op, struct aa_label *label,
+ if (!buffer)
+ return -ENOMEM;
+ error = fn_for_each_confined(label, profile,
+- profile_path_perm(op, profile, path, buffer, request,
+- cond, flags, &perms));
++ profile_path_perm(op, subj_cred, profile, path, buffer,
++ request, cond, flags, &perms));
+
+ aa_put_buffer(buffer);
+
+@@ -301,7 +323,8 @@ static inline bool xindex_is_subset(u32 link, u32 target)
+ return true;
+ }
+
+-static int profile_path_link(struct aa_profile *profile,
++static int profile_path_link(const struct cred *subj_cred,
++ struct aa_profile *profile,
+ const struct path *link, char *buffer,
+ const struct path *target, char *buffer2,
+ struct path_cond *cond)
+@@ -315,13 +338,15 @@ static int profile_path_link(struct aa_profile *profile,
+ aa_state_t state;
+ int error;
+
+- error = path_name(OP_LINK, &profile->label, link, profile->path_flags,
++ error = path_name(OP_LINK, subj_cred, &profile->label, link,
++ profile->path_flags,
+ buffer, &lname, cond, AA_MAY_LINK);
+ if (error)
+ goto audit;
+
+ /* buffer2 freed below, tname is pointer in buffer2 */
+- error = path_name(OP_LINK, &profile->label, target, profile->path_flags,
++ error = path_name(OP_LINK, subj_cred, &profile->label, target,
++ profile->path_flags,
+ buffer2, &tname, cond, AA_MAY_LINK);
+ if (error)
+ goto audit;
+@@ -381,12 +406,14 @@ static int profile_path_link(struct aa_profile *profile,
+ error = 0;
+
+ audit:
+- return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname,
++ return aa_audit_file(subj_cred,
++ profile, &lperms, OP_LINK, request, lname, tname,
+ NULL, cond->uid, info, error);
+ }
+
+ /**
+ * aa_path_link - Handle hard link permission check
++ * @subj_cred: subject cred
+ * @label: the label being enforced (NOT NULL)
+ * @old_dentry: the target dentry (NOT NULL)
+ * @new_dir: directory the new link will be created in (NOT NULL)
+@@ -403,7 +430,8 @@ static int profile_path_link(struct aa_profile *profile,
+ *
+ * Returns: %0 if allowed else error
+ */
+-int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
++int aa_path_link(const struct cred *subj_cred,
++ struct aa_label *label, struct dentry *old_dentry,
+ const struct path *new_dir, struct dentry *new_dentry)
+ {
+ struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry };
+@@ -424,8 +452,8 @@ int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
+ goto out;
+
+ error = fn_for_each_confined(label, profile,
+- profile_path_link(profile, &link, buffer, &target,
+- buffer2, &cond));
++ profile_path_link(subj_cred, profile, &link, buffer,
++ &target, buffer2, &cond));
+ out:
+ aa_put_buffer(buffer);
+ aa_put_buffer(buffer2);
+@@ -453,7 +481,8 @@ static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label,
+ spin_unlock(&fctx->lock);
+ }
+
+-static int __file_path_perm(const char *op, struct aa_label *label,
++static int __file_path_perm(const char *op, const struct cred *subj_cred,
++ struct aa_label *label,
+ struct aa_label *flabel, struct file *file,
+ u32 request, u32 denied, bool in_atomic)
+ {
+@@ -480,7 +509,8 @@ static int __file_path_perm(const char *op, struct aa_label *label,
+
+ /* check every profile in task label not in current cache */
+ error = fn_for_each_not_in_set(flabel, label, profile,
+- profile_path_perm(op, profile, &file->f_path, buffer,
++ profile_path_perm(op, subj_cred, profile,
++ &file->f_path, buffer,
+ request, &cond, flags, &perms));
+ if (denied && !error) {
+ /*
+@@ -493,12 +523,14 @@ static int __file_path_perm(const char *op, struct aa_label *label,
+ */
+ if (label == flabel)
+ error = fn_for_each(label, profile,
+- profile_path_perm(op, profile, &file->f_path,
++ profile_path_perm(op, subj_cred,
++ profile, &file->f_path,
+ buffer, request, &cond, flags,
+ &perms));
+ else
+ error = fn_for_each_not_in_set(label, flabel, profile,
+- profile_path_perm(op, profile, &file->f_path,
++ profile_path_perm(op, subj_cred,
++ profile, &file->f_path,
+ buffer, request, &cond, flags,
+ &perms));
+ }
+@@ -510,7 +542,8 @@ static int __file_path_perm(const char *op, struct aa_label *label,
+ return error;
+ }
+
+-static int __file_sock_perm(const char *op, struct aa_label *label,
++static int __file_sock_perm(const char *op, const struct cred *subj_cred,
++ struct aa_label *label,
+ struct aa_label *flabel, struct file *file,
+ u32 request, u32 denied)
+ {
+@@ -524,11 +557,12 @@ static int __file_sock_perm(const char *op, struct aa_label *label,
+ return 0;
+
+ /* TODO: improve to skip profiles cached in flabel */
+- error = aa_sock_file_perm(label, op, request, sock);
++ error = aa_sock_file_perm(subj_cred, label, op, request, sock);
+ if (denied) {
+ /* TODO: improve to skip profiles checked above */
+ /* check every profile in file label to is cached */
+- last_error(error, aa_sock_file_perm(flabel, op, request, sock));
++ last_error(error, aa_sock_file_perm(subj_cred, flabel, op,
++ request, sock));
+ }
+ if (!error)
+ update_file_ctx(file_ctx(file), label, request);
+@@ -539,6 +573,7 @@ static int __file_sock_perm(const char *op, struct aa_label *label,
+ /**
+ * aa_file_perm - do permission revalidation check & audit for @file
+ * @op: operation being checked
++ * @subj_cred: subject cred
+ * @label: label being enforced (NOT NULL)
+ * @file: file to revalidate access permissions on (NOT NULL)
+ * @request: requested permissions
+@@ -546,7 +581,8 @@ static int __file_sock_perm(const char *op, struct aa_label *label,
+ *
+ * Returns: %0 if access allowed else error
+ */
+-int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
++int aa_file_perm(const char *op, const struct cred *subj_cred,
++ struct aa_label *label, struct file *file,
+ u32 request, bool in_atomic)
+ {
+ struct aa_file_ctx *fctx;
+@@ -582,19 +618,19 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
+ /* TODO: label cross check */
+
+ if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry))
+- error = __file_path_perm(op, label, flabel, file, request,
+- denied, in_atomic);
++ error = __file_path_perm(op, subj_cred, label, flabel, file,
++ request, denied, in_atomic);
+
+ else if (S_ISSOCK(file_inode(file)->i_mode))
+- error = __file_sock_perm(op, label, flabel, file, request,
+- denied);
++ error = __file_sock_perm(op, subj_cred, label, flabel, file,
++ request, denied);
+ aa_put_label(flabel);
+
+ done:
+ return error;
+ }
+
+-static void revalidate_tty(struct aa_label *label)
++static void revalidate_tty(const struct cred *subj_cred, struct aa_label *label)
+ {
+ struct tty_struct *tty;
+ int drop_tty = 0;
+@@ -612,8 +648,8 @@ static void revalidate_tty(struct aa_label *label)
+ struct tty_file_private, list);
+ file = file_priv->file;
+
+- if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE,
+- IN_ATOMIC))
++ if (aa_file_perm(OP_INHERIT, subj_cred, label, file,
++ MAY_READ | MAY_WRITE, IN_ATOMIC))
+ drop_tty = 1;
+ }
+ spin_unlock(&tty->files_lock);
+@@ -623,12 +659,17 @@ static void revalidate_tty(struct aa_label *label)
+ no_tty();
+ }
+
++struct cred_label {
++ const struct cred *cred;
++ struct aa_label *label;
++};
++
+ static int match_file(const void *p, struct file *file, unsigned int fd)
+ {
+- struct aa_label *label = (struct aa_label *)p;
++ struct cred_label *cl = (struct cred_label *)p;
+
+- if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file),
+- IN_ATOMIC))
++ if (aa_file_perm(OP_INHERIT, cl->cred, cl->label, file,
++ aa_map_file_to_perms(file), IN_ATOMIC))
+ return fd + 1;
+ return 0;
+ }
+@@ -638,13 +679,17 @@ static int match_file(const void *p, struct file *file, unsigned int fd)
+ void aa_inherit_files(const struct cred *cred, struct files_struct *files)
+ {
+ struct aa_label *label = aa_get_newest_cred_label(cred);
++ struct cred_label cl = {
++ .cred = cred,
++ .label = label,
++ };
+ struct file *devnull = NULL;
+ unsigned int n;
+
+- revalidate_tty(label);
++ revalidate_tty(cred, label);
+
+ /* Revalidate access to inherited open files. */
+- n = iterate_fd(files, 0, match_file, label);
++ n = iterate_fd(files, 0, match_file, &cl);
+ if (!n) /* none found? */
+ goto out;
+
+@@ -654,7 +699,7 @@ void aa_inherit_files(const struct cred *cred, struct files_struct *files)
+ /* replace all the matching ones with this */
+ do {
+ replace_fd(n - 1, devnull, 0);
+- } while ((n = iterate_fd(files, n, match_file, label)) != 0);
++ } while ((n = iterate_fd(files, n, match_file, &cl)) != 0);
+ if (devnull)
+ fput(devnull);
+ out:
+diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
+index 096f0a04af87f..42d701fec5a6d 100644
+--- a/security/apparmor/include/audit.h
++++ b/security/apparmor/include/audit.h
+@@ -109,6 +109,7 @@ struct apparmor_audit_data {
+ int type;
+ u16 class;
+ const char *op;
++ const struct cred *subj_cred;
+ struct aa_label *subj_label;
+ const char *name;
+ const char *info;
+diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
+index d420e2d10b31b..d6dcc604ec0cc 100644
+--- a/security/apparmor/include/capability.h
++++ b/security/apparmor/include/capability.h
+@@ -36,7 +36,8 @@ struct aa_caps {
+
+ extern struct aa_sfs_entry aa_sfs_entry_caps[];
+
+-int aa_capable(struct aa_label *label, int cap, unsigned int opts);
++int aa_capable(const struct cred *subj_cred, struct aa_label *label,
++ int cap, unsigned int opts);
+
+ static inline void aa_free_cap_rules(struct aa_caps *caps)
+ {
+diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
+index 5be620af33ba0..64dc6d1a7a05c 100644
+--- a/security/apparmor/include/file.h
++++ b/security/apparmor/include/file.h
+@@ -108,7 +108,8 @@ struct path_cond {
+
+ #define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill)
+
+-int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
++int aa_audit_file(const struct cred *cred,
++ struct aa_profile *profile, struct aa_perms *perms,
+ const char *op, u32 request, const char *name,
+ const char *target, struct aa_label *tlabel, kuid_t ouid,
+ const char *info, int error);
+@@ -119,14 +120,16 @@ aa_state_t aa_str_perms(struct aa_policydb *file_rules, aa_state_t start,
+ const char *name, struct path_cond *cond,
+ struct aa_perms *perms);
+
+-int aa_path_perm(const char *op, struct aa_label *label,
+- const struct path *path, int flags, u32 request,
+- struct path_cond *cond);
++int aa_path_perm(const char *op, const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
++ int flags, u32 request, struct path_cond *cond);
+
+-int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
+- const struct path *new_dir, struct dentry *new_dentry);
++int aa_path_link(const struct cred *subj_cred, struct aa_label *label,
++ struct dentry *old_dentry, const struct path *new_dir,
++ struct dentry *new_dentry);
+
+-int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
++int aa_file_perm(const char *op, const struct cred *subj_cred,
++ struct aa_label *label, struct file *file,
+ u32 request, bool in_atomic);
+
+ void aa_inherit_files(const struct cred *cred, struct files_struct *files);
+diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
+index a1ac6ffb95e9c..74d17052f76bc 100644
+--- a/security/apparmor/include/ipc.h
++++ b/security/apparmor/include/ipc.h
+@@ -13,6 +13,8 @@
+
+ #include <linux/sched.h>
+
+-int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
++int aa_may_signal(const struct cred *subj_cred, struct aa_label *sender,
++ const struct cred *target_cred, struct aa_label *target,
++ int sig);
+
+ #endif /* __AA_IPC_H */
+diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h
+index a710683b24965..10c76f906a653 100644
+--- a/security/apparmor/include/mount.h
++++ b/security/apparmor/include/mount.h
+@@ -25,26 +25,33 @@
+
+ #define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN)
+
+-int aa_remount(struct aa_label *label, const struct path *path,
++int aa_remount(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ unsigned long flags, void *data);
+
+-int aa_bind_mount(struct aa_label *label, const struct path *path,
++int aa_bind_mount(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ const char *old_name, unsigned long flags);
+
+
+-int aa_mount_change_type(struct aa_label *label, const struct path *path,
++int aa_mount_change_type(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ unsigned long flags);
+
+-int aa_move_mount(struct aa_label *label, const struct path *path,
++int aa_move_mount(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ const char *old_name);
+
+-int aa_new_mount(struct aa_label *label, const char *dev_name,
++int aa_new_mount(const struct cred *subj_cred,
++ struct aa_label *label, const char *dev_name,
+ const struct path *path, const char *type, unsigned long flags,
+ void *data);
+
+-int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags);
++int aa_umount(const struct cred *subj_cred,
++ struct aa_label *label, struct vfsmount *mnt, int flags);
+
+-int aa_pivotroot(struct aa_label *label, const struct path *old_path,
++int aa_pivotroot(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *old_path,
+ const struct path *new_path);
+
+ #endif /* __AA_MOUNT_H */
+diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
+index a336e57864e89..aa8515af677f0 100644
+--- a/security/apparmor/include/net.h
++++ b/security/apparmor/include/net.h
+@@ -93,7 +93,8 @@ void audit_net_cb(struct audit_buffer *ab, void *va);
+ int aa_profile_af_perm(struct aa_profile *profile,
+ struct apparmor_audit_data *ad,
+ u32 request, u16 family, int type);
+-int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
++int aa_af_perm(const struct cred *subj_cred, struct aa_label *label,
++ const char *op, u32 request, u16 family,
+ int type, int protocol);
+ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
+ struct apparmor_audit_data *ad,
+@@ -105,7 +106,8 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile,
+ }
+ int aa_sk_perm(const char *op, u32 request, struct sock *sk);
+
+-int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
++int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
++ const char *op, u32 request,
+ struct socket *sock);
+
+ int apparmor_secmark_check(struct aa_label *label, char *op, u32 request,
+diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
+index 545f791cabdae..fa15a5c7febb8 100644
+--- a/security/apparmor/include/policy.h
++++ b/security/apparmor/include/policy.h
+@@ -370,9 +370,12 @@ static inline int AUDIT_MODE(struct aa_profile *profile)
+ return profile->audit;
+ }
+
+-bool aa_policy_view_capable(struct aa_label *label, struct aa_ns *ns);
+-bool aa_policy_admin_capable(struct aa_label *label, struct aa_ns *ns);
+-int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns,
++bool aa_policy_view_capable(const struct cred *subj_cred,
++ struct aa_label *label, struct aa_ns *ns);
++bool aa_policy_admin_capable(const struct cred *subj_cred,
++ struct aa_label *label, struct aa_ns *ns);
++int aa_may_manage_policy(const struct cred *subj_cred,
++ struct aa_label *label, struct aa_ns *ns,
+ u32 mask);
+ bool aa_current_policy_view_capable(struct aa_ns *ns);
+ bool aa_current_policy_admin_capable(struct aa_ns *ns);
+diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h
+index 961d85d328ea9..ad2c0da8e64fc 100644
+--- a/security/apparmor/include/resource.h
++++ b/security/apparmor/include/resource.h
+@@ -33,7 +33,8 @@ struct aa_rlimit {
+ extern struct aa_sfs_entry aa_sfs_entry_rlimit[];
+
+ int aa_map_resource(int resource);
+-int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
++int aa_task_setrlimit(const struct cred *subj_cred, struct aa_label *label,
++ struct task_struct *task,
+ unsigned int resource, struct rlimit *new_rlim);
+
+ void __aa_transition_rlimits(struct aa_label *old, struct aa_label *new);
+diff --git a/security/apparmor/include/task.h b/security/apparmor/include/task.h
+index 13437d62c70f4..29ba55107b7d6 100644
+--- a/security/apparmor/include/task.h
++++ b/security/apparmor/include/task.h
+@@ -91,7 +91,8 @@ static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx)
+ "segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \
+ "xcpu xfsz vtalrm prof winch io pwr sys emt lost"
+
+-int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
++int aa_may_ptrace(const struct cred *tracer_cred, struct aa_label *tracer,
++ const struct cred *tracee_cred, struct aa_label *tracee,
+ u32 request);
+
+
+diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
+index fd8306399b820..c0d0dbd7b4c4b 100644
+--- a/security/apparmor/ipc.c
++++ b/security/apparmor/ipc.c
+@@ -75,7 +75,8 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va)
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+
+-static int profile_signal_perm(struct aa_profile *profile,
++static int profile_signal_perm(const struct cred *cred,
++ struct aa_profile *profile,
+ struct aa_label *peer, u32 request,
+ struct apparmor_audit_data *ad)
+ {
+@@ -88,6 +89,7 @@ static int profile_signal_perm(struct aa_profile *profile,
+ !ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_SIGNAL))
+ return 0;
+
++ ad->subj_cred = cred;
+ ad->peer = peer;
+ /* TODO: secondary cache check <profile, profile, perm> */
+ state = aa_dfa_next(rules->policy.dfa,
+@@ -98,7 +100,9 @@ static int profile_signal_perm(struct aa_profile *profile,
+ return aa_check_perms(profile, &perms, request, ad, audit_signal_cb);
+ }
+
+-int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
++int aa_may_signal(const struct cred *subj_cred, struct aa_label *sender,
++ const struct cred *target_cred, struct aa_label *target,
++ int sig)
+ {
+ struct aa_profile *profile;
+ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_SIGNAL, OP_SIGNAL);
+@@ -106,6 +110,8 @@ int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig)
+ ad.signal = map_signal_num(sig);
+ ad.unmappedsig = sig;
+ return xcheck_labels(sender, target, profile,
+- profile_signal_perm(profile, target, MAY_WRITE, &ad),
+- profile_signal_perm(profile, sender, MAY_READ, &ad));
++ profile_signal_perm(subj_cred, profile, target,
++ MAY_WRITE, &ad),
++ profile_signal_perm(target_cred, profile, sender,
++ MAY_READ, &ad));
+ }
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 359fbfbb4a66e..60f95cc4532a8 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -116,15 +116,17 @@ static int apparmor_ptrace_access_check(struct task_struct *child,
+ unsigned int mode)
+ {
+ struct aa_label *tracer, *tracee;
++ const struct cred *cred;
+ int error;
+
++ cred = get_task_cred(child);
++ tracee = cred_label(cred); /* ref count on cred */
+ tracer = __begin_current_label_crit_section();
+- tracee = aa_get_task_label(child);
+- error = aa_may_ptrace(tracer, tracee,
++ error = aa_may_ptrace(current_cred(), tracer, cred, tracee,
+ (mode & PTRACE_MODE_READ) ? AA_PTRACE_READ
+ : AA_PTRACE_TRACE);
+- aa_put_label(tracee);
+ __end_current_label_crit_section(tracer);
++ put_cred(cred);
+
+ return error;
+ }
+@@ -132,12 +134,15 @@ static int apparmor_ptrace_access_check(struct task_struct *child,
+ static int apparmor_ptrace_traceme(struct task_struct *parent)
+ {
+ struct aa_label *tracer, *tracee;
++ const struct cred *cred;
+ int error;
+
+ tracee = __begin_current_label_crit_section();
+- tracer = aa_get_task_label(parent);
+- error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
+- aa_put_label(tracer);
++ cred = get_task_cred(parent);
++ tracer = cred_label(cred); /* ref count on cred */
++ error = aa_may_ptrace(cred, tracer, current_cred(), tracee,
++ AA_PTRACE_TRACE);
++ put_cred(cred);
+ __end_current_label_crit_section(tracee);
+
+ return error;
+@@ -188,7 +193,7 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
+
+ label = aa_get_newest_cred_label(cred);
+ if (!unconfined(label))
+- error = aa_capable(label, cap, opts);
++ error = aa_capable(cred, label, cap, opts);
+ aa_put_label(label);
+
+ return error;
+@@ -211,7 +216,8 @@ static int common_perm(const char *op, const struct path *path, u32 mask,
+
+ label = __begin_current_label_crit_section();
+ if (!unconfined(label))
+- error = aa_path_perm(op, label, path, 0, mask, cond);
++ error = aa_path_perm(op, current_cred(), label, path, 0, mask,
++ cond);
+ __end_current_label_crit_section(label);
+
+ return error;
+@@ -357,7 +363,8 @@ static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_
+
+ label = begin_current_label_crit_section();
+ if (!unconfined(label))
+- error = aa_path_link(label, old_dentry, new_dir, new_dentry);
++ error = aa_path_link(current_cred(), label, old_dentry, new_dir,
++ new_dentry);
+ end_current_label_crit_section(label);
+
+ return error;
+@@ -396,23 +403,27 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d
+ vfsuid = i_uid_into_vfsuid(idmap, d_backing_inode(old_dentry));
+ cond_exchange.uid = vfsuid_into_kuid(vfsuid);
+
+- error = aa_path_perm(OP_RENAME_SRC, label, &new_path, 0,
++ error = aa_path_perm(OP_RENAME_SRC, current_cred(),
++ label, &new_path, 0,
+ MAY_READ | AA_MAY_GETATTR | MAY_WRITE |
+ AA_MAY_SETATTR | AA_MAY_DELETE,
+ &cond_exchange);
+ if (!error)
+- error = aa_path_perm(OP_RENAME_DEST, label, &old_path,
++ error = aa_path_perm(OP_RENAME_DEST, current_cred(),
++ label, &old_path,
+ 0, MAY_WRITE | AA_MAY_SETATTR |
+ AA_MAY_CREATE, &cond_exchange);
+ }
+
+ if (!error)
+- error = aa_path_perm(OP_RENAME_SRC, label, &old_path, 0,
++ error = aa_path_perm(OP_RENAME_SRC, current_cred(),
++ label, &old_path, 0,
+ MAY_READ | AA_MAY_GETATTR | MAY_WRITE |
+ AA_MAY_SETATTR | AA_MAY_DELETE,
+ &cond);
+ if (!error)
+- error = aa_path_perm(OP_RENAME_DEST, label, &new_path,
++ error = aa_path_perm(OP_RENAME_DEST, current_cred(),
++ label, &new_path,
+ 0, MAY_WRITE | AA_MAY_SETATTR |
+ AA_MAY_CREATE, &cond);
+
+@@ -467,7 +478,8 @@ static int apparmor_file_open(struct file *file)
+ vfsuid = i_uid_into_vfsuid(idmap, inode);
+ cond.uid = vfsuid_into_kuid(vfsuid);
+
+- error = aa_path_perm(OP_OPEN, label, &file->f_path, 0,
++ error = aa_path_perm(OP_OPEN, file->f_cred,
++ label, &file->f_path, 0,
+ aa_map_file_to_perms(file), &cond);
+ /* todo cache full allowed permissions set and state */
+ fctx->allow = aa_map_file_to_perms(file);
+@@ -507,7 +519,7 @@ static int common_file_perm(const char *op, struct file *file, u32 mask,
+ return -EACCES;
+
+ label = __begin_current_label_crit_section();
+- error = aa_file_perm(op, label, file, mask, in_atomic);
++ error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic);
+ __end_current_label_crit_section(label);
+
+ return error;
+@@ -585,17 +597,21 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path,
+ label = __begin_current_label_crit_section();
+ if (!unconfined(label)) {
+ if (flags & MS_REMOUNT)
+- error = aa_remount(label, path, flags, data);
++ error = aa_remount(current_cred(), label, path, flags,
++ data);
+ else if (flags & MS_BIND)
+- error = aa_bind_mount(label, path, dev_name, flags);
++ error = aa_bind_mount(current_cred(), label, path,
++ dev_name, flags);
+ else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE |
+ MS_UNBINDABLE))
+- error = aa_mount_change_type(label, path, flags);
++ error = aa_mount_change_type(current_cred(), label,
++ path, flags);
+ else if (flags & MS_MOVE)
+- error = aa_move_mount(label, path, dev_name);
++ error = aa_move_mount(current_cred(), label, path,
++ dev_name);
+ else
+- error = aa_new_mount(label, dev_name, path, type,
+- flags, data);
++ error = aa_new_mount(current_cred(), label, dev_name,
++ path, type, flags, data);
+ }
+ __end_current_label_crit_section(label);
+
+@@ -609,7 +625,7 @@ static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
+
+ label = __begin_current_label_crit_section();
+ if (!unconfined(label))
+- error = aa_umount(label, mnt, flags);
++ error = aa_umount(current_cred(), label, mnt, flags);
+ __end_current_label_crit_section(label);
+
+ return error;
+@@ -623,7 +639,7 @@ static int apparmor_sb_pivotroot(const struct path *old_path,
+
+ label = aa_get_current_label();
+ if (!unconfined(label))
+- error = aa_pivotroot(label, old_path, new_path);
++ error = aa_pivotroot(current_cred(), label, old_path, new_path);
+ aa_put_label(label);
+
+ return error;
+@@ -785,7 +801,8 @@ static int apparmor_task_setrlimit(struct task_struct *task,
+ int error = 0;
+
+ if (!unconfined(label))
+- error = aa_task_setrlimit(label, task, resource, new_rlim);
++ error = aa_task_setrlimit(current_cred(), label, task,
++ resource, new_rlim);
+ __end_current_label_crit_section(label);
+
+ return error;
+@@ -794,26 +811,27 @@ static int apparmor_task_setrlimit(struct task_struct *task,
+ static int apparmor_task_kill(struct task_struct *target, struct kernel_siginfo *info,
+ int sig, const struct cred *cred)
+ {
++ const struct cred *tc;
+ struct aa_label *cl, *tl;
+ int error;
+
++ tc = get_task_cred(target);
++ tl = aa_get_newest_cred_label(tc);
+ if (cred) {
+ /*
+ * Dealing with USB IO specific behavior
+ */
+ cl = aa_get_newest_cred_label(cred);
+- tl = aa_get_task_label(target);
+- error = aa_may_signal(cl, tl, sig);
++ error = aa_may_signal(cred, cl, tc, tl, sig);
+ aa_put_label(cl);
+- aa_put_label(tl);
+ return error;
++ } else {
++ cl = __begin_current_label_crit_section();
++ error = aa_may_signal(current_cred(), cl, tc, tl, sig);
++ __end_current_label_crit_section(cl);
+ }
+-
+- cl = __begin_current_label_crit_section();
+- tl = aa_get_task_label(target);
+- error = aa_may_signal(cl, tl, sig);
+ aa_put_label(tl);
+- __end_current_label_crit_section(cl);
++ put_cred(tc);
+
+ return error;
+ }
+@@ -879,7 +897,8 @@ static int apparmor_socket_create(int family, int type, int protocol, int kern)
+ if (!(kern || unconfined(label)))
+ error = af_select(family,
+ create_perm(label, family, type, protocol),
+- aa_af_perm(label, OP_CREATE, AA_MAY_CREATE,
++ aa_af_perm(current_cred(), label,
++ OP_CREATE, AA_MAY_CREATE,
+ family, type, protocol));
+ end_current_label_crit_section(label);
+
+diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
+index 3830bceff9c8b..2bb77aacc49ae 100644
+--- a/security/apparmor/mount.c
++++ b/security/apparmor/mount.c
+@@ -113,6 +113,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+
+ /**
+ * audit_mount - handle the auditing of mount operations
++ * @subj_cred: cred of the subject
+ * @profile: the profile being enforced (NOT NULL)
+ * @op: operation being mediated (NOT NULL)
+ * @name: name of object being mediated (MAYBE NULL)
+@@ -128,7 +129,8 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+ *
+ * Returns: %0 or error on failure
+ */
+-static int audit_mount(struct aa_profile *profile, const char *op,
++static int audit_mount(const struct cred *subj_cred,
++ struct aa_profile *profile, const char *op,
+ const char *name, const char *src_name,
+ const char *type, const char *trans,
+ unsigned long flags, const void *data, u32 request,
+@@ -166,6 +168,7 @@ static int audit_mount(struct aa_profile *profile, const char *op,
+ return error;
+ }
+
++ ad.subj_cred = subj_cred;
+ ad.name = name;
+ ad.mnt.src_name = src_name;
+ ad.mnt.type = type;
+@@ -284,6 +287,7 @@ static int path_flags(struct aa_profile *profile, const struct path *path)
+
+ /**
+ * match_mnt_path_str - handle path matching for mount
++ * @subj_cred: cred of confined subject
+ * @profile: the confining profile
+ * @mntpath: for the mntpnt (NOT NULL)
+ * @buffer: buffer to be used to lookup mntpath
+@@ -296,7 +300,8 @@ static int path_flags(struct aa_profile *profile, const struct path *path)
+ *
+ * Returns: 0 on success else error
+ */
+-static int match_mnt_path_str(struct aa_profile *profile,
++static int match_mnt_path_str(const struct cred *subj_cred,
++ struct aa_profile *profile,
+ const struct path *mntpath, char *buffer,
+ const char *devname, const char *type,
+ unsigned long flags, void *data, bool binary,
+@@ -337,12 +342,14 @@ static int match_mnt_path_str(struct aa_profile *profile,
+ error = 0;
+
+ audit:
+- return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL,
++ return audit_mount(subj_cred, profile, OP_MOUNT, mntpnt, devname,
++ type, NULL,
+ flags, data, AA_MAY_MOUNT, &perms, info, error);
+ }
+
+ /**
+ * match_mnt - handle path matching for mount
++ * @subj_cred: cred of the subject
+ * @profile: the confining profile
+ * @path: for the mntpnt (NOT NULL)
+ * @buffer: buffer to be used to lookup mntpath
+@@ -355,7 +362,8 @@ static int match_mnt_path_str(struct aa_profile *profile,
+ *
+ * Returns: 0 on success else error
+ */
+-static int match_mnt(struct aa_profile *profile, const struct path *path,
++static int match_mnt(const struct cred *subj_cred,
++ struct aa_profile *profile, const struct path *path,
+ char *buffer, const struct path *devpath, char *devbuffer,
+ const char *type, unsigned long flags, void *data,
+ bool binary)
+@@ -379,11 +387,12 @@ static int match_mnt(struct aa_profile *profile, const struct path *path,
+ devname = ERR_PTR(error);
+ }
+
+- return match_mnt_path_str(profile, path, buffer, devname, type, flags,
+- data, binary, info);
++ return match_mnt_path_str(subj_cred, profile, path, buffer, devname,
++ type, flags, data, binary, info);
+ }
+
+-int aa_remount(struct aa_label *label, const struct path *path,
++int aa_remount(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ unsigned long flags, void *data)
+ {
+ struct aa_profile *profile;
+@@ -400,14 +409,16 @@ int aa_remount(struct aa_label *label, const struct path *path,
+ if (!buffer)
+ return -ENOMEM;
+ error = fn_for_each_confined(label, profile,
+- match_mnt(profile, path, buffer, NULL, NULL, NULL,
++ match_mnt(subj_cred, profile, path, buffer, NULL,
++ NULL, NULL,
+ flags, data, binary));
+ aa_put_buffer(buffer);
+
+ return error;
+ }
+
+-int aa_bind_mount(struct aa_label *label, const struct path *path,
++int aa_bind_mount(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ const char *dev_name, unsigned long flags)
+ {
+ struct aa_profile *profile;
+@@ -434,8 +445,8 @@ int aa_bind_mount(struct aa_label *label, const struct path *path,
+ goto out;
+
+ error = fn_for_each_confined(label, profile,
+- match_mnt(profile, path, buffer, &old_path, old_buffer,
+- NULL, flags, NULL, false));
++ match_mnt(subj_cred, profile, path, buffer, &old_path,
++ old_buffer, NULL, flags, NULL, false));
+ out:
+ aa_put_buffer(buffer);
+ aa_put_buffer(old_buffer);
+@@ -444,7 +455,8 @@ int aa_bind_mount(struct aa_label *label, const struct path *path,
+ return error;
+ }
+
+-int aa_mount_change_type(struct aa_label *label, const struct path *path,
++int aa_mount_change_type(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ unsigned long flags)
+ {
+ struct aa_profile *profile;
+@@ -462,14 +474,16 @@ int aa_mount_change_type(struct aa_label *label, const struct path *path,
+ if (!buffer)
+ return -ENOMEM;
+ error = fn_for_each_confined(label, profile,
+- match_mnt(profile, path, buffer, NULL, NULL, NULL,
++ match_mnt(subj_cred, profile, path, buffer, NULL,
++ NULL, NULL,
+ flags, NULL, false));
+ aa_put_buffer(buffer);
+
+ return error;
+ }
+
+-int aa_move_mount(struct aa_label *label, const struct path *path,
++int aa_move_mount(const struct cred *subj_cred,
++ struct aa_label *label, const struct path *path,
+ const char *orig_name)
+ {
+ struct aa_profile *profile;
+@@ -493,7 +507,8 @@ int aa_move_mount(struct aa_label *label, const struct path *path,
+ if (!buffer || !old_buffer)
+ goto out;
+ error = fn_for_each_confined(label, profile,
+- match_mnt(profile, path, buffer, &old_path, old_buffer,
++ match_mnt(subj_cred, profile, path, buffer, &old_path,
++ old_buffer,
+ NULL, MS_MOVE, NULL, false));
+ out:
+ aa_put_buffer(buffer);
+@@ -503,9 +518,9 @@ int aa_move_mount(struct aa_label *label, const struct path *path,
+ return error;
+ }
+
+-int aa_new_mount(struct aa_label *label, const char *dev_name,
+- const struct path *path, const char *type, unsigned long flags,
+- void *data)
++int aa_new_mount(const struct cred *subj_cred, struct aa_label *label,
++ const char *dev_name, const struct path *path,
++ const char *type, unsigned long flags, void *data)
+ {
+ struct aa_profile *profile;
+ char *buffer = NULL, *dev_buffer = NULL;
+@@ -550,12 +565,14 @@ int aa_new_mount(struct aa_label *label, const char *dev_name,
+ goto out;
+ }
+ error = fn_for_each_confined(label, profile,
+- match_mnt(profile, path, buffer, dev_path, dev_buffer,
++ match_mnt(subj_cred, profile, path, buffer,
++ dev_path, dev_buffer,
+ type, flags, data, binary));
+ } else {
+ error = fn_for_each_confined(label, profile,
+- match_mnt_path_str(profile, path, buffer, dev_name,
+- type, flags, data, binary, NULL));
++ match_mnt_path_str(subj_cred, profile, path,
++ buffer, dev_name,
++ type, flags, data, binary, NULL));
+ }
+
+ out:
+@@ -567,7 +584,8 @@ int aa_new_mount(struct aa_label *label, const char *dev_name,
+ return error;
+ }
+
+-static int profile_umount(struct aa_profile *profile, const struct path *path,
++static int profile_umount(const struct cred *subj_cred,
++ struct aa_profile *profile, const struct path *path,
+ char *buffer)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+@@ -596,11 +614,13 @@ static int profile_umount(struct aa_profile *profile, const struct path *path,
+ error = -EACCES;
+
+ audit:
+- return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL,
++ return audit_mount(subj_cred, profile, OP_UMOUNT, name, NULL, NULL,
++ NULL, 0, NULL,
+ AA_MAY_UMOUNT, &perms, info, error);
+ }
+
+-int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
++int aa_umount(const struct cred *subj_cred, struct aa_label *label,
++ struct vfsmount *mnt, int flags)
+ {
+ struct aa_profile *profile;
+ char *buffer = NULL;
+@@ -615,7 +635,7 @@ int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
+ return -ENOMEM;
+
+ error = fn_for_each_confined(label, profile,
+- profile_umount(profile, &path, buffer));
++ profile_umount(subj_cred, profile, &path, buffer));
+ aa_put_buffer(buffer);
+
+ return error;
+@@ -625,7 +645,8 @@ int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags)
+ *
+ * Returns: label for transition or ERR_PTR. Does not return NULL
+ */
+-static struct aa_label *build_pivotroot(struct aa_profile *profile,
++static struct aa_label *build_pivotroot(const struct cred *subj_cred,
++ struct aa_profile *profile,
+ const struct path *new_path,
+ char *new_buffer,
+ const struct path *old_path,
+@@ -670,7 +691,8 @@ static struct aa_label *build_pivotroot(struct aa_profile *profile,
+ error = 0;
+
+ audit:
+- error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name,
++ error = audit_mount(subj_cred, profile, OP_PIVOTROOT, new_name,
++ old_name,
+ NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT,
+ &perms, info, error);
+ if (error)
+@@ -679,7 +701,8 @@ static struct aa_label *build_pivotroot(struct aa_profile *profile,
+ return aa_get_newest_label(&profile->label);
+ }
+
+-int aa_pivotroot(struct aa_label *label, const struct path *old_path,
++int aa_pivotroot(const struct cred *subj_cred, struct aa_label *label,
++ const struct path *old_path,
+ const struct path *new_path)
+ {
+ struct aa_profile *profile;
+@@ -697,7 +720,8 @@ int aa_pivotroot(struct aa_label *label, const struct path *old_path,
+ if (!old_buffer || !new_buffer)
+ goto out;
+ target = fn_label_build(label, profile, GFP_KERNEL,
+- build_pivotroot(profile, new_path, new_buffer,
++ build_pivotroot(subj_cred, profile, new_path,
++ new_buffer,
+ old_path, old_buffer));
+ if (!target) {
+ info = "label build failed";
+@@ -723,7 +747,8 @@ int aa_pivotroot(struct aa_label *label, const struct path *old_path,
+ fail:
+ /* TODO: add back in auditing of new_name and old_name */
+ error = fn_for_each(label, profile,
+- audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */,
++ audit_mount(subj_cred, profile, OP_PIVOTROOT,
++ NULL /*new_name */,
+ NULL /* old_name */,
+ NULL, NULL,
+ 0, NULL, AA_MAY_PIVOTROOT, &nullperms, info,
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 5e50f80e35db0..704c171232ab4 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -135,8 +135,8 @@ int aa_profile_af_perm(struct aa_profile *profile,
+ return aa_check_perms(profile, &perms, request, ad, audit_net_cb);
+ }
+
+-int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
+- int type, int protocol)
++int aa_af_perm(const struct cred *subj_cred, struct aa_label *label,
++ const char *op, u32 request, u16 family, int type, int protocol)
+ {
+ struct aa_profile *profile;
+ DEFINE_AUDIT_NET(ad, op, NULL, family, type, protocol);
+@@ -146,7 +146,9 @@ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family,
+ type));
+ }
+
+-static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
++static int aa_label_sk_perm(const struct cred *subj_cred,
++ struct aa_label *label,
++ const char *op, u32 request,
+ struct sock *sk)
+ {
+ struct aa_sk_ctx *ctx = SK_CTX(sk);
+@@ -159,6 +161,7 @@ static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request,
+ struct aa_profile *profile;
+ DEFINE_AUDIT_SK(ad, op, sk);
+
++ ad.subj_cred = subj_cred;
+ error = fn_for_each_confined(label, profile,
+ aa_profile_af_sk_perm(profile, &ad, request, sk));
+ }
+@@ -176,21 +179,21 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk)
+
+ /* TODO: switch to begin_current_label ???? */
+ label = begin_current_label_crit_section();
+- error = aa_label_sk_perm(label, op, request, sk);
++ error = aa_label_sk_perm(current_cred(), label, op, request, sk);
+ end_current_label_crit_section(label);
+
+ return error;
+ }
+
+
+-int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
+- struct socket *sock)
++int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label,
++ const char *op, u32 request, struct socket *sock)
+ {
+ AA_BUG(!label);
+ AA_BUG(!sock);
+ AA_BUG(!sock->sk);
+
+- return aa_label_sk_perm(label, op, request, sock->sk);
++ return aa_label_sk_perm(subj_cred, label, op, request, sock->sk);
+ }
+
+ #ifdef CONFIG_NETWORK_SECMARK
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index e5f1ef83b0fda..8a07793ce1032 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -762,21 +762,23 @@ static int audit_policy(struct aa_label *subj_label, const char *op,
+ /* don't call out to other LSMs in the stack for apparmor policy admin
+ * permissions
+ */
+-static int policy_ns_capable(struct aa_label *label,
++static int policy_ns_capable(const struct cred *subj_cred,
++ struct aa_label *label,
+ struct user_namespace *userns, int cap)
+ {
+ int err;
+
+ /* check for MAC_ADMIN cap in cred */
+- err = cap_capable(current_cred(), userns, cap, CAP_OPT_NONE);
++ err = cap_capable(subj_cred, userns, cap, CAP_OPT_NONE);
+ if (!err)
+- err = aa_capable(label, cap, CAP_OPT_NONE);
++ err = aa_capable(subj_cred, label, cap, CAP_OPT_NONE);
+
+ return err;
+ }
+
+ /**
+ * aa_policy_view_capable - check if viewing policy in at @ns is allowed
++ * @subj_cred: cred of subject
+ * @label: label that is trying to view policy in ns
+ * @ns: namespace being viewed by @label (may be NULL if @label's ns)
+ *
+@@ -785,9 +787,10 @@ static int policy_ns_capable(struct aa_label *label,
+ * If @ns is NULL then the namespace being viewed is assumed to be the
+ * tasks current namespace.
+ */
+-bool aa_policy_view_capable(struct aa_label *label, struct aa_ns *ns)
++bool aa_policy_view_capable(const struct cred *subj_cred,
++ struct aa_label *label, struct aa_ns *ns)
+ {
+- struct user_namespace *user_ns = current_user_ns();
++ struct user_namespace *user_ns = subj_cred->user_ns;
+ struct aa_ns *view_ns = labels_view(label);
+ bool root_in_user_ns = uid_eq(current_euid(), make_kuid(user_ns, 0)) ||
+ in_egroup_p(make_kgid(user_ns, 0));
+@@ -804,15 +807,17 @@ bool aa_policy_view_capable(struct aa_label *label, struct aa_ns *ns)
+ return response;
+ }
+
+-bool aa_policy_admin_capable(struct aa_label *label, struct aa_ns *ns)
++bool aa_policy_admin_capable(const struct cred *subj_cred,
++ struct aa_label *label, struct aa_ns *ns)
+ {
+- struct user_namespace *user_ns = current_user_ns();
+- bool capable = policy_ns_capable(label, user_ns, CAP_MAC_ADMIN) == 0;
++ struct user_namespace *user_ns = subj_cred->user_ns;
++ bool capable = policy_ns_capable(subj_cred, label, user_ns,
++ CAP_MAC_ADMIN) == 0;
+
+ AA_DEBUG("cap_mac_admin? %d\n", capable);
+ AA_DEBUG("policy locked? %d\n", aa_g_lock_policy);
+
+- return aa_policy_view_capable(label, ns) && capable &&
++ return aa_policy_view_capable(subj_cred, label, ns) && capable &&
+ !aa_g_lock_policy;
+ }
+
+@@ -822,7 +827,7 @@ bool aa_current_policy_view_capable(struct aa_ns *ns)
+ bool res;
+
+ label = __begin_current_label_crit_section();
+- res = aa_policy_view_capable(label, ns);
++ res = aa_policy_view_capable(current_cred(), label, ns);
+ __end_current_label_crit_section(label);
+
+ return res;
+@@ -834,7 +839,7 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns)
+ bool res;
+
+ label = __begin_current_label_crit_section();
+- res = aa_policy_admin_capable(label, ns);
++ res = aa_policy_admin_capable(current_cred(), label, ns);
+ __end_current_label_crit_section(label);
+
+ return res;
+@@ -842,13 +847,15 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns)
+
+ /**
+ * aa_may_manage_policy - can the current task manage policy
++ * @subj_cred; subjects cred
+ * @label: label to check if it can manage policy
+ * @ns: namespace being managed by @label (may be NULL if @label's ns)
+ * @mask: contains the policy manipulation operation being done
+ *
+ * Returns: 0 if the task is allowed to manipulate policy else error
+ */
+-int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask)
++int aa_may_manage_policy(const struct cred *subj_cred, struct aa_label *label,
++ struct aa_ns *ns, u32 mask)
+ {
+ const char *op;
+
+@@ -864,7 +871,7 @@ int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask)
+ return audit_policy(label, op, NULL, NULL, "policy_locked",
+ -EACCES);
+
+- if (!aa_policy_admin_capable(label, ns))
++ if (!aa_policy_admin_capable(subj_cred, label, ns))
+ return audit_policy(label, op, NULL, NULL, "not policy admin",
+ -EACCES);
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index 73ba26c646a5e..dcc94c3153d51 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -43,6 +43,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+
+ /**
+ * audit_resource - audit setting resource limit
++ * @subj_cred: cred setting the resource
+ * @profile: profile being enforced (NOT NULL)
+ * @resource: rlimit being auditing
+ * @value: value being set
+@@ -52,13 +53,15 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+ *
+ * Returns: 0 or ad->error else other error code on failure
+ */
+-static int audit_resource(struct aa_profile *profile, unsigned int resource,
++static int audit_resource(const struct cred *subj_cred,
++ struct aa_profile *profile, unsigned int resource,
+ unsigned long value, struct aa_label *peer,
+ const char *info, int error)
+ {
+ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_RLIMITS,
+ OP_SETRLIMIT);
+
++ ad.subj_cred = subj_cred;
+ ad.rlim.rlim = resource;
+ ad.rlim.max = value;
+ ad.peer = peer;
+@@ -82,7 +85,8 @@ int aa_map_resource(int resource)
+ return rlim_map[resource];
+ }
+
+-static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
++static int profile_setrlimit(const struct cred *subj_cred,
++ struct aa_profile *profile, unsigned int resource,
+ struct rlimit *new_rlim)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+@@ -92,12 +96,13 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
+ if (rules->rlimits.mask & (1 << resource) && new_rlim->rlim_max >
+ rules->rlimits.limits[resource].rlim_max)
+ e = -EACCES;
+- return audit_resource(profile, resource, new_rlim->rlim_max, NULL, NULL,
+- e);
++ return audit_resource(subj_cred, profile, resource, new_rlim->rlim_max,
++ NULL, NULL, e);
+ }
+
+ /**
+ * aa_task_setrlimit - test permission to set an rlimit
++ * @subj_cred: cred setting the limit
+ * @label: label confining the task (NOT NULL)
+ * @task: task the resource is being set on
+ * @resource: the resource being set
+@@ -107,7 +112,8 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource,
+ *
+ * Returns: 0 or error code if setting resource failed
+ */
+-int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
++int aa_task_setrlimit(const struct cred *subj_cred, struct aa_label *label,
++ struct task_struct *task,
+ unsigned int resource, struct rlimit *new_rlim)
+ {
+ struct aa_profile *profile;
+@@ -126,14 +132,15 @@ int aa_task_setrlimit(struct aa_label *label, struct task_struct *task,
+ */
+
+ if (label != peer &&
+- aa_capable(label, CAP_SYS_RESOURCE, CAP_OPT_NOAUDIT) != 0)
++ aa_capable(subj_cred, label, CAP_SYS_RESOURCE, CAP_OPT_NOAUDIT) != 0)
+ error = fn_for_each(label, profile,
+- audit_resource(profile, resource,
++ audit_resource(subj_cred, profile, resource,
+ new_rlim->rlim_max, peer,
+ "cap_sys_resource", -EACCES));
+ else
+ error = fn_for_each_confined(label, profile,
+- profile_setrlimit(profile, resource, new_rlim));
++ profile_setrlimit(subj_cred, profile, resource,
++ new_rlim));
+ aa_put_label(peer);
+
+ return error;
+diff --git a/security/apparmor/task.c b/security/apparmor/task.c
+index 79850e8321420..0d7af707cccdd 100644
+--- a/security/apparmor/task.c
++++ b/security/apparmor/task.c
+@@ -226,14 +226,16 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
+
+ /* assumes check for RULE_MEDIATES is already done */
+ /* TODO: conditionals */
+-static int profile_ptrace_perm(struct aa_profile *profile,
+- struct aa_label *peer, u32 request,
+- struct apparmor_audit_data *ad)
++static int profile_ptrace_perm(const struct cred *cred,
++ struct aa_profile *profile,
++ struct aa_label *peer, u32 request,
++ struct apparmor_audit_data *ad)
+ {
+ struct aa_ruleset *rules = list_first_entry(&profile->rules,
+ typeof(*rules), list);
+ struct aa_perms perms = { };
+
++ ad->subj_cred = cred;
+ ad->peer = peer;
+ aa_profile_match_label(profile, rules, peer, AA_CLASS_PTRACE, request,
+ &perms);
+@@ -241,7 +243,8 @@ static int profile_ptrace_perm(struct aa_profile *profile,
+ return aa_check_perms(profile, &perms, request, ad, audit_ptrace_cb);
+ }
+
+-static int profile_tracee_perm(struct aa_profile *tracee,
++static int profile_tracee_perm(const struct cred *cred,
++ struct aa_profile *tracee,
+ struct aa_label *tracer, u32 request,
+ struct apparmor_audit_data *ad)
+ {
+@@ -249,10 +252,11 @@ static int profile_tracee_perm(struct aa_profile *tracee,
+ !ANY_RULE_MEDIATES(&tracee->rules, AA_CLASS_PTRACE))
+ return 0;
+
+- return profile_ptrace_perm(tracee, tracer, request, ad);
++ return profile_ptrace_perm(cred, tracee, tracer, request, ad);
+ }
+
+-static int profile_tracer_perm(struct aa_profile *tracer,
++static int profile_tracer_perm(const struct cred *cred,
++ struct aa_profile *tracer,
+ struct aa_label *tracee, u32 request,
+ struct apparmor_audit_data *ad)
+ {
+@@ -260,7 +264,7 @@ static int profile_tracer_perm(struct aa_profile *tracer,
+ return 0;
+
+ if (ANY_RULE_MEDIATES(&tracer->rules, AA_CLASS_PTRACE))
+- return profile_ptrace_perm(tracer, tracee, request, ad);
++ return profile_ptrace_perm(cred, tracer, tracee, request, ad);
+
+ /* profile uses the old style capability check for ptrace */
+ if (&tracer->label == tracee)
+@@ -269,8 +273,8 @@ static int profile_tracer_perm(struct aa_profile *tracer,
+ ad->subj_label = &tracer->label;
+ ad->peer = tracee;
+ ad->request = 0;
+- ad->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
+- CAP_OPT_NONE);
++ ad->error = aa_capable(cred, &tracer->label, CAP_SYS_PTRACE,
++ CAP_OPT_NONE);
+
+ return aa_audit(AUDIT_APPARMOR_AUTO, tracer, ad, audit_ptrace_cb);
+ }
+@@ -283,7 +287,8 @@ static int profile_tracer_perm(struct aa_profile *tracer,
+ *
+ * Returns: %0 else error code if permission denied or error
+ */
+-int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
++int aa_may_ptrace(const struct cred *tracer_cred, struct aa_label *tracer,
++ const struct cred *tracee_cred, struct aa_label *tracee,
+ u32 request)
+ {
+ struct aa_profile *profile;
+@@ -291,6 +296,8 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
+ DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_PTRACE, OP_PTRACE);
+
+ return xcheck_labels(tracer, tracee, profile,
+- profile_tracer_perm(profile, tracee, request, &sa),
+- profile_tracee_perm(profile, tracer, xrequest, &sa));
++ profile_tracer_perm(tracer_cred, profile, tracee,
++ request, &sa),
++ profile_tracee_perm(tracee_cred, profile, tracer,
++ xrequest, &sa));
+ }
+--
+2.42.0
+
--- /dev/null
+From 1df12c1710f6af2f580f6cffecd20d981358a372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Sep 2022 00:46:09 -0700
+Subject: apparmor: rename audit_data->label to audit_data->subj_label
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit d20f5a1a6e792d22199c9989ec7ab9e95c48d60c ]
+
+rename audit_data's label field to subj_label to better reflect its
+use. Also at the same time drop unneeded assignments to ->subj_label
+as the later call to aa_check_perms will do the assignment if needed.
+
+Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/audit.c | 6 +++---
+ security/apparmor/file.c | 2 +-
+ security/apparmor/include/audit.h | 2 +-
+ security/apparmor/ipc.c | 2 +-
+ security/apparmor/lib.c | 5 ++---
+ security/apparmor/lsm.c | 4 ++--
+ security/apparmor/net.c | 2 +-
+ security/apparmor/policy.c | 6 +++---
+ security/apparmor/resource.c | 2 +-
+ security/apparmor/task.c | 4 ++--
+ 10 files changed, 17 insertions(+), 18 deletions(-)
+
+diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c
+index 06ad6a8fcce18..6933cb2f679b0 100644
+--- a/security/apparmor/audit.c
++++ b/security/apparmor/audit.c
+@@ -113,8 +113,8 @@ static void audit_pre(struct audit_buffer *ab, void *va)
+ audit_log_format(ab, " error=%d", ad->error);
+ }
+
+- if (ad->label) {
+- struct aa_label *label = ad->label;
++ if (ad->subj_label) {
++ struct aa_label *label = ad->subj_label;
+
+ if (label_isprofile(label)) {
+ struct aa_profile *profile = labels_profile(label);
+@@ -187,7 +187,7 @@ int aa_audit(int type, struct aa_profile *profile,
+ if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED)
+ type = AUDIT_APPARMOR_KILL;
+
+- ad->label = &profile->label;
++ ad->subj_label = &profile->label;
+
+ aa_audit_msg(type, ad, cb);
+
+diff --git a/security/apparmor/file.c b/security/apparmor/file.c
+index 9ea95fa18e7d5..5bfa70a972071 100644
+--- a/security/apparmor/file.c
++++ b/security/apparmor/file.c
+@@ -67,7 +67,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
+
+ if (ad->peer) {
+ audit_log_format(ab, " target=");
+- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer,
+ FLAG_VIEW_SUBNS, GFP_KERNEL);
+ } else if (ad->fs.target) {
+ audit_log_format(ab, " target=");
+diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
+index 85931ec94e916..096f0a04af87f 100644
+--- a/security/apparmor/include/audit.h
++++ b/security/apparmor/include/audit.h
+@@ -109,7 +109,7 @@ struct apparmor_audit_data {
+ int type;
+ u16 class;
+ const char *op;
+- struct aa_label *label;
++ struct aa_label *subj_label;
+ const char *name;
+ const char *info;
+ u32 request;
+diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
+index f198b8d620a4f..fd8306399b820 100644
+--- a/security/apparmor/ipc.c
++++ b/security/apparmor/ipc.c
+@@ -71,7 +71,7 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va)
+ audit_log_format(ab, " signal=rtmin+%d",
+ ad->signal - SIGRT_BASE);
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+
+diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
+index d6b2750fd72e4..c87bccafff446 100644
+--- a/security/apparmor/lib.c
++++ b/security/apparmor/lib.c
+@@ -297,7 +297,7 @@ static void aa_audit_perms_cb(struct audit_buffer *ab, void *va)
+ PERMS_NAMES_MASK);
+ }
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+
+@@ -357,7 +357,6 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target,
+ typeof(*rules), list);
+ struct aa_perms perms;
+
+- ad->label = &profile->label;
+ ad->peer = &target->label;
+ ad->request = request;
+
+@@ -419,7 +418,7 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+ }
+
+ if (ad) {
+- ad->label = &profile->label;
++ ad->subj_label = &profile->label;
+ ad->request = request;
+ ad->denied = denied;
+ ad->error = error;
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index fd7852a4737c7..359fbfbb4a66e 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -722,11 +722,11 @@ static int apparmor_setprocattr(const char *name, void *value,
+ return error;
+
+ fail:
+- ad.label = begin_current_label_crit_section();
++ ad.subj_label = begin_current_label_crit_section();
+ ad.info = name;
+ ad.error = error = -EINVAL;
+ aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL);
+- end_current_label_crit_section(ad.label);
++ end_current_label_crit_section(ad.subj_label);
+ goto out;
+ }
+
+diff --git a/security/apparmor/net.c b/security/apparmor/net.c
+index 0c7304cd479c5..5e50f80e35db0 100644
+--- a/security/apparmor/net.c
++++ b/security/apparmor/net.c
+@@ -100,7 +100,7 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
+ }
+ if (ad->peer) {
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+ }
+diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
+index 9a7dbe64f102b..e5f1ef83b0fda 100644
+--- a/security/apparmor/policy.c
++++ b/security/apparmor/policy.c
+@@ -733,7 +733,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+
+ /**
+ * audit_policy - Do auditing of policy changes
+- * @label: label to check if it can manage policy
++ * @subj_label: label to check if it can manage policy
+ * @op: policy operation being performed
+ * @ns_name: name of namespace being manipulated
+ * @name: name of profile being manipulated (NOT NULL)
+@@ -742,7 +742,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+ *
+ * Returns: the error to be returned after audit is done
+ */
+-static int audit_policy(struct aa_label *label, const char *op,
++static int audit_policy(struct aa_label *subj_label, const char *op,
+ const char *ns_name, const char *name,
+ const char *info, int error)
+ {
+@@ -752,7 +752,7 @@ static int audit_policy(struct aa_label *label, const char *op,
+ ad.name = name;
+ ad.info = info;
+ ad.error = error;
+- ad.label = label;
++ ad.subj_label = subj_label;
+
+ aa_audit_msg(AUDIT_APPARMOR_STATUS, &ad, audit_cb);
+
+diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c
+index b6b5e1bfe9a26..73ba26c646a5e 100644
+--- a/security/apparmor/resource.c
++++ b/security/apparmor/resource.c
+@@ -36,7 +36,7 @@ static void audit_cb(struct audit_buffer *ab, void *va)
+ rlim_names[ad->rlim.rlim], ad->rlim.max);
+ if (ad->peer) {
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+ }
+diff --git a/security/apparmor/task.c b/security/apparmor/task.c
+index 8bd1f212215c4..79850e8321420 100644
+--- a/security/apparmor/task.c
++++ b/security/apparmor/task.c
+@@ -220,7 +220,7 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va)
+ }
+ }
+ audit_log_format(ab, " peer=");
+- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer,
++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer,
+ FLAGS_NONE, GFP_ATOMIC);
+ }
+
+@@ -266,7 +266,7 @@ static int profile_tracer_perm(struct aa_profile *tracer,
+ if (&tracer->label == tracee)
+ return 0;
+
+- ad->label = &tracer->label;
++ ad->subj_label = &tracer->label;
+ ad->peer = tracee;
+ ad->request = 0;
+ ad->error = aa_capable(&tracer->label, CAP_SYS_PTRACE,
+--
+2.42.0
+
--- /dev/null
+From c093b26521e8af0928c5d725c505409e1920066d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 19:21:17 +0800
+Subject: Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE
+
+From: Guan Wentao <guanwentao@uniontech.com>
+
+[ Upstream commit da06ff1f585ea784c79f80e7fab0e0c4ebb49c1c ]
+
+Add PID/VID 0bda:b85b for Realtek RTL8852BE USB bluetooth part.
+The PID/VID was reported by the patch last year. [1]
+Some SBCs like rockpi 5B A8 module contains the device.
+And it`s founded in website. [2] [3]
+
+Here is the device tables in /sys/kernel/debug/usb/devices .
+
+T: Bus=07 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=0bda ProdID=b85b Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Link: https://lore.kernel.org/all/20220420052402.19049-1-tangmeng@uniontech.com/ [1]
+Link: https://forum.radxa.com/t/bluetooth-on-ubuntu/13051/4 [2]
+Link: https://ubuntuforums.org/showthread.php?t=2489527 [3]
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Meng Tang <tangmeng@uniontech.com>
+Signed-off-by: Guan Wentao <guanwentao@uniontech.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index e3f11ea2a9fcd..66080fae072f2 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -543,6 +543,8 @@ static const struct usb_device_id quirks_table[] = {
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
++ { USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
+--
+2.42.0
+
--- /dev/null
+From 83cbff78bef8ab61bad6f1513462e5338b832b14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Sep 2023 16:46:55 +0530
+Subject: Bluetooth: btusb: Add RTW8852BE device 13d3:3570 to device tables
+
+From: Masum Reza <masumrezarock100@gmail.com>
+
+[ Upstream commit 02be109d3a405dbc4d53fb4b4473d7a113548088 ]
+
+This device is used in TP-Link TX20E WiFi+Bluetooth adapter.
+
+Relevant information in /sys/kernel/debug/usb/devices
+about the Bluetooth device is listed as the below.
+
+T: Bus=01 Lev=01 Prnt=01 Port=08 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
+D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
+P: Vendor=13d3 ProdID=3570 Rev= 0.00
+S: Manufacturer=Realtek
+S: Product=Bluetooth Radio
+S: SerialNumber=00e04c000001
+C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA
+I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
+E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
+I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
+I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
+I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
+I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
+I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
+I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
+E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
+
+Signed-off-by: Masum Reza <masumrezarock100@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bluetooth/btusb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 63ebd5677d267..e3f11ea2a9fcd 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -543,6 +543,8 @@ static const struct usb_device_id quirks_table[] = {
+ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
++ { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK |
++ BTUSB_WIDEBAND_SPEECH },
+ { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK |
+ BTUSB_WIDEBAND_SPEECH },
+
+--
+2.42.0
+
--- /dev/null
+From 1fb8159e9c2490c44b8cf3061ec4b7598ed0cb7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 20:13:23 -0700
+Subject: cxl/port: Fix delete_endpoint() vs parent unregistration race
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 8d2ad999ca3c64cb08cf6a58d227b9d9e746d708 ]
+
+The CXL subsystem, at cxl_mem ->probe() time, establishes a lineage of
+ports (struct cxl_port objects) between an endpoint and the root of a
+CXL topology. Each port including the endpoint port is attached to the
+cxl_port driver.
+
+Given that setup, it follows that when either any port in that lineage
+goes through a cxl_port ->remove() event, or the memdev goes through a
+cxl_mem ->remove() event. The hierarchy below the removed port, or the
+entire hierarchy if the memdev is removed needs to come down.
+
+The delete_endpoint() callback is careful to check whether it is being
+called to tear down the hierarchy, or if it is only being called to
+teardown the memdev because an ancestor port is going through
+->remove().
+
+That care needs to take the device_lock() of the endpoint's parent.
+Which requires 2 bugs to be fixed:
+
+1/ A reference on the parent is needed to prevent use-after-free
+ scenarios like this signature:
+
+ BUG: spinlock bad magic on CPU#0, kworker/u56:0/11
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20230524-3.fc38 05/24/2023
+ Workqueue: cxl_port detach_memdev [cxl_core]
+ RIP: 0010:spin_bug+0x65/0xa0
+ Call Trace:
+ do_raw_spin_lock+0x69/0xa0
+ __mutex_lock+0x695/0xb80
+ delete_endpoint+0xad/0x150 [cxl_core]
+ devres_release_all+0xb8/0x110
+ device_unbind_cleanup+0xe/0x70
+ device_release_driver_internal+0x1d2/0x210
+ detach_memdev+0x15/0x20 [cxl_core]
+ process_one_work+0x1e3/0x4c0
+ worker_thread+0x1dd/0x3d0
+
+2/ In the case of RCH topologies, the parent device that needs to be
+ locked is not always @port->dev as returned by cxl_mem_find_port(), use
+ endpoint->dev.parent instead.
+
+Fixes: 8dd2bc0f8e02 ("cxl/mem: Add the cxl_mem driver")
+Cc: <stable@vger.kernel.org>
+Reported-by: Robert Richter <rrichter@amd.com>
+Closes: http://lore.kernel.org/r/20231018171713.1883517-2-rrichter@amd.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/port.c | 34 +++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
+index 2c6001592fe20..6a75a3cb601ec 100644
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -1242,35 +1242,39 @@ static struct device *grandparent(struct device *dev)
+ return NULL;
+ }
+
++static struct device *endpoint_host(struct cxl_port *endpoint)
++{
++ struct cxl_port *port = to_cxl_port(endpoint->dev.parent);
++
++ if (is_cxl_root(port))
++ return port->uport_dev;
++ return &port->dev;
++}
++
+ static void delete_endpoint(void *data)
+ {
+ struct cxl_memdev *cxlmd = data;
+ struct cxl_port *endpoint = cxlmd->endpoint;
+- struct cxl_port *parent_port;
+- struct device *parent;
+-
+- parent_port = cxl_mem_find_port(cxlmd, NULL);
+- if (!parent_port)
+- goto out;
+- parent = &parent_port->dev;
++ struct device *host = endpoint_host(endpoint);
+
+- device_lock(parent);
+- if (parent->driver && !endpoint->dead) {
+- devm_release_action(parent, cxl_unlink_parent_dport, endpoint);
+- devm_release_action(parent, cxl_unlink_uport, endpoint);
+- devm_release_action(parent, unregister_port, endpoint);
++ device_lock(host);
++ if (host->driver && !endpoint->dead) {
++ devm_release_action(host, cxl_unlink_parent_dport, endpoint);
++ devm_release_action(host, cxl_unlink_uport, endpoint);
++ devm_release_action(host, unregister_port, endpoint);
+ }
+ cxlmd->endpoint = NULL;
+- device_unlock(parent);
+- put_device(parent);
+-out:
++ device_unlock(host);
+ put_device(&endpoint->dev);
++ put_device(host);
+ }
+
+ int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint)
+ {
++ struct device *host = endpoint_host(endpoint);
+ struct device *dev = &cxlmd->dev;
+
++ get_device(host);
+ get_device(&endpoint->dev);
+ cxlmd->endpoint = endpoint;
+ cxlmd->depth = endpoint->depth;
+--
+2.42.0
+
--- /dev/null
+From 81d1fc2e5b8aa62e8d1ca5524b89b8e25127f2dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 10:09:06 -0700
+Subject: cxl/region: Fix x1 root-decoder granularity calculations
+
+From: Jim Harris <jim.harris@samsung.com>
+
+[ Upstream commit 98a04c7aced2b43b3ac4befe216c4eecc7257d4b ]
+
+Root decoder granularity must match value from CFWMS, which may not
+be the region's granularity for non-interleaved root decoders.
+
+So when calculating granularities for host bridge decoders, use the
+region's granularity instead of the root decoder's granularity to ensure
+the correct granularities are set for the host bridge decoders and any
+downstream switch decoders.
+
+Test configuration is 1 host bridge * 2 switches * 2 endpoints per switch.
+
+Region created with 2048 granularity using following command line:
+
+cxl create-region -m -d decoder0.0 -w 4 mem0 mem2 mem1 mem3 \
+ -g 2048 -s 2048M
+
+Use "cxl list -PDE | grep granularity" to get a view of the granularity
+set at each level of the topology.
+
+Before this patch:
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":512,
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":512,
+"interleave_granularity":256,
+
+After:
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":4096,
+ "interleave_granularity":2048,
+ "interleave_granularity":2048,
+ "interleave_granularity":4096,
+"interleave_granularity":2048,
+
+Fixes: 27b3f8d13830 ("cxl/region: Program target lists")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Jim Harris <jim.harris@samsung.com>
+Link: https://lore.kernel.org/r/169824893473.1403938.16110924262989774582.stgit@bgt-140510-bm03.eng.stellus.in
+[djbw: fixup the prebuilt cxl_test region]
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 9 ++++++++-
+ tools/testing/cxl/test/cxl.c | 2 +-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index 359af06233021..9d60020c5cb3b 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -1127,7 +1127,14 @@ static int cxl_port_setup_targets(struct cxl_port *port,
+ }
+
+ if (is_cxl_root(parent_port)) {
+- parent_ig = cxlrd->cxlsd.cxld.interleave_granularity;
++ /*
++ * Root decoder IG is always set to value in CFMWS which
++ * may be different than this region's IG. We can use the
++ * region's IG here since interleave_granularity_store()
++ * does not allow interleaved host-bridges with
++ * root IG != region IG.
++ */
++ parent_ig = p->interleave_granularity;
+ parent_iw = cxlrd->cxlsd.cxld.interleave_ways;
+ /*
+ * For purposes of address bit routing, use power-of-2 math for
+diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
+index fb6ab9cef84f7..b885462999022 100644
+--- a/tools/testing/cxl/test/cxl.c
++++ b/tools/testing/cxl/test/cxl.c
+@@ -831,7 +831,7 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld)
+ cxld->interleave_ways = 2;
+ else
+ cxld->interleave_ways = 1;
+- cxld->interleave_granularity = 256;
++ cxld->interleave_granularity = 4096;
+ cxld->hpa_range = (struct range) {
+ .start = base,
+ .end = base + size - 1,
+--
+2.42.0
+
--- /dev/null
+From fb508286dd45a6c20533ea1da620dc625fca6b47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Sep 2023 16:52:54 -0400
+Subject: drm/amd/display: enable dsc_clk even if dsc_pg disabled
+
+From: Muhammad Ahmed <ahmed.ahmed@amd.com>
+
+[ Upstream commit 40255df370e94d44f0f0a924400d68db0ee31bec ]
+
+[why]
+need to enable dsc_clk regardless dsc_pg
+
+Reviewed-by: Charlene Liu <charlene.liu@amd.com>
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Muhammad Ahmed <ahmed.ahmed@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 8 ++++----
+ drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 3 +++
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index 38abbd0c9d997..186936ad283a5 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -1843,7 +1843,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
+ if (dc->hwss.subvp_pipe_control_lock)
+ dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use);
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, false);
+
+ disable_dangling_plane(dc, context);
+@@ -1950,7 +1950,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
+ dc->hwss.optimize_bandwidth(dc, context);
+ }
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, true);
+
+ if (dc->ctx->dce_version >= DCE_VERSION_MAX)
+@@ -2197,7 +2197,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc)
+
+ dc->hwss.optimize_bandwidth(dc, context);
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, true);
+ }
+
+@@ -3533,7 +3533,7 @@ static void commit_planes_for_stream(struct dc *dc,
+ if (get_seamless_boot_stream_count(context) == 0)
+ dc->hwss.prepare_bandwidth(dc, context);
+
+- if (dc->debug.enable_double_buffered_dsc_pg_support)
++ if (dc->hwss.update_dsc_pg)
+ dc->hwss.update_dsc_pg(dc, context, false);
+
+ context_clock_trace(dc, context);
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+index be59e1c02f8aa..c9140b50c3454 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
+@@ -77,6 +77,9 @@ void dcn32_dsc_pg_control(
+ if (hws->ctx->dc->debug.disable_dsc_power_gate)
+ return;
+
++ if (!hws->ctx->dc->debug.enable_double_buffered_dsc_pg_support)
++ return;
++
+ REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);
+ if (org_ip_request_cntl == 0)
+ REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);
+--
+2.42.0
+
--- /dev/null
+From 6b13da968c234929a21e3dc1e7120e617481ad86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Jul 2023 14:27:31 +0000
+Subject: rcutorture: Fix stuttering races and other issues
+
+From: Joel Fernandes (Google) <joel@joelfernandes.org>
+
+[ Upstream commit cca42bd8eb1b54a4c9bbf48c79d120e66619a3e4 ]
+
+The stuttering code isn't functioning as expected. Ideally, it should
+pause the torture threads for a designated period before resuming. Yet,
+it fails to halt the test for the correct duration. Additionally, a race
+condition exists, potentially causing the stuttering code to pause for
+an extended period if the 'spt' variable is non-zero due to the stutter
+orchestration thread's inadequate CPU time.
+
+Moreover, over-stuttering can hinder RCU's progress on TREE07 kernels.
+This happens as the stuttering code may run within a softirq due to RCU
+callbacks. Consequently, ksoftirqd keeps a CPU busy for several seconds,
+thus obstructing RCU's progress. This situation triggers a warning
+message in the logs:
+
+[ 2169.481783] rcu_torture_writer: rtort_pipe_count: 9
+
+This warning suggests that an RCU torture object, although invisible to
+RCU readers, couldn't make it past the pipe array and be freed -- a
+strong indication that there weren't enough grace periods during the
+stutter interval.
+
+To address these issues, this patch sets the "stutter end" time to an
+absolute point in the future set by the main stutter thread. This is
+then used for waiting in stutter_wait(). While the stutter thread still
+defines this absolute time, the waiters' waiting logic doesn't rely on
+the stutter thread receiving sufficient CPU time to halt the stuttering
+as the halting is now self-controlled.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/torture.c | 45 ++++++++++++---------------------------------
+ 1 file changed, 12 insertions(+), 33 deletions(-)
+
+diff --git a/kernel/torture.c b/kernel/torture.c
+index e851b8e9390b3..c7b475883b9a8 100644
+--- a/kernel/torture.c
++++ b/kernel/torture.c
+@@ -721,7 +721,7 @@ static void torture_shutdown_cleanup(void)
+ * suddenly applied to or removed from the system.
+ */
+ static struct task_struct *stutter_task;
+-static int stutter_pause_test;
++static ktime_t stutter_till_abs_time;
+ static int stutter;
+ static int stutter_gap;
+
+@@ -731,30 +731,16 @@ static int stutter_gap;
+ */
+ bool stutter_wait(const char *title)
+ {
+- unsigned int i = 0;
+ bool ret = false;
+- int spt;
++ ktime_t till_ns;
+
+ cond_resched_tasks_rcu_qs();
+- spt = READ_ONCE(stutter_pause_test);
+- for (; spt; spt = READ_ONCE(stutter_pause_test)) {
+- if (!ret && !rt_task(current)) {
+- sched_set_normal(current, MAX_NICE);
+- ret = true;
+- }
+- if (spt == 1) {
+- torture_hrtimeout_jiffies(1, NULL);
+- } else if (spt == 2) {
+- while (READ_ONCE(stutter_pause_test)) {
+- if (!(i++ & 0xffff))
+- torture_hrtimeout_us(10, 0, NULL);
+- cond_resched();
+- }
+- } else {
+- torture_hrtimeout_jiffies(round_jiffies_relative(HZ), NULL);
+- }
+- torture_shutdown_absorb(title);
++ till_ns = READ_ONCE(stutter_till_abs_time);
++ if (till_ns && ktime_before(ktime_get(), till_ns)) {
++ torture_hrtimeout_ns(till_ns, 0, HRTIMER_MODE_ABS, NULL);
++ ret = true;
+ }
++ torture_shutdown_absorb(title);
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(stutter_wait);
+@@ -765,23 +751,16 @@ EXPORT_SYMBOL_GPL(stutter_wait);
+ */
+ static int torture_stutter(void *arg)
+ {
+- DEFINE_TORTURE_RANDOM(rand);
+- int wtime;
++ ktime_t till_ns;
+
+ VERBOSE_TOROUT_STRING("torture_stutter task started");
+ do {
+ if (!torture_must_stop() && stutter > 1) {
+- wtime = stutter;
+- if (stutter > 2) {
+- WRITE_ONCE(stutter_pause_test, 1);
+- wtime = stutter - 3;
+- torture_hrtimeout_jiffies(wtime, &rand);
+- wtime = 2;
+- }
+- WRITE_ONCE(stutter_pause_test, 2);
+- torture_hrtimeout_jiffies(wtime, NULL);
++ till_ns = ktime_add_ns(ktime_get(),
++ jiffies_to_nsecs(stutter));
++ WRITE_ONCE(stutter_till_abs_time, till_ns);
++ torture_hrtimeout_jiffies(stutter - 1, NULL);
+ }
+- WRITE_ONCE(stutter_pause_test, 0);
+ if (!torture_must_stop())
+ torture_hrtimeout_jiffies(stutter_gap, NULL);
+ torture_shutdown_absorb("torture_stutter");
+--
+2.42.0
+
--- /dev/null
+From c57c67ed524ea6affabaeeeb4aee3e7d60b9386b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Oct 2023 12:48:08 +0300
+Subject: selftests/resctrl: Extend signal handler coverage to unmount on
+ receiving signal
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 3aff5146445582454c35900f3c0c972987cdd595 ]
+
+Unmounting resctrl FS has been moved into the per test functions in
+resctrl_tests.c by commit caddc0fbe495 ("selftests/resctrl: Move
+resctrl FS mount/umount to higher level"). In case a signal (SIGINT,
+SIGTERM, or SIGHUP) is received, the running selftest is aborted by
+ctrlc_handler() which then unmounts resctrl fs before exiting. The
+current section between signal_handler_register() and
+signal_handler_unregister(), however, does not cover the entire
+duration when resctrl FS is mounted.
+
+Move signal_handler_register() and signal_handler_unregister() calls
+from per test files into resctrl_tests.c to properly unmount resctrl
+fs. In order to not add signal_handler_register()/unregister() n times,
+create helpers test_prepare() and test_cleanup().
+
+Do not call ksft_exit_fail_msg() in test_prepare() but only in the per
+test function to keep the control flow cleaner without adding calls to
+exit() deep into the call chain.
+
+Adjust child process kill() call in ctrlc_handler() to only be invoked
+if the child was already forked.
+
+Fixes: caddc0fbe495 ("selftests/resctrl: Move resctrl FS mount/umount to higher level")
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/cat_test.c | 8 ---
+ .../testing/selftests/resctrl/resctrl_tests.c | 69 ++++++++++++-------
+ tools/testing/selftests/resctrl/resctrl_val.c | 22 +++---
+ 3 files changed, 55 insertions(+), 44 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
+index 97b87285ab2a9..224ba8544d8af 100644
+--- a/tools/testing/selftests/resctrl/cat_test.c
++++ b/tools/testing/selftests/resctrl/cat_test.c
+@@ -167,12 +167,6 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+ strcpy(param.filename, RESULT_FILE_NAME1);
+ param.num_of_runs = 0;
+ param.cpu_no = sibling_cpu_no;
+- } else {
+- ret = signal_handler_register();
+- if (ret) {
+- kill(bm_pid, SIGKILL);
+- goto out;
+- }
+ }
+
+ remove(param.filename);
+@@ -209,10 +203,8 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+ }
+ close(pipefd[0]);
+ kill(bm_pid, SIGKILL);
+- signal_handler_unregister();
+ }
+
+-out:
+ cat_test_cleanup();
+
+ return ret;
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 1ac22c6d8ce8f..31373b69e675d 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -67,15 +67,39 @@ void tests_cleanup(void)
+ cat_test_cleanup();
+ }
+
+-static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
++static int test_prepare(void)
+ {
+ int res;
+
+- ksft_print_msg("Starting MBM BW change ...\n");
++ res = signal_handler_register();
++ if (res) {
++ ksft_print_msg("Failed to register signal handler\n");
++ return res;
++ }
+
+ res = mount_resctrlfs();
+ if (res) {
+- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
++ signal_handler_unregister();
++ ksft_print_msg("Failed to mount resctrl FS\n");
++ return res;
++ }
++ return 0;
++}
++
++static void test_cleanup(void)
++{
++ umount_resctrlfs();
++ signal_handler_unregister();
++}
++
++static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
++{
++ int res;
++
++ ksft_print_msg("Starting MBM BW change ...\n");
++
++ if (test_prepare()) {
++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
+ return;
+ }
+
+@@ -83,7 +107,7 @@ static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
+ !validate_resctrl_feature_request("L3_MON", "mbm_local_bytes") ||
+ (get_vendor() != ARCH_INTEL)) {
+ ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n");
+- goto umount;
++ goto cleanup;
+ }
+
+ res = mbm_bw_change(cpu_no, benchmark_cmd);
+@@ -91,8 +115,8 @@ static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
+ if ((get_vendor() == ARCH_INTEL) && res)
+ ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
+
+-umount:
+- umount_resctrlfs();
++cleanup:
++ test_cleanup();
+ }
+
+ static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
+@@ -101,9 +125,8 @@ static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
+
+ ksft_print_msg("Starting MBA Schemata change ...\n");
+
+- res = mount_resctrlfs();
+- if (res) {
+- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
++ if (test_prepare()) {
++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
+ return;
+ }
+
+@@ -111,14 +134,14 @@ static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
+ !validate_resctrl_feature_request("L3_MON", "mbm_local_bytes") ||
+ (get_vendor() != ARCH_INTEL)) {
+ ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n");
+- goto umount;
++ goto cleanup;
+ }
+
+ res = mba_schemata_change(cpu_no, benchmark_cmd);
+ ksft_test_result(!res, "MBA: schemata change\n");
+
+-umount:
+- umount_resctrlfs();
++cleanup:
++ test_cleanup();
+ }
+
+ static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
+@@ -127,16 +150,15 @@ static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
+
+ ksft_print_msg("Starting CMT test ...\n");
+
+- res = mount_resctrlfs();
+- if (res) {
+- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
++ if (test_prepare()) {
++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
+ return;
+ }
+
+ if (!validate_resctrl_feature_request("L3_MON", "llc_occupancy") ||
+ !validate_resctrl_feature_request("L3", NULL)) {
+ ksft_test_result_skip("Hardware does not support CMT or CMT is disabled\n");
+- goto umount;
++ goto cleanup;
+ }
+
+ res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd);
+@@ -144,8 +166,8 @@ static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
+ if ((get_vendor() == ARCH_INTEL) && res)
+ ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
+
+-umount:
+- umount_resctrlfs();
++cleanup:
++ test_cleanup();
+ }
+
+ static void run_cat_test(int cpu_no, int no_of_bits)
+@@ -154,22 +176,21 @@ static void run_cat_test(int cpu_no, int no_of_bits)
+
+ ksft_print_msg("Starting CAT test ...\n");
+
+- res = mount_resctrlfs();
+- if (res) {
+- ksft_exit_fail_msg("Failed to mount resctrl FS\n");
++ if (test_prepare()) {
++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
+ return;
+ }
+
+ if (!validate_resctrl_feature_request("L3", NULL)) {
+ ksft_test_result_skip("Hardware does not support CAT or CAT is disabled\n");
+- goto umount;
++ goto cleanup;
+ }
+
+ res = cat_perf_miss_val(cpu_no, no_of_bits, "L3");
+ ksft_test_result(!res, "CAT: test\n");
+
+-umount:
+- umount_resctrlfs();
++cleanup:
++ test_cleanup();
+ }
+
+ int main(int argc, char **argv)
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index 01bbe11a89834..b8ca6fa40b3bf 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -468,7 +468,9 @@ pid_t bm_pid, ppid;
+
+ void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
+ {
+- kill(bm_pid, SIGKILL);
++ /* Only kill child after bm_pid is set after fork() */
++ if (bm_pid)
++ kill(bm_pid, SIGKILL);
+ umount_resctrlfs();
+ tests_cleanup();
+ ksft_print_msg("Ending\n\n");
+@@ -485,6 +487,8 @@ int signal_handler_register(void)
+ struct sigaction sigact = {};
+ int ret = 0;
+
++ bm_pid = 0;
++
+ sigact.sa_sigaction = ctrlc_handler;
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = SA_SIGINFO;
+@@ -706,10 +710,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
+
+ ksft_print_msg("Benchmark PID: %d\n", bm_pid);
+
+- ret = signal_handler_register();
+- if (ret)
+- goto out;
+-
+ /*
+ * The cast removes constness but nothing mutates benchmark_cmd within
+ * the context of this process. At the receiving process, it becomes
+@@ -721,19 +721,19 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
+ /* Taskset benchmark to specified cpu */
+ ret = taskset_benchmark(bm_pid, param->cpu_no);
+ if (ret)
+- goto unregister;
++ goto out;
+
+ /* Write benchmark to specified control&monitoring grp in resctrl FS */
+ ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp,
+ resctrl_val);
+ if (ret)
+- goto unregister;
++ goto out;
+
+ if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) ||
+ !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) {
+ ret = initialize_mem_bw_imc();
+ if (ret)
+- goto unregister;
++ goto out;
+
+ initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp,
+ param->cpu_no, resctrl_val);
+@@ -748,7 +748,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
+ sizeof(pipe_message)) {
+ perror("# failed reading message from child process");
+ close(pipefd[0]);
+- goto unregister;
++ goto out;
+ }
+ }
+ close(pipefd[0]);
+@@ -757,7 +757,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
+ if (sigqueue(bm_pid, SIGUSR1, value) == -1) {
+ perror("# sigqueue SIGUSR1 to child");
+ ret = errno;
+- goto unregister;
++ goto out;
+ }
+
+ /* Give benchmark enough time to fully run */
+@@ -786,8 +786,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par
+ }
+ }
+
+-unregister:
+- signal_handler_unregister();
+ out:
+ kill(bm_pid, SIGKILL);
+
+--
+2.42.0
+
--- /dev/null
+From 06be35495ce0e4f598017fc4324198595deed4bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 12:53:37 +0300
+Subject: selftests/resctrl: Make benchmark command const and build it with
+ pointers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit e33cb5702a9f287d829b0e9e6abe57f6a4aba6d2 ]
+
+Benchmark command is used in multiple tests so it should not be
+mutated by the tests but CMT test alters span argument. Due to the
+order of tests (CMT test runs last), mutating the span argument in CMT
+test does not trigger any real problems currently.
+
+Mark benchmark_cmd strings as const and setup the benchmark command
+using pointers. Because the benchmark command becomes const, the input
+arguments can be used directly. Besides being simpler, using the input
+arguments directly also removes the internal size restriction.
+
+CMT test has to create a copy of the benchmark command before altering
+the benchmark command.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/cmt_test.c | 25 +++++++++---
+ tools/testing/selftests/resctrl/mba_test.c | 2 +-
+ tools/testing/selftests/resctrl/mbm_test.c | 2 +-
+ tools/testing/selftests/resctrl/resctrl.h | 10 +++--
+ .../testing/selftests/resctrl/resctrl_tests.c | 39 ++++++++-----------
+ tools/testing/selftests/resctrl/resctrl_val.c | 10 ++++-
+ 6 files changed, 53 insertions(+), 35 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c
+index 33dbe51e77122..50bdbce9fba95 100644
+--- a/tools/testing/selftests/resctrl/cmt_test.c
++++ b/tools/testing/selftests/resctrl/cmt_test.c
+@@ -68,14 +68,17 @@ void cmt_test_cleanup(void)
+ remove(RESULT_FILE_NAME);
+ }
+
+-int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
++int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd)
+ {
++ const char * const *cmd = benchmark_cmd;
++ const char *new_cmd[BENCHMARK_ARGS];
+ unsigned long cache_size = 0;
+ unsigned long long_mask;
++ char *span_str = NULL;
+ char cbm_mask[256];
+ int count_of_bits;
+ size_t span;
+- int ret;
++ int ret, i;
+
+ ret = get_cbm_mask("L3", cbm_mask);
+ if (ret)
+@@ -108,12 +111,23 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+ };
+
+ span = cache_size * n / count_of_bits;
+- if (strcmp(benchmark_cmd[0], "fill_buf") == 0)
+- sprintf(benchmark_cmd[1], "%zu", span);
++
++ if (strcmp(cmd[0], "fill_buf") == 0) {
++ /* Duplicate the command to be able to replace span in it */
++ for (i = 0; benchmark_cmd[i]; i++)
++ new_cmd[i] = benchmark_cmd[i];
++ new_cmd[i] = NULL;
++
++ ret = asprintf(&span_str, "%zu", span);
++ if (ret < 0)
++ return -1;
++ new_cmd[1] = span_str;
++ cmd = new_cmd;
++ }
+
+ remove(RESULT_FILE_NAME);
+
+- ret = resctrl_val(benchmark_cmd, ¶m);
++ ret = resctrl_val(cmd, ¶m);
+ if (ret)
+ goto out;
+
+@@ -121,6 +135,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+
+ out:
+ cmt_test_cleanup();
++ free(span_str);
+
+ return ret;
+ }
+diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
+index c5c0588779d2b..d3bf4368341ec 100644
+--- a/tools/testing/selftests/resctrl/mba_test.c
++++ b/tools/testing/selftests/resctrl/mba_test.c
+@@ -141,7 +141,7 @@ void mba_test_cleanup(void)
+ remove(RESULT_FILE_NAME);
+ }
+
+-int mba_schemata_change(int cpu_no, char **benchmark_cmd)
++int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd)
+ {
+ struct resctrl_val_param param = {
+ .resctrl_val = MBA_STR,
+diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
+index 445aea1c64e83..d3c0d30c676a7 100644
+--- a/tools/testing/selftests/resctrl/mbm_test.c
++++ b/tools/testing/selftests/resctrl/mbm_test.c
+@@ -109,7 +109,7 @@ void mbm_test_cleanup(void)
+ remove(RESULT_FILE_NAME);
+ }
+
+-int mbm_bw_change(int cpu_no, char **benchmark_cmd)
++int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd)
+ {
+ struct resctrl_val_param param = {
+ .resctrl_val = MBM_STR,
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index d33452fde5b94..8578a8b4e1459 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -33,6 +33,8 @@
+
+ #define END_OF_TESTS 1
+
++#define BENCHMARK_ARGS 64
++
+ #define DEFAULT_SPAN (250 * MB)
+
+ #define PARENT_EXIT(err_msg) \
+@@ -92,11 +94,11 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp,
+ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
+ int group_fd, unsigned long flags);
+ int run_fill_buf(size_t span, int memflush, int op, bool once);
+-int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param);
+-int mbm_bw_change(int cpu_no, char **benchmark_cmd);
++int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param);
++int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd);
+ void tests_cleanup(void);
+ void mbm_test_cleanup(void);
+-int mba_schemata_change(int cpu_no, char **benchmark_cmd);
++int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd);
+ void mba_test_cleanup(void);
+ int get_cbm_mask(char *cache_type, char *cbm_mask);
+ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
+@@ -106,7 +108,7 @@ void signal_handler_unregister(void);
+ int cat_val(struct resctrl_val_param *param, size_t span);
+ void cat_test_cleanup(void);
+ int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type);
+-int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd);
++int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd);
+ unsigned int count_bits(unsigned long n);
+ void cmt_test_cleanup(void);
+ int get_core_sibling(int cpu_no);
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 1826b674ea300..1ac22c6d8ce8f 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -10,9 +10,6 @@
+ */
+ #include "resctrl.h"
+
+-#define BENCHMARK_ARGS 64
+-#define BENCHMARK_ARG_SIZE 64
+-
+ static int detect_vendor(void)
+ {
+ FILE *inf = fopen("/proc/cpuinfo", "r");
+@@ -70,7 +67,7 @@ void tests_cleanup(void)
+ cat_test_cleanup();
+ }
+
+-static void run_mbm_test(char **benchmark_cmd, int cpu_no)
++static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no)
+ {
+ int res;
+
+@@ -98,7 +95,7 @@ static void run_mbm_test(char **benchmark_cmd, int cpu_no)
+ umount_resctrlfs();
+ }
+
+-static void run_mba_test(char **benchmark_cmd, int cpu_no)
++static void run_mba_test(const char * const *benchmark_cmd, int cpu_no)
+ {
+ int res;
+
+@@ -124,7 +121,7 @@ static void run_mba_test(char **benchmark_cmd, int cpu_no)
+ umount_resctrlfs();
+ }
+
+-static void run_cmt_test(char **benchmark_cmd, int cpu_no)
++static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no)
+ {
+ int res;
+
+@@ -178,11 +175,12 @@ static void run_cat_test(int cpu_no, int no_of_bits)
+ int main(int argc, char **argv)
+ {
+ bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true;
+- char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE];
+ int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0;
+- char *benchmark_cmd[BENCHMARK_ARGS];
++ const char *benchmark_cmd[BENCHMARK_ARGS];
+ int ben_ind, ben_count, tests = 0;
++ char *span_str = NULL;
+ bool cat_test = true;
++ int ret;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "-b") == 0) {
+@@ -262,23 +260,19 @@ int main(int argc, char **argv)
+ ksft_exit_fail_msg("Too long benchmark command.\n");
+
+ /* Extract benchmark command from command line. */
+- for (i = ben_ind; i < argc; i++) {
+- benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i];
+- if (strlen(argv[i]) >= BENCHMARK_ARG_SIZE)
+- ksft_exit_fail_msg("Too long benchmark command argument.\n");
+- sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]);
+- }
++ for (i = 0; i < argc - ben_ind; i++)
++ benchmark_cmd[i] = argv[i + ben_ind];
+ benchmark_cmd[ben_count] = NULL;
+ } else {
+ /* If no benchmark is given by "-b" argument, use fill_buf. */
+- for (i = 0; i < 5; i++)
+- benchmark_cmd[i] = benchmark_cmd_area[i];
+-
+- strcpy(benchmark_cmd[0], "fill_buf");
+- sprintf(benchmark_cmd[1], "%u", DEFAULT_SPAN);
+- strcpy(benchmark_cmd[2], "1");
+- strcpy(benchmark_cmd[3], "0");
+- strcpy(benchmark_cmd[4], "false");
++ benchmark_cmd[0] = "fill_buf";
++ ret = asprintf(&span_str, "%u", DEFAULT_SPAN);
++ if (ret < 0)
++ ksft_exit_fail_msg("Out of memory!\n");
++ benchmark_cmd[1] = span_str;
++ benchmark_cmd[2] = "1";
++ benchmark_cmd[3] = "0";
++ benchmark_cmd[4] = "false";
+ benchmark_cmd[5] = NULL;
+ }
+
+@@ -304,5 +298,6 @@ int main(int argc, char **argv)
+ if (cat_test)
+ run_cat_test(cpu_no, no_of_bits);
+
++ free(span_str);
+ ksft_finished();
+ }
+diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c
+index ee07e0943f583..01bbe11a89834 100644
+--- a/tools/testing/selftests/resctrl/resctrl_val.c
++++ b/tools/testing/selftests/resctrl/resctrl_val.c
+@@ -629,7 +629,7 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start)
+ *
+ * Return: 0 on success. non-zero on failure.
+ */
+-int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
++int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param)
+ {
+ char *resctrl_val = param->resctrl_val;
+ unsigned long bw_resc_start = 0;
+@@ -710,7 +710,13 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param)
+ if (ret)
+ goto out;
+
+- value.sival_ptr = benchmark_cmd;
++ /*
++ * The cast removes constness but nothing mutates benchmark_cmd within
++ * the context of this process. At the receiving process, it becomes
++ * argv, which is mutable, on exec() but that's after fork() so it
++ * doesn't matter for the process running the tests.
++ */
++ value.sival_ptr = (void *)benchmark_cmd;
+
+ /* Taskset benchmark to specified cpu */
+ ret = taskset_benchmark(bm_pid, param->cpu_no);
+--
+2.42.0
+
--- /dev/null
+From 9d927dab1a26936dae56d5e161f55f57358b70a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 12:53:34 +0300
+Subject: selftests/resctrl: Remove bw_report and bm_type from main()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit 47e36f16c7846bf3627ff68525e02555c53dc99e ]
+
+bw_report is always set to "reads" and bm_type is set to "fill_buf" but
+is never used.
+
+Set bw_report directly to "reads" in MBA/MBM test and remove bm_type.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/mba_test.c | 4 ++--
+ tools/testing/selftests/resctrl/mbm_test.c | 4 ++--
+ tools/testing/selftests/resctrl/resctrl.h | 4 ++--
+ .../testing/selftests/resctrl/resctrl_tests.c | 18 +++++++-----------
+ 4 files changed, 13 insertions(+), 17 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c
+index c7d1ec6d81ea8..c5c0588779d2b 100644
+--- a/tools/testing/selftests/resctrl/mba_test.c
++++ b/tools/testing/selftests/resctrl/mba_test.c
+@@ -141,7 +141,7 @@ void mba_test_cleanup(void)
+ remove(RESULT_FILE_NAME);
+ }
+
+-int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
++int mba_schemata_change(int cpu_no, char **benchmark_cmd)
+ {
+ struct resctrl_val_param param = {
+ .resctrl_val = MBA_STR,
+@@ -149,7 +149,7 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd)
+ .mongrp = "m1",
+ .cpu_no = cpu_no,
+ .filename = RESULT_FILE_NAME,
+- .bw_report = bw_report,
++ .bw_report = "reads",
+ .setup = mba_setup
+ };
+ int ret;
+diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
+index d0c26a5e89fb9..724412186d636 100644
+--- a/tools/testing/selftests/resctrl/mbm_test.c
++++ b/tools/testing/selftests/resctrl/mbm_test.c
+@@ -109,7 +109,7 @@ void mbm_test_cleanup(void)
+ remove(RESULT_FILE_NAME);
+ }
+
+-int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd)
++int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd)
+ {
+ struct resctrl_val_param param = {
+ .resctrl_val = MBM_STR,
+@@ -118,7 +118,7 @@ int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd
+ .span = span,
+ .cpu_no = cpu_no,
+ .filename = RESULT_FILE_NAME,
+- .bw_report = bw_report,
++ .bw_report = "reads",
+ .setup = mbm_setup
+ };
+ int ret;
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index 9e46fa90e7be7..df75c89060329 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -93,10 +93,10 @@ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
+ int group_fd, unsigned long flags);
+ int run_fill_buf(size_t span, int memflush, int op, bool once);
+ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param);
+-int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd);
++int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd);
+ void tests_cleanup(void);
+ void mbm_test_cleanup(void);
+-int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd);
++int mba_schemata_change(int cpu_no, char **benchmark_cmd);
+ void mba_test_cleanup(void);
+ int get_cbm_mask(char *cache_type, char *cbm_mask);
+ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 59a361660d8c8..116f67d833f75 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -70,8 +70,7 @@ void tests_cleanup(void)
+ cat_test_cleanup();
+ }
+
+-static void run_mbm_test(char **benchmark_cmd, size_t span,
+- int cpu_no, char *bw_report)
++static void run_mbm_test(char **benchmark_cmd, size_t span, int cpu_no)
+ {
+ int res;
+
+@@ -90,7 +89,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span,
+ goto umount;
+ }
+
+- res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd);
++ res = mbm_bw_change(span, cpu_no, benchmark_cmd);
+ ksft_test_result(!res, "MBM: bw change\n");
+ if ((get_vendor() == ARCH_INTEL) && res)
+ ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
+@@ -99,7 +98,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span,
+ umount_resctrlfs();
+ }
+
+-static void run_mba_test(char **benchmark_cmd, int cpu_no, char *bw_report)
++static void run_mba_test(char **benchmark_cmd, int cpu_no)
+ {
+ int res;
+
+@@ -118,7 +117,7 @@ static void run_mba_test(char **benchmark_cmd, int cpu_no, char *bw_report)
+ goto umount;
+ }
+
+- res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd);
++ res = mba_schemata_change(cpu_no, benchmark_cmd);
+ ksft_test_result(!res, "MBA: schemata change\n");
+
+ umount:
+@@ -179,9 +178,9 @@ static void run_cat_test(int cpu_no, int no_of_bits)
+ int main(int argc, char **argv)
+ {
+ bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true;
+- char *benchmark_cmd[BENCHMARK_ARGS], bw_report[64], bm_type[64];
+ char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE];
+ int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0;
++ char *benchmark_cmd[BENCHMARK_ARGS];
+ int ben_ind, ben_count, tests = 0;
+ size_t span = 250 * MB;
+ bool cat_test = true;
+@@ -284,9 +283,6 @@ int main(int argc, char **argv)
+ benchmark_cmd[5] = NULL;
+ }
+
+- sprintf(bw_report, "reads");
+- sprintf(bm_type, "fill_buf");
+-
+ if (!check_resctrlfs_support())
+ return ksft_exit_skip("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n");
+
+@@ -298,10 +294,10 @@ int main(int argc, char **argv)
+ ksft_set_plan(tests ? : 4);
+
+ if (mbm_test)
+- run_mbm_test(benchmark_cmd, span, cpu_no, bw_report);
++ run_mbm_test(benchmark_cmd, span, cpu_no);
+
+ if (mba_test)
+- run_mba_test(benchmark_cmd, cpu_no, bw_report);
++ run_mba_test(benchmark_cmd, cpu_no);
+
+ if (cmt_test)
+ run_cmt_test(benchmark_cmd, cpu_no);
+--
+2.42.0
+
--- /dev/null
+From 3034595e60cb16e8b4cafd69d9ddeba421bf018a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 12:53:35 +0300
+Subject: selftests/resctrl: Simplify span lifetime
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+[ Upstream commit b1a901e078c4ee4a6fe13021c4577ef5f3155251 ]
+
+struct resctrl_val_param contains span member. resctrl_val(), however,
+never uses it because the value of span is embedded into the default
+benchmark command and parsed from it by run_benchmark().
+
+Remove span from resctrl_val_param. Provide DEFAULT_SPAN for the code
+that needs it. CMT and CAT tests communicate span that is different
+from the DEFAULT_SPAN between their internal functions which is
+converted into passing it directly as a parameter.
+
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/resctrl/cache.c | 5 +++--
+ tools/testing/selftests/resctrl/cat_test.c | 13 +++++++------
+ tools/testing/selftests/resctrl/cmt_test.c | 11 ++++++-----
+ tools/testing/selftests/resctrl/mbm_test.c | 5 ++---
+ tools/testing/selftests/resctrl/resctrl.h | 8 ++++----
+ tools/testing/selftests/resctrl/resctrl_tests.c | 9 ++++-----
+ 6 files changed, 26 insertions(+), 25 deletions(-)
+
+diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c
+index d3cbb829ff6a7..a0318bd3a63d8 100644
+--- a/tools/testing/selftests/resctrl/cache.c
++++ b/tools/testing/selftests/resctrl/cache.c
+@@ -205,10 +205,11 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid)
+ * cache_val: execute benchmark and measure LLC occupancy resctrl
+ * and perf cache miss for the benchmark
+ * @param: parameters passed to cache_val()
++ * @span: buffer size for the benchmark
+ *
+ * Return: 0 on success. non-zero on failure.
+ */
+-int cat_val(struct resctrl_val_param *param)
++int cat_val(struct resctrl_val_param *param, size_t span)
+ {
+ int memflush = 1, operation = 0, ret = 0;
+ char *resctrl_val = param->resctrl_val;
+@@ -245,7 +246,7 @@ int cat_val(struct resctrl_val_param *param)
+ if (ret)
+ break;
+
+- if (run_fill_buf(param->span, memflush, operation, true)) {
++ if (run_fill_buf(span, memflush, operation, true)) {
+ fprintf(stderr, "Error-running fill buffer\n");
+ ret = -1;
+ goto pe_close;
+diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c
+index 3848dfb46aba4..97b87285ab2a9 100644
+--- a/tools/testing/selftests/resctrl/cat_test.c
++++ b/tools/testing/selftests/resctrl/cat_test.c
+@@ -41,7 +41,7 @@ static int cat_setup(struct resctrl_val_param *p)
+ return ret;
+ }
+
+-static int check_results(struct resctrl_val_param *param)
++static int check_results(struct resctrl_val_param *param, size_t span)
+ {
+ char *token_array[8], temp[512];
+ unsigned long sum_llc_perf_miss = 0;
+@@ -76,7 +76,7 @@ static int check_results(struct resctrl_val_param *param)
+ fclose(fp);
+ no_of_bits = count_bits(param->mask);
+
+- return show_cache_info(sum_llc_perf_miss, no_of_bits, param->span / 64,
++ return show_cache_info(sum_llc_perf_miss, no_of_bits, span / 64,
+ MAX_DIFF, MAX_DIFF_PERCENT, runs - 1,
+ get_vendor() == ARCH_INTEL, false);
+ }
+@@ -96,6 +96,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+ char cbm_mask[256];
+ int count_of_bits;
+ char pipe_message;
++ size_t span;
+
+ /* Get default cbm mask for L3/L2 cache */
+ ret = get_cbm_mask(cache_type, cbm_mask);
+@@ -140,7 +141,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+ /* Set param values for parent thread which will be allocated bitmask
+ * with (max_bits - n) bits
+ */
+- param.span = cache_size * (count_of_bits - n) / count_of_bits;
++ span = cache_size * (count_of_bits - n) / count_of_bits;
+ strcpy(param.ctrlgrp, "c2");
+ strcpy(param.mongrp, "m2");
+ strcpy(param.filename, RESULT_FILE_NAME2);
+@@ -162,7 +163,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+ param.mask = l_mask_1;
+ strcpy(param.ctrlgrp, "c1");
+ strcpy(param.mongrp, "m1");
+- param.span = cache_size * n / count_of_bits;
++ span = cache_size * n / count_of_bits;
+ strcpy(param.filename, RESULT_FILE_NAME1);
+ param.num_of_runs = 0;
+ param.cpu_no = sibling_cpu_no;
+@@ -176,9 +177,9 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type)
+
+ remove(param.filename);
+
+- ret = cat_val(¶m);
++ ret = cat_val(¶m, span);
+ if (ret == 0)
+- ret = check_results(¶m);
++ ret = check_results(¶m, span);
+
+ if (bm_pid == 0) {
+ /* Tell parent that child is ready */
+diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c
+index cc93cb5ae7ee9..33dbe51e77122 100644
+--- a/tools/testing/selftests/resctrl/cmt_test.c
++++ b/tools/testing/selftests/resctrl/cmt_test.c
+@@ -27,7 +27,7 @@ static int cmt_setup(struct resctrl_val_param *p)
+ return 0;
+ }
+
+-static int check_results(struct resctrl_val_param *param, int no_of_bits)
++static int check_results(struct resctrl_val_param *param, size_t span, int no_of_bits)
+ {
+ char *token_array[8], temp[512];
+ unsigned long sum_llc_occu_resc = 0;
+@@ -58,7 +58,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits)
+ }
+ fclose(fp);
+
+- return show_cache_info(sum_llc_occu_resc, no_of_bits, param->span,
++ return show_cache_info(sum_llc_occu_resc, no_of_bits, span,
+ MAX_DIFF, MAX_DIFF_PERCENT, runs - 1,
+ true, true);
+ }
+@@ -74,6 +74,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+ unsigned long long_mask;
+ char cbm_mask[256];
+ int count_of_bits;
++ size_t span;
+ int ret;
+
+ ret = get_cbm_mask("L3", cbm_mask);
+@@ -102,13 +103,13 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+ .cpu_no = cpu_no,
+ .filename = RESULT_FILE_NAME,
+ .mask = ~(long_mask << n) & long_mask,
+- .span = cache_size * n / count_of_bits,
+ .num_of_runs = 0,
+ .setup = cmt_setup,
+ };
+
++ span = cache_size * n / count_of_bits;
+ if (strcmp(benchmark_cmd[0], "fill_buf") == 0)
+- sprintf(benchmark_cmd[1], "%zu", param.span);
++ sprintf(benchmark_cmd[1], "%zu", span);
+
+ remove(RESULT_FILE_NAME);
+
+@@ -116,7 +117,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd)
+ if (ret)
+ goto out;
+
+- ret = check_results(¶m, n);
++ ret = check_results(¶m, span, n);
+
+ out:
+ cmt_test_cleanup();
+diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c
+index 724412186d636..445aea1c64e83 100644
+--- a/tools/testing/selftests/resctrl/mbm_test.c
++++ b/tools/testing/selftests/resctrl/mbm_test.c
+@@ -109,13 +109,12 @@ void mbm_test_cleanup(void)
+ remove(RESULT_FILE_NAME);
+ }
+
+-int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd)
++int mbm_bw_change(int cpu_no, char **benchmark_cmd)
+ {
+ struct resctrl_val_param param = {
+ .resctrl_val = MBM_STR,
+ .ctrlgrp = "c1",
+ .mongrp = "m1",
+- .span = span,
+ .cpu_no = cpu_no,
+ .filename = RESULT_FILE_NAME,
+ .bw_report = "reads",
+@@ -129,7 +128,7 @@ int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd)
+ if (ret)
+ goto out;
+
+- ret = check_results(span);
++ ret = check_results(DEFAULT_SPAN);
+
+ out:
+ mbm_test_cleanup();
+diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h
+index df75c89060329..d33452fde5b94 100644
+--- a/tools/testing/selftests/resctrl/resctrl.h
++++ b/tools/testing/selftests/resctrl/resctrl.h
+@@ -33,6 +33,8 @@
+
+ #define END_OF_TESTS 1
+
++#define DEFAULT_SPAN (250 * MB)
++
+ #define PARENT_EXIT(err_msg) \
+ do { \
+ perror(err_msg); \
+@@ -47,7 +49,6 @@
+ * @ctrlgrp: Name of the control monitor group (con_mon grp)
+ * @mongrp: Name of the monitor group (mon grp)
+ * @cpu_no: CPU number to which the benchmark would be binded
+- * @span: Memory bytes accessed in each benchmark iteration
+ * @filename: Name of file to which the o/p should be written
+ * @bw_report: Bandwidth report type (reads vs writes)
+ * @setup: Call back function to setup test environment
+@@ -57,7 +58,6 @@ struct resctrl_val_param {
+ char ctrlgrp[64];
+ char mongrp[64];
+ int cpu_no;
+- size_t span;
+ char filename[64];
+ char *bw_report;
+ unsigned long mask;
+@@ -93,7 +93,7 @@ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu,
+ int group_fd, unsigned long flags);
+ int run_fill_buf(size_t span, int memflush, int op, bool once);
+ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param);
+-int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd);
++int mbm_bw_change(int cpu_no, char **benchmark_cmd);
+ void tests_cleanup(void);
+ void mbm_test_cleanup(void);
+ int mba_schemata_change(int cpu_no, char **benchmark_cmd);
+@@ -103,7 +103,7 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size);
+ void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
+ int signal_handler_register(void);
+ void signal_handler_unregister(void);
+-int cat_val(struct resctrl_val_param *param);
++int cat_val(struct resctrl_val_param *param, size_t span);
+ void cat_test_cleanup(void);
+ int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type);
+ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd);
+diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c
+index 116f67d833f75..1826b674ea300 100644
+--- a/tools/testing/selftests/resctrl/resctrl_tests.c
++++ b/tools/testing/selftests/resctrl/resctrl_tests.c
+@@ -70,7 +70,7 @@ void tests_cleanup(void)
+ cat_test_cleanup();
+ }
+
+-static void run_mbm_test(char **benchmark_cmd, size_t span, int cpu_no)
++static void run_mbm_test(char **benchmark_cmd, int cpu_no)
+ {
+ int res;
+
+@@ -89,7 +89,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span, int cpu_no)
+ goto umount;
+ }
+
+- res = mbm_bw_change(span, cpu_no, benchmark_cmd);
++ res = mbm_bw_change(cpu_no, benchmark_cmd);
+ ksft_test_result(!res, "MBM: bw change\n");
+ if ((get_vendor() == ARCH_INTEL) && res)
+ ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
+@@ -182,7 +182,6 @@ int main(int argc, char **argv)
+ int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0;
+ char *benchmark_cmd[BENCHMARK_ARGS];
+ int ben_ind, ben_count, tests = 0;
+- size_t span = 250 * MB;
+ bool cat_test = true;
+
+ for (i = 0; i < argc; i++) {
+@@ -276,7 +275,7 @@ int main(int argc, char **argv)
+ benchmark_cmd[i] = benchmark_cmd_area[i];
+
+ strcpy(benchmark_cmd[0], "fill_buf");
+- sprintf(benchmark_cmd[1], "%zu", span);
++ sprintf(benchmark_cmd[1], "%u", DEFAULT_SPAN);
+ strcpy(benchmark_cmd[2], "1");
+ strcpy(benchmark_cmd[3], "0");
+ strcpy(benchmark_cmd[4], "false");
+@@ -294,7 +293,7 @@ int main(int argc, char **argv)
+ ksft_set_plan(tests ? : 4);
+
+ if (mbm_test)
+- run_mbm_test(benchmark_cmd, span, cpu_no);
++ run_mbm_test(benchmark_cmd, cpu_no);
+
+ if (mba_test)
+ run_mba_test(benchmark_cmd, cpu_no);
+--
+2.42.0
+
i3c-master-svc-fix-check-wrong-status-register-in-irq-handler.patch
i3c-master-svc-fix-sda-keep-low-when-polling-ibiwon-timeout-happen.patch
i3c-master-svc-fix-random-hot-join-failure-since-timeout-error.patch
+apparmor-fix-kernel-doc-warnings-in-apparmor-audit.c.patch
+apparmor-fix-kernel-doc-warnings-in-apparmor-lib.c.patch
+apparmor-fix-kernel-doc-warnings-in-apparmor-resourc.patch
+apparmor-fix-kernel-doc-warnings-in-apparmor-policy..patch
+apparmor-combine-common_audit_data-and-apparmor_audi.patch
+apparmor-rename-audit_data-label-to-audit_data-subj_.patch
+apparmor-pass-cred-through-to-audit-info.patch
+apparmor-fix-regression-in-mount-mediation.patch
+bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch
+bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch
+drm-amd-display-enable-dsc_clk-even-if-dsc_pg-disabl.patch
+torture-make-torture_hrtimeout_ns-take-an-hrtimer-mo.patch
+rcutorture-fix-stuttering-races-and-other-issues.patch
+selftests-resctrl-remove-bw_report-and-bm_type-from-.patch
+selftests-resctrl-simplify-span-lifetime.patch
+selftests-resctrl-make-benchmark-command-const-and-b.patch
+selftests-resctrl-extend-signal-handler-coverage-to-.patch
+cxl-region-fix-x1-root-decoder-granularity-calculati.patch
+cxl-port-fix-delete_endpoint-vs-parent-unregistratio.patch
--- /dev/null
+From 42cec578f5f387699165906a7ab1eb12daaa55d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 13:57:03 -0700
+Subject: torture: Make torture_hrtimeout_ns() take an hrtimer mode parameter
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ Upstream commit a741deac787f0d2d7068638c067db20af9e63752 ]
+
+The current torture-test sleeps are waiting for a duration, but there
+are situations where it is better to wait for an absolute time, for
+example, when ending a stutter interval. This commit therefore adds
+an hrtimer mode parameter to torture_hrtimeout_ns(). Why not also the
+other torture_hrtimeout_*() functions? The theory is that most absolute
+times will be in nanoseconds, especially not (say) jiffies.
+
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Stable-dep-of: cca42bd8eb1b ("rcutorture: Fix stuttering races and other issues")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/torture.h | 3 ++-
+ kernel/torture.c | 13 +++++++------
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/include/linux/torture.h b/include/linux/torture.h
+index bb466eec01e42..017f0f710815a 100644
+--- a/include/linux/torture.h
++++ b/include/linux/torture.h
+@@ -81,7 +81,8 @@ static inline void torture_random_init(struct torture_random_state *trsp)
+ }
+
+ /* Definitions for high-resolution-timer sleeps. */
+-int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, struct torture_random_state *trsp);
++int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, const enum hrtimer_mode mode,
++ struct torture_random_state *trsp);
+ int torture_hrtimeout_us(u32 baset_us, u32 fuzzt_ns, struct torture_random_state *trsp);
+ int torture_hrtimeout_ms(u32 baset_ms, u32 fuzzt_us, struct torture_random_state *trsp);
+ int torture_hrtimeout_jiffies(u32 baset_j, struct torture_random_state *trsp);
+diff --git a/kernel/torture.c b/kernel/torture.c
+index b28b05bbef027..e851b8e9390b3 100644
+--- a/kernel/torture.c
++++ b/kernel/torture.c
+@@ -87,14 +87,15 @@ EXPORT_SYMBOL_GPL(verbose_torout_sleep);
+ * nanosecond random fuzz. This function and its friends desynchronize
+ * testing from the timer wheel.
+ */
+-int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, struct torture_random_state *trsp)
++int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, const enum hrtimer_mode mode,
++ struct torture_random_state *trsp)
+ {
+ ktime_t hto = baset_ns;
+
+ if (trsp)
+ hto += torture_random(trsp) % fuzzt_ns;
+ set_current_state(TASK_IDLE);
+- return schedule_hrtimeout(&hto, HRTIMER_MODE_REL);
++ return schedule_hrtimeout(&hto, mode);
+ }
+ EXPORT_SYMBOL_GPL(torture_hrtimeout_ns);
+
+@@ -106,7 +107,7 @@ int torture_hrtimeout_us(u32 baset_us, u32 fuzzt_ns, struct torture_random_state
+ {
+ ktime_t baset_ns = baset_us * NSEC_PER_USEC;
+
+- return torture_hrtimeout_ns(baset_ns, fuzzt_ns, trsp);
++ return torture_hrtimeout_ns(baset_ns, fuzzt_ns, HRTIMER_MODE_REL, trsp);
+ }
+ EXPORT_SYMBOL_GPL(torture_hrtimeout_us);
+
+@@ -123,7 +124,7 @@ int torture_hrtimeout_ms(u32 baset_ms, u32 fuzzt_us, struct torture_random_state
+ fuzzt_ns = (u32)~0U;
+ else
+ fuzzt_ns = fuzzt_us * NSEC_PER_USEC;
+- return torture_hrtimeout_ns(baset_ns, fuzzt_ns, trsp);
++ return torture_hrtimeout_ns(baset_ns, fuzzt_ns, HRTIMER_MODE_REL, trsp);
+ }
+ EXPORT_SYMBOL_GPL(torture_hrtimeout_ms);
+
+@@ -136,7 +137,7 @@ int torture_hrtimeout_jiffies(u32 baset_j, struct torture_random_state *trsp)
+ {
+ ktime_t baset_ns = jiffies_to_nsecs(baset_j);
+
+- return torture_hrtimeout_ns(baset_ns, jiffies_to_nsecs(1), trsp);
++ return torture_hrtimeout_ns(baset_ns, jiffies_to_nsecs(1), HRTIMER_MODE_REL, trsp);
+ }
+ EXPORT_SYMBOL_GPL(torture_hrtimeout_jiffies);
+
+@@ -153,7 +154,7 @@ int torture_hrtimeout_s(u32 baset_s, u32 fuzzt_ms, struct torture_random_state *
+ fuzzt_ns = (u32)~0U;
+ else
+ fuzzt_ns = fuzzt_ms * NSEC_PER_MSEC;
+- return torture_hrtimeout_ns(baset_ns, fuzzt_ns, trsp);
++ return torture_hrtimeout_ns(baset_ns, fuzzt_ns, HRTIMER_MODE_REL, trsp);
+ }
+ EXPORT_SYMBOL_GPL(torture_hrtimeout_s);
+
+--
+2.42.0
+