diff --git a/tools/kvm/Makefile b/tools/kvm/Makefile
index 2bb5713..8aa0125 100644
--- a/tools/kvm/Makefile
+++ b/tools/kvm/Makefile
@@ -38,7 +38,6 @@ PROGRAM	:= lkvm
 PROGRAM_ALIAS := vm
 
 GUEST_INIT := guest/init
-GUEST_INIT_S2 := guest/init_stage2
 
 OBJS	+= builtin-balloon.o
 OBJS	+= builtin-debug.o
@@ -271,7 +270,7 @@ ifneq ($(WERROR),0)
 	CFLAGS += -Werror
 endif
 
-all: arch_support_check $(PROGRAM) $(PROGRAM_ALIAS) $(GUEST_INIT) $(GUEST_INIT_S2)
+all: arch_support_check $(PROGRAM) $(PROGRAM_ALIAS) $(GUEST_INIT)
 
 arch_support_check:
 	$(UNSUPP_ERR)
@@ -287,13 +286,13 @@ KVMTOOLS-VERSION-FILE:
 # $(OTHEROBJS) are things that do not get substituted like this.
 #
 STATIC_OBJS = $(patsubst %.o,%.static.o,$(OBJS) $(OBJS_STATOPT))
-GUEST_OBJS = guest/guest_init.o guest/guest_init_stage2.o
+GUEST_OBJS = guest/guest_init.o
 
-$(PROGRAM)-static:  $(DEPS) $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_INIT) $(GUEST_INIT_S2)
+$(PROGRAM)-static:  $(DEPS) $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_INIT)
 	$(E) "  LINK    " $@
 	$(Q) $(CC) -static $(CFLAGS) $(STATIC_OBJS) $(OTHEROBJS) $(GUEST_OBJS) $(LIBS) $(LIBS_STATOPT) -o $@
 
-$(PROGRAM): $(DEPS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_INIT) $(GUEST_INIT_S2)
+$(PROGRAM): $(DEPS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_INIT)
 	$(E) "  LINK    " $@
 	$(Q) $(CC) $(CFLAGS) $(OBJS) $(OBJS_DYNOPT) $(OTHEROBJS) $(GUEST_OBJS) $(LIBS) $(LIBS_DYNOPT) -o $@
 
@@ -306,11 +305,6 @@ $(GUEST_INIT): guest/init.c
 	$(Q) $(CC) -static guest/init.c -o $@
 	$(Q) $(LD) -r -b binary -o guest/guest_init.o $(GUEST_INIT)
 
-$(GUEST_INIT_S2): guest/init_stage2.c
-	$(E) "  LINK    " $@
-	$(Q) $(CC) -static guest/init_stage2.c -o $@
-	$(Q) $(LD) -r -b binary -o guest/guest_init_stage2.o $(GUEST_INIT_S2)
-
 $(DEPS):
 
 util/rbtree.d: ../../lib/rbtree.c
@@ -407,7 +401,7 @@ clean:
 	$(Q) rm -f x86/bios/bios-rom.h
 	$(Q) rm -f tests/boot/boot_test.iso
 	$(Q) rm -rf tests/boot/rootfs/
-	$(Q) rm -f $(DEPS) $(OBJS) $(OTHEROBJS) $(OBJS_DYNOPT) $(STATIC_OBJS) $(PROGRAM) $(PROGRAM_ALIAS) $(PROGRAM)-static $(GUEST_INIT) $(GUEST_INIT_S2) $(GUEST_OBJS)
+	$(Q) rm -f $(DEPS) $(OBJS) $(OTHEROBJS) $(OBJS_DYNOPT) $(STATIC_OBJS) $(PROGRAM) $(PROGRAM_ALIAS) $(PROGRAM)-static $(GUEST_INIT) $(GUEST_OBJS)
 	$(Q) rm -f cscope.*
 	$(Q) rm -f tags
 	$(Q) rm -f TAGS
diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index 1b407a6..0412e58 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -111,8 +111,6 @@ bool do_debug_print = false;
 static int nrcpus;
 static int vidmode = -1;
 
-extern char _binary_guest_init_stage2_start;
-extern char _binary_guest_init_stage2_size;
 extern char _binary_guest_init_start;
 extern char _binary_guest_init_size;
 
@@ -829,19 +827,6 @@ static int kvm_setup_guest_init(void)
 		die("Fail to setup %s", tmp);
 	close(fd);
 
-	/* Setup /virt/init_stage2 */
-	size = (size_t)&_binary_guest_init_stage2_size;
-	data = (char *)&_binary_guest_init_stage2_start;
-	snprintf(tmp, PATH_MAX, "%s%s/virt/init_stage2", kvm__get_dir(), rootfs);
-	remove(tmp);
-	fd = open(tmp, O_CREAT | O_WRONLY, 0755);
-	if (fd < 0)
-		die("Fail to setup %s", tmp);
-	ret = xwrite(fd, data, size);
-	if (ret < 0)
-		die("Fail to setup %s", tmp);
-	close(fd);
-
 	return 0;
 }
 
diff --git a/tools/kvm/guest/init.c b/tools/kvm/guest/init.c
index 032a261..6a2e1cd 100644
--- a/tools/kvm/guest/init.c
+++ b/tools/kvm/guest/init.c
@@ -7,6 +7,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <errno.h>
+#include <linux/reboot.h>
 
 static int run_process(char *filename)
 {
@@ -16,6 +17,14 @@ static int run_process(char *filename)
 	return execve(filename, new_argv, new_env);
 }
 
+static int run_process_sandbox(char *filename)
+{
+	char *new_argv[] = { filename, "/virt/sandbox.sh", NULL };
+	char *new_env[] = { "TERM=linux", NULL };
+
+	return execve(filename, new_argv, new_env);
+}
+
 static void do_mounts(void)
 {
 	mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L");
@@ -26,11 +35,33 @@ static void do_mounts(void)
 
 int main(int argc, char *argv[])
 {
+	pid_t child;
+	int status;
+
 	puts("Mounting...");
 
 	do_mounts();
 
-	run_process("/virt/init_stage2");
+	/* get session leader */
+	setsid();
+
+	/* set controlling terminal */
+	ioctl(0, TIOCSCTTY, 1);
+
+	child = fork();
+	if (child < 0) {
+		printf("Fatal: fork() failed with %d\n", child);
+		return 0;
+	} else if (child == 0) {
+		if (access("/virt/sandbox.sh", R_OK) == 0)
+			run_process_sandbox("/bin/sh");
+		else
+			run_process("/bin/sh");
+	} else {
+		waitpid(child, &status, 0);
+	}
+
+	reboot(LINUX_REBOOT_CMD_RESTART);
 
 	printf("Init failed: %s\n", strerror(errno));
 
diff --git a/tools/kvm/guest/init_stage2.c b/tools/kvm/guest/init_stage2.c
deleted file mode 100644
index 5f93894..0000000
--- a/tools/kvm/guest/init_stage2.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * This is a stage 2 of the init. This part should do all the heavy
- * lifting such as setting up the console and calling /bin/sh.
- */
-#include <sys/mount.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <linux/reboot.h>
-
-static int run_process(char *filename)
-{
-	char *new_argv[] = { filename, NULL };
-	char *new_env[] = { "TERM=linux", NULL };
-
-	return execve(filename, new_argv, new_env);
-}
-
-static int run_process_sandbox(char *filename)
-{
-	char *new_argv[] = { filename, "/virt/sandbox.sh", NULL };
-	char *new_env[] = { "TERM=linux", NULL };
-
-	return execve(filename, new_argv, new_env);
-}
-
-int main(int argc, char *argv[])
-{
-	pid_t child;
-	int status;
-
-	/* get session leader */
-	setsid();
-
-	/* set controlling terminal */
-	ioctl(0, TIOCSCTTY, 1);
-
-	child = fork();
-	if (child < 0) {
-		printf("Fatal: fork() failed with %d\n", child);
-		return 0;
-	} else if (child == 0) {
-		if (access("/virt/sandbox.sh", R_OK) == 0)
-			run_process_sandbox("/bin/sh");
-		else
-			run_process("/bin/sh");
-	} else {
-		waitpid(child, &status, 0);
-	}
-
-	reboot(LINUX_REBOOT_CMD_RESTART);
-
-	return 0;
-}
