summaryrefslogtreecommitdiff
path: root/Kernel/VM
diff options
context:
space:
mode:
Diffstat (limited to 'Kernel/VM')
-rw-r--r--Kernel/VM/InodeVMObject.cpp2
-rw-r--r--Kernel/VM/InodeVMObject.h2
-rw-r--r--Kernel/VM/MemoryManager.cpp33
-rw-r--r--Kernel/VM/MemoryManager.h6
-rw-r--r--Kernel/VM/Region.cpp30
-rw-r--r--Kernel/VM/Region.h1
6 files changed, 28 insertions, 46 deletions
diff --git a/Kernel/VM/InodeVMObject.cpp b/Kernel/VM/InodeVMObject.cpp
index 8c5b07d413..c63417fab0 100644
--- a/Kernel/VM/InodeVMObject.cpp
+++ b/Kernel/VM/InodeVMObject.cpp
@@ -89,7 +89,7 @@ void InodeVMObject::inode_size_changed(Badge<Inode>, size_t old_size, size_t new
});
}
-void InodeVMObject::inode_contents_changed(Badge<Inode>, off_t offset, ssize_t size, const u8* data)
+void InodeVMObject::inode_contents_changed(Badge<Inode>, off_t offset, ssize_t size, const UserOrKernelBuffer& data)
{
(void)size;
(void)data;
diff --git a/Kernel/VM/InodeVMObject.h b/Kernel/VM/InodeVMObject.h
index 727199ff7e..94e7073709 100644
--- a/Kernel/VM/InodeVMObject.h
+++ b/Kernel/VM/InodeVMObject.h
@@ -39,7 +39,7 @@ public:
Inode& inode() { return *m_inode; }
const Inode& inode() const { return *m_inode; }
- void inode_contents_changed(Badge<Inode>, off_t, ssize_t, const u8*);
+ void inode_contents_changed(Badge<Inode>, off_t, ssize_t, const UserOrKernelBuffer&);
void inode_size_changed(Badge<Inode>, size_t old_size, size_t new_size);
size_t amount_dirty() const;
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp
index 88bb451435..fc5114f296 100644
--- a/Kernel/VM/MemoryManager.cpp
+++ b/Kernel/VM/MemoryManager.cpp
@@ -767,39 +767,6 @@ bool MemoryManager::validate_user_stack(const Process& process, VirtualAddress v
return region && region->is_user_accessible() && region->is_stack();
}
-bool MemoryManager::validate_kernel_read(const Process& process, VirtualAddress vaddr, size_t size) const
-{
- ScopedSpinLock lock(s_mm_lock);
- return validate_range<AccessSpace::Kernel, AccessType::Read>(process, vaddr, size);
-}
-
-bool MemoryManager::can_read_without_faulting(const Process& process, VirtualAddress vaddr, size_t size) const
-{
- // FIXME: Use the size argument!
- UNUSED_PARAM(size);
- ScopedSpinLock lock(s_mm_lock);
- auto* pte = const_cast<MemoryManager*>(this)->pte(process.page_directory(), vaddr);
- if (!pte)
- return false;
- return pte->is_present();
-}
-
-bool MemoryManager::validate_user_read(const Process& process, VirtualAddress vaddr, size_t size) const
-{
- if (!is_user_address(vaddr))
- return false;
- ScopedSpinLock lock(s_mm_lock);
- return validate_range<AccessSpace::User, AccessType::Read>(process, vaddr, size);
-}
-
-bool MemoryManager::validate_user_write(const Process& process, VirtualAddress vaddr, size_t size) const
-{
- if (!is_user_address(vaddr))
- return false;
- ScopedSpinLock lock(s_mm_lock);
- return validate_range<AccessSpace::User, AccessType::Write>(process, vaddr, size);
-}
-
void MemoryManager::register_vmobject(VMObject& vmobject)
{
ScopedSpinLock lock(s_mm_lock);
diff --git a/Kernel/VM/MemoryManager.h b/Kernel/VM/MemoryManager.h
index f3f4bbb90c..d9823377ab 100644
--- a/Kernel/VM/MemoryManager.h
+++ b/Kernel/VM/MemoryManager.h
@@ -100,12 +100,6 @@ public:
void enter_process_paging_scope(Process&);
bool validate_user_stack(const Process&, VirtualAddress) const;
- bool validate_user_read(const Process&, VirtualAddress, size_t) const;
- bool validate_user_write(const Process&, VirtualAddress, size_t) const;
-
- bool validate_kernel_read(const Process&, VirtualAddress, size_t) const;
-
- bool can_read_without_faulting(const Process&, VirtualAddress, size_t) const;
enum class ShouldZeroFill {
No,
diff --git a/Kernel/VM/Region.cpp b/Kernel/VM/Region.cpp
index d3b4d02676..a1d39daf24 100644
--- a/Kernel/VM/Region.cpp
+++ b/Kernel/VM/Region.cpp
@@ -439,13 +439,24 @@ PageFaultResponse Region::handle_cow_fault(size_t page_index_in_region)
klog() << "MM: handle_cow_fault was unable to allocate a physical page";
return PageFaultResponse::OutOfMemory;
}
- auto physical_page_to_copy = move(page_slot);
+
u8* dest_ptr = MM.quickmap_page(*page);
const u8* src_ptr = vaddr().offset(page_index_in_region * PAGE_SIZE).as_ptr();
#ifdef PAGE_FAULT_DEBUG
- dbg() << " >> COW " << page->paddr() << " <- " << physical_page_to_copy->paddr();
+ dbg() << " >> COW " << page->paddr() << " <- " << page_slot->paddr();
#endif
- copy_from_user(dest_ptr, src_ptr, PAGE_SIZE);
+ {
+ SmapDisabler disabler;
+ void* fault_at;
+ if (!safe_memcpy(dest_ptr, src_ptr, PAGE_SIZE, fault_at)) {
+ if ((u8*)fault_at >= dest_ptr && (u8*)fault_at <= dest_ptr + PAGE_SIZE)
+ dbg() << " >> COW: error copying page " << page_slot->paddr() << "/" << VirtualAddress(src_ptr) << " to " << page->paddr() << "/" << VirtualAddress(dest_ptr) << ": failed to write to page at " << VirtualAddress(fault_at);
+ else if ((u8*)fault_at >= src_ptr && (u8*)fault_at <= src_ptr + PAGE_SIZE)
+ dbg() << " >> COW: error copying page " << page_slot->paddr() << "/" << VirtualAddress(src_ptr) << " to " << page->paddr() << "/" << VirtualAddress(dest_ptr) << ": failed to read from page at " << VirtualAddress(fault_at);
+ else
+ ASSERT_NOT_REACHED();
+ }
+ }
page_slot = move(page);
MM.unquickmap_page();
set_should_cow(page_index_in_region, false);
@@ -489,7 +500,8 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region)
sti();
u8 page_buffer[PAGE_SIZE];
auto& inode = inode_vmobject.inode();
- auto nread = inode.read_bytes((first_page_index() + page_index_in_region) * PAGE_SIZE, PAGE_SIZE, page_buffer, nullptr);
+ auto buffer = UserOrKernelBuffer::for_kernel_buffer(page_buffer);
+ auto nread = inode.read_bytes((first_page_index() + page_index_in_region) * PAGE_SIZE, PAGE_SIZE, buffer, nullptr);
if (nread < 0) {
klog() << "MM: handle_inode_fault had error (" << nread << ") while reading!";
return PageFaultResponse::ShouldCrash;
@@ -506,7 +518,15 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region)
}
u8* dest_ptr = MM.quickmap_page(*vmobject_physical_page_entry);
- memcpy(dest_ptr, page_buffer, PAGE_SIZE);
+ {
+ void* fault_at;
+ if (!safe_memcpy(dest_ptr, page_buffer, PAGE_SIZE, fault_at)) {
+ if ((u8*)fault_at >= dest_ptr && (u8*)fault_at <= dest_ptr + PAGE_SIZE)
+ dbg() << " >> inode fault: error copying data to " << vmobject_physical_page_entry->paddr() << "/" << VirtualAddress(dest_ptr) << ", failed at " << VirtualAddress(fault_at);
+ else
+ ASSERT_NOT_REACHED();
+ }
+ }
MM.unquickmap_page();
remap_page(page_index_in_region);
diff --git a/Kernel/VM/Region.h b/Kernel/VM/Region.h
index 5480e186de..68d40e53c3 100644
--- a/Kernel/VM/Region.h
+++ b/Kernel/VM/Region.h
@@ -79,6 +79,7 @@ public:
unsigned access() const { return m_access; }
void set_name(const String& name) { m_name = name; }
+ void set_name(String&& name) { m_name = move(name); }
const VMObject& vmobject() const { return *m_vmobject; }
VMObject& vmobject() { return *m_vmobject; }