xref: /xnu-12377.81.4/tests/vm/vectorupl.c (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796)
1 /*
2  * Copyright (c) 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 
30 #include <darwintest.h>
31 #include <darwintest_utils.h>
32 
33 #include <stdlib.h>
34 
35 T_GLOBAL_META(
36 	T_META_NAMESPACE("xnu.vm"),
37 	T_META_RADAR_COMPONENT_NAME("xnu"),
38 	T_META_RADAR_COMPONENT_VERSION("VM"),
39 	T_META_OWNER("jharmening"),
40 	T_META_CHECK_LEAKS(false),
41 	T_META_RUN_CONCURRENTLY(true));
42 
43 #define NUM_IOVS 7
44 
45 T_DECL(vm_vector_upl,
46     "Test for vector UPLs",
47     T_META_TAG_VM_PREFERRED)
48 {
49 	struct {
50 		uint64_t base;
51 		uint32_t len;
52 	} w_iovs[NUM_IOVS];
53 	int64_t expected_bytes;
54 	int w, w_idx;
55 
56 	T_SETUPBEGIN;
57 	expected_bytes = 0;
58 	for (w = 0; w < NUM_IOVS; w++) {
59 		w_iovs[w].len = (uint32_t) ((w + 1) * (int)PAGE_SIZE);
60 		void *iov_base;
61 		T_QUIET; T_ASSERT_POSIX_SUCCESS(posix_memalign(&iov_base, PAGE_SIZE, w_iovs[w].len), "alloc(w_iov_base[%d])", w);
62 		memset(iov_base, 'a' + w, w_iovs[w].len);
63 		w_iovs[w].base = (uint64_t)iov_base;
64 		expected_bytes += w_iovs[w].len;
65 	}
66 	T_SETUPEND;
67 
68 	struct {
69 		uint64_t iov;
70 		uint16_t iovcnt;
71 	} arg;
72 
73 	arg.iov = (uint64_t) &w_iovs[0];
74 	arg.iovcnt = NUM_IOVS;
75 
76 	int64_t addr = (int64_t)&arg;
77 	int64_t result = 0;
78 	size_t s = sizeof(result);
79 	T_ASSERT_POSIX_SUCCESS(sysctlbyname("debug.test.vm_vector_upl", &result, &s, &addr, sizeof(addr)),
80 	    "sysctlbyname(debug.test.vm_vector_upl)");
81 
82 	T_EXPECT_EQ_LLONG(result, expected_bytes, "sysctl output");
83 
84 	w = 0;
85 	w_idx = 0;
86 
87 	/* Validate that the kernel sysctl handler mapped and mutated the page contents as expected. */
88 	for (w = 0; w < NUM_IOVS; w++) {
89 		char *iov_base = (char*)w_iovs[w].base;
90 		for (w_idx = 0; w_idx < w_iovs[w].len; w_idx++) {
91 			T_QUIET; T_ASSERT_EQ(iov_base[w_idx], 'a' + w + 1,
92 			    "w_iovs[%d].iov_base[%d]='%c' == '%c'",
93 			    w, w_idx, (unsigned char)iov_base[w_idx], (unsigned char)('a' + w + 1));
94 		}
95 	}
96 
97 	T_PASS("%s", __FUNCTION__);
98 }
99