source: mainline/kernel/generic/src/mm/backend_user.c@ eadaeae8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since eadaeae8 was eadaeae8, checked in by Jakub Jermar <jakub@…>, 7 years ago

Make capability handles type-safe

Define distinct pointer types for the handles of the supported
capability types and use them instead of integer handles. This makes it
virtually impossible to pass a non-handle or a handle of different type
instead of the proper handle. Also turn cap_handle_t into an "untyped"
capability handle that can be assigned to and from the "typed" handles.

This commit also fixes a bug in msim-con driver, which wrongly used the
IRQ number instead of the IRQ capability handle to unregister the IRQ.

This commit also fixes the wrong use of the capability handle instead
of error code in libusbhost.

  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[75b139f]1/*
2 * Copyright (c) 2016 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup genericmm
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Backend for address space areas backed by the user pager.
36 *
37 */
38
39#include <mm/as.h>
40#include <mm/page.h>
[d078c9b9]41#include <mm/frame.h>
[ae6021d]42#include <abi/mm/as.h>
[5c2af75]43#include <abi/ipc/methods.h>
44#include <ipc/sysipc.h>
[75b139f]45#include <synch/mutex.h>
46#include <typedefs.h>
47#include <align.h>
[63e27ef]48#include <assert.h>
[5c2af75]49#include <errno.h>
50#include <log.h>
[62ca560]51#include <str.h>
[75b139f]52
53static bool user_create(as_area_t *);
54static void user_destroy(as_area_t *);
55
56static bool user_is_resizable(as_area_t *);
57static bool user_is_shareable(as_area_t *);
58
59static int user_page_fault(as_area_t *, uintptr_t, pf_access_t);
60static void user_frame_free(as_area_t *, uintptr_t, uintptr_t);
61
62mem_backend_t user_backend = {
63 .create = user_create,
[d078c9b9]64 .resize = NULL,
65 .share = NULL,
[75b139f]66 .destroy = user_destroy,
67
68 .is_resizable = user_is_resizable,
69 .is_shareable = user_is_shareable,
70
71 .page_fault = user_page_fault,
72 .frame_free = user_frame_free,
73
74 .create_shared_data = NULL,
75 .destroy_shared_data = NULL
76};
77
78bool user_create(as_area_t *area)
79{
80 return true;
81}
82
83void user_destroy(as_area_t *area)
84{
85 return;
86}
87
88bool user_is_resizable(as_area_t *area)
89{
[d078c9b9]90 return false;
[75b139f]91}
92
93bool user_is_shareable(as_area_t *area)
94{
[d078c9b9]95 return false;
[75b139f]96}
97
98/** Service a page fault in the user-paged address space area.
99 *
100 * The address space area and page tables must be already locked.
101 *
102 * @param area Pointer to the address space area.
103 * @param upage Faulting virtual page.
104 * @param access Access mode that caused the fault (i.e. read/write/exec).
105 *
106 * @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e.
107 * serviced).
108 */
109int user_page_fault(as_area_t *area, uintptr_t upage, pf_access_t access)
110{
[63e27ef]111 assert(page_table_locked(AS));
112 assert(mutex_locked(&area->lock));
113 assert(IS_ALIGNED(upage, PAGE_SIZE));
[75b139f]114
[5c2af75]115 if (!as_area_check_access(area, access))
116 return AS_PF_FAULT;
117
[ae6021d]118 as_area_pager_info_t *pager_info = &area->backend_data.pager_info;
119
[5c2af75]120 ipc_data_t data = {};
121 IPC_SET_IMETHOD(data, IPC_M_PAGE_IN);
122 IPC_SET_ARG1(data, upage - area->base);
123 IPC_SET_ARG2(data, PAGE_SIZE);
[ae6021d]124 IPC_SET_ARG3(data, pager_info->id1);
125 IPC_SET_ARG4(data, pager_info->id2);
126 IPC_SET_ARG5(data, pager_info->id3);
[5c2af75]127
[b7fd2a0]128 errno_t rc = ipc_req_internal(pager_info->pager, &data, (sysarg_t) true);
[5c2af75]129
130 if (rc != EOK) {
131 log(LF_USPACE, LVL_FATAL,
[35ebd42]132 "Page-in request for page %#" PRIxPTR
[eadaeae8]133 " at pager %p failed with error %s.",
[62ca560]134 upage, pager_info->pager, str_error_name(rc));
[5c2af75]135 return AS_PF_FAULT;
136 }
137
138 if (IPC_GET_RETVAL(data) != EOK)
139 return AS_PF_FAULT;
140
141 /*
142 * A successful reply will contain the physical frame in ARG1.
143 * The physical frame will have the reference count already
[9befb0d]144 * incremented (if applicable).
[5c2af75]145 */
146
147 uintptr_t frame = IPC_GET_ARG1(data);
148 page_mapping_insert(AS, upage, frame, as_area_get_flags(area));
149 if (!used_space_insert(area, upage, 1))
150 panic("Cannot insert used space.");
151
152 return AS_PF_OK;
[75b139f]153}
154
155/** Free a frame that is backed by the user memory backend.
156 *
157 * The address space area and page tables must be already locked.
158 *
159 * @param area Ignored.
160 * @param page Virtual address of the page corresponding to the frame.
161 * @param frame Frame to be released.
162 */
163void user_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
164{
[63e27ef]165 assert(page_table_locked(area->as));
166 assert(mutex_locked(&area->lock));
[d078c9b9]167
168 pfn_t pfn = ADDR2PFN(frame);
169 if (find_zone(pfn, 1, 0) != (size_t) -1) {
170 frame_free(frame, 1);
171 } else {
172 /* Nothing to do */
173 }
[a35b458]174
[75b139f]175}
176
177/** @}
178 */
Note: See TracBrowser for help on using the repository browser.