Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
xcap
xcap-capability-linux
Commits
127a863f
Commit
127a863f
authored
Mar 17, 2014
by
Weibin Sun
Committed by
Vikram Narayanan
Oct 25, 2016
Browse files
loader code done
Conflicts: arch/x86/lcd/lcd_main.c Resolved-by:
Vikram Narayanan
<
vikram186@gmail.com
>
parent
a62128fc
Changes
3
Hide whitespace changes
Inline
Side-by-side
arch/x86/lcd/lcd_defs.h
View file @
127a863f
...
...
@@ -196,29 +196,29 @@ typedef struct {
/* Memory layout */
// Range format: [begin, end)
// 0x0000 0000 0000 0000 ~ 0x0000 0000 0100 0000 : 16MB : hole (Avoid possible MMIO)
// 0x0000 0000 0100 0000 ~ 0x0000 0000 0500 0000 : 64MB : Page table structures
// 0x0000 0000 0000 0000 ~ 0x0000 0000 4000 0000 : 1GB : Physical Mem
// 4K gap
// 0x0000 0000 4000 1000 ~ 0x0000 0000 4040 1000 : 4MB : Page table structures
// 0x0000 0000 4040 1000 ~ 0x0000 0000 4040 2000 : 4KB : GDT
// 0x0000 0000 4040 2000 ~ 0x0000 0000 4040 3000 : 4KB : IDT
// 0x0000 0000 4040 3000 ~ 0x0000 0000 4040 4000 : 4KB : TSS page (sizeof(lcd_tss_struct))
// 4K page gap as memory guard
// 0x0000 0000 0500 1000 ~ 0x0000 0000 0500 2000 : 4KB : GDT
// 0x0000 0000 0500 2000 ~ 0x0000 0000 0500 3000 : 4KB : IDT
// 0x0000 0000 0500 3000 ~ 0x0000 0000 0500 4000 : 4KB : TSS page (sizeof(lcd_tss_struct))
// 4K page gap as memory guard
// 0x0000 0000 0500 5000 ~ 0x0000 0000 0500 6000 : 4KB : Common ISR code page
// 4K memory guard
// 0x0000 0000 0500 7000 ~ 0x0000 0000 0500 F000 : 32KB : stack
// 0x0000 0000 4040 5000 ~ 0x0000 0000 4040 6000 : 4KB : Common ISR code page
// 4K memory guard
// 0x0000 0000
0501 0
000 ~ 0x0000 0000
0511 0000 : 1MB : 256 ISRs, 4KB code page per ISR
// 0x0000 0000
4040 7
000 ~ 0x0000 0000
4040 F000 : 32KB : stack
// 4K memory guard
// 0x0000 0000 0511 1000 ~ Memory limit : Code/data (start from 81MB+68KB)
//
// Todo:
// Heap start; Heap end.
// 0x0000 0000 4041 0000 ~ 0x0000 0000 4051 0000 : 1MB : 256 ISRs, 4KB code page per ISR
// Bootup structure:
#define LCD_PHY_MEM_SIZE (1 << 30)
/* 1GB physical mem */
#define LCD_NR_PT_PAGES (1 << 1
4
)
/* #pages for page table */
#define LCD_PT_PAGES_START (
0x1ULL << 24)
/* above 16M
B */
#define LCD_NR_PT_PAGES (1 << 1
0
)
/* #pages for page table */
#define LCD_PT_PAGES_START (
LCD_PHY_MEM_SIZE + PAGE_SIZE)
/* 1GB + 4K
B */
#define LCD_PT_PAGES_END (LCD_PT_PAGES_START + (LCD_NR_PT_PAGES << PAGE_SHIFT))
#define LCD_GDT_ADDR (LCD_PT_PAGES_END
+ PAGE_SIZE
)
/* start from
80MB
+ 4K
B
*/
#define LCD_GDT_ADDR (LCD_PT_PAGES_END)
/* start from
1G + 4M
+ 4K */
#define LCD_IDT_ADDR (LCD_GDT_ADDR + PAGE_SIZE)
#define LCD_TSS_ADDR (LCD_IDT_ADDR + PAGE_SIZE)
#define LCD_TSS_SIZE (sizeof(struct lcd_tss_struct))
...
...
@@ -236,6 +236,8 @@ typedef struct {
#define LCD_ISR_END (LCD_ISR_START + LCD_NR_ISRS*PAGE_SIZE)
#define LCD_ISR_ADDR(n) (LCD_ISR_START + (n)*PAGE_SIZE)
#define LCD_PHY_MEM_LIMIT LCD_ISR_END
#define LCD_FREE_MEM_START (LCD_ISR_END + PAGE_SIZE)
#define LCD_TEST_CODE_ADDR LCD_FREE_MEM_START
...
...
@@ -255,4 +257,8 @@ const char* lcd_exit_reason(int exit_code);
// Inside LCD:
int
lcd_read_mod_file
(
const
char
*
filepath
,
void
**
content
,
long
*
size
);
int
lcd_load_vmlinux
(
const
char
*
kfile
,
lcd_struct
*
lcd
,
u64
*
elf_entry
);
#endif
arch/x86/lcd/lcd_main.c
View file @
127a863f
...
...
@@ -440,7 +440,7 @@ static int ept_alloc_pt_item(lcd_struct *vcpu,
ret
=
ept_lookup_gpa
(
vcpu
,
(
void
*
)((
*
gpfn
)
<<
PAGE_SHIFT
),
1
,
&
epte
);
if
(
!
ret
)
{
if
(
!
epte_present
(
*
epte
))
{
*
page
=
__get_free_page
(
GFP_
ATOMIC
);
*
page
=
__get_free_page
(
GFP_
KERNEL
);
if
(
!
(
*
page
))
{
ret
=
-
ENOMEM
;
}
else
{
...
...
@@ -679,44 +679,6 @@ static int vmx_setup_initial_page_table(lcd_struct *vcpu) {
gpa
+=
PAGE_SIZE
;
}
/* Test code page */
gpa
=
gva
=
LCD_TEST_CODE_ADDR
;
ret
=
map_gva_to_gpa
(
vcpu
,
gva
,
gpa
,
1
,
0
);
if
(
ret
)
{
printk
(
KERN_ERR
"ept: populate code page failed
\n
"
);
return
ret
;
}
hpa
=
__get_free_page
(
GFP_KERNEL
);
if
(
!
hpa
)
return
-
ENOMEM
;
memset
((
void
*
)
hpa
,
0
,
PAGE_SIZE
);
{
u8
*
bincode
=
(
u8
*
)
hpa
;
/* 0: b8 e0 0f 00 01 mov $0x1000fe0,%eax*/
/* 5: c7 00 ef be ad de movl $0xdeadbeef,(%rax) */
/* ((u8*)hpa)[0] = 0xb8; ((u8*)hpa)[1] = 0xe0; ((u8*)hpa)[2] = 0xf; ((u8*)hpa)[3] = 0x10; */
/* ((u8*)hpa)[5] = 0xc7; ((u8*)hpa)[7] = 0xef; ((u8*)hpa)[8] = 0xbe; ((u8*)hpa)[9] = 0xad; */
/* ((u8*)hpa)[10] = 0xde; */
/* ((u8*)hpa)[11] = 0xf4; ((u8*)hpa)[12] = 0xf4; */
bincode
[
0
]
=
0xf
;
bincode
[
1
]
=
0x1
;
bincode
[
2
]
=
0xc1
;
bincode
[
3
]
=
0xb8
;
bincode
[
4
]
=
0x34
;
bincode
[
5
]
=
0x12
;
bincode
[
8
]
=
0x48
;
bincode
[
9
]
=
0x89
;
bincode
[
10
]
=
0xc1
;
bincode
[
11
]
=
0xeb
;
bincode
[
12
]
=
0xf6
;
bincode
[
13
]
=
0x90
;
bincode
[
14
]
=
0xf4
;
}
hpa
=
__pa
(
hpa
);
ret
=
ept_set_epte
(
vcpu
,
gpa
,
hpa
,
0
);
if
(
ret
)
{
printk
(
KERN_ERR
"ept: map code page failed
\n
"
);
return
ret
;
}
// commented to check the dynamically allocated stack
#if 0
/* Map stack PT */
gpa
=
gva
=
LCD_STACK_BOTTOM
;
for
(
i
=
0
;
i
<
(
LCD_STACK_SIZE
>>
PAGE_SHIFT
);
++
i
)
{
...
...
@@ -740,7 +702,7 @@ static int vmx_setup_initial_page_table(lcd_struct *vcpu) {
gva
+=
PAGE_SIZE
;
gpa
+=
PAGE_SIZE
;
}
#endif
/* Map descriptors and tables in EPT */
ret
=
ept_set_epte
(
vcpu
,
LCD_GDT_ADDR
,
__pa
(
vcpu
->
gdt
),
0
);
if
(
ret
)
{
...
...
@@ -1686,11 +1648,26 @@ static int vmx_handle_ept_violation(lcd_struct *vcpu) {
return
-
EINVAL
;
}
/* TODO: fix this. Now we fail on EPT fault unconditionally. */
/* ret = vmx_do_ept_fault(vcpu, gpa, gva, exit_qual); */
printk
(
KERN_INFO
"EPT: get violation GPA 0x%lx, GVA: 0x%lx, fail now!
\n
"
,
gpa
,
gva
);
ret
=
-
EINVAL
;
/*
* EPT Fault.
* TODO: lock page table?
*/
if
(
gpa
<
LCD_PHY_MEM_SIZE
)
{
u64
gpa_pg
;
u64
pg
=
__get_free_page
(
GFP_KERNEL
);
if
(
!
pg
)
ret
=
-
ENOMEM
;
else
{
gpa_pg
=
round_down
(
gpa
,
PAGE_SIZE
);
ret
=
lcd_map_gpa_to_hpa
(
vcpu
,
gpa_pg
,
__pa
(
pg
),
0
);
if
(
ret
)
{
printk
(
KERN_ERR
"EPT: map page %p for %p failed
\n
"
,
(
void
*
)
pg
,
(
void
*
)
gpa_pg
);
free_page
(
pg
);
}
}
}
else
ret
=
-
EINVAL
;
if
(
ret
)
{
printk
(
KERN_ERR
"vmx: EPT violation failure "
...
...
arch/x86/lcd/utils.c
View file @
127a863f
#include
<linux/kernel.h>
#include
<linux/module.h>
#include
<linux/mm.h>
#include
<linux/slab.h>
#include
<linux/string.h>
#include
<uapi/asm/kvm.h>
#include
<linux/fs.h>
...
...
@@ -10,6 +11,7 @@
#include
<asm/uaccess.h>
#include
<asm/vmx.h>
#include
<uapi/linux/elf.h>
#include
"lcd_defs.h"
...
...
@@ -58,7 +60,115 @@ error_out:
return
err
;
}
int
lcd_load_vmlinux
(
const
char
*
kfile
,
lcd_struct
*
lcd
)
{
void
process_vmlinux_note
(
lcd_struct
*
lcd
,
Elf64_Phdr
*
hdr
,
struct
file
*
filp
)
{
char
*
name
,
*
desc
;
u64
ofs
;
Elf64_Nhdr
nhdr
;
int
ret
;
u64
pos
;
/* REQ: Name and Desc size less than half page */
name
=
(
char
*
)
__get_free_page
(
GFP_KERNEL
);
if
(
!
name
)
{
printk
(
KERN_ERR
"Out of mem for note
\n
"
);
return
;
}
desc
=
name
+
(
PAGE_SIZE
>
1
);
ofs
=
hdr
->
p_offset
;
pos
=
ofs
;
while
(
ofs
<
hdr
->
p_offset
+
hdr
->
p_filesz
)
{
ret
=
vfs_read
(
filp
,
(
char
*
)
&
nhdr
,
sizeof
(
nhdr
),
&
pos
);
if
(
ret
!=
sizeof
(
nhdr
))
{
printk
(
KERN_ERR
"Error reading vmlinux note
\n
"
);
goto
after_mem_out
;
}
if
(
nhdr
.
n_namesz
>
0
)
{
ret
=
vfs_read
(
filp
,
name
,
round_up
(
nhdr
.
n_namesz
,
hdr
->
p_align
),
&
pos
);
if
(
ret
!=
round_up
(
nhdr
.
n_namesz
,
hdr
->
p_align
))
{
printk
(
KERN_ERR
"Error reading vmlinux note name
\n
"
);
goto
after_mem_out
;
}
}
if
(
nhdr
.
n_descsz
>
0
)
{
ret
=
vfs_read
(
filp
,
desc
,
round_up
(
nhdr
.
n_descsz
,
hdr
->
p_align
),
&
pos
);
if
(
ret
!=
round_up
(
nhdr
.
n_descsz
,
hdr
->
p_align
))
{
printk
(
KERN_ERR
"Error reading vmlinux note desc
\n
"
);
goto
after_mem_out
;
}
}
/* TODO: use Xen notes */
}
after_mem_out:
free_page
((
u64
)
name
);
}
void
load_vmlinux_segment
(
lcd_struct
*
lcd
,
Elf64_Phdr
*
hdr
,
struct
file
*
filp
)
{
u64
sz
,
left
;
int
ret
;
u64
hva
,
gpa
;
u64
pos
;
pos
=
hdr
->
p_offset
;
left
=
hdr
->
p_filesz
;
gpa
=
round_down
(
hdr
->
p_paddr
,
PAGE_SIZE
);
sz
=
PAGE_SIZE
-
(
hdr
->
p_paddr
-
gpa
);
if
(
sz
>
hdr
->
p_filesz
)
sz
=
hdr
->
p_filesz
;
while
(
left
>
0
)
{
ret
=
lcd_find_hva_by_gpa
(
lcd
,
gpa
,
&
hva
);
if
(
ret
==
-
ENOENT
)
{
hva
=
__get_free_page
(
GFP_KERNEL
);
if
(
!
hva
)
{
printk
(
KERN_ERR
"Out of memory for vmlinux
\n
"
);
return
;
}
if
(
lcd_map_gpa_to_hpa
(
lcd
,
gpa
,
__pa
(
hva
),
0
))
{
printk
(
KERN_ERR
"Map ept page failed
\n
"
);
free_page
(
hva
);
return
;
}
if
(
lcd_map_gva_to_gpa
(
lcd
,
gpa
,
gpa
,
1
,
0
))
{
printk
(
KERN_ERR
"Map gva to gpa failed
\n
"
);
return
;
}
}
else
if
(
ret
)
{
printk
(
KERN_ERR
"Find hva error %p
\n
"
,
(
void
*
)
gpa
);
return
;
}
if
(
left
==
hdr
->
p_filesz
)
hva
+=
hdr
->
p_paddr
-
gpa
;
ret
=
vfs_read
(
filp
,
(
void
*
)
hva
,
sz
,
&
pos
);
if
(
ret
!=
sz
)
{
printk
(
KERN_ERR
"Error reading vmlinux %d
\n
"
,
ret
);
return
;
}
left
-=
sz
;
sz
=
(
left
>
PAGE_SIZE
)
?
PAGE_SIZE
:
left
;
gpa
+=
PAGE_SIZE
;
}
}
int
lcd_load_vmlinux
(
const
char
*
kfile
,
lcd_struct
*
lcd
,
u64
*
elf_entry
)
{
Elf64_Ehdr
hdr
;
Elf64_Phdr
*
phdrs
;
mm_segment_t
oldfs
;
...
...
@@ -77,7 +187,7 @@ int lcd_load_vmlinux(const char* kfile, lcd_struct *lcd) {
goto
error_out
;
}
err
=
vfs_read
(
filp
,
&
hdr
,
sizeof
(
hdr
),
&
pos
);
err
=
vfs_read
(
filp
,
(
char
*
)
&
hdr
,
sizeof
(
hdr
),
&
pos
);
if
(
err
!=
sizeof
(
hdr
))
{
printk
(
KERN_ERR
"Error when reading vmlinux %d
\n
"
,
err
);
goto
after_open_error_out
;
...
...
@@ -90,15 +200,15 @@ int lcd_load_vmlinux(const char* kfile, lcd_struct *lcd) {
goto
after_open_error_out
;
}
phdrs
=
kmalloc
(
sizeof
(
Elf64_Phdr
)
*
hdr
.
e_phnum
,
G
P
F_KERNEL
);
phdrs
=
kmalloc
(
sizeof
(
Elf64_Phdr
)
*
hdr
.
e_phnum
,
GF
P
_KERNEL
);
if
(
!
phdrs
)
{
err
=
-
ENOMEM
;
printk
(
KERN_ERR
"Out of mem
\n
"
);
goto
after_open_error_out
;
}
pos
=
hdr
->
e_phoff
;
err
=
vfs_read
(
filp
,
phdrs
,
sizeof
(
Elf64_Phdr
)
*
hdr
.
e_phnum
,
&
pos
);
pos
=
hdr
.
e_phoff
;
err
=
vfs_read
(
filp
,
(
char
*
)
phdrs
,
sizeof
(
Elf64_Phdr
)
*
hdr
.
e_phnum
,
&
pos
);
if
(
err
!=
sizeof
(
Elf64_Phdr
)
*
hdr
.
e_phnum
)
{
printk
(
KERN_ERR
"Error when reading p hdrs %d
\n
"
,
err
);
goto
after_mem_error_out
;
...
...
@@ -110,11 +220,15 @@ int lcd_load_vmlinux(const char* kfile, lcd_struct *lcd) {
if
(
phdrs
[
i
].
p_type
!=
PT_NOTE
)
continue
;
else
{
// todo READ NOTE.
process_vmlinux_note
(
lcd
,
&
phdrs
[
i
],
filp
);
}
}
else
{
load_vmlinux_segment
(
lcd
,
&
phdrs
[
i
],
filp
);
}
}
*
elf_entry
=
hdr
.
e_entry
;
after_mem_error_out:
kfree
(
phdrs
);
after_open_error_out:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment