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
This commit is contained in:
Jérôme Duval 2018-05-07 19:00:21 +02:00
parent cd6365c7ce
commit db9b70ee54
8 changed files with 157 additions and 4 deletions

View File

@ -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 <image.h>
#include <SupportDefs.h>
#define COMMPAGE_COMPAT
#include <commpage_defs.h>
#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 */

View File

@ -1,4 +1,5 @@
/*
* Copyright 2018 Haiku Inc. All Rights Reserved.
* Copyright 2006, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* 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 */

View File

@ -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 <arch/x86/arch_commpage_defs.h>
#else
#include <arch_commpage_defs.h>
#endif
#endif /* _SYSTEM_COMMPAGE_DEFS_H */

View File

@ -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 <commpage_compat.h>
#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;
}

View File

@ -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 <commpage_compat.h>
#else
#include <commpage.h>
#endif
#include <string.h>
@ -13,9 +19,12 @@
#include <vm/vm.h>
#include <vm/vm_types.h>
#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);

View File

@ -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"

View File

@ -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 <boot_item.h>
#include <boot_splash.h>
#include <commpage.h>
#ifdef _COMPAT_MODE
# include <commpage_compat.h>
#endif
#include <condition_variable.h>
#include <cpu.h>
#include <debug.h>
@ -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);

View File

@ -10,6 +10,9 @@
#include <arch/real_time_clock.h>
#include <commpage.h>
#ifdef _COMPAT_MODE
# include <commpage_compat.h>
#endif
#include <real_time_clock.h>
#include <real_time_data.h>
#include <syscalls.h>
@ -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();
}