add vsyscall
- getcpu() is not implemented. It will cause SIGILL. - gettimeofday() and time() are implemented with syscall.
This commit is contained in:
@@ -1698,6 +1698,21 @@ void init_low_area(struct page_table *pt)
|
|||||||
set_pt_large_page(pt, 0, 0, PTATTR_WRITABLE);
|
set_pt_large_page(pt, 0, 0, PTATTR_WRITABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_vsyscall_area(struct page_table *pt)
|
||||||
|
{
|
||||||
|
extern char vsyscall_page[];
|
||||||
|
int error;
|
||||||
|
|
||||||
|
#define VSYSCALL_ADDR ((void *)(0xffffffffff600000))
|
||||||
|
error = __set_pt_page(pt, VSYSCALL_ADDR,
|
||||||
|
virt_to_phys(vsyscall_page), PTATTR_ACTIVE|PTATTR_USER);
|
||||||
|
if (error) {
|
||||||
|
panic("init_vsyscall_area:__set_pt_page failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void init_page_table(void)
|
void init_page_table(void)
|
||||||
{
|
{
|
||||||
#ifdef USE_LARGE_PAGES
|
#ifdef USE_LARGE_PAGES
|
||||||
@@ -1712,6 +1727,7 @@ void init_page_table(void)
|
|||||||
init_fixed_area(init_pt);
|
init_fixed_area(init_pt);
|
||||||
init_low_area(init_pt);
|
init_low_area(init_pt);
|
||||||
init_text_area(init_pt);
|
init_text_area(init_pt);
|
||||||
|
init_vsyscall_area(init_pt);
|
||||||
|
|
||||||
load_page_table(init_pt);
|
load_page_table(init_pt);
|
||||||
kprintf("Page table is now at %p\n", init_pt);
|
kprintf("Page table is now at %p\n", init_pt);
|
||||||
|
|||||||
60
arch/x86/kernel/vsyscall.c
Normal file
60
arch/x86/kernel/vsyscall.c
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
* \file vsyscall.c
|
||||||
|
* License details are found in the file LICENSE.
|
||||||
|
* \brief
|
||||||
|
* implements x86's vsyscall
|
||||||
|
* \author Gou Nakamura <go.nakamura.yw@hitachi-solutions.com> \par
|
||||||
|
* Copyright (C) 2014 Hitachi, Ltd.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* HISTORY:
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* .vsyscall.* section's LMAs are different from their VMA.
|
||||||
|
* make sure that these are position-independent codes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
extern int vsyscall_gettimeofday(void *tv, void *tz)
|
||||||
|
__attribute__ ((section (".vsyscall.gettimeofday")));
|
||||||
|
|
||||||
|
int vsyscall_gettimeofday(void *tv, void *tz)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
|
||||||
|
asm ("syscall" : "=a" (error)
|
||||||
|
: "a" (__NR_gettimeofday), "D" (tv), "S" (tz)
|
||||||
|
: "%rcx", "%r11", "memory");
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern long vsyscall_time(void *tp)
|
||||||
|
__attribute__ ((section (".vsyscall.time")));
|
||||||
|
|
||||||
|
long vsyscall_time(void *tp)
|
||||||
|
{
|
||||||
|
long t;
|
||||||
|
|
||||||
|
asm ( "syscall ;"
|
||||||
|
/*
|
||||||
|
* This vsyscall_time() cannot fail, because glibc's
|
||||||
|
* vsyscall_time() does not set the errno.
|
||||||
|
*
|
||||||
|
* Because a possible error is only a memory access error,
|
||||||
|
* in order that this function generates SIGSEGV
|
||||||
|
* rather than returns error when a memory access error occurs,
|
||||||
|
* this function accesses memory in user mode.
|
||||||
|
*/
|
||||||
|
"test %%rdx,%%rdx;"
|
||||||
|
"jz 1f;"
|
||||||
|
"mov %%rax,(%%rdx);"
|
||||||
|
"1:"
|
||||||
|
: "=a" (t)
|
||||||
|
: "a" (__NR_time), "d" (tp), "D" (0)
|
||||||
|
: "%rcx", "%r11", "memory");
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
@@ -20,6 +20,19 @@ SECTIONS
|
|||||||
.rodata : {
|
.rodata : {
|
||||||
*(.rodata .rodata.*)
|
*(.rodata .rodata.*)
|
||||||
} :data
|
} :data
|
||||||
|
|
||||||
|
.vsyscall : ALIGN(0x1000) {
|
||||||
|
vsyscall_page = .;
|
||||||
|
|
||||||
|
. = vsyscall_page + 0x000;
|
||||||
|
*(.vsyscall.gettimeofday)
|
||||||
|
|
||||||
|
. = vsyscall_page + 0x400;
|
||||||
|
*(.vsyscall.time)
|
||||||
|
|
||||||
|
. = ALIGN(4096);
|
||||||
|
} : data = 0xf4
|
||||||
|
|
||||||
.bss : {
|
.bss : {
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,19 @@ SECTIONS
|
|||||||
.rodata : {
|
.rodata : {
|
||||||
*(.rodata .rodata.*)
|
*(.rodata .rodata.*)
|
||||||
} :data
|
} :data
|
||||||
|
|
||||||
|
.vsyscall : ALIGN(0x1000) {
|
||||||
|
vsyscall_page = .;
|
||||||
|
|
||||||
|
. = vsyscall_page + 0x000;
|
||||||
|
*(.vsyscall.gettimeofday)
|
||||||
|
|
||||||
|
. = vsyscall_page + 0x400;
|
||||||
|
*(.vsyscall.time)
|
||||||
|
|
||||||
|
. = ALIGN(4096);
|
||||||
|
} : data = 0xf4
|
||||||
|
|
||||||
.bss : {
|
.bss : {
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,19 @@ SECTIONS
|
|||||||
.rodata : {
|
.rodata : {
|
||||||
*(.rodata .rodata.*)
|
*(.rodata .rodata.*)
|
||||||
} :data
|
} :data
|
||||||
|
|
||||||
|
.vsyscall : ALIGN(0x1000) {
|
||||||
|
vsyscall_page = .;
|
||||||
|
|
||||||
|
. = vsyscall_page + 0x000;
|
||||||
|
*(.vsyscall.gettimeofday)
|
||||||
|
|
||||||
|
. = vsyscall_page + 0x400;
|
||||||
|
*(.vsyscall.time)
|
||||||
|
|
||||||
|
. = ALIGN(4096);
|
||||||
|
} : data = 0xf4
|
||||||
|
|
||||||
.bss : {
|
.bss : {
|
||||||
*(.bss .bss.*)
|
*(.bss .bss.*)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#ifndef __HEADER_SYSCALL_H
|
#ifndef __HEADER_SYSCALL_H
|
||||||
#define __HEADER_SYSCALL_H
|
#define __HEADER_SYSCALL_H
|
||||||
|
|
||||||
|
#include <ihk/context.h>
|
||||||
#include <ihk/memconst.h>
|
#include <ihk/memconst.h>
|
||||||
|
|
||||||
#define NUM_SYSCALLS 255
|
#define NUM_SYSCALLS 255
|
||||||
|
|||||||
Reference in New Issue
Block a user