]>
Commit | Line | Data |
---|---|---|
d9a64523 A |
1 | /* |
2 | * Copyright (c) 2016 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 <vm/vm_page.h> | |
30 | #include <vm/pmap.h> | |
31 | #include <kern/ledger.h> | |
32 | #include <kern/thread.h> | |
33 | ||
34 | ||
35 | extern ledger_template_t task_ledger_template; | |
36 | ||
37 | kern_return_t test_pmap_enter_disconnect(unsigned int num_loops); | |
38 | kern_return_t test_pmap_iommu_disconnect(void); | |
39 | ||
40 | #define PMAP_TEST_VA (0xDEAD << PAGE_SHIFT) | |
41 | ||
42 | typedef struct { | |
43 | pmap_t pmap; | |
44 | volatile boolean_t stop; | |
45 | ppnum_t pn; | |
46 | } pmap_test_thread_args; | |
47 | ||
48 | static pmap_t | |
49 | pmap_create_wrapper() { | |
50 | pmap_t new_pmap = NULL; | |
51 | ledger_t ledger; | |
52 | assert(task_ledger_template != NULL); | |
53 | if ((ledger = ledger_instantiate(task_ledger_template, LEDGER_CREATE_ACTIVE_ENTRIES)) == NULL) | |
54 | return NULL; | |
55 | new_pmap = pmap_create(ledger, 0, FALSE); | |
56 | ledger_dereference(ledger); | |
57 | return new_pmap; | |
58 | } | |
59 | ||
60 | static void | |
61 | pmap_disconnect_thread(void *arg, wait_result_t __unused wres) { | |
62 | pmap_test_thread_args *args = arg; | |
63 | do { | |
64 | pmap_disconnect(args->pn); | |
65 | } while (!args->stop); | |
66 | thread_wakeup((event_t)args); | |
67 | } | |
68 | ||
69 | kern_return_t | |
70 | test_pmap_enter_disconnect(unsigned int num_loops) | |
71 | { | |
72 | kern_return_t kr = KERN_SUCCESS; | |
73 | thread_t disconnect_thread; | |
74 | pmap_t new_pmap = pmap_create_wrapper(); | |
75 | if (new_pmap == NULL) | |
76 | return KERN_FAILURE; | |
77 | vm_page_t m = vm_page_grab(); | |
78 | if (m == VM_PAGE_NULL) { | |
79 | pmap_destroy(new_pmap); | |
80 | return KERN_FAILURE; | |
81 | } | |
82 | ppnum_t phys_page = VM_PAGE_GET_PHYS_PAGE(m); | |
83 | pmap_test_thread_args args = {new_pmap, FALSE, phys_page}; | |
84 | kern_return_t res = kernel_thread_start(pmap_disconnect_thread, &args, &disconnect_thread); | |
85 | if (res) { | |
86 | pmap_destroy(new_pmap); | |
87 | vm_page_lock_queues(); | |
88 | vm_page_free(m); | |
89 | vm_page_unlock_queues(); | |
90 | return res; | |
91 | } | |
92 | thread_deallocate(disconnect_thread); | |
93 | ||
94 | while (num_loops-- != 0) { | |
95 | kr = pmap_enter(new_pmap, PMAP_TEST_VA, phys_page, | |
96 | VM_PROT_READ | VM_PROT_WRITE, VM_PROT_NONE, VM_WIMG_USE_DEFAULT, FALSE); | |
97 | assert(kr == KERN_SUCCESS); | |
98 | } | |
99 | ||
100 | assert_wait((event_t)&args, THREAD_UNINT); | |
101 | args.stop = TRUE; | |
102 | thread_block(THREAD_CONTINUE_NULL); | |
103 | ||
104 | pmap_remove(new_pmap, PMAP_TEST_VA, PMAP_TEST_VA + PAGE_SIZE); | |
105 | vm_page_lock_queues(); | |
106 | vm_page_free(m); | |
107 | vm_page_unlock_queues(); | |
108 | pmap_destroy(new_pmap); | |
109 | return KERN_SUCCESS; | |
110 | } | |
111 | ||
112 | kern_return_t | |
113 | test_pmap_iommu_disconnect(void) | |
114 | { | |
115 | return KERN_SUCCESS; | |
116 | } | |
117 |