1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 02:37:35 +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:
Andreas Kling 2021-01-17 08:51:41 +01:00
parent 2cd16778b5
commit bf0719092f
28 changed files with 2 additions and 1022 deletions

View file

@ -3,7 +3,6 @@ set(SOURCES
MallocTracer.cpp
MmapRegion.cpp
Region.cpp
SharedBufferRegion.cpp
SimpleRegion.cpp
SoftCPU.cpp
SoftMMU.cpp

View file

@ -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);

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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 };
};
}

View file

@ -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() == &region; });
}
@ -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)

View file

@ -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;
};
}