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
This commit is contained in:
Linus Torvalds
2025-07-20 09:29:43 -07:00
22 changed files with 196 additions and 112 deletions
+1
View File
@@ -34,6 +34,7 @@
#include <linux/syscore_ops.h>
#include <clocksource/hyperv_timer.h>
#include <linux/highmem.h>
#include <linux/export.h>
void *hv_hypercall_pg;
EXPORT_SYMBOL_GPL(hv_hypercall_pg);
+41 -28
View File
@@ -10,6 +10,7 @@
#include <linux/pci.h>
#include <linux/irq.h>
#include <linux/export.h>
#include <asm/mshyperv.h>
static int hv_map_interrupt(union hv_device_id device_id, bool level,
@@ -46,7 +47,7 @@ static int hv_map_interrupt(union hv_device_id device_id, bool level,
if (nr_bank < 0) {
local_irq_restore(flags);
pr_err("%s: unable to generate VP set\n", __func__);
return EINVAL;
return -EINVAL;
}
intr_desc->target.flags = HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET;
@@ -66,7 +67,7 @@ static int hv_map_interrupt(union hv_device_id device_id, bool level,
if (!hv_result_success(status))
hv_status_err(status, "\n");
return hv_result(status);
return hv_result_to_errno(status);
}
static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry)
@@ -88,7 +89,10 @@ static int hv_unmap_interrupt(u64 id, struct hv_interrupt_entry *old_entry)
status = hv_do_hypercall(HVCALL_UNMAP_DEVICE_INTERRUPT, input, NULL);
local_irq_restore(flags);
return hv_result(status);
if (!hv_result_success(status))
hv_status_err(status, "\n");
return hv_result_to_errno(status);
}
#ifdef CONFIG_PCI_MSI
@@ -169,13 +173,34 @@ static union hv_device_id hv_build_pci_dev_id(struct pci_dev *dev)
return dev_id;
}
static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector,
struct hv_interrupt_entry *entry)
/**
* hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor.
* @data: Describes the IRQ
* @out_entry: Hypervisor (MSI) interrupt entry (can be NULL)
*
* Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall.
*
* Return: 0 on success, -errno on failure
*/
int hv_map_msi_interrupt(struct irq_data *data,
struct hv_interrupt_entry *out_entry)
{
union hv_device_id device_id = hv_build_pci_dev_id(dev);
struct irq_cfg *cfg = irqd_cfg(data);
struct hv_interrupt_entry dummy;
union hv_device_id device_id;
struct msi_desc *msidesc;
struct pci_dev *dev;
int cpu;
return hv_map_interrupt(device_id, false, cpu, vector, entry);
msidesc = irq_data_get_msi_desc(data);
dev = msi_desc_to_pci_dev(msidesc);
device_id = hv_build_pci_dev_id(dev);
cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
return hv_map_interrupt(device_id, false, cpu, cfg->vector,
out_entry ? out_entry : &dummy);
}
EXPORT_SYMBOL_GPL(hv_map_msi_interrupt);
static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi_msg *msg)
{
@@ -188,13 +213,11 @@ static inline void entry_to_msi_msg(struct hv_interrupt_entry *entry, struct msi
static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry *old_entry);
static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
{
struct hv_interrupt_entry *stored_entry;
struct irq_cfg *cfg = irqd_cfg(data);
struct msi_desc *msidesc;
struct pci_dev *dev;
struct hv_interrupt_entry out_entry, *stored_entry;
struct irq_cfg *cfg = irqd_cfg(data);
const cpumask_t *affinity;
int cpu;
u64 status;
int ret;
msidesc = irq_data_get_msi_desc(data);
dev = msi_desc_to_pci_dev(msidesc);
@@ -204,9 +227,6 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
return;
}
affinity = irq_data_get_effective_affinity_mask(data);
cpu = cpumask_first_and(affinity, cpu_online_mask);
if (data->chip_data) {
/*
* This interrupt is already mapped. Let's unmap first.
@@ -219,14 +239,12 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
stored_entry = data->chip_data;
data->chip_data = NULL;
status = hv_unmap_msi_interrupt(dev, stored_entry);
ret = hv_unmap_msi_interrupt(dev, stored_entry);
kfree(stored_entry);
if (status != HV_STATUS_SUCCESS) {
hv_status_debug(status, "failed to unmap\n");
if (ret)
return;
}
}
stored_entry = kzalloc(sizeof(*stored_entry), GFP_ATOMIC);
@@ -235,15 +253,14 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
return;
}
status = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry);
if (status != HV_STATUS_SUCCESS) {
ret = hv_map_msi_interrupt(data, stored_entry);
if (ret) {
kfree(stored_entry);
return;
}
*stored_entry = out_entry;
data->chip_data = stored_entry;
entry_to_msi_msg(&out_entry, msg);
entry_to_msi_msg(data->chip_data, msg);
return;
}
@@ -257,7 +274,6 @@ static void hv_teardown_msi_irq(struct pci_dev *dev, struct irq_data *irqd)
{
struct hv_interrupt_entry old_entry;
struct msi_msg msg;
u64 status;
if (!irqd->chip_data) {
pr_debug("%s: no chip data\n!", __func__);
@@ -270,10 +286,7 @@ static void hv_teardown_msi_irq(struct pci_dev *dev, struct irq_data *irqd)
kfree(irqd->chip_data);
irqd->chip_data = NULL;
status = hv_unmap_msi_interrupt(dev, &old_entry);
if (status != HV_STATUS_SUCCESS)
hv_status_err(status, "\n");
(void)hv_unmap_msi_interrupt(dev, &old_entry);
}
static void hv_msi_free_irq(struct irq_domain *domain,
+1
View File
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <linux/export.h>
#include <asm/svm.h>
#include <asm/sev.h>
#include <asm/io.h>
+1
View File
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/export.h>
#include <hyperv/hvhdk.h>
#include <asm/mshyperv.h>
#include <asm/tlbflush.h>
+2 -20
View File
@@ -112,12 +112,6 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
return hv_status;
}
/* Hypercall to the L0 hypervisor */
static inline u64 hv_do_nested_hypercall(u64 control, void *input, void *output)
{
return hv_do_hypercall(control | HV_HYPERCALL_NESTED, input, output);
}
/* Fast hypercall with 8 bytes of input and no output */
static inline u64 _hv_do_fast_hypercall8(u64 control, u64 input1)
{
@@ -165,13 +159,6 @@ static inline u64 hv_do_fast_hypercall8(u16 code, u64 input1)
return _hv_do_fast_hypercall8(control, input1);
}
static inline u64 hv_do_fast_nested_hypercall8(u16 code, u64 input1)
{
u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
return _hv_do_fast_hypercall8(control, input1);
}
/* Fast hypercall with 16 bytes of input */
static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
{
@@ -223,13 +210,6 @@ static inline u64 hv_do_fast_hypercall16(u16 code, u64 input1, u64 input2)
return _hv_do_fast_hypercall16(control, input1, input2);
}
static inline u64 hv_do_fast_nested_hypercall16(u16 code, u64 input1, u64 input2)
{
u64 control = (u64)code | HV_HYPERCALL_FAST_BIT | HV_HYPERCALL_NESTED;
return _hv_do_fast_hypercall16(control, input1, input2);
}
extern struct hv_vp_assist_page **hv_vp_assist_page;
static inline struct hv_vp_assist_page *hv_get_vp_assist_page(unsigned int cpu)
@@ -262,6 +242,8 @@ static inline void hv_apic_init(void) {}
struct irq_domain *hv_create_pci_msi_domain(void);
int hv_map_msi_interrupt(struct irq_data *data,
struct hv_interrupt_entry *out_entry);
int hv_map_ioapic_interrupt(int ioapic_id, bool level, int vcpu, int vector,
struct hv_interrupt_entry *entry);
int hv_unmap_ioapic_interrupt(int ioapic_id, struct hv_interrupt_entry *entry);
+1
View File
@@ -22,6 +22,7 @@
#include <linux/irq.h>
#include <linux/acpi.h>
#include <linux/hyperv.h>
#include <linux/export.h>
#include <clocksource/hyperv_timer.h>
#include <hyperv/hvhdk.h>
#include <asm/mshyperv.h>
+1 -1
View File
@@ -9,7 +9,7 @@ config HYPERV
select PARAVIRT
select X86_HV_CALLBACK_VECTOR if X86
select OF_EARLY_FLATTREE if OF
select SYSFB if !HYPERV_VTL_MODE
select SYSFB if EFI && !HYPERV_VTL_MODE
help
Select this option to run Linux as a Hyper-V client operating
system.
+1
View File
@@ -18,6 +18,7 @@
#include <linux/uio.h>
#include <linux/interrupt.h>
#include <linux/set_memory.h>
#include <linux/export.h>
#include <asm/page.h>
#include <asm/mshyperv.h>
+1
View File
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/cpu.h>
#include <linux/hyperv.h>
#include <linux/export.h>
#include <asm/mshyperv.h>
#include <linux/sched/isolation.h>
+4 -1
View File
@@ -519,7 +519,10 @@ void vmbus_set_event(struct vmbus_channel *channel)
else
WARN_ON_ONCE(1);
} else {
hv_do_fast_hypercall8(HVCALL_SIGNAL_EVENT, channel->sig_event);
u64 control = HVCALL_SIGNAL_EVENT;
control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
hv_do_fast_hypercall8(control, channel->sig_event);
}
}
EXPORT_SYMBOL_GPL(vmbus_set_event);
+4 -2
View File
@@ -85,8 +85,10 @@ int hv_post_message(union hv_connection_id connection_id,
else
status = HV_STATUS_INVALID_PARAMETER;
} else {
status = hv_do_hypercall(HVCALL_POST_MESSAGE,
aligned_msg, NULL);
u64 control = HVCALL_POST_MESSAGE;
control |= hv_nested ? HV_HYPERCALL_NESTED : 0;
status = hv_do_hypercall(control, aligned_msg, NULL);
}
local_irq_restore(flags);
+1
View File
@@ -6,6 +6,7 @@
#include <linux/slab.h>
#include <linux/cpuhotplug.h>
#include <linux/minmax.h>
#include <linux/export.h>
#include <asm/mshyperv.h>
/*
+1
View File
@@ -13,6 +13,7 @@
#include <linux/mm.h>
#include <asm/mshyperv.h>
#include <linux/resume_user_mode.h>
#include <linux/export.h>
#include "mshv.h"
+1
View File
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/export.h>
#include <asm/mshyperv.h>
#include "mshv_root.h"
+1
View File
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/prefetch.h>
#include <linux/io.h>
#include <linux/export.h>
#include <asm/mshyperv.h>
#include "hyperv_vmbus.h"
+5 -4
View File
@@ -2509,7 +2509,7 @@ static int vmbus_acpi_add(struct platform_device *pdev)
return 0;
}
#endif
#ifndef HYPERVISOR_CALLBACK_VECTOR
static int vmbus_set_irq(struct platform_device *pdev)
{
struct irq_data *data;
@@ -2534,6 +2534,7 @@ static int vmbus_set_irq(struct platform_device *pdev)
return 0;
}
#endif
static int vmbus_device_add(struct platform_device *pdev)
{
@@ -2549,11 +2550,11 @@ static int vmbus_device_add(struct platform_device *pdev)
if (ret)
return ret;
if (!__is_defined(HYPERVISOR_CALLBACK_VECTOR))
ret = vmbus_set_irq(pdev);
#ifndef HYPERVISOR_CALLBACK_VECTOR
ret = vmbus_set_irq(pdev);
if (ret)
return ret;
#endif
for_each_of_range(&parser, &range) {
struct resource *res;
+12 -21
View File
@@ -193,15 +193,13 @@ struct hyperv_root_ir_data {
static void
hyperv_root_ir_compose_msi_msg(struct irq_data *irq_data, struct msi_msg *msg)
{
u64 status;
u32 vector;
struct irq_cfg *cfg;
int ioapic_id;
const struct cpumask *affinity;
int cpu;
struct hv_interrupt_entry entry;
struct hyperv_root_ir_data *data = irq_data->chip_data;
struct hv_interrupt_entry entry;
const struct cpumask *affinity;
struct IO_APIC_route_entry e;
struct irq_cfg *cfg;
int cpu, ioapic_id;
u32 vector;
cfg = irqd_cfg(irq_data);
affinity = irq_data_get_effective_affinity_mask(irq_data);
@@ -214,23 +212,16 @@ hyperv_root_ir_compose_msi_msg(struct irq_data *irq_data, struct msi_msg *msg)
&& data->entry.ioapic_rte.as_uint64) {
entry = data->entry;
status = hv_unmap_ioapic_interrupt(ioapic_id, &entry);
if (status != HV_STATUS_SUCCESS)
hv_status_debug(status, "failed to unmap\n");
(void)hv_unmap_ioapic_interrupt(ioapic_id, &entry);
data->entry.ioapic_rte.as_uint64 = 0;
data->entry.source = 0; /* Invalid source */
}
status = hv_map_ioapic_interrupt(ioapic_id, data->is_level, cpu,
vector, &entry);
if (status != HV_STATUS_SUCCESS) {
hv_status_err(status, "map failed\n");
if (hv_map_ioapic_interrupt(ioapic_id, data->is_level, cpu,
vector, &entry))
return;
}
data->entry = entry;
@@ -322,10 +313,10 @@ static void hyperv_root_irq_remapping_free(struct irq_domain *domain,
data = irq_data->chip_data;
e = &data->entry;
if (e->source == HV_DEVICE_TYPE_IOAPIC
&& e->ioapic_rte.as_uint64)
hv_unmap_ioapic_interrupt(data->ioapic_id,
&data->entry);
if (e->source == HV_DEVICE_TYPE_IOAPIC &&
e->ioapic_rte.as_uint64)
(void)hv_unmap_ioapic_interrupt(data->ioapic_id,
&data->entry);
kfree(data);
}
@@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <linux/utsname.h>
#include <linux/version.h>
#include <linux/export.h>
#include <net/mana/mana.h>
@@ -10,6 +10,7 @@
#include <linux/filter.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/export.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
+1
View File
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hyperv.h>
#include <linux/export.h>
struct hyperv_pci_block_ops hvpci_block_ops;
EXPORT_SYMBOL_GPL(hvpci_block_ops);
+19 -2
View File
@@ -600,7 +600,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
#define hv_msi_prepare pci_msi_prepare
/**
* hv_arch_irq_unmask() - "Unmask" the IRQ by setting its current
* hv_irq_retarget_interrupt() - "Unmask" the IRQ by setting its current
* affinity.
* @data: Describes the IRQ
*
@@ -609,7 +609,7 @@ static unsigned int hv_msi_get_int_vector(struct irq_data *data)
* is built out of this PCI bus's instance GUID and the function
* number of the device.
*/
static void hv_arch_irq_unmask(struct irq_data *data)
static void hv_irq_retarget_interrupt(struct irq_data *data)
{
struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
struct hv_retarget_device_interrupt *params;
@@ -714,6 +714,20 @@ out:
dev_err(&hbus->hdev->device,
"%s() failed: %#llx", __func__, res);
}
static void hv_arch_irq_unmask(struct irq_data *data)
{
if (hv_root_partition())
/*
* In case of the nested root partition, the nested hypervisor
* is taking care of interrupt remapping and thus the
* MAP_DEVICE_INTERRUPT hypercall is required instead of
* RETARGET_INTERRUPT.
*/
(void)hv_map_msi_interrupt(data, NULL);
else
hv_irq_retarget_interrupt(data);
}
#elif defined(CONFIG_ARM64)
/*
* SPI vectors to use for vPCI; arch SPIs range is [32, 1019], but leaving a bit
@@ -4144,6 +4158,9 @@ static int __init init_hv_pci_drv(void)
if (!hv_is_hyperv_initialized())
return -ENODEV;
if (hv_root_partition() && !hv_nested)
return -ENODEV;
ret = hv_pci_irqchip_init();
if (ret)
return ret;
+95 -33
View File
@@ -35,7 +35,10 @@
#define WIN8_SRV_MINOR 1
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
#define FCOPY_UIO "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio"
#define FCOPY_DEVICE_PATH(subdir) \
"/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/" #subdir
#define FCOPY_UIO_PATH FCOPY_DEVICE_PATH(uio)
#define FCOPY_CHANNELS_PATH FCOPY_DEVICE_PATH(channels)
#define FCOPY_VER_COUNT 1
static const int fcopy_versions[] = {
@@ -47,9 +50,62 @@ static const int fw_versions[] = {
UTIL_FW_VERSION
};
#define HV_RING_SIZE 0x4000 /* 16KB ring buffer size */
static uint32_t get_ring_buffer_size(void)
{
char ring_path[PATH_MAX];
DIR *dir;
struct dirent *entry;
struct stat st;
uint32_t ring_size = 0;
int retry_count = 0;
static unsigned char desc[HV_RING_SIZE];
/* Find the channel directory */
dir = opendir(FCOPY_CHANNELS_PATH);
if (!dir) {
usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */
dir = opendir(FCOPY_CHANNELS_PATH);
if (!dir) {
syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno));
return 0;
}
}
retry_once:
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0) {
snprintf(ring_path, sizeof(ring_path), "%s/%s/ring",
FCOPY_CHANNELS_PATH, entry->d_name);
if (stat(ring_path, &st) == 0) {
/*
* stat returns size of Tx, Rx rings combined,
* so take half of it for individual ring size.
*/
ring_size = (uint32_t)st.st_size / 2;
syslog(LOG_INFO, "Ring buffer size from %s: %u bytes",
ring_path, ring_size);
break;
}
}
}
if (!ring_size && retry_count == 0) {
retry_count = 1;
rewinddir(dir);
usleep(100 * 1000); /* Wait 100ms and retry once */
goto retry_once;
}
closedir(dir);
if (!ring_size)
syslog(LOG_ERR, "Could not determine ring size");
return ring_size;
}
static unsigned char *desc;
static int target_fd;
static char target_fname[PATH_MAX];
@@ -62,8 +118,11 @@ static int hv_fcopy_create_file(char *file_name, char *path_name, __u32 flags)
filesize = 0;
p = path_name;
snprintf(target_fname, sizeof(target_fname), "%s/%s",
path_name, file_name);
if (snprintf(target_fname, sizeof(target_fname), "%s/%s",
path_name, file_name) >= sizeof(target_fname)) {
syslog(LOG_ERR, "target file name is too long: %s/%s", path_name, file_name);
goto done;
}
/*
* Check to see if the path is already in place; if not,
@@ -270,7 +329,7 @@ static void wcstoutf8(char *dest, const __u16 *src, size_t dest_size)
{
size_t len = 0;
while (len < dest_size) {
while (len < dest_size && *src) {
if (src[len] < 0x80)
dest[len++] = (char)(*src++);
else
@@ -282,27 +341,15 @@ static void wcstoutf8(char *dest, const __u16 *src, size_t dest_size)
static int hv_fcopy_start(struct hv_start_fcopy *smsg_in)
{
/*
* file_name and path_name should have same length with appropriate
* member of hv_start_fcopy.
*/
char file_name[W_MAX_PATH], path_name[W_MAX_PATH];
setlocale(LC_ALL, "en_US.utf8");
size_t file_size, path_size;
char *file_name, *path_name;
char *in_file_name = (char *)smsg_in->file_name;
char *in_path_name = (char *)smsg_in->path_name;
file_size = wcstombs(NULL, (const wchar_t *restrict)in_file_name, 0) + 1;
path_size = wcstombs(NULL, (const wchar_t *restrict)in_path_name, 0) + 1;
file_name = (char *)malloc(file_size * sizeof(char));
path_name = (char *)malloc(path_size * sizeof(char));
if (!file_name || !path_name) {
free(file_name);
free(path_name);
syslog(LOG_ERR, "Can't allocate memory for file name and/or path name");
return HV_E_FAIL;
}
wcstoutf8(file_name, (__u16 *)in_file_name, file_size);
wcstoutf8(path_name, (__u16 *)in_path_name, path_size);
wcstoutf8(file_name, smsg_in->file_name, W_MAX_PATH - 1);
wcstoutf8(path_name, smsg_in->path_name, W_MAX_PATH - 1);
return hv_fcopy_create_file(file_name, path_name, smsg_in->copy_flags);
}
@@ -406,7 +453,7 @@ int main(int argc, char *argv[])
int daemonize = 1, long_index = 0, opt, ret = -EINVAL;
struct vmbus_br txbr, rxbr;
void *ring;
uint32_t len = HV_RING_SIZE;
uint32_t ring_size, len;
char uio_name[NAME_MAX] = {0};
char uio_dev_path[PATH_MAX] = {0};
@@ -437,7 +484,20 @@ int main(int argc, char *argv[])
openlog("HV_UIO_FCOPY", 0, LOG_USER);
syslog(LOG_INFO, "starting; pid is:%d", getpid());
fcopy_get_first_folder(FCOPY_UIO, uio_name);
ring_size = get_ring_buffer_size();
if (!ring_size) {
ret = -ENODEV;
goto exit;
}
desc = malloc(ring_size * sizeof(unsigned char));
if (!desc) {
syslog(LOG_ERR, "malloc failed for desc buffer");
ret = -ENOMEM;
goto exit;
}
fcopy_get_first_folder(FCOPY_UIO_PATH, uio_name);
snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
fcopy_fd = open(uio_dev_path, O_RDWR);
@@ -445,17 +505,17 @@ int main(int argc, char *argv[])
syslog(LOG_ERR, "open %s failed; error: %d %s",
uio_dev_path, errno, strerror(errno));
ret = fcopy_fd;
goto exit;
goto free_desc;
}
ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
ring = vmbus_uio_map(&fcopy_fd, ring_size);
if (!ring) {
ret = errno;
syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret));
goto close;
}
vmbus_br_setup(&txbr, ring, HV_RING_SIZE);
vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE);
vmbus_br_setup(&txbr, ring, ring_size);
vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size);
rxbr.vbr->imask = 0;
@@ -472,7 +532,7 @@ int main(int argc, char *argv[])
goto close;
}
len = HV_RING_SIZE;
len = ring_size;
ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
if (unlikely(ret <= 0)) {
/* This indicates a failure to communicate (or worse) */
@@ -492,6 +552,8 @@ int main(int argc, char *argv[])
}
close:
close(fcopy_fd);
free_desc:
free(desc);
exit:
return ret;
}