diff --git a/zircon/kernel/lib/userboot/userboot.cpp b/zircon/kernel/lib/userboot/userboot.cpp index f7a421a9eef3106ba6cf55da2f6d063a0c51f470..cd965e93303ea0ba37df407e8eb4f891b6b15d9a 100644 --- a/zircon/kernel/lib/userboot/userboot.cpp +++ b/zircon/kernel/lib/userboot/userboot.cpp @@ -147,12 +147,16 @@ static zx_status_t get_job_handle(Handle** ptr) { static zx_status_t get_resource_handle(Handle** ptr) { zx_rights_t rights; - fbl::RefPtr<ResourceDispatcher> root; + KernelHandle<ResourceDispatcher> root; zx_status_t result = ResourceDispatcher::Create(&root, &rights, ZX_RSRC_KIND_ROOT, 0, 0, 0, "root"); - if (result == ZX_OK) - *ptr = Handle::Make(fbl::RefPtr<Dispatcher>(root.get()), - rights).release(); + if (result != ZX_OK) + return result; + + HandleOwner handle_owner = Handle::Make(ktl::move(root), rights); + if (!handle_owner) + return ZX_ERR_NO_MEMORY; + *ptr = handle_owner.release(); return result; } diff --git a/zircon/kernel/object/include/object/resource_dispatcher.h b/zircon/kernel/object/include/object/resource_dispatcher.h index 861ca2f4c561a9c4ea1ed12315b6cd18147eeeb6..44b42206951dcff5a3337a8e5969226e683a06b5 100644 --- a/zircon/kernel/object/include/object/resource_dispatcher.h +++ b/zircon/kernel/object/include/object/resource_dispatcher.h @@ -33,10 +33,10 @@ public: using ResourceList = fbl::DoublyLinkedList<ResourceDispatcher*>; using RefPtr = fbl::RefPtr<ResourceDispatcher>; - // Creates ResourceDispatcher object representing access rights ta + // Creates ResourceDispatcher object representing access rights to a // given region of address space from a particular address space allocator, or a root resource // granted full access permissions. Only one instance of the root resource is created at boot. - static zx_status_t Create(ResourceDispatcher::RefPtr* dispatcher, + static zx_status_t Create(KernelHandle<ResourceDispatcher>* handle, zx_rights_t* rights, uint32_t kind, uint64_t base, diff --git a/zircon/kernel/object/resource_dispatcher.cpp b/zircon/kernel/object/resource_dispatcher.cpp index 23568b52f1948492cdc1d2f308c4a33c9ec01754..b51a6b6ed9b3d4f06b90b7e015ddcd2b3990ab00 100644 --- a/zircon/kernel/object/resource_dispatcher.cpp +++ b/zircon/kernel/object/resource_dispatcher.cpp @@ -36,7 +36,7 @@ ResourceDispatcher::ResourceList ResourceDispatcher::static_resource_list_; RegionAllocator::RegionPool::RefPtr ResourceDispatcher::region_pool_; const char* kLogTag = "Resources:"; -zx_status_t ResourceDispatcher::Create(fbl::RefPtr<ResourceDispatcher>* dispatcher, +zx_status_t ResourceDispatcher::Create(KernelHandle<ResourceDispatcher>* handle, zx_rights_t* rights, uint32_t kind, uint64_t base, @@ -113,19 +113,19 @@ zx_status_t ResourceDispatcher::Create(fbl::RefPtr<ResourceDispatcher>* dispatch // itself. The constructor will handle adding itself to the shared list if // necessary. fbl::AllocChecker ac; - auto disp = fbl::AdoptRef(new (&ac) ResourceDispatcher(kind, base, size, flags, - ktl::move(region_uptr), - rallocs, resource_list)); + KernelHandle new_handle(fbl::AdoptRef(new (&ac) ResourceDispatcher(kind, base, size, flags, + ktl::move(region_uptr), + rallocs, resource_list))); if (!ac.check()) { return ZX_ERR_NO_MEMORY; } if (name != nullptr) { - disp->set_name(name, ZX_MAX_NAME_LEN); + new_handle.dispatcher()->set_name(name, ZX_MAX_NAME_LEN); } *rights = default_rights(); - *dispatcher = ktl::move(disp); + *handle = ktl::move(new_handle); LTRACEF("%s [%u, %#lx, %zu] resource created.\n", kLogTag, kind, base, size); return ZX_OK; diff --git a/zircon/kernel/platform/pc/memory.cpp b/zircon/kernel/platform/pc/memory.cpp index 19f0e76ccc20fdeb4d990e3bec6fa7de42781c60..eb966e6d1b7a4c6c584294da7c9e4a6dc6f90d31 100644 --- a/zircon/kernel/platform/pc/memory.cpp +++ b/zircon/kernel/platform/pc/memory.cpp @@ -22,6 +22,7 @@ #include <vm/vm.h> #include <zircon/types.h> #include <zircon/boot/e820.h> +#include <object/handle.h> #include <object/resource_dispatcher.h> #include "platform_p.h" @@ -46,7 +47,7 @@ constexpr uint8_t kMaxReservedMmioEntries = 64; typedef struct reserved_mmio_space { uint64_t base; size_t len; - ResourceDispatcher::RefPtr dispatcher; + KernelHandle<ResourceDispatcher> handle; } reserved_mmio_space_t; reserved_mmio_space_t reserved_mmio_entries[kMaxReservedMmioEntries]; static uint8_t reserved_mmio_count = 0; @@ -451,7 +452,8 @@ static void x86_resource_init_hook(unsigned int rl) { for (uint8_t i = 0; i < reserved_mmio_count; i++) { zx_rights_t rights; auto& entry = reserved_mmio_entries[i]; - zx_status_t st = ResourceDispatcher::Create(&entry.dispatcher, &rights, ZX_RSRC_KIND_MMIO, + + zx_status_t st = ResourceDispatcher::Create(&entry.handle, &rights, ZX_RSRC_KIND_MMIO, entry.base, entry.len, ZX_RSRC_FLAG_EXCLUSIVE, "platform_memory"); if (st == ZX_OK) { diff --git a/zircon/kernel/syscalls/resource.cpp b/zircon/kernel/syscalls/resource.cpp index 9c954f56f3e29f6da9f2c329d8acbf44d8c2f3fe..51e29731c9995c0e5053714630b8dc73621c5db3 100644 --- a/zircon/kernel/syscalls/resource.cpp +++ b/zircon/kernel/syscalls/resource.cpp @@ -68,12 +68,12 @@ zx_status_t sys_resource_create(zx_handle_t parent_rsrc, // Create a new Resource zx_rights_t rights; - fbl::RefPtr<ResourceDispatcher> child; - status = ResourceDispatcher::Create(&child, &rights, kind, base, size, flags, name); + KernelHandle<ResourceDispatcher> handle; + status = ResourceDispatcher::Create(&handle, &rights, kind, base, size, flags, name); if (status != ZX_OK) { return status; } // Create a handle for the child - return resource_out->make(ktl::move(child), rights); + return resource_out->make(ktl::move(handle), rights); } diff --git a/zircon/kernel/tests/resource_tests.cpp b/zircon/kernel/tests/resource_tests.cpp index cb085f088c8198a59f245ed5b5f7a1493dfe00e8..83eab283a8d9dcceddfe7e781ed66c58a90c88f9 100644 --- a/zircon/kernel/tests/resource_tests.cpp +++ b/zircon/kernel/tests/resource_tests.cpp @@ -8,6 +8,7 @@ #include <fbl/alloc_checker.h> #include <ktl/unique_ptr.h> +#include <object/handle.h> #include <object/resource_dispatcher.h> #include <lib/unittest/unittest.h> @@ -17,12 +18,11 @@ static bool unconfigured() { ResourceDispatcher::ResourceList test_resource_list; zx_rights_t rights; - ResourceDispatcher::RefPtr disp1, disp2; - EXPECT_EQ(ResourceDispatcher::Create(&disp1, &rights, ZX_RSRC_KIND_MMIO, 0, PAGE_SIZE, 0, + KernelHandle<ResourceDispatcher> handle1, handle2; + EXPECT_EQ(ResourceDispatcher::Create(&handle1, &rights, ZX_RSRC_KIND_MMIO, 0, PAGE_SIZE, 0, NULL, test_rallocs, &test_resource_list), ZX_ERR_BAD_STATE, "MMIO GetRegion should return ERR_BAD_STATE"); - ResourceDispatcher::RefPtr disp; - EXPECT_EQ(ResourceDispatcher::Create(&disp2, &rights, ZX_RSRC_KIND_IRQ, 0, PAGE_SIZE, 0, + EXPECT_EQ(ResourceDispatcher::Create(&handle2, &rights, ZX_RSRC_KIND_IRQ, 0, PAGE_SIZE, 0, NULL, test_rallocs, &test_resource_list), ZX_ERR_BAD_STATE, "IRQ GetRegion should return ERR_BAD_STATE"); // Nothing should be in the lists. @@ -56,7 +56,7 @@ static bool exclusive_then_shared() { ResourceDispatcher::ResourceList test_resource_list; RegionAllocator test_rallocs[ZX_RSRC_KIND_COUNT]; - ResourceDispatcher::RefPtr disp1, disp2; + KernelHandle<ResourceDispatcher> handle1, handle2; zx_rights_t rights; uint64_t base = 0; uint64_t size = PAGE_SIZE; @@ -65,14 +65,14 @@ static bool exclusive_then_shared() { test_rallocs), ZX_OK, ""); // Creating the exclusive resource will succeed. - EXPECT_EQ(ResourceDispatcher::Create(&disp1, &rights, ZX_RSRC_KIND_MMIO, base, size, + EXPECT_EQ(ResourceDispatcher::Create(&handle1, &rights, ZX_RSRC_KIND_MMIO, base, size, flags, "ets-disp1", test_rallocs, &test_resource_list), ZX_OK, "Creating the exclusive resource failed."); EXPECT_EQ(test_resource_list.size_slow(), 1u, ""); // Creating the shared resource should fail flags = 0; - EXPECT_EQ(ResourceDispatcher::Create(&disp2, &rights, ZX_RSRC_KIND_MMIO, base, size, + EXPECT_EQ(ResourceDispatcher::Create(&handle2, &rights, ZX_RSRC_KIND_MMIO, base, size, flags, "ets-disp2", test_rallocs, &test_resource_list), ZX_ERR_NOT_FOUND, "Creating the shared resource succeeded."); @@ -87,7 +87,7 @@ static bool shared_then_exclusive() { ResourceDispatcher::ResourceList test_resource_list; RegionAllocator test_rallocs[ZX_RSRC_KIND_COUNT]; - ResourceDispatcher::RefPtr disp1, disp2; + KernelHandle<ResourceDispatcher> handle1, handle2; zx_rights_t rights; uint64_t base = 0; uint64_t size = PAGE_SIZE; @@ -96,14 +96,14 @@ static bool shared_then_exclusive() { test_rallocs), ZX_OK, ""); // Creating the shared resource will succeed. - EXPECT_EQ(ResourceDispatcher::Create(&disp1, &rights, ZX_RSRC_KIND_MMIO, base, size, + EXPECT_EQ(ResourceDispatcher::Create(&handle1, &rights, ZX_RSRC_KIND_MMIO, base, size, flags, "ets-disp1", test_rallocs, &test_resource_list), ZX_OK, "Creating the exclusive resource failed."); EXPECT_EQ(test_resource_list.size_slow(), 1u, ""); // Creating the exclusive resource should fail flags = ZX_RSRC_FLAG_EXCLUSIVE; - EXPECT_EQ(ResourceDispatcher::Create(&disp2, &rights, ZX_RSRC_KIND_MMIO, base, size, + EXPECT_EQ(ResourceDispatcher::Create(&handle2, &rights, ZX_RSRC_KIND_MMIO, base, size, flags, "ets-disp2", test_rallocs, &test_resource_list), ZX_ERR_NOT_FOUND, "Creating the shared resource succeeded."); @@ -117,19 +117,19 @@ static bool out_of_allocator_range() { ResourceDispatcher::ResourceList test_resource_list; RegionAllocator test_rallocs[ZX_RSRC_KIND_COUNT]; - ResourceDispatcher::RefPtr disp1; + KernelHandle<ResourceDispatcher> handle1; zx_rights_t rights; uint64_t size = 0xFFFF; ASSERT_EQ(ResourceDispatcher::InitializeAllocator(ZX_RSRC_KIND_MMIO, 0, size, test_rallocs), ZX_OK, ""); // Overlap near the end - EXPECT_EQ(ResourceDispatcher::Create(&disp1, &rights, ZX_RSRC_KIND_MMIO, size - 0xFF, 0xFFF, + EXPECT_EQ(ResourceDispatcher::Create(&handle1, &rights, ZX_RSRC_KIND_MMIO, size - 0xFF, 0xFFF, 0, "ooar-disp1", test_rallocs, &test_resource_list), ZX_ERR_NOT_FOUND, ""); // Pick a chunk outside the range entirely - EXPECT_EQ(ResourceDispatcher::Create(&disp1, &rights, ZX_RSRC_KIND_MMIO, size + size, size, + EXPECT_EQ(ResourceDispatcher::Create(&handle1, &rights, ZX_RSRC_KIND_MMIO, size + size, size, 0, "ooar-disp1", test_rallocs, &test_resource_list), ZX_ERR_NOT_FOUND, "");