]> rtime.felk.cvut.cz Git - jailhouse.git/blob - Documentation/articles/LJ-article-04-2015.txt
Documentation: articles: LJ-article-04-2015.txt
[jailhouse.git] / Documentation / articles / LJ-article-04-2015.txt
1 Get to know Jailhouse
2 =====================
3
4 By Valentine Sinitsyn <valentine.sinitsyn@gmail.com>
5
6 Originally appeared in Linux Journal issue 252 (April 2015).
7 Minor fixes and updates applied.
8
9 As you read Linux Journal, you probably know Linux has rich
10 virtualization ecosystem. KVM is de-facto standard, VirtualBox is widely
11 used for desktop virtualization, veterans should remember Xen (it's
12 still in a good shape, by the way!) and there is also VMware (which
13 isn't free but runs on Linux as well). This is not to mention a
14 multitude of lesser-known hypervisors like educational lguest or hobbyst
15 Xvisor. In such crowded landscape, is there a place for a newcomer?
16
17 There is likely not much sense in creating Yet Another Linux-based
18 "versatile" hypervisor (except doing it just for fun, you know). But
19 there are some specific use cases which general-purpose solutions don't
20 address quite well. One of such areas is real-time virtualization, that
21 is frequently met in industrial automation, medicine,
22 telecommunications, and high-performance computing. In these
23 applications, dedicating a whole CPU or its core to the software that
24 runs bare-metal (with no underlying OS) is a way to meet strict deadline
25 requirements. While it is possible to pin KVM instance to processor core
26 and pass-through PCI devices to guests, tests [1] show the worst-case
27 latency may be above some realistic requirements. As usual with Free
28 Software, the situation is getting better with time, but there one other
29 thing.
30
31 And it's security. Sensitive software systems go through rigorous
32 certifications (like Common Criteria) or even formal verification
33 procedures. If you want them to run virtualized (say, for consolidation
34 purposes), the hypervisor must isolate them from non-certifiable
35 workloads. This implies the hypervisor itself must be small enough,
36 otherwise it may end up being larger (and more "suspicious") than the
37 software it segregates thus devastating the whole idea of isolation.
38
39 So looks like there is some room for a lightweight (for real-time camp),
40 small and simple (for security folks) open-source Linux-friendly
41 hypervisor for real-time and certifiable workloads. And it's where
42 Jailhouse comes into a play (this being said, safety, not security
43 is the primary focus at this point).
44
45 New guy in a block
46 ------------------
47
48 Jailhouse was born in Siemens and is developed as Free Software project
49 (GPLv2) since November 2013. On May 2015, Jailhouse 0.5 was released to
50 general public. Jailhouse is rather young and more of research project
51 than ready-to-use tool, so it's a good time to get acquainted with it
52 now, and stay prepared to meet it in the production.
53
54 From the technical point of view, Jailhouse is static partitioning
55 hypervisor that runs bare-metal but cooperates with Linux closely. It
56 means Jailhouse doesn't emulate resources you don't have - it just
57 splits your hardware into isolated compartments called "cells" that are
58 wholly dedicated to guest software programs called "inmates". One of
59 these cells runs Linux OS and is known as "root cell"; other cells
60 borrow CPUs and devices from the root cell as they are created.
61 Besides Linux, Jailhouse supports bare-metal applications but
62 it can't run general-purpose OS (like Windows or FreeBSD) unmodified: as
63 discussed, there are plenty of other options, if you need to. One day,
64 Jailhouse may also support running KVM in the root cell, thus delivering
65 the best of two worlds.
66
67 As said above, Jailhouse cooperates with Linux closely and relies on it
68 for hardware bootstrapping, hypervisor launch and doing management tasks
69 (like creating new cells). Bootstrapping is really essential here, as it
70 is rather complex task for modern computers, and implementing it within
71 Jailhouse would make it a way more complex. This being said, Jailhouse
72 doesn't meld with the kernel as KVM (which is a kernel module on x86, or
73 even linked-in on ARM) does. It is loaded as firmware image (the same way
74 Wi-Fi adapters load their firmware blobs) and resides in dedicated memory
75 region which you should reserve at Linux boot time. Jailhouse's kernel
76 module (jailhouse.ko, also called "driver") loads the firmware and creates
77 /dev/jailhouse device which jailhouse userspace tool uses, but it doesn't
78 contain any hypervisor logic.
79
80 Jailhouse is an example of Asynchronous Multiprocessing (AMP)
81 architecture. Compared to traditional Symmetric Multiprocessing (SMP)
82 systems, CPU cores in Jailhouse are not treated equal: say, cores 0 and
83 1 may run Linux and have access to SATA hard drive while core 2 runs a
84 bare-metal application which only has access to serial port. As most
85 computers Jailhouse can run on have shared L2/L3 caches, this means
86 there is a possibility for cache thrashing. To understand why it
87 happens, consider that Jailhouse maps the same guest physical memory
88 address (GPA) to different host (or real) physical address for different
89 inmates. If two inmates occasionally have the same GPA (naturally
90 containing diverse data) in the same L2/L3 cache line due to cache
91 associativity, they will interfere each other's work and degrade the
92 performance. This effect is yet to be measured, and Jailhouse currently
93 has no dedicated means to mitigate it. However there is a vision that
94 for many applications this performance loss won't be crucial. Future CPUs
95 may also introduce some QoS mechanisms to manage caches better. Moreover,
96 this issue is not specific in Jailhouse and also affects e.g. cloud platforms.
97
98 Now you have enough background to understand what Jailhouse is (and what
99 isn't). I hope you are interested; if it's the case, let's see how to
100 install and run it on your system.
101
102 Getting up-to-date
103 ------------------
104
105 Sometimes you may need very latest KVM and QEMU to give Jailhouse a try.
106 KVM is part of the kernel, and updating the critical system component
107 just to try some new software would probably seem overkill. Luckily,
108 there is another way.
109
110 kvm-kmod [2] is a tool to take KVM modules from one kernel and compile
111 them for another, and is usually used to build latest KVM for your
112 current kernel. The build process is detailed in the README, but in a
113 nutshell you clone the repository, initialize a submodule (it's the
114 source for KVM) and run configure script followed by make. When modules
115 are ready, just insmod them instead of what your distribution provides
116 (don't forget to unload those first). If you want the change permanent,
117 run 'make modules_install'. kvm-kmod can take KVM sources fromever you
118 point to, but the defaults are usually sufficient.
119
120 Compiling QEMU is easier but more time-consuming. It follows the usual
121 'configure && make' procedure, and doesn't need to be installed
122 system-wide (which is package manager-friendly). Just put
123 '/path/to/qemu/x86_64-softmmu/qemu-system-x86_64' instead of plain
124 'qemu-system-x86_64' in the text's examples.
125
126 Building Jailhouse
127 ------------------
128
129 Despite having a 0.5 release now, Jailhouse is still a young project
130 that is developed in quick paces. You are unlikely to find it in your
131 distribution's repositories for the same reasons, so the preferred way
132 to get Jailhouse is to build it from Git.
133
134 To run Jailhouse, you'll need a recent multicore VT-x-enabled Intel x86
135 64-bit CPU, and a motherboard with VT-d support. Version 0.5 introduced
136 support for AMD64 (albeit AMD IOMMU support is still in the works) and
137 ARM (v7 or better). At least 1GB RAM is recommended, and even more for
138 nested setup we discuss below. On software side, you'll need the usual
139 developer tools (make, gcc, git) and headers for your Linux kernel.
140
141 Running Jailhouse on real hardware isn't straightforward at this time,
142 and if you only want to play with it, there is a better alternative.
143 Given that you meet CPU requirements, the hypervisor should run well
144 under KVM/QEMU; this is known as nested setup. Jailhouse relies on some
145 bleeding-edge features, so you'll need at least Linux 3.17 and QEMU 2.1
146 for everything to work smoothly. Unless you are on rolling release
147 distribution, this could be a problem, so you may want to compile these
148 tools by yourself. This is detailed in the sidebar, and I suggest you
149 have a look at it even if you are lucky enough to have the required
150 versions pre-packaged: Jailhouse evolves and may need yet unreleased
151 features and fixes by the time you read this.
152
153 Make sure you have nested mode enabled in KVM. Both kvm-intel and
154 kvm-amd kernel modules accept 'nested=1' parameter which is responsible
155 just for that. You can set it manually, in modprobe command line (don't
156 forget to unload previous module's instance first). Alternatively, add
157 'options kvm-intel nested=1' (or similar kvm-amd line) to a new file
158 under /etc/modprobe.d.
159
160 You should also reserve memory for Jailhouse and inmates. To do this,
161 simply add 'memmap=66M$0x3b000000' to QEMU guest kernel command line.
162 For one-time usage, do this from the GRUB menu (press 'e', edit the
163 command line, press 'F10'). To make the change persistent, edit
164 GRUB_CMDLINE_LINUX variable in /etc/default/grub at QEMU guest side
165 and regenerate the configuration with grub-mkconfig. If you are using
166 GRUB 2, make sure you escape the dollar sign in 'memmap=' with three
167 slashes (\\\).
168
169 Now, take a JeOS edition of your favorite distribution. You can produce
170 one with SUSE Studio, ubuntu-vm-builder and similar, or just install a
171 minimal system the ordinary way yourself. It is recommended to have the
172 same kernel on the host and inside QEMU. Now, run the virtual machine as
173 (Intel CPU assumed):
174
175 qemu-system-x86_64 -machine q35 -m 1G -enable-kvm -smp 4 \
176  -cpu kvm64,-kvm_pv_eoi,-kvm_steal_time,-kvm_asyncpf,-kvmclock,+vmx,+x2apic \
177  -drive file=LinuxInstallation.img,id=disk,if=none \
178  -fsdev local,path=/path/to/jailhouse,security_model=passthrough,id=vfs \
179  -device virtio-9p-pci,addr=1f.7,mount_tag=host,fsdev=vfs \
180  -device ide-hd,drive=disk -serial stdio -serial file:com2.txt
181
182 Note we enabled 9p (-virtfs) to access the host filesystem from QEMU
183 guest side; /path/to/jailhouse is where you are going to compile
184 Jailhouse now. Cd to this directory and run:
185
186 git clone git@github.com:siemens/jailhouse.git jailhouse cd jailhouse
187 make
188
189 Now, switch to the guest and mount 9p filesystem (for example, with
190 'mount -t 9p host /mnt'). Cd to /mnt/jailhouse and execute:
191
192 sudo make firmware_install sudo insmod jailhouse.ko
193
194 This copies Jailhouse binary image you've built to /lib/firmware and
195 inserts Jailhouse driver module. You can now enable Jailhouse with:
196
197 sudo tools/jailhouse enable configs/qemu-vm.cell
198
199 As the command returns, type 'dmesg | tail'. If you see "The Jailhouse
200 is opening." message, you've successfully launched the hypervisor, and
201 your Linux guest now runs under Jailhouse (which itself runs under
202 KVM/QEMU). If you get an error, it is an indication that your CPU misses
203 some required feature. If the guest hangs, this is most likely due to
204 your host kernel or QEMU are not up-to-date enough for Jailhouse, or
205 something is wrong with qemu-vm cell config. Jailhouse sends all its
206 messages to serial port, and QEMU simply prints them to the terminal
207 where it was started. Look at the messages to see what resource
208 (I/O port, memory and so on) caused the problem, and read on for the
209 details of Jailhouse configuration.
210
211 Configs and inmates
212 -------------------
213
214 Creating Jailhouse configuration files isn't straightforward. As the
215 codebase must be kept small, most of the logic that takes place
216 automatically in other hypervisors must be done manually here (albeit
217 with some help from the tools that come with Jailhouse). Compared to
218 libvirt or VirtualBox XML, Jailhouse configuration files are very
219 detailed and rather low-level. The configuration is currently expressed
220 in form of plain C files (found under configs/ in the sources) compiled
221 into raw binaries, however another format (like DeviceTree) could be
222 used in future versions.
223
224 Most of the time, you wouldn't need to create a cell config from
225 scratch, unless you authored a whole new inmate, or want the hypervisor
226 to run on your specific hardware (that's addressed in the sidebar).
227
228 Cell configuration files contain information like hypervisor base
229 address (it should be within area you reserved with 'memmap=' earlier),
230 a mask of CPUs assigned to the cell (for root cells, it's 0xff, or all
231 CPUs in the system), the list of memory regions and the permissions this
232 cell has to them, I/O ports bitmap (0 marks a port as cell-accessible),
233 and the list of PCI devices.
234
235 Each Jailhouse cell has its own config file, so you'll have one config
236 for the root cell describing the platform Jailhouse executes on (like
237 qemu-vm.c we saw above) and several others for each running cell. It's
238 possible for inmates to share one config file (and thus one cell), but
239 then only one of these inmates will be active at given time.
240
241 In order to launch an inmate, you need to create its cell first:
242
243 sudo tools/jailhouse cell create configs/apic-demo.cell
244
245 apic-demo.cell is cell configuration file that comes with Jailhouse (I
246 also assume you still use QEMU setup described earlier). This cell
247 doesn't use any PCI devices, but in more complex cases it is recommended
248 to unload Linux drivers before moving devices to the cell with this
249 command.
250
251 Now, the inmate image can be loaded into memory:
252
253 sudo tools/jailhouse cell load apic-demo inmates/demos/x86/apic-demo.bin
254 -a 0xf0000
255
256 Jailhouse treats all inmates as opaque binaries, and although it
257 provides a small framework to develop them faster, the only thing it
258 needs to know about the inmate image is its base address. Jailhouse
259 expects an inmate entry point at 0xffff0 (which is different from x86
260 reset vector). apic-demo.bin is a standard demo inmate that comes with
261 Jailhouse, and inmates framework linker script ensures that if the
262 binary is mapped at 0xf0000, the entry point will be at the right
263 address. 'apic-demo' is just a name, and it can be almost anything you
264 want.
265
266 Finally, start the cell with:
267
268 tools/jailhouse cell start apic-demo
269
270 Now, switch back to the terminal you run QEMU from. You'll see lines
271 like this one are being sent to the serial port:
272
273 Calibrated APIC frequency: 1000008 kHz Timer fired, jitter: 38400 ns,
274 min: 38400 ns, max: 38400 ns ...
275
276 apic-demo is a purely demonstrational inmate. It programs APIC timer
277 (found on each contemporary CPU's core) to fire at 10 Hz, and measures
278 actual time between the events happening. Jitter is the difference
279 between the expected and actual time (the latency), and the smaller it
280 is, the less visible (in terms of performance) the hypervisor is.
281 Although this test isn't quite comprehensive, it is important as
282 Jailhouse targets realtime inmates and needs to be as lightweight as
283 possible.
284
285 Jailhouse also provides some means for getting cell statistics. At the
286 most basic level, there is sysfs interface under /sys/devices/jailhouse.
287 Several tools exist that pretty-print this data. For instance, you can
288 list cells currently on the system with:
289
290 sudo tools/jailhouse cell list
291
292 For more detailed statistics, run:
293
294 sudo tools/jailhouse cell stats apic-demo
295
296 The data you see is updated periodically (as in top utility) and contains
297 various low-level counters like the number of hypercalls issued, or the
298 number of I/O port accesses. The lifetime total and per-second values are
299 given for each entry. It's mainly for developers, but higher numbers mean
300 the inmate causes hypervisor involvement more often, thus degrading the
301 performance. Ideally, these should be close to zero, as jitter in apic-demo.
302 To exit the tool, press Q.
303
304 Tearing down
305 ------------
306
307 Jailhouse comes with several demo inmates, not only apic-demo. Let's try
308 something different. Stop the inmate with:
309
310 sudo tools/jailhouse cell destroy apic-demo JAILHOUSE_CELL_DESTROY:
311 Operation not permitted
312
313 What's the reason? Remember apic-demo cell had 'running/locked' state in
314 the cell list. Jailhouse introduces locked state to prevent changes to
315 the configuration; a cell that locks the hypervisor is essentially more
316 important than the root one (think it does some critical job at the
317 power plant while Linux is mostly for management purposes on that
318 system). Luckily, apic-demo is a toy inmate and it unlocks Jailhouse
319 after the first shutdown attempt, so the second one should succeed.
320 Execute the command above one more time, and apic-demo should disappear
321 from the cell listing.
322
323 Now, create tiny-demo cell (which is originally for tiny-demo.bin, also
324 from the Jailhouse demo inmates set) and load 32-bit-demo.bin into it
325 the usual way:
326
327 sudo tools/jailhouse cell create configs/tiny-demo.cell sudo
328 tools/jailhouse cell load tiny-demo inmates/demos/x86/32-bit-demo.bin -a
329 0xf0000 sudo tools/jailhouse cell start tiny-demo
330
331 Look into com2.txt in the host (the same directory you started QEMU
332 from). Not only this shows that cells can be reused by the inmates
333 provided they have compatible resource requirements, it is also a proof
334 that Jailhouse can run 32-bit inmates (the hypervisor itself and the
335 root cell always run in 64-bit mode).
336
337 When you are done with Jailhouse, you can disable it with:
338
339 sudo tools/jailhouse disable
340
341 For this to succeed, the must be no cells in "running/locked" state.
342
343 This is the end of our short trip to Jailhouse: I hope you enjoyed your
344 stay. For now, Jailhouse is not a ready-to-consume product, so you may
345 not see an immediate use of it. However, it's actively developed and
346 somewhat unique to Linux ecosystem, and if you have a need for real-time
347 application virtualization, it makes sense to keep a close eye on its
348 progress.
349
350 Jailhouse for real
351 ------------------
352
353 QEMU is great for giving Jailhouse a try, but it's also possible to test
354 it on real hardware. However, you should never do this on your PC: with
355 low-level tool Jailhouse is, you can easily hang your root cell where
356 Linux runs, which may result in filesystem and data corruption.
357
358 Jailhouse comes with helper tool to generate cell configs, but usually
359 you still need to tweak the resultant file. The tool depends on Python;
360 if you don't have it on your testing board, Jailhouse lets you to
361 collect required data and generate the configuration on your main Linux
362 PC (it's safe):
363
364 sudo tools/jailhouse config collect data.tar
365
366 Copy data.tar to your PC or notebook and untar
367
368 tools/jailhouse config create -r path/to/untarred/data configs/myboard.c
369
370 Configuration tool reads many files under /proc and /sys (either
371 collected or directly), analyzes them and generates memory regions, PCI
372 devices list and other things required for Jailhouse to run.
373
374 Post-processing the generated config is mostly trial and error process.
375 You enable Jailhouse and try to do something. If the system locks up,
376 you analyze serial output and decide if you need to grant access. If you
377 are trying to run Jailhouse on a memory-constrained system (less than 1
378 GB RAM), be careful with hypervisor memory area, as the configuration
379 tool can currently get it wrong. Don't forget to reserve memory for
380 Jailhouse through kernel command line the same way you did it with QEMU.
381 On some AMD-based systems, you may need to adjust Memory Mapped I/O
382 (MMIO) regions, because Jailhouse doesn't support AMD IOMMU technology
383 yet while the configuration tool implies it.
384
385 To capture Jailhouse serial output, you'll likely need serial-to-USB
386 adapter and null modem cable. Many modern motherboards come with no COM
387 ports, but they have headers you can connect a socket to. Once you connect
388 your board to main Linux PC, run minicom or alike to see the output (remember
389 to set port's baud rate to 115200 in program's settings).
390
391 References
392 ----------
393
394 1.  Static System Partitioning and KVM (KVM Forum 2013 slides):
395     https://docs.google.com/file/d/0B6HTUUWSPdd-Zl93MVhlMnRJRjg
396 2.  kvm-kmod homepage: http://git.kiszka.org/?p=kvm-kmod.git