Skip to content

Commit 3c376c4

Browse files
committed
Code cleanup for remote access, prevent fault loop
1 parent e9b0cc2 commit 3c376c4

File tree

7 files changed

+15
-35
lines changed

7 files changed

+15
-35
lines changed

lib/tinykvm/common.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace tinykvm
4747
// Print profiling results. Side effect: *sorts vectors*
4848
// when user_defined is non-empty, it will use that label
4949
// instead of "UserDefined"
50-
void print(const char* user_defined = "");
50+
void print(const char* user_defined = "") const;
5151
// Clear all profiling samples
5252
void reset() {
5353
for (auto& vec : times)

lib/tinykvm/machine.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ struct Machine
149149
template <typename T> T* get_userdata() { return static_cast<T*> (m_userdata); }
150150

151151
std::string_view memory_at(uint64_t a, size_t s) const;
152-
template <typename T = char>
153-
T* rw_memory_at(uint64_t a, size_t s);
154152
bool memory_safe_at(uint64_t a, size_t s) const;
155153
char* unsafe_memory_at(uint64_t a, size_t s) { return memory.at(a, s); }
156154
uint64_t translate(uint64_t virt) const;

lib/tinykvm/machine_inline.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,6 @@ inline std::string_view Machine::memory_at(uint64_t a, size_t s) const
215215
{
216216
return memory.view(a, s);
217217
}
218-
template <typename T>
219-
inline T* Machine::rw_memory_at(uint64_t a, size_t s)
220-
{
221-
return (T*) memory.safely_at(a, s);
222-
}
223218
inline bool Machine::memory_safe_at(uint64_t a, size_t s) const
224219
{
225220
return memory.safely_within(a, s);

lib/tinykvm/machine_utils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ std::string Machine::memcstring(address_t src, size_t maxlen) const
637637
return result;
638638
}
639639

640-
void MachineProfiling::print(const char* user_defined) {
640+
void MachineProfiling::print(const char* user_defined) const {
641641
std::array<std::string, 7> locnames = {
642642
"vCPU Run",
643643
"Reset",
@@ -651,7 +651,7 @@ void MachineProfiling::print(const char* user_defined) {
651651
locnames[UserDefined] = user_defined;
652652
}
653653
for (size_t i = 0; i < locnames.size(); i++) {
654-
auto& vec = this->times[i];
654+
auto vec = this->times[i];
655655
if (vec.empty()) continue;
656656
// Sort the times to find min/max and median
657657
std::sort(vec.begin(), vec.end());

lib/tinykvm/memory.cpp

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,7 @@ uint64_t* vMemory::page_at(uint64_t addr) const
261261
}
262262
}
263263
/* Remote machine always last resort */
264-
if (machine.has_remote())
265-
{
264+
if (machine.has_remote()) {
266265
return machine.remote().main_memory().page_at(addr);
267266
}
268267
memory_exception("Memory::page_at() invalid region", addr, 4096);
@@ -278,21 +277,12 @@ char* vMemory::safely_at(uint64_t addr, size_t asize)
278277

279278
if (safely_within(addr, asize))
280279
return &ptr[addr - physbase];
280+
281281
/* Remote machine always last resort */
282-
if (machine.has_remote())
283-
{
282+
if (machine.has_remote()) {
284283
return machine.remote().main_memory().safely_at(addr, asize);
285284
}
286285

287-
/* Slow-path page walk */
288-
const auto pagebase = addr & ~PageMask();
289-
const auto offset = addr & PageMask();
290-
if (offset + asize <= vMemory::PageSize())
291-
{
292-
auto* page = this->get_writable_page(pagebase, expectedUsermodeFlags(), false, false);
293-
return &page[offset];
294-
}
295-
296286
memory_exception("Memory::safely_at() invalid region", addr, asize);
297287
}
298288
const char* vMemory::safely_at(uint64_t addr, size_t asize) const
@@ -306,20 +296,9 @@ const char* vMemory::safely_at(uint64_t addr, size_t asize) const
306296
}
307297
}
308298
/* Remote machine always last resort */
309-
if (machine.has_remote())
310-
{
299+
if (machine.has_remote()) {
311300
return machine.remote().main_memory().safely_at(addr, asize);
312301
}
313-
314-
/* Slow-path page walk */
315-
const auto pagebase = addr & ~PageMask();
316-
const auto offset = addr & PageMask();
317-
if (offset + asize <= vMemory::PageSize())
318-
{
319-
auto* page = this->get_userpage_at(pagebase);
320-
return &page[offset];
321-
}
322-
323302
memory_exception("Memory::safely_at() invalid region", addr, asize);
324303
}
325304
std::string_view vMemory::view(uint64_t addr, size_t asize) const {

lib/tinykvm/vcpu.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ namespace tinykvm
5656
void* timer_id = nullptr;
5757
uint64_t remote_return_address = 0;
5858
uint64_t remote_original_tls_base = 0;
59+
uint64_t remote_fault_address = 0;
5960
std::mutex* remote_serializer = nullptr;
6061

6162
private:

lib/tinykvm/vcpu_run.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,13 @@ long vCPU::run_once()
293293
WritablePageOptions zero_opts;
294294
zero_opts.zeroes = false;
295295
(void)writable_page_at(machine().remote().memory, addr, PDE64_USER | PDE64_RW, zero_opts);
296+
// Remember that this address caused a fault, so that we don't loop infinitely
297+
if (this->remote_fault_address == addr) {
298+
// This address already caused a fault
299+
this->handle_exception(intr);
300+
Machine::machine_exception("Remote VM page fault repeat on same address", intr);
301+
}
302+
this->remote_fault_address = addr;
296303
regs.rax = 0; /* Indicate that it was local */
297304
this->set_registers(regs);
298305
return KVM_EXIT_IO;

0 commit comments

Comments
 (0)