1 #include "kvm/kvm.h"
2 #include "kvm/util.h"
3 #include "kvm/8250-serial.h"
4 #include "kvm/virtio-console.h"
5 #include "kvm/fdt.h"
6
7 #include <linux/kernel.h>
8 #include <linux/kvm.h>
9 #include <linux/sizes.h>
10
11 struct kvm_ext kvm_req_ext[] = {
12 { DEFINE_KVM_EXT(KVM_CAP_ONE_REG) },
13 { 0, 0 },
14 };
15
kvm__arch_default_ram_address(void)16 u64 kvm__arch_default_ram_address(void)
17 {
18 return RISCV_RAM;
19 }
20
kvm__arch_validate_cfg(struct kvm * kvm)21 void kvm__arch_validate_cfg(struct kvm *kvm)
22 {
23 }
24
kvm__arch_cpu_supports_vm(void)25 bool kvm__arch_cpu_supports_vm(void)
26 {
27 /* The KVM capability check is enough. */
28 return true;
29 }
30
kvm__init_ram(struct kvm * kvm)31 void kvm__init_ram(struct kvm *kvm)
32 {
33 int err;
34 u64 phys_start, phys_size;
35 void *host_mem;
36
37 phys_start = RISCV_RAM;
38 phys_size = kvm->ram_size;
39 host_mem = kvm->ram_start;
40
41 err = kvm__register_ram(kvm, phys_start, phys_size, host_mem);
42 if (err)
43 die("Failed to register %lld bytes of memory at physical "
44 "address 0x%llx [err %d]", phys_size, phys_start, err);
45
46 kvm->arch.memory_guest_start = phys_start;
47 }
48
kvm__arch_delete_ram(struct kvm * kvm)49 void kvm__arch_delete_ram(struct kvm *kvm)
50 {
51 munmap(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size);
52 }
53
kvm__arch_read_term(struct kvm * kvm)54 void kvm__arch_read_term(struct kvm *kvm)
55 {
56 serial8250__update_consoles(kvm);
57 virtio_console__inject_interrupt(kvm);
58 }
59
kvm__arch_set_cmdline(char * cmdline,bool video)60 void kvm__arch_set_cmdline(char *cmdline, bool video)
61 {
62 }
63
64 #if __riscv_xlen == 64
65 #define HUGEPAGE_SIZE SZ_2M
66 #else
67 #define HUGEPAGE_SIZE SZ_4M
68 #endif
69
kvm__arch_init(struct kvm * kvm)70 void kvm__arch_init(struct kvm *kvm)
71 {
72 /*
73 * Allocate guest memory. We must align our buffer to 64K to
74 * correlate with the maximum guest page size for virtio-mmio.
75 * If using THP, then our minimal alignment becomes hugepage
76 * size. The hugepage size is always greater than 64K, so
77 * let's go with that.
78 */
79 kvm->ram_size = min(kvm->cfg.ram_size, (u64)RISCV_MAX_MEMORY(kvm));
80 kvm->arch.ram_alloc_size = kvm->ram_size;
81 if (!kvm->cfg.hugetlbfs_path)
82 kvm->arch.ram_alloc_size += HUGEPAGE_SIZE;
83 kvm->arch.ram_alloc_start = mmap_anon_or_hugetlbfs(kvm,
84 kvm->cfg.hugetlbfs_path,
85 kvm->arch.ram_alloc_size);
86
87 if (kvm->arch.ram_alloc_start == MAP_FAILED)
88 die("Failed to map %lld bytes for guest memory (%d)",
89 kvm->arch.ram_alloc_size, errno);
90
91 kvm->ram_start = (void *)ALIGN((unsigned long)kvm->arch.ram_alloc_start,
92 SZ_2M);
93
94 madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
95 MADV_MERGEABLE);
96
97 madvise(kvm->arch.ram_alloc_start, kvm->arch.ram_alloc_size,
98 MADV_HUGEPAGE);
99
100 riscv__irqchip_create(kvm);
101 }
102
103 #define FDT_ALIGN SZ_4M
104 #define INITRD_ALIGN 8
kvm__arch_load_kernel_image(struct kvm * kvm,int fd_kernel,int fd_initrd,const char * kernel_cmdline)105 bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
106 const char *kernel_cmdline)
107 {
108 void *pos, *kernel_end, *limit;
109 unsigned long guest_addr, kernel_offset;
110 ssize_t file_size;
111
112 /*
113 * Linux requires the initrd and dtb to be mapped inside lowmem,
114 * so we can't just place them at the top of memory.
115 */
116 limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1;
117
118 #if __riscv_xlen == 64
119 /* Linux expects to be booted at 2M boundary for RV64 */
120 kernel_offset = 0x200000;
121 #else
122 /* Linux expects to be booted at 4M boundary for RV32 */
123 kernel_offset = 0x400000;
124 #endif
125
126 pos = kvm->ram_start + kernel_offset;
127 kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos);
128 file_size = read_file(fd_kernel, pos, limit - pos);
129 if (file_size < 0) {
130 if (errno == ENOMEM)
131 die("kernel image too big to fit in guest memory.");
132
133 die_perror("kernel read");
134 }
135 kernel_end = pos + file_size;
136 pr_debug("Loaded kernel to 0x%llx (%zd bytes)",
137 kvm->arch.kern_guest_start, file_size);
138
139 /* Place FDT just after kernel at FDT_ALIGN address */
140 pos = kernel_end + FDT_ALIGN;
141 guest_addr = ALIGN(host_to_guest_flat(kvm, pos), FDT_ALIGN);
142 pos = guest_flat_to_host(kvm, guest_addr);
143 if (pos < kernel_end)
144 die("fdt overlaps with kernel image.");
145
146 kvm->arch.dtb_guest_start = guest_addr;
147 pr_debug("Placing fdt at 0x%llx - 0x%llx",
148 kvm->arch.dtb_guest_start,
149 host_to_guest_flat(kvm, limit));
150
151 /* ... and finally the initrd, if we have one. */
152 if (fd_initrd != -1) {
153 struct stat sb;
154 unsigned long initrd_start;
155
156 if (fstat(fd_initrd, &sb))
157 die_perror("fstat");
158
159 pos = limit - (sb.st_size + INITRD_ALIGN);
160 guest_addr = ALIGN(host_to_guest_flat(kvm, pos), INITRD_ALIGN);
161 pos = guest_flat_to_host(kvm, guest_addr);
162 if (pos < kernel_end)
163 die("initrd overlaps with kernel image.");
164
165 initrd_start = guest_addr;
166 file_size = read_file(fd_initrd, pos, limit - pos);
167 if (file_size == -1) {
168 if (errno == ENOMEM)
169 die("initrd too big to fit in guest memory.");
170
171 die_perror("initrd read");
172 }
173
174 kvm->arch.initrd_guest_start = initrd_start;
175 kvm->arch.initrd_size = file_size;
176 pr_debug("Loaded initrd to 0x%llx (%llu bytes)",
177 kvm->arch.initrd_guest_start,
178 kvm->arch.initrd_size);
179 } else {
180 kvm->arch.initrd_size = 0;
181 }
182
183 return true;
184 }
185
kvm__load_firmware(struct kvm * kvm,const char * firmware_filename)186 bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
187 {
188 /* TODO: Firmware loading to be supported later. */
189 return false;
190 }
191
kvm__arch_setup_firmware(struct kvm * kvm)192 int kvm__arch_setup_firmware(struct kvm *kvm)
193 {
194 return 0;
195 }
196