1import os
2import time
3
4import infra.basetest
5
6
7class TestJailhouse(infra.basetest.BRTest):
8    # This test uses a specific configuration, mainly for matching the
9    # requirements of the Jailhouse Qemu inmate demo. We also use the
10    # Linux kernel from Siemens, which includes patches for
11    # Jailhouse. Finally, we use the kernel config from
12    # board/qemu/aarch64-virt rather than the Kernel defconfig, for
13    # faster build (as it enable less components, but includes
14    # everything needed for this test).
15    kernel_ver = "eb6927f7eea77f823b96c0c22ad9d4a2d7ffdfce"
16    kernel_url = \
17        f"$(call github,siemens,linux,{kernel_ver})/linux-{kernel_ver}.tar.gz"
18    config = \
19        f"""
20        BR2_aarch64=y
21        BR2_TOOLCHAIN_EXTERNAL=y
22        BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0"
23        BR2_LINUX_KERNEL=y
24        BR2_LINUX_KERNEL_CUSTOM_TARBALL=y
25        BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION="{kernel_url}"
26        BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
27        BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config"
28        BR2_PACKAGE_JAILHOUSE=y
29        BR2_TARGET_ROOTFS_EXT2=y
30        BR2_TARGET_ROOTFS_EXT2_4=y
31        # BR2_TARGET_ROOTFS_TAR is not set
32        """
33
34    def test_run(self):
35        drive = os.path.join(self.builddir, "images", "rootfs.ext4")
36        kern = os.path.join(self.builddir, "images", "Image")
37        # Qemu option and Kernel args are taken from Jailhouse demo. See:
38        # https://github.com/siemens/jailhouse/blob/master/README.md
39        # We also add oops=panic to improve the test coverage.
40        self.emulator.boot(arch="aarch64",
41                           kernel=kern,
42                           kernel_cmdline=["root=/dev/vda console=ttyAMA0 mem=768M oops=panic"],
43                           options=["-M", "virt,gic-version=3,virtualization=on,its=off",
44                                    "-cpu", "cortex-a57",
45                                    "-m", "1G",
46                                    "-smp", "16",
47                                    "-drive", f"file={drive},if=none,format=raw,id=hd0",
48                                    "-device", "virtio-blk-device,drive=hd0"])
49        self.emulator.login()
50
51        # Check the program can execute.
52        self.assertRunOk("jailhouse --version")
53
54        # Load the kernel module.
55        self.assertRunOk("modprobe jailhouse")
56
57        # Check the device is present.
58        self.assertRunOk("ls -al /dev/jailhouse")
59
60        # Load the cell config this this qemu test.
61        self.assertRunOk("jailhouse enable /etc/jailhouse/qemu-arm64.cell")
62
63        # Dump the jailhouse console, and check we see its
64        # initialization string.
65        out, ret = self.emulator.run("jailhouse console")
66        self.assertEqual(ret, 0)
67        self.assertIn("Initializing Jailhouse hypervisor", "\n".join(out))
68
69        # Create the cell.
70        cell_cfg = "/etc/jailhouse/qemu-arm64-inmate-demo.cell"
71        cmd = f"jailhouse cell create {cell_cfg}"
72        self.assertRunOk(cmd)
73
74        # Load the demo image.
75        cell_name = "inmate-demo"
76        img = "/usr/libexec/jailhouse/demos/gic-demo.bin"
77        cmd = f"jailhouse cell load {cell_name} {img}"
78        self.assertRunOk(cmd)
79
80        # List Jailhouse cells and check we see the one we loaded.
81        out, ret = self.emulator.run("jailhouse cell list")
82        self.assertEqual(ret, 0)
83        self.assertIn(cell_name, "\n".join(out))
84
85        # We should also see our cell in sysfs.
86        cmd = "cat /sys/devices/jailhouse/cells/1/name"
87        out, ret = self.emulator.run(cmd)
88        self.assertEqual(ret, 0)
89        self.assertEqual(out[0], cell_name)
90
91        # Start the cell.
92        self.assertRunOk(f"jailhouse cell start {cell_name}")
93
94        # Let the demo cell run for few seconds...
95        time.sleep(3)
96
97        # Stop and unload the cell.
98        self.assertRunOk(f"jailhouse cell shutdown {cell_name}")
99        self.assertRunOk(f"jailhouse cell destroy {cell_name}")
100
101        # Stop and unload jailhouse.
102        self.assertRunOk("jailhouse disable")
103        self.assertRunOk("modprobe -r jailhouse")
104