1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 23:17:45 +00:00

Kernel: Wrap HIDManagement keymap data in SpinlockProtected

This serializes access to the current keymap data everywhere in the
kernel, allowing to mark sys$setkeymap() as not needing the big lock.
This commit is contained in:
Andreas Kling 2022-03-07 16:34:14 +01:00
parent ff60e8ffc6
commit baa6ff5649
5 changed files with 52 additions and 36 deletions

View file

@ -13,7 +13,7 @@ constexpr size_t map_name_max_size = 50;
ErrorOr<FlatPtr> Process::sys$setkeymap(Userspace<const Syscall::SC_setkeymap_params*> user_params)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
VERIFY_NO_PROCESS_BIG_LOCK(this);
TRY(require_promise(Pledge::setkeymap));
if (!is_superuser())
@ -37,25 +37,25 @@ ErrorOr<FlatPtr> Process::sys$setkeymap(Userspace<const Syscall::SC_setkeymap_pa
return 0;
}
ErrorOr<FlatPtr> Process::sys$getkeymap(Userspace<const Syscall::SC_getkeymap_params*> user_params)
ErrorOr<FlatPtr> Process::sys$getkeymap(Userspace<Syscall::SC_getkeymap_params const*> user_params)
{
VERIFY_NO_PROCESS_BIG_LOCK(this);
TRY(require_promise(Pledge::getkeymap));
auto params = TRY(copy_typed_from_user(user_params));
auto keymap_name = TRY(KString::try_create(HIDManagement::the().keymap_name()));
Keyboard::CharacterMapData const& character_maps = HIDManagement::the().character_map();
return HIDManagement::the().keymap_data().with([&](auto const& keymap_data) -> ErrorOr<FlatPtr> {
if (params.map_name.size < keymap_data.character_map_name->length())
return ENAMETOOLONG;
TRY(copy_to_user(params.map_name.data, keymap_data.character_map_name->characters(), keymap_data.character_map_name->length()));
TRY(copy_to_user(params.map, character_maps.map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.shift_map, character_maps.shift_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.alt_map, character_maps.alt_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.altgr_map, character_maps.altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.shift_altgr_map, character_maps.shift_altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
if (params.map_name.size < keymap_name->length())
return ENAMETOOLONG;
TRY(copy_to_user(params.map_name.data, keymap_name->characters(), keymap_name->length()));
return 0;
auto const& character_maps = keymap_data.character_map;
TRY(copy_to_user(params.map, character_maps.map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.shift_map, character_maps.shift_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.alt_map, character_maps.alt_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.altgr_map, character_maps.altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
TRY(copy_to_user(params.shift_altgr_map, character_maps.shift_altgr_map, CHAR_MAP_SIZE * sizeof(u32)));
return 0;
});
}
}