mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 06:47:34 +00:00
Kernel+Userland: Remove shared buffers (shbufs)
All users of this mechanism have been switched to anonymous files and passing file descriptors with sendfd()/recvfd(). Shbufs got us where we are today, but it's time we say good-bye to them and welcome a much more idiomatic replacement. :^)
This commit is contained in:
parent
2cd16778b5
commit
bf0719092f
28 changed files with 2 additions and 1022 deletions
|
@ -3,7 +3,6 @@ set(SOURCES
|
|||
MallocTracer.cpp
|
||||
MmapRegion.cpp
|
||||
Region.cpp
|
||||
SharedBufferRegion.cpp
|
||||
SimpleRegion.cpp
|
||||
SoftCPU.cpp
|
||||
SoftMMU.cpp
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "Emulator.h"
|
||||
#include "MmapRegion.h"
|
||||
#include "SharedBufferRegion.h"
|
||||
#include "SimpleRegion.h"
|
||||
#include "SoftCPU.h"
|
||||
#include <AK/Format.h>
|
||||
|
@ -385,14 +384,6 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
|
|||
return virt$ioctl(arg1, arg2, arg3);
|
||||
case SC_get_dir_entries:
|
||||
return virt$get_dir_entries(arg1, arg2, arg3);
|
||||
case SC_shbuf_create:
|
||||
return virt$shbuf_create(arg1, arg2);
|
||||
case SC_shbuf_allow_pid:
|
||||
return virt$shbuf_allow_pid(arg1, arg2);
|
||||
case SC_shbuf_get:
|
||||
return virt$shbuf_get(arg1, arg2);
|
||||
case SC_shbuf_release:
|
||||
return virt$shbuf_release(arg1);
|
||||
case SC_profiling_enable:
|
||||
return virt$profiling_enable(arg1);
|
||||
case SC_profiling_disable:
|
||||
|
@ -560,48 +551,6 @@ int Emulator::virt$recvfd(int socket)
|
|||
return syscall(SC_recvfd, socket);
|
||||
}
|
||||
|
||||
int Emulator::virt$shbuf_create(int size, FlatPtr buffer)
|
||||
{
|
||||
u8* host_data = nullptr;
|
||||
int shbuf_id = syscall(SC_shbuf_create, size, &host_data);
|
||||
if (shbuf_id < 0)
|
||||
return shbuf_id;
|
||||
FlatPtr address = allocate_vm(size, PAGE_SIZE);
|
||||
auto region = SharedBufferRegion::create_with_shbuf_id(address, size, shbuf_id, host_data);
|
||||
m_mmu.add_region(move(region));
|
||||
m_mmu.copy_to_vm(buffer, &address, sizeof(address));
|
||||
return shbuf_id;
|
||||
}
|
||||
|
||||
FlatPtr Emulator::virt$shbuf_get(int shbuf_id, FlatPtr size_ptr)
|
||||
{
|
||||
size_t host_size = 0;
|
||||
void* host_data = (void*)syscall(SC_shbuf_get, shbuf_id, &host_size);
|
||||
if (host_data == (void*)-1)
|
||||
return (FlatPtr)host_data;
|
||||
FlatPtr address = allocate_vm(host_size, PAGE_SIZE);
|
||||
auto region = SharedBufferRegion::create_with_shbuf_id(address, host_size, shbuf_id, (u8*)host_data);
|
||||
m_mmu.add_region(move(region));
|
||||
m_mmu.copy_to_vm(size_ptr, &host_size, sizeof(host_size));
|
||||
return address;
|
||||
}
|
||||
|
||||
int Emulator::virt$shbuf_allow_pid(int shbuf_id, pid_t peer_pid)
|
||||
{
|
||||
auto* region = m_mmu.shbuf_region(shbuf_id);
|
||||
ASSERT(region);
|
||||
return region->allow_pid(peer_pid);
|
||||
}
|
||||
|
||||
int Emulator::virt$shbuf_release(int shbuf_id)
|
||||
{
|
||||
auto* region = m_mmu.shbuf_region(shbuf_id);
|
||||
ASSERT(region);
|
||||
auto rc = region->release();
|
||||
m_mmu.remove_region(*region);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int Emulator::virt$profiling_enable(pid_t pid)
|
||||
{
|
||||
return syscall(SC_profiling_enable, pid);
|
||||
|
|
|
@ -91,10 +91,6 @@ private:
|
|||
int virt$stat(FlatPtr);
|
||||
int virt$realpath(FlatPtr);
|
||||
int virt$gethostname(FlatPtr, ssize_t);
|
||||
int virt$shbuf_create(int size, FlatPtr buffer);
|
||||
int virt$shbuf_allow_pid(int, pid_t peer_pid);
|
||||
FlatPtr virt$shbuf_get(int shbuf_id, FlatPtr size);
|
||||
int virt$shbuf_release(int shbuf_id);
|
||||
int virt$profiling_enable(pid_t);
|
||||
int virt$profiling_disable(pid_t);
|
||||
int virt$disown(pid_t);
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "SharedBufferRegion.h"
|
||||
#include "Emulator.h"
|
||||
#include <Kernel/API/Syscall.h>
|
||||
#include <serenity.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace UserspaceEmulator {
|
||||
|
||||
NonnullOwnPtr<SharedBufferRegion> SharedBufferRegion::create_with_shbuf_id(u32 base, u32 size, int shbuf_id, u8* host_data)
|
||||
{
|
||||
return adopt_own(*new SharedBufferRegion(base, size, shbuf_id, host_data));
|
||||
}
|
||||
|
||||
SharedBufferRegion::SharedBufferRegion(u32 base, u32 size, int shbuf_id, u8* host_data)
|
||||
: Region(base, size)
|
||||
, m_data(host_data)
|
||||
, m_shbuf_id(shbuf_id)
|
||||
{
|
||||
m_shadow_data = (u8*)malloc(size);
|
||||
memset(m_shadow_data, 1, size);
|
||||
}
|
||||
|
||||
SharedBufferRegion::~SharedBufferRegion()
|
||||
{
|
||||
free(m_shadow_data);
|
||||
}
|
||||
|
||||
ValueWithShadow<u8> SharedBufferRegion::read8(FlatPtr offset)
|
||||
{
|
||||
ASSERT(offset < size());
|
||||
return { *reinterpret_cast<const u8*>(m_data + offset), *reinterpret_cast<const u8*>(m_shadow_data + offset) };
|
||||
}
|
||||
|
||||
ValueWithShadow<u16> SharedBufferRegion::read16(u32 offset)
|
||||
{
|
||||
ASSERT(offset + 1 < size());
|
||||
return { *reinterpret_cast<const u16*>(m_data + offset), *reinterpret_cast<const u16*>(m_shadow_data + offset) };
|
||||
}
|
||||
|
||||
ValueWithShadow<u32> SharedBufferRegion::read32(u32 offset)
|
||||
{
|
||||
ASSERT(offset + 3 < size());
|
||||
return { *reinterpret_cast<const u32*>(m_data + offset), *reinterpret_cast<const u32*>(m_shadow_data + offset) };
|
||||
}
|
||||
|
||||
ValueWithShadow<u64> SharedBufferRegion::read64(u32 offset)
|
||||
{
|
||||
ASSERT(offset + 7 < size());
|
||||
return { *reinterpret_cast<const u64*>(m_data + offset), *reinterpret_cast<const u64*>(m_shadow_data + offset) };
|
||||
}
|
||||
|
||||
void SharedBufferRegion::write8(u32 offset, ValueWithShadow<u8> value)
|
||||
{
|
||||
ASSERT(offset < size());
|
||||
*reinterpret_cast<u8*>(m_data + offset) = value.value();
|
||||
*reinterpret_cast<u8*>(m_shadow_data + offset) = value.shadow();
|
||||
}
|
||||
|
||||
void SharedBufferRegion::write16(u32 offset, ValueWithShadow<u16> value)
|
||||
{
|
||||
ASSERT(offset + 1 < size());
|
||||
*reinterpret_cast<u16*>(m_data + offset) = value.value();
|
||||
*reinterpret_cast<u16*>(m_shadow_data + offset) = value.shadow();
|
||||
}
|
||||
|
||||
void SharedBufferRegion::write32(u32 offset, ValueWithShadow<u32> value)
|
||||
{
|
||||
ASSERT(offset + 3 < size());
|
||||
*reinterpret_cast<u32*>(m_data + offset) = value.value();
|
||||
*reinterpret_cast<u32*>(m_shadow_data + offset) = value.shadow();
|
||||
}
|
||||
|
||||
void SharedBufferRegion::write64(u32 offset, ValueWithShadow<u64> value)
|
||||
{
|
||||
ASSERT(offset + 7 < size());
|
||||
*reinterpret_cast<u64*>(m_data + offset) = value.value();
|
||||
*reinterpret_cast<u64*>(m_shadow_data + offset) = value.shadow();
|
||||
}
|
||||
|
||||
int SharedBufferRegion::allow_pid(pid_t pid)
|
||||
{
|
||||
return syscall(SC_shbuf_allow_pid, m_shbuf_id, pid);
|
||||
}
|
||||
|
||||
int SharedBufferRegion::release()
|
||||
{
|
||||
return syscall(SC_shbuf_release, m_shbuf_id);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SoftMMU.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace UserspaceEmulator {
|
||||
|
||||
class SharedBufferRegion final : public Region {
|
||||
public:
|
||||
static NonnullOwnPtr<SharedBufferRegion> create_with_shbuf_id(u32 base, u32 size, int shbuf_id, u8* shbuf_data);
|
||||
virtual ~SharedBufferRegion() override;
|
||||
|
||||
virtual ValueWithShadow<u8> read8(u32 offset) override;
|
||||
virtual ValueWithShadow<u16> read16(u32 offset) override;
|
||||
virtual ValueWithShadow<u32> read32(u32 offset) override;
|
||||
virtual ValueWithShadow<u64> read64(u32 offset) override;
|
||||
|
||||
virtual void write8(u32 offset, ValueWithShadow<u8>) override;
|
||||
virtual void write16(u32 offset, ValueWithShadow<u16>) override;
|
||||
virtual void write32(u32 offset, ValueWithShadow<u32>) override;
|
||||
virtual void write64(u32 offset, ValueWithShadow<u64>) override;
|
||||
|
||||
virtual u8* data() override { return m_data; }
|
||||
virtual u8* shadow_data() override { return m_shadow_data; }
|
||||
|
||||
int shbuf_id() const { return m_shbuf_id; }
|
||||
|
||||
int allow_pid(pid_t);
|
||||
int release();
|
||||
|
||||
private:
|
||||
SharedBufferRegion(u32 base, u32 size, int shbuf_id, u8* shbuf_data);
|
||||
|
||||
u8* m_data { nullptr };
|
||||
u8* m_shadow_data { nullptr };
|
||||
int m_shbuf_id { 0 };
|
||||
};
|
||||
|
||||
}
|
|
@ -28,7 +28,6 @@
|
|||
#include "Emulator.h"
|
||||
#include "MmapRegion.h"
|
||||
#include "Report.h"
|
||||
#include "SharedBufferRegion.h"
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/Memory.h>
|
||||
|
||||
|
@ -43,10 +42,6 @@ void SoftMMU::add_region(NonnullOwnPtr<Region> region)
|
|||
{
|
||||
ASSERT(!find_region({ 0x23, region->base() }));
|
||||
|
||||
// FIXME: More sanity checks pls
|
||||
if (is<SharedBufferRegion>(*region))
|
||||
m_shbuf_regions.set(static_cast<SharedBufferRegion*>(region.ptr())->shbuf_id(), region.ptr());
|
||||
|
||||
size_t first_page_in_region = region->base() / PAGE_SIZE;
|
||||
size_t last_page_in_region = (region->base() + region->size() - 1) / PAGE_SIZE;
|
||||
for (size_t page = first_page_in_region; page <= last_page_in_region; ++page) {
|
||||
|
@ -63,8 +58,6 @@ void SoftMMU::remove_region(Region& region)
|
|||
m_page_to_region_map[first_page_in_region + i] = nullptr;
|
||||
}
|
||||
|
||||
if (is<SharedBufferRegion>(region))
|
||||
m_shbuf_regions.remove(static_cast<SharedBufferRegion&>(region).shbuf_id());
|
||||
m_regions.remove_first_matching([&](auto& entry) { return entry.ptr() == ®ion; });
|
||||
}
|
||||
|
||||
|
@ -238,11 +231,6 @@ ByteBuffer SoftMMU::copy_buffer_from_vm(const FlatPtr source, size_t size)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
SharedBufferRegion* SoftMMU::shbuf_region(int shbuf_id)
|
||||
{
|
||||
return (SharedBufferRegion*)m_shbuf_regions.get(shbuf_id).value_or(nullptr);
|
||||
}
|
||||
|
||||
bool SoftMMU::fast_fill_memory8(X86::LogicalAddress address, size_t size, ValueWithShadow<u8> value)
|
||||
{
|
||||
if (!size)
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
namespace UserspaceEmulator {
|
||||
|
||||
class Emulator;
|
||||
class SharedBufferRegion;
|
||||
|
||||
class SoftMMU {
|
||||
public:
|
||||
|
@ -74,8 +73,6 @@ public:
|
|||
void copy_from_vm(void* destination, const FlatPtr source, size_t);
|
||||
ByteBuffer copy_buffer_from_vm(const FlatPtr source, size_t);
|
||||
|
||||
SharedBufferRegion* shbuf_region(int shbuf_id);
|
||||
|
||||
template<typename Callback>
|
||||
void for_each_region(Callback callback)
|
||||
{
|
||||
|
@ -96,7 +93,6 @@ private:
|
|||
|
||||
OwnPtr<Region> m_tls_region;
|
||||
NonnullOwnPtrVector<Region> m_regions;
|
||||
HashMap<int, Region*> m_shbuf_regions;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue