Skip to content

Commit d734360

Browse files
committed
add Qemu patches
Signed-off-by: Wojciech Ozga <woz@zurich.ibm.com>
1 parent e94b4be commit d734360

1 file changed

Lines changed: 256 additions & 0 deletions

File tree

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
2+
index b472301637..c39c09b16b 100644
3+
--- a/accel/kvm/kvm-all.c
4+
+++ b/accel/kvm/kvm-all.c
5+
@@ -2527,6 +2527,13 @@ static int kvm_init(MachineState *ms)
6+
type = kvm_arch_get_default_type(ms);
7+
}
8+
9+
+ if (object_property_find(OBJECT(current_machine), "cove")) {
10+
+ if (object_property_get_bool(OBJECT(current_machine), "cove", &error_abort)) {
11+
+ type = 1UL << 10;
12+
+ warn_report("Creating CoVE TVM");
13+
+ }
14+
+ }
15+
+
16+
do {
17+
ret = kvm_ioctl(s, KVM_CREATE_VM, type);
18+
} while (ret == -EINTR);
19+
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
20+
index 52bf8e67de..7f4550bbf1 100644
21+
--- a/hw/riscv/boot.c
22+
+++ b/hw/riscv/boot.c
23+
@@ -16,7 +16,7 @@
24+
* You should have received a copy of the GNU General Public License along with
25+
* this program. If not, see <http://www.gnu.org/licenses/>.
26+
*/
27+
-
28+
+#include <linux/kvm.h>
29+
#include "qemu/osdep.h"
30+
#include "qemu/datadir.h"
31+
#include "qemu/units.h"
32+
@@ -205,6 +205,18 @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
33+
}
34+
}
35+
36+
+ #if defined(CONFIG_KVM)
37+
+ struct kvm_riscv_cove_measure_region mr = {
38+
+ .user_addr = 0,
39+
+ .gpa = start,
40+
+ .size = size,
41+
+ .type = KVM_RISCV_COVE_REGION_INITRD,
42+
+ };
43+
+ warn_report("Register initrd region %lx %ld", start, size);
44+
+ KVMState *s = KVM_STATE(machine->accelerator);
45+
+ kvm_vm_ioctl(s, KVM_RISCV_COVE_MEASURE_REGION, &mr);
46+
+ #endif
47+
+
48+
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
49+
if (fdt) {
50+
end = start + size;
51+
@@ -222,6 +234,7 @@ target_ulong riscv_load_kernel(MachineState *machine,
52+
const char *kernel_filename = machine->kernel_filename;
53+
uint64_t kernel_load_base, kernel_entry;
54+
void *fdt = machine->fdt;
55+
+ ssize_t kernel_size;
56+
57+
g_assert(kernel_filename != NULL);
58+
59+
@@ -232,20 +245,23 @@ target_ulong riscv_load_kernel(MachineState *machine,
60+
* the (expected) load address load address. This allows kernels to have
61+
* separate SBI and ELF entry points (used by FreeBSD, for example).
62+
*/
63+
- if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
64+
+ kernel_size = load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
65+
NULL, &kernel_load_base, NULL, NULL, 0,
66+
- EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
67+
+ EM_RISCV, 1, 0, NULL, true, sym_cb) > 0;
68+
+ if (kernel_size > 0) {
69+
kernel_entry = kernel_load_base;
70+
goto out;
71+
}
72+
73+
- if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
74+
- NULL, NULL, NULL) > 0) {
75+
+ kernel_size = load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
76+
+ NULL, NULL, NULL);
77+
+ if (kernel_size > 0) {
78+
goto out;
79+
}
80+
81+
- if (load_image_targphys_as(kernel_filename, kernel_start_addr,
82+
- current_machine->ram_size, NULL) > 0) {
83+
+ kernel_size = load_image_targphys_as(kernel_filename, kernel_start_addr,
84+
+ current_machine->ram_size, NULL);
85+
+ if (kernel_size > 0) {
86+
kernel_entry = kernel_start_addr;
87+
goto out;
88+
}
89+
@@ -262,6 +278,35 @@ out:
90+
kernel_entry = extract64(kernel_entry, 0, 32);
91+
}
92+
93+
+ #if defined(CONFIG_KVM)
94+
+ struct kvm_riscv_cove_measure_region mr = {
95+
+ .user_addr = 0,
96+
+ .gpa = kernel_entry,
97+
+ .size = kernel_size,
98+
+ .type = KVM_RISCV_COVE_REGION_KERNEL,
99+
+ };
100+
+ warn_report("Register kernel region %lx %ld", kernel_entry, kernel_size);
101+
+ KVMState *s = KVM_STATE(machine->accelerator);
102+
+ kvm_vm_ioctl(s, KVM_RISCV_COVE_MEASURE_REGION, &mr);
103+
+
104+
+ if (object_property_find(OBJECT(current_machine), "cove-tap-filename")) {
105+
+ const char * tap_filename = object_property_get_str(OBJECT(current_machine), "cove-tap-filename", NULL);
106+
+ hwaddr tap_addr = (kernel_entry+kernel_size);
107+
+ tap_addr = ((4096-1) & tap_addr) ? ((tap_addr+4096) & ~(4096-1)) : tap_addr;
108+
+ error_report("Loading CoVE TAP %s %lx", tap_filename, tap_addr);
109+
+ if (load_image_targphys(tap_filename, tap_addr, 4096) <= 0) {
110+
+ error_report("Loading CoVE TAP failed");
111+
+ }
112+
+ struct kvm_riscv_cove_measure_region mr = {
113+
+ .user_addr = 0,
114+
+ .gpa = tap_addr,
115+
+ .size = 4096,
116+
+ .type = KVM_RISCV_COVE_REGION_COVE_TAP,
117+
+ };
118+
+ kvm_vm_ioctl(KVM_STATE(machine->accelerator), KVM_RISCV_COVE_MEASURE_REGION, &mr);
119+
+ }
120+
+ #endif
121+
+
122+
if (load_initrd && machine->initrd_filename) {
123+
riscv_load_initrd(machine, kernel_entry);
124+
}
125+
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
126+
index 505a36dff6..40a41eb9ee 100644
127+
--- a/hw/riscv/virt.c
128+
+++ b/hw/riscv/virt.c
129+
@@ -17,7 +17,8 @@
130+
* You should have received a copy of the GNU General Public License along with
131+
* this program. If not, see <http://www.gnu.org/licenses/>.
132+
*/
133+
-
134+
+#include <linux/kvm.h>
135+
+#include <libfdt.h>
136+
#include "qemu/osdep.h"
137+
#include "qemu/units.h"
138+
#include "qemu/error-report.h"
139+
@@ -1312,6 +1313,17 @@ static void virt_machine_done(Notifier *notifier, void *data)
140+
machine);
141+
riscv_load_fdt(fdt_load_addr, machine->fdt);
142+
143+
+ #if defined(CONFIG_KVM)
144+
+ uint32_t fdtsize = fdt_totalsize(machine->fdt);
145+
+ struct kvm_riscv_cove_measure_region mr = {
146+
+ .user_addr = 0,
147+
+ .gpa = fdt_load_addr,
148+
+ .size = fdtsize,
149+
+ .type = KVM_RISCV_COVE_REGION_FDT,
150+
+ };
151+
+ kvm_vm_ioctl(KVM_STATE(machine->accelerator), KVM_RISCV_COVE_MEASURE_REGION, &mr);
152+
+ #endif
153+
+
154+
/* load the reset vector */
155+
riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
156+
virt_memmap[VIRT_MROM].base,
157+
@@ -1330,6 +1342,12 @@ static void virt_machine_done(Notifier *notifier, void *data)
158+
if (virt_is_acpi_enabled(s)) {
159+
virt_acpi_setup(s);
160+
}
161+
+
162+
+ #if defined(CONFIG_KVM)
163+
+ struct kvm_riscv_cove_vm_finalize finalize = {
164+
+ };
165+
+ kvm_vm_ioctl(KVM_STATE(machine->accelerator), KVM_RISCV_COVE_VM_FINALIZE, &finalize);
166+
+ #endif
167+
}
168+
169+
static void virt_machine_init(MachineState *machine)
170+
@@ -1540,6 +1558,33 @@ static void virt_machine_instance_init(Object *obj)
171+
s->acpi = ON_OFF_AUTO_AUTO;
172+
}
173+
174+
+static bool virt_get_cove(Object *obj, Error **errp)
175+
+{
176+
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
177+
+
178+
+ return s->cove;
179+
+}
180+
+
181+
+static void virt_set_cove(Object *obj, bool value, Error **errp)
182+
+{
183+
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
184+
+
185+
+ s->cove = value;
186+
+}
187+
+
188+
+static char *virt_get_cove_tap_filename(Object *obj, Error **errp)
189+
+{
190+
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
191+
+ return g_strdup(s->cove_tap_filename);
192+
+}
193+
+
194+
+static void virt_set_cove_tap_filename(Object *obj, const char *val, Error **errp)
195+
+{
196+
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
197+
+ g_free(s->cove_tap_filename);
198+
+ s->cove_tap_filename = g_strdup(val);
199+
+}
200+
+
201+
static char *virt_get_aia_guests(Object *obj, Error **errp)
202+
{
203+
RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
204+
@@ -1714,6 +1759,10 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
205+
NULL, NULL);
206+
object_class_property_set_description(oc, "acpi",
207+
"Enable ACPI");
208+
+ object_class_property_add_bool(oc, "cove", virt_get_cove,
209+
+ virt_set_cove);
210+
+ object_class_property_add_str(oc, "cove-tap-filename", virt_get_cove_tap_filename,
211+
+ virt_set_cove_tap_filename);
212+
}
213+
214+
static const TypeInfo virt_machine_typeinfo = {
215+
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
216+
index e5c474b26e..c01e733b34 100644
217+
--- a/include/hw/riscv/virt.h
218+
+++ b/include/hw/riscv/virt.h
219+
@@ -60,6 +60,8 @@ struct RISCVVirtState {
220+
char *oem_table_id;
221+
OnOffAuto acpi;
222+
const MemMapEntry *memmap;
223+
+ bool cove;
224+
+ char *cove_tap_filename;
225+
};
226+
227+
enum {
228+
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
229+
index 1f3f3333a4..9dc12996ef 100644
230+
--- a/linux-headers/linux/kvm.h
231+
+++ b/linux-headers/linux/kvm.h
232+
@@ -2245,4 +2245,24 @@ struct kvm_s390_zpci_op {
233+
/* flags for kvm_s390_zpci_op->u.reg_aen.flags */
234+
#define KVM_S390_ZPCIOP_REGAEN_HOST (1 << 0)
235+
236+
+enum KVM_RISCV_COVE_REGION {
237+
+ KVM_RISCV_COVE_REGION_FIRMWARE = 0,
238+
+ KVM_RISCV_COVE_REGION_KERNEL,
239+
+ KVM_RISCV_COVE_REGION_FDT,
240+
+ KVM_RISCV_COVE_REGION_INITRD,
241+
+ KVM_RISCV_COVE_REGION_COVE_TAP,
242+
+};
243+
+
244+
+struct kvm_riscv_cove_measure_region {
245+
+ unsigned long user_addr;
246+
+ unsigned long gpa;
247+
+ unsigned long size;
248+
+ enum KVM_RISCV_COVE_REGION type;
249+
+};
250+
+
251+
+struct kvm_riscv_cove_vm_finalize {};
252+
+
253+
+#define KVM_RISCV_COVE_MEASURE_REGION _IOR(KVMIO, 0xb6, struct kvm_riscv_cove_measure_region)
254+
+#define KVM_RISCV_COVE_VM_FINALIZE _IOR(KVMIO, 0xb7, struct kvm_riscv_cove_vm_finalize)
255+
+
256+
#endif /* __LINUX_KVM_H */

0 commit comments

Comments
 (0)