1 // SPDX-License-Identifier: GPL-2.0-or-later
14 * Helper function for testing the behaviour of a newly exec-ed process
16 static int dexcr_prctl_onexec_test_child(unsigned long which
, const char *status
)
18 unsigned long dexcr
= mfspr(SPRN_DEXCR_RO
);
19 unsigned long aspect
= pr_which_to_aspect(which
);
20 int ctrl
= pr_get_dexcr(which
);
22 if (!strcmp(status
, "set")) {
23 FAIL_IF_EXIT_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_SET
),
24 "setting aspect across exec not applied");
26 FAIL_IF_EXIT_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_SET_ONEXEC
),
27 "setting aspect across exec not inherited");
29 FAIL_IF_EXIT_MSG(!(aspect
& dexcr
), "setting aspect across exec did not take effect");
30 } else if (!strcmp(status
, "clear")) {
31 FAIL_IF_EXIT_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR
),
32 "clearing aspect across exec not applied");
34 FAIL_IF_EXIT_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
),
35 "clearing aspect across exec not inherited");
37 FAIL_IF_EXIT_MSG(aspect
& dexcr
, "clearing aspect across exec did not take effect");
39 FAIL_IF_EXIT_MSG(true, "unknown expected status");
46 * Test that the given prctl value can be manipulated freely
48 static int dexcr_prctl_aspect_test(unsigned long which
)
50 unsigned long aspect
= pr_which_to_aspect(which
);
56 SKIP_IF_MSG(!dexcr_exists(), "DEXCR not supported");
57 SKIP_IF_MSG(!pr_dexcr_aspect_supported(which
), "DEXCR aspect not supported");
58 SKIP_IF_MSG(!pr_dexcr_aspect_editable(which
), "DEXCR aspect not editable with prctl");
60 /* We reject invalid combinations of arguments */
61 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_SET
| PR_PPC_DEXCR_CTRL_CLEAR
);
63 FAIL_IF_MSG(err
!= -1, "simultaneous set and clear should be rejected");
64 FAIL_IF_MSG(errno_save
!= EINVAL
, "simultaneous set and clear should be rejected with EINVAL");
66 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_SET_ONEXEC
| PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
);
68 FAIL_IF_MSG(err
!= -1, "simultaneous set and clear on exec should be rejected");
69 FAIL_IF_MSG(errno_save
!= EINVAL
, "simultaneous set and clear on exec should be rejected with EINVAL");
71 /* We set the aspect */
72 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_SET
);
73 FAIL_IF_MSG(err
, "PR_PPC_DEXCR_CTRL_SET failed");
75 ctrl
= pr_get_dexcr(which
);
76 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_SET
), "config value not PR_PPC_DEXCR_CTRL_SET");
77 FAIL_IF_MSG(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR
, "config value unexpected clear flag");
78 FAIL_IF_MSG(!(aspect
& mfspr(SPRN_DEXCR_RO
)), "setting aspect did not take effect");
80 /* We clear the aspect */
81 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_CLEAR
);
82 FAIL_IF_MSG(err
, "PR_PPC_DEXCR_CTRL_CLEAR failed");
84 ctrl
= pr_get_dexcr(which
);
85 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR
), "config value not PR_PPC_DEXCR_CTRL_CLEAR");
86 FAIL_IF_MSG(ctrl
& PR_PPC_DEXCR_CTRL_SET
, "config value unexpected set flag");
87 FAIL_IF_MSG(aspect
& mfspr(SPRN_DEXCR_RO
), "clearing aspect did not take effect");
89 /* We make it set on exec (doesn't change our current value) */
90 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_SET_ONEXEC
);
91 FAIL_IF_MSG(err
, "PR_PPC_DEXCR_CTRL_SET_ONEXEC failed");
93 ctrl
= pr_get_dexcr(which
);
94 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR
), "process aspect should still be cleared");
95 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_SET_ONEXEC
), "config value not PR_PPC_DEXCR_CTRL_SET_ONEXEC");
96 FAIL_IF_MSG(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
, "config value unexpected clear on exec flag");
97 FAIL_IF_MSG(aspect
& mfspr(SPRN_DEXCR_RO
), "scheduling aspect to set on exec should not change it now");
99 /* We make it clear on exec (doesn't change our current value) */
100 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
);
101 FAIL_IF_MSG(err
, "PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC failed");
103 ctrl
= pr_get_dexcr(which
);
104 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR
), "process aspect config should still be cleared");
105 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
), "config value not PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC");
106 FAIL_IF_MSG(ctrl
& PR_PPC_DEXCR_CTRL_SET_ONEXEC
, "config value unexpected set on exec flag");
107 FAIL_IF_MSG(aspect
& mfspr(SPRN_DEXCR_RO
), "process aspect should still be cleared");
109 /* We allow setting the current and on-exec value in a single call */
110 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_SET
| PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
);
111 FAIL_IF_MSG(err
, "PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC failed");
113 ctrl
= pr_get_dexcr(which
);
114 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_SET
), "config value not PR_PPC_DEXCR_CTRL_SET");
115 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
), "config value not PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC");
116 FAIL_IF_MSG(!(aspect
& mfspr(SPRN_DEXCR_RO
)), "process aspect should be set");
118 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_CLEAR
| PR_PPC_DEXCR_CTRL_SET_ONEXEC
);
119 FAIL_IF_MSG(err
, "PR_PPC_DEXCR_CTRL_CLEAR | PR_PPC_DEXCR_CTRL_SET_ONEXEC failed");
121 ctrl
= pr_get_dexcr(which
);
122 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR
), "config value not PR_PPC_DEXCR_CTRL_CLEAR");
123 FAIL_IF_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_SET_ONEXEC
), "config value not PR_PPC_DEXCR_CTRL_SET_ONEXEC");
124 FAIL_IF_MSG(aspect
& mfspr(SPRN_DEXCR_RO
), "process aspect should be clear");
126 /* Verify the onexec value is applied across exec */
129 char which_str
[32] = {};
130 char *args
[] = { "dexcr_prctl_onexec_test_child", which_str
, "set", NULL
};
131 unsigned int ctrl
= pr_get_dexcr(which
);
133 sprintf(which_str
, "%lu", which
);
135 FAIL_IF_EXIT_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_SET_ONEXEC
),
136 "setting aspect on exec not copied across fork");
138 FAIL_IF_EXIT_MSG(mfspr(SPRN_DEXCR_RO
) & aspect
,
139 "setting aspect on exec wrongly applied to fork");
141 execve("/proc/self/exe", args
, NULL
);
144 await_child_success(pid
);
146 err
= pr_set_dexcr(which
, PR_PPC_DEXCR_CTRL_SET
| PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
);
147 FAIL_IF_MSG(err
, "PR_PPC_DEXCR_CTRL_SET | PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC failed");
151 char which_str
[32] = {};
152 char *args
[] = { "dexcr_prctl_onexec_test_child", which_str
, "clear", NULL
};
153 unsigned int ctrl
= pr_get_dexcr(which
);
155 sprintf(which_str
, "%lu", which
);
157 FAIL_IF_EXIT_MSG(!(ctrl
& PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC
),
158 "clearing aspect on exec not copied across fork");
160 FAIL_IF_EXIT_MSG(!(mfspr(SPRN_DEXCR_RO
) & aspect
),
161 "clearing aspect on exec wrongly applied to fork");
163 execve("/proc/self/exe", args
, NULL
);
166 await_child_success(pid
);
171 static int dexcr_prctl_ibrtpd_test(void)
173 return dexcr_prctl_aspect_test(PR_PPC_DEXCR_IBRTPD
);
176 static int dexcr_prctl_srapd_test(void)
178 return dexcr_prctl_aspect_test(PR_PPC_DEXCR_SRAPD
);
181 static int dexcr_prctl_nphie_test(void)
183 return dexcr_prctl_aspect_test(PR_PPC_DEXCR_NPHIE
);
186 int main(int argc
, char *argv
[])
191 * Some tests require checking what happens across exec, so we may be
192 * invoked as the child of a particular test
195 if (argc
== 3 && !strcmp(argv
[0], "dexcr_prctl_onexec_test_child")) {
198 err
= parse_ulong(argv
[1], strlen(argv
[1]), &which
, 10);
199 FAIL_IF_MSG(err
, "failed to parse which value for child");
201 return dexcr_prctl_onexec_test_child(which
, argv
[2]);
204 FAIL_IF_MSG(true, "unknown test case");
208 * Otherwise we are the main test invocation and run the full suite
210 err
|= test_harness(dexcr_prctl_ibrtpd_test
, "dexcr_prctl_ibrtpd");
211 err
|= test_harness(dexcr_prctl_srapd_test
, "dexcr_prctl_srapd");
212 err
|= test_harness(dexcr_prctl_nphie_test
, "dexcr_prctl_nphie");