kernel/x86_64: remove memset and memcpy from commpage

There is absolutely no reason for these functions to be in commpage,
they don't do anything that involves the kernel in any way.

Additionaly, this patch rewrites memset and memcpy to C++, current
implementation is quite simple (though it may perform surprisingly
well when dealing with large buffers on cpus with ermsb). Better
versions are coming soon.

Signed-off-by: Paweł Dziepak <[email protected]>
This commit is contained in:
Paweł Dziepak
2014-09-14 19:16:52 +02:00
parent 6156a508ad
commit f2f91078bd
8 changed files with 55 additions and 131 deletions
@@ -9,11 +9,9 @@
# error Must not be included directly. Include <commpage_defs.h> instead!
#endif
#define COMMPAGE_ENTRY_X86_MEMCPY (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
#define COMMPAGE_ENTRY_X86_MEMSET (COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
#define COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 2)
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 0)
#define COMMPAGE_ENTRY_X86_THREAD_EXIT \
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3)
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 1)
#endif /* _SYSTEM_ARCH_x86_64_COMMPAGE_DEFS_H */
@@ -30,6 +30,10 @@ extern "C" void x86_sysenter();
void (*gX86SetSyscallStack)(addr_t stackTop) = NULL;
extern int memcpy_end;
extern int memset_end;
static bool
all_cpus_have_feature(enum x86_feature_type type, int feature)
{
@@ -109,8 +113,20 @@ x86_initialize_syscall(void)
addr_t position = fill_commpage_entry(COMMPAGE_ENTRY_X86_SYSCALL,
syscallCode, len);
// put the optimized functions into the commpage
size_t memcpyLen = (addr_t)&memcpy_end - (addr_t)memcpy;
addr_t memcpyPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY,
(const void*)memcpy, memcpyLen);
size_t memsetLen = (addr_t)&memset_end - (addr_t)memset;
addr_t memsetPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET,
(const void*)memset, memsetLen);
// add syscall to the commpage image
image_id image = get_commpage_image();
elf_add_memory_image_symbol(image, "commpage_memcpy", memcpyPosition,
memcpyLen, B_SYMBOL_TYPE_TEXT);
elf_add_memory_image_symbol(image, "commpage_memset", memsetPosition,
memsetLen, B_SYMBOL_TYPE_TEXT);
elf_add_memory_image_symbol(image, "commpage_syscall", position, len,
B_SYMBOL_TYPE_TEXT);
}
+1 -14
View File
@@ -105,9 +105,6 @@ static const size_t kDoubleFaultStackSize = 4096; // size per CPU
static x86_cpu_module_info* sCpuModule;
extern int memcpy_end;
extern int memset_end;
/* CPU topology information */
static uint32 (*sGetCPUTopologyID)(int currentCPU);
static uint32 sHierarchyMask[CPU_TOPOLOGY_LEVELS];
@@ -1154,13 +1151,6 @@ arch_cpu_init_post_modules(kernel_args* args)
call_all_cpus(&init_mtrrs, NULL);
}
// put the optimized functions into the commpage
size_t memcpyLen = (addr_t)&memcpy_end - (addr_t)memcpy;
addr_t memcpyPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMCPY,
(const void*)memcpy, memcpyLen);
size_t memsetLen = (addr_t)&memset_end - (addr_t)memset;
addr_t memsetPosition = fill_commpage_entry(COMMPAGE_ENTRY_X86_MEMSET,
(const void*)memset, memsetLen);
size_t threadExitLen = (addr_t)x86_end_userspace_thread_exit
- (addr_t)x86_userspace_thread_exit;
addr_t threadExitPosition = fill_commpage_entry(
@@ -1169,10 +1159,7 @@ arch_cpu_init_post_modules(kernel_args* args)
// add the functions to the commpage image
image_id image = get_commpage_image();
elf_add_memory_image_symbol(image, "commpage_memcpy", memcpyPosition,
memcpyLen, B_SYMBOL_TYPE_TEXT);
elf_add_memory_image_symbol(image, "commpage_memset", memsetPosition,
memsetLen, B_SYMBOL_TYPE_TEXT);
elf_add_memory_image_symbol(image, "commpage_thread_exit",
threadExitPosition, threadExitLen, B_SYMBOL_TYPE_TEXT);
+2 -5
View File
@@ -21,6 +21,7 @@ KernelMergeObject kernel_os_arch_$(TARGET_ARCH).o :
;
SEARCH_SOURCE += [ FDirName $(posixSources) arch $(TARGET_ARCH) ] ;
SEARCH_SOURCE += [ FDirName $(posixSources) string arch $(TARGET_ARCH) ] ;
KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o :
siglongjmp.S
@@ -28,12 +29,8 @@ KernelMergeObject kernel_lib_posix_arch_$(TARGET_ARCH).o :
kernel_longjmp_return.c
kernel_setjmp_save_sigs.c
arch_string.S
arch_string.cpp
: $(TARGET_KERNEL_PIC_CCFLAGS)
;
# Explicitly tell the build system that arch_string.S includes the generated
# asm_offsets.h.
Includes [ FGristFiles arch_string.S ]
: <src!system!kernel!arch!x86>asm_offsets.h ;
@@ -1,85 +0,0 @@
/*
* Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
* Distributed under the terms of the MIT License.
*/
#include <asm_defs.h>
.align 8
FUNCTION(memcpy):
push %rbp
movq %rsp, %rbp
// Preserve original destination address for return value.
movq %rdi, %rax
// size -> %rcx
movq %rdx, %rcx
// For small copies, always do it bytewise, the additional overhead is
// not worth it.
cmp $24, %rcx
jl .Lmemcpy_generic_byte_copy
// Do both source and dest have the same alignment?
movq %rsi, %r8
xorq %rdi, %r8
test $7, %r8
jnz .Lmemcpy_generic_byte_copy
// Align up to an 8-byte boundary.
movq %rdi, %r8
andq $7, %r8
jz .Lmemcpy_generic_qword_copy
movq $8, %rcx
subq %r8, %rcx
subq %rcx, %rdx // Subtract from the overall count.
rep
movsb
// Get back the original count value.
movq %rdx, %rcx
.Lmemcpy_generic_qword_copy:
// Move by quadwords.
shrq $3, %rcx
rep
movsq
// Get the remaining count.
movq %rdx, %rcx
andq $7, %rcx
.Lmemcpy_generic_byte_copy:
// Move any remaining data by bytes.
rep
movsb
pop %rbp
ret
FUNCTION_END(memcpy)
SYMBOL(memcpy_end):
.align 8
FUNCTION(memset):
push %rbp
movq %rsp, %rbp
// Preserve original destination address for return value.
movq %rdi, %r8
// size -> %rcx, value -> %al
movq %rdx, %rcx
movl %esi, %eax
// Move by bytes.
rep
stosb
movq %r8, %rax
pop %rbp
ret
FUNCTION_END(memset)
SYMBOL(memset_end):
@@ -1,5 +1,7 @@
SubDir HAIKU_TOP src system libroot posix string arch x86_64 ;
SubDirC++Flags -std=gnu++11 ;
local architectureObject ;
for architectureObject in [ MultiArchSubDirSetup x86_64 ] {
on $(architectureObject) {
@@ -8,7 +10,7 @@ for architectureObject in [ MultiArchSubDirSetup x86_64 ] {
UsePrivateSystemHeaders ;
MergeObject <$(architecture)>posix_string_arch_$(TARGET_ARCH).o :
arch_string.S
arch_string.cpp
;
}
}
@@ -1,22 +0,0 @@
/*
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <asm_defs.h>
#include <commpage_defs.h>
FUNCTION(memcpy):
movq __gCommPageAddress@GOTPCREL(%rip), %rax
movq (%rax), %rax
addq 8 * COMMPAGE_ENTRY_X86_MEMCPY(%rax), %rax
jmp *%rax
FUNCTION_END(memcpy)
FUNCTION(memset):
movq __gCommPageAddress@GOTPCREL(%rip), %rax
movq (%rax), %rax
addq 8 * COMMPAGE_ENTRY_X86_MEMSET(%rax), %rax
jmp *%rax
FUNCTION_END(memset)
@@ -0,0 +1,31 @@
/*
* Copyright 2014, Paweł Dziepak, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <cstddef>
extern "C" void*
memcpy(void* destination, const void* source, size_t length)
{
auto returnValue = destination;
__asm__ __volatile__("rep movsb"
: "+D" (destination), "+S" (source), "+c" (length)
: : "memory");
return returnValue;
}
extern "C" void*
memset(void* destination, int value, size_t length)
{
auto returnValue = destination;
__asm__ __volatile__("rep stosb"
: "+D" (destination), "+c" (length)
: "a" (value)
: "memory");
return returnValue;
}