From a32c287b5cba3867dcf91514c08eb3e261261bc4 Mon Sep 17 00:00:00 2001 From: Roman Kiryanov Date: Tue, 23 Jan 2024 16:11:02 -0800 Subject: Sync address_space_host_memory_allocator.cpp to external/qemu Bug: 322026591 Test: presubmit Change-Id: I9c8ca9a4e79127e52bc54e75f1a880dcd1c910c3 Signed-off-by: Roman Kiryanov (cherry picked from commit 926d94b552ca6874cbc774c2cdbda07ec64bc504) --- host-common/address_space_host_memory_allocator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host-common/address_space_host_memory_allocator.cpp b/host-common/address_space_host_memory_allocator.cpp index ed2e5fa..8db3bbe 100644 --- a/host-common/address_space_host_memory_allocator.cpp +++ b/host-common/address_space_host_memory_allocator.cpp @@ -107,7 +107,6 @@ uint64_t AddressSpaceHostMemoryAllocatorContext::unallocate(AddressSpaceDevicePi } else { return -1; } - return 0; } AddressSpaceDeviceType AddressSpaceHostMemoryAllocatorContext::getDeviceType() const { @@ -162,6 +161,7 @@ void AddressSpaceHostMemoryAllocatorContext::clear() { phys_addr, host_ptr, size); } } + m_paddr2ptr.clear(); } } // namespace emulation -- cgit v1.2.3 From fe3ad987a9cb14b3969da2cf919c11fd3c036b21 Mon Sep 17 00:00:00 2001 From: Roman Kiryanov Date: Tue, 23 Jan 2024 16:24:35 -0800 Subject: Sync address_space_shared_slots_host_memory_allocator.cpp to external/qemu Bug: 322026591 Test: presubmit Change-Id: Ia1c5ca52dd72ef526c8d5537bc469abe1a73849a Signed-off-by: Roman Kiryanov (cherry picked from commit cc1f4f0d839bde42534e97991cd60c605a0be6e3) --- ...dress_space_shared_slots_host_memory_allocator.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/host-common/address_space_shared_slots_host_memory_allocator.cpp b/host-common/address_space_shared_slots_host_memory_allocator.cpp index 31032b3..7136048 100644 --- a/host-common/address_space_shared_slots_host_memory_allocator.cpp +++ b/host-common/address_space_shared_slots_host_memory_allocator.cpp @@ -49,6 +49,23 @@ uint64_t allocateAddressSpaceBlock(const AddressSpaceHwFuncs* hw, uint32_t size) } } +uint64_t allocateAddressSpaceBlockFixed(uint64_t gpa, const AddressSpaceHwFuncs* hw, uint32_t size) { + uint64_t offset = gpa - hw->getPhysAddrStartLocked(); + if (hw->allocSharedHostRegionFixedLocked(size, offset)) { + // Note: even if we do not succeed in allocSharedHostRegionFixedLocked, + // assume this is because we're doing a snapshot load, and the VMSTATE + // description of memory slots in hw/pci/goldfish_address_space.c + // already contains the entry we wanted. TODO: Consider always + // allowing allocSharedHostRegionFixedLocked succeed if it encounters + // an unavailable block at the same offset and size, and/or add a + // "forSnapshotLoad" flag to allocSharedHostRegionFixedLocked in order + // to specifically account for this case. + return hw->getPhysAddrStartLocked() + offset; + } else { + return hw->getPhysAddrStartLocked() + offset; + } +} + int freeAddressBlock(const AddressSpaceHwFuncs* hw, uint64_t phys) { const uint64_t start = hw->getPhysAddrStartLocked(); if (phys < start) { return -1; } @@ -238,7 +255,7 @@ bool MemBlock::load(base::Stream* stream, android::aligned_buf_free(bits); return false; } - const uint64_t physBase = allocateAddressSpaceBlock(hw, bitsSize); + const uint64_t physBase = allocateAddressSpaceBlockFixed(physBaseLoaded, hw, bitsSize); if (!physBase) { android::aligned_buf_free(bits); return false; -- cgit v1.2.3 From 04b21e118c60fd87e262618358318ad28e074659 Mon Sep 17 00:00:00 2001 From: Roman Kiryanov Date: Tue, 23 Jan 2024 17:37:33 -0800 Subject: Support variable guest page size in goldfish_address_space This is required for 16K kernels Bug: 322026591 Test: presubmit Change-Id: I52801be79ac0dde3eb03a28980d858f75095328b Signed-off-by: Roman Kiryanov (cherry picked from commit 9b46aa71fa161732eedd7ae90d97503d15cd155e) --- host-common/address_space_device.cpp | 3 +- .../address_space_host_memory_allocator.cpp | 19 ++++++++----- ...dress_space_host_memory_allocator_unittests.cpp | 32 ++++++++++++++++++---- ...ss_space_shared_slots_host_memory_allocator.cpp | 15 ++++++---- .../include/host-common/address_space_device.h | 1 + .../address_space_host_memory_allocator.h | 4 ++- host-common/testing/HostAddressSpace.cpp | 5 ++++ host-common/testing/HostAddressSpace.h | 1 + 8 files changed, 60 insertions(+), 20 deletions(-) diff --git a/host-common/address_space_device.cpp b/host-common/address_space_device.cpp index 48a3052..c7951be 100644 --- a/host-common/address_space_device.cpp +++ b/host-common/address_space_device.cpp @@ -363,7 +363,8 @@ private: return nullptr; case AddressSpaceDeviceType::HostMemoryAllocator: return DeviceContextPtr(new AddressSpaceHostMemoryAllocatorContext( - get_address_space_device_control_ops())); + get_address_space_device_control_ops(), + get_address_space_device_hw_funcs())); case AddressSpaceDeviceType::SharedSlotsHostMemoryAllocator: return DeviceContextPtr(new AddressSpaceSharedSlotsHostMemoryAllocatorContext( get_address_space_device_control_ops(), diff --git a/host-common/address_space_host_memory_allocator.cpp b/host-common/address_space_host_memory_allocator.cpp index ed2e5fa..ac6e2db 100644 --- a/host-common/address_space_host_memory_allocator.cpp +++ b/host-common/address_space_host_memory_allocator.cpp @@ -21,11 +21,16 @@ namespace android { namespace emulation { +namespace { +size_t align(size_t value, size_t alignment) { + return (value + alignment - 1) & (~(alignment - 1)); +} +} AddressSpaceHostMemoryAllocatorContext::AddressSpaceHostMemoryAllocatorContext( - const address_space_device_control_ops *ops) - : m_ops(ops) { -} + const address_space_device_control_ops *ops, const AddressSpaceHwFuncs* hw) + : m_ops(ops), + m_hw(hw) {} AddressSpaceHostMemoryAllocatorContext::~AddressSpaceHostMemoryAllocatorContext() { clear(); @@ -54,13 +59,13 @@ void AddressSpaceHostMemoryAllocatorContext::perform(AddressSpaceDevicePingInfo void *AddressSpaceHostMemoryAllocatorContext::allocate_impl(const uint64_t phys_addr, const uint64_t size) { #if defined(__APPLE__) && defined(__arm64__) - constexpr uint64_t alignment = 16384; + constexpr uint64_t k_alloc_alignment = 16384; #else - constexpr uint64_t alignment = 4096; + constexpr uint64_t k_alloc_alignment = 4096; #endif - const uint64_t aligned_size = ((size + alignment - 1) / alignment) * alignment; + const uint64_t aligned_size = align(size, (*m_hw->getGuestPageSize)()); - void *host_ptr = android::aligned_buf_alloc(alignment, aligned_size); + void *host_ptr = android::aligned_buf_alloc(k_alloc_alignment, aligned_size); if (host_ptr) { auto r = m_paddr2ptr.insert({phys_addr, {host_ptr, aligned_size}}); if (r.second) { diff --git a/host-common/address_space_host_memory_allocator_unittests.cpp b/host-common/address_space_host_memory_allocator_unittests.cpp index 77f0517..8ec3fa2 100644 --- a/host-common/address_space_host_memory_allocator_unittests.cpp +++ b/host-common/address_space_host_memory_allocator_unittests.cpp @@ -29,6 +29,10 @@ int empty_add_memory_mapping(uint64_t gpa, void *ptr, uint64_t size) { int empty_remove_memory_mapping(uint64_t gpa, void *ptr, uint64_t size) { return 1; } +uint32_t getGuestPageSize() { + return 4096; +} + struct address_space_device_control_ops create_address_space_device_control_ops() { struct address_space_device_control_ops ops = {}; @@ -38,6 +42,14 @@ struct address_space_device_control_ops create_address_space_device_control_ops( return ops; } +AddressSpaceHwFuncs create_address_space_device_hw_funcs() { + AddressSpaceHwFuncs hw_funcs = {}; + + hw_funcs.getGuestPageSize = &getGuestPageSize; + + return hw_funcs; +} + AddressSpaceDevicePingInfo createAllocateRequest(uint64_t phys_addr) { AddressSpaceDevicePingInfo req = {}; @@ -64,7 +76,9 @@ TEST(AddressSpaceHostMemoryAllocatorContext, getDeviceType) { struct address_space_device_control_ops ops = create_address_space_device_control_ops(); - AddressSpaceHostMemoryAllocatorContext ctx(&ops); + AddressSpaceHwFuncs hw_funcs = create_address_space_device_hw_funcs(); + + AddressSpaceHostMemoryAllocatorContext ctx(&ops, &hw_funcs); EXPECT_EQ(ctx.getDeviceType(), AddressSpaceDeviceType::HostMemoryAllocator); } @@ -73,7 +87,9 @@ TEST(AddressSpaceHostMemoryAllocatorContext, AllocateDeallocate) { struct address_space_device_control_ops ops = create_address_space_device_control_ops(); - AddressSpaceHostMemoryAllocatorContext ctx(&ops); + AddressSpaceHwFuncs hw_funcs = create_address_space_device_hw_funcs(); + + AddressSpaceHostMemoryAllocatorContext ctx(&ops, &hw_funcs); AddressSpaceDevicePingInfo req; @@ -90,7 +106,9 @@ TEST(AddressSpaceHostMemoryAllocatorContext, AllocateSamePhysAddr) { struct address_space_device_control_ops ops = create_address_space_device_control_ops(); - AddressSpaceHostMemoryAllocatorContext ctx(&ops); + AddressSpaceHwFuncs hw_funcs = create_address_space_device_hw_funcs(); + + AddressSpaceHostMemoryAllocatorContext ctx(&ops, &hw_funcs); AddressSpaceDevicePingInfo req; @@ -127,7 +145,9 @@ TEST(AddressSpaceHostMemoryAllocatorContext, AllocateMappingFail) { struct address_space_device_control_ops ops = create_address_space_device_control_ops(); - AddressSpaceHostMemoryAllocatorContext ctx(&ops); + AddressSpaceHwFuncs hw_funcs = create_address_space_device_hw_funcs(); + + AddressSpaceHostMemoryAllocatorContext ctx(&ops, &hw_funcs); AddressSpaceDevicePingInfo req; @@ -140,7 +160,9 @@ TEST(AddressSpaceHostMemoryAllocatorContext, UnallocateTwice) { struct address_space_device_control_ops ops = create_address_space_device_control_ops(); - AddressSpaceHostMemoryAllocatorContext ctx(&ops); + AddressSpaceHwFuncs hw_funcs = create_address_space_device_hw_funcs(); + + AddressSpaceHostMemoryAllocatorContext ctx(&ops, &hw_funcs); AddressSpaceDevicePingInfo req; diff --git a/host-common/address_space_shared_slots_host_memory_allocator.cpp b/host-common/address_space_shared_slots_host_memory_allocator.cpp index 31032b3..ca933f1 100644 --- a/host-common/address_space_shared_slots_host_memory_allocator.cpp +++ b/host-common/address_space_shared_slots_host_memory_allocator.cpp @@ -27,6 +27,10 @@ namespace android { namespace emulation { namespace { +size_t align(size_t value, size_t alignment) { + return (value + alignment - 1) & (~(alignment - 1)); +} + typedef AddressSpaceSharedSlotsHostMemoryAllocatorContext ASSSHMAC; typedef ASSSHMAC::MemBlock MemBlock; typedef MemBlock::FreeSubblocks_t FreeSubblocks_t; @@ -35,9 +39,9 @@ using base::AutoLock; using base::Lock; #if defined(__APPLE__) && defined(__arm64__) -constexpr uint32_t kAlignment = 16384; +constexpr uint32_t kAllocAlignment = 16384; #else -constexpr uint32_t kAlignment = 4096; +constexpr uint32_t kAllocAlignment = 4096; #endif uint64_t allocateAddressSpaceBlock(const AddressSpaceHwFuncs* hw, uint32_t size) { @@ -72,7 +76,7 @@ std::pair translatePhysAddr(uint64_t p) { MemBlock::MemBlock(const address_space_device_control_ops* o, const AddressSpaceHwFuncs* h, uint32_t sz) : ops(o), hw(h) { - bits = android::aligned_buf_alloc(kAlignment, sz); + bits = android::aligned_buf_alloc(kAllocAlignment, sz); bitsSize = sz; physBase = allocateAddressSpaceBlock(hw, sz); if (!physBase) { @@ -230,7 +234,7 @@ bool MemBlock::load(base::Stream* stream, MemBlock* block) { const uint64_t physBaseLoaded = stream->getBe64(); const uint32_t bitsSize = stream->getBe32(); - void* const bits = android::aligned_buf_alloc(kAlignment, bitsSize); + void* const bits = android::aligned_buf_alloc(kAllocAlignment, bitsSize); if (!bits) { return false; } @@ -307,8 +311,7 @@ void AddressSpaceSharedSlotsHostMemoryAllocatorContext::perform(AddressSpaceDevi uint64_t AddressSpaceSharedSlotsHostMemoryAllocatorContext::allocate( AddressSpaceDevicePingInfo *info) { - const uint32_t alignedSize = - ((info->size + kAlignment - 1) / kAlignment) * kAlignment; + const uint32_t alignedSize = align(info->size, (*m_hw->getGuestPageSize)()); AutoLock lock(g_blocksLock); for (auto& kv : g_blocks) { diff --git a/host-common/include/host-common/address_space_device.h b/host-common/include/host-common/address_space_device.h index 22bbbe7..ae5f58f 100644 --- a/host-common/include/host-common/address_space_device.h +++ b/host-common/include/host-common/address_space_device.h @@ -97,6 +97,7 @@ struct AddressSpaceHwFuncs { * are relative to. */ uint64_t (*getPhysAddrStart)(void); uint64_t (*getPhysAddrStartLocked)(void); + uint32_t (*getGuestPageSize)(void); /* Version of allocSharedHostRegionLocked but for a fixed offset */ int (*allocSharedHostRegionFixedLocked)(uint64_t page_aligned_size, uint64_t offset); diff --git a/host-common/include/host-common/address_space_host_memory_allocator.h b/host-common/include/host-common/address_space_host_memory_allocator.h index a2419c3..c87213c 100644 --- a/host-common/include/host-common/address_space_host_memory_allocator.h +++ b/host-common/include/host-common/address_space_host_memory_allocator.h @@ -28,7 +28,8 @@ public: Unallocate = 2 }; - AddressSpaceHostMemoryAllocatorContext(const address_space_device_control_ops *ops); + AddressSpaceHostMemoryAllocatorContext(const address_space_device_control_ops *ops, + const AddressSpaceHwFuncs* hw); ~AddressSpaceHostMemoryAllocatorContext(); void perform(AddressSpaceDevicePingInfo *info) override; @@ -51,6 +52,7 @@ private: std::unordered_map> m_paddr2ptr; const address_space_device_control_ops *m_ops; // do not save/load + const AddressSpaceHwFuncs* m_hw; }; } // namespace emulation diff --git a/host-common/testing/HostAddressSpace.cpp b/host-common/testing/HostAddressSpace.cpp index a401150..bdde0a0 100644 --- a/host-common/testing/HostAddressSpace.cpp +++ b/host-common/testing/HostAddressSpace.cpp @@ -479,6 +479,10 @@ uint64_t HostAddressSpaceDevice::getPhysAddrStart() { return HostAddressSpaceDevice::getImpl()->getPhysAddrStart(); } +uint32_t HostAddressSpaceDevice::getGuestPageSize() { + return 4096; +} + int HostAddressSpaceDevice::allocSharedHostRegionFixedLocked(uint64_t page_aligned_size, uint64_t offset) { return HostAddressSpaceDevice::getImpl()->allocSharedHostRegionFixedLocked(page_aligned_size, offset); } @@ -490,6 +494,7 @@ static const AddressSpaceHwFuncs sAddressSpaceHwFuncs = { &HostAddressSpaceDevice::freeSharedHostRegionLocked, &HostAddressSpaceDevice::getPhysAddrStart, &HostAddressSpaceDevice::getPhysAddrStart, + &HostAddressSpaceDevice::getGuestPageSize, &HostAddressSpaceDevice::allocSharedHostRegionFixedLocked, }; diff --git a/host-common/testing/HostAddressSpace.h b/host-common/testing/HostAddressSpace.h index 3890717..4daf7dd 100644 --- a/host-common/testing/HostAddressSpace.h +++ b/host-common/testing/HostAddressSpace.h @@ -64,6 +64,7 @@ public: static int allocSharedHostRegionFixedLocked(uint64_t page_aligned_size, uint64_t offset); static uint64_t getPhysAddrStart(); static uint64_t getPhysAddrStartLocked(); + static uint32_t getGuestPageSize(); private: class Impl; -- cgit v1.2.3