Skip to content

Commit 7d0a670

Browse files
committed
segregate virtual page mapping from conceptual allocations
1 parent 9efbce8 commit 7d0a670

29 files changed

Lines changed: 128 additions & 159 deletions

File tree

api/arch/x86/paging.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <delegate>
2323
#include <util/bitops.hpp>
2424
#include <util/units.hpp>
25-
#include <kernel/memory.hpp>
25+
#include <mem/vmap.hpp>
2626
#include <cstdlib>
2727
#include <expects>
2828

api/mem/alloc.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef MEM_ALLOC_HPP
2+
#define MEM_ALLOC_HPP
3+
4+
#include <mem/alloc/buddy.hpp>
5+
#include <mem/allocator.hpp>
6+
7+
namespace os::mem {
8+
9+
using Raw_allocator = buddy::Alloc<false>;
10+
11+
/** Get default allocator for untyped allocations */
12+
Raw_allocator& raw_allocator();
13+
14+
template <typename T>
15+
using Typed_allocator = Allocator<T, Raw_allocator>;
16+
17+
/** Get default std::allocator for typed allocations */
18+
template <typename T>
19+
inline Typed_allocator<T> system_allocator() {
20+
return Typed_allocator<T>(raw_allocator());
21+
}
22+
23+
/** True once the heap is initialized and usable */
24+
bool heap_ready();
25+
26+
} // namespace os::mem
27+
28+
#endif // MEM_ALLOC_HPP
Lines changed: 76 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,18 @@
1-
// -*- C++ -*-
2-
// This file is a part of the IncludeOS unikernel - www.includeos.org
3-
//
4-
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
5-
// and Alfred Bratterud
6-
//
7-
// Licensed under the Apache License, Version 2.0 (the "License");
8-
// you may not use this file except in compliance with the License.
9-
// You may obtain a copy of the License at
10-
//
11-
// http://www.apache.org/licenses/LICENSE-2.0
12-
//
13-
// Unless required by applicable law or agreed to in writing, software
14-
// distributed under the License is distributed on an "AS IS" BASIS,
15-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16-
// See the License for the specific language governing permissions and
17-
// limitations under the License.
18-
19-
#ifndef MEM_MEMORY_HPP
20-
#define MEM_MEMORY_HPP
1+
#ifndef MEM_VMAP_HPP
2+
#define MEM_VMAP_HPP
213

224
#include <util/bitops.hpp>
235
#include <util/units.hpp>
24-
#include <mem/alloc/buddy.hpp>
25-
#include <mem/allocator.hpp>
266
#include <mem/flags.hpp>
27-
#include <sstream>
28-
#include <expects>
297
#include <mem/memmap.hpp>
8+
#include <expects>
9+
#include <algorithm>
10+
#include <cstdio>
11+
#include <stdexcept>
12+
#include <string>
3013

3114
namespace os::mem {
3215

33-
using Raw_allocator = buddy::Alloc<false>;
34-
35-
/** Get default allocator for untyped allocations */
36-
Raw_allocator& raw_allocator();
37-
38-
template <typename T>
39-
using Typed_allocator = Allocator<T, Raw_allocator>;
40-
41-
/** Get default std::allocator for typed allocations */
42-
template <typename T>
43-
Typed_allocator<T> system_allocator() { return Typed_allocator<T>(raw_allocator()); }
44-
4516
/** Get bitfield with bit set for each supported page size */
4617
uintptr_t supported_page_sizes();
4718

@@ -62,15 +33,14 @@ namespace os::mem {
6233
* For interfacing with the virtual memory API, e.g. mem::map / mem::protect.
6334
**/
6435
template <typename Fl = Access>
65-
struct Mapping
66-
{
36+
struct Mapping {
6737
static const size_t any_size;
6838

6939
uintptr_t lin = 0;
7040
uintptr_t phys = 0;
71-
Fl flags {};
72-
size_t size = 0;
73-
size_t page_sizes = 0;
41+
Fl flags {};
42+
size_t size = 0;
43+
size_t page_sizes = 0;
7444

7545
// Constructors
7646
Mapping() = default;
@@ -94,15 +64,13 @@ namespace os::mem {
9464
inline size_t max_psize() const noexcept;
9565

9666
std::string to_string() const;
97-
98-
}; // struct Mapping<>
67+
};
9968

10069
using Map = Mapping<>;
10170

10271
/** Exception class possibly used by various ::mem functions. **/
10372
class Memory_exception : public std::runtime_error
104-
{ using runtime_error::runtime_error; };
105-
73+
{ using std::runtime_error::runtime_error; };
10674

10775
/**
10876
* Map linear address to physical memory, according to provided Mapping.
@@ -123,7 +91,9 @@ namespace os::mem {
12391

12492
/** Determine active page size of a given linear address **/
12593
uintptr_t active_page_size(uintptr_t addr);
126-
uintptr_t active_page_size(void* addr);
94+
inline uintptr_t active_page_size(void* addr) {
95+
return active_page_size((uintptr_t) addr);
96+
}
12797

12898
/**
12999
* Set and return access flags for a given linear address range.
@@ -150,81 +120,70 @@ namespace os::mem {
150120
**/
151121
Access protect_page(uintptr_t linear, Access flags = Access::read);
152122

153-
154123
/** Get the physical address to which linear address is mapped **/
155124
uintptr_t virt_to_phys(uintptr_t linear);
156125

157-
void virtual_move(uintptr_t src, size_t size, uintptr_t dst, const char* label);
126+
inline void virtual_move(uintptr_t src, size_t size, uintptr_t dst, const char* label)
127+
{
128+
using namespace util::bitops;
129+
const auto flags = os::mem::Access::read | os::mem::Access::write;
130+
// setup @dst as new virt area for @src
131+
os::mem::map({dst, src, flags, size}, label);
132+
// unpresent @src
133+
os::mem::protect(src, size, os::mem::Access::none);
134+
}
158135

159136
/** Virtual memory map **/
160137
inline Memory_map& vmmap() {
161138
// TODO Move to machine
162139
static Memory_map memmap;
163140
return memmap;
164-
};
165-
166-
bool heap_ready();
167-
168-
} // os::mem
169-
170-
171-
172-
141+
}
173142

174143

175-
namespace os::mem {
176144

177145
//
178-
// mem::Mapping implementation
146+
// Mapping implementation
179147
//
180-
181148
template <typename Fl>
182-
Mapping<Fl>::Mapping(uintptr_t linear, uintptr_t physical, Fl fl, size_t sz)
183-
: lin{linear}, phys{physical}, flags{fl}, size{sz},
184-
page_sizes{any_size} {}
149+
inline Mapping<Fl>::Mapping(uintptr_t linear, uintptr_t physical, Fl fl, size_t sz)
150+
: lin{linear}, phys{physical}, flags{fl}, size{sz}, page_sizes{any_size} {}
185151

186152
template <typename Fl>
187-
Mapping<Fl>::Mapping(uintptr_t linear, uintptr_t physical, Fl fl, size_t sz, size_t psz)
188-
: lin{linear}, phys{physical}, flags{fl}, size{sz}, page_sizes{psz}
189-
{}
153+
inline Mapping<Fl>::Mapping(uintptr_t linear, uintptr_t physical, Fl fl, size_t sz, size_t psz)
154+
: lin{linear}, phys{physical}, flags{fl}, size{sz}, page_sizes{psz} {}
190155

191156
template <typename Fl>
192-
bool Mapping<Fl>::operator==(const Mapping& rhs) const noexcept
193-
{ return lin == rhs.lin
194-
&& phys == rhs.phys
195-
&& flags == rhs.flags
196-
&& size == rhs.size
197-
&& page_sizes == rhs.page_sizes; }
157+
inline bool Mapping<Fl>::operator==(const Mapping& rhs) const noexcept {
158+
return lin == rhs.lin
159+
&& phys == rhs.phys
160+
&& flags == rhs.flags
161+
&& size == rhs.size
162+
&& page_sizes == rhs.page_sizes;
163+
}
198164

199165
template <typename Fl>
200-
Mapping<Fl>::operator bool() const noexcept
201-
{ return size != 0 && page_sizes !=0; }
166+
inline Mapping<Fl>::operator bool() const noexcept {
167+
return size != 0 && page_sizes != 0;
168+
}
202169

203170
template <typename Fl>
204-
bool Mapping<Fl>::operator!=(const Mapping& rhs) const noexcept
205-
{ return ! (*this == rhs); }
171+
inline bool Mapping<Fl>::operator!=(const Mapping& rhs) const noexcept {
172+
return !(*this == rhs);
173+
}
206174

207175
template <typename Fl>
208-
Mapping<Fl> Mapping<Fl>::operator+(const Mapping& rhs) noexcept
209-
{
176+
inline Mapping<Fl> Mapping<Fl>::operator+(const Mapping& rhs) noexcept {
210177
using namespace util::bitops;
211178
Mapping res;
212179

213180
// Adding with empty map behaves like 0 + x / x + 0.
214-
if (! rhs) {
215-
return *this;
216-
}
217-
218-
if (! *this)
219-
return rhs;
220-
221-
if (res == rhs)
222-
return res;
181+
if (not rhs) return *this;
182+
if (not *this) return rhs;
183+
if (res == rhs) return res;
223184

224185
// The mappings must have connecting ranges
225-
if ((rhs.lin + rhs.size != lin)
226-
and lin + size != rhs.lin)
227-
{
186+
if ((rhs.lin + rhs.size != lin) and (lin + size != rhs.lin)) {
228187
Ensures(!res);
229188
return res;
230189
}
@@ -235,37 +194,35 @@ namespace os::mem {
235194

236195
// The mappings can span several page sizes
237196
res.page_sizes |= rhs.page_sizes;
238-
if (page_sizes && page_sizes != rhs.page_sizes)
239-
{
197+
if (page_sizes && page_sizes != rhs.page_sizes) {
240198
res.page_sizes |= page_sizes;
241199
}
242200

243-
res.size = size + rhs.size;
201+
res.size = size + rhs.size;
244202
res.flags = flags & rhs.flags;
245203

246-
if (rhs)
247-
Ensures(res);
248-
204+
if (rhs) Ensures(res);
249205
return res;
250206
}
251207

252208
template <typename Fl>
253-
Mapping<Fl> Mapping<Fl>::operator+=(const Mapping& rhs) noexcept {
209+
inline Mapping<Fl> Mapping<Fl>::operator+=(const Mapping& rhs) noexcept {
254210
*this = *this + rhs;
255211
return *this;
256212
}
257213

258214
template <typename Fl>
259-
size_t Mapping<Fl>::min_psize() const noexcept
260-
{ return util::bits::keepfirst(page_sizes); }
215+
inline size_t Mapping<Fl>::min_psize() const noexcept {
216+
return util::bits::keepfirst(page_sizes);
217+
}
261218

262219
template <typename Fl>
263-
size_t Mapping<Fl>::max_psize() const noexcept
264-
{ return util::bits::keeplast(page_sizes); }
220+
inline size_t Mapping<Fl>::max_psize() const noexcept {
221+
return util::bits::keeplast(page_sizes);
222+
}
265223

266224
template <typename Fl>
267-
inline std::string Mapping<Fl>::to_string() const
268-
{
225+
inline std::string Mapping<Fl>::to_string() const {
269226
using namespace util::literals;
270227
char buffer[1024];
271228
int len = snprintf(buffer, sizeof(buffer),
@@ -281,47 +238,35 @@ namespace os::mem {
281238
" (%lu pages á %s)",
282239
size / page_sizes,
283240
util::Byte_r(page_sizes).to_string().c_str());
284-
}
285-
else {
241+
} else {
286242
len += snprintf(buffer + len, sizeof(buffer) - len,
287243
" (page sizes: %s)", page_sizes_str(page_sizes).c_str());
288244
}
289-
290245
return std::string(buffer, len);
291246
}
292247

293-
inline std::string page_sizes_str(size_t bits)
294-
{
248+
inline std::string page_sizes_str(size_t bits) {
295249
using namespace util::literals;
296250
if (bits == 0) return "None";
297251

298252
std::string out;
299-
while (bits){
300-
auto ps = 1 << (__builtin_ffsl(bits) - 1);
301-
bits &= ~ps;
302-
out += util::Byte_r(ps).to_string();
303-
if (bits)
304-
out += ", ";
305-
}
253+
while (bits) {
254+
// index of lowest set bit (well-defined because bits != 0 here)
255+
const unsigned tz = std::countr_zero(bits);
306256

307-
return out;
308-
}
257+
// convert that bit to the corresponding power-of-two size
258+
const std::size_t ps = 1 << tz;
309259

310-
inline uintptr_t active_page_size(void* addr) {
311-
return active_page_size((uintptr_t) addr);
312-
}
260+
// and remove that bit from the input
261+
bits &= ~ps;
313262

314-
inline void
315-
virtual_move(uintptr_t src, size_t size, uintptr_t dst, const char* label)
316-
{
317-
using namespace util::bitops;
318-
const auto flags = os::mem::Access::read | os::mem::Access::write;
319-
// setup @dst as new virt area for @src
320-
os::mem::map({dst, src, flags, size}, label);
321-
// unpresent @src
322-
os::mem::protect(src, size, os::mem::Access::none);
263+
// append formatted size; add a comma if there are more bits left
264+
std::format_to(std::back_inserter(out), "{}", util::Byte_r(ps).to_string());
265+
if (bits) out += ", ";
266+
}
267+
return out;
323268
}
324-
}
325269

270+
} // namespace os::mem
326271

327-
#endif // MEM_MEMORY_HPP
272+
#endif // MEM_VMAP_HPP

api/util/typename.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
#include <hal/machine.hpp>
1919
#include <util/units.hpp>
20-
#include <kernel/memory.hpp>
20+
#include <mem/alloc.hpp>
2121
#include <string>
2222

2323
// Demangle

lib/LiveUpdate/src/os.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <kernel.hpp>
22
#include <os.hpp>
3-
#include <kernel/memory.hpp>
3+
#include <mem/vmap.hpp>
44

55
#define HIGHMEM_LOCATION (1ull << 45)
66
//#define LIU_DEBUG 1

lib/LiveUpdate/src/storage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "storage.hpp"
2222
#include <os.hpp>
2323
#include <kernel.hpp>
24-
#include <kernel/memory.hpp>
24+
#include <mem/vmap.hpp>
2525
#include <util/crc32.hpp>
2626
#include <cassert>
2727
//#define VERIFY_MEMORY

0 commit comments

Comments
 (0)