Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'hyperv-fixes-signed-20250718' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull hyperv fixes from Wei Liu:

- Select use CONFIG_SYSFB only if EFI is enabled (Michael Kelley)

- An assorted set of fixes to remove warnings for missing export.h
header inclusion (Naman Jain)

- An assorted set of fixes for when Linux run as the root partition
for Microsoft Hypervisor (Mukesh Rathor, Nuno Das Neves, Stanislav
Kinsburskii)

- Fix the check for HYPERVISOR_CALLBACK_VECTOR (Naman Jain)

- Fix fcopy tool to handle irregularities with size of ring buffer
(Naman Jain)

- Fix incorrect file path conversion in fcopy tool (Yasumasa Suenaga)

* tag 'hyperv-fixes-signed-20250718' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
tools/hv: fcopy: Fix irregularities with size of ring buffer
PCI: hv: Use the correct hypercall for unmasking interrupts on nested
x86/hyperv: Expose hv_map_msi_interrupt()
Drivers: hv: Use nested hypercall for post message and signal event
x86/hyperv: Clean up hv_map/unmap_interrupt() return values
x86/hyperv: Fix usage of cpu_online_mask to get valid cpu
PCI: hv: Don't load the driver for baremetal root partition
net: mana: Fix warnings for missing export.h header inclusion
PCI: hv: Fix warnings for missing export.h header inclusion
clocksource: hyper-v: Fix warnings for missing export.h header inclusion
x86/hyperv: Fix warnings for missing export.h header inclusion
Drivers: hv: Fix warnings for missing export.h header inclusion
Drivers: hv: Fix the check for HYPERVISOR_CALLBACK_VECTOR
tools/hv: fcopy: Fix incorrect file path conversion
Drivers: hv: Select CONFIG_SYSFB only if EFI is enabled

+196 -112
+1
arch/x86/hyperv/hv_init.c
··· 34 34 #include <linux/syscore_ops.h> 35 35 #include <clocksource/hyperv_timer.h> 36 36 #include <linux/highmem.h> 37 + #include <linux/export.h> 37 38 38 39 void *hv_hypercall_pg; 39 40 EXPORT_SYMBOL_GPL(hv_hypercall_pg);
+41 -28
arch/x86/hyperv/irqdomain.c
··· 10 10 11 11 #include <linux/pci.h> 12 12 #include <linux/irq.h> 13 + #include <linux/export.h> 13 14 #include <asm/mshyperv.h> 14 15 15 16 static int hv_map_interrupt(union hv_device_id device_id, bool level, ··· 47 46 if (nr_bank < 0) { 48 47 local_irq_restore(flags); 49 48 pr_err("%s: unable to generate VP set\n", __func__); 50 - return EINVAL; 49 + return -EINVAL; 51 50 } 52 51 intr_desc->target.flags = HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET; 53 52 ··· 67 66 if (!hv_result_success(status)) 68 67 hv_status_err(status, "\n"); 69 68 70 - return hv_result(status); 69 + return hv_result_to_errno(status); 71 70 } 72 71 73 72 static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry) ··· 89 88 status = hv_do_hypercall(HVCALL_UNMAP_DEVICE_INTERRUPT, input, NULL); 90 89 local_irq_restore(flags); 91 90 92 - return hv_result(status); 91 + if (!hv_result_success(status)) 92 + hv_status_err(status, "\n"); 93 + 94 + return hv_result_to_errno(status); 93 95 } 94 96 95 97 #ifdef CONFIG_PCI_MSI ··· 173 169 return dev_id; 174 170 } 175 171 176 - static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector, 177 - struct hv_interrupt_entry *entry) 172 + /** 173 + * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor. 174 + * @data: Describes the IRQ 175 + * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL) 176 + * 177 + * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall. 178 + * 179 + * Return: 0 on success, -errno on failure 180 + */ 181 + int hv_map_msi_interrupt(struct irq_data *data, 182 + struct hv_interrupt_entry *out_entry) 178 183 { 179 - union hv_device_id device_id = hv_build_pci_dev_id(dev); 184 + struct irq_cfg *cfg = irqd_cfg(data); 185 + struct hv_interrupt_entry dummy; 186 + union hv_device_id device_id; 187 + struct msi_desc *msidesc; 188 + struct pci_dev *dev; 189 + int cpu; 180 190 181 - return hv_map_interrupt(device_id, false, cpu, vector, entry); 191 + msidesc = irq_data_get_msi_desc(data); 192 + dev = msi_desc_to_pci_dev(msidesc); 193 + device_id = hv_build_pci_dev_id(dev); 194 + cpu = cpumask_first(irq_data_get_effective_affinity_mask(data)); 195 + 196 + return hv_map_interrupt(device_id, false, cpu, cfg->vector, 197 + out_entry ? out_entry : &dummy); 182 198 } 199 + EXPORT_SYMBOL_GPL(hv_map_msi_interrupt); 183 200 184 201 static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi_msg *msg) 185 202 { ··· 213 188 static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry); 214 189 static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) 215 190 { 191 + struct hv_interrupt_entry *stored_entry; 192 + struct irq_cfg *cfg = irqd_cfg(data); 216 193 struct msi_desc *msidesc; 217 194 struct pci_dev *dev; 218 - struct hv_interrupt_entry out_entry, *stored_entry; 219 - struct irq_cfg *cfg = irqd_cfg(data); 220 - const cpumask_t *affinity; 221 - int cpu; 222 - u64 status; 195 + int ret; 223 196 224 197 msidesc = irq_data_get_msi_desc(data); 225 198 dev = msi_desc_to_pci_dev(msidesc); ··· 226 203 pr_debug("%s: cfg is NULL", __func__); 227 204 return; 228 205 } 229 - 230 - affinity = irq_data_get_effective_affinity_mask(data); 231 - cpu = cpumask_first_and(affinity, cpu_online_mask); 232 206 233 207 if (data->chip_data) { 234 208 /* ··· 239 219 stored_entry = data->chip_data; 240 220 data->chip_data = NULL; 241 221 242 - status = hv_unmap_msi_interrupt(dev, stored_entry); 222 + ret = hv_unmap_msi_interrupt(dev, stored_entry); 243 223 244 224 kfree(stored_entry); 245 225 246 - if (status != HV_STATUS_SUCCESS) { 247 - hv_status_debug(status, "failed to unmap\n"); 226 + if (ret) 248 227 return; 249 - } 250 228 } 251 229 252 230 stored_entry = kzalloc(sizeof(*stored_entry), GFP_ATOMIC); ··· 253 235 return; 254 236 } 255 237 256 - status = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry); 257 - if (status != HV_STATUS_SUCCESS) { 238 + ret = hv_map_msi_interrupt(data, stored_entry); 239 + if (ret) { 258 240 kfree(stored_entry); 259 241 return; 260 242 } 261 243 262 - *stored_entry = out_entry; 263 244 data->chip_data = stored_entry; 264 - entry_to_msi_msg(&out_entry, msg); 245 + entry_to_msi_msg(data->chip_data, msg); 265 246 266 247 return; 267 248 } ··· 274 257 { 275 258 struct hv_interrupt_entry old_entry; 276 259 struct msi_msg msg; 277 - u64 status; 278 260 279 261 if (!irqd->chip_data) { 280 262 pr_debug("%s: no chip data\n!", __func__); ··· 286 270 kfree(irqd->chip_data); 287 271 irqd->chip_data = NULL; 288 272 289 - status = hv_unmap_msi_interrupt(dev, &old_entry); 290 - 291 - if (status != HV_STATUS_SUCCESS) 292 - hv_status_err(status, "\n"); 273 + (void)hv_unmap_msi_interrupt(dev, &old_entry); 293 274 } 294 275 295 276 static void hv_msi_free_irq(struct irq_domain *domain,
+1
arch/x86/hyperv/ivm.c
··· 10 10 #include <linux/types.h> 11 11 #include <linux/slab.h> 12 12 #include <linux/cpu.h> 13 + #include <linux/export.h> 13 14 #include <asm/svm.h> 14 15 #include <asm/sev.h> 15 16 #include <asm/io.h>
+1
arch/x86/hyperv/nested.c
··· 11 11 12 12 13 13 #include <linux/types.h> 14 + #include <linux/export.h> 14 15 #include <hyperv/hvhdk.h> 15 16 #include <asm/mshyperv.h> 16 17 #include <asm/tlbflush.h>
+2 -20
arch/x86/include/asm/mshyperv.h
··· 112 112 return hv_status; 113 113 } 114 114 115 - /* Hypercall to the L0 hypervisor */ 116 - static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output) 117 - { 118 - return hv_do_hypercall(control | HV_HYPERCALL_NESTED, input, output); 119 - } 120 - 121 115 /* Fast hypercall with 8 bytes of input and no output */ 122 116 static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1) 123 117 { ··· 155 161 static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1) 156 162 { 157 163 u64 control = (u64)code | HV_HYPERCALL_FAST_BIT; 158 - 159 - return _hv_do_fast_hypercall8(control, input1); 160 - } 161 - 162 - static inline u64 hv_do_fast_nested_hypercall8(u16 code, u64 input1) 163 - { 164 - u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED; 165 164 166 165 return _hv_do_fast_hypercall8(control, input1); 167 166 } ··· 210 223 return _hv_do_fast_hypercall16(control, input1, input2); 211 224 } 212 225 213 - static inline u64 hv_do_fast_nested_hypercall16(u16 code, u64 input1, u64 input2) 214 - { 215 - u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED; 216 - 217 - return _hv_do_fast_hypercall16(control, input1, input2); 218 - } 219 - 220 226 extern struct hv_vp_assist_page **hv_vp_assist_page; 221 227 222 228 static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu) ··· 242 262 243 263 struct irq_domain *hv_create_pci_msi_domain(void); 244 264 265 + int hv_map_msi_interrupt(struct irq_data *data, 266 + struct hv_interrupt_entry *out_entry); 245 267 int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector, 246 268 struct hv_interrupt_entry *entry); 247 269 int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
+1
drivers/clocksource/hyperv_timer.c
··· 22 22 #include <linux/irq.h> 23 23 #include <linux/acpi.h> 24 24 #include <linux/hyperv.h> 25 + #include <linux/export.h> 25 26 #include <clocksource/hyperv_timer.h> 26 27 #include <hyperv/hvhdk.h> 27 28 #include <asm/mshyperv.h>
+1 -1
drivers/hv/Kconfig
··· 9 9 select PARAVIRT 10 10 select X86_HV_CALLBACK_VECTOR if X86 11 11 select OF_EARLY_FLATTREE if OF 12 - select SYSFB if !HYPERV_VTL_MODE 12 + select SYSFB if EFI && !HYPERV_VTL_MODE 13 13 help 14 14 Select this option to run Linux as a Hyper-V client operating 15 15 system.
+1
drivers/hv/channel.c
··· 18 18 #include <linux/uio.h> 19 19 #include <linux/interrupt.h> 20 20 #include <linux/set_memory.h> 21 + #include <linux/export.h> 21 22 #include <asm/page.h> 22 23 #include <asm/mshyperv.h> 23 24
+1
drivers/hv/channel_mgmt.c
··· 20 20 #include <linux/delay.h> 21 21 #include <linux/cpu.h> 22 22 #include <linux/hyperv.h> 23 + #include <linux/export.h> 23 24 #include <asm/mshyperv.h> 24 25 #include <linux/sched/isolation.h> 25 26
+4 -1
drivers/hv/connection.c
··· 519 519 else 520 520 WARN_ON_ONCE(1); 521 521 } else { 522 - hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event); 522 + u64 control = HVCALL_SIGNAL_EVENT; 523 + 524 + control |= hv_nested ? HV_HYPERCALL_NESTED : 0; 525 + hv_do_fast_hypercall8(control, channel->sig_event); 523 526 } 524 527 } 525 528 EXPORT_SYMBOL_GPL(vmbus_set_event);
+4 -2
drivers/hv/hv.c
··· 85 85 else 86 86 status = HV_STATUS_INVALID_PARAMETER; 87 87 } else { 88 - status = hv_do_hypercall(HVCALL_POST_MESSAGE, 89 - aligned_msg, NULL); 88 + u64 control = HVCALL_POST_MESSAGE; 89 + 90 + control |= hv_nested ? HV_HYPERCALL_NESTED : 0; 91 + status = hv_do_hypercall(control, aligned_msg, NULL); 90 92 } 91 93 92 94 local_irq_restore(flags);
+1
drivers/hv/hv_proc.c
··· 6 6 #include <linux/slab.h> 7 7 #include <linux/cpuhotplug.h> 8 8 #include <linux/minmax.h> 9 + #include <linux/export.h> 9 10 #include <asm/mshyperv.h> 10 11 11 12 /*
+1
drivers/hv/mshv_common.c
··· 13 13 #include <linux/mm.h> 14 14 #include <asm/mshyperv.h> 15 15 #include <linux/resume_user_mode.h> 16 + #include <linux/export.h> 16 17 17 18 #include "mshv.h" 18 19
+1
drivers/hv/mshv_root_hv_call.c
··· 9 9 10 10 #include <linux/kernel.h> 11 11 #include <linux/mm.h> 12 + #include <linux/export.h> 12 13 #include <asm/mshyperv.h> 13 14 14 15 #include "mshv_root.h"
+1
drivers/hv/ring_buffer.c
··· 18 18 #include <linux/slab.h> 19 19 #include <linux/prefetch.h> 20 20 #include <linux/io.h> 21 + #include <linux/export.h> 21 22 #include <asm/mshyperv.h> 22 23 23 24 #include "hyperv_vmbus.h"
+5 -4
drivers/hv/vmbus_drv.c
··· 2509 2509 return 0; 2510 2510 } 2511 2511 #endif 2512 - 2512 + #ifndef HYPERVISOR_CALLBACK_VECTOR 2513 2513 static int vmbus_set_irq(struct platform_device *pdev) 2514 2514 { 2515 2515 struct irq_data *data; ··· 2534 2534 2535 2535 return 0; 2536 2536 } 2537 + #endif 2537 2538 2538 2539 static int vmbus_device_add(struct platform_device *pdev) 2539 2540 { ··· 2550 2549 if (ret) 2551 2550 return ret; 2552 2551 2553 - if (!__is_defined(HYPERVISOR_CALLBACK_VECTOR)) 2554 - ret = vmbus_set_irq(pdev); 2552 + #ifndef HYPERVISOR_CALLBACK_VECTOR 2553 + ret = vmbus_set_irq(pdev); 2555 2554 if (ret) 2556 2555 return ret; 2557 - 2556 + #endif 2558 2557 for_each_of_range(&parser, &range) { 2559 2558 struct resource *res; 2560 2559
+12 -21
drivers/iommu/hyperv-iommu.c
··· 193 193 static void 194 194 hyperv_root_ir_compose_msi_msg(struct irq_data *irq_data, struct msi_msg *msg) 195 195 { 196 - u64 status; 197 - u32 vector; 198 - struct irq_cfg *cfg; 199 - int ioapic_id; 200 - const struct cpumask *affinity; 201 - int cpu; 202 - struct hv_interrupt_entry entry; 203 196 struct hyperv_root_ir_data *data = irq_data->chip_data; 197 + struct hv_interrupt_entry entry; 198 + const struct cpumask *affinity; 204 199 struct IO_APIC_route_entry e; 200 + struct irq_cfg *cfg; 201 + int cpu, ioapic_id; 202 + u32 vector; 205 203 206 204 cfg = irqd_cfg(irq_data); 207 205 affinity = irq_data_get_effective_affinity_mask(irq_data); ··· 212 214 && data->entry.ioapic_rte.as_uint64) { 213 215 entry = data->entry; 214 216 215 - status = hv_unmap_ioapic_interrupt(ioapic_id, &entry); 216 - 217 - if (status != HV_STATUS_SUCCESS) 218 - hv_status_debug(status, "failed to unmap\n"); 217 + (void)hv_unmap_ioapic_interrupt(ioapic_id, &entry); 219 218 220 219 data->entry.ioapic_rte.as_uint64 = 0; 221 220 data->entry.source = 0; /* Invalid source */ 222 221 } 223 222 224 223 225 - status = hv_map_ioapic_interrupt(ioapic_id, data->is_level, cpu, 226 - vector, &entry); 227 - 228 - if (status != HV_STATUS_SUCCESS) { 229 - hv_status_err(status, "map failed\n"); 224 + if (hv_map_ioapic_interrupt(ioapic_id, data->is_level, cpu, 225 + vector, &entry)) 230 226 return; 231 - } 232 227 233 228 data->entry = entry; 234 229 ··· 313 322 data = irq_data->chip_data; 314 323 e = &data->entry; 315 324 316 - if (e->source == HV_DEVICE_TYPE_IOAPIC 317 - && e->ioapic_rte.as_uint64) 318 - hv_unmap_ioapic_interrupt(data->ioapic_id, 319 - &data->entry); 325 + if (e->source == HV_DEVICE_TYPE_IOAPIC && 326 + e->ioapic_rte.as_uint64) 327 + (void)hv_unmap_ioapic_interrupt(data->ioapic_id, 328 + &data->entry); 320 329 321 330 kfree(data); 322 331 }
+1
drivers/net/ethernet/microsoft/mana/gdma_main.c
··· 6 6 #include <linux/pci.h> 7 7 #include <linux/utsname.h> 8 8 #include <linux/version.h> 9 + #include <linux/export.h> 9 10 10 11 #include <net/mana/mana.h> 11 12
+1
drivers/net/ethernet/microsoft/mana/mana_en.c
··· 10 10 #include <linux/filter.h> 11 11 #include <linux/mm.h> 12 12 #include <linux/pci.h> 13 + #include <linux/export.h> 13 14 14 15 #include <net/checksum.h> 15 16 #include <net/ip6_checksum.h>
+1
drivers/pci/controller/pci-hyperv-intf.c
··· 14 14 #include <linux/kernel.h> 15 15 #include <linux/module.h> 16 16 #include <linux/hyperv.h> 17 + #include <linux/export.h> 17 18 18 19 struct hyperv_pci_block_ops hvpci_block_ops; 19 20 EXPORT_SYMBOL_GPL(hvpci_block_ops);
+19 -2
drivers/pci/controller/pci-hyperv.c
··· 600 600 #define hv_msi_prepare pci_msi_prepare 601 601 602 602 /** 603 - * hv_arch_irq_unmask() - "Unmask" the IRQ by setting its current 603 + * hv_irq_retarget_interrupt() - "Unmask" the IRQ by setting its current 604 604 * affinity. 605 605 * @data: Describes the IRQ 606 606 * ··· 609 609 * is built out of this PCI bus's instance GUID and the function 610 610 * number of the device. 611 611 */ 612 - static void hv_arch_irq_unmask(struct irq_data *data) 612 + static void hv_irq_retarget_interrupt(struct irq_data *data) 613 613 { 614 614 struct msi_desc *msi_desc = irq_data_get_msi_desc(data); 615 615 struct hv_retarget_device_interrupt *params; ··· 713 713 if (!hv_result_success(res) && hbus->state != hv_pcibus_removing) 714 714 dev_err(&hbus->hdev->device, 715 715 "%s() failed: %#llx", __func__, res); 716 + } 717 + 718 + static void hv_arch_irq_unmask(struct irq_data *data) 719 + { 720 + if (hv_root_partition()) 721 + /* 722 + * In case of the nested root partition, the nested hypervisor 723 + * is taking care of interrupt remapping and thus the 724 + * MAP_DEVICE_INTERRUPT hypercall is required instead of 725 + * RETARGET_INTERRUPT. 726 + */ 727 + (void)hv_map_msi_interrupt(data, NULL); 728 + else 729 + hv_irq_retarget_interrupt(data); 716 730 } 717 731 #elif defined(CONFIG_ARM64) 718 732 /* ··· 4156 4142 int ret; 4157 4143 4158 4144 if (!hv_is_hyperv_initialized()) 4145 + return -ENODEV; 4146 + 4147 + if (hv_root_partition() && !hv_nested) 4159 4148 return -ENODEV; 4160 4149 4161 4150 ret = hv_pci_irqchip_init();
+95 -33
tools/hv/hv_fcopy_uio_daemon.c
··· 35 35 #define WIN8_SRV_MINOR 1 36 36 #define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR) 37 37 38 - #define FCOPY_UIO "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio" 38 + #define FCOPY_DEVICE_PATH(subdir) \ 39 + "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/" #subdir 40 + #define FCOPY_UIO_PATH FCOPY_DEVICE_PATH(uio) 41 + #define FCOPY_CHANNELS_PATH FCOPY_DEVICE_PATH(channels) 39 42 40 43 #define FCOPY_VER_COUNT 1 41 44 static const int fcopy_versions[] = { ··· 50 47 UTIL_FW_VERSION 51 48 }; 52 49 53 - #define HV_RING_SIZE 0x4000 /* 16KB ring buffer size */ 50 + static uint32_t get_ring_buffer_size(void) 51 + { 52 + char ring_path[PATH_MAX]; 53 + DIR *dir; 54 + struct dirent *entry; 55 + struct stat st; 56 + uint32_t ring_size = 0; 57 + int retry_count = 0; 54 58 55 - static unsigned char desc[HV_RING_SIZE]; 59 + /* Find the channel directory */ 60 + dir = opendir(FCOPY_CHANNELS_PATH); 61 + if (!dir) { 62 + usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */ 63 + dir = opendir(FCOPY_CHANNELS_PATH); 64 + if (!dir) { 65 + syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno)); 66 + return 0; 67 + } 68 + } 69 + 70 + retry_once: 71 + while ((entry = readdir(dir)) != NULL) { 72 + if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && 73 + strcmp(entry->d_name, "..") != 0) { 74 + snprintf(ring_path, sizeof(ring_path), "%s/%s/ring", 75 + FCOPY_CHANNELS_PATH, entry->d_name); 76 + 77 + if (stat(ring_path, &st) == 0) { 78 + /* 79 + * stat returns size of Tx, Rx rings combined, 80 + * so take half of it for individual ring size. 81 + */ 82 + ring_size = (uint32_t)st.st_size / 2; 83 + syslog(LOG_INFO, "Ring buffer size from %s: %u bytes", 84 + ring_path, ring_size); 85 + break; 86 + } 87 + } 88 + } 89 + 90 + if (!ring_size && retry_count == 0) { 91 + retry_count = 1; 92 + rewinddir(dir); 93 + usleep(100 * 1000); /* Wait 100ms and retry once */ 94 + goto retry_once; 95 + } 96 + 97 + closedir(dir); 98 + 99 + if (!ring_size) 100 + syslog(LOG_ERR, "Could not determine ring size"); 101 + 102 + return ring_size; 103 + } 104 + 105 + static unsigned char *desc; 56 106 57 107 static int target_fd; 58 108 static char target_fname[PATH_MAX]; ··· 118 62 119 63 filesize = 0; 120 64 p = path_name; 121 - snprintf(target_fname, sizeof(target_fname), "%s/%s", 122 - path_name, file_name); 65 + if (snprintf(target_fname, sizeof(target_fname), "%s/%s", 66 + path_name, file_name) >= sizeof(target_fname)) { 67 + syslog(LOG_ERR, "target file name is too long: %s/%s", path_name, file_name); 68 + goto done; 69 + } 123 70 124 71 /* 125 72 * Check to see if the path is already in place; if not, ··· 329 270 { 330 271 size_t len = 0; 331 272 332 - while (len < dest_size) { 273 + while (len < dest_size && *src) { 333 274 if (src[len] < 0x80) 334 275 dest[len++] = (char)(*src++); 335 276 else ··· 341 282 342 283 static int hv_fcopy_start(struct hv_start_fcopy *smsg_in) 343 284 { 285 + /* 286 + * file_name and path_name should have same length with appropriate 287 + * member of hv_start_fcopy. 288 + */ 289 + char file_name[W_MAX_PATH], path_name[W_MAX_PATH]; 290 + 344 291 setlocale(LC_ALL, "en_US.utf8"); 345 - size_t file_size, path_size; 346 - char *file_name, *path_name; 347 - char *in_file_name = (char *)smsg_in->file_name; 348 - char *in_path_name = (char *)smsg_in->path_name; 349 - 350 - file_size = wcstombs(NULL, (const wchar_t *restrict)in_file_name, 0) + 1; 351 - path_size = wcstombs(NULL, (const wchar_t *restrict)in_path_name, 0) + 1; 352 - 353 - file_name = (char *)malloc(file_size * sizeof(char)); 354 - path_name = (char *)malloc(path_size * sizeof(char)); 355 - 356 - if (!file_name || !path_name) { 357 - free(file_name); 358 - free(path_name); 359 - syslog(LOG_ERR, "Can't allocate memory for file name and/or path name"); 360 - return HV_E_FAIL; 361 - } 362 - 363 - wcstoutf8(file_name, (__u16 *)in_file_name, file_size); 364 - wcstoutf8(path_name, (__u16 *)in_path_name, path_size); 292 + wcstoutf8(file_name, smsg_in->file_name, W_MAX_PATH - 1); 293 + wcstoutf8(path_name, smsg_in->path_name, W_MAX_PATH - 1); 365 294 366 295 return hv_fcopy_create_file(file_name, path_name, smsg_in->copy_flags); 367 296 } ··· 453 406 int daemonize = 1, long_index = 0, opt, ret = -EINVAL; 454 407 struct vmbus_br txbr, rxbr; 455 408 void *ring; 456 - uint32_t len = HV_RING_SIZE; 409 + uint32_t ring_size, len; 457 410 char uio_name[NAME_MAX] = {0}; 458 411 char uio_dev_path[PATH_MAX] = {0}; 459 412 ··· 484 437 openlog("HV_UIO_FCOPY", 0, LOG_USER); 485 438 syslog(LOG_INFO, "starting; pid is:%d", getpid()); 486 439 487 - fcopy_get_first_folder(FCOPY_UIO, uio_name); 440 + ring_size = get_ring_buffer_size(); 441 + if (!ring_size) { 442 + ret = -ENODEV; 443 + goto exit; 444 + } 445 + 446 + desc = malloc(ring_size * sizeof(unsigned char)); 447 + if (!desc) { 448 + syslog(LOG_ERR, "malloc failed for desc buffer"); 449 + ret = -ENOMEM; 450 + goto exit; 451 + } 452 + 453 + fcopy_get_first_folder(FCOPY_UIO_PATH, uio_name); 488 454 snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name); 489 455 fcopy_fd = open(uio_dev_path, O_RDWR); 490 456 ··· 505 445 syslog(LOG_ERR, "open %s failed; error: %d %s", 506 446 uio_dev_path, errno, strerror(errno)); 507 447 ret = fcopy_fd; 508 - goto exit; 448 + goto free_desc; 509 449 } 510 450 511 - ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE); 451 + ring = vmbus_uio_map(&fcopy_fd, ring_size); 512 452 if (!ring) { 513 453 ret = errno; 514 454 syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret)); 515 455 goto close; 516 456 } 517 - vmbus_br_setup(&txbr, ring, HV_RING_SIZE); 518 - vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE); 457 + vmbus_br_setup(&txbr, ring, ring_size); 458 + vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size); 519 459 520 460 rxbr.vbr->imask = 0; 521 461 ··· 532 472 goto close; 533 473 } 534 474 535 - len = HV_RING_SIZE; 475 + len = ring_size; 536 476 ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len); 537 477 if (unlikely(ret <= 0)) { 538 478 /* This indicates a failure to communicate (or worse) */ ··· 552 492 } 553 493 close: 554 494 close(fcopy_fd); 495 + free_desc: 496 + free(desc); 555 497 exit: 556 498 return ret; 557 499 }