@@ -93,27 +93,6 @@ using namespace std::string_literals;
93
93
94
94
static const auto throw_invalid_argument = [](const char *err) { throw std::invalid_argument{err}; };
95
95
96
- // / \brief Creates a memory address range.
97
- // / \param d Description of address range for use in error messages.
98
- // / \param start Target physical address where range starts.
99
- // / \param length Length of range, in bytes.
100
- // / \param f Flags for address range.
101
- // / \param backing_store Backing store configuration for range.
102
- // / \returns New address range with flags already set.
103
- // / \details If \p backing_store.data_filename is non-empty and file is large enough to back entire address range,
104
- // / return a memory-mapped range, otherwise use calloc.
105
- static inline auto make_memory_address_range (const std::string &d, uint64_t start, uint64_t length, pmas_flags flags,
106
- const backing_store_config &backing_store) {
107
- if (backing_store.data_filename .empty () && backing_store.shared ) {
108
- throw std::invalid_argument{" shared address range requires non-empty memory filename when initializing " + d};
109
- }
110
- if (backing_store.data_filename .empty () ||
111
- length > static_cast <uint64_t >(os_get_file_length (backing_store.data_filename .c_str ()))) {
112
- return make_callocd_memory_address_range (d, start, length, flags, backing_store.data_filename );
113
- }
114
- return make_mmapd_memory_address_range (d, start, length, flags, backing_store.data_filename , backing_store.shared );
115
- }
116
-
117
96
void machine::check_address_range (const address_range &ar, register_where where) {
118
97
if (!where.interpret && !where.merkle ) {
119
98
throw std::runtime_error{" address range " s + ar.get_description () + " must be registered somwhere" s};
@@ -158,8 +137,8 @@ void machine::replace_memory_range(const memory_range_config &config) {
158
137
}
159
138
// Replace range, preserving original flags.
160
139
// This will automatically start with all pages dirty.
161
- existing = make_moved_unique (make_memory_address_range ( existing->get_description (), existing->get_start (),
162
- existing->get_length (), existing->get_flags (), config.backing_store ) );
140
+ existing = make_moved_unique (memory_address_range{ existing->get_description (), existing->get_start (),
141
+ existing->get_length (), existing->get_flags (), config.backing_store , config. read_only } );
163
142
return ;
164
143
}
165
144
}
@@ -196,12 +175,12 @@ void machine::init_uarch(const uarch_config &c) {
196
175
constexpr auto ram_description = " uarch RAM" ;
197
176
if (c.ram .backing_store .data_filename .empty ()) {
198
177
m_us.ram = ®ister_address_range (
199
- make_callocd_memory_address_range ( ram_description, AR_UARCH_RAM_START, UARCH_RAM_LENGTH, uram_flags) ,
178
+ memory_address_range{ ram_description, AR_UARCH_RAM_START, UARCH_RAM_LENGTH, uram_flags} ,
200
179
register_where{.merkle = true , .interpret = false });
201
180
memcpy (m_us.ram ->get_host_memory (), uarch_pristine_ram, uarch_pristine_ram_len);
202
181
} else {
203
- m_us.ram = ®ister_address_range (make_memory_address_range ( ram_description, AR_UARCH_RAM_START,
204
- UARCH_RAM_LENGTH, uram_flags, c.ram .backing_store ) ,
182
+ m_us.ram = ®ister_address_range (memory_address_range{ ram_description, AR_UARCH_RAM_START, UARCH_RAM_LENGTH ,
183
+ uram_flags, c.ram .backing_store } ,
205
184
register_where{.merkle = true , .interpret = false });
206
185
}
207
186
}
@@ -291,25 +270,14 @@ void machine::init_ram_ar(const ram_config &ram) {
291
270
if (ram.length == 0 ) {
292
271
throw std::invalid_argument (" RAM length cannot be zero" );
293
272
}
294
- register_address_range (make_memory_address_range ( " RAM" s, AR_RAM_START, ram.length , ram_flags, ram.backing_store ) ,
273
+ register_address_range (memory_address_range{ " RAM" s, AR_RAM_START, ram.length , ram_flags, ram.backing_store } ,
295
274
register_where{.merkle = true , .interpret = true });
296
275
}
297
276
298
277
void machine::init_flash_drive_ars (flash_drive_configs &flash_drive) {
299
278
if (flash_drive.size () > FLASH_DRIVE_MAX) {
300
279
throw std::invalid_argument{" too many flash drives" };
301
280
}
302
- // Flags for flash drives
303
- static const pmas_flags flash_flags{
304
- .M = true ,
305
- .IO = false ,
306
- .R = true ,
307
- .W = true ,
308
- .X = false ,
309
- .IR = true ,
310
- .IW = true ,
311
- .DID = PMA_ISTART_DID::flash_drive,
312
- };
313
281
// Register all flash drives
314
282
int i = 0 ; // NOLINT(misc-const-correctness)
315
283
for (auto &f : flash_drive) {
@@ -341,8 +309,19 @@ void machine::init_flash_drive_ars(flash_drive_configs &flash_drive) {
341
309
}
342
310
f.length = length;
343
311
}
312
+ // Flags for flash drives
313
+ static const pmas_flags flash_flags{
314
+ .M = true ,
315
+ .IO = false ,
316
+ .R = true ,
317
+ .W = !f.read_only ,
318
+ .X = false ,
319
+ .IR = true ,
320
+ .IW = !f.read_only ,
321
+ .DID = PMA_ISTART_DID::flash_drive,
322
+ };
344
323
register_address_range (
345
- make_memory_address_range ( flash_description, f.start , f.length , flash_flags, f.backing_store ) ,
324
+ memory_address_range{ flash_description, f.start , f.length , flash_flags, f.backing_store , f. read_only } ,
346
325
register_where{.merkle = true , .interpret = true });
347
326
i++;
348
327
}
@@ -456,11 +435,11 @@ void machine::init_cmio_ars(const cmio_config &c) {
456
435
.IW = true ,
457
436
.DID = PMA_ISTART_DID::cmio_rx_buffer,
458
437
};
459
- register_address_range (make_memory_address_range ( " CMIO tx buffer memory range" s, AR_CMIO_TX_BUFFER_START,
460
- AR_CMIO_TX_BUFFER_LENGTH, tx_flags, c.tx_buffer .backing_store ) ,
438
+ register_address_range (memory_address_range{ " CMIO tx buffer memory range" s, AR_CMIO_TX_BUFFER_START,
439
+ AR_CMIO_TX_BUFFER_LENGTH, tx_flags, c.tx_buffer .backing_store } ,
461
440
register_where{.merkle = true , .interpret = true });
462
- register_address_range (make_memory_address_range ( " CMIO rx buffer memory range" s, AR_CMIO_RX_BUFFER_START,
463
- AR_CMIO_RX_BUFFER_LENGTH, rx_flags, c.rx_buffer .backing_store ) ,
441
+ register_address_range (memory_address_range{ " CMIO rx buffer memory range" s, AR_CMIO_RX_BUFFER_START,
442
+ AR_CMIO_RX_BUFFER_LENGTH, rx_flags, c.rx_buffer .backing_store } ,
464
443
register_where{.merkle = true , .interpret = true });
465
444
}
466
445
@@ -517,7 +496,7 @@ void machine::init_pmas_contents(const pmas_config &config, memory_address_range
517
496
518
497
void machine::init_tlb_contents (const tlb_config &config) {
519
498
if (const auto &image_filename = config.backing_store .data_filename ; !image_filename.empty ()) {
520
- auto shadow_tlb_ptr = make_unique_mmap<shadow_tlb_state>(image_filename. c_str (), 1 , false /* not shared */ );
499
+ auto shadow_tlb_ptr = make_unique_mmap<shadow_tlb_state>(1 , os_mmap_flags{}, image_filename );
521
500
auto &shadow_tlb = *shadow_tlb_ptr;
522
501
for (auto set_index : {TLB_CODE, TLB_READ, TLB_WRITE}) {
523
502
for (uint64_t slot_index = 0 ; slot_index < TLB_SET_SIZE; ++slot_index) {
@@ -550,7 +529,7 @@ static inline auto make_dtb_address_range(const dtb_config &config) {
550
529
.IW = true ,
551
530
.DID = PMA_ISTART_DID::memory,
552
531
};
553
- return make_memory_address_range ( " DTB" s, AR_DTB_START, AR_DTB_LENGTH, dtb_flags, config.backing_store ) ;
532
+ return memory_address_range{ " DTB" s, AR_DTB_START, AR_DTB_LENGTH, dtb_flags, config.backing_store } ;
554
533
}
555
534
556
535
void machine::init_dtb_contents (const machine_config &config, memory_address_range &dtb) {
@@ -570,7 +549,7 @@ static inline auto make_pmas_address_range(const pmas_config &config) {
570
549
.IW = false ,
571
550
.DID = PMA_ISTART_DID::memory,
572
551
};
573
- return make_memory_address_range ( " PMAs" , AR_PMAS_START, AR_PMAS_LENGTH, m_pmas_flags, config.backing_store ) ;
552
+ return memory_address_range{ " PMAs" , AR_PMAS_START, AR_PMAS_LENGTH, m_pmas_flags, config.backing_store } ;
574
553
}
575
554
576
555
// ??D It is best to leave the std::move() on r because it may one day be necessary!
@@ -2190,6 +2169,9 @@ void machine::write_memory(uint64_t paddr, const unsigned char *data, uint64_t l
2190
2169
if (!ar.is_memory ()) {
2191
2170
throw std::invalid_argument{" address range to write is not entirely in single memory range" };
2192
2171
}
2172
+ if (ar.is_host_read_only ()) {
2173
+ throw std::invalid_argument{" address range is read-only in the host" };
2174
+ }
2193
2175
if (is_protected (ar.get_driver_id ())) {
2194
2176
throw std::invalid_argument{" attempt to write to protected memory range" };
2195
2177
}
@@ -2216,6 +2198,9 @@ void machine::fill_memory(uint64_t paddr, uint8_t val, uint64_t length) {
2216
2198
if (!ar.is_memory ()) {
2217
2199
throw std::invalid_argument{" address range to fill is not entirely in memory PMA" };
2218
2200
}
2201
+ if (ar.is_host_read_only ()) {
2202
+ throw std::invalid_argument{" address range is read-only in the host" };
2203
+ }
2219
2204
if (is_protected (ar.get_driver_id ())) {
2220
2205
throw std::invalid_argument{" attempt fill to protected memory range" };
2221
2206
}
@@ -2346,7 +2331,7 @@ void machine::write_word(uint64_t paddr, uint64_t val) {
2346
2331
<< std::dec << paddr << " )" ;
2347
2332
throw std::runtime_error{err.str ()};
2348
2333
}
2349
- if (!ar.is_writeable ()) {
2334
+ if (!ar.is_writeable () || ar. is_host_read_only () ) {
2350
2335
std::ostringstream err;
2351
2336
err << " attempted memory write to read-only " << ar.get_description () << " at address 0x" << std::hex << paddr
2352
2337
<< " (" << std::dec << paddr << " )" ;
@@ -2531,7 +2516,7 @@ interpreter_break_reason machine::log_step(uint64_t mcycle_count, const std::str
2531
2516
interpreter_break_reason machine::verify_step (const hash_type &root_hash_before, const std::string &filename,
2532
2517
uint64_t mcycle_count, const hash_type &root_hash_after) {
2533
2518
auto data_length = os_get_file_length (filename.c_str (), " step log file" );
2534
- auto data = make_unique_mmap<unsigned char >(filename. c_str (), data_length, false /* not shared */ );
2519
+ auto data = make_unique_mmap<unsigned char >(data_length, os_mmap_flags{}, filename );
2535
2520
replay_step_state_access::context context;
2536
2521
replay_step_state_access a (context, data.get (), data_length, root_hash_before);
2537
2522
uint64_t mcycle_end{};
0 commit comments