mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-04-28 10:53:40 +00:00
kvmtool/x86: implement guest_pre_init
Add the tiny x86/init.S which just mounts /host and execs /virt/init. NOTE: of course, the usage of CONFIG_GUEST_PRE_INIT is ugly, we need to cleanup this code. But I'd prefer to do this on top of this minimal/simple change. And I think this needs cleanups in any case, for example I think lkvm shouldn't abuse the "init=" kernel parameter at all. Acked-by: Pekka Enberg <penberg@kernel.org> Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:
committed by
Will Deacon
parent
0f04bdf429
commit
5614f9d933
1
Makefile
1
Makefile
@@ -110,6 +110,7 @@ endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ARCH := x86
|
||||
DEFINES += -DCONFIG_X86_64
|
||||
ARCH_PRE_INIT = x86/init.S
|
||||
endif
|
||||
|
||||
### Arch-specific stuff
|
||||
|
||||
@@ -594,7 +594,11 @@ static struct kvm *kvm_cmd_run_init(int argc, const char **argv)
|
||||
if (kvm->cfg.custom_rootfs) {
|
||||
kvm_run_set_sandbox(kvm);
|
||||
|
||||
#ifdef CONFIG_GUEST_PRE_INIT
|
||||
strcat(real_cmdline, " init=/virt/pre_init");
|
||||
#else
|
||||
strcat(real_cmdline, " init=/virt/init");
|
||||
#endif
|
||||
|
||||
if (!kvm->cfg.no_dhcp)
|
||||
strcat(real_cmdline, " ip=dhcp");
|
||||
|
||||
@@ -144,12 +144,24 @@ static int extract_file(const char *guestfs_name, const char *filename,
|
||||
|
||||
extern char _binary_guest_init_start;
|
||||
extern char _binary_guest_init_size;
|
||||
extern char _binary_guest_pre_init_start;
|
||||
extern char _binary_guest_pre_init_size;
|
||||
|
||||
int kvm_setup_guest_init(const char *guestfs_name)
|
||||
{
|
||||
return extract_file(guestfs_name, "virt/init",
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_GUEST_PRE_INIT
|
||||
err = extract_file(guestfs_name, "virt/pre_init",
|
||||
&_binary_guest_pre_init_start,
|
||||
&_binary_guest_pre_init_size);
|
||||
if (err)
|
||||
return err;
|
||||
#endif
|
||||
err = extract_file(guestfs_name, "virt/init",
|
||||
&_binary_guest_init_start,
|
||||
&_binary_guest_init_size);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
int kvm_setup_guest_init(const char *guestfs_name)
|
||||
|
||||
@@ -30,7 +30,9 @@ static int run_process_sandbox(char *filename)
|
||||
|
||||
static void do_mounts(void)
|
||||
{
|
||||
#ifndef CONFIG_GUEST_PRE_INIT
|
||||
mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L");
|
||||
#endif
|
||||
mount("", "/sys", "sysfs", 0, NULL);
|
||||
mount("proc", "/proc", "proc", 0, NULL);
|
||||
mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
|
||||
|
||||
38
x86/init.S
Normal file
38
x86/init.S
Normal file
@@ -0,0 +1,38 @@
|
||||
.data
|
||||
|
||||
.m_dev:
|
||||
.string "hostfs"
|
||||
.m_dir:
|
||||
.string "/host"
|
||||
.m_typ:
|
||||
.string "9p"
|
||||
.m_opt:
|
||||
.string "trans=virtio,version=9p2000.L"
|
||||
|
||||
.e_nam:
|
||||
.string "/virt/init"
|
||||
|
||||
.text
|
||||
.globl _start
|
||||
_start:
|
||||
|
||||
mov $165, %rax # __NR_mount
|
||||
mov $.m_dev, %rdi
|
||||
mov $.m_dir, %rsi
|
||||
mov $.m_typ, %rdx
|
||||
mov $1, %r10 # MS_RDONLY
|
||||
mov $.m_opt, %r8
|
||||
syscall
|
||||
|
||||
mov $59, %rax # __NR_execve
|
||||
mov $.e_nam, %rdi
|
||||
lea 8(%rsp), %rsi # argv[]
|
||||
mov %rdi, (%rsi) # change argv[0]
|
||||
pop %rcx # argc
|
||||
inc %rcx
|
||||
lea (%rsi,%rcx,8), %rdx # envp[]
|
||||
syscall
|
||||
|
||||
mov $60, %rax # __NR_exit
|
||||
mov $1, %rdi
|
||||
syscall # panic
|
||||
Reference in New Issue
Block a user