├── .gitignore ├── COPYING ├── CREDITS-Git ├── Documentation ├── kernel-debugging.txt ├── kvm-balloon.txt ├── kvm-debug.txt ├── kvm-list.txt ├── kvm-pause.txt ├── kvm-resume.txt ├── kvm-run.txt ├── kvm-sandbox.txt ├── kvm-setup.txt ├── kvm-stat.txt ├── kvm-stop.txt ├── kvm-version.txt └── virtio-console.txt ├── INSTALL ├── Makefile ├── README ├── arm ├── aarch32 │ ├── arm-cpu.c │ ├── include │ │ ├── asm │ │ │ └── kvm.h │ │ └── kvm │ │ │ ├── barrier.h │ │ │ ├── kvm-arch.h │ │ │ ├── kvm-config-arch.h │ │ │ └── kvm-cpu-arch.h │ └── kvm-cpu.c ├── aarch64 │ ├── arm-cpu.c │ ├── include │ │ ├── asm │ │ │ └── kvm.h │ │ └── kvm │ │ │ ├── barrier.h │ │ │ ├── kvm-arch.h │ │ │ ├── kvm-config-arch.h │ │ │ └── kvm-cpu-arch.h │ └── kvm-cpu.c ├── fdt.c ├── gic.c ├── include │ └── arm-common │ │ ├── gic.h │ │ ├── kvm-arch.h │ │ ├── kvm-config-arch.h │ │ ├── kvm-cpu-arch.h │ │ ├── pci.h │ │ └── timer.h ├── ioport.c ├── irq.c ├── kvm-cpu.c ├── kvm.c ├── pci.c └── timer.c ├── builtin-balloon.c ├── builtin-debug.c ├── builtin-help.c ├── builtin-list.c ├── builtin-pause.c ├── builtin-resume.c ├── builtin-run.c ├── builtin-sandbox.c ├── builtin-setup.c ├── builtin-stat.c ├── builtin-stop.c ├── builtin-version.c ├── code16gcc.h ├── command-list.txt ├── config ├── feature-tests.mak └── utilities.mak ├── devices.c ├── disk ├── blk.c ├── core.c ├── qcow.c └── raw.c ├── framebuffer.c ├── guest └── init.c ├── guest_compat.c ├── hw ├── i8042.c ├── pci-shmem.c ├── rtc.c ├── serial.c └── vesa.c ├── include ├── asm │ └── hweight.h ├── kvm │ ├── 8250-serial.h │ ├── apic.h │ ├── brlock.h │ ├── builtin-balloon.h │ ├── builtin-debug.h │ ├── builtin-help.h │ ├── builtin-list.h │ ├── builtin-pause.h │ ├── builtin-resume.h │ ├── builtin-run.h │ ├── builtin-sandbox.h │ ├── builtin-setup.h │ ├── builtin-stat.h │ ├── builtin-stop.h │ ├── builtin-version.h │ ├── compiler.h │ ├── devices.h │ ├── disk-image.h │ ├── fdt.h │ ├── framebuffer.h │ ├── gtk3.h │ ├── guest_compat.h │ ├── i8042.h │ ├── ioeventfd.h │ ├── ioport.h │ ├── iovec.h │ ├── irq.h │ ├── kvm-cmd.h │ ├── kvm-config.h │ ├── kvm-cpu.h │ ├── kvm-ipc.h │ ├── kvm.h │ ├── msi.h │ ├── mutex.h │ ├── of_pci.h │ ├── parse-options.h │ ├── pci-shmem.h │ ├── pci.h │ ├── qcow.h │ ├── rbtree-interval.h │ ├── read-write.h │ ├── rtc.h │ ├── rwsem.h │ ├── sdl.h │ ├── strbuf.h │ ├── symbol.h │ ├── term.h │ ├── threadpool.h │ ├── uip.h │ ├── util-init.h │ ├── util.h │ ├── vesa.h │ ├── virtio-9p.h │ ├── virtio-balloon.h │ ├── virtio-blk.h │ ├── virtio-console.h │ ├── virtio-mmio.h │ ├── virtio-net.h │ ├── virtio-pci-dev.h │ ├── virtio-pci.h │ ├── virtio-rng.h │ ├── virtio-scsi.h │ ├── virtio.h │ └── vnc.h └── linux │ ├── 9p.h │ ├── bitops.h │ ├── byteorder.h │ ├── compiler.h │ ├── err.h │ ├── kernel.h │ ├── kvm.h │ ├── list.h │ ├── prefetch.h │ ├── psci.h │ ├── rbtree.h │ ├── rbtree_augmented.h │ ├── sizes.h │ ├── stddef.h │ ├── stringify.h │ ├── types.h │ ├── vhost.h │ ├── virtio_ids.h │ ├── virtio_mmio.h │ ├── virtio_net.h │ └── virtio_scsi.h ├── ioeventfd.c ├── ioport.c ├── irq.c ├── kvm-cmd.c ├── kvm-cpu.c ├── kvm-ipc.c ├── kvm.c ├── main.c ├── mips ├── include │ ├── asm │ │ └── kvm.h │ └── kvm │ │ ├── barrier.h │ │ ├── kvm-arch.h │ │ ├── kvm-config-arch.h │ │ └── kvm-cpu-arch.h ├── irq.c ├── kvm-cpu.c └── kvm.c ├── mmio.c ├── net └── uip │ ├── arp.c │ ├── buf.c │ ├── core.c │ ├── csum.c │ ├── dhcp.c │ ├── icmp.c │ ├── ipv4.c │ ├── tcp.c │ └── udp.c ├── pci.c ├── powerpc ├── boot.c ├── cpu_info.c ├── cpu_info.h ├── include │ ├── asm │ │ └── kvm.h │ └── kvm │ │ ├── barrier.h │ │ ├── kvm-arch.h │ │ ├── kvm-config-arch.h │ │ └── kvm-cpu-arch.h ├── ioport.c ├── irq.c ├── kvm-cpu.c ├── kvm.c ├── spapr.h ├── spapr_hcall.c ├── spapr_hvcons.c ├── spapr_hvcons.h ├── spapr_pci.c ├── spapr_pci.h ├── spapr_rtas.c ├── xics.c └── xics.h ├── symbol.c ├── term.c ├── tests ├── Makefile ├── boot │ ├── Makefile │ └── init.c ├── kernel │ ├── .gitignore │ ├── Makefile │ ├── README │ └── kernel.S └── pit │ ├── .gitignore │ ├── Makefile │ ├── README │ └── tick.S ├── ui ├── gtk3.c ├── sdl.c └── vnc.c ├── util ├── KVMTOOLS-VERSION-GEN ├── generate-cmdlist.sh ├── init.c ├── iovec.c ├── kvm-ifup-vbr0 ├── parse-options.c ├── rbtree-interval.c ├── rbtree.c ├── read-write.c ├── set_private_br.sh ├── strbuf.c ├── threadpool.c └── util.c ├── virtio ├── 9p-pdu.c ├── 9p.c ├── balloon.c ├── blk.c ├── console.c ├── core.c ├── mmio.c ├── net.c ├── pci.c ├── rng.c └── scsi.c └── x86 ├── bios.c ├── bios ├── .gitignore ├── bios-rom.S ├── e820.c ├── entry.S ├── gen-offsets.sh ├── int10.c ├── int15.c ├── local.S ├── macro.S ├── memcpy.c └── rom.ld.S ├── boot.c ├── cpuid.c ├── include ├── asm │ ├── apicdef.h │ ├── bios │ │ ├── memcpy.h │ │ ├── types.h │ │ └── vesa.h │ ├── kvm.h │ ├── mpspec_def.h │ ├── processor-flags.h │ └── segment.h └── kvm │ ├── assembly.h │ ├── barrier.h │ ├── bios-export.h │ ├── bios.h │ ├── boot-protocol.h │ ├── cpufeature.h │ ├── e820.h │ ├── interrupt.h │ ├── kvm-arch.h │ ├── kvm-config-arch.h │ ├── kvm-cpu-arch.h │ └── mptable.h ├── init.S ├── interrupt.c ├── ioport.c ├── irq.c ├── kvm-cpu.c ├── kvm.c └── mptable.c /.gitignore: -------------------------------------------------------------------------------- 1 | /lkvm 2 | /lkvm-static 3 | /vm 4 | *.o 5 | *.d 6 | *.swp 7 | .cscope 8 | tags 9 | include/common-cmds.h 10 | tests/boot/boot_test.iso 11 | tests/boot/rootfs/ 12 | guest/init 13 | guest/pre_init 14 | guest/init_stage2 15 | KVMTOOLS-VERSION-FILE 16 | /x86/bios/bios.bin 17 | /x86/bios/bios.bin.elf 18 | -------------------------------------------------------------------------------- /CREDITS-Git: -------------------------------------------------------------------------------- 1 | Most of the infrastructure that 'perf' uses here has been reused 2 | from the Git project, as of version: 3 | 4 | 66996ec: Sync with 1.6.2.4 5 | 6 | Here is an (incomplete!) list of main contributors to those files 7 | in util/* and elsewhere: 8 | 9 | Alex Riesen 10 | Christian Couder 11 | Dmitry Potapov 12 | Jeff King 13 | Johannes Schindelin 14 | Johannes Sixt 15 | Junio C Hamano 16 | Linus Torvalds 17 | Matthias Kestenholz 18 | Michal Ostrowski 19 | Miklos Vajna 20 | Petr Baudis 21 | Pierre Habouzit 22 | René Scharfe 23 | Samuel Tardieu 24 | Shawn O. Pearce 25 | Steffen Prohaska 26 | Steve Haslam 27 | 28 | Thanks guys! 29 | 30 | The full history of the files can be found in the upstream Git commits. 31 | -------------------------------------------------------------------------------- /Documentation/kernel-debugging.txt: -------------------------------------------------------------------------------- 1 | This document explains how to debug a guests' kernel using KGDB. 2 | 3 | 1. Run the guest: 4 | 'lkvm run -k [vmlinuz] -p "kgdboc=ttyS1 kgdbwait" --tty 1' 5 | 6 | And see which PTY got assigned to ttyS1 (you'll see: 7 | ' Info: Assigned terminal 1 to pty /dev/pts/X'). 8 | 9 | 2. Run GDB on the host: 10 | 'gdb [vmlinuz]' 11 | 12 | 3. Connect to the guest (from within GDB): 13 | 'target remote /dev/pty/X' 14 | 15 | 4. Start debugging! (enter 'continue' to continue boot). 16 | -------------------------------------------------------------------------------- /Documentation/kvm-balloon.txt: -------------------------------------------------------------------------------- 1 | lkvm-balloon(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-balloon - Inflate or deflate the virtio balloon 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm balloon [command] [size] [instance]' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command inflates or deflates the virtio balloon located in the 16 | specified instance. 17 | For a list of running instances see 'lkvm list'. 18 | 19 | Command can be either 'inflate' or 'deflate'. Inflate increases the 20 | size of the balloon, thus decreasing the amount of virtual RAM available 21 | for the guest. Deflation returns previously inflated memory back to the 22 | guest. 23 | 24 | size is specified in Mb. 25 | -------------------------------------------------------------------------------- /Documentation/kvm-debug.txt: -------------------------------------------------------------------------------- 1 | lkvm-debug(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-debug - Print debug information from a running instance 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm debug [instance]' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command prints debug information from a running instance. 16 | For a list of running instances see 'lkvm list'. 17 | -------------------------------------------------------------------------------- /Documentation/kvm-list.txt: -------------------------------------------------------------------------------- 1 | lkvm-list(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-list - Print a list of running instances on the host. 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm list' 12 | 13 | DESCRIPTION 14 | ----------- 15 | This command prints a list of running instances on the host which 16 | belong to the user who currently ran 'lkvm list'. 17 | -------------------------------------------------------------------------------- /Documentation/kvm-pause.txt: -------------------------------------------------------------------------------- 1 | lkvm-pause(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-pause - Pause the virtual machine 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm pause [instance]' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command pauses a virtual machine. 16 | For a list of running instances see 'lkvm list'. 17 | -------------------------------------------------------------------------------- /Documentation/kvm-resume.txt: -------------------------------------------------------------------------------- 1 | lkvm-resume(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-resume - Resume the virtual machine 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm resume [instance]' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command resumes a virtual machine. 16 | For a list of running instances see 'lkvm list'. 17 | -------------------------------------------------------------------------------- /Documentation/kvm-run.txt: -------------------------------------------------------------------------------- 1 | lkvm-run(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-run - Start the virtual machine 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm run' [-k | --kernel ] 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command starts a virtual machine. 16 | 17 | OPTIONS 18 | ------- 19 | -m:: 20 | --mem=:: 21 | Virtual machine memory size in MiB. 22 | 23 | -p:: 24 | --params:: 25 | Additional kernel command line arguments. 26 | 27 | -r:: 28 | --initrd=:: 29 | Initial RAM disk image. 30 | 31 | -k:: 32 | --kernel=:: 33 | The virtual machine kernel. 34 | 35 | --dev=:: 36 | KVM device file. 37 | 38 | -i:: 39 | --image=:: 40 | A disk image file. 41 | 42 | -s:: 43 | --single-step:: 44 | Enable single stepping. 45 | 46 | -g:: 47 | --ioport-debug:: 48 | Enable ioport debugging. 49 | 50 | -c:: 51 | --enable-virtio-console:: 52 | Enable the virtual IO console. 53 | 54 | --cpus:: 55 | The number of virtual CPUs to run. 56 | 57 | --debug:: 58 | Enable debug messages. 59 | 60 | SEE ALSO 61 | -------- 62 | linkkvm: 63 | -------------------------------------------------------------------------------- /Documentation/kvm-sandbox.txt: -------------------------------------------------------------------------------- 1 | lkvm-sandbox(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-sandbox - Run a command in a sandboxed guest 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm sandbox ['lkvm run' arguments] -- [sandboxed command]' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The sandboxed command will run in a guest as part of it's init 16 | command. 17 | -------------------------------------------------------------------------------- /Documentation/kvm-setup.txt: -------------------------------------------------------------------------------- 1 | lkvm-setup(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-setup - Setup a new virtual machine 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm setup ' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command setups a virtual machine. 16 | -------------------------------------------------------------------------------- /Documentation/kvm-stat.txt: -------------------------------------------------------------------------------- 1 | lkvm-stat(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-stat - Print statistics about a running instance 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm [command] [-n instance] [-p instance pid] [--all]' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command prints statistics about a running instance. 16 | For a list of running instances see 'lkvm list'. 17 | 18 | Commands: 19 | --memory, -m Display memory statistics 20 | -------------------------------------------------------------------------------- /Documentation/kvm-stop.txt: -------------------------------------------------------------------------------- 1 | lkvm-stop(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-stop - Stop a running instance 7 | 8 | SYNOPSIS 9 | -------- 10 | [verse] 11 | 'lkvm stop [instance]' 12 | 13 | DESCRIPTION 14 | ----------- 15 | The command stops a running instance. 16 | For a list of running instances see 'lkvm list'. 17 | -------------------------------------------------------------------------------- /Documentation/kvm-version.txt: -------------------------------------------------------------------------------- 1 | lkvm-version(1) 2 | ================ 3 | 4 | NAME 5 | ---- 6 | lkvm-version - Print the version of the kernel tree kvm tools 7 | was built on. 8 | 9 | SYNOPSIS 10 | -------- 11 | [verse] 12 | 'lkvm version' 13 | 14 | DESCRIPTION 15 | ----------- 16 | The command prints the version of the kernel that was used to build 17 | kvm tools. 18 | 19 | Note that the version is not the version of the kernel which is currently 20 | running on the host, but is the version of the kernel tree from which kvm 21 | tools was built. 22 | -------------------------------------------------------------------------------- /Documentation/virtio-console.txt: -------------------------------------------------------------------------------- 1 | General 2 | -------- 3 | 4 | virtio-console as the name implies is a console over virtio transport. Here is 5 | a simple head to head comparison of the virtio-console vs regular 8250 console: 6 | 7 | 8250 serial console: 8 | 9 | - Requires CONFIG_SERIAL_8250=y and CONFIG_SERIAL_8250_CONSOLE=y kernel configs, 10 | which are enabled almost everywhere. 11 | - Doesn't require guest-side changes. 12 | - Compatible with older guests. 13 | 14 | virtio-console: 15 | 16 | - Requires CONFIG_VIRTIO_CONSOLE=y (along with all other virtio dependencies), 17 | which got enabled only in recent kernels (but not all of them). 18 | - Much faster. 19 | - Consumes less processing resources. 20 | - Requires guest-side changes. 21 | 22 | Enabling virtio-console 23 | ------------------------ 24 | 25 | First, make sure guest kernel is built with CONFIG_VIRTIO_CONSOLE=y. Once this 26 | is done, the following has to be done inside guest image: 27 | 28 | - Add the following line to /etc/inittab: 29 | 'hvc0:2345:respawn:/sbin/agetty -L 9600 hvc0' 30 | - Add 'hvc0' to /etc/securetty (so you could actually log on) 31 | - Start the guest with '--console virtio' 32 | 33 | Common errors 34 | -------------- 35 | 36 | Q: I don't see anything on the screen! 37 | A: Make sure CONFIG_VIRTIO_CONSOLE=y is enabled in the *guest* kernel, also 38 | make sure you've updated /etc/inittab 39 | 40 | Q: It won't accept my username/password, but I enter them correctly! 41 | A: You didn't add 'hvc0' to /etc/securetty 42 | -------------------------------------------------------------------------------- /arm/aarch32/arm-cpu.c: -------------------------------------------------------------------------------- 1 | #include "kvm/kvm.h" 2 | #include "kvm/kvm-cpu.h" 3 | #include "kvm/util.h" 4 | 5 | #include "arm-common/gic.h" 6 | #include "arm-common/timer.h" 7 | 8 | #include 9 | #include 10 | 11 | static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle) 12 | { 13 | int timer_interrupts[4] = {13, 14, 11, 10}; 14 | 15 | gic__generate_fdt_nodes(fdt, gic_phandle, IRQCHIP_GICV2); 16 | timer__generate_fdt_nodes(fdt, kvm, timer_interrupts); 17 | } 18 | 19 | static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu) 20 | { 21 | vcpu->generate_fdt_nodes = generate_fdt_nodes; 22 | return 0; 23 | } 24 | 25 | static struct kvm_arm_target target_generic_v7 = { 26 | .id = UINT_MAX, 27 | .compatible = "arm,arm-v7", 28 | .init = arm_cpu__vcpu_init, 29 | }; 30 | 31 | static struct kvm_arm_target target_cortex_a15 = { 32 | .id = KVM_ARM_TARGET_CORTEX_A15, 33 | .compatible = "arm,cortex-a15", 34 | .init = arm_cpu__vcpu_init, 35 | }; 36 | 37 | static struct kvm_arm_target target_cortex_a7 = { 38 | .id = KVM_ARM_TARGET_CORTEX_A7, 39 | .compatible = "arm,cortex-a7", 40 | .init = arm_cpu__vcpu_init, 41 | }; 42 | 43 | static int arm_cpu__core_init(struct kvm *kvm) 44 | { 45 | kvm_cpu__set_kvm_arm_generic_target(&target_generic_v7); 46 | 47 | return (kvm_cpu__register_kvm_arm_target(&target_cortex_a15) || 48 | kvm_cpu__register_kvm_arm_target(&target_cortex_a7)); 49 | } 50 | core_init(arm_cpu__core_init); 51 | -------------------------------------------------------------------------------- /arm/aarch32/include/kvm/barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_BARRIER_H 2 | #define KVM__KVM_BARRIER_H 3 | 4 | #define dmb() asm volatile ("dmb" : : : "memory") 5 | 6 | #define mb() dmb() 7 | #define rmb() dmb() 8 | #define wmb() dmb() 9 | 10 | #endif /* KVM__KVM_BARRIER_H */ 11 | -------------------------------------------------------------------------------- /arm/aarch32/include/kvm/kvm-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_ARCH_H 2 | #define KVM__KVM_ARCH_H 3 | 4 | #define ARM_GIC_DIST_SIZE 0x1000 5 | #define ARM_GIC_CPUI_SIZE 0x2000 6 | 7 | #define ARM_KERN_OFFSET(...) 0x8000 8 | 9 | #define ARM_MAX_MEMORY(...) ARM_LOMAP_MAX_MEMORY 10 | 11 | #include "arm-common/kvm-arch.h" 12 | 13 | #endif /* KVM__KVM_ARCH_H */ 14 | -------------------------------------------------------------------------------- /arm/aarch32/include/kvm/kvm-config-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CONFIG_ARCH_H 2 | #define KVM__KVM_CONFIG_ARCH_H 3 | 4 | #define ARM_OPT_ARCH_RUN(...) 5 | 6 | #include "arm-common/kvm-config-arch.h" 7 | 8 | #endif /* KVM__KVM_CONFIG_ARCH_H */ 9 | -------------------------------------------------------------------------------- /arm/aarch32/include/kvm/kvm-cpu-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CPU_ARCH_H 2 | #define KVM__KVM_CPU_ARCH_H 3 | 4 | #include "kvm/kvm.h" 5 | 6 | #include "arm-common/kvm-cpu-arch.h" 7 | 8 | #define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid) { \ 9 | [0] = (!!(cpuid) << KVM_ARM_VCPU_POWER_OFF), \ 10 | } 11 | 12 | #define ARM_MPIDR_HWID_BITMASK 0xFFFFFF 13 | #define ARM_CPU_ID 0, 0, 0 14 | #define ARM_CPU_ID_MPIDR 5 15 | 16 | #endif /* KVM__KVM_CPU_ARCH_H */ 17 | -------------------------------------------------------------------------------- /arm/aarch64/arm-cpu.c: -------------------------------------------------------------------------------- 1 | #include "kvm/fdt.h" 2 | #include "kvm/kvm.h" 3 | #include "kvm/kvm-cpu.h" 4 | #include "kvm/util.h" 5 | 6 | #include "arm-common/gic.h" 7 | #include "arm-common/timer.h" 8 | 9 | #include 10 | #include 11 | 12 | static void generate_fdt_nodes(void *fdt, struct kvm *kvm, u32 gic_phandle) 13 | { 14 | int timer_interrupts[4] = {13, 14, 11, 10}; 15 | gic__generate_fdt_nodes(fdt, gic_phandle, kvm->cfg.arch.irqchip); 16 | timer__generate_fdt_nodes(fdt, kvm, timer_interrupts); 17 | } 18 | 19 | static int arm_cpu__vcpu_init(struct kvm_cpu *vcpu) 20 | { 21 | vcpu->generate_fdt_nodes = generate_fdt_nodes; 22 | return 0; 23 | } 24 | 25 | static struct kvm_arm_target target_generic_v8 = { 26 | .id = UINT_MAX, 27 | .compatible = "arm,arm-v8", 28 | .init = arm_cpu__vcpu_init, 29 | }; 30 | 31 | static struct kvm_arm_target target_aem_v8 = { 32 | .id = KVM_ARM_TARGET_AEM_V8, 33 | .compatible = "arm,arm-v8", 34 | .init = arm_cpu__vcpu_init, 35 | }; 36 | 37 | static struct kvm_arm_target target_foundation_v8 = { 38 | .id = KVM_ARM_TARGET_FOUNDATION_V8, 39 | .compatible = "arm,arm-v8", 40 | .init = arm_cpu__vcpu_init, 41 | }; 42 | 43 | static struct kvm_arm_target target_cortex_a57 = { 44 | .id = KVM_ARM_TARGET_CORTEX_A57, 45 | .compatible = "arm,cortex-a57", 46 | .init = arm_cpu__vcpu_init, 47 | }; 48 | 49 | /* 50 | * We really don't need to register a target for every 51 | * new CPU. The target for Potenza CPU is only registered 52 | * to enable compatibility with older host kernels. 53 | */ 54 | static struct kvm_arm_target target_potenza = { 55 | .id = KVM_ARM_TARGET_XGENE_POTENZA, 56 | .compatible = "arm,arm-v8", 57 | .init = arm_cpu__vcpu_init, 58 | }; 59 | 60 | static int arm_cpu__core_init(struct kvm *kvm) 61 | { 62 | kvm_cpu__set_kvm_arm_generic_target(&target_generic_v8); 63 | 64 | return (kvm_cpu__register_kvm_arm_target(&target_aem_v8) || 65 | kvm_cpu__register_kvm_arm_target(&target_foundation_v8) || 66 | kvm_cpu__register_kvm_arm_target(&target_cortex_a57) || 67 | kvm_cpu__register_kvm_arm_target(&target_potenza)); 68 | } 69 | core_init(arm_cpu__core_init); 70 | -------------------------------------------------------------------------------- /arm/aarch64/include/kvm/barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_BARRIER_H 2 | #define KVM__KVM_BARRIER_H 3 | 4 | #define mb() asm volatile ("dmb ish" : : : "memory") 5 | #define rmb() asm volatile ("dmb ishld" : : : "memory") 6 | #define wmb() asm volatile ("dmb ishst" : : : "memory") 7 | 8 | #endif /* KVM__KVM_BARRIER_H */ 9 | -------------------------------------------------------------------------------- /arm/aarch64/include/kvm/kvm-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_ARCH_H 2 | #define KVM__KVM_ARCH_H 3 | 4 | #define ARM_GIC_DIST_SIZE 0x10000 5 | #define ARM_GIC_CPUI_SIZE 0x20000 6 | 7 | #define ARM_KERN_OFFSET(kvm) ((kvm)->cfg.arch.aarch32_guest ? \ 8 | 0x8000 : \ 9 | 0x80000) 10 | 11 | #define ARM_MAX_MEMORY(kvm) ((kvm)->cfg.arch.aarch32_guest ? \ 12 | ARM_LOMAP_MAX_MEMORY : \ 13 | ARM_HIMAP_MAX_MEMORY) 14 | 15 | #include "arm-common/kvm-arch.h" 16 | 17 | #endif /* KVM__KVM_ARCH_H */ 18 | -------------------------------------------------------------------------------- /arm/aarch64/include/kvm/kvm-config-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CONFIG_ARCH_H 2 | #define KVM__KVM_CONFIG_ARCH_H 3 | 4 | #define ARM_OPT_ARCH_RUN(cfg) \ 5 | OPT_BOOLEAN('\0', "aarch32", &(cfg)->aarch32_guest, \ 6 | "Run AArch32 guest"), 7 | 8 | #include "arm-common/kvm-config-arch.h" 9 | 10 | #endif /* KVM__KVM_CONFIG_ARCH_H */ 11 | -------------------------------------------------------------------------------- /arm/aarch64/include/kvm/kvm-cpu-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CPU_ARCH_H 2 | #define KVM__KVM_CPU_ARCH_H 3 | 4 | #include "kvm/kvm.h" 5 | 6 | #include "arm-common/kvm-cpu-arch.h" 7 | 8 | #define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid) { \ 9 | [0] = ((!!(cpuid) << KVM_ARM_VCPU_POWER_OFF) | \ 10 | (!!(kvm)->cfg.arch.aarch32_guest << KVM_ARM_VCPU_EL1_32BIT)) \ 11 | } 12 | 13 | #define ARM_MPIDR_HWID_BITMASK 0xFF00FFFFFFUL 14 | #define ARM_CPU_ID 3, 0, 0, 0 15 | #define ARM_CPU_ID_MPIDR 5 16 | #define ARM_CPU_CTRL 3, 0, 1, 0 17 | #define ARM_CPU_CTRL_SCTLR_EL1 0 18 | 19 | #endif /* KVM__KVM_CPU_ARCH_H */ 20 | -------------------------------------------------------------------------------- /arm/include/arm-common/gic.h: -------------------------------------------------------------------------------- 1 | #ifndef ARM_COMMON__GIC_H 2 | #define ARM_COMMON__GIC_H 3 | 4 | #define GIC_SGI_IRQ_BASE 0 5 | #define GIC_PPI_IRQ_BASE 16 6 | #define GIC_SPI_IRQ_BASE 32 7 | 8 | #define GIC_FDT_IRQ_NUM_CELLS 3 9 | 10 | #define GIC_FDT_IRQ_TYPE_SPI 0 11 | #define GIC_FDT_IRQ_TYPE_PPI 1 12 | 13 | #define GIC_FDT_IRQ_PPI_CPU_SHIFT 8 14 | #define GIC_FDT_IRQ_PPI_CPU_MASK (0xff << GIC_FDT_IRQ_PPI_CPU_SHIFT) 15 | 16 | #define GIC_CPUI_CTLR_EN (1 << 0) 17 | #define GIC_CPUI_PMR_MIN_PRIO 0xff 18 | 19 | #define GIC_CPUI_OFF_PMR 4 20 | 21 | #define GIC_MAX_CPUS 8 22 | #define GIC_MAX_IRQ 255 23 | 24 | enum irqchip_type { 25 | IRQCHIP_GICV2, 26 | IRQCHIP_GICV3, 27 | }; 28 | 29 | struct kvm; 30 | 31 | int gic__alloc_irqnum(void); 32 | int gic__create(struct kvm *kvm, enum irqchip_type type); 33 | void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type); 34 | 35 | #endif /* ARM_COMMON__GIC_H */ 36 | -------------------------------------------------------------------------------- /arm/include/arm-common/kvm-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef ARM_COMMON__KVM_ARCH_H 2 | #define ARM_COMMON__KVM_ARCH_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "arm-common/gic.h" 9 | 10 | #define ARM_IOPORT_AREA _AC(0x0000000000000000, UL) 11 | #define ARM_MMIO_AREA _AC(0x0000000000010000, UL) 12 | #define ARM_AXI_AREA _AC(0x0000000040000000, UL) 13 | #define ARM_MEMORY_AREA _AC(0x0000000080000000, UL) 14 | 15 | #define ARM_LOMAP_MAX_MEMORY ((1ULL << 32) - ARM_MEMORY_AREA) 16 | #define ARM_HIMAP_MAX_MEMORY ((1ULL << 40) - ARM_MEMORY_AREA) 17 | 18 | #define ARM_GIC_DIST_BASE (ARM_AXI_AREA - ARM_GIC_DIST_SIZE) 19 | #define ARM_GIC_CPUI_BASE (ARM_GIC_DIST_BASE - ARM_GIC_CPUI_SIZE) 20 | #define ARM_GIC_SIZE (ARM_GIC_DIST_SIZE + ARM_GIC_CPUI_SIZE) 21 | 22 | #define ARM_IOPORT_SIZE (ARM_MMIO_AREA - ARM_IOPORT_AREA) 23 | #define ARM_VIRTIO_MMIO_SIZE (ARM_AXI_AREA - (ARM_MMIO_AREA + ARM_GIC_SIZE)) 24 | #define ARM_PCI_CFG_SIZE (1ULL << 24) 25 | #define ARM_PCI_MMIO_SIZE (ARM_MEMORY_AREA - \ 26 | (ARM_AXI_AREA + ARM_PCI_CFG_SIZE)) 27 | 28 | #define KVM_IOPORT_AREA ARM_IOPORT_AREA 29 | #define KVM_PCI_CFG_AREA ARM_AXI_AREA 30 | #define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE) 31 | #define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA 32 | 33 | /* 34 | * On a GICv3 there must be one redistributor per vCPU. 35 | * The value here is the size for one, we multiply this at runtime with 36 | * the number of requested vCPUs to get the actual size. 37 | */ 38 | #define ARM_GIC_REDIST_SIZE 0x20000 39 | 40 | #define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE 41 | 42 | #define KVM_VM_TYPE 0 43 | 44 | #define VIRTIO_DEFAULT_TRANS(kvm) \ 45 | ((kvm)->cfg.arch.virtio_trans_pci ? VIRTIO_PCI : VIRTIO_MMIO) 46 | 47 | #define VIRTIO_RING_ENDIAN (VIRTIO_ENDIAN_LE | VIRTIO_ENDIAN_BE) 48 | 49 | static inline bool arm_addr_in_ioport_region(u64 phys_addr) 50 | { 51 | u64 limit = KVM_IOPORT_AREA + ARM_IOPORT_SIZE; 52 | return phys_addr >= KVM_IOPORT_AREA && phys_addr < limit; 53 | } 54 | 55 | struct kvm_arch { 56 | /* 57 | * We may have to align the guest memory for virtio, so keep the 58 | * original pointers here for munmap. 59 | */ 60 | void *ram_alloc_start; 61 | u64 ram_alloc_size; 62 | 63 | /* 64 | * Guest addresses for memory layout. 65 | */ 66 | u64 memory_guest_start; 67 | u64 kern_guest_start; 68 | u64 initrd_guest_start; 69 | u64 initrd_size; 70 | u64 dtb_guest_start; 71 | }; 72 | 73 | #endif /* ARM_COMMON__KVM_ARCH_H */ 74 | -------------------------------------------------------------------------------- /arm/include/arm-common/kvm-config-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef ARM_COMMON__KVM_CONFIG_ARCH_H 2 | #define ARM_COMMON__KVM_CONFIG_ARCH_H 3 | 4 | #include "kvm/parse-options.h" 5 | 6 | struct kvm_config_arch { 7 | const char *dump_dtb_filename; 8 | unsigned int force_cntfrq; 9 | bool virtio_trans_pci; 10 | bool aarch32_guest; 11 | enum irqchip_type irqchip; 12 | }; 13 | 14 | int irqchip_parser(const struct option *opt, const char *arg, int unset); 15 | 16 | #define OPT_ARCH_RUN(pfx, cfg) \ 17 | pfx, \ 18 | ARM_OPT_ARCH_RUN(cfg) \ 19 | OPT_STRING('\0', "dump-dtb", &(cfg)->dump_dtb_filename, \ 20 | ".dtb file", "Dump generated .dtb to specified file"), \ 21 | OPT_UINTEGER('\0', "override-bad-firmware-cntfrq", &(cfg)->force_cntfrq,\ 22 | "Specify Generic Timer frequency in guest DT to " \ 23 | "work around buggy secure firmware *Firmware should be " \ 24 | "updated to program CNTFRQ correctly*"), \ 25 | OPT_BOOLEAN('\0', "force-pci", &(cfg)->virtio_trans_pci, \ 26 | "Force virtio devices to use PCI as their default " \ 27 | "transport"), \ 28 | OPT_CALLBACK('\0', "irqchip", &(cfg)->irqchip, \ 29 | "[gicv2|gicv3]", \ 30 | "Type of interrupt controller to emulate in the guest", \ 31 | irqchip_parser, NULL), 32 | 33 | #endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */ 34 | -------------------------------------------------------------------------------- /arm/include/arm-common/kvm-cpu-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef ARM_COMMON__KVM_CPU_ARCH_H 2 | #define ARM_COMMON__KVM_CPU_ARCH_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | struct kvm; 9 | 10 | struct kvm_cpu { 11 | pthread_t thread; 12 | 13 | unsigned long cpu_id; 14 | unsigned long cpu_type; 15 | const char *cpu_compatible; 16 | 17 | struct kvm *kvm; 18 | int vcpu_fd; 19 | struct kvm_run *kvm_run; 20 | 21 | u8 is_running; 22 | u8 paused; 23 | u8 needs_nmi; 24 | 25 | struct kvm_coalesced_mmio_ring *ring; 26 | 27 | void (*generate_fdt_nodes)(void *fdt, struct kvm* kvm, 28 | u32 gic_phandle); 29 | }; 30 | 31 | struct kvm_arm_target { 32 | u32 id; 33 | const char *compatible; 34 | int (*init)(struct kvm_cpu *vcpu); 35 | }; 36 | 37 | void kvm_cpu__set_kvm_arm_generic_target(struct kvm_arm_target *target); 38 | 39 | int kvm_cpu__register_kvm_arm_target(struct kvm_arm_target *target); 40 | 41 | static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, 42 | int direction, int size, u32 count) 43 | { 44 | return false; 45 | } 46 | 47 | static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, 48 | u8 *data, u32 len, u8 is_write) 49 | { 50 | if (arm_addr_in_ioport_region(phys_addr)) { 51 | int direction = is_write ? KVM_EXIT_IO_OUT : KVM_EXIT_IO_IN; 52 | u16 port = (phys_addr - KVM_IOPORT_AREA) & USHRT_MAX; 53 | 54 | return kvm__emulate_io(vcpu, port, data, direction, len, 1); 55 | } 56 | 57 | return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); 58 | } 59 | 60 | unsigned long kvm_cpu__get_vcpu_mpidr(struct kvm_cpu *vcpu); 61 | 62 | #endif /* ARM_COMMON__KVM_CPU_ARCH_H */ 63 | -------------------------------------------------------------------------------- /arm/include/arm-common/pci.h: -------------------------------------------------------------------------------- 1 | #ifndef ARM_COMMON__PCI_H 2 | #define ARM_COMMON__PCI_H 3 | 4 | void pci__generate_fdt_nodes(void *fdt, u32 gic_phandle); 5 | 6 | #endif /* ARM_COMMON__PCI_H */ 7 | -------------------------------------------------------------------------------- /arm/include/arm-common/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef ARM_COMMON__TIMER_H 2 | #define ARM_COMMON__TIMER_H 3 | 4 | void timer__generate_fdt_nodes(void *fdt, struct kvm *kvm, int *irqs); 5 | 6 | #endif /* ARM_COMMON__TIMER_H */ 7 | -------------------------------------------------------------------------------- /arm/ioport.c: -------------------------------------------------------------------------------- 1 | #include "kvm/ioport.h" 2 | #include "kvm/irq.h" 3 | 4 | void ioport__setup_arch(struct kvm *kvm) 5 | { 6 | } 7 | 8 | void ioport__map_irq(u8 *irq) 9 | { 10 | *irq = irq__alloc_line(); 11 | } 12 | -------------------------------------------------------------------------------- /arm/irq.c: -------------------------------------------------------------------------------- 1 | #include "kvm/irq.h" 2 | #include "kvm/kvm.h" 3 | #include "kvm/util.h" 4 | 5 | int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) 6 | { 7 | die(__FUNCTION__); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /arm/kvm.c: -------------------------------------------------------------------------------- 1 | #include "kvm/kvm.h" 2 | #include "kvm/term.h" 3 | #include "kvm/util.h" 4 | #include "kvm/8250-serial.h" 5 | #include "kvm/virtio-console.h" 6 | 7 | #include "arm-common/gic.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | struct kvm_ext kvm_req_ext[] = { 14 | { DEFINE_KVM_EXT(KVM_CAP_IRQCHIP) }, 15 | { DEFINE_KVM_EXT(KVM_CAP_ONE_REG) }, 16 | { DEFINE_KVM_EXT(KVM_CAP_ARM_PSCI) }, 17 | { 0, 0 }, 18 | }; 19 | 20 | bool kvm__arch_cpu_supports_vm(void) 21 | { 22 | /* The KVM capability check is enough. */ 23 | return true; 24 | } 25 | 26 | void kvm__init_ram(struct kvm *kvm) 27 | { 28 | int err; 29 | u64 phys_start, phys_size; 30 | void *host_mem; 31 | 32 | phys_start = ARM_MEMORY_AREA; 33 | phys_size = kvm->ram_size; 34 | host_mem = kvm->ram_start; 35 | 36 | err = kvm__register_mem(kvm, phys_start, phys_size, host_mem); 37 | if (err) 38 | die("Failed to register %lld bytes of memory at physical " 39 | "address 0x%llx [err %d]", phys_size, phys_start, err); 40 | 41 | kvm->arch.memory_guest_start = phys_start; 42 | } 43 | 44 | void kvm__arch_delete_ram(struct kvm *kvm) 45 | { 46 | munmap(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size); 47 | } 48 | 49 | void kvm__arch_read_term(struct kvm *kvm) 50 | { 51 | if (term_readable(0)) { 52 | serial8250__update_consoles(kvm); 53 | virtio_console__inject_interrupt(kvm); 54 | } 55 | } 56 | 57 | void kvm__arch_set_cmdline(char *cmdline, bool video) 58 | { 59 | } 60 | 61 | void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size) 62 | { 63 | /* 64 | * Allocate guest memory. We must align our buffer to 64K to 65 | * correlate with the maximum guest page size for virtio-mmio. 66 | * If using THP, then our minimal alignment becomes 2M. 67 | * 2M trumps 64K, so let's go with that. 68 | */ 69 | kvm->ram_size = min(ram_size, (u64)ARM_MAX_MEMORY(kvm)); 70 | kvm->arch.ram_alloc_size = kvm->ram_size + SZ_2M; 71 | kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, 72 | kvm->arch.ram_alloc_size); 73 | 74 | if (kvm->arch.ram_alloc_start == MAP_FAILED) 75 | die("Failed to map %lld bytes for guest memory (%d)", 76 | kvm->arch.ram_alloc_size, errno); 77 | 78 | kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start, 79 | SZ_2M); 80 | 81 | madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size, 82 | MADV_MERGEABLE | MADV_HUGEPAGE); 83 | 84 | /* Create the virtual GIC. */ 85 | if (gic__create(kvm, kvm->cfg.arch.irqchip)) 86 | die("Failed to create virtual GIC"); 87 | } 88 | -------------------------------------------------------------------------------- /arm/timer.c: -------------------------------------------------------------------------------- 1 | #include "kvm/fdt.h" 2 | #include "kvm/kvm.h" 3 | #include "kvm/kvm-cpu.h" 4 | #include "kvm/util.h" 5 | 6 | #include "arm-common/gic.h" 7 | #include "arm-common/timer.h" 8 | 9 | void timer__generate_fdt_nodes(void *fdt, struct kvm *kvm, int *irqs) 10 | { 11 | const char compatible[] = "arm,armv8-timer\0arm,armv7-timer"; 12 | 13 | u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \ 14 | & GIC_FDT_IRQ_PPI_CPU_MASK; 15 | u32 irq_prop[] = { 16 | cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 17 | cpu_to_fdt32(irqs[0]), 18 | cpu_to_fdt32(cpu_mask | IRQ_TYPE_EDGE_RISING), 19 | 20 | cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 21 | cpu_to_fdt32(irqs[1]), 22 | cpu_to_fdt32(cpu_mask | IRQ_TYPE_EDGE_RISING), 23 | 24 | cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 25 | cpu_to_fdt32(irqs[2]), 26 | cpu_to_fdt32(cpu_mask | IRQ_TYPE_EDGE_RISING), 27 | 28 | cpu_to_fdt32(GIC_FDT_IRQ_TYPE_PPI), 29 | cpu_to_fdt32(irqs[3]), 30 | cpu_to_fdt32(cpu_mask | IRQ_TYPE_EDGE_RISING), 31 | }; 32 | 33 | _FDT(fdt_begin_node(fdt, "timer")); 34 | _FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible))); 35 | _FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop))); 36 | _FDT(fdt_property(fdt, "always-on", NULL, 0)); 37 | if (kvm->cfg.arch.force_cntfrq > 0) 38 | _FDT(fdt_property_cell(fdt, "clock-frequency", kvm->cfg.arch.force_cntfrq)); 39 | _FDT(fdt_end_node(fdt)); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /builtin-balloon.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | static const char *instance_name; 13 | static u64 inflate; 14 | static u64 deflate; 15 | 16 | static const char * const balloon_usage[] = { 17 | "lkvm balloon [-n name] [-p pid] [-i amount] [-d amount]", 18 | NULL 19 | }; 20 | 21 | static const struct option balloon_options[] = { 22 | OPT_GROUP("Instance options:"), 23 | OPT_STRING('n', "name", &instance_name, "name", "Instance name"), 24 | OPT_GROUP("Balloon options:"), 25 | OPT_U64('i', "inflate", &inflate, "Amount to inflate (in MB)"), 26 | OPT_U64('d', "deflate", &deflate, "Amount to deflate (in MB)"), 27 | OPT_END(), 28 | }; 29 | 30 | void kvm_balloon_help(void) 31 | { 32 | usage_with_options(balloon_usage, balloon_options); 33 | } 34 | 35 | static void parse_balloon_options(int argc, const char **argv) 36 | { 37 | while (argc != 0) { 38 | argc = parse_options(argc, argv, balloon_options, balloon_usage, 39 | PARSE_OPT_STOP_AT_NON_OPTION); 40 | if (argc != 0) 41 | kvm_balloon_help(); 42 | } 43 | } 44 | 45 | int kvm_cmd_balloon(int argc, const char **argv, const char *prefix) 46 | { 47 | int instance; 48 | int r; 49 | int amount; 50 | 51 | parse_balloon_options(argc, argv); 52 | 53 | if (inflate == 0 && deflate == 0) 54 | kvm_balloon_help(); 55 | 56 | if (instance_name == NULL) 57 | kvm_balloon_help(); 58 | 59 | instance = kvm__get_sock_by_instance(instance_name); 60 | 61 | if (instance <= 0) 62 | die("Failed locating instance"); 63 | 64 | if (inflate) 65 | amount = inflate; 66 | else if (deflate) 67 | amount = -deflate; 68 | else 69 | kvm_balloon_help(); 70 | 71 | r = kvm_ipc__send_msg(instance, KVM_IPC_BALLOON, 72 | sizeof(amount), (u8 *)&amount); 73 | 74 | close(instance); 75 | 76 | if (r < 0) 77 | return -1; 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /builtin-debug.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define BUFFER_SIZE 100 14 | 15 | static bool all; 16 | static int nmi = -1; 17 | static bool dump; 18 | static const char *instance_name; 19 | static const char *sysrq; 20 | 21 | static const char * const debug_usage[] = { 22 | "lkvm debug [--all] [-n name] [-d] [-m vcpu]", 23 | NULL 24 | }; 25 | 26 | static const struct option debug_options[] = { 27 | OPT_GROUP("General options:"), 28 | OPT_BOOLEAN('d', "dump", &dump, "Generate a debug dump from guest"), 29 | OPT_INTEGER('m', "nmi", &nmi, "Generate NMI on VCPU"), 30 | OPT_STRING('s', "sysrq", &sysrq, "sysrq", "Inject a sysrq"), 31 | OPT_GROUP("Instance options:"), 32 | OPT_BOOLEAN('a', "all", &all, "Debug all instances"), 33 | OPT_STRING('n', "name", &instance_name, "name", "Instance name"), 34 | OPT_END() 35 | }; 36 | 37 | static void parse_debug_options(int argc, const char **argv) 38 | { 39 | while (argc != 0) { 40 | argc = parse_options(argc, argv, debug_options, debug_usage, 41 | PARSE_OPT_STOP_AT_NON_OPTION); 42 | if (argc != 0) 43 | kvm_debug_help(); 44 | } 45 | } 46 | 47 | void kvm_debug_help(void) 48 | { 49 | usage_with_options(debug_usage, debug_options); 50 | } 51 | 52 | static int do_debug(const char *name, int sock) 53 | { 54 | char buff[BUFFER_SIZE]; 55 | struct debug_cmd_params cmd = {.dbg_type = 0}; 56 | int r; 57 | 58 | if (dump) 59 | cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_DUMP; 60 | 61 | if (nmi != -1) { 62 | cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_NMI; 63 | cmd.cpu = nmi; 64 | } 65 | 66 | if (sysrq) { 67 | cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_SYSRQ; 68 | cmd.sysrq = sysrq[0]; 69 | } 70 | 71 | r = kvm_ipc__send_msg(sock, KVM_IPC_DEBUG, sizeof(cmd), (u8 *)&cmd); 72 | if (r < 0) 73 | return r; 74 | 75 | if (!dump) 76 | return 0; 77 | 78 | do { 79 | r = xread(sock, buff, BUFFER_SIZE); 80 | if (r < 0) 81 | return 0; 82 | printf("%.*s", r, buff); 83 | } while (r > 0); 84 | 85 | return 0; 86 | } 87 | 88 | int kvm_cmd_debug(int argc, const char **argv, const char *prefix) 89 | { 90 | parse_debug_options(argc, argv); 91 | int instance; 92 | int r; 93 | 94 | if (all) 95 | return kvm__enumerate_instances(do_debug); 96 | 97 | if (instance_name == NULL) 98 | kvm_debug_help(); 99 | 100 | instance = kvm__get_sock_by_instance(instance_name); 101 | 102 | if (instance <= 0) 103 | die("Failed locating instance"); 104 | 105 | r = do_debug(instance_name, instance); 106 | 107 | close(instance); 108 | 109 | return r; 110 | } 111 | -------------------------------------------------------------------------------- /builtin-help.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* user defined headers */ 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | const char kvm_usage_string[] = 14 | "lkvm COMMAND [ARGS]"; 15 | 16 | const char kvm_more_info_string[] = 17 | "See 'lkvm help COMMAND' for more information on a specific command."; 18 | 19 | 20 | static void list_common_cmds_help(void) 21 | { 22 | unsigned int i, longest = 0; 23 | 24 | for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { 25 | if (longest < strlen(common_cmds[i].name)) 26 | longest = strlen(common_cmds[i].name); 27 | } 28 | 29 | puts(" The most commonly used lkvm commands are:"); 30 | for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { 31 | printf(" %-*s ", longest, common_cmds[i].name); 32 | puts(common_cmds[i].help); 33 | } 34 | } 35 | 36 | static void kvm_help(void) 37 | { 38 | printf("\n To start a simple non-privileged shell run '%s run'\n\n" 39 | "usage: %s\n\n", KVM_BINARY_NAME, kvm_usage_string); 40 | list_common_cmds_help(); 41 | printf("\n %s\n\n", kvm_more_info_string); 42 | } 43 | 44 | 45 | static void help_cmd(const char *cmd) 46 | { 47 | struct cmd_struct *p; 48 | p = kvm_get_command(kvm_commands, cmd); 49 | if (!p) 50 | kvm_help(); 51 | else if (p->help) 52 | p->help(); 53 | } 54 | 55 | int kvm_cmd_help(int argc, const char **argv, const char *prefix) 56 | { 57 | if (!argv || !*argv) { 58 | kvm_help(); 59 | return 0; 60 | } 61 | help_cmd(argv[0]); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /builtin-list.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static bool run; 15 | static bool rootfs; 16 | 17 | static const char * const list_usage[] = { 18 | "lkvm list", 19 | NULL 20 | }; 21 | 22 | static const struct option list_options[] = { 23 | OPT_GROUP("General options:"), 24 | OPT_BOOLEAN('i', "run", &run, "List running instances"), 25 | OPT_BOOLEAN('r', "rootfs", &rootfs, "List rootfs instances"), 26 | OPT_END() 27 | }; 28 | 29 | #define KVM_INSTANCE_RUNNING "running" 30 | #define KVM_INSTANCE_PAUSED "paused" 31 | #define KVM_INSTANCE_SHUTOFF "shut off" 32 | 33 | void kvm_list_help(void) 34 | { 35 | usage_with_options(list_usage, list_options); 36 | } 37 | 38 | static pid_t get_pid(int sock) 39 | { 40 | pid_t pid; 41 | int r; 42 | 43 | r = kvm_ipc__send(sock, KVM_IPC_PID); 44 | if (r < 0) 45 | return r; 46 | 47 | r = read(sock, &pid, sizeof(pid)); 48 | if (r < 0) 49 | return r; 50 | 51 | return pid; 52 | } 53 | 54 | int get_vmstate(int sock) 55 | { 56 | int vmstate; 57 | int r; 58 | 59 | r = kvm_ipc__send(sock, KVM_IPC_VMSTATE); 60 | if (r < 0) 61 | return r; 62 | 63 | r = read(sock, &vmstate, sizeof(vmstate)); 64 | if (r < 0) 65 | return r; 66 | 67 | return vmstate; 68 | 69 | } 70 | 71 | static int print_guest(const char *name, int sock) 72 | { 73 | pid_t pid; 74 | int vmstate; 75 | 76 | pid = get_pid(sock); 77 | vmstate = get_vmstate(sock); 78 | 79 | if ((int)pid < 0 || vmstate < 0) 80 | return -1; 81 | 82 | if (vmstate == KVM_VMSTATE_PAUSED) 83 | printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_PAUSED); 84 | else 85 | printf("%5d %-20s %s\n", pid, name, KVM_INSTANCE_RUNNING); 86 | 87 | return 0; 88 | } 89 | 90 | static int kvm_list_running_instances(void) 91 | { 92 | return kvm__enumerate_instances(print_guest); 93 | } 94 | 95 | static int kvm_list_rootfs(void) 96 | { 97 | DIR *dir; 98 | struct dirent *dirent; 99 | 100 | dir = opendir(kvm__get_dir()); 101 | if (dir == NULL) 102 | return -1; 103 | 104 | while ((dirent = readdir(dir))) { 105 | if (dirent->d_type == DT_DIR && 106 | strcmp(dirent->d_name, ".") && 107 | strcmp(dirent->d_name, "..")) 108 | printf("%5s %-20s %s\n", "", dirent->d_name, KVM_INSTANCE_SHUTOFF); 109 | } 110 | 111 | return 0; 112 | } 113 | 114 | static void parse_setup_options(int argc, const char **argv) 115 | { 116 | while (argc != 0) { 117 | argc = parse_options(argc, argv, list_options, list_usage, 118 | PARSE_OPT_STOP_AT_NON_OPTION); 119 | if (argc != 0) 120 | kvm_list_help(); 121 | } 122 | } 123 | 124 | int kvm_cmd_list(int argc, const char **argv, const char *prefix) 125 | { 126 | int status, r; 127 | 128 | parse_setup_options(argc, argv); 129 | 130 | if (!run && !rootfs) 131 | run = rootfs = true; 132 | 133 | printf("%6s %-20s %s\n", "PID", "NAME", "STATE"); 134 | printf("------------------------------------\n"); 135 | 136 | status = 0; 137 | 138 | if (run) { 139 | r = kvm_list_running_instances(); 140 | if (r < 0) 141 | perror("Error listing instances"); 142 | 143 | status |= r; 144 | } 145 | 146 | if (rootfs) { 147 | r = kvm_list_rootfs(); 148 | if (r < 0) 149 | perror("Error listing rootfs"); 150 | 151 | status |= r; 152 | } 153 | 154 | return status; 155 | } 156 | -------------------------------------------------------------------------------- /builtin-pause.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | static bool all; 14 | static const char *instance_name; 15 | 16 | static const char * const pause_usage[] = { 17 | "lkvm pause [--all] [-n name]", 18 | NULL 19 | }; 20 | 21 | static const struct option pause_options[] = { 22 | OPT_GROUP("General options:"), 23 | OPT_BOOLEAN('a', "all", &all, "Pause all instances"), 24 | OPT_STRING('n', "name", &instance_name, "name", "Instance name"), 25 | OPT_END() 26 | }; 27 | 28 | static void parse_pause_options(int argc, const char **argv) 29 | { 30 | while (argc != 0) { 31 | argc = parse_options(argc, argv, pause_options, pause_usage, 32 | PARSE_OPT_STOP_AT_NON_OPTION); 33 | if (argc != 0) 34 | kvm_pause_help(); 35 | } 36 | } 37 | 38 | void kvm_pause_help(void) 39 | { 40 | usage_with_options(pause_usage, pause_options); 41 | } 42 | 43 | static int do_pause(const char *name, int sock) 44 | { 45 | int r; 46 | int vmstate; 47 | 48 | vmstate = get_vmstate(sock); 49 | if (vmstate < 0) 50 | return vmstate; 51 | if (vmstate == KVM_VMSTATE_PAUSED) { 52 | printf("Guest %s is already paused.\n", name); 53 | return 0; 54 | } 55 | 56 | r = kvm_ipc__send(sock, KVM_IPC_PAUSE); 57 | if (r) 58 | return r; 59 | 60 | printf("Guest %s paused\n", name); 61 | 62 | return 0; 63 | } 64 | 65 | int kvm_cmd_pause(int argc, const char **argv, const char *prefix) 66 | { 67 | int instance; 68 | int r; 69 | 70 | parse_pause_options(argc, argv); 71 | 72 | if (all) 73 | return kvm__enumerate_instances(do_pause); 74 | 75 | if (instance_name == NULL) 76 | kvm_pause_help(); 77 | 78 | instance = kvm__get_sock_by_instance(instance_name); 79 | 80 | if (instance <= 0) 81 | die("Failed locating instance"); 82 | 83 | r = do_pause(instance_name, instance); 84 | 85 | close(instance); 86 | 87 | return r; 88 | } 89 | -------------------------------------------------------------------------------- /builtin-resume.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | static bool all; 14 | static const char *instance_name; 15 | 16 | static const char * const resume_usage[] = { 17 | "lkvm resume [--all] [-n name]", 18 | NULL 19 | }; 20 | 21 | static const struct option resume_options[] = { 22 | OPT_GROUP("General options:"), 23 | OPT_BOOLEAN('a', "all", &all, "Resume all instances"), 24 | OPT_STRING('n', "name", &instance_name, "name", "Instance name"), 25 | OPT_END() 26 | }; 27 | 28 | static void parse_resume_options(int argc, const char **argv) 29 | { 30 | while (argc != 0) { 31 | argc = parse_options(argc, argv, resume_options, resume_usage, 32 | PARSE_OPT_STOP_AT_NON_OPTION); 33 | if (argc != 0) 34 | kvm_resume_help(); 35 | } 36 | } 37 | 38 | void kvm_resume_help(void) 39 | { 40 | usage_with_options(resume_usage, resume_options); 41 | } 42 | 43 | static int do_resume(const char *name, int sock) 44 | { 45 | int r; 46 | int vmstate; 47 | 48 | vmstate = get_vmstate(sock); 49 | if (vmstate < 0) 50 | return vmstate; 51 | if (vmstate == KVM_VMSTATE_RUNNING) { 52 | printf("Guest %s is still running.\n", name); 53 | return 0; 54 | } 55 | 56 | r = kvm_ipc__send(sock, KVM_IPC_RESUME); 57 | if (r) 58 | return r; 59 | 60 | printf("Guest %s resumed\n", name); 61 | 62 | return 0; 63 | } 64 | 65 | int kvm_cmd_resume(int argc, const char **argv, const char *prefix) 66 | { 67 | int instance; 68 | int r; 69 | 70 | parse_resume_options(argc, argv); 71 | 72 | if (all) 73 | return kvm__enumerate_instances(do_resume); 74 | 75 | if (instance_name == NULL) 76 | kvm_resume_help(); 77 | 78 | instance = kvm__get_sock_by_instance(instance_name); 79 | 80 | if (instance <= 0) 81 | die("Failed locating instance"); 82 | 83 | r = do_resume(instance_name, instance); 84 | 85 | close(instance); 86 | 87 | return r; 88 | } 89 | -------------------------------------------------------------------------------- /builtin-sandbox.c: -------------------------------------------------------------------------------- 1 | #include "kvm/builtin-sandbox.h" 2 | #include "kvm/builtin-run.h" 3 | 4 | int kvm_cmd_sandbox(int argc, const char **argv, const char *prefix) 5 | { 6 | kvm_run_set_wrapper_sandbox(); 7 | 8 | return kvm_cmd_run(argc, argv, prefix); 9 | } 10 | -------------------------------------------------------------------------------- /builtin-stop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | static bool all; 13 | static const char *instance_name; 14 | 15 | static const char * const stop_usage[] = { 16 | "lkvm stop [--all] [-n name]", 17 | NULL 18 | }; 19 | 20 | static const struct option stop_options[] = { 21 | OPT_GROUP("General options:"), 22 | OPT_BOOLEAN('a', "all", &all, "Stop all instances"), 23 | OPT_STRING('n', "name", &instance_name, "name", "Instance name"), 24 | OPT_END() 25 | }; 26 | 27 | static void parse_stop_options(int argc, const char **argv) 28 | { 29 | while (argc != 0) { 30 | argc = parse_options(argc, argv, stop_options, stop_usage, 31 | PARSE_OPT_STOP_AT_NON_OPTION); 32 | if (argc != 0) 33 | kvm_stop_help(); 34 | } 35 | } 36 | 37 | void kvm_stop_help(void) 38 | { 39 | usage_with_options(stop_usage, stop_options); 40 | } 41 | 42 | static int do_stop(const char *name, int sock) 43 | { 44 | return kvm_ipc__send(sock, KVM_IPC_STOP); 45 | } 46 | 47 | int kvm_cmd_stop(int argc, const char **argv, const char *prefix) 48 | { 49 | int instance; 50 | int r; 51 | 52 | parse_stop_options(argc, argv); 53 | 54 | if (all) 55 | return kvm__enumerate_instances(do_stop); 56 | 57 | if (instance_name == NULL) 58 | kvm_stop_help(); 59 | 60 | instance = kvm__get_sock_by_instance(instance_name); 61 | 62 | if (instance <= 0) 63 | die("Failed locating instance"); 64 | 65 | r = do_stop(instance_name, instance); 66 | 67 | close(instance); 68 | 69 | return r; 70 | } 71 | -------------------------------------------------------------------------------- /builtin-version.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int kvm_cmd_version(int argc, const char **argv, const char *prefix) 11 | { 12 | printf("kvm tool %s\n", KVMTOOLS_VERSION); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /code16gcc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * code16gcc.h 3 | * 4 | * This file is -include'd when compiling 16-bit C code. 5 | * Note: this asm() needs to be emitted before gcc emits any code. 6 | * Depending on gcc version, this requires -fno-unit-at-a-time or 7 | * -fno-toplevel-reorder. 8 | * 9 | * Hopefully gcc will eventually have a real -m16 option so we can 10 | * drop this hack long term. 11 | */ 12 | 13 | #ifndef __ASSEMBLY__ 14 | asm(".code16gcc"); 15 | #endif 16 | -------------------------------------------------------------------------------- /command-list.txt: -------------------------------------------------------------------------------- 1 | # 2 | # List of known perf commands. 3 | # command name category [deprecated] [common] 4 | # 5 | lkvm-run mainporcelain common 6 | lkvm-setup mainporcelain common 7 | lkvm-pause common 8 | lkvm-resume common 9 | lkvm-version common 10 | lkvm-list common 11 | lkvm-debug common 12 | lkvm-balloon common 13 | lkvm-stop common 14 | lkvm-stat common 15 | lkvm-sandbox common 16 | -------------------------------------------------------------------------------- /devices.c: -------------------------------------------------------------------------------- 1 | #include "kvm/devices.h" 2 | #include "kvm/kvm.h" 3 | #include "kvm/pci.h" 4 | #include "kvm/virtio-mmio.h" 5 | 6 | #include 7 | #include 8 | 9 | struct device_bus { 10 | struct rb_root root; 11 | int dev_num; 12 | }; 13 | 14 | static struct device_bus device_trees[DEVICE_BUS_MAX] = { 15 | [0 ... (DEVICE_BUS_MAX - 1)] = { RB_ROOT, 0 }, 16 | }; 17 | 18 | int device__register(struct device_header *dev) 19 | { 20 | struct device_bus *bus; 21 | struct rb_node **node, *parent = NULL; 22 | 23 | if (dev->bus_type >= DEVICE_BUS_MAX) { 24 | pr_warning("Ignoring device registration on unknown bus %d\n", 25 | dev->bus_type); 26 | return -EINVAL; 27 | } 28 | 29 | bus = &device_trees[dev->bus_type]; 30 | dev->dev_num = bus->dev_num++; 31 | 32 | switch (dev->bus_type) { 33 | case DEVICE_BUS_PCI: 34 | pci__assign_irq(dev); 35 | break; 36 | case DEVICE_BUS_MMIO: 37 | virtio_mmio_assign_irq(dev); 38 | break; 39 | default: 40 | break; 41 | } 42 | 43 | node = &bus->root.rb_node; 44 | while (*node) { 45 | int num = rb_entry(*node, struct device_header, node)->dev_num; 46 | int result = dev->dev_num - num; 47 | 48 | if (result < 0) 49 | node = &((*node)->rb_left); 50 | else if (result > 0) 51 | node = &((*node)->rb_right); 52 | else 53 | return -EEXIST; 54 | } 55 | 56 | rb_link_node(&dev->node, parent, node); 57 | rb_insert_color(&dev->node, &bus->root); 58 | return 0; 59 | } 60 | 61 | void device__unregister(struct device_header *dev) 62 | { 63 | struct device_bus *bus = &device_trees[dev->bus_type]; 64 | rb_erase(&dev->node, &bus->root); 65 | } 66 | 67 | struct device_header *device__find_dev(enum device_bus_type bus_type, u8 dev_num) 68 | { 69 | struct rb_node *node; 70 | 71 | if (bus_type >= DEVICE_BUS_MAX) 72 | return ERR_PTR(-EINVAL); 73 | 74 | node = device_trees[bus_type].root.rb_node; 75 | while (node) { 76 | struct device_header *dev = rb_entry(node, struct device_header, 77 | node); 78 | if (dev_num < dev->dev_num) { 79 | node = node->rb_left; 80 | } else if (dev_num > dev->dev_num) { 81 | node = node->rb_right; 82 | } else { 83 | return dev; 84 | } 85 | } 86 | 87 | return NULL; 88 | } 89 | 90 | struct device_header *device__first_dev(enum device_bus_type bus_type) 91 | { 92 | struct rb_node *node; 93 | 94 | if (bus_type >= DEVICE_BUS_MAX) 95 | return NULL; 96 | 97 | node = rb_first(&device_trees[bus_type].root); 98 | return node ? rb_entry(node, struct device_header, node) : NULL; 99 | } 100 | 101 | struct device_header *device__next_dev(struct device_header *dev) 102 | { 103 | struct rb_node *node = rb_next(&dev->node); 104 | return node ? rb_entry(node, struct device_header, node) : NULL; 105 | } 106 | -------------------------------------------------------------------------------- /disk/blk.c: -------------------------------------------------------------------------------- 1 | #include "kvm/disk-image.h" 2 | 3 | #include 4 | #include 5 | 6 | /* 7 | * raw image and blk dev are similar, so reuse raw image ops. 8 | */ 9 | static struct disk_image_operations blk_dev_ops = { 10 | .read = raw_image__read, 11 | .write = raw_image__write, 12 | }; 13 | 14 | static bool is_mounted(struct stat *st) 15 | { 16 | struct stat st_buf; 17 | struct mntent *mnt; 18 | FILE *f; 19 | 20 | f = setmntent("/proc/mounts", "r"); 21 | if (!f) 22 | return false; 23 | 24 | while ((mnt = getmntent(f)) != NULL) { 25 | if (stat(mnt->mnt_fsname, &st_buf) == 0 && 26 | S_ISBLK(st_buf.st_mode) && st->st_rdev == st_buf.st_rdev) { 27 | fclose(f); 28 | return true; 29 | } 30 | } 31 | 32 | fclose(f); 33 | return false; 34 | } 35 | 36 | struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st) 37 | { 38 | struct disk_image *disk; 39 | int fd, r; 40 | u64 size; 41 | 42 | if (!S_ISBLK(st->st_mode)) 43 | return ERR_PTR(-EINVAL); 44 | 45 | if (is_mounted(st)) { 46 | pr_err("Block device %s is already mounted! Unmount before use.", 47 | filename); 48 | return ERR_PTR(-EINVAL); 49 | } 50 | 51 | /* 52 | * Be careful! We are opening host block device! 53 | * Open it readonly since we do not want to break user's data on disk. 54 | */ 55 | fd = open(filename, flags); 56 | if (fd < 0) 57 | return ERR_PTR(fd); 58 | 59 | if (ioctl(fd, BLKGETSIZE64, &size) < 0) { 60 | r = -errno; 61 | close(fd); 62 | return ERR_PTR(r); 63 | } 64 | 65 | /* 66 | * FIXME: This will not work on 32-bit host because we can not 67 | * mmap large disk. There is not enough virtual address space 68 | * in 32-bit host. However, this works on 64-bit host. 69 | */ 70 | disk = disk_image__new(fd, size, &blk_dev_ops, DISK_IMAGE_REGULAR); 71 | #ifdef CONFIG_HAS_AIO 72 | if (!IS_ERR_OR_NULL(disk)) 73 | disk->async = 1; 74 | #endif 75 | return disk; 76 | } 77 | -------------------------------------------------------------------------------- /framebuffer.c: -------------------------------------------------------------------------------- 1 | #include "kvm/framebuffer.h" 2 | #include "kvm/kvm.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | static LIST_HEAD(framebuffers); 11 | 12 | struct framebuffer *fb__register(struct framebuffer *fb) 13 | { 14 | INIT_LIST_HEAD(&fb->node); 15 | list_add(&fb->node, &framebuffers); 16 | 17 | return fb; 18 | } 19 | 20 | int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops) 21 | { 22 | if (fb->nr_targets >= FB_MAX_TARGETS) 23 | return -ENOSPC; 24 | 25 | fb->targets[fb->nr_targets++] = ops; 26 | 27 | return 0; 28 | } 29 | 30 | static int start_targets(struct framebuffer *fb) 31 | { 32 | unsigned long i; 33 | 34 | for (i = 0; i < fb->nr_targets; i++) { 35 | struct fb_target_operations *ops = fb->targets[i]; 36 | int err = 0; 37 | 38 | if (ops->start) 39 | err = ops->start(fb); 40 | 41 | if (err) 42 | return err; 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | int fb__init(struct kvm *kvm) 49 | { 50 | struct framebuffer *fb; 51 | 52 | list_for_each_entry(fb, &framebuffers, node) { 53 | int err; 54 | 55 | err = start_targets(fb); 56 | if (err) 57 | return err; 58 | } 59 | 60 | return 0; 61 | } 62 | firmware_init(fb__init); 63 | 64 | int fb__exit(struct kvm *kvm) 65 | { 66 | struct framebuffer *fb; 67 | 68 | list_for_each_entry(fb, &framebuffers, node) { 69 | u32 i; 70 | 71 | for (i = 0; i < fb->nr_targets; i++) 72 | if (fb->targets[i]->stop) 73 | fb->targets[i]->stop(fb); 74 | 75 | munmap(fb->mem, fb->mem_size); 76 | } 77 | 78 | return 0; 79 | } 80 | firmware_exit(fb__exit); 81 | -------------------------------------------------------------------------------- /guest/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a simple init for shared rootfs guests. This part should be limited 3 | * to doing mounts and running stage 2 of the init process. 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | static int run_process(char *filename) 15 | { 16 | char *new_argv[] = { filename, NULL }; 17 | char *new_env[] = { "TERM=linux", "DISPLAY=192.168.33.1:0", 18 | "HOME=/virt/home", NULL }; 19 | 20 | return execve(filename, new_argv, new_env); 21 | } 22 | 23 | static int run_process_sandbox(char *filename) 24 | { 25 | char *new_argv[] = { filename, "/virt/sandbox.sh", NULL }; 26 | char *new_env[] = { "TERM=linux", "HOME=/virt/home", NULL }; 27 | 28 | return execve(filename, new_argv, new_env); 29 | } 30 | 31 | static void do_mounts(void) 32 | { 33 | #ifndef CONFIG_GUEST_PRE_INIT 34 | mount("hostfs", "/host", "9p", MS_RDONLY, "trans=virtio,version=9p2000.L"); 35 | #endif 36 | mount("", "/sys", "sysfs", 0, NULL); 37 | mount("proc", "/proc", "proc", 0, NULL); 38 | mount("devtmpfs", "/dev", "devtmpfs", 0, NULL); 39 | mkdir("/dev/pts", 0755); 40 | mount("devpts", "/dev/pts", "devpts", 0, NULL); 41 | } 42 | 43 | int main(int argc, char *argv[]) 44 | { 45 | pid_t child; 46 | int status; 47 | 48 | puts("Mounting..."); 49 | 50 | do_mounts(); 51 | 52 | /* get session leader */ 53 | setsid(); 54 | 55 | /* set controlling terminal */ 56 | ioctl(0, TIOCSCTTY, 1); 57 | 58 | child = fork(); 59 | if (child < 0) { 60 | printf("Fatal: fork() failed with %d\n", child); 61 | return 0; 62 | } else if (child == 0) { 63 | if (access("/virt/sandbox.sh", R_OK) == 0) 64 | run_process_sandbox("/bin/sh"); 65 | else 66 | run_process("/bin/sh"); 67 | } else { 68 | pid_t corpse; 69 | 70 | do { 71 | corpse = waitpid(-1, &status, 0); 72 | } while (corpse != child); 73 | } 74 | 75 | reboot(RB_AUTOBOOT); 76 | 77 | printf("Init failed: %s\n", strerror(errno)); 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /guest_compat.c: -------------------------------------------------------------------------------- 1 | #include "kvm/guest_compat.h" 2 | 3 | #include "kvm/mutex.h" 4 | 5 | #include 6 | #include 7 | 8 | struct compat_message { 9 | int id; 10 | char *title; 11 | char *desc; 12 | 13 | struct list_head list; 14 | }; 15 | 16 | static int id; 17 | static DEFINE_MUTEX(compat_mtx); 18 | static LIST_HEAD(messages); 19 | 20 | static void compat__free(struct compat_message *msg) 21 | { 22 | free(msg->title); 23 | free(msg->desc); 24 | free(msg); 25 | } 26 | 27 | int compat__add_message(const char *title, const char *desc) 28 | { 29 | struct compat_message *msg; 30 | int msg_id; 31 | 32 | msg = malloc(sizeof(*msg)); 33 | if (msg == NULL) 34 | goto cleanup; 35 | 36 | msg->title = strdup(title); 37 | msg->desc = strdup(desc); 38 | 39 | if (msg->title == NULL || msg->desc == NULL) 40 | goto cleanup; 41 | 42 | mutex_lock(&compat_mtx); 43 | 44 | msg->id = msg_id = id++; 45 | list_add_tail(&msg->list, &messages); 46 | 47 | mutex_unlock(&compat_mtx); 48 | 49 | return msg_id; 50 | 51 | cleanup: 52 | if (msg) 53 | compat__free(msg); 54 | 55 | return -ENOMEM; 56 | } 57 | 58 | int compat__remove_message(int id) 59 | { 60 | struct compat_message *pos, *n; 61 | 62 | mutex_lock(&compat_mtx); 63 | 64 | list_for_each_entry_safe(pos, n, &messages, list) { 65 | if (pos->id == id) { 66 | list_del(&pos->list); 67 | compat__free(pos); 68 | 69 | mutex_unlock(&compat_mtx); 70 | 71 | return 0; 72 | } 73 | } 74 | 75 | mutex_unlock(&compat_mtx); 76 | 77 | return -ENOENT; 78 | } 79 | 80 | int compat__print_all_messages(void) 81 | { 82 | mutex_lock(&compat_mtx); 83 | 84 | while (!list_empty(&messages)) { 85 | struct compat_message *msg; 86 | 87 | msg = list_first_entry(&messages, struct compat_message, list); 88 | 89 | printf("\n # KVM compatibility warning.\n\t%s\n\t%s\n", 90 | msg->title, msg->desc); 91 | 92 | list_del(&msg->list); 93 | compat__free(msg); 94 | } 95 | 96 | mutex_unlock(&compat_mtx); 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /hw/vesa.c: -------------------------------------------------------------------------------- 1 | #include "kvm/vesa.h" 2 | 3 | #include "kvm/devices.h" 4 | #include "kvm/virtio-pci-dev.h" 5 | #include "kvm/framebuffer.h" 6 | #include "kvm/kvm-cpu.h" 7 | #include "kvm/ioport.h" 8 | #include "kvm/util.h" 9 | #include "kvm/irq.h" 10 | #include "kvm/kvm.h" 11 | #include "kvm/pci.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | static bool vesa_pci_io_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 22 | { 23 | return true; 24 | } 25 | 26 | static bool vesa_pci_io_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size) 27 | { 28 | return true; 29 | } 30 | 31 | static struct ioport_operations vesa_io_ops = { 32 | .io_in = vesa_pci_io_in, 33 | .io_out = vesa_pci_io_out, 34 | }; 35 | 36 | static struct pci_device_header vesa_pci_device = { 37 | .vendor_id = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET), 38 | .device_id = cpu_to_le16(PCI_DEVICE_ID_VESA), 39 | .header_type = PCI_HEADER_TYPE_NORMAL, 40 | .revision_id = 0, 41 | .class[2] = 0x03, 42 | .subsys_vendor_id = cpu_to_le16(PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET), 43 | .subsys_id = cpu_to_le16(PCI_SUBSYSTEM_ID_VESA), 44 | .bar[1] = cpu_to_le32(VESA_MEM_ADDR | PCI_BASE_ADDRESS_SPACE_MEMORY), 45 | .bar_size[1] = VESA_MEM_SIZE, 46 | }; 47 | 48 | static struct device_header vesa_device = { 49 | .bus_type = DEVICE_BUS_PCI, 50 | .data = &vesa_pci_device, 51 | }; 52 | 53 | static struct framebuffer vesafb; 54 | 55 | struct framebuffer *vesa__init(struct kvm *kvm) 56 | { 57 | u16 vesa_base_addr; 58 | char *mem; 59 | int r; 60 | 61 | if (!kvm->cfg.vnc && !kvm->cfg.sdl && !kvm->cfg.gtk) 62 | return NULL; 63 | 64 | r = ioport__register(kvm, IOPORT_EMPTY, &vesa_io_ops, IOPORT_SIZE, NULL); 65 | if (r < 0) 66 | return ERR_PTR(r); 67 | 68 | vesa_base_addr = (u16)r; 69 | vesa_pci_device.bar[0] = cpu_to_le32(vesa_base_addr | PCI_BASE_ADDRESS_SPACE_IO); 70 | device__register(&vesa_device); 71 | 72 | mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0); 73 | if (mem == MAP_FAILED) 74 | ERR_PTR(-errno); 75 | 76 | kvm__register_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem); 77 | 78 | vesafb = (struct framebuffer) { 79 | .width = VESA_WIDTH, 80 | .height = VESA_HEIGHT, 81 | .depth = VESA_BPP, 82 | .mem = mem, 83 | .mem_addr = VESA_MEM_ADDR, 84 | .mem_size = VESA_MEM_SIZE, 85 | .kvm = kvm, 86 | }; 87 | return fb__register(&vesafb); 88 | } 89 | -------------------------------------------------------------------------------- /include/asm/hweight.h: -------------------------------------------------------------------------------- 1 | #ifndef _KVM_ASM_HWEIGHT_H_ 2 | #define _KVM_ASM_HWEIGHT_H_ 3 | 4 | #include 5 | unsigned int hweight32(unsigned int w); 6 | unsigned long hweight64(__u64 w); 7 | 8 | #endif /* _KVM_ASM_HWEIGHT_H_ */ 9 | -------------------------------------------------------------------------------- /include/kvm/8250-serial.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__8250_SERIAL_H 2 | #define KVM__8250_SERIAL_H 3 | 4 | struct kvm; 5 | 6 | int serial8250__init(struct kvm *kvm); 7 | int serial8250__exit(struct kvm *kvm); 8 | void serial8250__update_consoles(struct kvm *kvm); 9 | void serial8250__inject_sysrq(struct kvm *kvm, char sysrq); 10 | 11 | #endif /* KVM__8250_SERIAL_H */ 12 | -------------------------------------------------------------------------------- /include/kvm/apic.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_APIC_H_ 2 | #define KVM_APIC_H_ 3 | 4 | #include 5 | 6 | /* 7 | * APIC, IOAPIC stuff 8 | */ 9 | #define APIC_BASE_ADDR_STEP 0x00400000 10 | #define IOAPIC_BASE_ADDR_STEP 0x00100000 11 | 12 | #define APIC_ADDR(apic) (APIC_DEFAULT_PHYS_BASE + apic * APIC_BASE_ADDR_STEP) 13 | #define IOAPIC_ADDR(ioapic) (IO_APIC_DEFAULT_PHYS_BASE + ioapic * IOAPIC_BASE_ADDR_STEP) 14 | 15 | #define KVM_APIC_VERSION 0x14 /* xAPIC */ 16 | 17 | #endif /* KVM_APIC_H_ */ 18 | -------------------------------------------------------------------------------- /include/kvm/brlock.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__BRLOCK_H 2 | #define KVM__BRLOCK_H 3 | 4 | #include "kvm/kvm.h" 5 | #include "kvm/barrier.h" 6 | 7 | /* 8 | * brlock is a lock which is very cheap for reads, but very expensive 9 | * for writes. 10 | * This lock will be used when updates are very rare and reads are common. 11 | * This lock is currently implemented by stopping the guest while 12 | * performing the updates. We assume that the only threads whichread from 13 | * the locked data are VCPU threads, and the only writer isn't a VCPU thread. 14 | */ 15 | 16 | #ifndef barrier 17 | #define barrier() __asm__ __volatile__("": : :"memory") 18 | #endif 19 | 20 | #ifdef KVM_BRLOCK_DEBUG 21 | 22 | #include "kvm/rwsem.h" 23 | 24 | DECLARE_RWSEM(brlock_sem); 25 | 26 | #define br_read_lock(kvm) down_read(&brlock_sem); 27 | #define br_read_unlock(kvm) up_read(&brlock_sem); 28 | 29 | #define br_write_lock(kvm) down_write(&brlock_sem); 30 | #define br_write_unlock(kvm) up_write(&brlock_sem); 31 | 32 | #else 33 | 34 | #define br_read_lock(kvm) barrier() 35 | #define br_read_unlock(kvm) barrier() 36 | 37 | #define br_write_lock(kvm) kvm__pause(kvm) 38 | #define br_write_unlock(kvm) kvm__continue(kvm) 39 | #endif 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /include/kvm/builtin-balloon.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__BALLOON_H 2 | #define KVM__BALLOON_H 3 | 4 | #include 5 | 6 | int kvm_cmd_balloon(int argc, const char **argv, const char *prefix); 7 | void kvm_balloon_help(void) NORETURN; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/kvm/builtin-debug.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__DEBUG_H 2 | #define KVM__DEBUG_H 3 | 4 | #include 5 | #include 6 | 7 | #define KVM_DEBUG_CMD_TYPE_DUMP (1 << 0) 8 | #define KVM_DEBUG_CMD_TYPE_NMI (1 << 1) 9 | #define KVM_DEBUG_CMD_TYPE_SYSRQ (1 << 2) 10 | 11 | struct debug_cmd_params { 12 | u32 dbg_type; 13 | u32 cpu; 14 | char sysrq; 15 | }; 16 | 17 | int kvm_cmd_debug(int argc, const char **argv, const char *prefix); 18 | void kvm_debug_help(void) NORETURN; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/kvm/builtin-help.h: -------------------------------------------------------------------------------- 1 | #ifndef __KVM_HELP_H__ 2 | #define __KVM_HELP_H__ 3 | 4 | int kvm_cmd_help(int argc, const char **argv, const char *prefix); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/kvm/builtin-list.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__LIST_H 2 | #define KVM__LIST_H 3 | 4 | #include 5 | 6 | int kvm_cmd_list(int argc, const char **argv, const char *prefix); 7 | void kvm_list_help(void) NORETURN; 8 | int get_vmstate(int sock); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/kvm/builtin-pause.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__PAUSE_H 2 | #define KVM__PAUSE_H 3 | 4 | #include 5 | 6 | int kvm_cmd_pause(int argc, const char **argv, const char *prefix); 7 | void kvm_pause_help(void) NORETURN; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/kvm/builtin-resume.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__RESUME_H 2 | #define KVM__RESUME_H 3 | 4 | #include 5 | 6 | int kvm_cmd_resume(int argc, const char **argv, const char *prefix); 7 | void kvm_resume_help(void) NORETURN; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/kvm/builtin-run.h: -------------------------------------------------------------------------------- 1 | #ifndef __KVM_RUN_H__ 2 | #define __KVM_RUN_H__ 3 | 4 | #include 5 | 6 | int kvm_cmd_run(int argc, const char **argv, const char *prefix); 7 | void kvm_run_help(void) NORETURN; 8 | 9 | void kvm_run_set_wrapper_sandbox(void); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /include/kvm/builtin-sandbox.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__SANDBOX_H 2 | #define KVM__SANDBOX_H 3 | 4 | int kvm_cmd_sandbox(int argc, const char **argv, const char *prefix); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/kvm/builtin-setup.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__SETUP_H 2 | #define KVM__SETUP_H 3 | 4 | #include 5 | 6 | int kvm_cmd_setup(int argc, const char **argv, const char *prefix); 7 | void kvm_setup_help(void) NORETURN; 8 | int kvm_setup_create_new(const char *guestfs_name); 9 | void kvm_setup_resolv(const char *guestfs_name); 10 | int kvm_setup_guest_init(const char *guestfs_name); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /include/kvm/builtin-stat.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__STAT_H 2 | #define KVM__STAT_H 3 | 4 | #include 5 | 6 | int kvm_cmd_stat(int argc, const char **argv, const char *prefix); 7 | void kvm_stat_help(void) NORETURN; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/kvm/builtin-stop.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__STOP_H 2 | #define KVM__STOP_H 3 | 4 | #include 5 | 6 | int kvm_cmd_stop(int argc, const char **argv, const char *prefix); 7 | void kvm_stop_help(void) NORETURN; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /include/kvm/builtin-version.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__VERSION_H 2 | #define KVM__VERSION_H 3 | 4 | int kvm_cmd_version(int argc, const char **argv, const char *prefix); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/kvm/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_COMPILER_H_ 2 | #define KVM_COMPILER_H_ 3 | 4 | #ifndef __compiletime_error 5 | # define __compiletime_error(message) 6 | #endif 7 | 8 | #define notrace __attribute__((no_instrument_function)) 9 | 10 | #endif /* KVM_COMPILER_H_ */ 11 | -------------------------------------------------------------------------------- /include/kvm/devices.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__DEVICES_H 2 | #define KVM__DEVICES_H 3 | 4 | #include 5 | #include 6 | 7 | enum device_bus_type { 8 | DEVICE_BUS_PCI, 9 | DEVICE_BUS_MMIO, 10 | DEVICE_BUS_IOPORT, 11 | DEVICE_BUS_MAX, 12 | }; 13 | 14 | struct device_header { 15 | enum device_bus_type bus_type; 16 | void *data; 17 | int dev_num; 18 | struct rb_node node; 19 | }; 20 | 21 | int device__register(struct device_header *dev); 22 | void device__unregister(struct device_header *dev); 23 | struct device_header *device__find_dev(enum device_bus_type bus_type, 24 | u8 dev_num); 25 | 26 | struct device_header *device__first_dev(enum device_bus_type bus_type); 27 | struct device_header *device__next_dev(struct device_header *dev); 28 | 29 | #endif /* KVM__DEVICES_H */ 30 | -------------------------------------------------------------------------------- /include/kvm/disk-image.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__DISK_IMAGE_H 2 | #define KVM__DISK_IMAGE_H 3 | 4 | #include "kvm/read-write.h" 5 | #include "kvm/util.h" 6 | #include "kvm/parse-options.h" 7 | 8 | #include 9 | #include /* for BLKGETSIZE64 */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define SECTOR_SHIFT 9 23 | #define SECTOR_SIZE (1UL << SECTOR_SHIFT) 24 | 25 | enum { 26 | DISK_IMAGE_REGULAR, 27 | DISK_IMAGE_MMAP, 28 | }; 29 | 30 | #define MAX_DISK_IMAGES 4 31 | 32 | struct disk_image; 33 | 34 | struct disk_image_operations { 35 | ssize_t (*read)(struct disk_image *disk, u64 sector, const struct iovec *iov, 36 | int iovcount, void *param); 37 | ssize_t (*write)(struct disk_image *disk, u64 sector, const struct iovec *iov, 38 | int iovcount, void *param); 39 | int (*flush)(struct disk_image *disk); 40 | int (*close)(struct disk_image *disk); 41 | }; 42 | 43 | struct disk_image_params { 44 | const char *filename; 45 | /* 46 | * wwpn == World Wide Port Number 47 | * tpgt == Target Portal Group Tag 48 | */ 49 | const char *wwpn; 50 | const char *tpgt; 51 | bool readonly; 52 | bool direct; 53 | }; 54 | 55 | struct disk_image { 56 | int fd; 57 | u64 size; 58 | struct disk_image_operations *ops; 59 | void *priv; 60 | void *disk_req_cb_param; 61 | void (*disk_req_cb)(void *param, long len); 62 | bool async; 63 | int evt; 64 | #ifdef CONFIG_HAS_AIO 65 | io_context_t ctx; 66 | #endif 67 | const char *wwpn; 68 | const char *tpgt; 69 | int debug_iodelay; 70 | }; 71 | 72 | int disk_img_name_parser(const struct option *opt, const char *arg, int unset); 73 | int disk_image__init(struct kvm *kvm); 74 | int disk_image__exit(struct kvm *kvm); 75 | struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int mmap); 76 | int disk_image__flush(struct disk_image *disk); 77 | ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov, 78 | int iovcount, void *param); 79 | ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iovec *iov, 80 | int iovcount, void *param); 81 | ssize_t disk_image__get_serial(struct disk_image *disk, void *buffer, ssize_t *len); 82 | 83 | struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly); 84 | struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st); 85 | 86 | ssize_t raw_image__read(struct disk_image *disk, u64 sector, 87 | const struct iovec *iov, int iovcount, void *param); 88 | ssize_t raw_image__write(struct disk_image *disk, u64 sector, 89 | const struct iovec *iov, int iovcount, void *param); 90 | ssize_t raw_image__read_mmap(struct disk_image *disk, u64 sector, 91 | const struct iovec *iov, int iovcount, void *param); 92 | ssize_t raw_image__write_mmap(struct disk_image *disk, u64 sector, 93 | const struct iovec *iov, int iovcount, void *param); 94 | int raw_image__close(struct disk_image *disk); 95 | void disk_image__set_callback(struct disk_image *disk, void (*disk_req_cb)(void *param, long len)); 96 | #endif /* KVM__DISK_IMAGE_H */ 97 | -------------------------------------------------------------------------------- /include/kvm/fdt.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__FDT_H 2 | #define KVM__FDT_H 3 | 4 | #ifdef CONFIG_HAS_LIBFDT 5 | #include 6 | #endif 7 | 8 | #include 9 | 10 | #define FDT_MAX_SIZE 0x10000 11 | 12 | /* Those definitions are generic FDT values for specifying IRQ 13 | * types and are used in the Linux kernel internally as well as in 14 | * the dts files and their documentation. 15 | */ 16 | enum irq_type { 17 | IRQ_TYPE_NONE = 0x00000000, 18 | IRQ_TYPE_EDGE_RISING = 0x00000001, 19 | IRQ_TYPE_EDGE_FALLING = 0x00000002, 20 | IRQ_TYPE_EDGE_BOTH = (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING), 21 | IRQ_TYPE_LEVEL_HIGH = 0x00000004, 22 | IRQ_TYPE_LEVEL_LOW = 0x00000008, 23 | IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), 24 | }; 25 | 26 | /* Helper for the various bits of code that generate FDT nodes */ 27 | #define _FDT(exp) \ 28 | do { \ 29 | int ret = (exp); \ 30 | if (ret < 0) { \ 31 | die("Error creating device tree: %s: %s\n", \ 32 | #exp, fdt_strerror(ret)); \ 33 | } \ 34 | } while (0) 35 | 36 | static inline u32 fdt__alloc_phandle(void) 37 | { 38 | static u32 phandle = 0; 39 | return ++phandle; 40 | } 41 | 42 | #endif /* KVM__FDT_H */ 43 | -------------------------------------------------------------------------------- /include/kvm/framebuffer.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__FRAMEBUFFER_H 2 | #define KVM__FRAMEBUFFER_H 3 | 4 | #include 5 | #include 6 | 7 | struct framebuffer; 8 | 9 | struct fb_target_operations { 10 | int (*start)(struct framebuffer *fb); 11 | int (*stop)(struct framebuffer *fb); 12 | }; 13 | 14 | #define FB_MAX_TARGETS 2 15 | 16 | struct framebuffer { 17 | struct list_head node; 18 | 19 | u32 width; 20 | u32 height; 21 | u8 depth; 22 | char *mem; 23 | u64 mem_addr; 24 | u64 mem_size; 25 | struct kvm *kvm; 26 | 27 | unsigned long nr_targets; 28 | struct fb_target_operations *targets[FB_MAX_TARGETS]; 29 | }; 30 | 31 | struct framebuffer *fb__register(struct framebuffer *fb); 32 | int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops); 33 | int fb__init(struct kvm *kvm); 34 | int fb__exit(struct kvm *kvm); 35 | 36 | #endif /* KVM__FRAMEBUFFER_H */ 37 | -------------------------------------------------------------------------------- /include/kvm/gtk3.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__GTK3_H 2 | #define KVM__GTK3_H 3 | 4 | #include "kvm/util.h" 5 | 6 | struct framebuffer; 7 | 8 | #ifdef CONFIG_HAS_GTK3 9 | int kvm_gtk_init(struct kvm *kvm); 10 | int kvm_gtk_exit(struct kvm *kvm); 11 | #else 12 | static inline int kvm_gtk_init(struct kvm *kvm) 13 | { 14 | if (kvm->cfg.gtk) 15 | die("GTK3 support not compiled in. (install the gtk3-devel or libgtk3.0-dev package)"); 16 | 17 | return 0; 18 | } 19 | static inline int kvm_gtk_exit(struct kvm *kvm) 20 | { 21 | if (kvm->cfg.gtk) 22 | die("GTK3 support not compiled in. (install the gtk3-devel or libgtk3.0-dev package)"); 23 | 24 | return 0; 25 | } 26 | #endif 27 | 28 | #endif /* KVM__GTK3_H */ 29 | -------------------------------------------------------------------------------- /include/kvm/guest_compat.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__GUEST_COMPAT_H 2 | #define KVM__GUEST_COMPAT_H 3 | 4 | int compat__print_all_messages(void); 5 | int compat__remove_message(int id); 6 | int compat__add_message(const char *title, const char *description); 7 | 8 | 9 | #endif -------------------------------------------------------------------------------- /include/kvm/i8042.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__PCKBD_H 2 | #define KVM__PCKBD_H 3 | 4 | #include 5 | 6 | struct kvm; 7 | 8 | void mouse_queue(u8 c); 9 | void kbd_queue(u8 c); 10 | int kbd__init(struct kvm *kvm); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /include/kvm/ioeventfd.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__IOEVENTFD_H 2 | #define KVM__IOEVENTFD_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "kvm/util.h" 8 | 9 | struct kvm; 10 | 11 | struct ioevent { 12 | u64 io_addr; 13 | u8 io_len; 14 | void (*fn)(struct kvm *kvm, void *ptr); 15 | struct kvm *fn_kvm; 16 | void *fn_ptr; 17 | int fd; 18 | u64 datamatch; 19 | 20 | struct list_head list; 21 | }; 22 | 23 | #define IOEVENTFD_FLAG_PIO (1 << 0) 24 | #define IOEVENTFD_FLAG_USER_POLL (1 << 1) 25 | 26 | int ioeventfd__init(struct kvm *kvm); 27 | int ioeventfd__exit(struct kvm *kvm); 28 | int ioeventfd__add_event(struct ioevent *ioevent, int flags); 29 | int ioeventfd__del_event(u64 addr, u64 datamatch); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/kvm/ioport.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__IOPORT_H 2 | #define KVM__IOPORT_H 3 | 4 | #include "kvm/devices.h" 5 | #include "kvm/kvm-cpu.h" 6 | #include "kvm/rbtree-interval.h" 7 | #include "kvm/fdt.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /* some ports we reserve for own use */ 16 | #define IOPORT_DBG 0xe0 17 | #define IOPORT_START 0x6200 18 | #define IOPORT_SIZE 0x400 19 | 20 | #define IOPORT_EMPTY USHRT_MAX 21 | 22 | struct kvm; 23 | 24 | struct ioport { 25 | struct rb_int_node node; 26 | struct ioport_operations *ops; 27 | void *priv; 28 | struct device_header dev_hdr; 29 | }; 30 | 31 | struct ioport_operations { 32 | bool (*io_in)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size); 33 | bool (*io_out)(struct ioport *ioport, struct kvm_cpu *vcpu, u16 port, void *data, int size); 34 | void (*generate_fdt_node)(struct ioport *ioport, void *fdt, 35 | void (*generate_irq_prop)(void *fdt, 36 | u8 irq, 37 | enum irq_type)); 38 | }; 39 | 40 | void ioport__setup_arch(struct kvm *kvm); 41 | void ioport__map_irq(u8 *irq); 42 | 43 | int ioport__register(struct kvm *kvm, u16 port, struct ioport_operations *ops, 44 | int count, void *param); 45 | int ioport__unregister(struct kvm *kvm, u16 port); 46 | int ioport__init(struct kvm *kvm); 47 | int ioport__exit(struct kvm *kvm); 48 | 49 | static inline u8 ioport__read8(u8 *data) 50 | { 51 | return *data; 52 | } 53 | /* On BE platforms, PCI I/O is byteswapped, i.e. LE, so swap back. */ 54 | static inline u16 ioport__read16(u16 *data) 55 | { 56 | return le16_to_cpu(*data); 57 | } 58 | 59 | static inline u32 ioport__read32(u32 *data) 60 | { 61 | return le32_to_cpu(*data); 62 | } 63 | 64 | static inline void ioport__write8(u8 *data, u8 value) 65 | { 66 | *data = value; 67 | } 68 | 69 | static inline void ioport__write16(u16 *data, u16 value) 70 | { 71 | *data = cpu_to_le16(value); 72 | } 73 | 74 | static inline void ioport__write32(u32 *data, u32 value) 75 | { 76 | *data = cpu_to_le32(value); 77 | } 78 | 79 | #endif /* KVM__IOPORT_H */ 80 | -------------------------------------------------------------------------------- /include/kvm/iovec.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_UTIL_IOVEC_H_ 2 | #define KVM_UTIL_IOVEC_H_ 3 | 4 | extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); 5 | extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, 6 | size_t offset, int len); 7 | extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); 8 | extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, 9 | size_t offset, int len); 10 | 11 | static inline size_t iov_size(const struct iovec *iovec, size_t len) 12 | { 13 | size_t size = 0, i; 14 | 15 | for (i = 0; i < len; i++) 16 | size += iovec[i].iov_len; 17 | 18 | return size; 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /include/kvm/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__IRQ_H 2 | #define KVM__IRQ_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "kvm/msi.h" 10 | 11 | struct kvm; 12 | 13 | int irq__alloc_line(void); 14 | int irq__get_nr_allocated_lines(void); 15 | 16 | int irq__init(struct kvm *kvm); 17 | int irq__exit(struct kvm *kvm); 18 | int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/kvm/kvm-cmd.h: -------------------------------------------------------------------------------- 1 | #ifndef __KVM_CMD_H__ 2 | #define __KVM_CMD_H__ 3 | 4 | struct cmd_struct { 5 | const char *cmd; 6 | int (*fn)(int, const char **, const char *); 7 | void (*help)(void); 8 | int option; 9 | }; 10 | 11 | extern struct cmd_struct kvm_commands[]; 12 | struct cmd_struct *kvm_get_command(struct cmd_struct *command, 13 | const char *cmd); 14 | 15 | int handle_command(struct cmd_struct *command, int argc, const char **argv); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /include/kvm/kvm-config.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_CONFIG_H_ 2 | #define KVM_CONFIG_H_ 3 | 4 | #include "kvm/disk-image.h" 5 | #include "kvm/kvm-config-arch.h" 6 | 7 | #define DEFAULT_KVM_DEV "/dev/kvm" 8 | #define DEFAULT_CONSOLE "serial" 9 | #define DEFAULT_NETWORK "user" 10 | #define DEFAULT_HOST_ADDR "192.168.33.1" 11 | #define DEFAULT_GUEST_ADDR "192.168.33.15" 12 | #define DEFAULT_GUEST_MAC "02:15:15:15:15:15" 13 | #define DEFAULT_HOST_MAC "02:01:01:01:01:01" 14 | #define DEFAULT_SCRIPT "none" 15 | #define DEFAULT_SANDBOX_FILENAME "guest/sandbox.sh" 16 | 17 | #define MIN_RAM_SIZE_MB (64ULL) 18 | #define MIN_RAM_SIZE_BYTE (MIN_RAM_SIZE_MB << MB_SHIFT) 19 | 20 | struct kvm_config { 21 | struct kvm_config_arch arch; 22 | struct disk_image_params disk_image[MAX_DISK_IMAGES]; 23 | u64 ram_size; 24 | u8 image_count; 25 | u8 num_net_devices; 26 | bool virtio_rng; 27 | int active_console; 28 | int debug_iodelay; 29 | int nrcpus; 30 | const char *kernel_cmdline; 31 | const char *kernel_filename; 32 | const char *vmlinux_filename; 33 | const char *initrd_filename; 34 | const char *firmware_filename; 35 | const char *console; 36 | const char *dev; 37 | const char *network; 38 | const char *host_ip; 39 | const char *guest_ip; 40 | const char *guest_mac; 41 | const char *host_mac; 42 | const char *script; 43 | const char *guest_name; 44 | const char *sandbox; 45 | const char *hugetlbfs_path; 46 | const char *custom_rootfs_name; 47 | const char *real_cmdline; 48 | struct virtio_net_params *net_params; 49 | bool single_step; 50 | bool vnc; 51 | bool gtk; 52 | bool sdl; 53 | bool balloon; 54 | bool using_rootfs; 55 | bool custom_rootfs; 56 | bool no_net; 57 | bool no_dhcp; 58 | bool ioport_debug; 59 | bool mmio_debug; 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /include/kvm/kvm-cpu.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CPU_H 2 | #define KVM__KVM_CPU_H 3 | 4 | #include "kvm/kvm-cpu-arch.h" 5 | #include 6 | 7 | int kvm_cpu__init(struct kvm *kvm); 8 | int kvm_cpu__exit(struct kvm *kvm); 9 | struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id); 10 | void kvm_cpu__delete(struct kvm_cpu *vcpu); 11 | void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu); 12 | void kvm_cpu__setup_cpuid(struct kvm_cpu *vcpu); 13 | void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu); 14 | void kvm_cpu__run(struct kvm_cpu *vcpu); 15 | void kvm_cpu__reboot(struct kvm *kvm); 16 | int kvm_cpu__start(struct kvm_cpu *cpu); 17 | bool kvm_cpu__handle_exit(struct kvm_cpu *vcpu); 18 | int kvm_cpu__get_endianness(struct kvm_cpu *vcpu); 19 | 20 | int kvm_cpu__get_debug_fd(void); 21 | void kvm_cpu__set_debug_fd(int fd); 22 | void kvm_cpu__show_code(struct kvm_cpu *vcpu); 23 | void kvm_cpu__show_registers(struct kvm_cpu *vcpu); 24 | void kvm_cpu__show_page_tables(struct kvm_cpu *vcpu); 25 | void kvm_cpu__arch_nmi(struct kvm_cpu *cpu); 26 | 27 | #endif /* KVM__KVM_CPU_H */ 28 | -------------------------------------------------------------------------------- /include/kvm/kvm-ipc.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__IPC_H_ 2 | #define KVM__IPC_H_ 3 | 4 | #include 5 | #include "kvm/kvm.h" 6 | 7 | enum { 8 | KVM_IPC_BALLOON = 1, 9 | KVM_IPC_DEBUG = 2, 10 | KVM_IPC_STAT = 3, 11 | KVM_IPC_PAUSE = 4, 12 | KVM_IPC_RESUME = 5, 13 | KVM_IPC_STOP = 6, 14 | KVM_IPC_PID = 7, 15 | KVM_IPC_VMSTATE = 8, 16 | }; 17 | 18 | int kvm_ipc__register_handler(u32 type, void (*cb)(struct kvm *kvm, 19 | int fd, u32 type, u32 len, u8 *msg)); 20 | int kvm_ipc__init(struct kvm *kvm); 21 | int kvm_ipc__exit(struct kvm *kvm); 22 | 23 | int kvm_ipc__send(int fd, u32 type); 24 | int kvm_ipc__send_msg(int fd, u32 type, u32 len, u8 *msg); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /include/kvm/msi.h: -------------------------------------------------------------------------------- 1 | #ifndef LKVM_MSI_H 2 | #define LKVM_MSI_H 3 | 4 | struct msi_msg { 5 | u32 address_lo; /* low 32 bits of msi message address */ 6 | u32 address_hi; /* high 32 bits of msi message address */ 7 | u32 data; /* 16 bits of msi message data */ 8 | }; 9 | 10 | #endif /* LKVM_MSI_H */ 11 | -------------------------------------------------------------------------------- /include/kvm/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__MUTEX_H 2 | #define KVM__MUTEX_H 3 | 4 | #include 5 | 6 | #include "kvm/util.h" 7 | 8 | /* 9 | * Kernel-alike mutex API - to make it easier for kernel developers 10 | * to write user-space code! :-) 11 | */ 12 | 13 | struct mutex { 14 | pthread_mutex_t mutex; 15 | }; 16 | #define MUTEX_INITIALIZER { .mutex = PTHREAD_MUTEX_INITIALIZER } 17 | 18 | #define DEFINE_MUTEX(mtx) struct mutex mtx = MUTEX_INITIALIZER 19 | 20 | static inline void mutex_init(struct mutex *lock) 21 | { 22 | if (pthread_mutex_init(&lock->mutex, NULL) != 0) 23 | die("unexpected pthread_mutex_init() failure!"); 24 | } 25 | 26 | static inline void mutex_lock(struct mutex *lock) 27 | { 28 | if (pthread_mutex_lock(&lock->mutex) != 0) 29 | die("unexpected pthread_mutex_lock() failure!"); 30 | 31 | } 32 | 33 | static inline void mutex_unlock(struct mutex *lock) 34 | { 35 | if (pthread_mutex_unlock(&lock->mutex) != 0) 36 | die("unexpected pthread_mutex_unlock() failure!"); 37 | } 38 | 39 | #endif /* KVM__MUTEX_H */ 40 | -------------------------------------------------------------------------------- /include/kvm/of_pci.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__OF_PCI_H 2 | #define KVM__OF_PCI_H 3 | 4 | #include 5 | 6 | /* 7 | * Definitions for implementing parts of the OpenFirmware PCI Bus Binding 8 | * Specification (IEEE Std 1275-1994). 9 | */ 10 | 11 | struct of_pci_unit_address { 12 | u32 hi, mid, lo; 13 | } __attribute__((packed)); 14 | 15 | struct of_pci_irq_mask { 16 | struct of_pci_unit_address pci_addr; 17 | u32 pci_pin; 18 | } __attribute__((packed)); 19 | 20 | struct of_pci_ranges_entry { 21 | struct of_pci_unit_address pci_addr; 22 | u64 cpu_addr; 23 | u64 length; 24 | } __attribute__((packed)); 25 | 26 | /* Macros to operate with address in OF binding to PCI */ 27 | #define __b_x(x, p, l) (((x) & ((1<<(l))-1)) << (p)) 28 | #define of_pci_b_n(x) __b_x((x), 31, 1) /* 0 if relocatable */ 29 | #define of_pci_b_p(x) __b_x((x), 30, 1) /* 1 if prefetchable */ 30 | #define of_pci_b_t(x) __b_x((x), 29, 1) /* 1 if the address is aliased */ 31 | #define of_pci_b_ss(x) __b_x((x), 24, 2) /* the space code */ 32 | #define of_pci_b_bbbbbbbb(x) __b_x((x), 16, 8) /* bus number */ 33 | #define of_pci_b_ddddd(x) __b_x((x), 11, 5) /* device number */ 34 | #define of_pci_b_fff(x) __b_x((x), 8, 3) /* function number */ 35 | #define of_pci_b_rrrrrrrr(x) __b_x((x), 0, 8) /* register number */ 36 | 37 | #define OF_PCI_SS_CONFIG 0 38 | #define OF_PCI_SS_IO 1 39 | #define OF_PCI_SS_M32 2 40 | #define OF_PCI_SS_M64 3 41 | 42 | #define OF_PCI_IRQ_MAP_MAX 256 /* 5 bit device + 3 bit pin */ 43 | 44 | #endif /* KVM__OF_PCI_H */ 45 | -------------------------------------------------------------------------------- /include/kvm/pci-shmem.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__PCI_SHMEM_H 2 | #define KVM__PCI_SHMEM_H 3 | 4 | #include 5 | #include 6 | 7 | #include "kvm/parse-options.h" 8 | 9 | #define SHMEM_DEFAULT_SIZE (16 << MB_SHIFT) 10 | #define SHMEM_DEFAULT_ADDR (0xc8000000) 11 | #define SHMEM_DEFAULT_HANDLE "/kvm_shmem" 12 | 13 | struct kvm; 14 | struct shmem_info; 15 | 16 | struct shmem_info { 17 | u64 phys_addr; 18 | u64 size; 19 | char *handle; 20 | int create; 21 | int private; 22 | int file; 23 | }; 24 | 25 | int pci_shmem__init(struct kvm *kvm); 26 | int pci_shmem__exit(struct kvm *kvm); 27 | int pci_shmem__register_mem(struct shmem_info *si); 28 | int shmem_parser(const struct option *opt, const char *arg, int unset); 29 | 30 | int pci_shmem__get_local_irqfd(struct kvm *kvm); 31 | int pci_shmem__add_client(struct kvm *kvm, u32 id, int fd); 32 | int pci_shmem__remove_client(struct kvm *kvm, u32 id); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/kvm/pci.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__PCI_H 2 | #define KVM__PCI_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "kvm/devices.h" 10 | #include "kvm/kvm.h" 11 | #include "kvm/msi.h" 12 | 13 | /* 14 | * PCI Configuration Mechanism #1 I/O ports. See Section 3.7.4.1. 15 | * ("Configuration Mechanism #1") of the PCI Local Bus Specification 2.1 for 16 | * details. 17 | */ 18 | #define PCI_CONFIG_ADDRESS 0xcf8 19 | #define PCI_CONFIG_DATA 0xcfc 20 | #define PCI_CONFIG_BUS_FORWARD 0xcfa 21 | #define PCI_IO_SIZE 0x100 22 | #define PCI_CFG_SIZE (1ULL << 24) 23 | 24 | union pci_config_address { 25 | struct { 26 | #if __BYTE_ORDER == __LITTLE_ENDIAN 27 | unsigned reg_offset : 2; /* 1 .. 0 */ 28 | unsigned register_number : 6; /* 7 .. 2 */ 29 | unsigned function_number : 3; /* 10 .. 8 */ 30 | unsigned device_number : 5; /* 15 .. 11 */ 31 | unsigned bus_number : 8; /* 23 .. 16 */ 32 | unsigned reserved : 7; /* 30 .. 24 */ 33 | unsigned enable_bit : 1; /* 31 */ 34 | #else 35 | unsigned enable_bit : 1; /* 31 */ 36 | unsigned reserved : 7; /* 30 .. 24 */ 37 | unsigned bus_number : 8; /* 23 .. 16 */ 38 | unsigned device_number : 5; /* 15 .. 11 */ 39 | unsigned function_number : 3; /* 10 .. 8 */ 40 | unsigned register_number : 6; /* 7 .. 2 */ 41 | unsigned reg_offset : 2; /* 1 .. 0 */ 42 | #endif 43 | }; 44 | u32 w; 45 | }; 46 | 47 | struct msix_table { 48 | struct msi_msg msg; 49 | u32 ctrl; 50 | }; 51 | 52 | struct msix_cap { 53 | u8 cap; 54 | u8 next; 55 | u16 ctrl; 56 | u32 table_offset; 57 | u32 pba_offset; 58 | }; 59 | 60 | struct pci_device_header { 61 | u16 vendor_id; 62 | u16 device_id; 63 | u16 command; 64 | u16 status; 65 | u8 revision_id; 66 | u8 class[3]; 67 | u8 cacheline_size; 68 | u8 latency_timer; 69 | u8 header_type; 70 | u8 bist; 71 | u32 bar[6]; 72 | u32 card_bus; 73 | u16 subsys_vendor_id; 74 | u16 subsys_id; 75 | u32 exp_rom_bar; 76 | u8 capabilities; 77 | u8 reserved1[3]; 78 | u32 reserved2; 79 | u8 irq_line; 80 | u8 irq_pin; 81 | u8 min_gnt; 82 | u8 max_lat; 83 | struct msix_cap msix; 84 | u8 empty[136]; /* Rest of PCI config space */ 85 | u32 bar_size[6]; 86 | } __attribute__((packed)); 87 | 88 | int pci__init(struct kvm *kvm); 89 | int pci__exit(struct kvm *kvm); 90 | struct pci_device_header *pci__find_dev(u8 dev_num); 91 | u32 pci_get_io_space_block(u32 size); 92 | void pci__assign_irq(struct device_header *dev_hdr); 93 | void pci__config_wr(struct kvm *kvm, union pci_config_address addr, void *data, int size); 94 | void pci__config_rd(struct kvm *kvm, union pci_config_address addr, void *data, int size); 95 | 96 | #endif /* KVM__PCI_H */ 97 | -------------------------------------------------------------------------------- /include/kvm/qcow.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__QCOW_H 2 | #define KVM__QCOW_H 3 | 4 | #include "kvm/mutex.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb) 12 | 13 | #define QCOW1_VERSION 1 14 | #define QCOW2_VERSION 2 15 | 16 | #define QCOW1_OFLAG_COMPRESSED (1ULL << 63) 17 | 18 | #define QCOW2_OFLAG_COPIED (1ULL << 63) 19 | #define QCOW2_OFLAG_COMPRESSED (1ULL << 62) 20 | 21 | #define QCOW2_OFLAGS_MASK (QCOW2_OFLAG_COPIED|QCOW2_OFLAG_COMPRESSED) 22 | 23 | #define QCOW2_OFFSET_MASK (~QCOW2_OFLAGS_MASK) 24 | 25 | #define MAX_CACHE_NODES 32 26 | 27 | struct qcow_l2_table { 28 | u64 offset; 29 | struct rb_node node; 30 | struct list_head list; 31 | u8 dirty; 32 | u64 table[]; 33 | }; 34 | 35 | struct qcow_l1_table { 36 | u32 table_size; 37 | u64 *l1_table; 38 | 39 | /* Level2 caching data structures */ 40 | struct rb_root root; 41 | struct list_head lru_list; 42 | int nr_cached; 43 | }; 44 | 45 | #define QCOW_REFCOUNT_BLOCK_SHIFT 1 46 | 47 | struct qcow_refcount_block { 48 | u64 offset; 49 | struct rb_node node; 50 | struct list_head list; 51 | u64 size; 52 | u8 dirty; 53 | u16 entries[]; 54 | }; 55 | 56 | struct qcow_refcount_table { 57 | u32 rf_size; 58 | u64 *rf_table; 59 | 60 | /* Refcount block caching data structures */ 61 | struct rb_root root; 62 | struct list_head lru_list; 63 | int nr_cached; 64 | }; 65 | 66 | struct qcow_header { 67 | u64 size; /* in bytes */ 68 | u64 l1_table_offset; 69 | u32 l1_size; 70 | u8 cluster_bits; 71 | u8 l2_bits; 72 | u64 refcount_table_offset; 73 | u32 refcount_table_size; 74 | }; 75 | 76 | struct qcow { 77 | struct mutex mutex; 78 | struct qcow_header *header; 79 | struct qcow_l1_table table; 80 | struct qcow_refcount_table refcount_table; 81 | int fd; 82 | int csize_shift; 83 | int csize_mask; 84 | u32 version; 85 | u64 cluster_size; 86 | u64 cluster_offset_mask; 87 | u64 free_clust_idx; 88 | void *cluster_cache; 89 | void *cluster_data; 90 | void *copy_buff; 91 | }; 92 | 93 | struct qcow1_header_disk { 94 | u32 magic; 95 | u32 version; 96 | 97 | u64 backing_file_offset; 98 | u32 backing_file_size; 99 | u32 mtime; 100 | 101 | u64 size; /* in bytes */ 102 | 103 | u8 cluster_bits; 104 | u8 l2_bits; 105 | u32 crypt_method; 106 | 107 | u64 l1_table_offset; 108 | }; 109 | 110 | struct qcow2_header_disk { 111 | u32 magic; 112 | u32 version; 113 | 114 | u64 backing_file_offset; 115 | u32 backing_file_size; 116 | 117 | u32 cluster_bits; 118 | u64 size; /* in bytes */ 119 | u32 crypt_method; 120 | 121 | u32 l1_size; 122 | u64 l1_table_offset; 123 | 124 | u64 refcount_table_offset; 125 | u32 refcount_table_clusters; 126 | 127 | u32 nb_snapshots; 128 | u64 snapshots_offset; 129 | }; 130 | 131 | struct disk_image *qcow_probe(int fd, bool readonly); 132 | 133 | #endif /* KVM__QCOW_H */ 134 | -------------------------------------------------------------------------------- /include/kvm/rbtree-interval.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__INTERVAL_RBTREE_H 2 | #define KVM__INTERVAL_RBTREE_H 3 | 4 | #include 5 | #include 6 | 7 | #define RB_INT_INIT(l, h) \ 8 | (struct rb_int_node){.low = l, .high = h} 9 | #define rb_int(n) rb_entry(n, struct rb_int_node, node) 10 | 11 | struct rb_int_node { 12 | struct rb_node node; 13 | u64 low; 14 | u64 high; 15 | }; 16 | 17 | /* Return the rb_int_node interval in which 'point' is located. */ 18 | struct rb_int_node *rb_int_search_single(struct rb_root *root, u64 point); 19 | 20 | /* Return the rb_int_node in which start:len is located. */ 21 | struct rb_int_node *rb_int_search_range(struct rb_root *root, u64 low, u64 high); 22 | 23 | int rb_int_insert(struct rb_root *root, struct rb_int_node *data); 24 | 25 | static inline void rb_int_erase(struct rb_root *root, struct rb_int_node *node) 26 | { 27 | rb_erase(&node->node, root); 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/kvm/read-write.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_READ_WRITE_H 2 | #define KVM_READ_WRITE_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #ifdef CONFIG_HAS_AIO 9 | #include 10 | #endif 11 | 12 | ssize_t xread(int fd, void *buf, size_t count); 13 | ssize_t xwrite(int fd, const void *buf, size_t count); 14 | 15 | ssize_t read_in_full(int fd, void *buf, size_t count); 16 | ssize_t write_in_full(int fd, const void *buf, size_t count); 17 | 18 | ssize_t xpread(int fd, void *buf, size_t count, off_t offset); 19 | ssize_t xpwrite(int fd, const void *buf, size_t count, off_t offset); 20 | 21 | ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset); 22 | ssize_t pwrite_in_full(int fd, const void *buf, size_t count, off_t offset); 23 | 24 | ssize_t xreadv(int fd, const struct iovec *iov, int iovcnt); 25 | ssize_t xwritev(int fd, const struct iovec *iov, int iovcnt); 26 | 27 | ssize_t readv_in_full(int fd, const struct iovec *iov, int iovcnt); 28 | ssize_t writev_in_full(int fd, const struct iovec *iov, int iovcnt); 29 | 30 | ssize_t xpreadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); 31 | ssize_t xpwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); 32 | 33 | ssize_t preadv_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset); 34 | ssize_t pwritev_in_full(int fd, const struct iovec *iov, int iovcnt, off_t offset); 35 | 36 | #ifdef CONFIG_HAS_AIO 37 | int aio_preadv(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, 38 | off_t offset, int ev, void *param); 39 | int aio_pwritev(io_context_t ctx, struct iocb *iocb, int fd, const struct iovec *iov, int iovcnt, 40 | off_t offset, int ev, void *param); 41 | #endif 42 | 43 | #endif /* KVM_READ_WRITE_H */ 44 | -------------------------------------------------------------------------------- /include/kvm/rtc.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__RTC_H 2 | #define KVM__RTC_H 3 | 4 | struct kvm; 5 | 6 | int rtc__init(struct kvm *kvm); 7 | int rtc__exit(struct kvm *kvm); 8 | 9 | #endif /* KVM__RTC_H */ 10 | -------------------------------------------------------------------------------- /include/kvm/rwsem.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__RWSEM_H 2 | #define KVM__RWSEM_H 3 | 4 | #include 5 | 6 | #include "kvm/util.h" 7 | 8 | /* 9 | * Kernel-alike rwsem API - to make it easier for kernel developers 10 | * to write user-space code! :-) 11 | */ 12 | 13 | #define DECLARE_RWSEM(sem) pthread_rwlock_t sem = PTHREAD_RWLOCK_INITIALIZER 14 | 15 | static inline void down_read(pthread_rwlock_t *rwsem) 16 | { 17 | if (pthread_rwlock_rdlock(rwsem) != 0) 18 | die("unexpected pthread_rwlock_rdlock() failure!"); 19 | } 20 | 21 | static inline void down_write(pthread_rwlock_t *rwsem) 22 | { 23 | if (pthread_rwlock_wrlock(rwsem) != 0) 24 | die("unexpected pthread_rwlock_wrlock() failure!"); 25 | } 26 | 27 | static inline void up_read(pthread_rwlock_t *rwsem) 28 | { 29 | if (pthread_rwlock_unlock(rwsem) != 0) 30 | die("unexpected pthread_rwlock_unlock() failure!"); 31 | } 32 | 33 | static inline void up_write(pthread_rwlock_t *rwsem) 34 | { 35 | if (pthread_rwlock_unlock(rwsem) != 0) 36 | die("unexpected pthread_rwlock_unlock() failure!"); 37 | } 38 | 39 | #endif /* KVM__RWSEM_H */ 40 | -------------------------------------------------------------------------------- /include/kvm/sdl.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__SDL_H 2 | #define KVM__SDL_H 3 | 4 | #include "kvm/util.h" 5 | 6 | struct framebuffer; 7 | 8 | #ifdef CONFIG_HAS_SDL 9 | int sdl__init(struct kvm *kvm); 10 | int sdl__exit(struct kvm *kvm); 11 | #else 12 | static inline int sdl__init(struct kvm *kvm) 13 | { 14 | if (kvm->cfg.sdl) 15 | die("SDL support not compiled in. (install the SDL-dev[el] package)"); 16 | 17 | return 0; 18 | } 19 | static inline int sdl__exit(struct kvm *kvm) 20 | { 21 | if (kvm->cfg.sdl) 22 | die("SDL support not compiled in. (install the SDL-dev[el] package)"); 23 | 24 | return 0; 25 | } 26 | #endif 27 | 28 | #endif /* KVM__SDL_H */ 29 | -------------------------------------------------------------------------------- /include/kvm/strbuf.h: -------------------------------------------------------------------------------- 1 | #ifndef __STRBUF_H__ 2 | #define __STRBUF_H__ 3 | 4 | #include 5 | #include 6 | 7 | int prefixcmp(const char *str, const char *prefix); 8 | 9 | #ifndef HAVE_STRLCPY 10 | extern size_t strlcat(char *dest, const char *src, size_t count); 11 | extern size_t strlcpy(char *dest, const char *src, size_t size); 12 | #endif 13 | 14 | /* some inline functions */ 15 | 16 | static inline const char *skip_prefix(const char *str, const char *prefix) 17 | { 18 | size_t len = strlen(prefix); 19 | return strncmp(str, prefix, len) ? NULL : str + len; 20 | } 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /include/kvm/symbol.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__SYMBOL_H 2 | #define KVM__SYMBOL_H 3 | 4 | #include 5 | #include 6 | 7 | struct kvm; 8 | 9 | #define SYMBOL_DEFAULT_UNKNOWN "" 10 | 11 | #ifdef CONFIG_HAS_BFD 12 | 13 | int symbol_init(struct kvm *kvm); 14 | int symbol_exit(struct kvm *kvm); 15 | char *symbol_lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size); 16 | 17 | #else 18 | 19 | static inline int symbol_init(struct kvm *kvm) { return 0; } 20 | static inline char *symbol_lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size) 21 | { 22 | char *s = strncpy(sym, SYMBOL_DEFAULT_UNKNOWN, size); 23 | sym[size - 1] = '\0'; 24 | return s; 25 | } 26 | static inline int symbol_exit(struct kvm *kvm) { return 0; } 27 | 28 | #endif 29 | 30 | #endif /* KVM__SYMBOL_H */ 31 | -------------------------------------------------------------------------------- /include/kvm/term.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__TERM_H 2 | #define KVM__TERM_H 3 | 4 | #include "kvm/kvm.h" 5 | 6 | #include 7 | #include 8 | 9 | #define CONSOLE_8250 1 10 | #define CONSOLE_VIRTIO 2 11 | #define CONSOLE_HV 3 12 | 13 | #define TERM_MAX_DEVS 4 14 | 15 | int term_putc_iov(struct iovec *iov, int iovcnt, int term); 16 | int term_getc_iov(struct kvm *kvm, struct iovec *iov, int iovcnt, int term); 17 | int term_putc(char *addr, int cnt, int term); 18 | int term_getc(struct kvm *kvm, int term); 19 | 20 | bool term_readable(int term); 21 | int tty_parser(const struct option *opt, const char *arg, int unset); 22 | 23 | #endif /* KVM__TERM_H */ 24 | -------------------------------------------------------------------------------- /include/kvm/threadpool.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__THREADPOOL_H 2 | #define KVM__THREADPOOL_H 3 | 4 | #include "kvm/mutex.h" 5 | 6 | #include 7 | 8 | struct kvm; 9 | 10 | typedef void (*kvm_thread_callback_fn_t)(struct kvm *kvm, void *data); 11 | 12 | struct thread_pool__job { 13 | kvm_thread_callback_fn_t callback; 14 | struct kvm *kvm; 15 | void *data; 16 | 17 | int signalcount; 18 | struct mutex mutex; 19 | 20 | struct list_head queue; 21 | }; 22 | 23 | static inline void thread_pool__init_job(struct thread_pool__job *job, struct kvm *kvm, kvm_thread_callback_fn_t callback, void *data) 24 | { 25 | *job = (struct thread_pool__job) { 26 | .kvm = kvm, 27 | .callback = callback, 28 | .data = data, 29 | .mutex = MUTEX_INITIALIZER, 30 | }; 31 | } 32 | 33 | int thread_pool__init(struct kvm *kvm); 34 | int thread_pool__exit(struct kvm *kvm); 35 | 36 | void thread_pool__do_job(struct thread_pool__job *job); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /include/kvm/util-init.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__UTIL_INIT_H 2 | #define KVM__UTIL_INIT_H 3 | 4 | struct kvm; 5 | 6 | struct init_item { 7 | struct hlist_node n; 8 | const char *fn_name; 9 | int (*init)(struct kvm *); 10 | }; 11 | 12 | int init_list__init(struct kvm *kvm); 13 | int init_list__exit(struct kvm *kvm); 14 | 15 | int init_list_add(struct init_item *t, int (*init)(struct kvm *), 16 | int priority, const char *name); 17 | int exit_list_add(struct init_item *t, int (*init)(struct kvm *), 18 | int priority, const char *name); 19 | 20 | #define __init_list_add(cb, l) \ 21 | static void __attribute__ ((constructor)) __init__##cb(void) \ 22 | { \ 23 | static char name[] = #cb; \ 24 | static struct init_item t; \ 25 | init_list_add(&t, cb, l, name); \ 26 | } 27 | 28 | #define __exit_list_add(cb, l) \ 29 | static void __attribute__ ((constructor)) __init__##cb(void) \ 30 | { \ 31 | static char name[] = #cb; \ 32 | static struct init_item t; \ 33 | exit_list_add(&t, cb, l, name); \ 34 | } 35 | 36 | #define core_init(cb) __init_list_add(cb, 0) 37 | #define base_init(cb) __init_list_add(cb, 2) 38 | #define dev_base_init(cb) __init_list_add(cb, 4) 39 | #define dev_init(cb) __init_list_add(cb, 5) 40 | #define virtio_dev_init(cb) __init_list_add(cb, 6) 41 | #define firmware_init(cb) __init_list_add(cb, 7) 42 | #define late_init(cb) __init_list_add(cb, 9) 43 | 44 | #define core_exit(cb) __exit_list_add(cb, 0) 45 | #define base_exit(cb) __exit_list_add(cb, 2) 46 | #define dev_base_exit(cb) __exit_list_add(cb, 4) 47 | #define dev_exit(cb) __exit_list_add(cb, 5) 48 | #define virtio_dev_exit(cb) __exit_list_add(cb, 6) 49 | #define firmware_exit(cb) __exit_list_add(cb, 7) 50 | #define late_exit(cb) __exit_list_add(cb, 9) 51 | #endif 52 | -------------------------------------------------------------------------------- /include/kvm/util.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef KVM__UTIL_H 4 | #define KVM__UTIL_H 5 | 6 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 7 | 8 | /* 9 | * Some bits are stolen from perf tool :) 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef __GNUC__ 27 | #define NORETURN __attribute__((__noreturn__)) 28 | #else 29 | #define NORETURN 30 | #ifndef __attribute__ 31 | #define __attribute__(x) 32 | #endif 33 | #endif 34 | 35 | extern bool do_debug_print; 36 | 37 | #define PROT_RW (PROT_READ|PROT_WRITE) 38 | #define MAP_ANON_NORESERVE (MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE) 39 | 40 | extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 41 | extern void die_perror(const char *s) NORETURN; 42 | extern int pr_err(const char *err, ...) __attribute__((format (printf, 1, 2))); 43 | extern void pr_warning(const char *err, ...) __attribute__((format (printf, 1, 2))); 44 | extern void pr_info(const char *err, ...) __attribute__((format (printf, 1, 2))); 45 | extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 46 | 47 | #define pr_debug(fmt, ...) \ 48 | do { \ 49 | if (do_debug_print) \ 50 | pr_info("(%s) %s:%d: " fmt, __FILE__, \ 51 | __func__, __LINE__, ##__VA_ARGS__); \ 52 | } while (0) 53 | 54 | 55 | #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) 56 | 57 | #ifndef BUG_ON_HANDLER 58 | # define BUG_ON_HANDLER(condition) \ 59 | do { \ 60 | if ((condition)) { \ 61 | pr_err("BUG at %s:%d", __FILE__, __LINE__); \ 62 | raise(SIGABRT); \ 63 | } \ 64 | } while (0) 65 | #endif 66 | 67 | #define BUG_ON(condition) BUG_ON_HANDLER((condition)) 68 | 69 | #define DIE_IF(cnd) \ 70 | do { \ 71 | if (cnd) \ 72 | die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \ 73 | __stringify(cnd) "\n"); \ 74 | } while (0) 75 | 76 | #define WARN_ON(condition) ({ \ 77 | int __ret_warn_on = !!(condition); \ 78 | if (__ret_warn_on) \ 79 | pr_warning("(%s) %s:%d: failed condition: %s", \ 80 | __FILE__, __func__, __LINE__, \ 81 | __stringify(condition)); \ 82 | __ret_warn_on; \ 83 | }) 84 | 85 | #define MSECS_TO_USECS(s) ((s) * 1000) 86 | 87 | /* Millisecond sleep */ 88 | static inline void msleep(unsigned int msecs) 89 | { 90 | usleep(MSECS_TO_USECS(msecs)); 91 | } 92 | 93 | struct kvm; 94 | void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size); 95 | void *mmap_anon_or_hugetlbfs(struct kvm *kvm, const char *hugetlbfs_path, u64 size); 96 | 97 | #endif /* KVM__UTIL_H */ 98 | -------------------------------------------------------------------------------- /include/kvm/vesa.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__VESA_H 2 | #define KVM__VESA_H 3 | 4 | #define VESA_WIDTH 640 5 | #define VESA_HEIGHT 480 6 | 7 | #define VESA_MEM_ADDR 0xd0000000 8 | #define VESA_MEM_SIZE (4*VESA_WIDTH*VESA_HEIGHT) 9 | #define VESA_BPP 32 10 | 11 | struct kvm; 12 | struct biosregs; 13 | 14 | struct framebuffer *vesa__init(struct kvm *self); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/kvm/virtio-9p.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__VIRTIO_9P_H 2 | #define KVM__VIRTIO_9P_H 3 | #include "kvm/virtio.h" 4 | #include "kvm/pci.h" 5 | #include "kvm/threadpool.h" 6 | #include "kvm/parse-options.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define NUM_VIRT_QUEUES 1 14 | #define VIRTQUEUE_NUM 128 15 | #define VIRTIO_9P_DEFAULT_TAG "kvm_9p" 16 | #define VIRTIO_9P_HDR_LEN (sizeof(u32)+sizeof(u8)+sizeof(u16)) 17 | #define VIRTIO_9P_VERSION_DOTL "9P2000.L" 18 | #define MAX_TAG_LEN 32 19 | 20 | struct p9_msg { 21 | u32 size; 22 | u8 cmd; 23 | u16 tag; 24 | u8 msg[0]; 25 | } __attribute__((packed)); 26 | 27 | struct p9_fid { 28 | u32 fid; 29 | u32 uid; 30 | char abs_path[PATH_MAX]; 31 | char *path; 32 | DIR *dir; 33 | int fd; 34 | struct rb_node node; 35 | }; 36 | 37 | struct p9_dev_job { 38 | struct virt_queue *vq; 39 | struct p9_dev *p9dev; 40 | struct thread_pool__job job_id; 41 | }; 42 | 43 | struct p9_dev { 44 | struct list_head list; 45 | struct virtio_device vdev; 46 | struct rb_root fids; 47 | 48 | struct virtio_9p_config *config; 49 | u32 features; 50 | 51 | /* virtio queue */ 52 | struct virt_queue vqs[NUM_VIRT_QUEUES]; 53 | struct p9_dev_job jobs[NUM_VIRT_QUEUES]; 54 | char root_dir[PATH_MAX]; 55 | }; 56 | 57 | struct p9_pdu { 58 | u32 queue_head; 59 | size_t read_offset; 60 | size_t write_offset; 61 | u16 out_iov_cnt; 62 | u16 in_iov_cnt; 63 | struct iovec in_iov[VIRTQUEUE_NUM]; 64 | struct iovec out_iov[VIRTQUEUE_NUM]; 65 | }; 66 | 67 | struct kvm; 68 | 69 | int virtio_9p_rootdir_parser(const struct option *opt, const char *arg, int unset); 70 | int virtio_9p_img_name_parser(const struct option *opt, const char *arg, int unset); 71 | int virtio_9p__register(struct kvm *kvm, const char *root, const char *tag_name); 72 | int virtio_9p__init(struct kvm *kvm); 73 | int virtio_p9_pdu_readf(struct p9_pdu *pdu, const char *fmt, ...); 74 | int virtio_p9_pdu_writef(struct p9_pdu *pdu, const char *fmt, ...); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /include/kvm/virtio-balloon.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__BLN_VIRTIO_H 2 | #define KVM__BLN_VIRTIO_H 3 | 4 | struct kvm; 5 | 6 | int virtio_bln__init(struct kvm *kvm); 7 | int virtio_bln__exit(struct kvm *kvm); 8 | 9 | #endif /* KVM__BLN_VIRTIO_H */ 10 | -------------------------------------------------------------------------------- /include/kvm/virtio-blk.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__BLK_VIRTIO_H 2 | #define KVM__BLK_VIRTIO_H 3 | 4 | #include "kvm/disk-image.h" 5 | 6 | struct kvm; 7 | 8 | int virtio_blk__init(struct kvm *kvm); 9 | int virtio_blk__exit(struct kvm *kvm); 10 | void virtio_blk_complete(void *param, long len); 11 | 12 | #endif /* KVM__BLK_VIRTIO_H */ 13 | -------------------------------------------------------------------------------- /include/kvm/virtio-console.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__CONSOLE_VIRTIO_H 2 | #define KVM__CONSOLE_VIRTIO_H 3 | 4 | struct kvm; 5 | 6 | int virtio_console__init(struct kvm *kvm); 7 | void virtio_console__inject_interrupt(struct kvm *kvm); 8 | int virtio_console__exit(struct kvm *kvm); 9 | 10 | #endif /* KVM__CONSOLE_VIRTIO_H */ 11 | -------------------------------------------------------------------------------- /include/kvm/virtio-mmio.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__VIRTIO_MMIO_H 2 | #define KVM__VIRTIO_MMIO_H 3 | 4 | #include 5 | #include 6 | 7 | #define VIRTIO_MMIO_MAX_VQ 32 8 | #define VIRTIO_MMIO_MAX_CONFIG 1 9 | #define VIRTIO_MMIO_IO_SIZE 0x200 10 | 11 | struct kvm; 12 | 13 | struct virtio_mmio_ioevent_param { 14 | struct virtio_device *vdev; 15 | u32 vq; 16 | }; 17 | 18 | struct virtio_mmio_hdr { 19 | char magic[4]; 20 | u32 version; 21 | u32 device_id; 22 | u32 vendor_id; 23 | u32 host_features; 24 | u32 host_features_sel; 25 | u32 reserved_1[2]; 26 | u32 guest_features; 27 | u32 guest_features_sel; 28 | u32 guest_page_size; 29 | u32 reserved_2; 30 | u32 queue_sel; 31 | u32 queue_num_max; 32 | u32 queue_num; 33 | u32 queue_align; 34 | u32 queue_pfn; 35 | u32 reserved_3[3]; 36 | u32 queue_notify; 37 | u32 reserved_4[3]; 38 | u32 interrupt_state; 39 | u32 interrupt_ack; 40 | u32 reserved_5[2]; 41 | u32 status; 42 | } __attribute__((packed)); 43 | 44 | struct virtio_mmio { 45 | u32 addr; 46 | void *dev; 47 | struct kvm *kvm; 48 | u8 irq; 49 | struct virtio_mmio_hdr hdr; 50 | struct device_header dev_hdr; 51 | struct virtio_mmio_ioevent_param ioeventfds[VIRTIO_MMIO_MAX_VQ]; 52 | }; 53 | 54 | int virtio_mmio_signal_vq(struct kvm *kvm, struct virtio_device *vdev, u32 vq); 55 | int virtio_mmio_signal_config(struct kvm *kvm, struct virtio_device *vdev); 56 | int virtio_mmio_exit(struct kvm *kvm, struct virtio_device *vdev); 57 | int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev, 58 | int device_id, int subsys_id, int class); 59 | void virtio_mmio_assign_irq(struct device_header *dev_hdr); 60 | #endif 61 | -------------------------------------------------------------------------------- /include/kvm/virtio-net.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__VIRTIO_NET_H 2 | #define KVM__VIRTIO_NET_H 3 | 4 | #include "kvm/parse-options.h" 5 | 6 | struct kvm; 7 | 8 | struct virtio_net_params { 9 | const char *guest_ip; 10 | const char *host_ip; 11 | const char *script; 12 | const char *downscript; 13 | const char *trans; 14 | const char *tapif; 15 | char guest_mac[6]; 16 | char host_mac[6]; 17 | struct kvm *kvm; 18 | int mode; 19 | int vhost; 20 | int fd; 21 | int mq; 22 | }; 23 | 24 | int virtio_net__init(struct kvm *kvm); 25 | int virtio_net__exit(struct kvm *kvm); 26 | int netdev_parser(const struct option *opt, const char *arg, int unset); 27 | 28 | enum { 29 | NET_MODE_USER, 30 | NET_MODE_TAP 31 | }; 32 | 33 | #endif /* KVM__VIRTIO_NET_H */ 34 | -------------------------------------------------------------------------------- /include/kvm/virtio-pci-dev.h: -------------------------------------------------------------------------------- 1 | #ifndef VIRTIO_PCI_DEV_H_ 2 | #define VIRTIO_PCI_DEV_H_ 3 | 4 | #include 5 | 6 | /* 7 | * Virtio PCI device constants and resources 8 | * they do use (such as irqs and pins). 9 | */ 10 | 11 | #define PCI_DEVICE_ID_VIRTIO_NET 0x1000 12 | #define PCI_DEVICE_ID_VIRTIO_BLK 0x1001 13 | #define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003 14 | #define PCI_DEVICE_ID_VIRTIO_RNG 0x1004 15 | #define PCI_DEVICE_ID_VIRTIO_BLN 0x1005 16 | #define PCI_DEVICE_ID_VIRTIO_SCSI 0x1008 17 | #define PCI_DEVICE_ID_VIRTIO_9P 0x1009 18 | #define PCI_DEVICE_ID_VESA 0x2000 19 | #define PCI_DEVICE_ID_PCI_SHMEM 0x0001 20 | 21 | #define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4 22 | #define PCI_VENDOR_ID_PCI_SHMEM 0x0001 23 | #define PCI_SUBSYSTEM_VENDOR_ID_REDHAT_QUMRANET 0x1af4 24 | 25 | #define PCI_SUBSYSTEM_ID_VESA 0x0004 26 | #define PCI_SUBSYSTEM_ID_PCI_SHMEM 0x0001 27 | 28 | #define PCI_CLASS_BLK 0x018000 29 | #define PCI_CLASS_NET 0x020000 30 | #define PCI_CLASS_CONSOLE 0x078000 31 | /* 32 | * 0xFF Device does not fit in any defined classes 33 | */ 34 | #define PCI_CLASS_RNG 0xff0000 35 | #define PCI_CLASS_BLN 0xff0000 36 | #define PCI_CLASS_9P 0xff0000 37 | 38 | #endif /* VIRTIO_PCI_DEV_H_ */ 39 | -------------------------------------------------------------------------------- /include/kvm/virtio-pci.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__VIRTIO_PCI_H 2 | #define KVM__VIRTIO_PCI_H 3 | 4 | #include "kvm/devices.h" 5 | #include "kvm/pci.h" 6 | 7 | #include 8 | 9 | #define VIRTIO_PCI_MAX_VQ 32 10 | #define VIRTIO_PCI_MAX_CONFIG 1 11 | 12 | struct kvm; 13 | 14 | struct virtio_pci_ioevent_param { 15 | struct virtio_device *vdev; 16 | u32 vq; 17 | }; 18 | 19 | #define VIRTIO_PCI_F_SIGNAL_MSI (1 << 0) 20 | 21 | struct virtio_pci { 22 | struct pci_device_header pci_hdr; 23 | struct device_header dev_hdr; 24 | void *dev; 25 | struct kvm *kvm; 26 | 27 | u16 port_addr; 28 | u32 mmio_addr; 29 | u8 status; 30 | u8 isr; 31 | u32 features; 32 | 33 | /* 34 | * We cannot rely on the INTERRUPT_LINE byte in the config space once 35 | * we have run guest code, as the OS is allowed to use that field 36 | * as a scratch pad to communicate between driver and PCI layer. 37 | * So store our legacy interrupt line number in here for internal use. 38 | */ 39 | u8 legacy_irq_line; 40 | 41 | /* MSI-X */ 42 | u16 config_vector; 43 | u32 config_gsi; 44 | u32 vq_vector[VIRTIO_PCI_MAX_VQ]; 45 | u32 gsis[VIRTIO_PCI_MAX_VQ]; 46 | u32 msix_io_block; 47 | u64 msix_pba; 48 | struct msix_table msix_table[VIRTIO_PCI_MAX_VQ + VIRTIO_PCI_MAX_CONFIG]; 49 | 50 | /* virtio queue */ 51 | u16 queue_selector; 52 | struct virtio_pci_ioevent_param ioeventfds[VIRTIO_PCI_MAX_VQ]; 53 | }; 54 | 55 | int virtio_pci__signal_vq(struct kvm *kvm, struct virtio_device *vdev, u32 vq); 56 | int virtio_pci__signal_config(struct kvm *kvm, struct virtio_device *vdev); 57 | int virtio_pci__exit(struct kvm *kvm, struct virtio_device *vdev); 58 | int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev, 59 | int device_id, int subsys_id, int class); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /include/kvm/virtio-rng.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__RNG_VIRTIO_H 2 | #define KVM__RNG_VIRTIO_H 3 | 4 | struct kvm; 5 | 6 | int virtio_rng__init(struct kvm *kvm); 7 | int virtio_rng__exit(struct kvm *kvm); 8 | 9 | #endif /* KVM__RNG_VIRTIO_H */ 10 | -------------------------------------------------------------------------------- /include/kvm/virtio-scsi.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__SCSI_VIRTIO_H 2 | #define KVM__SCSI_VIRTIO_H 3 | 4 | #include "kvm/disk-image.h" 5 | 6 | struct kvm; 7 | 8 | int virtio_scsi_init(struct kvm *kvm); 9 | int virtio_scsi_exit(struct kvm *kvm); 10 | 11 | #endif /* KVM__SCSI_VIRTIO_H */ 12 | -------------------------------------------------------------------------------- /include/kvm/vnc.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__VNC_H 2 | #define KVM__VNC_H 3 | 4 | #include "kvm/kvm.h" 5 | 6 | struct framebuffer; 7 | 8 | #ifdef CONFIG_HAS_VNCSERVER 9 | int vnc__init(struct kvm *kvm); 10 | int vnc__exit(struct kvm *kvm); 11 | #else 12 | static inline int vnc__init(struct kvm *kvm) 13 | { 14 | return 0; 15 | } 16 | static inline int vnc__exit(struct kvm *kvm) 17 | { 18 | return 0; 19 | } 20 | #endif 21 | 22 | #endif /* KVM__VNC_H */ 23 | -------------------------------------------------------------------------------- /include/linux/bitops.h: -------------------------------------------------------------------------------- 1 | #ifndef _KVM_LINUX_BITOPS_H_ 2 | #define _KVM_LINUX_BITOPS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define BITS_PER_LONG __WORDSIZE 9 | #define BITS_PER_BYTE 8 10 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) 11 | 12 | static inline void set_bit(int nr, unsigned long *addr) 13 | { 14 | addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG); 15 | } 16 | 17 | static inline void clear_bit(int nr, unsigned long *addr) 18 | { 19 | addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG)); 20 | } 21 | 22 | static __always_inline int test_bit(unsigned int nr, const unsigned long *addr) 23 | { 24 | return ((1UL << (nr % BITS_PER_LONG)) & 25 | (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; 26 | } 27 | 28 | static inline unsigned long hweight_long(unsigned long w) 29 | { 30 | return sizeof(w) == 4 ? hweight32(w) : hweight64(w); 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /include/linux/byteorder.h: -------------------------------------------------------------------------------- 1 | #ifndef __BYTE_ORDER_H__ 2 | #define __BYTE_ORDER_H__ 3 | 4 | #include 5 | 6 | /* taken from include/linux/byteorder/generic.h */ 7 | #define cpu_to_le64 __cpu_to_le64 8 | #define le64_to_cpu __le64_to_cpu 9 | #define cpu_to_le32 __cpu_to_le32 10 | #define le32_to_cpu __le32_to_cpu 11 | #define cpu_to_le16 __cpu_to_le16 12 | #define le16_to_cpu __le16_to_cpu 13 | #define cpu_to_be64 __cpu_to_be64 14 | #define be64_to_cpu __be64_to_cpu 15 | #define cpu_to_be32 __cpu_to_be32 16 | #define be32_to_cpu __be32_to_cpu 17 | #define cpu_to_be16 __cpu_to_be16 18 | #define be16_to_cpu __be16_to_cpu 19 | 20 | /* change in situ versions */ 21 | #define cpu_to_le64s __cpu_to_le64s 22 | #define le64_to_cpus __le64_to_cpus 23 | #define cpu_to_le32s __cpu_to_le32s 24 | #define le32_to_cpus __le32_to_cpus 25 | #define cpu_to_le16s __cpu_to_le16s 26 | #define le16_to_cpus __le16_to_cpus 27 | #define cpu_to_be64s __cpu_to_be64s 28 | #define be64_to_cpus __be64_to_cpus 29 | #define cpu_to_be32s __cpu_to_be32s 30 | #define be32_to_cpus __be32_to_cpus 31 | #define cpu_to_be16s __cpu_to_be16s 32 | #define be16_to_cpus __be16_to_cpus 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /include/linux/compiler.h: -------------------------------------------------------------------------------- 1 | #ifndef _PERF_LINUX_COMPILER_H_ 2 | #define _PERF_LINUX_COMPILER_H_ 3 | 4 | #ifndef __always_inline 5 | #define __always_inline inline 6 | #endif 7 | #define __user 8 | 9 | #ifndef __attribute_const__ 10 | #define __attribute_const__ 11 | #endif 12 | 13 | #define __used __attribute__((__unused__)) 14 | #define __packed __attribute__((packed)) 15 | #define __iomem 16 | #define __force 17 | #define __must_check 18 | #define unlikely 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /include/linux/err.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_ERR_H 2 | #define _LINUX_ERR_H 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | /* 10 | * Kernel pointers have redundant information, so we can use a 11 | * scheme where we can return either an error code or a normal 12 | * pointer with the same return value. 13 | * 14 | * This should be a per-architecture thing, to allow different 15 | * error and pointer decisions. 16 | */ 17 | #define MAX_ERRNO 4095 18 | 19 | #ifndef __ASSEMBLY__ 20 | 21 | #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) 22 | 23 | static inline void * __must_check ERR_PTR(long error) 24 | { 25 | return (void *) error; 26 | } 27 | 28 | static inline long __must_check PTR_ERR(__force const void *ptr) 29 | { 30 | return (long) ptr; 31 | } 32 | 33 | static inline bool __must_check IS_ERR(__force const void *ptr) 34 | { 35 | return IS_ERR_VALUE((unsigned long)ptr); 36 | } 37 | 38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr) 39 | { 40 | return !ptr || IS_ERR_VALUE((unsigned long)ptr); 41 | } 42 | 43 | /** 44 | * ERR_CAST - Explicitly cast an error-valued pointer to another pointer type 45 | * @ptr: The pointer to cast. 46 | * 47 | * Explicitly cast an error-valued pointer to another pointer type in such a 48 | * way as to make it clear that's what's going on. 49 | */ 50 | static inline void * __must_check ERR_CAST(__force const void *ptr) 51 | { 52 | /* cast away the const */ 53 | return (void *) ptr; 54 | } 55 | 56 | static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) 57 | { 58 | if (IS_ERR(ptr)) 59 | return PTR_ERR(ptr); 60 | else 61 | return 0; 62 | } 63 | 64 | /* Deprecated */ 65 | #define PTR_RET(p) PTR_ERR_OR_ZERO(p) 66 | 67 | #endif 68 | 69 | #endif /* _LINUX_ERR_H */ 70 | -------------------------------------------------------------------------------- /include/linux/kernel.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef KVM__LINUX_KERNEL_H_ 3 | #define KVM__LINUX_KERNEL_H_ 4 | 5 | #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) 6 | 7 | #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) 8 | #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 9 | 10 | #ifndef offsetof 11 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 12 | #endif 13 | 14 | #ifndef container_of 15 | /** 16 | * container_of - cast a member of a structure out to the containing structure 17 | * @ptr: the pointer to the member. 18 | * @type: the type of the container struct this is embedded in. 19 | * @member: the name of the member within the struct. 20 | * 21 | */ 22 | #define container_of(ptr, type, member) ({ \ 23 | const typeof(((type *)0)->member) * __mptr = (ptr); \ 24 | (type *)((char *)__mptr - offsetof(type, member)); }) 25 | #endif 26 | 27 | #define min(x, y) ({ \ 28 | typeof(x) _min1 = (x); \ 29 | typeof(y) _min2 = (y); \ 30 | (void) (&_min1 == &_min2); \ 31 | _min1 < _min2 ? _min1 : _min2; }) 32 | 33 | #define max(x, y) ({ \ 34 | typeof(x) _max1 = (x); \ 35 | typeof(y) _max2 = (y); \ 36 | (void) (&_max1 == &_max2); \ 37 | _max1 > _max2 ? _max1 : _max2; }) 38 | 39 | #define min_t(type, x, y) ({ \ 40 | type __min1 = (x); \ 41 | type __min2 = (y); \ 42 | __min1 < __min2 ? __min1: __min2; }) 43 | 44 | #define max_t(type, x, y) ({ \ 45 | type __max1 = (x); \ 46 | type __max2 = (y); \ 47 | __max1 > __max2 ? __max1: __max2; }) 48 | 49 | #define true 1 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /include/linux/prefetch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__LINUX_PREFETCH_H 2 | #define KVM__LINUX_PREFETCH_H 3 | 4 | static inline void prefetch(void *a __attribute__((unused))) { } 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /include/linux/psci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ARM Power State and Coordination Interface (PSCI) header 3 | * 4 | * This header holds common PSCI defines and macros shared 5 | * by: ARM kernel, ARM64 kernel, KVM ARM/ARM64 and user space. 6 | * 7 | * Copyright (C) 2014 Linaro Ltd. 8 | * Author: Anup Patel 9 | */ 10 | 11 | #ifndef _UAPI_LINUX_PSCI_H 12 | #define _UAPI_LINUX_PSCI_H 13 | 14 | /* 15 | * PSCI v0.1 interface 16 | * 17 | * The PSCI v0.1 function numbers are implementation defined. 18 | * 19 | * Only PSCI return values such as: SUCCESS, NOT_SUPPORTED, 20 | * INVALID_PARAMS, and DENIED defined below are applicable 21 | * to PSCI v0.1. 22 | */ 23 | 24 | /* PSCI v0.2 interface */ 25 | #define PSCI_0_2_FN_BASE 0x84000000 26 | #define PSCI_0_2_FN(n) (PSCI_0_2_FN_BASE + (n)) 27 | #define PSCI_0_2_64BIT 0x40000000 28 | #define PSCI_0_2_FN64_BASE \ 29 | (PSCI_0_2_FN_BASE + PSCI_0_2_64BIT) 30 | #define PSCI_0_2_FN64(n) (PSCI_0_2_FN64_BASE + (n)) 31 | 32 | #define PSCI_0_2_FN_PSCI_VERSION PSCI_0_2_FN(0) 33 | #define PSCI_0_2_FN_CPU_SUSPEND PSCI_0_2_FN(1) 34 | #define PSCI_0_2_FN_CPU_OFF PSCI_0_2_FN(2) 35 | #define PSCI_0_2_FN_CPU_ON PSCI_0_2_FN(3) 36 | #define PSCI_0_2_FN_AFFINITY_INFO PSCI_0_2_FN(4) 37 | #define PSCI_0_2_FN_MIGRATE PSCI_0_2_FN(5) 38 | #define PSCI_0_2_FN_MIGRATE_INFO_TYPE PSCI_0_2_FN(6) 39 | #define PSCI_0_2_FN_MIGRATE_INFO_UP_CPU PSCI_0_2_FN(7) 40 | #define PSCI_0_2_FN_SYSTEM_OFF PSCI_0_2_FN(8) 41 | #define PSCI_0_2_FN_SYSTEM_RESET PSCI_0_2_FN(9) 42 | 43 | #define PSCI_0_2_FN64_CPU_SUSPEND PSCI_0_2_FN64(1) 44 | #define PSCI_0_2_FN64_CPU_ON PSCI_0_2_FN64(3) 45 | #define PSCI_0_2_FN64_AFFINITY_INFO PSCI_0_2_FN64(4) 46 | #define PSCI_0_2_FN64_MIGRATE PSCI_0_2_FN64(5) 47 | #define PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU PSCI_0_2_FN64(7) 48 | 49 | /* PSCI v0.2 power state encoding for CPU_SUSPEND function */ 50 | #define PSCI_0_2_POWER_STATE_ID_MASK 0xffff 51 | #define PSCI_0_2_POWER_STATE_ID_SHIFT 0 52 | #define PSCI_0_2_POWER_STATE_TYPE_SHIFT 16 53 | #define PSCI_0_2_POWER_STATE_TYPE_MASK \ 54 | (0x1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT) 55 | #define PSCI_0_2_POWER_STATE_AFFL_SHIFT 24 56 | #define PSCI_0_2_POWER_STATE_AFFL_MASK \ 57 | (0x3 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) 58 | 59 | /* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ 60 | #define PSCI_0_2_AFFINITY_LEVEL_ON 0 61 | #define PSCI_0_2_AFFINITY_LEVEL_OFF 1 62 | #define PSCI_0_2_AFFINITY_LEVEL_ON_PENDING 2 63 | 64 | /* PSCI v0.2 multicore support in Trusted OS returned by MIGRATE_INFO_TYPE */ 65 | #define PSCI_0_2_TOS_UP_MIGRATE 0 66 | #define PSCI_0_2_TOS_UP_NO_MIGRATE 1 67 | #define PSCI_0_2_TOS_MP 2 68 | 69 | /* PSCI version decoding (independent of PSCI version) */ 70 | #define PSCI_VERSION_MAJOR_SHIFT 16 71 | #define PSCI_VERSION_MINOR_MASK \ 72 | ((1U << PSCI_VERSION_MAJOR_SHIFT) - 1) 73 | #define PSCI_VERSION_MAJOR_MASK ~PSCI_VERSION_MINOR_MASK 74 | #define PSCI_VERSION_MAJOR(ver) \ 75 | (((ver) & PSCI_VERSION_MAJOR_MASK) >> PSCI_VERSION_MAJOR_SHIFT) 76 | #define PSCI_VERSION_MINOR(ver) \ 77 | ((ver) & PSCI_VERSION_MINOR_MASK) 78 | 79 | /* PSCI return values (inclusive of all PSCI versions) */ 80 | #define PSCI_RET_SUCCESS 0 81 | #define PSCI_RET_NOT_SUPPORTED -1 82 | #define PSCI_RET_INVALID_PARAMS -2 83 | #define PSCI_RET_DENIED -3 84 | #define PSCI_RET_ALREADY_ON -4 85 | #define PSCI_RET_ON_PENDING -5 86 | #define PSCI_RET_INTERNAL_FAILURE -6 87 | #define PSCI_RET_NOT_PRESENT -7 88 | #define PSCI_RET_DISABLED -8 89 | 90 | #endif /* _UAPI_LINUX_PSCI_H */ 91 | -------------------------------------------------------------------------------- /include/linux/sizes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * include/linux/sizes.h 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License version 2 as 6 | * published by the Free Software Foundation. 7 | */ 8 | #ifndef __LINUX_SIZES_H__ 9 | #define __LINUX_SIZES_H__ 10 | 11 | #define SZ_1 0x00000001 12 | #define SZ_2 0x00000002 13 | #define SZ_4 0x00000004 14 | #define SZ_8 0x00000008 15 | #define SZ_16 0x00000010 16 | #define SZ_32 0x00000020 17 | #define SZ_64 0x00000040 18 | #define SZ_128 0x00000080 19 | #define SZ_256 0x00000100 20 | #define SZ_512 0x00000200 21 | 22 | #define SZ_1K 0x00000400 23 | #define SZ_2K 0x00000800 24 | #define SZ_4K 0x00001000 25 | #define SZ_8K 0x00002000 26 | #define SZ_16K 0x00004000 27 | #define SZ_32K 0x00008000 28 | #define SZ_64K 0x00010000 29 | #define SZ_128K 0x00020000 30 | #define SZ_256K 0x00040000 31 | #define SZ_512K 0x00080000 32 | 33 | #define SZ_1M 0x00100000 34 | #define SZ_2M 0x00200000 35 | #define SZ_4M 0x00400000 36 | #define SZ_8M 0x00800000 37 | #define SZ_16M 0x01000000 38 | #define SZ_32M 0x02000000 39 | #define SZ_64M 0x04000000 40 | #define SZ_128M 0x08000000 41 | #define SZ_256M 0x10000000 42 | #define SZ_512M 0x20000000 43 | 44 | #define SZ_1G 0x40000000 45 | #define SZ_2G 0x80000000 46 | 47 | #endif /* __LINUX_SIZES_H__ */ 48 | -------------------------------------------------------------------------------- /include/linux/stddef.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_STDDEF_H 2 | #define _LINUX_STDDEF_H 3 | 4 | #undef NULL 5 | #define NULL ((void *)0) 6 | 7 | #undef offsetof 8 | #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /include/linux/stringify.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINUX_STRINGIFY_H 2 | #define __LINUX_STRINGIFY_H 3 | 4 | /* Indirect stringification. Doing two levels allows the parameter to be a 5 | * macro itself. For example, compile with -DFOO=bar, __stringify(FOO) 6 | * converts to "bar". 7 | */ 8 | 9 | #define __stringify_1(x...) #x 10 | #define __stringify(x...) __stringify_1(x) 11 | 12 | #endif /* !__LINUX_STRINGIFY_H */ 13 | -------------------------------------------------------------------------------- /include/linux/types.h: -------------------------------------------------------------------------------- 1 | #ifndef LINUX_TYPES_H 2 | #define LINUX_TYPES_H 3 | 4 | #include 5 | #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */ 6 | #include 7 | 8 | typedef __u64 u64; 9 | typedef __s64 s64; 10 | 11 | typedef __u32 u32; 12 | typedef __s32 s32; 13 | 14 | typedef __u16 u16; 15 | typedef __s16 s16; 16 | 17 | typedef __u8 u8; 18 | typedef __s8 s8; 19 | 20 | #ifdef __CHECKER__ 21 | #define __bitwise__ __attribute__((bitwise)) 22 | #else 23 | #define __bitwise__ 24 | #endif 25 | #ifdef __CHECK_ENDIAN__ 26 | #define __bitwise __bitwise__ 27 | #else 28 | #define __bitwise 29 | #endif 30 | 31 | 32 | typedef __u16 __bitwise __le16; 33 | typedef __u16 __bitwise __be16; 34 | typedef __u32 __bitwise __le32; 35 | typedef __u32 __bitwise __be32; 36 | typedef __u64 __bitwise __le64; 37 | typedef __u64 __bitwise __be64; 38 | 39 | struct list_head { 40 | struct list_head *next, *prev; 41 | }; 42 | 43 | struct hlist_head { 44 | struct hlist_node *first; 45 | }; 46 | 47 | struct hlist_node { 48 | struct hlist_node *next, **pprev; 49 | }; 50 | 51 | #endif /* LINUX_TYPES_H */ 52 | -------------------------------------------------------------------------------- /include/linux/virtio_ids.h: -------------------------------------------------------------------------------- 1 | #ifndef _LINUX_VIRTIO_IDS_H 2 | #define _LINUX_VIRTIO_IDS_H 3 | /* 4 | * Virtio IDs 5 | * 6 | * This header is BSD licensed so anyone can use the definitions to implement 7 | * compatible drivers/servers. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions 11 | * are met: 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * 3. Neither the name of IBM nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE 24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 | * SUCH DAMAGE. */ 31 | 32 | #define VIRTIO_ID_NET 1 /* virtio net */ 33 | #define VIRTIO_ID_BLOCK 2 /* virtio block */ 34 | #define VIRTIO_ID_CONSOLE 3 /* virtio console */ 35 | #define VIRTIO_ID_RNG 4 /* virtio rng */ 36 | #define VIRTIO_ID_BALLOON 5 /* virtio balloon */ 37 | #define VIRTIO_ID_RPMSG 7 /* virtio remote processor messaging */ 38 | #define VIRTIO_ID_SCSI 8 /* virtio scsi */ 39 | #define VIRTIO_ID_9P 9 /* 9p virtio console */ 40 | #define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */ 41 | #define VIRTIO_ID_CAIF 12 /* Virtio caif */ 42 | #define VIRTIO_ID_INPUT 18 /* virtio input */ 43 | 44 | #endif /* _LINUX_VIRTIO_IDS_H */ 45 | -------------------------------------------------------------------------------- /irq.c: -------------------------------------------------------------------------------- 1 | #include "kvm/irq.h" 2 | #include "kvm/kvm-arch.h" 3 | 4 | static u8 next_line = KVM_IRQ_OFFSET; 5 | 6 | int irq__alloc_line(void) 7 | { 8 | return next_line++; 9 | } 10 | 11 | int irq__get_nr_allocated_lines(void) 12 | { 13 | return next_line - KVM_IRQ_OFFSET; 14 | } 15 | -------------------------------------------------------------------------------- /kvm-cmd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* user defined header files */ 6 | #include "kvm/builtin-debug.h" 7 | #include "kvm/builtin-pause.h" 8 | #include "kvm/builtin-resume.h" 9 | #include "kvm/builtin-balloon.h" 10 | #include "kvm/builtin-list.h" 11 | #include "kvm/builtin-version.h" 12 | #include "kvm/builtin-setup.h" 13 | #include "kvm/builtin-stop.h" 14 | #include "kvm/builtin-stat.h" 15 | #include "kvm/builtin-help.h" 16 | #include "kvm/builtin-sandbox.h" 17 | #include "kvm/kvm-cmd.h" 18 | #include "kvm/builtin-run.h" 19 | #include "kvm/util.h" 20 | 21 | struct cmd_struct kvm_commands[] = { 22 | { "pause", kvm_cmd_pause, kvm_pause_help, 0 }, 23 | { "resume", kvm_cmd_resume, kvm_resume_help, 0 }, 24 | { "debug", kvm_cmd_debug, kvm_debug_help, 0 }, 25 | { "balloon", kvm_cmd_balloon, kvm_balloon_help, 0 }, 26 | { "list", kvm_cmd_list, kvm_list_help, 0 }, 27 | { "version", kvm_cmd_version, NULL, 0 }, 28 | { "--version", kvm_cmd_version, NULL, 0 }, 29 | { "stop", kvm_cmd_stop, kvm_stop_help, 0 }, 30 | { "stat", kvm_cmd_stat, kvm_stat_help, 0 }, 31 | { "help", kvm_cmd_help, NULL, 0 }, 32 | { "setup", kvm_cmd_setup, kvm_setup_help, 0 }, 33 | { "run", kvm_cmd_run, kvm_run_help, 0 }, 34 | { "sandbox", kvm_cmd_sandbox, kvm_run_help, 0 }, 35 | { NULL, NULL, NULL, 0 }, 36 | }; 37 | 38 | /* 39 | * kvm_get_command: Searches the command in an array of the commands and 40 | * returns a pointer to cmd_struct if a match is found. 41 | * 42 | * Input parameters: 43 | * command: Array of possible commands. The last entry in the array must be 44 | * NULL. 45 | * cmd: A string command to search in the array 46 | * 47 | * Return Value: 48 | * NULL: If the cmd is not matched with any of the command in the command array 49 | * p: Pointer to cmd_struct of the matching command 50 | */ 51 | struct cmd_struct *kvm_get_command(struct cmd_struct *command, 52 | const char *cmd) 53 | { 54 | struct cmd_struct *p = command; 55 | 56 | while (p->cmd) { 57 | if (!strcmp(p->cmd, cmd)) 58 | return p; 59 | p++; 60 | } 61 | return NULL; 62 | } 63 | 64 | int handle_command(struct cmd_struct *command, int argc, const char **argv) 65 | { 66 | struct cmd_struct *p; 67 | const char *prefix = NULL; 68 | int ret = 0; 69 | 70 | if (!argv || !*argv) { 71 | p = kvm_get_command(command, "help"); 72 | BUG_ON(!p); 73 | return p->fn(argc, argv, prefix); 74 | } 75 | 76 | p = kvm_get_command(command, argv[0]); 77 | if (!p) { 78 | p = kvm_get_command(command, "help"); 79 | BUG_ON(!p); 80 | p->fn(0, NULL, prefix); 81 | return EINVAL; 82 | } 83 | 84 | ret = p->fn(argc - 1, &argv[1], prefix); 85 | if (ret < 0) { 86 | if (errno == EPERM) 87 | die("Permission error - are you root?"); 88 | } 89 | 90 | return ret; 91 | } 92 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include "kvm/kvm.h" 2 | 3 | #include 4 | #include 5 | 6 | /* user defined header files */ 7 | #include 8 | 9 | static int handle_kvm_command(int argc, char **argv) 10 | { 11 | return handle_command(kvm_commands, argc, (const char **) &argv[0]); 12 | } 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | kvm__set_dir("%s/%s", HOME_DIR, KVM_PID_FILE_PATH); 17 | 18 | return handle_kvm_command(argc - 1, &argv[1]); 19 | } 20 | -------------------------------------------------------------------------------- /mips/include/kvm/barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef _KVM_BARRIER_H_ 2 | #define _KVM_BARRIER_H_ 3 | 4 | #define barrier() asm volatile("": : :"memory") 5 | 6 | #define mb() asm volatile (".set push\n\t.set mips2\n\tsync\n\t.set pop": : :"memory") 7 | #define rmb() mb() 8 | #define wmb() mb() 9 | 10 | #ifdef CONFIG_SMP 11 | #define smp_mb() mb() 12 | #define smp_rmb() rmb() 13 | #define smp_wmb() wmb() 14 | #else 15 | #define smp_mb() barrier() 16 | #define smp_rmb() barrier() 17 | #define smp_wmb() barrier() 18 | #endif 19 | 20 | #endif /* _KVM_BARRIER_H_ */ 21 | -------------------------------------------------------------------------------- /mips/include/kvm/kvm-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_ARCH_H 2 | #define KVM__KVM_ARCH_H 3 | 4 | 5 | /* 6 | * Guest memory map is: 7 | * 0x00000000-0x0fffffff : System RAM 8 | * 0x10000000-0x1fffffff : I/O (defined by KVM_MMIO_START and KVM_MMIO_SIZE) 9 | * 0x20000000- ... : System RAM 10 | * See also kvm__init_ram(). 11 | */ 12 | 13 | #define KVM_MMIO_START 0x10000000 14 | #define KVM_PCI_CFG_AREA KVM_MMIO_START 15 | #define KVM_PCI_MMIO_AREA (KVM_MMIO_START + 0x1000000) 16 | #define KVM_VIRTIO_MMIO_AREA (KVM_MMIO_START + 0x2000000) 17 | #define KVM_MMIO_SIZE 0x10000000 18 | 19 | /* 20 | * Just for reference. This and the above corresponds to what's used 21 | * in mipsvz_page_fault() in kvm_mipsvz.c of the host kernel. 22 | */ 23 | #define KVM_MIPS_IOPORT_AREA 0x1e000000 24 | #define KVM_MIPS_IOPORT_SIZE 0x00010000 25 | #define KVM_MIPS_IRQCHIP_AREA 0x1e010000 26 | #define KVM_MIPS_IRQCHIP_SIZE 0x00010000 27 | 28 | #define KVM_IRQ_OFFSET 1 29 | 30 | /* 31 | * MIPS-VZ (trap and emulate is 0) 32 | */ 33 | #define KVM_VM_TYPE 1 34 | 35 | #define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI 36 | 37 | #include 38 | 39 | #include "linux/types.h" 40 | 41 | struct kvm_arch { 42 | u64 entry_point; 43 | u64 argc; 44 | u64 argv; 45 | bool is64bit; 46 | }; 47 | 48 | #endif /* KVM__KVM_ARCH_H */ 49 | -------------------------------------------------------------------------------- /mips/include/kvm/kvm-config-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CONFIG_ARCH_H 2 | #define KVM__KVM_CONFIG_ARCH_H 3 | 4 | struct kvm_config_arch { 5 | }; 6 | 7 | #endif /* KVM__MIPS_KVM_CONFIG_ARCH_H */ 8 | -------------------------------------------------------------------------------- /mips/include/kvm/kvm-cpu-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CPU_ARCH_H 2 | #define KVM__KVM_CPU_ARCH_H 3 | 4 | #include /* for struct kvm_regs */ 5 | #include "kvm/kvm.h" /* for kvm__emulate_{mm}io() */ 6 | #include 7 | 8 | struct kvm; 9 | 10 | struct kvm_cpu { 11 | pthread_t thread; /* VCPU thread */ 12 | 13 | unsigned long cpu_id; 14 | 15 | struct kvm *kvm; /* parent KVM */ 16 | int vcpu_fd; /* For VCPU ioctls() */ 17 | struct kvm_run *kvm_run; 18 | 19 | struct kvm_regs regs; 20 | 21 | u8 is_running; 22 | u8 paused; 23 | u8 needs_nmi; 24 | 25 | struct kvm_coalesced_mmio_ring *ring; 26 | }; 27 | 28 | /* 29 | * As these are such simple wrappers, let's have them in the header so they'll 30 | * be cheaper to call: 31 | */ 32 | static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count) 33 | { 34 | return kvm__emulate_io(vcpu, port, data, direction, size, count); 35 | } 36 | 37 | static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write) 38 | { 39 | return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); 40 | } 41 | 42 | #endif /* KVM__KVM_CPU_ARCH_H */ 43 | -------------------------------------------------------------------------------- /mips/irq.c: -------------------------------------------------------------------------------- 1 | #include "kvm/irq.h" 2 | #include "kvm/kvm.h" 3 | 4 | #include 5 | 6 | int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) 7 | { 8 | pr_warning("irq__add_msix_route"); 9 | return 1; 10 | } 11 | -------------------------------------------------------------------------------- /net/uip/arp.c: -------------------------------------------------------------------------------- 1 | #include "kvm/uip.h" 2 | 3 | int uip_tx_do_arp(struct uip_tx_arg *arg) 4 | { 5 | struct uip_arp *arp, *arp2; 6 | struct uip_info *info; 7 | struct uip_buf *buf; 8 | 9 | info = arg->info; 10 | buf = uip_buf_clone(arg); 11 | 12 | arp = (struct uip_arp *)(arg->eth); 13 | arp2 = (struct uip_arp *)(buf->eth); 14 | 15 | /* 16 | * ARP replay code: 2 17 | */ 18 | arp2->op = htons(0x2); 19 | arp2->dmac = arp->smac; 20 | arp2->dip = arp->sip; 21 | 22 | if (arp->dip == htonl(info->host_ip)) { 23 | arp2->smac = info->host_mac; 24 | arp2->sip = htonl(info->host_ip); 25 | 26 | uip_buf_set_used(info, buf); 27 | } 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /net/uip/buf.c: -------------------------------------------------------------------------------- 1 | #include "kvm/uip.h" 2 | 3 | #include 4 | #include 5 | 6 | struct uip_buf *uip_buf_get_used(struct uip_info *info) 7 | { 8 | struct uip_buf *buf; 9 | bool found = false; 10 | 11 | mutex_lock(&info->buf_lock); 12 | 13 | while (!(info->buf_used_nr > 0)) 14 | pthread_cond_wait(&info->buf_used_cond, &info->buf_lock.mutex); 15 | 16 | list_for_each_entry(buf, &info->buf_head, list) { 17 | if (buf->status == UIP_BUF_STATUS_USED) { 18 | /* 19 | * Set status to INUSE immediately to prevent 20 | * someone from using this buf until we free it 21 | */ 22 | buf->status = UIP_BUF_STATUS_INUSE; 23 | info->buf_used_nr--; 24 | found = true; 25 | break; 26 | } 27 | } 28 | 29 | mutex_unlock(&info->buf_lock); 30 | 31 | return found ? buf : NULL; 32 | } 33 | 34 | struct uip_buf *uip_buf_get_free(struct uip_info *info) 35 | { 36 | struct uip_buf *buf; 37 | bool found = false; 38 | 39 | mutex_lock(&info->buf_lock); 40 | 41 | while (!(info->buf_free_nr > 0)) 42 | pthread_cond_wait(&info->buf_free_cond, &info->buf_lock.mutex); 43 | 44 | list_for_each_entry(buf, &info->buf_head, list) { 45 | if (buf->status == UIP_BUF_STATUS_FREE) { 46 | /* 47 | * Set status to INUSE immediately to prevent 48 | * someone from using this buf until we free it 49 | */ 50 | buf->status = UIP_BUF_STATUS_INUSE; 51 | info->buf_free_nr--; 52 | found = true; 53 | break; 54 | } 55 | } 56 | 57 | mutex_unlock(&info->buf_lock); 58 | 59 | return found ? buf : NULL; 60 | } 61 | 62 | struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf) 63 | { 64 | mutex_lock(&info->buf_lock); 65 | 66 | buf->status = UIP_BUF_STATUS_USED; 67 | info->buf_used_nr++; 68 | pthread_cond_signal(&info->buf_used_cond); 69 | 70 | mutex_unlock(&info->buf_lock); 71 | 72 | return buf; 73 | } 74 | 75 | struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf) 76 | { 77 | mutex_lock(&info->buf_lock); 78 | 79 | buf->status = UIP_BUF_STATUS_FREE; 80 | info->buf_free_nr++; 81 | pthread_cond_signal(&info->buf_free_cond); 82 | 83 | mutex_unlock(&info->buf_lock); 84 | 85 | return buf; 86 | } 87 | 88 | struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg) 89 | { 90 | struct uip_buf *buf; 91 | struct uip_eth *eth2; 92 | struct uip_info *info; 93 | 94 | info = arg->info; 95 | 96 | /* 97 | * Get buffer from device to guest 98 | */ 99 | buf = uip_buf_get_free(info); 100 | 101 | /* 102 | * Clone buffer 103 | */ 104 | memcpy(buf->vnet, arg->vnet, arg->vnet_len); 105 | memcpy(buf->eth, arg->eth, arg->eth_len); 106 | buf->vnet_len = arg->vnet_len; 107 | buf->eth_len = arg->eth_len; 108 | 109 | eth2 = (struct uip_eth *)buf->eth; 110 | eth2->src = info->host_mac; 111 | eth2->dst = arg->eth->src; 112 | 113 | return buf; 114 | } 115 | -------------------------------------------------------------------------------- /net/uip/csum.c: -------------------------------------------------------------------------------- 1 | #include "kvm/uip.h" 2 | 3 | static u16 uip_csum(u16 csum, u8 *addr, u16 count) 4 | { 5 | long sum = csum; 6 | 7 | while (count > 1) { 8 | sum += *(u16 *)addr; 9 | addr += 2; 10 | count -= 2; 11 | } 12 | 13 | if (count > 0) 14 | sum += *(unsigned char *)addr; 15 | 16 | while (sum>>16) 17 | sum = (sum & 0xffff) + (sum >> 16); 18 | 19 | return ~sum; 20 | } 21 | 22 | u16 uip_csum_ip(struct uip_ip *ip) 23 | { 24 | return uip_csum(0, &ip->vhl, uip_ip_hdrlen(ip)); 25 | } 26 | 27 | u16 uip_csum_icmp(struct uip_ip *ip, struct uip_icmp *icmp) 28 | { 29 | return icmp->csum = uip_csum(0, &icmp->type, htons(ip->len) - uip_ip_hdrlen(ip) - 8); /* icmp header len = 8 */ 30 | } 31 | 32 | u16 uip_csum_udp(struct uip_ip *ip, struct uip_udp *udp) 33 | { 34 | struct uip_pseudo_hdr hdr; 35 | int udp_len; 36 | u8 *pad; 37 | 38 | hdr.sip = ip->sip; 39 | hdr.dip = ip->dip; 40 | hdr.zero = 0; 41 | hdr.proto = ip->proto; 42 | hdr.len = udp->len; 43 | 44 | udp_len = uip_udp_len(udp); 45 | 46 | if (udp_len % 2) { 47 | pad = (u8 *)&udp->sport + udp_len; 48 | *pad = 0; 49 | memcpy((u8 *)&udp->sport + udp_len + 1, &hdr, sizeof(hdr)); 50 | return uip_csum(0, (u8 *)&udp->sport, udp_len + 1 + sizeof(hdr)); 51 | } else { 52 | memcpy((u8 *)&udp->sport + udp_len, &hdr, sizeof(hdr)); 53 | return uip_csum(0, (u8 *)&udp->sport, udp_len + sizeof(hdr)); 54 | } 55 | 56 | } 57 | 58 | u16 uip_csum_tcp(struct uip_ip *ip, struct uip_tcp *tcp) 59 | { 60 | struct uip_pseudo_hdr hdr; 61 | u16 tcp_len; 62 | u8 *pad; 63 | 64 | tcp_len = ntohs(ip->len) - uip_ip_hdrlen(ip); 65 | 66 | hdr.sip = ip->sip; 67 | hdr.dip = ip->dip; 68 | hdr.zero = 0; 69 | hdr.proto = ip->proto; 70 | hdr.len = htons(tcp_len); 71 | 72 | if (tcp_len > UIP_MAX_TCP_PAYLOAD + 20) 73 | pr_warning("tcp_len(%d) is too large", tcp_len); 74 | 75 | if (tcp_len % 2) { 76 | pad = (u8 *)&tcp->sport + tcp_len; 77 | *pad = 0; 78 | memcpy((u8 *)&tcp->sport + tcp_len + 1, &hdr, sizeof(hdr)); 79 | return uip_csum(0, (u8 *)&tcp->sport, tcp_len + 1 + sizeof(hdr)); 80 | } else { 81 | memcpy((u8 *)&tcp->sport + tcp_len, &hdr, sizeof(hdr)); 82 | return uip_csum(0, (u8 *)&tcp->sport, tcp_len + sizeof(hdr)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /net/uip/icmp.c: -------------------------------------------------------------------------------- 1 | #include "kvm/uip.h" 2 | 3 | int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg) 4 | { 5 | struct uip_ip *ip, *ip2; 6 | struct uip_icmp *icmp2; 7 | struct uip_icmp *icmp; 8 | struct uip_buf *buf; 9 | 10 | ip = (struct uip_ip *)(arg->eth); 11 | icmp = uip_ip_proto(ip); 12 | 13 | /* Check the icmp type first.. */ 14 | 15 | switch(icmp->type) { 16 | case UIP_ICMP_ECHO: 17 | buf = uip_buf_clone(arg); 18 | ip2 = (struct uip_ip *)(buf->eth); 19 | icmp2 = uip_ip_proto(ip2); 20 | ip2->sip = ip->dip; 21 | ip2->dip = ip->sip; 22 | ip2->csum = 0; 23 | /* 24 | * ICMP reply: 0 25 | */ 26 | icmp2->type = UIP_ICMP_ECHO_REPLY; 27 | icmp2->csum = 0; 28 | ip2->csum = uip_csum_ip(ip2); 29 | icmp2->csum = uip_csum_icmp(ip2, icmp2); 30 | 31 | uip_buf_set_used(arg->info, buf); 32 | 33 | return 0; 34 | /* FIXME: need to process unreachable reports */ 35 | default: 36 | return 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /net/uip/ipv4.c: -------------------------------------------------------------------------------- 1 | #include "kvm/uip.h" 2 | 3 | int uip_tx_do_ipv4(struct uip_tx_arg *arg) 4 | { 5 | struct uip_ip *ip; 6 | 7 | ip = (struct uip_ip *)(arg->eth); 8 | 9 | switch (ip->proto) { 10 | case UIP_IP_P_ICMP: 11 | uip_tx_do_ipv4_icmp(arg); 12 | break; 13 | case UIP_IP_P_TCP: 14 | uip_tx_do_ipv4_tcp(arg); 15 | break; 16 | case UIP_IP_P_UDP: 17 | uip_tx_do_ipv4_udp(arg); 18 | break; 19 | default: 20 | break; 21 | } 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /powerpc/boot.c: -------------------------------------------------------------------------------- 1 | #include "kvm/kvm.h" 2 | 3 | #include 4 | 5 | bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename) 6 | { 7 | return false; 8 | } 9 | -------------------------------------------------------------------------------- /powerpc/cpu_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC CPU identification 3 | * 4 | * Copyright 2012 Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef CPU_INFO_H 12 | #define CPU_INFO_H 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | struct cpu_info { 21 | const char *name; 22 | u32 tb_freq; /* timebase frequency */ 23 | u32 d_bsize; /* d-cache block size */ 24 | u32 i_bsize; /* i-cache block size */ 25 | u32 flags; 26 | struct kvm_ppc_smmu_info mmu_info; 27 | }; 28 | 29 | struct pvr_info { 30 | u32 pvr_mask; 31 | u32 pvr; 32 | struct cpu_info *cpu_info; 33 | }; 34 | 35 | /* Misc capabilities/CPU properties */ 36 | #define CPUINFO_FLAG_DFP 0x00000001 37 | #define CPUINFO_FLAG_VMX 0x00000002 38 | #define CPUINFO_FLAG_VSX 0x00000004 39 | 40 | struct cpu_info *find_cpu_info(struct kvm *kvm); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /powerpc/include/kvm/barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef _KVM_BARRIER_H_ 2 | #define _KVM_BARRIER_H_ 3 | 4 | #define mb() asm volatile ("sync" : : : "memory") 5 | #define rmb() asm volatile ("sync" : : : "memory") 6 | #define wmb() asm volatile ("sync" : : : "memory") 7 | 8 | #endif /* _KVM_BARRIER_H_ */ 9 | -------------------------------------------------------------------------------- /powerpc/include/kvm/kvm-arch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC64 architecture-specific definitions 3 | * 4 | * Copyright 2011 Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef KVM__KVM_ARCH_H 12 | #define KVM__KVM_ARCH_H 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | /* 19 | * MMIO lives after RAM, but it'd be nice if it didn't constantly move. 20 | * Choose a suitably high address, e.g. 63T... This limits RAM size. 21 | */ 22 | #define PPC_MMIO_START 0x3F0000000000UL 23 | #define PPC_MMIO_SIZE 0x010000000000UL 24 | 25 | #define KERNEL_LOAD_ADDR 0x0000000000000000 26 | #define KERNEL_START_ADDR 0x0000000000000000 27 | #define KERNEL_SECONDARY_START_ADDR 0x0000000000000060 28 | #define INITRD_LOAD_ADDR 0x0000000002800000 29 | 30 | #define RTAS_MAX_SIZE 0x10000 31 | 32 | #define TIMEBASE_FREQ 512000000ULL 33 | 34 | #define KVM_MMIO_START PPC_MMIO_START 35 | 36 | /* 37 | * This is the address that pci_get_io_space_block() starts allocating 38 | * from. Note that this is a PCI bus address. 39 | */ 40 | #define KVM_IOPORT_AREA 0x0 41 | #define KVM_PCI_CFG_AREA 0x1000000 42 | #define KVM_PCI_MMIO_AREA 0x2000000 43 | #define KVM_VIRTIO_MMIO_AREA 0x3000000 44 | 45 | #define KVM_IRQ_OFFSET 16 46 | 47 | #define KVM_VM_TYPE 0 48 | 49 | #define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI 50 | 51 | struct spapr_phb; 52 | 53 | struct kvm_arch { 54 | u64 sdr1; 55 | u32 pvr; 56 | unsigned long rtas_gra; 57 | unsigned long rtas_size; 58 | unsigned long fdt_gra; 59 | unsigned long initrd_gra; 60 | unsigned long initrd_size; 61 | struct icp_state *icp; 62 | struct spapr_phb *phb; 63 | }; 64 | 65 | #endif /* KVM__KVM_ARCH_H */ 66 | -------------------------------------------------------------------------------- /powerpc/include/kvm/kvm-config-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CONFIG_ARCH_H 2 | #define KVM__KVM_CONFIG_ARCH_H 3 | 4 | struct kvm_config_arch { 5 | }; 6 | 7 | #endif /* KVM__KVM_CONFIG_ARCH_H */ 8 | -------------------------------------------------------------------------------- /powerpc/include/kvm/kvm-cpu-arch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC64 cpu-specific definitions 3 | * 4 | * Copyright 2011 Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef KVM__KVM_CPU_ARCH_H 12 | #define KVM__KVM_CPU_ARCH_H 13 | 14 | /* Architecture-specific kvm_cpu definitions. */ 15 | 16 | #include /* for struct kvm_regs */ 17 | #include 18 | #include 19 | 20 | #define MSR_SF (1ULL<<63) 21 | #define MSR_HV (1ULL<<60) 22 | #define MSR_VEC (1ULL<<25) 23 | #define MSR_VSX (1ULL<<23) 24 | #define MSR_POW (1ULL<<18) 25 | #define MSR_EE (1ULL<<15) 26 | #define MSR_PR (1ULL<<14) 27 | #define MSR_FP (1ULL<<13) 28 | #define MSR_ME (1ULL<<12) 29 | #define MSR_FE0 (1ULL<<11) 30 | #define MSR_SE (1ULL<<10) 31 | #define MSR_BE (1ULL<<9) 32 | #define MSR_FE1 (1ULL<<8) 33 | #define MSR_IR (1ULL<<5) 34 | #define MSR_DR (1ULL<<4) 35 | #define MSR_PMM (1ULL<<2) 36 | #define MSR_RI (1ULL<<1) 37 | #define MSR_LE (1ULL<<0) 38 | 39 | #define POWER7_EXT_IRQ 0 40 | 41 | struct kvm; 42 | 43 | struct kvm_cpu { 44 | pthread_t thread; /* VCPU thread */ 45 | 46 | unsigned long cpu_id; 47 | 48 | struct kvm *kvm; /* parent KVM */ 49 | int vcpu_fd; /* For VCPU ioctls() */ 50 | struct kvm_run *kvm_run; 51 | 52 | struct kvm_regs regs; 53 | struct kvm_sregs sregs; 54 | struct kvm_fpu fpu; 55 | 56 | u8 is_running; 57 | u8 paused; 58 | u8 needs_nmi; 59 | /* 60 | * Although PPC KVM doesn't yet support coalesced MMIO, generic code 61 | * needs this in our kvm_cpu: 62 | */ 63 | struct kvm_coalesced_mmio_ring *ring; 64 | }; 65 | 66 | void kvm_cpu__irq(struct kvm_cpu *vcpu, int pin, int level); 67 | 68 | /* This is never actually called on PPC. */ 69 | static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count) 70 | { 71 | return false; 72 | } 73 | 74 | bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write); 75 | 76 | #endif /* KVM__KVM_CPU_ARCH_H */ 77 | -------------------------------------------------------------------------------- /powerpc/ioport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC64 ioport platform setup. There isn't any! :-) 3 | * 4 | * Copyright 2011 Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #include "kvm/ioport.h" 12 | 13 | #include 14 | 15 | void ioport__setup_arch(struct kvm *kvm) 16 | { 17 | /* PPC has no legacy ioports to set up */ 18 | } 19 | 20 | void ioport__map_irq(u8 *irq) 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /powerpc/irq.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PPC64 IRQ routines 3 | * 4 | * Copyright 2011 Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #include "kvm/devices.h" 12 | #include "kvm/irq.h" 13 | #include "kvm/kvm.h" 14 | #include "kvm/util.h" 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | #include "kvm/pci.h" 26 | 27 | int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) 28 | { 29 | die(__FUNCTION__); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /powerpc/spapr_hvcons.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPAPR HV console 3 | * 4 | * Borrowed lightly from QEMU's spapr_vty.c, Copyright (c) 2010 David Gibson, 5 | * IBM Corporation. 6 | * 7 | * Copyright (c) 2011 Matt Evans , IBM Corporation. 8 | * 9 | * This program is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License version 2 as published 11 | * by the Free Software Foundation. 12 | */ 13 | 14 | #include "kvm/term.h" 15 | #include "kvm/kvm.h" 16 | #include "kvm/kvm-cpu.h" 17 | #include "kvm/util.h" 18 | #include "spapr.h" 19 | #include "spapr_hvcons.h" 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | union hv_chario { 28 | struct { 29 | uint64_t char0_7; 30 | uint64_t char8_15; 31 | } a; 32 | uint8_t buf[16]; 33 | }; 34 | 35 | static unsigned long h_put_term_char(struct kvm_cpu *vcpu, unsigned long opcode, unsigned long *args) 36 | { 37 | /* To do: Read register from args[0], and check it. */ 38 | unsigned long len = args[1]; 39 | union hv_chario data; 40 | struct iovec iov; 41 | 42 | if (len > 16) { 43 | return H_PARAMETER; 44 | } 45 | data.a.char0_7 = cpu_to_be64(args[2]); 46 | data.a.char8_15 = cpu_to_be64(args[3]); 47 | 48 | iov.iov_base = data.buf; 49 | iov.iov_len = len; 50 | do { 51 | int ret; 52 | 53 | ret = term_putc_iov(&iov, 1, 0); 54 | if (ret < 0) { 55 | die("term_putc_iov error %d!\n", errno); 56 | } 57 | iov.iov_base += ret; 58 | iov.iov_len -= ret; 59 | } while (iov.iov_len > 0); 60 | 61 | return H_SUCCESS; 62 | } 63 | 64 | 65 | static unsigned long h_get_term_char(struct kvm_cpu *vcpu, unsigned long opcode, unsigned long *args) 66 | { 67 | /* To do: Read register from args[0], and check it. */ 68 | unsigned long *len = args + 0; 69 | unsigned long *char0_7 = args + 1; 70 | unsigned long *char8_15 = args + 2; 71 | union hv_chario data; 72 | struct iovec iov; 73 | 74 | if (vcpu->kvm->cfg.active_console != CONSOLE_HV) 75 | return H_SUCCESS; 76 | 77 | if (term_readable(0)) { 78 | iov.iov_base = data.buf; 79 | iov.iov_len = 16; 80 | 81 | *len = term_getc_iov(vcpu->kvm, &iov, 1, 0); 82 | *char0_7 = be64_to_cpu(data.a.char0_7); 83 | *char8_15 = be64_to_cpu(data.a.char8_15); 84 | } else { 85 | *len = 0; 86 | } 87 | 88 | return H_SUCCESS; 89 | } 90 | 91 | void spapr_hvcons_poll(struct kvm *kvm) 92 | { 93 | if (term_readable(0)) { 94 | /* 95 | * We can inject an IRQ to guest here if we want. The guest 96 | * will happily poll, though, so not required. 97 | */ 98 | } 99 | } 100 | 101 | void spapr_hvcons_init(void) 102 | { 103 | spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char); 104 | spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char); 105 | } 106 | -------------------------------------------------------------------------------- /powerpc/spapr_hvcons.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPAPR HV console 3 | * 4 | * Copyright (c) 2011 Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef spapr_hvcons_H 12 | #define spapr_hvcons_H 13 | 14 | #include "kvm/kvm.h" 15 | 16 | void spapr_hvcons_init(void); 17 | void spapr_hvcons_poll(struct kvm *kvm); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /powerpc/spapr_pci.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPAPR PHB definitions 3 | * 4 | * Modifications by Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef SPAPR_PCI_H 12 | #define SPAPR_PCI_H 13 | 14 | #include "kvm/kvm.h" 15 | #include "spapr.h" 16 | #include 17 | 18 | /* With XICS, we can easily accomodate 1 IRQ per PCI device. */ 19 | 20 | #define SPAPR_PCI_NUM_LSI 256 21 | 22 | struct spapr_phb { 23 | uint64_t buid; 24 | uint64_t mem_addr; 25 | uint64_t mem_size; 26 | uint64_t io_addr; 27 | uint64_t io_size; 28 | }; 29 | 30 | void spapr_create_phb(struct kvm *kvm, 31 | const char *busname, uint64_t buid, 32 | uint64_t mem_win_addr, uint64_t mem_win_size, 33 | uint64_t io_win_addr, uint64_t io_win_size); 34 | 35 | int spapr_populate_pci_devices(struct kvm *kvm, 36 | uint32_t xics_phandle, 37 | void *fdt); 38 | 39 | static inline bool spapr_phb_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write) 40 | { 41 | if ((phys_addr >= SPAPR_PCI_IO_WIN_ADDR) && 42 | (phys_addr < SPAPR_PCI_IO_WIN_ADDR + 43 | SPAPR_PCI_IO_WIN_SIZE)) { 44 | return kvm__emulate_io(vcpu, phys_addr - SPAPR_PCI_IO_WIN_ADDR, 45 | data, is_write ? KVM_EXIT_IO_OUT : 46 | KVM_EXIT_IO_IN, 47 | len, 1); 48 | } else if ((phys_addr >= SPAPR_PCI_MEM_WIN_ADDR) && 49 | (phys_addr < SPAPR_PCI_MEM_WIN_ADDR + 50 | SPAPR_PCI_MEM_WIN_SIZE)) { 51 | return kvm__emulate_mmio(vcpu, phys_addr - SPAPR_PCI_MEM_WIN_ADDR, 52 | data, len, is_write); 53 | } 54 | return false; 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /powerpc/xics.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PAPR Virtualized Interrupt System, aka ICS/ICP aka xics 3 | * 4 | * Copyright 2011 Matt Evans , IBM Corporation. 5 | * 6 | * This program is free software; you can redistribute it and/or modify it 7 | * under the terms of the GNU General Public License version 2 as published 8 | * by the Free Software Foundation. 9 | */ 10 | 11 | #ifndef XICS_H 12 | #define XICS_H 13 | 14 | #define XICS_IPI 0x2 15 | 16 | int xics_alloc_irqnum(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /symbol.c: -------------------------------------------------------------------------------- 1 | #include "kvm/symbol.h" 2 | 3 | #include "kvm/kvm.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | static bfd *abfd; 12 | 13 | int symbol_init(struct kvm *kvm) 14 | { 15 | int ret = 0; 16 | 17 | if (!kvm->vmlinux) 18 | return 0; 19 | 20 | bfd_init(); 21 | 22 | abfd = bfd_openr(kvm->vmlinux, NULL); 23 | if (abfd == NULL) { 24 | bfd_error_type err = bfd_get_error(); 25 | 26 | switch (err) { 27 | case bfd_error_no_memory: 28 | ret = -ENOMEM; 29 | break; 30 | case bfd_error_invalid_target: 31 | ret = -EINVAL; 32 | break; 33 | default: 34 | ret = -EFAULT; 35 | break; 36 | } 37 | } 38 | 39 | return ret; 40 | } 41 | late_init(symbol_init); 42 | 43 | static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_name) 44 | { 45 | int i, ret; 46 | 47 | ret = -ENOENT; 48 | 49 | for (i = 0; i < nr_symbols; i++) { 50 | asymbol *symbol = symbols[i]; 51 | 52 | if (!strcmp(bfd_asymbol_name(symbol), symbol_name)) 53 | return symbol; 54 | } 55 | 56 | return ERR_PTR(ret); 57 | } 58 | 59 | char *symbol_lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size) 60 | { 61 | const char *filename; 62 | bfd_vma sym_offset; 63 | bfd_vma sym_start; 64 | asection *section; 65 | unsigned int line; 66 | const char *func; 67 | long symtab_size; 68 | asymbol *symbol; 69 | asymbol **syms; 70 | int nr_syms, ret; 71 | 72 | ret = -ENOENT; 73 | if (!abfd) 74 | goto not_found; 75 | 76 | if (!bfd_check_format(abfd, bfd_object)) 77 | goto not_found; 78 | 79 | symtab_size = bfd_get_symtab_upper_bound(abfd); 80 | if (!symtab_size) 81 | goto not_found; 82 | 83 | ret = -ENOMEM; 84 | syms = malloc(symtab_size); 85 | if (!syms) 86 | goto not_found; 87 | 88 | nr_syms = bfd_canonicalize_symtab(abfd, syms); 89 | 90 | ret = -ENOENT; 91 | section = bfd_get_section_by_name(abfd, ".debug_aranges"); 92 | if (!section) 93 | goto not_found; 94 | 95 | if (!bfd_find_nearest_line(abfd, section, NULL, addr, &filename, &func, &line)) 96 | goto not_found; 97 | 98 | if (!func) 99 | goto not_found; 100 | 101 | symbol = lookup(syms, nr_syms, func); 102 | if (IS_ERR(symbol)) 103 | goto not_found; 104 | 105 | sym_start = bfd_asymbol_value(symbol); 106 | 107 | sym_offset = addr - sym_start; 108 | 109 | snprintf(sym, size, "%s+%llx (%s:%i)", func, (long long) sym_offset, filename, line); 110 | 111 | sym[size - 1] = '\0'; 112 | 113 | free(syms); 114 | 115 | return sym; 116 | 117 | not_found: 118 | return ERR_PTR(ret); 119 | } 120 | 121 | int symbol_exit(struct kvm *kvm) 122 | { 123 | bfd_boolean ret = TRUE; 124 | 125 | if (abfd) 126 | ret = bfd_close(abfd); 127 | 128 | if (ret == TRUE) 129 | return 0; 130 | 131 | return -EFAULT; 132 | } 133 | late_exit(symbol_exit); 134 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | all: kernel pit boot 2 | 3 | kernel: 4 | $(MAKE) -C kernel 5 | .PHONY: kernel 6 | 7 | pit: 8 | $(MAKE) -C pit 9 | .PHONY: pit 10 | 11 | boot: 12 | $(MAKE) -C boot 13 | .PHONY: boot 14 | 15 | clean: 16 | $(MAKE) -C kernel clean 17 | $(MAKE) -C pit clean 18 | $(MAKE) -C boot clean 19 | .PHONY: clean 20 | -------------------------------------------------------------------------------- /tests/boot/Makefile: -------------------------------------------------------------------------------- 1 | NAME := init 2 | 3 | OBJ := $(NAME).o 4 | 5 | all: $(.o) 6 | rm -rf rootfs 7 | mkdir rootfs 8 | gcc -static init.c -o rootfs/init 9 | mkisofs rootfs > boot_test.iso 10 | 11 | clean: 12 | rm -rf rootfs boot_test.iso 13 | .PHONY: clean 14 | -------------------------------------------------------------------------------- /tests/boot/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | puts("hello, KVM guest!\r"); 7 | 8 | reboot(LINUX_REBOOT_CMD_RESTART); 9 | 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /tests/kernel/.gitignore: -------------------------------------------------------------------------------- 1 | kernel.bin 2 | kernel.elf 3 | -------------------------------------------------------------------------------- /tests/kernel/Makefile: -------------------------------------------------------------------------------- 1 | NAME := kernel 2 | 3 | BIN := $(NAME).bin 4 | ELF := $(NAME).elf 5 | OBJ := $(NAME).o 6 | 7 | all: $(BIN) 8 | 9 | $(BIN): $(ELF) 10 | objcopy -O binary $< $@ 11 | 12 | $(ELF): $(OBJ) 13 | ld -Ttext=0x00 -nostdlib -static $< -o $@ 14 | 15 | %.o: %.S 16 | gcc -nostdinc -c $< -o $@ 17 | 18 | clean: 19 | rm -f $(BIN) $(ELF) $(OBJ) 20 | .PHONY: clean 21 | -------------------------------------------------------------------------------- /tests/kernel/README: -------------------------------------------------------------------------------- 1 | Compiling 2 | --------- 3 | 4 | You can simply type: 5 | 6 | $ make 7 | 8 | to build a 16-bit binary that uses the i8086 instruction set. 9 | 10 | Disassembling 11 | ------------- 12 | 13 | Use the "-m i8086" command line option with objdump to make sure it knows we're 14 | dealing with i8086 instruction set: 15 | 16 | $ objdump -d -m i8086 i8086.elf 17 | -------------------------------------------------------------------------------- /tests/kernel/kernel.S: -------------------------------------------------------------------------------- 1 | .code16gcc 2 | .text 3 | .globl _start 4 | .type _start, @function 5 | _start: 6 | # "This is probably the largest possible kernel that is bug free." -- Avi Kivity 7 | 1: 8 | jmp 1b 9 | -------------------------------------------------------------------------------- /tests/pit/.gitignore: -------------------------------------------------------------------------------- 1 | *.bin 2 | *.elf 3 | -------------------------------------------------------------------------------- /tests/pit/Makefile: -------------------------------------------------------------------------------- 1 | NAME := tick 2 | 3 | BIN := $(NAME).bin 4 | ELF := $(NAME).elf 5 | OBJ := $(NAME).o 6 | 7 | all: $(BIN) 8 | 9 | $(BIN): $(ELF) 10 | objcopy -O binary $< $@ 11 | 12 | $(ELF): $(OBJ) 13 | ld -Ttext=0x00 -nostdlib -static $< -o $@ 14 | 15 | %.o: %.S 16 | gcc -nostdinc -c $< -o $@ 17 | 18 | clean: 19 | rm -f $(BIN) $(ELF) $(OBJ) 20 | .PHONY: clean 21 | -------------------------------------------------------------------------------- /tests/pit/README: -------------------------------------------------------------------------------- 1 | Compiling 2 | --------- 3 | 4 | You can simply type: 5 | 6 | $ make 7 | 8 | to build a 16-bit binary that uses the i8086 instruction set. 9 | 10 | Disassembling 11 | ------------- 12 | 13 | Use the "-m i8086" command line option with objdump to make sure it knows we're 14 | dealing with i8086 instruction set: 15 | 16 | $ objdump -d -m i8086 i8086.elf 17 | -------------------------------------------------------------------------------- /tests/pit/tick.S: -------------------------------------------------------------------------------- 1 | #define IO_PIC 0x20 2 | #define IRQ_OFFSET 32 3 | #define IO_PIT 0x40 4 | #define TIMER_FREQ 1193182 5 | #define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x)) 6 | 7 | #define TEST_COUNT 0x0200 8 | 9 | .code16gcc 10 | .text 11 | .globl _start 12 | .type _start, @function 13 | _start: 14 | /* 15 | * fill up noop handlers 16 | */ 17 | xorw %ax, %ax 18 | xorw %di, %di 19 | movw %ax, %es 20 | movw $256, %cx 21 | fill_noop_idt: 22 | movw $noop_handler, %es:(%di) 23 | movw %cs, %es:2(%di) 24 | add $4, %di 25 | loop fill_noop_idt 26 | 27 | set_idt: 28 | movw $timer_isr, %es:(IRQ_OFFSET*4) 29 | movw %cs, %es:(IRQ_OFFSET*4+2) 30 | 31 | set_pic: 32 | # ICW1 33 | mov $0x11, %al 34 | mov $(IO_PIC), %dx 35 | out %al,%dx 36 | # ICW2 37 | mov $(IRQ_OFFSET), %al 38 | mov $(IO_PIC+1), %dx 39 | out %al, %dx 40 | # ICW3 41 | mov $0x00, %al 42 | mov $(IO_PIC+1), %dx 43 | out %al, %dx 44 | # ICW4 45 | mov $0x3, %al 46 | mov $(IO_PIC+1), %dx 47 | out %al, %dx 48 | 49 | set_pit: 50 | # set 8254 mode 51 | mov $(IO_PIT+3), %dx 52 | mov $0x34, %al 53 | outb %al, %dx 54 | # set 8254 freq 1KHz 55 | mov $(IO_PIT), %dx 56 | movb $(TIMER_DIV(1000) % 256), %al 57 | outb %al, %dx 58 | movb $(TIMER_DIV(1000) / 256), %al 59 | outb %al, %dx 60 | 61 | enable_irq0: 62 | mov $0xfe, %al 63 | mov $(IO_PIC+1), %dx 64 | out %al, %dx 65 | sti 66 | loop: 67 | 1: 68 | jmp 1b 69 | 70 | test_ok: 71 | mov $0x3f8,%dx 72 | cs lea msg2, %si 73 | mov $(msg2_end-msg2), %cx 74 | cs rep/outsb 75 | 76 | /* Reboot by using the i8042 reboot line */ 77 | mov $0xfe, %al 78 | outb %al, $0x64 79 | 80 | timer_isr: 81 | cli 82 | pushaw 83 | pushfw 84 | mov $0x3f8,%dx 85 | mov $0x2e, %al # . 86 | out %al,%dx 87 | decw count 88 | jz test_ok 89 | popfw 90 | popaw 91 | iretw 92 | 93 | noop_handler: 94 | iretw 95 | 96 | count: 97 | .word TEST_COUNT 98 | 99 | msg2: 100 | .asciz "\nTest OK\n" 101 | msg2_end: 102 | -------------------------------------------------------------------------------- /util/KVMTOOLS-VERSION-GEN: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ $# -eq 1 ] ; then 4 | OUTPUT=$1 5 | fi 6 | 7 | GVF=${OUTPUT}KVMTOOLS-VERSION-FILE 8 | 9 | LF=' 10 | ' 11 | 12 | # First check if there is a .git to get the version from git describe 13 | # otherwise try to get the version from the kernel makefile 14 | if test -d .git -o -f .git && 15 | VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && 16 | case "$VN" in 17 | *$LF*) (exit 1) ;; 18 | v[0-9]*) 19 | git update-index -q --refresh 20 | test -z "$(git diff-index --name-only HEAD --)" || 21 | VN="$VN-dirty" ;; 22 | esac 23 | then 24 | VN=$(echo "$VN" | sed -e 's/-/./g'); 25 | else 26 | VN=3.18.0 27 | fi 28 | 29 | VN=$(expr "$VN" : v*'\(.*\)') 30 | 31 | if test -r $GVF 32 | then 33 | VC=$(sed -e 's/^KVMTOOLS_VERSION = //' <$GVF) 34 | else 35 | VC=unset 36 | fi 37 | test "$VN" = "$VC" || { 38 | echo >&2 "KVMTOOLS_VERSION = $VN" 39 | echo "KVMTOOLS_VERSION = $VN" >$GVF 40 | } 41 | -------------------------------------------------------------------------------- /util/generate-cmdlist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "/* Automatically generated by $0 */ 4 | struct cmdname_help 5 | { 6 | char name[16]; 7 | char help[80]; 8 | }; 9 | 10 | static struct cmdname_help common_cmds[] = {" 11 | 12 | sed -n 's/^lkvm-\([^ \t]*\).*common/\1/p' command-list.txt | 13 | while read cmd 14 | do 15 | # TODO following sed command should be fixed 16 | sed -n '/^NAME/,/^lkvm-'"$cmd"'/ { 17 | /NAME/d 18 | /--/d 19 | s/.*kvm-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ 20 | p 21 | }' "Documentation/kvm-$cmd.txt" 22 | done 23 | echo "};" 24 | -------------------------------------------------------------------------------- /util/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "kvm/kvm.h" 5 | #include "kvm/util-init.h" 6 | 7 | #define PRIORITY_LISTS 10 8 | 9 | static struct hlist_head init_lists[PRIORITY_LISTS]; 10 | static struct hlist_head exit_lists[PRIORITY_LISTS]; 11 | 12 | int init_list_add(struct init_item *t, int (*init)(struct kvm *), 13 | int priority, const char *name) 14 | { 15 | t->init = init; 16 | t->fn_name = name; 17 | hlist_add_head(&t->n, &init_lists[priority]); 18 | 19 | return 0; 20 | } 21 | 22 | int exit_list_add(struct init_item *t, int (*init)(struct kvm *), 23 | int priority, const char *name) 24 | { 25 | t->init = init; 26 | t->fn_name = name; 27 | hlist_add_head(&t->n, &exit_lists[priority]); 28 | 29 | return 0; 30 | } 31 | 32 | int init_list__init(struct kvm *kvm) 33 | { 34 | unsigned int i; 35 | int r = 0; 36 | struct init_item *t; 37 | 38 | for (i = 0; i < ARRAY_SIZE(init_lists); i++) 39 | hlist_for_each_entry(t, &init_lists[i], n) { 40 | r = t->init(kvm); 41 | if (r < 0) { 42 | pr_warning("Failed init: %s\n", t->fn_name); 43 | goto fail; 44 | } 45 | } 46 | 47 | fail: 48 | return r; 49 | } 50 | 51 | int init_list__exit(struct kvm *kvm) 52 | { 53 | int i; 54 | int r = 0; 55 | struct init_item *t; 56 | 57 | for (i = ARRAY_SIZE(exit_lists) - 1; i >= 0; i--) 58 | hlist_for_each_entry(t, &exit_lists[i], n) { 59 | r = t->init(kvm); 60 | if (r < 0) { 61 | pr_warning("%s failed.\n", t->fn_name); 62 | goto fail; 63 | } 64 | } 65 | fail: 66 | return r; 67 | } 68 | -------------------------------------------------------------------------------- /util/iovec.c: -------------------------------------------------------------------------------- 1 | /* 2 | * iovec manipulation routines. 3 | * 4 | * 5 | * This program is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU General Public License 7 | * as published by the Free Software Foundation; either version 8 | * 2 of the License, or (at your option) any later version. 9 | * 10 | * Fixes: 11 | * Andrew Lunn : Errors in iovec copying. 12 | * Pedro Roque : Added memcpy_fromiovecend and 13 | * csum_..._fromiovecend. 14 | * Andi Kleen : fixed error handling for 2.1 15 | * Alexey Kuznetsov: 2.1 optimisations 16 | * Andi Kleen : Fix csum*fromiovecend for IPv6. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | /* 27 | * Copy kernel to iovec. Returns -EFAULT on error. 28 | * 29 | * Note: this modifies the original iovec. 30 | */ 31 | 32 | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) 33 | { 34 | while (len > 0) { 35 | if (iov->iov_len) { 36 | int copy = min_t(unsigned int, iov->iov_len, len); 37 | memcpy(iov->iov_base, kdata, copy); 38 | kdata += copy; 39 | len -= copy; 40 | iov->iov_len -= copy; 41 | iov->iov_base += copy; 42 | } 43 | iov++; 44 | } 45 | 46 | return 0; 47 | } 48 | 49 | /* 50 | * Copy kernel to iovec. Returns -EFAULT on error. 51 | */ 52 | 53 | int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, 54 | size_t offset, int len) 55 | { 56 | int copy; 57 | for (; len > 0; ++iov) { 58 | /* Skip over the finished iovecs */ 59 | if (unlikely(offset >= iov->iov_len)) { 60 | offset -= iov->iov_len; 61 | continue; 62 | } 63 | copy = min_t(unsigned int, iov->iov_len - offset, len); 64 | memcpy(iov->iov_base + offset, kdata, copy); 65 | offset = 0; 66 | kdata += copy; 67 | len -= copy; 68 | } 69 | 70 | return 0; 71 | } 72 | 73 | /* 74 | * Copy iovec to kernel. Returns -EFAULT on error. 75 | * 76 | * Note: this modifies the original iovec. 77 | */ 78 | 79 | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) 80 | { 81 | while (len > 0) { 82 | if (iov->iov_len) { 83 | int copy = min_t(unsigned int, len, iov->iov_len); 84 | memcpy(kdata, iov->iov_base, copy); 85 | len -= copy; 86 | kdata += copy; 87 | iov->iov_base += copy; 88 | iov->iov_len -= copy; 89 | } 90 | iov++; 91 | } 92 | 93 | return 0; 94 | } 95 | 96 | /* 97 | * Copy iovec from kernel. Returns -EFAULT on error. 98 | */ 99 | 100 | int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, 101 | size_t offset, int len) 102 | { 103 | /* Skip over the finished iovecs */ 104 | while (offset >= iov->iov_len) { 105 | offset -= iov->iov_len; 106 | iov++; 107 | } 108 | 109 | while (len > 0) { 110 | char *base = iov->iov_base + offset; 111 | int copy = min_t(unsigned int, len, iov->iov_len - offset); 112 | 113 | offset = 0; 114 | memcpy(kdata, base, copy); 115 | len -= copy; 116 | kdata += copy; 117 | iov++; 118 | } 119 | 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /util/kvm-ifup-vbr0: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | switch=vbr0 3 | /sbin/ifconfig $1 0.0.0.0 up 4 | /usr/sbin/brctl addif ${switch} $1 5 | /usr/sbin/brctl setfd ${switch} 0 6 | /usr/sbin/brctl stp ${switch} off 7 | -------------------------------------------------------------------------------- /util/rbtree-interval.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct rb_int_node *rb_int_search_single(struct rb_root *root, u64 point) 6 | { 7 | struct rb_node *node = root->rb_node; 8 | 9 | while (node) { 10 | struct rb_int_node *cur = rb_int(node); 11 | 12 | if (point < cur->low) 13 | node = node->rb_left; 14 | else if (cur->high <= point) 15 | node = node->rb_right; 16 | else 17 | return cur; 18 | } 19 | 20 | return NULL; 21 | } 22 | 23 | struct rb_int_node *rb_int_search_range(struct rb_root *root, u64 low, u64 high) 24 | { 25 | struct rb_int_node *range; 26 | 27 | range = rb_int_search_single(root, low); 28 | if (range == NULL) 29 | return NULL; 30 | 31 | /* We simply verify that 'high' is smaller than the end of the range where 'low' is located */ 32 | if (range->high < high) 33 | return NULL; 34 | 35 | return range; 36 | } 37 | 38 | int rb_int_insert(struct rb_root *root, struct rb_int_node *i_node) 39 | { 40 | struct rb_node **node = &root->rb_node, *parent = NULL; 41 | 42 | while (*node) { 43 | struct rb_int_node *cur = rb_int(*node); 44 | 45 | parent = *node; 46 | if (i_node->high <= cur->low) 47 | node = &cur->node.rb_left; 48 | else if (cur->high <= i_node->low) 49 | node = &cur->node.rb_right; 50 | else 51 | return -EEXIST; 52 | } 53 | 54 | rb_link_node(&i_node->node, parent, node); 55 | rb_insert_color(&i_node->node, root); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /util/set_private_br.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Author: Amos Kong 4 | # Date: Apr 14, 2011 5 | # Description: this script is used to create/delete a private bridge, 6 | # launch a dhcp server on the bridge by dnsmasq. 7 | # 8 | # @ ./set_private_br.sh $bridge_name $subnet_prefix 9 | # @ ./set_private_br.sh vbr0 192.168.33 10 | 11 | brname='vbr0' 12 | subnet='192.168.33' 13 | 14 | add_br() 15 | { 16 | echo "add new private bridge: $brname" 17 | /usr/sbin/brctl addbr $brname 18 | echo 1 > /proc/sys/net/ipv6/conf/$brname/disable_ipv6 19 | echo 1 > /proc/sys/net/ipv4/ip_forward 20 | /usr/sbin/brctl stp $brname on 21 | /usr/sbin/brctl setfd $brname 0 22 | ifconfig $brname $subnet.1 23 | ifconfig $brname up 24 | # Add forward rule, then guest can access public network 25 | iptables -t nat -A POSTROUTING -s $subnet.254/24 ! -d $subnet.254/24 -j MASQUERADE 26 | /etc/init.d/dnsmasq stop 27 | /etc/init.d/tftpd-hpa stop 2>/dev/null 28 | dnsmasq --strict-order --bind-interfaces --listen-address $subnet.1 --dhcp-range $subnet.1,$subnet.254 $tftp_cmd 29 | } 30 | 31 | del_br() 32 | { 33 | echo "cleanup bridge setup" 34 | kill -9 `pgrep dnsmasq|tail -1` 35 | ifconfig $brname down 36 | /usr/sbin/brctl delbr $brname 37 | iptables -t nat -D POSTROUTING -s $subnet.254/24 ! -d $subnet.254/24 -j MASQUERADE 38 | } 39 | 40 | 41 | if [ $# = 0 ]; then 42 | del_br 2>/dev/null 43 | exit 44 | fi 45 | if [ $# > 1 ]; then 46 | brname="$1" 47 | fi 48 | if [ $# = 2 ]; then 49 | subnet="$2" 50 | fi 51 | add_br 52 | -------------------------------------------------------------------------------- /util/strbuf.c: -------------------------------------------------------------------------------- 1 | 2 | /* user defined headers */ 3 | #include 4 | #include 5 | 6 | int prefixcmp(const char *str, const char *prefix) 7 | { 8 | for (; ; str++, prefix++) { 9 | if (!*prefix) 10 | return 0; 11 | else if (*str != *prefix) 12 | return (unsigned char)*prefix - (unsigned char)*str; 13 | } 14 | } 15 | 16 | #ifndef HAVE_STRLCPY 17 | /** 18 | * strlcat - Append a length-limited, %NUL-terminated string to another 19 | * @dest: The string to be appended to 20 | * @src: The string to append to it 21 | * @count: The size of the destination buffer. 22 | */ 23 | size_t strlcat(char *dest, const char *src, size_t count) 24 | { 25 | size_t dsize = strlen(dest); 26 | size_t len = strlen(src); 27 | size_t res = dsize + len; 28 | 29 | DIE_IF(dsize >= count); 30 | 31 | dest += dsize; 32 | count -= dsize; 33 | if (len >= count) 34 | len = count - 1; 35 | 36 | memcpy(dest, src, len); 37 | dest[len] = 0; 38 | 39 | return res; 40 | } 41 | 42 | /** 43 | * strlcpy - Copy a %NUL terminated string into a sized buffer 44 | * @dest: Where to copy the string to 45 | * @src: Where to copy the string from 46 | * @size: size of destination buffer 47 | * 48 | * Compatible with *BSD: the result is always a valid 49 | * NUL-terminated string that fits in the buffer (unless, 50 | * of course, the buffer size is zero). It does not pad 51 | * out the result like strncpy() does. 52 | */ 53 | size_t strlcpy(char *dest, const char *src, size_t size) 54 | { 55 | size_t ret = strlen(src); 56 | 57 | if (size) { 58 | size_t len = (ret >= size) ? size - 1 : ret; 59 | memcpy(dest, src, len); 60 | dest[len] = '\0'; 61 | } 62 | return ret; 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /util/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Taken from perf which in turn take it from GIT 3 | */ 4 | 5 | #include "kvm/util.h" 6 | 7 | #include 8 | #include /* For HUGETLBFS_MAGIC */ 9 | #include 10 | #include 11 | #include 12 | 13 | static void report(const char *prefix, const char *err, va_list params) 14 | { 15 | char msg[1024]; 16 | vsnprintf(msg, sizeof(msg), err, params); 17 | fprintf(stderr, " %s%s\n", prefix, msg); 18 | } 19 | 20 | static NORETURN void die_builtin(const char *err, va_list params) 21 | { 22 | report(" Fatal: ", err, params); 23 | exit(128); 24 | } 25 | 26 | static void error_builtin(const char *err, va_list params) 27 | { 28 | report(" Error: ", err, params); 29 | } 30 | 31 | static void warn_builtin(const char *warn, va_list params) 32 | { 33 | report(" Warning: ", warn, params); 34 | } 35 | 36 | static void info_builtin(const char *info, va_list params) 37 | { 38 | report(" Info: ", info, params); 39 | } 40 | 41 | void die(const char *err, ...) 42 | { 43 | va_list params; 44 | 45 | va_start(params, err); 46 | die_builtin(err, params); 47 | va_end(params); 48 | } 49 | 50 | int pr_err(const char *err, ...) 51 | { 52 | va_list params; 53 | 54 | va_start(params, err); 55 | error_builtin(err, params); 56 | va_end(params); 57 | return -1; 58 | } 59 | 60 | void pr_warning(const char *warn, ...) 61 | { 62 | va_list params; 63 | 64 | va_start(params, warn); 65 | warn_builtin(warn, params); 66 | va_end(params); 67 | } 68 | 69 | void pr_info(const char *info, ...) 70 | { 71 | va_list params; 72 | 73 | va_start(params, info); 74 | info_builtin(info, params); 75 | va_end(params); 76 | } 77 | 78 | void die_perror(const char *s) 79 | { 80 | perror(s); 81 | exit(1); 82 | } 83 | 84 | void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size) 85 | { 86 | char mpath[PATH_MAX]; 87 | int fd; 88 | struct statfs sfs; 89 | void *addr; 90 | unsigned long blk_size; 91 | 92 | if (statfs(htlbfs_path, &sfs) < 0) 93 | die("Can't stat %s\n", htlbfs_path); 94 | 95 | if ((unsigned int)sfs.f_type != HUGETLBFS_MAGIC) 96 | die("%s is not hugetlbfs!\n", htlbfs_path); 97 | 98 | blk_size = (unsigned long)sfs.f_bsize; 99 | if (sfs.f_bsize == 0 || blk_size > size) { 100 | die("Can't use hugetlbfs pagesize %ld for mem size %lld\n", 101 | blk_size, (unsigned long long)size); 102 | } 103 | 104 | kvm->ram_pagesize = blk_size; 105 | 106 | snprintf(mpath, PATH_MAX, "%s/kvmtoolXXXXXX", htlbfs_path); 107 | fd = mkstemp(mpath); 108 | if (fd < 0) 109 | die("Can't open %s for hugetlbfs map\n", mpath); 110 | unlink(mpath); 111 | if (ftruncate(fd, size) < 0) 112 | die("Can't ftruncate for mem mapping size %lld\n", 113 | (unsigned long long)size); 114 | addr = mmap(NULL, size, PROT_RW, MAP_PRIVATE, fd, 0); 115 | close(fd); 116 | 117 | return addr; 118 | } 119 | 120 | /* This function wraps the decision between hugetlbfs map (if requested) or normal mmap */ 121 | void *mmap_anon_or_hugetlbfs(struct kvm *kvm, const char *hugetlbfs_path, u64 size) 122 | { 123 | if (hugetlbfs_path) 124 | /* 125 | * We don't /need/ to map guest RAM from hugetlbfs, but we do so 126 | * if the user specifies a hugetlbfs path. 127 | */ 128 | return mmap_hugetlbfs(kvm, hugetlbfs_path, size); 129 | else { 130 | kvm->ram_pagesize = getpagesize(); 131 | return mmap(NULL, size, PROT_RW, MAP_ANON_NORESERVE, -1, 0); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /x86/bios/.gitignore: -------------------------------------------------------------------------------- 1 | bios-rom.bin 2 | bios-rom.bin.elf 3 | bios-rom.h 4 | -------------------------------------------------------------------------------- /x86/bios/bios-rom.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | .org 0 4 | #ifdef CONFIG_X86_64 5 | .code64 6 | #else 7 | .code32 8 | #endif 9 | 10 | GLOBAL(bios_rom) 11 | .incbin "x86/bios/bios.bin" 12 | END(bios_rom) 13 | -------------------------------------------------------------------------------- /x86/bios/e820.c: -------------------------------------------------------------------------------- 1 | #include "asm/bios/types.h" 2 | #include "kvm/e820.h" 3 | 4 | #include "kvm/bios.h" 5 | 6 | #include 7 | 8 | static inline u16 flat_to_seg16(u32 address) 9 | { 10 | return address >> 4; 11 | } 12 | 13 | static inline u16 flat_to_off16(u32 address, u32 segment) 14 | { 15 | return address - (segment << 4); 16 | } 17 | 18 | static inline void set_fs(u16 seg) 19 | { 20 | asm volatile("movw %0,%%fs" : : "rm" (seg)); 21 | } 22 | 23 | static inline u8 rdfs8(unsigned long addr) 24 | { 25 | u8 v; 26 | 27 | asm volatile("addr32 movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr)); 28 | 29 | return v; 30 | } 31 | 32 | static inline u32 rdfs32(unsigned long addr) 33 | { 34 | u32 v; 35 | 36 | asm volatile("addr32 movl %%fs:%1,%0" : "=q" (v) : "m" (*(u32 *)addr)); 37 | 38 | return v; 39 | } 40 | 41 | bioscall void e820_query_map(struct biosregs *regs) 42 | { 43 | struct e820map *e820; 44 | u32 map_size; 45 | u16 fs_seg; 46 | u32 ndx; 47 | 48 | e820 = (struct e820map *)E820_MAP_START; 49 | fs_seg = flat_to_seg16(E820_MAP_START); 50 | set_fs(fs_seg); 51 | 52 | ndx = regs->ebx; 53 | 54 | map_size = rdfs32(flat_to_off16((u32)&e820->nr_map, fs_seg)); 55 | 56 | if (ndx < map_size) { 57 | u32 start; 58 | unsigned int i; 59 | u8 *p; 60 | 61 | fs_seg = flat_to_seg16(E820_MAP_START); 62 | set_fs(fs_seg); 63 | 64 | start = (u32)&e820->map[ndx]; 65 | 66 | p = (void *) regs->edi; 67 | 68 | for (i = 0; i < sizeof(struct e820entry); i++) 69 | *p++ = rdfs8(flat_to_off16(start + i, fs_seg)); 70 | } 71 | 72 | regs->eax = SMAP; 73 | regs->ecx = sizeof(struct e820entry); 74 | regs->ebx = ++ndx; 75 | 76 | /* Clear CF to indicate success. */ 77 | regs->eflags &= ~X86_EFLAGS_CF; 78 | 79 | if (ndx >= map_size) 80 | regs->ebx = 0; /* end of map */ 81 | } 82 | -------------------------------------------------------------------------------- /x86/bios/entry.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Our pretty trivial BIOS emulation 3 | */ 4 | 5 | #include 6 | #include 7 | 8 | .org 0 9 | .code16gcc 10 | 11 | #define EFLAGS_CF (1 << 0) 12 | 13 | #include "macro.S" 14 | 15 | /* If you change these macros, remember to update 'struct biosregs' */ 16 | .macro SAVE_BIOSREGS 17 | pushl %fs 18 | pushl %es 19 | pushl %ds 20 | pushl %edi 21 | pushl %esi 22 | pushl %ebp 23 | pushl %esp 24 | pushl %edx 25 | pushl %ecx 26 | pushl %ebx 27 | pushl %eax 28 | .endm 29 | 30 | .macro RESTORE_BIOSREGS 31 | popl %eax 32 | popl %ebx 33 | popl %ecx 34 | popl %edx 35 | popl %esp 36 | popl %ebp 37 | popl %esi 38 | popl %edi 39 | popl %ds 40 | popl %es 41 | popl %fs 42 | .endm 43 | 44 | /* 45 | * fake interrupt handler, nothing can be faster ever 46 | */ 47 | ENTRY(bios_intfake) 48 | /* 49 | * Set CF to indicate failure. We don't want callers to think that the 50 | * interrupt handler succeeded and then treat the return values in 51 | * registers as valid data. 52 | */ 53 | orl $EFLAGS_CF, 0x4(%esp) 54 | 55 | IRET 56 | ENTRY_END(bios_intfake) 57 | 58 | /* 59 | * int 10 - video - service 60 | */ 61 | ENTRY(bios_int10) 62 | SAVE_BIOSREGS 63 | 64 | movl %esp, %eax 65 | /* this is way easier than doing it in assembly */ 66 | /* just push all the regs and jump to a C handler */ 67 | call int10_handler 68 | 69 | RESTORE_BIOSREGS 70 | 71 | /* Clear CF to indicate success. */ 72 | andl $~EFLAGS_CF, 0x4(%esp) 73 | 74 | IRET 75 | ENTRY_END(bios_int10) 76 | 77 | ENTRY(bios_int15) 78 | SAVE_BIOSREGS 79 | 80 | movl %esp, %eax 81 | call int15_handler 82 | 83 | RESTORE_BIOSREGS 84 | 85 | IRET 86 | ENTRY_END(bios_int15) 87 | 88 | GLOBAL(__locals) 89 | 90 | #include "local.S" 91 | 92 | END(__locals) 93 | -------------------------------------------------------------------------------- /x86/bios/gen-offsets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "/* Autogenerated file, don't edit */" 4 | echo "#ifndef BIOS_OFFSETS_H" 5 | echo "#define BIOS_OFFSETS_H" 6 | 7 | echo "" 8 | echo "#define BIOS_ENTRY_SIZE(name) (name##_end - name)" 9 | echo "" 10 | 11 | nm bios.bin.elf | grep ' [Tt] ' | awk '{ print "#define BIOS_OFFSET__" $3 " 0x" $1; }' 12 | 13 | echo "" 14 | echo "#endif" 15 | -------------------------------------------------------------------------------- /x86/bios/int10.c: -------------------------------------------------------------------------------- 1 | #include "kvm/bios.h" 2 | #include "kvm/vesa.h" 3 | 4 | #include "asm/bios/memcpy.h" 5 | 6 | #include "asm/bios/vesa.h" 7 | 8 | static far_ptr gen_far_ptr(unsigned int pa) 9 | { 10 | far_ptr ptr; 11 | 12 | ptr.seg = (pa >> 4); 13 | ptr.off = pa - (ptr.seg << 4); 14 | 15 | return ptr; 16 | } 17 | 18 | static inline void outb(unsigned short port, unsigned char val) 19 | { 20 | asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); 21 | } 22 | 23 | /* 24 | * It's probably much more useful to make this print to the serial 25 | * line rather than print to a non-displayed VGA memory 26 | */ 27 | static inline void int10_putchar(struct biosregs *args) 28 | { 29 | u8 al = args->eax & 0xFF; 30 | 31 | outb(0x3f8, al); 32 | } 33 | 34 | static void vbe_get_mode(struct biosregs *args) 35 | { 36 | struct vesa_mode_info *info = (struct vesa_mode_info *) args->edi; 37 | 38 | *info = (struct vesa_mode_info) { 39 | .mode_attr = 0xd9, /* 11011011 */ 40 | .logical_scan = VESA_WIDTH*4, 41 | .h_res = VESA_WIDTH, 42 | .v_res = VESA_HEIGHT, 43 | .bpp = VESA_BPP, 44 | .memory_layout = 6, 45 | .memory_planes = 1, 46 | .lfb_ptr = VESA_MEM_ADDR, 47 | .rmask = 8, 48 | .gmask = 8, 49 | .bmask = 8, 50 | .resv_mask = 8, 51 | .resv_pos = 24, 52 | .bpos = 16, 53 | .gpos = 8, 54 | }; 55 | } 56 | 57 | static void vbe_get_info(struct biosregs *args) 58 | { 59 | struct vesa_general_info *infop = (struct vesa_general_info *) args->edi; 60 | struct vesa_general_info info; 61 | 62 | info = (struct vesa_general_info) { 63 | .signature = VESA_MAGIC, 64 | .version = 0x102, 65 | .vendor_string = gen_far_ptr(VGA_ROM_BEGIN), 66 | .capabilities = 0x10, 67 | .video_mode_ptr = gen_far_ptr(VGA_ROM_MODES), 68 | .total_memory = (4 * VESA_WIDTH * VESA_HEIGHT) / 0x10000, 69 | }; 70 | 71 | memcpy16(args->es, infop, args->ds, &info, sizeof(info)); 72 | } 73 | 74 | #define VBE_STATUS_OK 0x004F 75 | 76 | static void int10_vesa(struct biosregs *args) 77 | { 78 | u8 al; 79 | 80 | al = args->eax & 0xff; 81 | 82 | switch (al) { 83 | case 0x00: 84 | vbe_get_info(args); 85 | break; 86 | case 0x01: 87 | vbe_get_mode(args); 88 | break; 89 | } 90 | 91 | args->eax = VBE_STATUS_OK; 92 | } 93 | 94 | bioscall void int10_handler(struct biosregs *args) 95 | { 96 | u8 ah; 97 | 98 | ah = (args->eax & 0xff00) >> 8; 99 | 100 | switch (ah) { 101 | case 0x0e: 102 | int10_putchar(args); 103 | break; 104 | case 0x4f: 105 | int10_vesa(args); 106 | break; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /x86/bios/int15.c: -------------------------------------------------------------------------------- 1 | #include "kvm/bios.h" 2 | 3 | #include "kvm/e820.h" 4 | 5 | #include 6 | 7 | bioscall void int15_handler(struct biosregs *regs) 8 | { 9 | switch (regs->eax) { 10 | case 0xe820: 11 | e820_query_map(regs); 12 | break; 13 | default: 14 | /* Set CF to indicate failure. */ 15 | regs->eflags |= X86_EFLAGS_CF; 16 | break; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /x86/bios/local.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Local variables for almost every BIOS irq handler 3 | * Must be put somewhere inside irq handler body 4 | */ 5 | __CALLER_SS: .int 0 6 | __CALLER_SP: .long 0 7 | __CALLER_CLOBBER: .long 0 8 | -------------------------------------------------------------------------------- /x86/bios/macro.S: -------------------------------------------------------------------------------- 1 | /* 2 | * handy BIOS macros 3 | */ 4 | 5 | /* 6 | * switch to BIOS stack 7 | */ 8 | .macro stack_swap 9 | movw %ss, %cs:(__CALLER_SS) 10 | movl %esp, %cs:(__CALLER_SP) 11 | movl %edx, %cs:(__CALLER_CLOBBER) 12 | movw $MB_BIOS_SS, %dx 13 | movw %dx, %ss 14 | movw $MB_BIOS_SP, %sp 15 | movl %cs:(__CALLER_CLOBBER), %edx 16 | .endm 17 | 18 | /* 19 | * restore the original stack 20 | */ 21 | .macro stack_restore 22 | movl %cs:(__CALLER_SP), %esp 23 | movw %cs:(__CALLER_SS), %ss 24 | .endm 25 | 26 | -------------------------------------------------------------------------------- /x86/bios/memcpy.c: -------------------------------------------------------------------------------- 1 | #include "asm/bios/memcpy.h" 2 | 3 | /* 4 | * Copy memory area in 16-bit real mode. 5 | */ 6 | void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len) 7 | { 8 | __asm__ __volatile__ ( 9 | "pushw %%ds \n" 10 | "pushw %%es \n" 11 | "movw %[src_seg], %%ds \n" 12 | "movw %[dst_seg], %%es \n" 13 | "rep movsb %%ds:(%%si), %%es:(%%di) \n" 14 | "popw %%es \n" 15 | "popw %%ds \n" 16 | : 17 | : "S"(src), 18 | "D"(dst), 19 | "c"(len), 20 | [src_seg] "r"(src_seg), 21 | [dst_seg] "r"(dst_seg) 22 | : "cc", "memory"); 23 | } 24 | -------------------------------------------------------------------------------- /x86/bios/rom.ld.S: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 2 | OUTPUT_ARCH(i386) 3 | 4 | SECTIONS { 5 | .text 0 : { 6 | *(.text) 7 | } 8 | 9 | /DISCARD/ : { 10 | *(.debug*) 11 | *(.data) 12 | *(.bss) 13 | *(.eh_frame*) 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /x86/boot.c: -------------------------------------------------------------------------------- 1 | #include "kvm/kvm.h" 2 | 3 | #include "kvm/util.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define BIOS_SELECTOR 0xf000 11 | #define BIOS_IP 0xfff0 12 | #define BIOS_SP 0x8000 13 | 14 | bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename) 15 | { 16 | struct stat st; 17 | void *p; 18 | int fd; 19 | int nr; 20 | 21 | fd = open(firmware_filename, O_RDONLY); 22 | if (fd < 0) 23 | return false; 24 | 25 | if (fstat(fd, &st)) 26 | return false; 27 | 28 | if (st.st_size > MB_FIRMWARE_BIOS_SIZE) 29 | die("firmware image %s is too big to fit in memory (%Lu KB).\n", firmware_filename, (u64)(st.st_size / 1024)); 30 | 31 | p = guest_flat_to_host(kvm, MB_FIRMWARE_BIOS_BEGIN); 32 | 33 | while ((nr = read(fd, p, st.st_size)) > 0) 34 | p += nr; 35 | 36 | kvm->arch.boot_selector = BIOS_SELECTOR; 37 | kvm->arch.boot_ip = BIOS_IP; 38 | kvm->arch.boot_sp = BIOS_SP; 39 | 40 | return true; 41 | } 42 | -------------------------------------------------------------------------------- /x86/cpuid.c: -------------------------------------------------------------------------------- 1 | #include "kvm/kvm-cpu.h" 2 | #include "kvm/cpufeature.h" 3 | 4 | #include "kvm/kvm.h" 5 | #include "kvm/util.h" 6 | 7 | #include 8 | #include 9 | 10 | #define MAX_KVM_CPUID_ENTRIES 100 11 | 12 | static void filter_cpuid(struct kvm_cpuid2 *kvm_cpuid) 13 | { 14 | unsigned int i; 15 | struct cpuid_regs regs; 16 | 17 | /* 18 | * Filter CPUID functions that are not supported by the hypervisor. 19 | */ 20 | for (i = 0; i < kvm_cpuid->nent; i++) { 21 | struct kvm_cpuid_entry2 *entry = &kvm_cpuid->entries[i]; 22 | 23 | switch (entry->function) { 24 | case 0: 25 | 26 | regs = (struct cpuid_regs) { 27 | .eax = 0x00, 28 | 29 | }; 30 | host_cpuid(®s); 31 | /* Vendor name */ 32 | entry->ebx = regs.ebx; 33 | entry->ecx = regs.ecx; 34 | entry->edx = regs.edx; 35 | break; 36 | case 1: 37 | /* Set X86_FEATURE_HYPERVISOR */ 38 | if (entry->index == 0) 39 | entry->ecx |= (1 << 31); 40 | /* Set CPUID_EXT_TSC_DEADLINE_TIMER*/ 41 | if (entry->index == 0) 42 | entry->ecx |= (1 << 24); 43 | break; 44 | case 6: 45 | /* Clear X86_FEATURE_EPB */ 46 | entry->ecx = entry->ecx & ~(1 << 3); 47 | break; 48 | case 10: { /* Architectural Performance Monitoring */ 49 | union cpuid10_eax { 50 | struct { 51 | unsigned int version_id :8; 52 | unsigned int num_counters :8; 53 | unsigned int bit_width :8; 54 | unsigned int mask_length :8; 55 | } split; 56 | unsigned int full; 57 | } eax; 58 | 59 | /* 60 | * If the host has perf system running, 61 | * but no architectural events available 62 | * through kvm pmu -- disable perf support, 63 | * thus guest won't even try to access msr 64 | * registers. 65 | */ 66 | if (entry->eax) { 67 | eax.full = entry->eax; 68 | if (eax.split.version_id != 2 || 69 | !eax.split.num_counters) 70 | entry->eax = 0; 71 | } 72 | break; 73 | } 74 | default: 75 | /* Keep the CPUID function as -is */ 76 | break; 77 | }; 78 | } 79 | } 80 | 81 | void kvm_cpu__setup_cpuid(struct kvm_cpu *vcpu) 82 | { 83 | struct kvm_cpuid2 *kvm_cpuid; 84 | 85 | kvm_cpuid = calloc(1, sizeof(*kvm_cpuid) + 86 | MAX_KVM_CPUID_ENTRIES * sizeof(*kvm_cpuid->entries)); 87 | 88 | kvm_cpuid->nent = MAX_KVM_CPUID_ENTRIES; 89 | if (ioctl(vcpu->kvm->sys_fd, KVM_GET_SUPPORTED_CPUID, kvm_cpuid) < 0) 90 | die_perror("KVM_GET_SUPPORTED_CPUID failed"); 91 | 92 | filter_cpuid(kvm_cpuid); 93 | 94 | if (ioctl(vcpu->vcpu_fd, KVM_SET_CPUID2, kvm_cpuid) < 0) 95 | die_perror("KVM_SET_CPUID2 failed"); 96 | 97 | free(kvm_cpuid); 98 | } 99 | -------------------------------------------------------------------------------- /x86/include/asm/bios/memcpy.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_BIOS_MEMCPY_H 2 | #define KVM_BIOS_MEMCPY_H 3 | 4 | #include 5 | #include 6 | 7 | void memcpy16(u16 dst_seg, void *dst, u16 src_seg, const void *src, size_t len); 8 | 9 | #endif /* KVM_BIOS_MEMCPY_H */ 10 | -------------------------------------------------------------------------------- /x86/include/asm/bios/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __X86_ASM_BIOS_TYPES_H 2 | #define __X86_ASM_BIOS_TYPES_H 3 | 4 | typedef unsigned char u8; 5 | typedef unsigned short u16; 6 | typedef unsigned int u32; 7 | typedef unsigned long long u64; 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /x86/include/asm/bios/vesa.h: -------------------------------------------------------------------------------- 1 | /* ----------------------------------------------------------------------- * 2 | * 3 | * Copyright 1999-2007 H. Peter Anvin - All Rights Reserved 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, Inc., 53 Temple Place Ste 330, 8 | * Boston MA 02111-1307, USA; either version 2 of the License, or 9 | * (at your option) any later version; incorporated herein by reference. 10 | * 11 | * ----------------------------------------------------------------------- */ 12 | 13 | #ifndef BOOT_VESA_H 14 | #define BOOT_VESA_H 15 | 16 | typedef struct { 17 | u16 off, seg; 18 | } far_ptr; 19 | 20 | /* VESA General Information table */ 21 | struct vesa_general_info { 22 | u32 signature; /* 0 Magic number = "VESA" */ 23 | u16 version; /* 4 */ 24 | far_ptr vendor_string; /* 6 */ 25 | u32 capabilities; /* 10 */ 26 | far_ptr video_mode_ptr; /* 14 */ 27 | u16 total_memory; /* 18 */ 28 | 29 | u8 reserved[236]; /* 20 */ 30 | } __attribute__ ((packed)); 31 | 32 | #define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24)) 33 | 34 | struct vesa_mode_info { 35 | u16 mode_attr; /* 0 */ 36 | u8 win_attr[2]; /* 2 */ 37 | u16 win_grain; /* 4 */ 38 | u16 win_size; /* 6 */ 39 | u16 win_seg[2]; /* 8 */ 40 | far_ptr win_scheme; /* 12 */ 41 | u16 logical_scan; /* 16 */ 42 | 43 | u16 h_res; /* 18 */ 44 | u16 v_res; /* 20 */ 45 | u8 char_width; /* 22 */ 46 | u8 char_height; /* 23 */ 47 | u8 memory_planes; /* 24 */ 48 | u8 bpp; /* 25 */ 49 | u8 banks; /* 26 */ 50 | u8 memory_layout; /* 27 */ 51 | u8 bank_size; /* 28 */ 52 | u8 image_planes; /* 29 */ 53 | u8 page_function; /* 30 */ 54 | 55 | u8 rmask; /* 31 */ 56 | u8 rpos; /* 32 */ 57 | u8 gmask; /* 33 */ 58 | u8 gpos; /* 34 */ 59 | u8 bmask; /* 35 */ 60 | u8 bpos; /* 36 */ 61 | u8 resv_mask; /* 37 */ 62 | u8 resv_pos; /* 38 */ 63 | u8 dcm_info; /* 39 */ 64 | 65 | u32 lfb_ptr; /* 40 Linear frame buffer address */ 66 | u32 offscreen_ptr; /* 44 Offscreen memory address */ 67 | u16 offscreen_size; /* 48 */ 68 | 69 | u8 reserved[206]; /* 50 */ 70 | } __attribute__ ((packed)); 71 | 72 | #endif /* LIB_SYS_VESA_H */ 73 | -------------------------------------------------------------------------------- /x86/include/asm/processor-flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASM_X86_PROCESSOR_FLAGS_H 2 | #define _ASM_X86_PROCESSOR_FLAGS_H 3 | /* Various flags defined: can be included from assembler. */ 4 | 5 | #ifndef _BITUL 6 | 7 | #ifdef __ASSEMBLY__ 8 | #define _AC(X,Y) X 9 | #define _AT(T,X) X 10 | #else 11 | #define __AC(X,Y) (X##Y) 12 | #define _AC(X,Y) __AC(X,Y) 13 | #define _AT(T,X) ((T)(X)) 14 | #endif 15 | 16 | #define _BITUL(x) (_AC(1,UL) << (x)) 17 | #define _BITULL(x) (_AC(1,ULL) << (x)) 18 | 19 | #endif 20 | 21 | /* 22 | * EFLAGS bits 23 | */ 24 | #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ 25 | 26 | /* 27 | * Basic CPU control in CR0 28 | */ 29 | #define X86_CR0_PE_BIT 0 /* Protection Enable */ 30 | #define X86_CR0_PE _BITUL(X86_CR0_PE_BIT) 31 | #define X86_CR0_PG_BIT 31 /* Paging */ 32 | #define X86_CR0_PG _BITUL(X86_CR0_PG_BIT) 33 | 34 | /* 35 | * Intel CPU features in CR4 36 | */ 37 | #define X86_CR4_PAE_BIT 5 /* enable physical address extensions */ 38 | #define X86_CR4_PAE _BITUL(X86_CR4_PAE_BIT) 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /x86/include/asm/segment.h: -------------------------------------------------------------------------------- 1 | #ifndef _ASM_X86_SEGMENT_H 2 | #define _ASM_X86_SEGMENT_H 3 | 4 | #include 5 | 6 | /* Constructor for a conventional segment GDT (or LDT) entry */ 7 | /* This is a macro so it can be used in initializers */ 8 | #define GDT_ENTRY(flags, base, limit) \ 9 | ((((base) & _AC(0xff000000,ULL)) << (56-24)) | \ 10 | (((flags) & _AC(0x0000f0ff,ULL)) << 40) | \ 11 | (((limit) & _AC(0x000f0000,ULL)) << (48-16)) | \ 12 | (((base) & _AC(0x00ffffff,ULL)) << 16) | \ 13 | (((limit) & _AC(0x0000ffff,ULL)))) 14 | 15 | #endif /* _ASM_X86_SEGMENT_H */ 16 | -------------------------------------------------------------------------------- /x86/include/kvm/assembly.h: -------------------------------------------------------------------------------- 1 | #ifndef ASSEMBLY_H_ 2 | #define ASSEMBLY_H_ 3 | 4 | #define __ALIGN .p2align 4, 0x90 5 | #define ENTRY(name) \ 6 | __ALIGN; \ 7 | .globl name; \ 8 | name: 9 | 10 | #define GLOBAL(name) \ 11 | .globl name; \ 12 | name: 13 | 14 | #define ENTRY_END(name) GLOBAL(name##_end) 15 | #define END(name) GLOBAL(name##_end) 16 | 17 | /* 18 | * gas produces size override prefix with which 19 | * we are unhappy, lets make it hardcoded for 20 | * 16 bit mode 21 | */ 22 | #define IRET .byte 0xcf 23 | 24 | #endif /* ASSEMBLY_H_ */ 25 | -------------------------------------------------------------------------------- /x86/include/kvm/barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef _KVM_BARRIER_H_ 2 | #define _KVM_BARRIER_H_ 3 | 4 | #define barrier() asm volatile("": : :"memory") 5 | 6 | #define mb() asm volatile ("mfence": : :"memory") 7 | #define rmb() asm volatile ("lfence": : :"memory") 8 | #define wmb() asm volatile ("sfence": : :"memory") 9 | 10 | #ifdef CONFIG_SMP 11 | #define smp_mb() mb() 12 | #define smp_rmb() rmb() 13 | #define smp_wmb() wmb() 14 | #else 15 | #define smp_mb() barrier() 16 | #define smp_rmb() barrier() 17 | #define smp_wmb() barrier() 18 | #endif 19 | 20 | #endif /* _KVM_BARRIER_H_ */ 21 | -------------------------------------------------------------------------------- /x86/include/kvm/bios-export.h: -------------------------------------------------------------------------------- 1 | #ifndef BIOS_EXPORT_H_ 2 | #define BIOS_EXPORT_H_ 3 | 4 | struct kvm; 5 | 6 | extern char bios_rom[0]; 7 | extern char bios_rom_end[0]; 8 | 9 | #define bios_rom_size (bios_rom_end - bios_rom) 10 | 11 | extern void setup_bios(struct kvm *kvm); 12 | 13 | #endif /* BIOS_EXPORT_H_ */ 14 | -------------------------------------------------------------------------------- /x86/include/kvm/bios.h: -------------------------------------------------------------------------------- 1 | #ifndef BIOS_H_ 2 | #define BIOS_H_ 3 | 4 | /* 5 | * X86-32 Memory Map (typical) 6 | * start end 7 | * Real Mode Interrupt Vector Table 0x00000000 0x000003FF 8 | * BDA area 0x00000400 0x000004FF 9 | * Conventional Low Memory 0x00000500 0x0009FBFF 10 | * EBDA area 0x0009FC00 0x0009FFFF 11 | * VIDEO RAM 0x000A0000 0x000BFFFF 12 | * VIDEO ROM (BIOS) 0x000C0000 0x000C7FFF 13 | * ROMs & unus. space (mapped hw & misc)0x000C8000 0x000EFFFF 160 KiB (typically) 14 | * Motherboard BIOS 0x000F0000 0x000FFFFF 15 | * Extended Memory 0x00100000 0xFEBFFFFF 16 | * Reserved (configs, ACPI, PnP, etc) 0xFEC00000 0xFFFFFFFF 17 | */ 18 | 19 | #define REAL_MODE_IVT_BEGIN 0x00000000 20 | #define REAL_MODE_IVT_END 0x000003ff 21 | 22 | #define BDA_START 0x00000400 23 | #define BDA_END 0x000004ff 24 | 25 | #define EBDA_START 0x0009fc00 26 | #define EBDA_END 0x0009ffff 27 | 28 | #define E820_MAP_START EBDA_START 29 | 30 | #define MB_BIOS_BEGIN 0x000f0000 31 | #define MB_FIRMWARE_BIOS_BEGIN 0x000e0000 32 | #define MB_BIOS_END 0x000fffff 33 | 34 | #define MB_BIOS_SIZE (MB_BIOS_END - MB_BIOS_BEGIN + 1) 35 | #define MB_FIRMWARE_BIOS_SIZE (MB_BIOS_END - MB_FIRMWARE_BIOS_BEGIN + 1) 36 | 37 | #define VGA_RAM_BEGIN 0x000a0000 38 | #define VGA_RAM_END 0x000bffff 39 | 40 | #define VGA_ROM_BEGIN 0x000c0000 41 | #define VGA_ROM_OEM_STRING VGA_ROM_BEGIN 42 | #define VGA_ROM_OEM_STRING_SIZE 16 43 | #define VGA_ROM_MODES (VGA_ROM_OEM_STRING + VGA_ROM_OEM_STRING_SIZE) 44 | #define VGA_ROM_MODES_SIZE 32 45 | #define VGA_ROM_END 0x000c7fff 46 | 47 | /* we handle one page only */ 48 | #define VGA_RAM_SEG (VGA_RAM_BEGIN >> 4) 49 | #define VGA_PAGE_SIZE 0x007d0 /* 80x25 */ 50 | 51 | /* real mode interrupt vector table */ 52 | #define REAL_INTR_BASE REAL_MODE_IVT_BEGIN 53 | #define REAL_INTR_VECTORS 256 54 | 55 | /* 56 | * BIOS stack must be at absolute predefined memory address 57 | * We reserve 64 bytes for BIOS stack 58 | */ 59 | #define MB_BIOS_SS 0xfff7 60 | #define MB_BIOS_SP 0x40 61 | 62 | /* 63 | * When interfere with assembler code we need to be sure how 64 | * arguments are passed in real mode. 65 | */ 66 | #define bioscall __attribute__((regparm(3))) 67 | 68 | #ifndef __ASSEMBLER__ 69 | 70 | #include 71 | 72 | struct biosregs { 73 | u32 eax; 74 | u32 ebx; 75 | u32 ecx; 76 | u32 edx; 77 | u32 esp; 78 | u32 ebp; 79 | u32 esi; 80 | u32 edi; 81 | u32 ds; 82 | u32 es; 83 | u32 fs; 84 | u32 eip; 85 | u32 eflags; 86 | }; 87 | 88 | extern bioscall void int10_handler(struct biosregs *regs); 89 | extern bioscall void int15_handler(struct biosregs *regs); 90 | 91 | #endif 92 | 93 | #endif /* BIOS_H_ */ 94 | -------------------------------------------------------------------------------- /x86/include/kvm/boot-protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux boot protocol specifics 3 | */ 4 | 5 | #ifndef BOOT_PROTOCOL_H_ 6 | #define BOOT_PROTOCOL_H_ 7 | 8 | /* 9 | * The protected mode kernel part of a modern bzImage is loaded 10 | * at 1 MB by default. 11 | */ 12 | #define BZ_DEFAULT_SETUP_SECTS 4 13 | #define BZ_KERNEL_START 0x100000UL 14 | #define INITRD_START 0x1000000UL 15 | 16 | #endif /* BOOT_PROTOCOL_H_ */ 17 | -------------------------------------------------------------------------------- /x86/include/kvm/cpufeature.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__CPUFEATURE_H 2 | #define KVM__CPUFEATURE_H 3 | 4 | #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */ 5 | #define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */ 6 | #define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */ 7 | 8 | #define CPUID_VENDOR_AMD_1 0x68747541 /* "Auth" */ 9 | #define CPUID_VENDOR_AMD_2 0x69746e65 /* "enti" */ 10 | #define CPUID_VENDOR_AMD_3 0x444d4163 /* "cAMD" */ 11 | 12 | /* 13 | * CPUID flags we need to deal with 14 | */ 15 | #define KVM__X86_FEATURE_VMX 5 /* Hardware virtualization */ 16 | #define KVM__X86_FEATURE_SVM 2 /* Secure virtual machine */ 17 | #define KVM__X86_FEATURE_XSAVE 26 /* XSAVE/XRSTOR/XSETBV/XGETBV */ 18 | 19 | #define cpu_feature_disable(reg, feature) \ 20 | ((reg) & ~(1 << (feature))) 21 | #define cpu_feature_enable(reg, feature) \ 22 | ((reg) | (1 << (feature))) 23 | 24 | struct cpuid_regs { 25 | u32 eax; 26 | u32 ebx; 27 | u32 ecx; 28 | u32 edx; 29 | }; 30 | 31 | static inline void host_cpuid(struct cpuid_regs *regs) 32 | { 33 | asm volatile("cpuid" 34 | : "=a" (regs->eax), 35 | "=b" (regs->ebx), 36 | "=c" (regs->ecx), 37 | "=d" (regs->edx) 38 | : "0" (regs->eax), "2" (regs->ecx)); 39 | } 40 | 41 | #endif /* KVM__CPUFEATURE_H */ 42 | -------------------------------------------------------------------------------- /x86/include/kvm/e820.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_E820_H 2 | #define KVM_E820_H 3 | 4 | #include 5 | #include 6 | 7 | #define SMAP 0x534d4150 /* ASCII "SMAP" */ 8 | 9 | #define E820MAX 128 /* number of entries in E820MAP */ 10 | #define E820_X_MAX E820MAX 11 | 12 | #define E820_RAM 1 13 | #define E820_RESERVED 2 14 | 15 | struct biosregs; 16 | 17 | extern bioscall void e820_query_map(struct biosregs *regs); 18 | 19 | #endif /* KVM_E820_H */ 20 | -------------------------------------------------------------------------------- /x86/include/kvm/interrupt.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__INTERRUPT_H 2 | #define KVM__INTERRUPT_H 3 | 4 | #include 5 | #include "kvm/bios.h" 6 | #include "kvm/bios-export.h" 7 | 8 | struct real_intr_desc { 9 | u16 offset; 10 | u16 segment; 11 | } __attribute__((packed)); 12 | 13 | #define REAL_SEGMENT_SHIFT 4 14 | #define REAL_SEGMENT(addr) ((addr) >> REAL_SEGMENT_SHIFT) 15 | #define REAL_OFFSET(addr) ((addr) & ((1 << REAL_SEGMENT_SHIFT) - 1)) 16 | #define REAL_INTR_SIZE (REAL_INTR_VECTORS * sizeof(struct real_intr_desc)) 17 | 18 | struct interrupt_table { 19 | struct real_intr_desc entries[REAL_INTR_VECTORS]; 20 | }; 21 | 22 | void interrupt_table__copy(struct interrupt_table *itable, void *dst, unsigned int size); 23 | void interrupt_table__setup(struct interrupt_table *itable, struct real_intr_desc *entry); 24 | void interrupt_table__set(struct interrupt_table *itable, struct real_intr_desc *entry, unsigned int num); 25 | 26 | #endif /* KVM__INTERRUPT_H */ 27 | -------------------------------------------------------------------------------- /x86/include/kvm/kvm-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_ARCH_H 2 | #define KVM__KVM_ARCH_H 3 | 4 | #include "kvm/interrupt.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /* 11 | * The hole includes VESA framebuffer and PCI memory. 12 | */ 13 | #define KVM_32BIT_MAX_MEM_SIZE (1ULL << 32) 14 | #define KVM_32BIT_GAP_SIZE (768 << 20) 15 | #define KVM_32BIT_GAP_START (KVM_32BIT_MAX_MEM_SIZE - KVM_32BIT_GAP_SIZE) 16 | 17 | #define KVM_MMIO_START KVM_32BIT_GAP_START 18 | 19 | /* This is the address that pci_get_io_space_block() starts allocating 20 | * from. Note that this is a PCI bus address (though same on x86). 21 | */ 22 | #define KVM_IOPORT_AREA 0x0 23 | #define KVM_PCI_CFG_AREA (KVM_MMIO_START + 0x1000000) 24 | #define KVM_PCI_MMIO_AREA (KVM_MMIO_START + 0x2000000) 25 | #define KVM_VIRTIO_MMIO_AREA (KVM_MMIO_START + 0x3000000) 26 | 27 | #define KVM_IRQ_OFFSET 5 28 | 29 | #define KVM_VM_TYPE 0 30 | 31 | #define VIRTIO_DEFAULT_TRANS(kvm) VIRTIO_PCI 32 | 33 | struct kvm_arch { 34 | u16 boot_selector; 35 | u64 boot_ip; 36 | u64 boot_sp; 37 | u64 boot_si; 38 | 39 | bool boot_protected; 40 | bool boot_64; 41 | 42 | struct interrupt_table interrupt_table; 43 | }; 44 | 45 | #endif /* KVM__KVM_ARCH_H */ 46 | -------------------------------------------------------------------------------- /x86/include/kvm/kvm-config-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CONFIG_ARCH_H 2 | #define KVM__KVM_CONFIG_ARCH_H 3 | 4 | #include "kvm/parse-options.h" 5 | 6 | struct kvm_config_arch { 7 | int vidmode; 8 | }; 9 | 10 | #define OPT_ARCH_RUN(pfx, cfg) \ 11 | pfx, \ 12 | OPT_GROUP("BIOS options:"), \ 13 | OPT_INTEGER('\0', "vidmode", &(cfg)->vidmode, "Video mode"), 14 | 15 | #endif /* KVM__KVM_CONFIG_ARCH_H */ 16 | -------------------------------------------------------------------------------- /x86/include/kvm/kvm-cpu-arch.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM__KVM_CPU_ARCH_H 2 | #define KVM__KVM_CPU_ARCH_H 3 | 4 | /* Architecture-specific kvm_cpu definitions. */ 5 | 6 | #include /* for struct kvm_regs */ 7 | #include "kvm/kvm.h" /* for kvm__emulate_{mm}io() */ 8 | #include 9 | #include 10 | 11 | struct kvm; 12 | 13 | struct kvm_cpu { 14 | pthread_t thread; /* VCPU thread */ 15 | 16 | unsigned long cpu_id; 17 | 18 | struct kvm *kvm; /* parent KVM */ 19 | int vcpu_fd; /* For VCPU ioctls() */ 20 | struct kvm_run *kvm_run; 21 | 22 | struct kvm_regs regs; 23 | struct kvm_sregs sregs; 24 | struct kvm_fpu fpu; 25 | 26 | struct kvm_msrs *msrs; /* dynamically allocated */ 27 | 28 | u8 is_running; 29 | u8 paused; 30 | u8 needs_nmi; 31 | 32 | struct kvm_coalesced_mmio_ring *ring; 33 | }; 34 | 35 | /* 36 | * As these are such simple wrappers, let's have them in the header so they'll 37 | * be cheaper to call: 38 | */ 39 | static inline bool kvm_cpu__emulate_io(struct kvm_cpu *vcpu, u16 port, void *data, int direction, int size, u32 count) 40 | { 41 | return kvm__emulate_io(vcpu, port, data, direction, size, count); 42 | } 43 | 44 | static inline bool kvm_cpu__emulate_mmio(struct kvm_cpu *vcpu, u64 phys_addr, u8 *data, u32 len, u8 is_write) 45 | { 46 | return kvm__emulate_mmio(vcpu, phys_addr, data, len, is_write); 47 | } 48 | 49 | #endif /* KVM__KVM_CPU_ARCH_H */ 50 | -------------------------------------------------------------------------------- /x86/include/kvm/mptable.h: -------------------------------------------------------------------------------- 1 | #ifndef KVM_MPTABLE_H_ 2 | #define KVM_MPTABLE_H_ 3 | 4 | struct kvm; 5 | 6 | int mptable__init(struct kvm *kvm); 7 | int mptable__exit(struct kvm *kvm); 8 | 9 | #endif /* KVM_MPTABLE_H_ */ 10 | -------------------------------------------------------------------------------- /x86/init.S: -------------------------------------------------------------------------------- 1 | .data 2 | 3 | .m_dev: 4 | .string "hostfs" 5 | .m_dir: 6 | .string "/host" 7 | .m_typ: 8 | .string "9p" 9 | .m_opt: 10 | .string "trans=virtio,version=9p2000.L" 11 | 12 | .e_nam: 13 | .string "/virt/init" 14 | 15 | .text 16 | .globl _start 17 | _start: 18 | 19 | mov $165, %rax # __NR_mount 20 | mov $.m_dev, %rdi 21 | mov $.m_dir, %rsi 22 | mov $.m_typ, %rdx 23 | mov $1, %r10 # MS_RDONLY 24 | mov $.m_opt, %r8 25 | syscall 26 | 27 | mov $59, %rax # __NR_execve 28 | mov $.e_nam, %rdi 29 | lea 8(%rsp), %rsi # argv[] 30 | mov %rdi, (%rsi) # change argv[0] 31 | pop %rcx # argc 32 | inc %rcx 33 | lea (%rsi,%rcx,8), %rdx # envp[] 34 | syscall 35 | 36 | mov $60, %rax # __NR_exit 37 | mov $1, %rdi 38 | syscall # panic 39 | -------------------------------------------------------------------------------- /x86/interrupt.c: -------------------------------------------------------------------------------- 1 | #include "kvm/interrupt.h" 2 | 3 | #include "kvm/util.h" 4 | 5 | #include 6 | 7 | void interrupt_table__copy(struct interrupt_table *itable, void *dst, unsigned int size) 8 | { 9 | if (size < sizeof(itable->entries)) 10 | die("An attempt to overwrite host memory"); 11 | 12 | memcpy(dst, itable->entries, sizeof(itable->entries)); 13 | } 14 | 15 | void interrupt_table__setup(struct interrupt_table *itable, struct real_intr_desc *entry) 16 | { 17 | unsigned int i; 18 | 19 | for (i = 0; i < REAL_INTR_VECTORS; i++) 20 | itable->entries[i] = *entry; 21 | } 22 | 23 | void interrupt_table__set(struct interrupt_table *itable, 24 | struct real_intr_desc *entry, unsigned int num) 25 | { 26 | if (num < REAL_INTR_VECTORS) 27 | itable->entries[num] = *entry; 28 | } 29 | -------------------------------------------------------------------------------- /x86/irq.c: -------------------------------------------------------------------------------- 1 | #include "kvm/irq.h" 2 | #include "kvm/kvm.h" 3 | #include "kvm/util.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #define IRQ_MAX_GSI 64 15 | #define IRQCHIP_MASTER 0 16 | #define IRQCHIP_SLAVE 1 17 | #define IRQCHIP_IOAPIC 2 18 | 19 | /* First 24 GSIs are routed between IRQCHIPs and IOAPICs */ 20 | static u32 gsi = 24; 21 | 22 | struct kvm_irq_routing *irq_routing; 23 | 24 | static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin) 25 | { 26 | if (gsi >= IRQ_MAX_GSI) 27 | return -ENOSPC; 28 | 29 | irq_routing->entries[irq_routing->nr++] = 30 | (struct kvm_irq_routing_entry) { 31 | .gsi = gsi, 32 | .type = type, 33 | .u.irqchip.irqchip = irqchip, 34 | .u.irqchip.pin = pin, 35 | }; 36 | 37 | return 0; 38 | } 39 | 40 | int irq__init(struct kvm *kvm) 41 | { 42 | int i, r; 43 | 44 | irq_routing = calloc(sizeof(struct kvm_irq_routing) + 45 | IRQ_MAX_GSI * sizeof(struct kvm_irq_routing_entry), 1); 46 | if (irq_routing == NULL) 47 | return -ENOMEM; 48 | 49 | /* Hook first 8 GSIs to master IRQCHIP */ 50 | for (i = 0; i < 8; i++) 51 | if (i != 2) 52 | irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_MASTER, i); 53 | 54 | /* Hook next 8 GSIs to slave IRQCHIP */ 55 | for (i = 8; i < 16; i++) 56 | irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_SLAVE, i - 8); 57 | 58 | /* Last but not least, IOAPIC */ 59 | for (i = 0; i < 24; i++) { 60 | if (i == 0) 61 | irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, 2); 62 | else if (i != 2) 63 | irq__add_routing(i, KVM_IRQ_ROUTING_IRQCHIP, IRQCHIP_IOAPIC, i); 64 | } 65 | 66 | r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing); 67 | if (r) { 68 | free(irq_routing); 69 | return errno; 70 | } 71 | 72 | return 0; 73 | } 74 | dev_base_init(irq__init); 75 | 76 | int irq__exit(struct kvm *kvm) 77 | { 78 | free(irq_routing); 79 | return 0; 80 | } 81 | dev_base_exit(irq__exit); 82 | 83 | int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg) 84 | { 85 | int r; 86 | 87 | irq_routing->entries[irq_routing->nr++] = 88 | (struct kvm_irq_routing_entry) { 89 | .gsi = gsi, 90 | .type = KVM_IRQ_ROUTING_MSI, 91 | .u.msi.address_hi = msg->address_hi, 92 | .u.msi.address_lo = msg->address_lo, 93 | .u.msi.data = msg->data, 94 | }; 95 | 96 | r = ioctl(kvm->vm_fd, KVM_SET_GSI_ROUTING, irq_routing); 97 | if (r) 98 | return r; 99 | 100 | return gsi++; 101 | } 102 | --------------------------------------------------------------------------------