xref: /xnu-12377.1.9/tests/unit/panic_path_test.c (revision f6217f891ac0bb64f3d375211650a4c1ff8ca1ea)
1 /*
2  * Copyright (c) 2000-2024 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #include <darwintest.h>
30 #include "mocks/unit_test_utils.h"
31 #include "mocks/mock_pmap.h"
32 
33 #include <kdp/output_stages/output_stages.h>
34 #include <kdp/kdp_core.h>
35 #include <vm/pmap.h>
36 #include <arm/pmap_public.h>
37 #include <sys/queue.h>
38 
39 #define UT_MODULE osfmk
40 
41 kern_return_t
42 memory_backing_aware_buffer_stage_outproc(
43 	struct kdp_output_stage *stage,
44 	unsigned int request,
45 	char *corename,
46 	uint64_t length,
47 	void * panic_data);
48 
49 static kern_return_t
kosf_outproc_mock(__unused struct kdp_output_stage * stage,__unused unsigned int request,__unused char * corename,__unused uint64_t length,__unused void * panic_data)50 kosf_outproc_mock(
51 	__unused struct kdp_output_stage *stage,
52 	__unused unsigned int request,
53 	__unused char *corename,
54 	__unused uint64_t length,
55 	__unused void *panic_data
56 	)
57 {
58 	return KERN_SUCCESS;
59 }
60 
61 T_GLOBAL_META(
62 	T_META_NAMESPACE("xnu.unit.panic_path_test"),
63 	T_META_RADAR_COMPONENT_NAME("xnu"),
64 	T_META_OWNER("e_zisman"),
65 	T_META_RUN_CONCURRENTLY(false)
66 	);
67 
68 T_DECL(xnu_osfmk_kdp_memory_backing_aware_buffer_stage_outproc, "memory_backing_aware_buffer_stage_outproc")
69 {
70 	// No need to actually fill with data.
71 	char panic_data[18 * 1024] __attribute__((aligned));
72 
73 	STAILQ_HEAD(, kdp_output_stage) stages;
74 	struct kdp_output_stage stage1;
75 	struct kdp_output_stage stage2;
76 	char data1[32];
77 	char data2[32];
78 
79 	stage1.kos_data = data1;
80 	stage2.kos_data = data2;
81 	stage1.kos_funcs.kosf_outproc = kosf_outproc_mock;
82 	stage2.kos_funcs.kosf_outproc = kosf_outproc_mock;
83 
84 	STAILQ_INIT(&stages);
85 	STAILQ_INSERT_HEAD(&stages, &stage1, kos_next);
86 	STAILQ_INSERT_TAIL(&stages, &stage2, kos_next);
87 
88 	struct {
89 		char *test_name;
90 		unsigned int pmap_cache_attributes_retval;
91 		size_t panic_data_length;
92 		kern_return_t expected;
93 	} test_cases[] = {
94 		{
95 			.test_name = "normal memory flow",
96 			.pmap_cache_attributes_retval = 0x02, // VM_WIMG_DEFAULT
97 			.panic_data_length = sizeof(panic_data),
98 			.expected = KERN_SUCCESS
99 		},
100 		{
101 			.test_name = "not-normal memory flow, 4-byte reads",
102 			.pmap_cache_attributes_retval = 0x00,
103 			.panic_data_length = sizeof(panic_data),
104 			.expected = KERN_SUCCESS
105 		},
106 		{
107 			.test_name = "not-normal memory flow, 1-byte reads",
108 			.pmap_cache_attributes_retval = 0x00,
109 			.panic_data_length = sizeof(panic_data) - 1, // ensure length of panic data is not aligned to 4 bytes.
110 			.expected = KERN_SUCCESS
111 		},
112 	};
113 
114 	T_MOCK_SET_RETVAL(kvtophys, pmap_paddr_t, 0x12345678); // arbitrary value; isn't used anyways since we mock pmap_cache_attributes.
115 
116 	for (size_t i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
117 		T_MOCK_SET_RETVAL(pmap_cache_attributes, unsigned int, test_cases[i].pmap_cache_attributes_retval);
118 
119 		T_EXPECT_EQ(
120 			test_cases[i].expected,
121 			memory_backing_aware_buffer_stage_outproc(&stage1, KDP_DATA, "corename", sizeof(panic_data), panic_data),
122 			"return value matches expectation"
123 			);
124 	}
125 }
126