diff options
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/firmware/qemu_fw_cfg.c | 291 | ||||
-rw-r--r-- | drivers/vhost/vhost.c | 2 | ||||
-rw-r--r-- | drivers/vhost/vhost.h | 4 | ||||
-rw-r--r-- | drivers/vhost/vsock.c | 11 | ||||
-rw-r--r-- | include/uapi/linux/qemu_fw_cfg.h | 97 | ||||
-rw-r--r-- | kernel/crash_core.c | 1 | ||||
-rw-r--r-- | tools/virtio/ringtest/ptr_ring.c | 5 |
8 files changed, 348 insertions, 64 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 5e929acb5a82..83f5a6fd7de3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -11464,6 +11464,7 @@ M: "Michael S. Tsirkin" <mst@redhat.com> | |||
11464 | L: qemu-devel@nongnu.org | 11464 | L: qemu-devel@nongnu.org |
11465 | S: Maintained | 11465 | S: Maintained |
11466 | F: drivers/firmware/qemu_fw_cfg.c | 11466 | F: drivers/firmware/qemu_fw_cfg.c |
11467 | F: include/uapi/linux/qemu_fw_cfg.h | ||
11467 | 11468 | ||
11468 | QIB DRIVER | 11469 | QIB DRIVER |
11469 | M: Dennis Dalessandro <dennis.dalessandro@intel.com> | 11470 | M: Dennis Dalessandro <dennis.dalessandro@intel.com> |
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index a41b572eeeb1..14fedbeca724 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c | |||
@@ -10,20 +10,21 @@ | |||
10 | * and select subsets of aarch64), a Device Tree node (on arm), or using | 10 | * and select subsets of aarch64), a Device Tree node (on arm), or using |
11 | * a kernel module (or command line) parameter with the following syntax: | 11 | * a kernel module (or command line) parameter with the following syntax: |
12 | * | 12 | * |
13 | * [qemu_fw_cfg.]ioport=<size>@<base>[:<ctrl_off>:<data_off>] | 13 | * [qemu_fw_cfg.]ioport=<size>@<base>[:<ctrl_off>:<data_off>[:<dma_off>]] |
14 | * or | 14 | * or |
15 | * [qemu_fw_cfg.]mmio=<size>@<base>[:<ctrl_off>:<data_off>] | 15 | * [qemu_fw_cfg.]mmio=<size>@<base>[:<ctrl_off>:<data_off>[:<dma_off>]] |
16 | * | 16 | * |
17 | * where: | 17 | * where: |
18 | * <size> := size of ioport or mmio range | 18 | * <size> := size of ioport or mmio range |
19 | * <base> := physical base address of ioport or mmio range | 19 | * <base> := physical base address of ioport or mmio range |
20 | * <ctrl_off> := (optional) offset of control register | 20 | * <ctrl_off> := (optional) offset of control register |
21 | * <data_off> := (optional) offset of data register | 21 | * <data_off> := (optional) offset of data register |
22 | * <dma_off> := (optional) offset of dma register | ||
22 | * | 23 | * |
23 | * e.g.: | 24 | * e.g.: |
24 | * qemu_fw_cfg.ioport=2@0x510:0:1 (the default on x86) | 25 | * qemu_fw_cfg.ioport=12@0x510:0:1:4 (the default on x86) |
25 | * or | 26 | * or |
26 | * qemu_fw_cfg.mmio=0xA@0x9020000:8:0 (the default on arm) | 27 | * qemu_fw_cfg.mmio=16@0x9020000:8:0:16 (the default on arm) |
27 | */ | 28 | */ |
28 | 29 | ||
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
@@ -32,29 +33,17 @@ | |||
32 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
33 | #include <linux/io.h> | 34 | #include <linux/io.h> |
34 | #include <linux/ioport.h> | 35 | #include <linux/ioport.h> |
36 | #include <uapi/linux/qemu_fw_cfg.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/crash_dump.h> | ||
39 | #include <linux/crash_core.h> | ||
35 | 40 | ||
36 | MODULE_AUTHOR("Gabriel L. Somlo <somlo@cmu.edu>"); | 41 | MODULE_AUTHOR("Gabriel L. Somlo <somlo@cmu.edu>"); |
37 | MODULE_DESCRIPTION("QEMU fw_cfg sysfs support"); | 42 | MODULE_DESCRIPTION("QEMU fw_cfg sysfs support"); |
38 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
39 | 44 | ||
40 | /* selector key values for "well-known" fw_cfg entries */ | 45 | /* fw_cfg revision attribute, in /sys/firmware/qemu_fw_cfg top-level dir. */ |
41 | #define FW_CFG_SIGNATURE 0x00 | 46 | static u32 fw_cfg_rev; |
42 | #define FW_CFG_ID 0x01 | ||
43 | #define FW_CFG_FILE_DIR 0x19 | ||
44 | |||
45 | /* size in bytes of fw_cfg signature */ | ||
46 | #define FW_CFG_SIG_SIZE 4 | ||
47 | |||
48 | /* fw_cfg "file name" is up to 56 characters (including terminating nul) */ | ||
49 | #define FW_CFG_MAX_FILE_PATH 56 | ||
50 | |||
51 | /* fw_cfg file directory entry type */ | ||
52 | struct fw_cfg_file { | ||
53 | u32 size; | ||
54 | u16 select; | ||
55 | u16 reserved; | ||
56 | char name[FW_CFG_MAX_FILE_PATH]; | ||
57 | }; | ||
58 | 47 | ||
59 | /* fw_cfg device i/o register addresses */ | 48 | /* fw_cfg device i/o register addresses */ |
60 | static bool fw_cfg_is_mmio; | 49 | static bool fw_cfg_is_mmio; |
@@ -63,19 +52,83 @@ static resource_size_t fw_cfg_p_size; | |||
63 | static void __iomem *fw_cfg_dev_base; | 52 | static void __iomem *fw_cfg_dev_base; |
64 | static void __iomem *fw_cfg_reg_ctrl; | 53 | static void __iomem *fw_cfg_reg_ctrl; |
65 | static void __iomem *fw_cfg_reg_data; | 54 | static void __iomem *fw_cfg_reg_data; |
55 | static void __iomem *fw_cfg_reg_dma; | ||
66 | 56 | ||
67 | /* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */ | 57 | /* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */ |
68 | static DEFINE_MUTEX(fw_cfg_dev_lock); | 58 | static DEFINE_MUTEX(fw_cfg_dev_lock); |
69 | 59 | ||
70 | /* pick appropriate endianness for selector key */ | 60 | /* pick appropriate endianness for selector key */ |
71 | static inline u16 fw_cfg_sel_endianness(u16 key) | 61 | static void fw_cfg_sel_endianness(u16 key) |
62 | { | ||
63 | if (fw_cfg_is_mmio) | ||
64 | iowrite16be(key, fw_cfg_reg_ctrl); | ||
65 | else | ||
66 | iowrite16(key, fw_cfg_reg_ctrl); | ||
67 | } | ||
68 | |||
69 | #ifdef CONFIG_CRASH_CORE | ||
70 | static inline bool fw_cfg_dma_enabled(void) | ||
71 | { | ||
72 | return (fw_cfg_rev & FW_CFG_VERSION_DMA) && fw_cfg_reg_dma; | ||
73 | } | ||
74 | |||
75 | /* qemu fw_cfg device is sync today, but spec says it may become async */ | ||
76 | static void fw_cfg_wait_for_control(struct fw_cfg_dma_access *d) | ||
72 | { | 77 | { |
73 | return fw_cfg_is_mmio ? cpu_to_be16(key) : cpu_to_le16(key); | 78 | for (;;) { |
79 | u32 ctrl = be32_to_cpu(READ_ONCE(d->control)); | ||
80 | |||
81 | /* do not reorder the read to d->control */ | ||
82 | rmb(); | ||
83 | if ((ctrl & ~FW_CFG_DMA_CTL_ERROR) == 0) | ||
84 | return; | ||
85 | |||
86 | cpu_relax(); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static ssize_t fw_cfg_dma_transfer(void *address, u32 length, u32 control) | ||
91 | { | ||
92 | phys_addr_t dma; | ||
93 | struct fw_cfg_dma_access *d = NULL; | ||
94 | ssize_t ret = length; | ||
95 | |||
96 | d = kmalloc(sizeof(*d), GFP_KERNEL); | ||
97 | if (!d) { | ||
98 | ret = -ENOMEM; | ||
99 | goto end; | ||
100 | } | ||
101 | |||
102 | /* fw_cfg device does not need IOMMU protection, so use physical addresses */ | ||
103 | *d = (struct fw_cfg_dma_access) { | ||
104 | .address = cpu_to_be64(address ? virt_to_phys(address) : 0), | ||
105 | .length = cpu_to_be32(length), | ||
106 | .control = cpu_to_be32(control) | ||
107 | }; | ||
108 | |||
109 | dma = virt_to_phys(d); | ||
110 | |||
111 | iowrite32be((u64)dma >> 32, fw_cfg_reg_dma); | ||
112 | /* force memory to sync before notifying device via MMIO */ | ||
113 | wmb(); | ||
114 | iowrite32be(dma, fw_cfg_reg_dma + 4); | ||
115 | |||
116 | fw_cfg_wait_for_control(d); | ||
117 | |||
118 | if (be32_to_cpu(READ_ONCE(d->control)) & FW_CFG_DMA_CTL_ERROR) { | ||
119 | ret = -EIO; | ||
120 | } | ||
121 | |||
122 | end: | ||
123 | kfree(d); | ||
124 | |||
125 | return ret; | ||
74 | } | 126 | } |
127 | #endif | ||
75 | 128 | ||
76 | /* read chunk of given fw_cfg blob (caller responsible for sanity-check) */ | 129 | /* read chunk of given fw_cfg blob (caller responsible for sanity-check) */ |
77 | static inline void fw_cfg_read_blob(u16 key, | 130 | static ssize_t fw_cfg_read_blob(u16 key, |
78 | void *buf, loff_t pos, size_t count) | 131 | void *buf, loff_t pos, size_t count) |
79 | { | 132 | { |
80 | u32 glk = -1U; | 133 | u32 glk = -1U; |
81 | acpi_status status; | 134 | acpi_status status; |
@@ -88,18 +141,60 @@ static inline void fw_cfg_read_blob(u16 key, | |||
88 | /* Should never get here */ | 141 | /* Should never get here */ |
89 | WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n"); | 142 | WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n"); |
90 | memset(buf, 0, count); | 143 | memset(buf, 0, count); |
91 | return; | 144 | return -EINVAL; |
92 | } | 145 | } |
93 | 146 | ||
94 | mutex_lock(&fw_cfg_dev_lock); | 147 | mutex_lock(&fw_cfg_dev_lock); |
95 | iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl); | 148 | fw_cfg_sel_endianness(key); |
96 | while (pos-- > 0) | 149 | while (pos-- > 0) |
97 | ioread8(fw_cfg_reg_data); | 150 | ioread8(fw_cfg_reg_data); |
98 | ioread8_rep(fw_cfg_reg_data, buf, count); | 151 | ioread8_rep(fw_cfg_reg_data, buf, count); |
99 | mutex_unlock(&fw_cfg_dev_lock); | 152 | mutex_unlock(&fw_cfg_dev_lock); |
100 | 153 | ||
101 | acpi_release_global_lock(glk); | 154 | acpi_release_global_lock(glk); |
155 | return count; | ||
156 | } | ||
157 | |||
158 | #ifdef CONFIG_CRASH_CORE | ||
159 | /* write chunk of given fw_cfg blob (caller responsible for sanity-check) */ | ||
160 | static ssize_t fw_cfg_write_blob(u16 key, | ||
161 | void *buf, loff_t pos, size_t count) | ||
162 | { | ||
163 | u32 glk = -1U; | ||
164 | acpi_status status; | ||
165 | ssize_t ret = count; | ||
166 | |||
167 | /* If we have ACPI, ensure mutual exclusion against any potential | ||
168 | * device access by the firmware, e.g. via AML methods: | ||
169 | */ | ||
170 | status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, &glk); | ||
171 | if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) { | ||
172 | /* Should never get here */ | ||
173 | WARN(1, "%s: Failed to lock ACPI!\n", __func__); | ||
174 | return -EINVAL; | ||
175 | } | ||
176 | |||
177 | mutex_lock(&fw_cfg_dev_lock); | ||
178 | if (pos == 0) { | ||
179 | ret = fw_cfg_dma_transfer(buf, count, key << 16 | ||
180 | | FW_CFG_DMA_CTL_SELECT | ||
181 | | FW_CFG_DMA_CTL_WRITE); | ||
182 | } else { | ||
183 | fw_cfg_sel_endianness(key); | ||
184 | ret = fw_cfg_dma_transfer(NULL, pos, FW_CFG_DMA_CTL_SKIP); | ||
185 | if (ret < 0) | ||
186 | goto end; | ||
187 | ret = fw_cfg_dma_transfer(buf, count, FW_CFG_DMA_CTL_WRITE); | ||
188 | } | ||
189 | |||
190 | end: | ||
191 | mutex_unlock(&fw_cfg_dev_lock); | ||
192 | |||
193 | acpi_release_global_lock(glk); | ||
194 | |||
195 | return ret; | ||
102 | } | 196 | } |
197 | #endif /* CONFIG_CRASH_CORE */ | ||
103 | 198 | ||
104 | /* clean up fw_cfg device i/o */ | 199 | /* clean up fw_cfg device i/o */ |
105 | static void fw_cfg_io_cleanup(void) | 200 | static void fw_cfg_io_cleanup(void) |
@@ -118,12 +213,14 @@ static void fw_cfg_io_cleanup(void) | |||
118 | # if (defined(CONFIG_ARM) || defined(CONFIG_ARM64)) | 213 | # if (defined(CONFIG_ARM) || defined(CONFIG_ARM64)) |
119 | # define FW_CFG_CTRL_OFF 0x08 | 214 | # define FW_CFG_CTRL_OFF 0x08 |
120 | # define FW_CFG_DATA_OFF 0x00 | 215 | # define FW_CFG_DATA_OFF 0x00 |
216 | # define FW_CFG_DMA_OFF 0x10 | ||
121 | # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m */ | 217 | # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m */ |
122 | # define FW_CFG_CTRL_OFF 0x00 | 218 | # define FW_CFG_CTRL_OFF 0x00 |
123 | # define FW_CFG_DATA_OFF 0x02 | 219 | # define FW_CFG_DATA_OFF 0x02 |
124 | # elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u */ | 220 | # elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u */ |
125 | # define FW_CFG_CTRL_OFF 0x00 | 221 | # define FW_CFG_CTRL_OFF 0x00 |
126 | # define FW_CFG_DATA_OFF 0x01 | 222 | # define FW_CFG_DATA_OFF 0x01 |
223 | # define FW_CFG_DMA_OFF 0x04 | ||
127 | # else | 224 | # else |
128 | # error "QEMU FW_CFG not available on this architecture!" | 225 | # error "QEMU FW_CFG not available on this architecture!" |
129 | # endif | 226 | # endif |
@@ -133,7 +230,7 @@ static void fw_cfg_io_cleanup(void) | |||
133 | static int fw_cfg_do_platform_probe(struct platform_device *pdev) | 230 | static int fw_cfg_do_platform_probe(struct platform_device *pdev) |
134 | { | 231 | { |
135 | char sig[FW_CFG_SIG_SIZE]; | 232 | char sig[FW_CFG_SIG_SIZE]; |
136 | struct resource *range, *ctrl, *data; | 233 | struct resource *range, *ctrl, *data, *dma; |
137 | 234 | ||
138 | /* acquire i/o range details */ | 235 | /* acquire i/o range details */ |
139 | fw_cfg_is_mmio = false; | 236 | fw_cfg_is_mmio = false; |
@@ -170,6 +267,7 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev) | |||
170 | /* were custom register offsets provided (e.g. on the command line)? */ | 267 | /* were custom register offsets provided (e.g. on the command line)? */ |
171 | ctrl = platform_get_resource_byname(pdev, IORESOURCE_REG, "ctrl"); | 268 | ctrl = platform_get_resource_byname(pdev, IORESOURCE_REG, "ctrl"); |
172 | data = platform_get_resource_byname(pdev, IORESOURCE_REG, "data"); | 269 | data = platform_get_resource_byname(pdev, IORESOURCE_REG, "data"); |
270 | dma = platform_get_resource_byname(pdev, IORESOURCE_REG, "dma"); | ||
173 | if (ctrl && data) { | 271 | if (ctrl && data) { |
174 | fw_cfg_reg_ctrl = fw_cfg_dev_base + ctrl->start; | 272 | fw_cfg_reg_ctrl = fw_cfg_dev_base + ctrl->start; |
175 | fw_cfg_reg_data = fw_cfg_dev_base + data->start; | 273 | fw_cfg_reg_data = fw_cfg_dev_base + data->start; |
@@ -179,9 +277,17 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev) | |||
179 | fw_cfg_reg_data = fw_cfg_dev_base + FW_CFG_DATA_OFF; | 277 | fw_cfg_reg_data = fw_cfg_dev_base + FW_CFG_DATA_OFF; |
180 | } | 278 | } |
181 | 279 | ||
280 | if (dma) | ||
281 | fw_cfg_reg_dma = fw_cfg_dev_base + dma->start; | ||
282 | #ifdef FW_CFG_DMA_OFF | ||
283 | else | ||
284 | fw_cfg_reg_dma = fw_cfg_dev_base + FW_CFG_DMA_OFF; | ||
285 | #endif | ||
286 | |||
182 | /* verify fw_cfg device signature */ | 287 | /* verify fw_cfg device signature */ |
183 | fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, 0, FW_CFG_SIG_SIZE); | 288 | if (fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, |
184 | if (memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) != 0) { | 289 | 0, FW_CFG_SIG_SIZE) < 0 || |
290 | memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) != 0) { | ||
185 | fw_cfg_io_cleanup(); | 291 | fw_cfg_io_cleanup(); |
186 | return -ENODEV; | 292 | return -ENODEV; |
187 | } | 293 | } |
@@ -189,9 +295,6 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev) | |||
189 | return 0; | 295 | return 0; |
190 | } | 296 | } |
191 | 297 | ||
192 | /* fw_cfg revision attribute, in /sys/firmware/qemu_fw_cfg top-level dir. */ | ||
193 | static u32 fw_cfg_rev; | ||
194 | |||
195 | static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char *buf) | 298 | static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char *buf) |
196 | { | 299 | { |
197 | return sprintf(buf, "%u\n", fw_cfg_rev); | 300 | return sprintf(buf, "%u\n", fw_cfg_rev); |
@@ -208,10 +311,38 @@ static const struct { | |||
208 | /* fw_cfg_sysfs_entry type */ | 311 | /* fw_cfg_sysfs_entry type */ |
209 | struct fw_cfg_sysfs_entry { | 312 | struct fw_cfg_sysfs_entry { |
210 | struct kobject kobj; | 313 | struct kobject kobj; |
211 | struct fw_cfg_file f; | 314 | u32 size; |
315 | u16 select; | ||
316 | char name[FW_CFG_MAX_FILE_PATH]; | ||
212 | struct list_head list; | 317 | struct list_head list; |
213 | }; | 318 | }; |
214 | 319 | ||
320 | #ifdef CONFIG_CRASH_CORE | ||
321 | static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f) | ||
322 | { | ||
323 | static struct fw_cfg_vmcoreinfo *data; | ||
324 | ssize_t ret; | ||
325 | |||
326 | data = kmalloc(sizeof(struct fw_cfg_vmcoreinfo), GFP_KERNEL); | ||
327 | if (!data) | ||
328 | return -ENOMEM; | ||
329 | |||
330 | *data = (struct fw_cfg_vmcoreinfo) { | ||
331 | .guest_format = cpu_to_le16(FW_CFG_VMCOREINFO_FORMAT_ELF), | ||
332 | .size = cpu_to_le32(VMCOREINFO_NOTE_SIZE), | ||
333 | .paddr = cpu_to_le64(paddr_vmcoreinfo_note()) | ||
334 | }; | ||
335 | /* spare ourself reading host format support for now since we | ||
336 | * don't know what else to format - host may ignore ours | ||
337 | */ | ||
338 | ret = fw_cfg_write_blob(be16_to_cpu(f->select), data, | ||
339 | 0, sizeof(struct fw_cfg_vmcoreinfo)); | ||
340 | |||
341 | kfree(data); | ||
342 | return ret; | ||
343 | } | ||
344 | #endif /* CONFIG_CRASH_CORE */ | ||
345 | |||
215 | /* get fw_cfg_sysfs_entry from kobject member */ | 346 | /* get fw_cfg_sysfs_entry from kobject member */ |
216 | static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj) | 347 | static inline struct fw_cfg_sysfs_entry *to_entry(struct kobject *kobj) |
217 | { | 348 | { |
@@ -272,17 +403,17 @@ struct fw_cfg_sysfs_attribute fw_cfg_sysfs_attr_##_attr = { \ | |||
272 | 403 | ||
273 | static ssize_t fw_cfg_sysfs_show_size(struct fw_cfg_sysfs_entry *e, char *buf) | 404 | static ssize_t fw_cfg_sysfs_show_size(struct fw_cfg_sysfs_entry *e, char *buf) |
274 | { | 405 | { |
275 | return sprintf(buf, "%u\n", e->f.size); | 406 | return sprintf(buf, "%u\n", e->size); |
276 | } | 407 | } |
277 | 408 | ||
278 | static ssize_t fw_cfg_sysfs_show_key(struct fw_cfg_sysfs_entry *e, char *buf) | 409 | static ssize_t fw_cfg_sysfs_show_key(struct fw_cfg_sysfs_entry *e, char *buf) |
279 | { | 410 | { |
280 | return sprintf(buf, "%u\n", e->f.select); | 411 | return sprintf(buf, "%u\n", e->select); |
281 | } | 412 | } |
282 | 413 | ||
283 | static ssize_t fw_cfg_sysfs_show_name(struct fw_cfg_sysfs_entry *e, char *buf) | 414 | static ssize_t fw_cfg_sysfs_show_name(struct fw_cfg_sysfs_entry *e, char *buf) |
284 | { | 415 | { |
285 | return sprintf(buf, "%s\n", e->f.name); | 416 | return sprintf(buf, "%s\n", e->name); |
286 | } | 417 | } |
287 | 418 | ||
288 | static FW_CFG_SYSFS_ATTR(size); | 419 | static FW_CFG_SYSFS_ATTR(size); |
@@ -333,14 +464,13 @@ static ssize_t fw_cfg_sysfs_read_raw(struct file *filp, struct kobject *kobj, | |||
333 | { | 464 | { |
334 | struct fw_cfg_sysfs_entry *entry = to_entry(kobj); | 465 | struct fw_cfg_sysfs_entry *entry = to_entry(kobj); |
335 | 466 | ||
336 | if (pos > entry->f.size) | 467 | if (pos > entry->size) |
337 | return -EINVAL; | 468 | return -EINVAL; |
338 | 469 | ||
339 | if (count > entry->f.size - pos) | 470 | if (count > entry->size - pos) |
340 | count = entry->f.size - pos; | 471 | count = entry->size - pos; |
341 | 472 | ||
342 | fw_cfg_read_blob(entry->f.select, buf, pos, count); | 473 | return fw_cfg_read_blob(entry->select, buf, pos, count); |
343 | return count; | ||
344 | } | 474 | } |
345 | 475 | ||
346 | static struct bin_attribute fw_cfg_sysfs_attr_raw = { | 476 | static struct bin_attribute fw_cfg_sysfs_attr_raw = { |
@@ -452,17 +582,28 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f) | |||
452 | int err; | 582 | int err; |
453 | struct fw_cfg_sysfs_entry *entry; | 583 | struct fw_cfg_sysfs_entry *entry; |
454 | 584 | ||
585 | #ifdef CONFIG_CRASH_CORE | ||
586 | if (fw_cfg_dma_enabled() && | ||
587 | strcmp(f->name, FW_CFG_VMCOREINFO_FILENAME) == 0 && | ||
588 | !is_kdump_kernel()) { | ||
589 | if (fw_cfg_write_vmcoreinfo(f) < 0) | ||
590 | pr_warn("fw_cfg: failed to write vmcoreinfo"); | ||
591 | } | ||
592 | #endif | ||
593 | |||
455 | /* allocate new entry */ | 594 | /* allocate new entry */ |
456 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | 595 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); |
457 | if (!entry) | 596 | if (!entry) |
458 | return -ENOMEM; | 597 | return -ENOMEM; |
459 | 598 | ||
460 | /* set file entry information */ | 599 | /* set file entry information */ |
461 | memcpy(&entry->f, f, sizeof(struct fw_cfg_file)); | 600 | entry->size = be32_to_cpu(f->size); |
601 | entry->select = be16_to_cpu(f->select); | ||
602 | memcpy(entry->name, f->name, FW_CFG_MAX_FILE_PATH); | ||
462 | 603 | ||
463 | /* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */ | 604 | /* register entry under "/sys/firmware/qemu_fw_cfg/by_key/" */ |
464 | err = kobject_init_and_add(&entry->kobj, &fw_cfg_sysfs_entry_ktype, | 605 | err = kobject_init_and_add(&entry->kobj, &fw_cfg_sysfs_entry_ktype, |
465 | fw_cfg_sel_ko, "%d", entry->f.select); | 606 | fw_cfg_sel_ko, "%d", entry->select); |
466 | if (err) | 607 | if (err) |
467 | goto err_register; | 608 | goto err_register; |
468 | 609 | ||
@@ -472,7 +613,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f) | |||
472 | goto err_add_raw; | 613 | goto err_add_raw; |
473 | 614 | ||
474 | /* try adding "/sys/firmware/qemu_fw_cfg/by_name/" symlink */ | 615 | /* try adding "/sys/firmware/qemu_fw_cfg/by_name/" symlink */ |
475 | fw_cfg_build_symlink(fw_cfg_fname_kset, &entry->kobj, entry->f.name); | 616 | fw_cfg_build_symlink(fw_cfg_fname_kset, &entry->kobj, entry->name); |
476 | 617 | ||
477 | /* success, add entry to global cache */ | 618 | /* success, add entry to global cache */ |
478 | fw_cfg_sysfs_cache_enlist(entry); | 619 | fw_cfg_sysfs_cache_enlist(entry); |
@@ -489,28 +630,35 @@ err_register: | |||
489 | static int fw_cfg_register_dir_entries(void) | 630 | static int fw_cfg_register_dir_entries(void) |
490 | { | 631 | { |
491 | int ret = 0; | 632 | int ret = 0; |
633 | __be32 files_count; | ||
492 | u32 count, i; | 634 | u32 count, i; |
493 | struct fw_cfg_file *dir; | 635 | struct fw_cfg_file *dir; |
494 | size_t dir_size; | 636 | size_t dir_size; |
495 | 637 | ||
496 | fw_cfg_read_blob(FW_CFG_FILE_DIR, &count, 0, sizeof(count)); | 638 | ret = fw_cfg_read_blob(FW_CFG_FILE_DIR, &files_count, |
497 | count = be32_to_cpu(count); | 639 | 0, sizeof(files_count)); |
640 | if (ret < 0) | ||
641 | return ret; | ||
642 | |||
643 | count = be32_to_cpu(files_count); | ||
498 | dir_size = count * sizeof(struct fw_cfg_file); | 644 | dir_size = count * sizeof(struct fw_cfg_file); |
499 | 645 | ||
500 | dir = kmalloc(dir_size, GFP_KERNEL); | 646 | dir = kmalloc(dir_size, GFP_KERNEL); |
501 | if (!dir) | 647 | if (!dir) |
502 | return -ENOMEM; | 648 | return -ENOMEM; |
503 | 649 | ||
504 | fw_cfg_read_blob(FW_CFG_FILE_DIR, dir, sizeof(count), dir_size); | 650 | ret = fw_cfg_read_blob(FW_CFG_FILE_DIR, dir, |
651 | sizeof(files_count), dir_size); | ||
652 | if (ret < 0) | ||
653 | goto end; | ||
505 | 654 | ||
506 | for (i = 0; i < count; i++) { | 655 | for (i = 0; i < count; i++) { |
507 | dir[i].size = be32_to_cpu(dir[i].size); | ||
508 | dir[i].select = be16_to_cpu(dir[i].select); | ||
509 | ret = fw_cfg_register_file(&dir[i]); | 656 | ret = fw_cfg_register_file(&dir[i]); |
510 | if (ret) | 657 | if (ret) |
511 | break; | 658 | break; |
512 | } | 659 | } |
513 | 660 | ||
661 | end: | ||
514 | kfree(dir); | 662 | kfree(dir); |
515 | return ret; | 663 | return ret; |
516 | } | 664 | } |
@@ -525,6 +673,7 @@ static inline void fw_cfg_kobj_cleanup(struct kobject *kobj) | |||
525 | static int fw_cfg_sysfs_probe(struct platform_device *pdev) | 673 | static int fw_cfg_sysfs_probe(struct platform_device *pdev) |
526 | { | 674 | { |
527 | int err; | 675 | int err; |
676 | __le32 rev; | ||
528 | 677 | ||
529 | /* NOTE: If we supported multiple fw_cfg devices, we'd first create | 678 | /* NOTE: If we supported multiple fw_cfg devices, we'd first create |
530 | * a subdirectory named after e.g. pdev->id, then hang per-device | 679 | * a subdirectory named after e.g. pdev->id, then hang per-device |
@@ -550,8 +699,11 @@ static int fw_cfg_sysfs_probe(struct platform_device *pdev) | |||
550 | goto err_probe; | 699 | goto err_probe; |
551 | 700 | ||
552 | /* get revision number, add matching top-level attribute */ | 701 | /* get revision number, add matching top-level attribute */ |
553 | fw_cfg_read_blob(FW_CFG_ID, &fw_cfg_rev, 0, sizeof(fw_cfg_rev)); | 702 | err = fw_cfg_read_blob(FW_CFG_ID, &rev, 0, sizeof(rev)); |
554 | fw_cfg_rev = le32_to_cpu(fw_cfg_rev); | 703 | if (err < 0) |
704 | goto err_probe; | ||
705 | |||
706 | fw_cfg_rev = le32_to_cpu(rev); | ||
555 | err = sysfs_create_file(fw_cfg_top_ko, &fw_cfg_rev_attr.attr); | 707 | err = sysfs_create_file(fw_cfg_top_ko, &fw_cfg_rev_attr.attr); |
556 | if (err) | 708 | if (err) |
557 | goto err_rev; | 709 | goto err_rev; |
@@ -597,7 +749,7 @@ MODULE_DEVICE_TABLE(of, fw_cfg_sysfs_mmio_match); | |||
597 | 749 | ||
598 | #ifdef CONFIG_ACPI | 750 | #ifdef CONFIG_ACPI |
599 | static const struct acpi_device_id fw_cfg_sysfs_acpi_match[] = { | 751 | static const struct acpi_device_id fw_cfg_sysfs_acpi_match[] = { |
600 | { "QEMU0002", }, | 752 | { FW_CFG_ACPI_DEVICE_ID, }, |
601 | {}, | 753 | {}, |
602 | }; | 754 | }; |
603 | MODULE_DEVICE_TABLE(acpi, fw_cfg_sysfs_acpi_match); | 755 | MODULE_DEVICE_TABLE(acpi, fw_cfg_sysfs_acpi_match); |
@@ -629,6 +781,7 @@ static struct platform_device *fw_cfg_cmdline_dev; | |||
629 | /* use special scanf/printf modifier for phys_addr_t, resource_size_t */ | 781 | /* use special scanf/printf modifier for phys_addr_t, resource_size_t */ |
630 | #define PH_ADDR_SCAN_FMT "@%" __PHYS_ADDR_PREFIX "i%n" \ | 782 | #define PH_ADDR_SCAN_FMT "@%" __PHYS_ADDR_PREFIX "i%n" \ |
631 | ":%" __PHYS_ADDR_PREFIX "i" \ | 783 | ":%" __PHYS_ADDR_PREFIX "i" \ |
784 | ":%" __PHYS_ADDR_PREFIX "i%n" \ | ||
632 | ":%" __PHYS_ADDR_PREFIX "i%n" | 785 | ":%" __PHYS_ADDR_PREFIX "i%n" |
633 | 786 | ||
634 | #define PH_ADDR_PR_1_FMT "0x%" __PHYS_ADDR_PREFIX "x@" \ | 787 | #define PH_ADDR_PR_1_FMT "0x%" __PHYS_ADDR_PREFIX "x@" \ |
@@ -638,12 +791,15 @@ static struct platform_device *fw_cfg_cmdline_dev; | |||
638 | ":%" __PHYS_ADDR_PREFIX "u" \ | 791 | ":%" __PHYS_ADDR_PREFIX "u" \ |
639 | ":%" __PHYS_ADDR_PREFIX "u" | 792 | ":%" __PHYS_ADDR_PREFIX "u" |
640 | 793 | ||
794 | #define PH_ADDR_PR_4_FMT PH_ADDR_PR_3_FMT \ | ||
795 | ":%" __PHYS_ADDR_PREFIX "u" | ||
796 | |||
641 | static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp) | 797 | static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp) |
642 | { | 798 | { |
643 | struct resource res[3] = {}; | 799 | struct resource res[4] = {}; |
644 | char *str; | 800 | char *str; |
645 | phys_addr_t base; | 801 | phys_addr_t base; |
646 | resource_size_t size, ctrl_off, data_off; | 802 | resource_size_t size, ctrl_off, data_off, dma_off; |
647 | int processed, consumed = 0; | 803 | int processed, consumed = 0; |
648 | 804 | ||
649 | /* only one fw_cfg device can exist system-wide, so if one | 805 | /* only one fw_cfg device can exist system-wide, so if one |
@@ -659,19 +815,20 @@ static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp) | |||
659 | /* consume "<size>" portion of command line argument */ | 815 | /* consume "<size>" portion of command line argument */ |
660 | size = memparse(arg, &str); | 816 | size = memparse(arg, &str); |
661 | 817 | ||
662 | /* get "@<base>[:<ctrl_off>:<data_off>]" chunks */ | 818 | /* get "@<base>[:<ctrl_off>:<data_off>[:<dma_off>]]" chunks */ |
663 | processed = sscanf(str, PH_ADDR_SCAN_FMT, | 819 | processed = sscanf(str, PH_ADDR_SCAN_FMT, |
664 | &base, &consumed, | 820 | &base, &consumed, |
665 | &ctrl_off, &data_off, &consumed); | 821 | &ctrl_off, &data_off, &consumed, |
822 | &dma_off, &consumed); | ||
666 | 823 | ||
667 | /* sscanf() must process precisely 1 or 3 chunks: | 824 | /* sscanf() must process precisely 1, 3 or 4 chunks: |
668 | * <base> is mandatory, optionally followed by <ctrl_off> | 825 | * <base> is mandatory, optionally followed by <ctrl_off> |
669 | * and <data_off>; | 826 | * and <data_off>, and <dma_off>; |
670 | * there must be no extra characters after the last chunk, | 827 | * there must be no extra characters after the last chunk, |
671 | * so str[consumed] must be '\0'. | 828 | * so str[consumed] must be '\0'. |
672 | */ | 829 | */ |
673 | if (str[consumed] || | 830 | if (str[consumed] || |
674 | (processed != 1 && processed != 3)) | 831 | (processed != 1 && processed != 3 && processed != 4)) |
675 | return -EINVAL; | 832 | return -EINVAL; |
676 | 833 | ||
677 | res[0].start = base; | 834 | res[0].start = base; |
@@ -688,6 +845,11 @@ static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp) | |||
688 | res[2].start = data_off; | 845 | res[2].start = data_off; |
689 | res[2].flags = IORESOURCE_REG; | 846 | res[2].flags = IORESOURCE_REG; |
690 | } | 847 | } |
848 | if (processed > 3) { | ||
849 | res[3].name = "dma"; | ||
850 | res[3].start = dma_off; | ||
851 | res[3].flags = IORESOURCE_REG; | ||
852 | } | ||
691 | 853 | ||
692 | /* "processed" happens to nicely match the number of resources | 854 | /* "processed" happens to nicely match the number of resources |
693 | * we need to pass in to this platform device. | 855 | * we need to pass in to this platform device. |
@@ -720,6 +882,13 @@ static int fw_cfg_cmdline_get(char *buf, const struct kernel_param *kp) | |||
720 | fw_cfg_cmdline_dev->resource[0].start, | 882 | fw_cfg_cmdline_dev->resource[0].start, |
721 | fw_cfg_cmdline_dev->resource[1].start, | 883 | fw_cfg_cmdline_dev->resource[1].start, |
722 | fw_cfg_cmdline_dev->resource[2].start); | 884 | fw_cfg_cmdline_dev->resource[2].start); |
885 | case 4: | ||
886 | return snprintf(buf, PAGE_SIZE, PH_ADDR_PR_4_FMT, | ||
887 | resource_size(&fw_cfg_cmdline_dev->resource[0]), | ||
888 | fw_cfg_cmdline_dev->resource[0].start, | ||
889 | fw_cfg_cmdline_dev->resource[1].start, | ||
890 | fw_cfg_cmdline_dev->resource[2].start, | ||
891 | fw_cfg_cmdline_dev->resource[3].start); | ||
723 | } | 892 | } |
724 | 893 | ||
725 | /* Should never get here */ | 894 | /* Should never get here */ |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 5320039671b7..bec722e41f58 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -1334,7 +1334,7 @@ err: | |||
1334 | return -EFAULT; | 1334 | return -EFAULT; |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) | 1337 | long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp) |
1338 | { | 1338 | { |
1339 | struct file *eventfp, *filep = NULL; | 1339 | struct file *eventfp, *filep = NULL; |
1340 | bool pollstart = false, pollstop = false; | 1340 | bool pollstart = false, pollstop = false; |
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index ac4b6056f19a..d8ee85ae8fdc 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h | |||
@@ -45,7 +45,7 @@ void vhost_poll_stop(struct vhost_poll *poll); | |||
45 | void vhost_poll_flush(struct vhost_poll *poll); | 45 | void vhost_poll_flush(struct vhost_poll *poll); |
46 | void vhost_poll_queue(struct vhost_poll *poll); | 46 | void vhost_poll_queue(struct vhost_poll *poll); |
47 | void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work); | 47 | void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work); |
48 | long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp); | 48 | long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp); |
49 | 49 | ||
50 | struct vhost_log { | 50 | struct vhost_log { |
51 | u64 addr; | 51 | u64 addr; |
@@ -177,7 +177,7 @@ void vhost_dev_reset_owner(struct vhost_dev *, struct vhost_umem *); | |||
177 | void vhost_dev_cleanup(struct vhost_dev *); | 177 | void vhost_dev_cleanup(struct vhost_dev *); |
178 | void vhost_dev_stop(struct vhost_dev *); | 178 | void vhost_dev_stop(struct vhost_dev *); |
179 | long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp); | 179 | long vhost_dev_ioctl(struct vhost_dev *, unsigned int ioctl, void __user *argp); |
180 | long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp); | 180 | long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp); |
181 | int vhost_vq_access_ok(struct vhost_virtqueue *vq); | 181 | int vhost_vq_access_ok(struct vhost_virtqueue *vq); |
182 | int vhost_log_access_ok(struct vhost_dev *); | 182 | int vhost_log_access_ok(struct vhost_dev *); |
183 | 183 | ||
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 0898dbdbf955..34bc3ab40c6d 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c | |||
@@ -699,12 +699,23 @@ static long vhost_vsock_dev_ioctl(struct file *f, unsigned int ioctl, | |||
699 | } | 699 | } |
700 | } | 700 | } |
701 | 701 | ||
702 | #ifdef CONFIG_COMPAT | ||
703 | static long vhost_vsock_dev_compat_ioctl(struct file *f, unsigned int ioctl, | ||
704 | unsigned long arg) | ||
705 | { | ||
706 | return vhost_vsock_dev_ioctl(f, ioctl, (unsigned long)compat_ptr(arg)); | ||
707 | } | ||
708 | #endif | ||
709 | |||
702 | static const struct file_operations vhost_vsock_fops = { | 710 | static const struct file_operations vhost_vsock_fops = { |
703 | .owner = THIS_MODULE, | 711 | .owner = THIS_MODULE, |
704 | .open = vhost_vsock_dev_open, | 712 | .open = vhost_vsock_dev_open, |
705 | .release = vhost_vsock_dev_release, | 713 | .release = vhost_vsock_dev_release, |
706 | .llseek = noop_llseek, | 714 | .llseek = noop_llseek, |
707 | .unlocked_ioctl = vhost_vsock_dev_ioctl, | 715 | .unlocked_ioctl = vhost_vsock_dev_ioctl, |
716 | #ifdef CONFIG_COMPAT | ||
717 | .compat_ioctl = vhost_vsock_dev_compat_ioctl, | ||
718 | #endif | ||
708 | }; | 719 | }; |
709 | 720 | ||
710 | static struct miscdevice vhost_vsock_misc = { | 721 | static struct miscdevice vhost_vsock_misc = { |
diff --git a/include/uapi/linux/qemu_fw_cfg.h b/include/uapi/linux/qemu_fw_cfg.h new file mode 100644 index 000000000000..e089c0159ec2 --- /dev/null +++ b/include/uapi/linux/qemu_fw_cfg.h | |||
@@ -0,0 +1,97 @@ | |||
1 | /* SPDX-License-Identifier: BSD-3-Clause */ | ||
2 | #ifndef _LINUX_FW_CFG_H | ||
3 | #define _LINUX_FW_CFG_H | ||
4 | |||
5 | #include <linux/types.h> | ||
6 | |||
7 | #define FW_CFG_ACPI_DEVICE_ID "QEMU0002" | ||
8 | |||
9 | /* selector key values for "well-known" fw_cfg entries */ | ||
10 | #define FW_CFG_SIGNATURE 0x00 | ||
11 | #define FW_CFG_ID 0x01 | ||
12 | #define FW_CFG_UUID 0x02 | ||
13 | #define FW_CFG_RAM_SIZE 0x03 | ||
14 | #define FW_CFG_NOGRAPHIC 0x04 | ||
15 | #define FW_CFG_NB_CPUS 0x05 | ||
16 | #define FW_CFG_MACHINE_ID 0x06 | ||
17 | #define FW_CFG_KERNEL_ADDR 0x07 | ||
18 | #define FW_CFG_KERNEL_SIZE 0x08 | ||
19 | #define FW_CFG_KERNEL_CMDLINE 0x09 | ||
20 | #define FW_CFG_INITRD_ADDR 0x0a | ||
21 | #define FW_CFG_INITRD_SIZE 0x0b | ||
22 | #define FW_CFG_BOOT_DEVICE 0x0c | ||
23 | #define FW_CFG_NUMA 0x0d | ||
24 | #define FW_CFG_BOOT_MENU 0x0e | ||
25 | #define FW_CFG_MAX_CPUS 0x0f | ||
26 | #define FW_CFG_KERNEL_ENTRY 0x10 | ||
27 | #define FW_CFG_KERNEL_DATA 0x11 | ||
28 | #define FW_CFG_INITRD_DATA 0x12 | ||
29 | #define FW_CFG_CMDLINE_ADDR 0x13 | ||
30 | #define FW_CFG_CMDLINE_SIZE 0x14 | ||
31 | #define FW_CFG_CMDLINE_DATA 0x15 | ||
32 | #define FW_CFG_SETUP_ADDR 0x16 | ||
33 | #define FW_CFG_SETUP_SIZE 0x17 | ||
34 | #define FW_CFG_SETUP_DATA 0x18 | ||
35 | #define FW_CFG_FILE_DIR 0x19 | ||
36 | |||
37 | #define FW_CFG_FILE_FIRST 0x20 | ||
38 | #define FW_CFG_FILE_SLOTS_MIN 0x10 | ||
39 | |||
40 | #define FW_CFG_WRITE_CHANNEL 0x4000 | ||
41 | #define FW_CFG_ARCH_LOCAL 0x8000 | ||
42 | #define FW_CFG_ENTRY_MASK (~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)) | ||
43 | |||
44 | #define FW_CFG_INVALID 0xffff | ||
45 | |||
46 | /* width in bytes of fw_cfg control register */ | ||
47 | #define FW_CFG_CTL_SIZE 0x02 | ||
48 | |||
49 | /* fw_cfg "file name" is up to 56 characters (including terminating nul) */ | ||
50 | #define FW_CFG_MAX_FILE_PATH 56 | ||
51 | |||
52 | /* size in bytes of fw_cfg signature */ | ||
53 | #define FW_CFG_SIG_SIZE 4 | ||
54 | |||
55 | /* FW_CFG_ID bits */ | ||
56 | #define FW_CFG_VERSION 0x01 | ||
57 | #define FW_CFG_VERSION_DMA 0x02 | ||
58 | |||
59 | /* fw_cfg file directory entry type */ | ||
60 | struct fw_cfg_file { | ||
61 | __be32 size; | ||
62 | __be16 select; | ||
63 | __u16 reserved; | ||
64 | char name[FW_CFG_MAX_FILE_PATH]; | ||
65 | }; | ||
66 | |||
67 | /* FW_CFG_DMA_CONTROL bits */ | ||
68 | #define FW_CFG_DMA_CTL_ERROR 0x01 | ||
69 | #define FW_CFG_DMA_CTL_READ 0x02 | ||
70 | #define FW_CFG_DMA_CTL_SKIP 0x04 | ||
71 | #define FW_CFG_DMA_CTL_SELECT 0x08 | ||
72 | #define FW_CFG_DMA_CTL_WRITE 0x10 | ||
73 | |||
74 | #define FW_CFG_DMA_SIGNATURE 0x51454d5520434647ULL /* "QEMU CFG" */ | ||
75 | |||
76 | /* Control as first field allows for different structures selected by this | ||
77 | * field, which might be useful in the future | ||
78 | */ | ||
79 | struct fw_cfg_dma_access { | ||
80 | __be32 control; | ||
81 | __be32 length; | ||
82 | __be64 address; | ||
83 | }; | ||
84 | |||
85 | #define FW_CFG_VMCOREINFO_FILENAME "etc/vmcoreinfo" | ||
86 | |||
87 | #define FW_CFG_VMCOREINFO_FORMAT_NONE 0x0 | ||
88 | #define FW_CFG_VMCOREINFO_FORMAT_ELF 0x1 | ||
89 | |||
90 | struct fw_cfg_vmcoreinfo { | ||
91 | __le16 host_format; | ||
92 | __le16 guest_format; | ||
93 | __le32 size; | ||
94 | __le64 paddr; | ||
95 | }; | ||
96 | |||
97 | #endif | ||
diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 4f63597c824d..a93590cdd9e1 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c | |||
@@ -376,6 +376,7 @@ phys_addr_t __weak paddr_vmcoreinfo_note(void) | |||
376 | { | 376 | { |
377 | return __pa(vmcoreinfo_note); | 377 | return __pa(vmcoreinfo_note); |
378 | } | 378 | } |
379 | EXPORT_SYMBOL(paddr_vmcoreinfo_note); | ||
379 | 380 | ||
380 | static int __init crash_save_vmcoreinfo_init(void) | 381 | static int __init crash_save_vmcoreinfo_init(void) |
381 | { | 382 | { |
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c index 477899c12c51..2d566fbd236b 100644 --- a/tools/virtio/ringtest/ptr_ring.c +++ b/tools/virtio/ringtest/ptr_ring.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #define likely(x) (__builtin_expect(!!(x), 1)) | 17 | #define likely(x) (__builtin_expect(!!(x), 1)) |
18 | #define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a)) | 18 | #define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a)) |
19 | #define SIZE_MAX (~(size_t)0) | 19 | #define SIZE_MAX (~(size_t)0) |
20 | #define KMALLOC_MAX_SIZE SIZE_MAX | ||
21 | #define BUG_ON(x) assert(x) | ||
20 | 22 | ||
21 | typedef pthread_spinlock_t spinlock_t; | 23 | typedef pthread_spinlock_t spinlock_t; |
22 | 24 | ||
@@ -57,6 +59,9 @@ static void kfree(void *p) | |||
57 | free(p); | 59 | free(p); |
58 | } | 60 | } |
59 | 61 | ||
62 | #define kvmalloc_array kmalloc_array | ||
63 | #define kvfree kfree | ||
64 | |||
60 | static void spin_lock_init(spinlock_t *lock) | 65 | static void spin_lock_init(spinlock_t *lock) |
61 | { | 66 | { |
62 | int r = pthread_spin_init(lock, 0); | 67 | int r = pthread_spin_init(lock, 0); |