From db9b70ee54c4896f8db1515e57ff68bd847fbbbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Mon, 7 May 2018 19:00:21 +0200 Subject: [PATCH] kernel: add a compatibility commpage on x86_64. * x86 uses a commpage with 32-bit addresses, incompatible with the one used for x86_64. For this reason, a compatibility commpage is needed to support a 32-bit userland on x86_64. * define ADDRESS_TYPE as a macro for addr_t (default) or uint32 (for the 32-bit commpage). * team_create_thread_start_internal() will use clone_commpage_area() with KERNEL_USER_DATA_BASE or clone_commpage_compat_area() with KERNEL_USER32_DATA_BASE, to setup the correct commpage. * real_time_clock (in compatibility mode) also updates the compatibility commpage with real time data. Change-Id: I61605077ce0beabab4439ef54edd1eae26f26fd2 --- headers/private/kernel/commpage_compat.h | 39 +++++++++++++++++++ .../system/arch/x86/arch_real_time_data.h | 2 + headers/private/system/commpage_defs.h | 5 +++ .../kernel/arch/x86/arch_commpage_compat.cpp | 35 +++++++++++++++++ src/system/kernel/commpage.cpp | 14 ++++++- src/system/kernel/commpage_compat.cpp | 24 ++++++++++++ src/system/kernel/main.cpp | 10 +++++ src/system/kernel/real_time_clock.cpp | 32 ++++++++++++++- 8 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 headers/private/kernel/commpage_compat.h create mode 100644 src/system/kernel/arch/x86/arch_commpage_compat.cpp create mode 100644 src/system/kernel/commpage_compat.cpp diff --git a/headers/private/kernel/commpage_compat.h b/headers/private/kernel/commpage_compat.h new file mode 100644 index 0000000000..5b3f394aea --- /dev/null +++ b/headers/private/kernel/commpage_compat.h @@ -0,0 +1,39 @@ +/* + * Copyright 2018 Haiku Inc. All Rights Reserved. + * Copyright 2007, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _KERNEL_COMMPAGE_COMPAT_H +#define _KERNEL_COMMPAGE_COMPAT_H + + +#include +#include + +#define COMMPAGE_COMPAT +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +status_t commpage_compat_init(void); +status_t commpage_compat_init_post_cpus(void); +void* allocate_commpage_compat_entry(int entry, size_t size); +addr_t fill_commpage_compat_entry(int entry, const void* copyFrom, + size_t size); +image_id get_commpage_compat_image(); +area_id clone_commpage_compat_area(team_id team, void** address); + +// implemented in the architecture specific part +status_t arch_commpage_compat_init(void); +status_t arch_commpage_compat_init_post_cpus(void); + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif /* _KERNEL_COMMPAGE_COMPAT_H */ diff --git a/headers/private/system/arch/x86/arch_real_time_data.h b/headers/private/system/arch/x86/arch_real_time_data.h index d6350c39f2..6f862dc34c 100644 --- a/headers/private/system/arch/x86/arch_real_time_data.h +++ b/headers/private/system/arch/x86/arch_real_time_data.h @@ -1,4 +1,5 @@ /* + * Copyright 2018 Haiku Inc. All Rights Reserved. * Copyright 2006, Ingo Weinhold . * All rights reserved. Distributed under the terms of the MIT License. */ @@ -12,6 +13,7 @@ struct arch_real_time_data { bigtime_t system_time_offset; uint32 system_time_conversion_factor; + uint32 _padding; }; #endif /* _KERNEL_ARCH_REAL_TIME_DATA_H */ diff --git a/headers/private/system/commpage_defs.h b/headers/private/system/commpage_defs.h index 0a69403182..81964f07aa 100644 --- a/headers/private/system/commpage_defs.h +++ b/headers/private/system/commpage_defs.h @@ -1,4 +1,5 @@ /* + * Copyright 2018 Haiku Inc. All Rights Reserved. * Copyright 2007, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -19,6 +20,10 @@ #define COMMPAGE_SIGNATURE 'COMM' #define COMMPAGE_VERSION 1 +#ifdef COMMPAGE_COMPAT +#include +#else #include +#endif #endif /* _SYSTEM_COMMPAGE_DEFS_H */ diff --git a/src/system/kernel/arch/x86/arch_commpage_compat.cpp b/src/system/kernel/arch/x86/arch_commpage_compat.cpp new file mode 100644 index 0000000000..fc454cadeb --- /dev/null +++ b/src/system/kernel/arch/x86/arch_commpage_compat.cpp @@ -0,0 +1,35 @@ +/* + * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. + * Copyright 2008-2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2007, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include "x86_signals.h" +#include "x86_syscalls.h" + + +void x86_compat_initialize_commpage_signal_handler(); + + +status_t +arch_commpage_compat_init(void) +{ + return B_OK; +} + + +status_t +arch_commpage_compat_init_post_cpus(void) +{ + // select the optimum syscall mechanism and patch the commpage + x86_compat_initialize_syscall(); + + // initialize the signal handler code in the commpage + x86_compat_initialize_commpage_signal_handler(); + + return B_OK; +} diff --git a/src/system/kernel/commpage.cpp b/src/system/kernel/commpage.cpp index c54a674b07..d895feb001 100644 --- a/src/system/kernel/commpage.cpp +++ b/src/system/kernel/commpage.cpp @@ -1,9 +1,15 @@ /* + * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. * Copyright 2007, Travis Geiselbrecht. All rights reserved. * Distributed under the terms of the MIT License. */ + +#ifdef COMMPAGE_COMPAT +#include +#else #include +#endif #include @@ -13,9 +19,12 @@ #include #include +#ifndef ADDRESS_TYPE +#define ADDRESS_TYPE addr_t +#endif static area_id sCommPageArea; -static addr_t* sCommPageAddress; +static ADDRESS_TYPE* sCommPageAddress; static void* sFreeCommPageSpace; static image_id sCommPageImage; @@ -54,7 +63,8 @@ get_commpage_image() area_id clone_commpage_area(team_id team, void** address) { - *address = (void*)KERNEL_USER_DATA_BASE; + if (*address == NULL) + *address = (void*)KERNEL_USER_DATA_BASE; return vm_clone_area(team, "commpage", address, B_RANDOMIZED_BASE_ADDRESS, B_READ_AREA | B_EXECUTE_AREA | B_KERNEL_AREA, REGION_PRIVATE_MAP, sCommPageArea, true); diff --git a/src/system/kernel/commpage_compat.cpp b/src/system/kernel/commpage_compat.cpp new file mode 100644 index 0000000000..88aabcd741 --- /dev/null +++ b/src/system/kernel/commpage_compat.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. + * Distributed under the terms of the MIT License. + */ + + +#define sCommPageArea sCommPageCompatArea +#define sCommPageAddress sCommPageCompatAddress +#define sFreeCommPageSpace sFreeCommPageCompatSpace +#define sCommPageImage sCommPageCompatImage + +#define allocate_commpage_entry allocate_commpage_compat_entry +#define fill_commpage_entry fill_commpage_compat_entry +#define get_commpage_image get_commpage_compat_image +#define clone_commpage_area clone_commpage_compat_area +#define commpage_init commpage_compat_init +#define commpage_init_post_cpus commpage_compat_init_post_cpus +#define arch_commpage_init arch_commpage_compat_init +#define arch_commpage_init_post_cpus arch_commpage_compat_init_post_cpus + +#define ADDRESS_TYPE uint32 +#define COMMPAGE_COMPAT + +#include "commpage.cpp" diff --git a/src/system/kernel/main.cpp b/src/system/kernel/main.cpp index f3a0a9b388..8677e36b31 100644 --- a/src/system/kernel/main.cpp +++ b/src/system/kernel/main.cpp @@ -1,4 +1,5 @@ /* + * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com. * Copyright 2002-2015, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * @@ -20,6 +21,9 @@ #include #include #include +#ifdef _COMPAT_MODE +# include +#endif #include #include #include @@ -163,6 +167,9 @@ _start(kernel_args *bootKernelArgs, int currentCPU) int_init_post_vm(&sKernelArgs); cpu_init_post_vm(&sKernelArgs); commpage_init(); +#ifdef _COMPAT_MODE + commpage_compat_init(); +#endif call_all_cpus_sync(non_boot_cpu_init, &sKernelArgs); TRACE("init system info\n"); @@ -285,6 +292,9 @@ main2(void* /*unused*/) boot_splash_init(sKernelArgs.boot_splash); commpage_init_post_cpus(); +#ifdef _COMPAT_MODE + commpage_compat_init_post_cpus(); +#endif TRACE("init ports\n"); port_init(&sKernelArgs); diff --git a/src/system/kernel/real_time_clock.cpp b/src/system/kernel/real_time_clock.cpp index 7db88c24f9..ac92dd58c9 100644 --- a/src/system/kernel/real_time_clock.cpp +++ b/src/system/kernel/real_time_clock.cpp @@ -10,6 +10,9 @@ #include #include +#ifdef _COMPAT_MODE +# include +#endif #include #include #include @@ -30,6 +33,9 @@ // January 1st, 1970 static struct real_time_data *sRealTimeData; +#ifdef _COMPAT_MODE +static struct real_time_data *sRealTimeDataCompat; +#endif static bool sIsGMT = false; static bigtime_t sTimezoneOffset = 0; static char sTimezoneName[B_FILE_NAME_LENGTH] = "GMT"; @@ -101,8 +107,15 @@ rtc_init(kernel_args *args) { sRealTimeData = (struct real_time_data*)allocate_commpage_entry( COMMPAGE_ENTRY_REAL_TIME_DATA, sizeof(struct real_time_data)); - arch_rtc_init(args, sRealTimeData); + +#ifdef _COMPAT_MODE + sRealTimeDataCompat = (struct real_time_data*) + allocate_commpage_compat_entry(COMMPAGE_ENTRY_REAL_TIME_DATA, + sizeof(struct real_time_data)); + arch_rtc_init(args, sRealTimeDataCompat); +#endif + rtc_hw_to_system(); add_debugger_command("rtc", &rtc_debug, "Set and test the real-time clock"); @@ -116,7 +129,12 @@ rtc_init(kernel_args *args) void set_real_time_clock_usecs(bigtime_t currentTime) { - arch_rtc_set_system_time_offset(sRealTimeData, currentTime - system_time()); + arch_rtc_set_system_time_offset(sRealTimeData, currentTime + - system_time()); +#ifdef _COMPAT_MODE + arch_rtc_set_system_time_offset(sRealTimeDataCompat, currentTime + - system_time()); +#endif rtc_system_to_hw(); real_time_clock_changed(); } @@ -257,6 +275,11 @@ _user_set_timezone(int32 timezoneOffset, const char *name, size_t nameLength) arch_rtc_set_system_time_offset(sRealTimeData, arch_rtc_get_system_time_offset(sRealTimeData) + sTimezoneOffset - offset); +#ifdef _COMPAT_MODE + arch_rtc_set_system_time_offset(sRealTimeDataCompat, + arch_rtc_get_system_time_offset(sRealTimeDataCompat) + + sTimezoneOffset - offset); +#endif real_time_clock_changed(); } @@ -302,6 +325,11 @@ _user_set_real_time_clock_is_gmt(bool isGMT) arch_rtc_set_system_time_offset(sRealTimeData, arch_rtc_get_system_time_offset(sRealTimeData) + (sIsGMT ? 1 : -1) * sTimezoneOffset); +#ifdef _COMPAT_MODE + arch_rtc_set_system_time_offset(sRealTimeDataCompat, + arch_rtc_get_system_time_offset(sRealTimeDataCompat) + + (sIsGMT ? 1 : -1) * sTimezoneOffset); +#endif real_time_clock_changed(); }