[PATCH 1/2] Drivers: hv: vmbus: check the creation_status in vmbus_establish_gpadl()

2018-11-25 Thread kys
From: Dexuan Cui 

This is a longstanding issue: if the vmbus upper-layer drivers try to
consume too many GPADLs, the host may return with an error
0xC044 (STATUS_QUOTA_EXCEEDED), but currently we forget to check
the creation_status, and hence we can pass an invalid GPADL handle
into the OPEN_CHANNEL message, and get an error code 0xc225 in
open_info->response.open_result.status, and finally we hang in
vmbus_open() -> "goto error_free_info" -> vmbus_teardown_gpadl().

With this patch, we can exit gracefully on STATUS_QUOTA_EXCEEDED.

Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: sta...@vger.kernel.org
Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index f96a77b18bb9..ce0ba2062723 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -516,6 +516,14 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, 
void *kbuffer,
}
wait_for_completion(&msginfo->waitevent);
 
+   if (msginfo->response.gpadl_created.creation_status != 0) {
+   pr_err("Failed to establish GPADL: err = 0x%x\n",
+  msginfo->response.gpadl_created.creation_status);
+
+   ret = -EDQUOT;
+   goto cleanup;
+   }
+
if (channel->rescind) {
ret = -ENODEV;
goto cleanup;
-- 
2.19.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] Drivers: hv: vmbus: offload the handling of channels to two workqueues

2018-11-25 Thread kys
From: Dexuan Cui 

vmbus_process_offer() mustn't call channel->sc_creation_callback()
directly for sub-channels, because sc_creation_callback() ->
vmbus_open() may never get the host's response to the
OPEN_CHANNEL message (the host may rescind a channel at any time,
e.g. in the case of hot removing a NIC), and vmbus_onoffer_rescind()
may not wake up the vmbus_open() as it's blocked due to a non-zero
vmbus_connection.offer_in_progress, and finally we have a deadlock.

The above is also true for primary channels, if the related device
drivers use sync probing mode by default.

And, usually the handling of primary channels and sub-channels can
depend on each other, so we should offload them to different
workqueues to avoid possible deadlock, e.g. in sync-probing mode,
NIC1's netvsc_subchan_work() can race with NIC2's netvsc_probe() ->
rtnl_lock(), and causes deadlock: the former gets the rtnl_lock
and waits for all the sub-channels to appear, but the latter
can't get the rtnl_lock and this blocks the handling of sub-channels.

The patch can fix the multiple-NIC deadlock described above for
v3.x kernels (e.g. RHEL 7.x) which don't support async-probing
of devices, and v4.4, v4.9, v4.14 and v4.18 which support async-probing
but don't enable async-probing for Hyper-V drivers (yet).

The patch can also fix the hang issue in sub-channel's handling described
above for all versions of kernels, including v4.19 and v4.20-rc3.

So the patch should be applied to all the existing kernels.

Fixes: 8195b1396ec8 ("hv_netvsc: fix deadlock on hotplug")
Cc: sta...@vger.kernel.org
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel_mgmt.c | 188 +-
 drivers/hv/connection.c   |  24 -
 drivers/hv/hyperv_vmbus.h |   7 ++
 include/linux/hyperv.h|   7 ++
 4 files changed, 161 insertions(+), 65 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 82e673671087..d01689079e9b 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -434,60 +434,16 @@ void vmbus_free_channels(void)
}
 }
 
-/*
- * vmbus_process_offer - Process the offer by creating a channel/device
- * associated with this offer
- */
-static void vmbus_process_offer(struct vmbus_channel *newchannel)
+/* Note: the function can run concurrently for primary/sub channels. */
+static void vmbus_add_channel_work(struct work_struct *work)
 {
-   struct vmbus_channel *channel;
-   bool fnew = true;
+   struct vmbus_channel *newchannel =
+   container_of(work, struct vmbus_channel, add_channel_work);
+   struct vmbus_channel *primary_channel = newchannel->primary_channel;
unsigned long flags;
u16 dev_type;
int ret;
 
-   /* Make sure this is a new offer */
-   mutex_lock(&vmbus_connection.channel_mutex);
-
-   /*
-* Now that we have acquired the channel_mutex,
-* we can release the potentially racing rescind thread.
-*/
-   atomic_dec(&vmbus_connection.offer_in_progress);
-
-   list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
-   if (!uuid_le_cmp(channel->offermsg.offer.if_type,
-   newchannel->offermsg.offer.if_type) &&
-   !uuid_le_cmp(channel->offermsg.offer.if_instance,
-   newchannel->offermsg.offer.if_instance)) {
-   fnew = false;
-   break;
-   }
-   }
-
-   if (fnew)
-   list_add_tail(&newchannel->listentry,
- &vmbus_connection.chn_list);
-
-   mutex_unlock(&vmbus_connection.channel_mutex);
-
-   if (!fnew) {
-   /*
-* Check to see if this is a sub-channel.
-*/
-   if (newchannel->offermsg.offer.sub_channel_index != 0) {
-   /*
-* Process the sub-channel.
-*/
-   newchannel->primary_channel = channel;
-   spin_lock_irqsave(&channel->lock, flags);
-   list_add_tail(&newchannel->sc_list, &channel->sc_list);
-   spin_unlock_irqrestore(&channel->lock, flags);
-   } else {
-   goto err_free_chan;
-   }
-   }
-
dev_type = hv_get_dev_type(newchannel);
 
init_vp_index(newchannel, dev_type);
@@ -505,27 +461,26 @@ static void vmbus_process_offer(struct vmbus_channel 
*newchannel)
/*
 * This state is used to indicate a successful open
 * so that when we do close the channel normally, we
-* can cleanup properly
+* can cleanup properly.
 */
newchannel->state = CHANNEL_OPEN_STATE;
 
-   if (!fnew) {
-   struct hv_device *dev
-   = newchann

[PATCH 0/2] Drivers: hv: vmbus: Miscellaneous fixes

2018-11-25 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes.

Dexuan Cui (2):
  Drivers: hv: vmbus: check the creation_status in
vmbus_establish_gpadl()
  Drivers: hv: vmbus: offload the handling of channels to two workqueues

 drivers/hv/channel.c  |   8 ++
 drivers/hv/channel_mgmt.c | 188 +-
 drivers/hv/connection.c   |  24 -
 drivers/hv/hyperv_vmbus.h |   7 ++
 include/linux/hyperv.h|   7 ++
 5 files changed, 169 insertions(+), 65 deletions(-)

-- 
2.19.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] Drivers: hv: vmbus: Remove the useless API vmbus_get_outgoing_channel()

2018-11-25 Thread kys
From: Dexuan Cui 

Commit d86adf482b84 ("scsi: storvsc: Enable multi-queue support") removed
the usage of the API in Jan 2017, and the API is not used since then.

netvsc and storvsc have their own algorithms to determine the outgoing
channel, so this API is useless.

And the API is potentially unsafe, because it reads primary->num_sc without
any lock held. This can be risky considering the RESCIND-OFFER message.

Let's remove the API.

Cc: Long Li 
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c  |  1 -
 drivers/hv/channel_mgmt.c | 45 ---
 include/linux/hyperv.h| 17 ---
 3 files changed, 63 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index de8193f3b838..f96a77b18bb9 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -703,7 +703,6 @@ int vmbus_disconnect_ring(struct vmbus_channel *channel)
/* Snapshot the list of subchannels */
spin_lock_irqsave(&channel->lock, flags);
list_splice_init(&channel->sc_list, &list);
-   channel->num_sc = 0;
spin_unlock_irqrestore(&channel->lock, flags);
 
list_for_each_entry_safe(cur_channel, tmp, &list, sc_list) {
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 6277597d3d58..82e673671087 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -405,7 +405,6 @@ void hv_process_channel_removal(struct vmbus_channel 
*channel)
primary_channel = channel->primary_channel;
spin_lock_irqsave(&primary_channel->lock, flags);
list_del(&channel->sc_list);
-   primary_channel->num_sc--;
spin_unlock_irqrestore(&primary_channel->lock, flags);
}
 
@@ -483,7 +482,6 @@ static void vmbus_process_offer(struct vmbus_channel 
*newchannel)
newchannel->primary_channel = channel;
spin_lock_irqsave(&channel->lock, flags);
list_add_tail(&newchannel->sc_list, &channel->sc_list);
-   channel->num_sc++;
spin_unlock_irqrestore(&channel->lock, flags);
} else {
goto err_free_chan;
@@ -1239,49 +1237,6 @@ int vmbus_request_offers(void)
return ret;
 }
 
-/*
- * Retrieve the (sub) channel on which to send an outgoing request.
- * When a primary channel has multiple sub-channels, we try to
- * distribute the load equally amongst all available channels.
- */
-struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary)
-{
-   struct list_head *cur, *tmp;
-   int cur_cpu;
-   struct vmbus_channel *cur_channel;
-   struct vmbus_channel *outgoing_channel = primary;
-   int next_channel;
-   int i = 1;
-
-   if (list_empty(&primary->sc_list))
-   return outgoing_channel;
-
-   next_channel = primary->next_oc++;
-
-   if (next_channel > (primary->num_sc)) {
-   primary->next_oc = 0;
-   return outgoing_channel;
-   }
-
-   cur_cpu = hv_cpu_number_to_vp_number(smp_processor_id());
-   list_for_each_safe(cur, tmp, &primary->sc_list) {
-   cur_channel = list_entry(cur, struct vmbus_channel, sc_list);
-   if (cur_channel->state != CHANNEL_OPENED_STATE)
-   continue;
-
-   if (cur_channel->target_vp == cur_cpu)
-   return cur_channel;
-
-   if (i == next_channel)
-   return cur_channel;
-
-   i++;
-   }
-
-   return outgoing_channel;
-}
-EXPORT_SYMBOL_GPL(vmbus_get_outgoing_channel);
-
 static void invoke_sc_cb(struct vmbus_channel *primary_channel)
 {
struct list_head *cur, *tmp;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index b3e24368930a..07a367f5e22f 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -830,15 +830,6 @@ struct vmbus_channel {
 * All Sub-channels of a primary channel are linked here.
 */
struct list_head sc_list;
-   /*
-* Current number of sub-channels.
-*/
-   int num_sc;
-   /*
-* Number of a sub-channel (position within sc_list) which is supposed
-* to be used as the next outgoing channel.
-*/
-   int next_oc;
/*
 * The primary channel this sub-channel belongs to.
 * This will be NULL for the primary channel.
@@ -965,14 +956,6 @@ void vmbus_set_sc_create_callback(struct vmbus_channel 
*primary_channel,
 void vmbus_set_chn_rescind_callback(struct vmbus_channel *channel,
void (*chn_rescind_cb)(struct vmbus_channel *));
 
-/*
- * Retrieve the (sub) channel on which to send an outgoing request.
- * When a primary channel has multiple sub-channels, we choose a
- * channel whose VCPU binding is clos

[PATCH] scsi: storvsc: Fix a race in sub-channel creation that can cause panic

2018-11-25 Thread kys
From: Dexuan Cui 

We can concurrently try to open the same sub-channel from 2 paths:

path #1: vmbus_onoffer() -> vmbus_process_offer() -> handle_sc_creation().
path #2: storvsc_probe() -> storvsc_connect_to_vsp() ->
 -> storvsc_channel_init() -> handle_multichannel_storage() ->
 -> vmbus_are_subchannels_present() -> handle_sc_creation().

They conflict with each other, but it was not an issue before the recent
commit ae6935ed7d42 ("vmbus: split ring buffer allocation from open"),
because at the beginning of vmbus_open() we checked newchannel->state so
only one path could succeed, and the other would return with -EINVAL.

After ae6935ed7d42, the failing path frees the channel's ringbuffer by
vmbus_free_ring(), and this causes a panic later.

Commit ae6935ed7d42 itself is good, and it just reveals the longstanding
race. We can resolve the issue by removing path #2, i.e. removing the
second vmbus_are_subchannels_present() in handle_multichannel_storage().

BTW, the comment "Check to see if sub-channels have already been created"
in handle_multichannel_storage() is incorrect: when we unload the driver,
we first close the sub-channel(s) and then close the primary channel, next
the host sends rescind-offer message(s) so primary->sc_list will become
empty. This means the first vmbus_are_subchannels_present() in
handle_multichannel_storage() is never useful.

Fixes: ae6935ed7d42 ("vmbus: split ring buffer allocation from open")
Cc: sta...@vger.kernel.org
Cc: Long Li 
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Signed-off-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/scsi/storvsc_drv.c | 61 +++---
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f03dc03a42c3..8f88348ebe42 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -446,7 +446,6 @@ struct storvsc_device {
 
bool destroy;
bool drain_notify;
-   bool open_sub_channel;
atomic_t num_outstanding_req;
struct Scsi_Host *host;
 
@@ -636,33 +635,38 @@ static inline struct storvsc_device *get_in_stor_device(
 static void handle_sc_creation(struct vmbus_channel *new_sc)
 {
struct hv_device *device = new_sc->primary_channel->device_obj;
+   struct device *dev = &device->device;
struct storvsc_device *stor_device;
struct vmstorage_channel_properties props;
+   int ret;
 
stor_device = get_out_stor_device(device);
if (!stor_device)
return;
 
-   if (stor_device->open_sub_channel == false)
-   return;
-
memset(&props, 0, sizeof(struct vmstorage_channel_properties));
 
-   vmbus_open(new_sc,
-  storvsc_ringbuffer_size,
-  storvsc_ringbuffer_size,
-  (void *)&props,
-  sizeof(struct vmstorage_channel_properties),
-  storvsc_on_channel_callback, new_sc);
+   ret = vmbus_open(new_sc,
+storvsc_ringbuffer_size,
+storvsc_ringbuffer_size,
+(void *)&props,
+sizeof(struct vmstorage_channel_properties),
+storvsc_on_channel_callback, new_sc);
 
-   if (new_sc->state == CHANNEL_OPENED_STATE) {
-   stor_device->stor_chns[new_sc->target_cpu] = new_sc;
-   cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus);
+   /* In case vmbus_open() fails, we don't use the sub-channel. */
+   if (ret != 0) {
+   dev_err(dev, "Failed to open sub-channel: err=%d\n", ret);
+   return;
}
+
+   /* Add the sub-channel to the array of available channels. */
+   stor_device->stor_chns[new_sc->target_cpu] = new_sc;
+   cpumask_set_cpu(new_sc->target_cpu, &stor_device->alloced_cpus);
 }
 
 static void  handle_multichannel_storage(struct hv_device *device, int 
max_chns)
 {
+   struct device *dev = &device->device;
struct storvsc_device *stor_device;
int num_cpus = num_online_cpus();
int num_sc;
@@ -679,21 +683,11 @@ static void  handle_multichannel_storage(struct hv_device 
*device, int max_chns)
request = &stor_device->init_request;
vstor_packet = &request->vstor_packet;
 
-   stor_device->open_sub_channel = true;
/*
 * Establish a handler for dealing with subchannels.
 */
vmbus_set_sc_create_callback(device->channel, handle_sc_creation);
 
-   /*
-* Check to see if sub-channels have already been created. This
-* can happen when this driver is re-loaded after unloading.
-*/
-
-   if (vmbus_are_subchannels_present(device->channel))
-   return;
-
-   stor_device->open_sub_channel = false;
/*
 * Request the host to create sub-channels.
 */
@@ -710,23 +

[PATCH 4/4] Drivers: hv: Enable CONFIG_HYPERV on ARM64

2018-11-21 Thread kys
From: Michael Kelley 

Update drivers/hv/Kconfig so CONFIG_HYPERV can be selected on ARM64,
causing the Hyper-V specific code to be built.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/Kconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 97954f575c3f..c3e11a2f9c70 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -4,7 +4,8 @@ menu "Microsoft Hyper-V guest support"
 
 config HYPERV
tristate "Microsoft Hyper-V client drivers"
-   depends on X86 && ACPI && PCI && X86_LOCAL_APIC && HYPERVISOR_GUEST
+   depends on ACPI && PCI && \
+   ((X86 && X86_LOCAL_APIC && HYPERVISOR_GUEST) || ARM64)
select PARAVIRT
help
  Select this option to run Linux as a Hyper-V client operating
-- 
2.19.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/4] arm64: hyperv: Add support for Hyper-V as a hypervisor

2018-11-21 Thread kys
From: Michael Kelley 

Add ARM64-specific code to enable Hyper-V. This code includes:
* Detecting Hyper-V and initializing the guest/Hyper-V interface
* Setting up Hyper-V's synthetic clocks
* Making hypercalls using the HVC instruction
* Setting up VMbus and stimer0 interrupts
* Setting up kexec and crash handlers
This code is architecture dependent code and is mostly driven by
architecture independent code in the VMbus driver in drivers/hv/hv.c
and drivers/hv/vmbus_drv.c.

This code is built only when CONFIG_HYPERV is enabled.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 MAINTAINERS  |   1 +
 arch/arm64/Makefile  |   1 +
 arch/arm64/hyperv/Makefile   |   2 +
 arch/arm64/hyperv/hv_hvc.S   |  54 +
 arch/arm64/hyperv/hv_init.c  | 441 +++
 arch/arm64/hyperv/mshyperv.c | 178 ++
 6 files changed, 677 insertions(+)
 create mode 100644 arch/arm64/hyperv/Makefile
 create mode 100644 arch/arm64/hyperv/hv_hvc.S
 create mode 100644 arch/arm64/hyperv/hv_init.c
 create mode 100644 arch/arm64/hyperv/mshyperv.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 72f19cef4c48..326eeb32a0cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6837,6 +6837,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: arch/x86/hyperv
 F: arch/arm64/include/asm/hyperv-tlfs.h
 F: arch/arm64/include/asm/mshyperv.h
+F: arch/arm64/hyperv
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 6cb9fc7e9382..ad9ec0579553 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -106,6 +106,7 @@ core-y  += arch/arm64/kernel/ arch/arm64/mm/
 core-$(CONFIG_NET) += arch/arm64/net/
 core-$(CONFIG_KVM) += arch/arm64/kvm/
 core-$(CONFIG_XEN) += arch/arm64/xen/
+core-$(CONFIG_HYPERV) += arch/arm64/hyperv/
 core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
 libs-y := arch/arm64/lib/ $(libs-y)
 core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
diff --git a/arch/arm64/hyperv/Makefile b/arch/arm64/hyperv/Makefile
new file mode 100644
index ..988eda55330c
--- /dev/null
+++ b/arch/arm64/hyperv/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y  := hv_init.o hv_hvc.o mshyperv.o
diff --git a/arch/arm64/hyperv/hv_hvc.S b/arch/arm64/hyperv/hv_hvc.S
new file mode 100644
index ..82636969b4f2
--- /dev/null
+++ b/arch/arm64/hyperv/hv_hvc.S
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * Microsoft Hyper-V hypervisor invocation routines
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : Michael Kelley 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ */
+
+#include 
+
+   .text
+/*
+ * Do the HVC instruction.  For Hyper-V the argument is always 1.
+ * x0 contains the hypercall control value, while additional registers
+ * vary depending on the hypercall, and whether the hypercall arguments
+ * are in memory or in registers (a "fast" hypercall per the Hyper-V
+ * TLFS).  When the arguments are in memory x1 is the guest physical
+ * address of the input arguments, and x2 is the guest physical
+ * address of the output arguments.  When the arguments are in
+ * registers, the register values depends on the hypercall.  Note
+ * that this version cannot return any values in registers.
+ */
+ENTRY(hv_do_hvc)
+   hvc #1
+   ret
+ENDPROC(hv_do_hvc)
+
+/*
+ * This variant of HVC invocation is for hv_get_vpreg and
+ * hv_get_vpreg_128. The input parameters are passed in registers
+ * along with a pointer in x4 to where the output result should
+ * be stored. The output is returned in x15 and x16.  x18 is used as
+ * scratch space to avoid buildng a stack frame, as Hyper-V does
+ * not preserve registers x0-x17.
+ */
+ENTRY(hv_do_hvc_fast_get)
+   mov x18, x4
+   hvc #1
+   str x15,[x18]
+   str x16,[x18,#8]
+   ret
+ENDPROC(hv_do_hvc_fast_get)
diff --git a/arch/arm64/hyperv/hv_init.c b/arch/arm64/hyperv/hv_init.c
new file mode 100644
index ..aa1a8c09d989
--- /dev/null
+++ b/arch/arm64/hyperv/hv_init.c
@@ -0,0 +1,441 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Initialization of the interface with Microsoft's Hyper-V hypervisor,
+ * and various low level utility routines for interacting with Hyper-V.
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : Michael Kelley 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GN

[PATCH 3/4] Drivers: hv: vmbus: Add hooks for per-CPU IRQ

2018-11-21 Thread kys
From: Michael Kelley 

Add hooks to enable/disable a per-CPU IRQ for VMbus. These hooks
are in the architecture independent setup and shutdown paths for
Hyper-V, and are needed by Linux guests on Hyper-V on ARM64.  The
x86/x64 implementation is null because VMbus interrupts on x86/x64
don't use an IRQ.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/include/asm/mshyperv.h | 4 
 drivers/hv/hv.c | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 0d6271cce198..8d97bd3a13a6 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -109,6 +109,10 @@ void hyperv_vector_handler(struct pt_regs *regs);
 void hv_setup_vmbus_irq(void (*handler)(void));
 void hv_remove_vmbus_irq(void);
 
+/* On x86/x64, there isn't a real IRQ to be enabled/disable */
+static inline void hv_enable_vmbus_irq(void) {}
+static inline void hv_disable_vmbus_irq(void) {}
+
 void hv_setup_kexec_handler(void (*handler)(void));
 void hv_remove_kexec_handler(void);
 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 166c2501de17..d0bb09a4bd73 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -307,6 +307,7 @@ int hv_synic_init(unsigned int cpu)
hv_set_siefp(siefp.as_uint64);
 
/* Setup the shared SINT. */
+   hv_enable_vmbus_irq();
hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
@@ -434,6 +435,7 @@ int hv_synic_cleanup(unsigned int cpu)
/* Disable the global synic bit */
sctrl.enable = 0;
hv_set_synic_state(sctrl.as_uint64);
+   hv_disable_vmbus_irq();
 
return 0;
 }
-- 
2.19.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/4] arm64: hyperv: Add core Hyper-V include files

2018-11-21 Thread kys
From: Michael Kelley 

hyperv-tlfs.h defines Hyper-V interfaces from the Hyper-V Top Level
Functional Spec (TLFS). The TLFS is distinctly oriented to x86/x64,
and Hyper-V has not separated out the architecture-dependent parts into
x86/x64 vs. ARM64. So hyperv-tlfs.h includes information for ARM64
that is not yet formally published. The TLFS is available here:

  docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/reference/tlfs

mshyperv.h defines Linux-specific structures and routines for
interacting with Hyper-V. It is split into an ARM64 specific file
and an architecture independent file in include/asm-generic.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 MAINTAINERS  |   3 +
 arch/arm64/include/asm/hyperv-tlfs.h | 338 +++
 arch/arm64/include/asm/mshyperv.h| 116 +
 include/asm-generic/mshyperv.h   | 240 +++
 4 files changed, 697 insertions(+)
 create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 create mode 100644 arch/arm64/include/asm/mshyperv.h
 create mode 100644 include/asm-generic/mshyperv.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f4855974f325..72f19cef4c48 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6835,6 +6835,8 @@ F:arch/x86/include/asm/trace/hyperv.h
 F: arch/x86/include/asm/hyperv-tlfs.h
 F: arch/x86/kernel/cpu/mshyperv.c
 F: arch/x86/hyperv
+F: arch/arm64/include/asm/hyperv-tlfs.h
+F: arch/arm64/include/asm/mshyperv.h
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
@@ -6846,6 +6848,7 @@ F:drivers/video/fbdev/hyperv_fb.c
 F: net/vmw_vsock/hyperv_transport.c
 F: include/linux/hyperv.h
 F: include/uapi/linux/hyperv.h
+F: include/asm-generic/mshyperv.h
 F: tools/hv/
 F: Documentation/ABI/stable/sysfs-bus-vmbus
 
diff --git a/arch/arm64/include/asm/hyperv-tlfs.h 
b/arch/arm64/include/asm/hyperv-tlfs.h
new file mode 100644
index ..924e37600e92
--- /dev/null
+++ b/arch/arm64/include/asm/hyperv-tlfs.h
@@ -0,0 +1,338 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/*
+ * This file contains definitions from the Hyper-V Hypervisor Top-Level
+ * Functional Specification (TLFS):
+ * 
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fvirtualization%2Fhyper-v-on-windows%2Freference%2Ftlfs&data=02%7C01%7Ckys%40microsoft.com%7Cc831a45fd63e4a4b083908d641216aa8%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636768009113747528&sdata=jRSrs9ZWXdmeS7LQUEpoSyUfBS7a5KLYy%2FolFdE2tI0%3D&reserved=0
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : Michael Kelley 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ */
+
+#ifndef _ASM_ARM64_HYPERV_H
+#define _ASM_ARM64_HYPERV_H
+
+#include 
+
+/*
+ * These Hyper-V registers provide information equivalent to the CPUID
+ * instruction on x86/x64.
+ */
+#define HV_REGISTER_HYPERVISOR_VERSION 0x0100 /*CPUID 0x4002 */
+#defineHV_REGISTER_PRIVILEGES_AND_FEATURES 0x0200 /*CPUID 
0x4003 */
+#defineHV_REGISTER_FEATURES0x0201 /*CPUID 
0x4004 */
+#defineHV_REGISTER_IMPLEMENTATION_LIMITS   0x0202 /*CPUID 
0x4005 */
+#define HV_ARM64_REGISTER_INTERFACE_VERSION0x00090006 /*CPUID 0x4001 */
+
+/*
+ * Feature identification. HvRegisterPrivilegesAndFeaturesInfo returns a
+ * 128-bit value with flags indicating which features are available to the
+ * partition based upon the current partition privileges. The 128-bit
+ * value is broken up with different portions stored in different 32-bit
+ * fields in the ms_hyperv structure.
+ */
+
+/* Partition Reference Counter available*/
+#define HV_MSR_TIME_REF_COUNT_AVAILABLE(1 << 1)
+
+/*
+ * Synthetic Timers available
+ */
+#define HV_MSR_SYNTIMER_AVAILABLE  (1 << 3)
+
+/* Frequency MSRs available */
+#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE(1 << 8)
+
+/* Reference TSC available */
+#define HV_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
+
+/* Crash MSR available */
+#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE   (1 << 10)
+
+
+/*
+ * This group of flags is in the high order 64-bits of the returned
+ * 128-bit value.
+ */
+
+/* STIMER direct mode is available */
+#define HV_STIMER_DIRECT_MODE_AVAILABLE(1 << 19)
+
+/*
+ * Implementation recommendations in register
+ * HvRegisterFeaturesInfo. Indicates which behaviors the hypervisor
+ * recommends the OS implement for optimal per

[PATCH 0/4] Hyper-V: Enable Linux guests on Hyper-V on ARM64

2018-11-21 Thread kys
From: "K. Y. Srinivasan" 

This series enables Linux guests running on Hyper-V on ARM64
hardware. New ARM64-specific code in arch/arm64/hyperv initializes
Hyper-V, including its synthetic clocks and hypercall mechanism.
Existing architecture independent drivers for Hyper-V's VMbus and
synthetic devices just work when built for ARM64. Hyper-V code is
built and included in the image and modules only if CONFIG_HYPERV
is enabled.

The four patches are organized as follows:
1) Add include files that define the Hyper-V interface as
   described in the Hyper-V Top Level Functional Spec (TLFS), plus
   additional definitions specific to Linux running on Hyper-V.

2) Add core Hyper-V support on ARM64, including hypercalls,
   synthetic clock initialization, and interrupt handlers.

3) Update the existing VMbus driver to generalize interrupt
   management across x86/x64 and ARM64.

4) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.

Some areas of Linux guests on Hyper-V on ARM64 are a work-
in-progress, primarily due to work still being done in Hyper-V:

* Hyper-V on ARM64 currently runs with a 4 Kbyte page size, and only
  supports guests with a 4 Kbyte page size. Because Hyper-V uses
  shared pages to communicate between the guest and the hypervisor,
  there are open design decisions on the page size to use when
  the guest is using 16K/64K pages.  Once those issues are
  resolved and Hyper-V fully supports 16K/64K guest pages, changes
  may be needed in the Linux drivers for Hyper-V synthetic devices.

* Hyper-V on ARM64 does not currently support mapping PCI devices
  into the guest address space. The Hyper-V PCI driver at
  drivers/pci/host/pci-hyperv.c has x86/x64-specific code and is
  not being built for ARM64.

In a few cases, terminology from the x86/x64 world has been carried
over into the ARM64 code ("MSR", "TSC").  Hyper-V still uses the
x86/x64 terminology and has not replaced it with something more
generic, so the code uses the Hyper-V terminology.  This will be
fixed when Hyper-V updates the usage in the TLFS.


Michael Kelley (4):
  arm64: hyperv: Add core Hyper-V include files
  arm64: hyperv: Add support for Hyper-V as a hypervisor
  Drivers: hv: vmbus: Add hooks for per-CPU IRQ
  Drivers: hv: Enable CONFIG_HYPERV on ARM64

 MAINTAINERS  |   4 +
 arch/arm64/Makefile  |   1 +
 arch/arm64/hyperv/Makefile   |   2 +
 arch/arm64/hyperv/hv_hvc.S   |  54 
 arch/arm64/hyperv/hv_init.c  | 441 +++
 arch/arm64/hyperv/mshyperv.c | 178 +++
 arch/arm64/include/asm/hyperv-tlfs.h | 338 
 arch/arm64/include/asm/mshyperv.h| 116 +++
 arch/x86/include/asm/mshyperv.h  |   4 +
 drivers/hv/Kconfig   |   3 +-
 drivers/hv/hv.c  |   2 +
 include/asm-generic/mshyperv.h   | 240 +++
 12 files changed, 1382 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/hyperv/Makefile
 create mode 100644 arch/arm64/hyperv/hv_hvc.S
 create mode 100644 arch/arm64/hyperv/hv_init.c
 create mode 100644 arch/arm64/hyperv/mshyperv.c
 create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 create mode 100644 arch/arm64/include/asm/mshyperv.h
 create mode 100644 include/asm-generic/mshyperv.h

-- 
2.19.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/4] Hyper-V: Enable Linux guests on Hyper-V on ARM64

2018-11-21 Thread kys
From: "K. Y. Srinivasan" 

This series enables Linux guests running on Hyper-V on ARM64
hardware. New ARM64-specific code in arch/arm64/hyperv initializes
Hyper-V, including its synthetic clocks and hypercall mechanism.
Existing architecture independent drivers for Hyper-V's VMbus and
synthetic devices just work when built for ARM64. Hyper-V code is
built and included in the image and modules only if CONFIG_HYPERV
is enabled.

The four patches are organized as follows:
1) Add include files that define the Hyper-V interface as
   described in the Hyper-V Top Level Functional Spec (TLFS), plus
   additional definitions specific to Linux running on Hyper-V.

2) Add core Hyper-V support on ARM64, including hypercalls,
   synthetic clock initialization, and interrupt handlers.

3) Update the existing VMbus driver to generalize interrupt
   management across x86/x64 and ARM64.

4) Make CONFIG_HYPERV selectable on ARM64 in addition to x86/x64.

Some areas of Linux guests on Hyper-V on ARM64 are a work-
in-progress, primarily due to work still being done in Hyper-V:

* Hyper-V on ARM64 currently runs with a 4 Kbyte page size, and only
  supports guests with a 4 Kbyte page size. Because Hyper-V uses
  shared pages to communicate between the guest and the hypervisor,
  there are open design decisions on the page size to use when
  the guest is using 16K/64K pages.  Once those issues are
  resolved and Hyper-V fully supports 16K/64K guest pages, changes
  may be needed in the Linux drivers for Hyper-V synthetic devices.

* Hyper-V on ARM64 does not currently support mapping PCI devices
  into the guest address space. The Hyper-V PCI driver at
  drivers/pci/host/pci-hyperv.c has x86/x64-specific code and is
  not being built for ARM64.

In a few cases, terminology from the x86/x64 world has been carried
over into the ARM64 code ("MSR", "TSC").  Hyper-V still uses the
x86/x64 terminology and has not replaced it with something more
generic, so the code uses the Hyper-V terminology.  This will be
fixed when Hyper-V updates the usage in the TLFS.


Michael Kelley (4):
  arm64: hyperv: Add core Hyper-V include files
  arm64: hyperv: Add support for Hyper-V as a hypervisor
  Drivers: hv: vmbus: Add hooks for per-CPU IRQ
  Drivers: hv: Enable CONFIG_HYPERV on ARM64

 MAINTAINERS  |   4 +
 arch/arm64/Makefile  |   1 +
 arch/arm64/hyperv/Makefile   |   2 +
 arch/arm64/hyperv/hv_hvc.S   |  54 
 arch/arm64/hyperv/hv_init.c  | 441 +++
 arch/arm64/hyperv/mshyperv.c | 178 +++
 arch/arm64/include/asm/hyperv-tlfs.h | 338 
 arch/arm64/include/asm/mshyperv.h| 116 +++
 arch/x86/include/asm/mshyperv.h  |   4 +
 drivers/hv/Kconfig   |   3 +-
 drivers/hv/hv.c  |   2 +
 include/asm-generic/mshyperv.h   | 240 +++
 12 files changed, 1382 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/hyperv/Makefile
 create mode 100644 arch/arm64/hyperv/hv_hvc.S
 create mode 100644 arch/arm64/hyperv/hv_init.c
 create mode 100644 arch/arm64/hyperv/mshyperv.c
 create mode 100644 arch/arm64/include/asm/hyperv-tlfs.h
 create mode 100644 arch/arm64/include/asm/mshyperv.h
 create mode 100644 include/asm-generic/mshyperv.h

-- 
2.19.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 2/5] hv_utils: update name in struct hv_driver util_drv

2018-10-17 Thread kys
From: Haiyang Zhang 

The correct module name is hv_utils. This patch corrects
the name in struct hv_driver util_drv.

Signed-off-by: Haiyang Zhang 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 423205077bf6..f10eeb120c8b 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -483,7 +483,7 @@ MODULE_DEVICE_TABLE(vmbus, id_table);
 
 /* The one and only one */
 static  struct hv_driver util_drv = {
-   .name = "hv_util",
+   .name = "hv_utils",
.id_table = id_table,
.probe =  util_probe,
.remove =  util_remove,
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 4/5] Drivers: hv: kvp: Use %u to print U32

2018-10-17 Thread kys
From: Dexuan Cui 

I didn't find a real issue. Let's just make it consistent with the
next "case REG_U64:" where %llu is used.

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_kvp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index d6106e1a0d4a..5054d1105236 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -437,7 +437,7 @@ kvp_send_key(struct work_struct *dummy)
val32 = in_msg->body.kvp_set.data.value_u32;
message->body.kvp_set.data.value_size =
sprintf(message->body.kvp_set.data.value,
-   "%d", val32) + 1;
+   "%u", val32) + 1;
break;
 
case REG_U64:
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 1/5] Drivers: hv: vmbus: Get rid of unnecessary state in hv_context

2018-10-17 Thread kys
From: "K. Y. Srinivasan" 

Currently we are replicating state in struct hv_context that is unnecessary -
this state can be retrieved from the hypervisor. Furthermore, this is a per-cpu
state that is being maintained as a global state in struct hv_context.
Get rid of this state in struct hv_context.

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c   | 10 +++---
 drivers/hv/hyperv_vmbus.h |  2 --
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 332d7c34be5c..166c2501de17 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -33,9 +33,7 @@
 #include "hyperv_vmbus.h"
 
 /* The one and only */
-struct hv_context hv_context = {
-   .synic_initialized  = false,
-};
+struct hv_context hv_context;
 
 /*
  * If false, we're using the old mechanism for stimer0 interrupts
@@ -326,8 +324,6 @@ int hv_synic_init(unsigned int cpu)
 
hv_set_synic_state(sctrl.as_uint64);
 
-   hv_context.synic_initialized = true;
-
/*
 * Register the per-cpu clockevent source.
 */
@@ -373,7 +369,8 @@ int hv_synic_cleanup(unsigned int cpu)
bool channel_found = false;
unsigned long flags;
 
-   if (!hv_context.synic_initialized)
+   hv_get_synic_state(sctrl.as_uint64);
+   if (sctrl.enable != 1)
return -EFAULT;
 
/*
@@ -435,7 +432,6 @@ int hv_synic_cleanup(unsigned int cpu)
hv_set_siefp(siefp.as_uint64);
 
/* Disable the global synic bit */
-   hv_get_synic_state(sctrl.as_uint64);
sctrl.enable = 0;
hv_set_synic_state(sctrl.as_uint64);
 
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 72eaba3d50fc..f17c06a5e74b 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -230,8 +230,6 @@ struct hv_context {
 
void *tsc_page;
 
-   bool synic_initialized;
-
struct hv_per_cpu_context __percpu *cpu_context;
 
/*
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 3/5] Drivers: hv: kvp: Fix the recent regression caused by incorrect clean-up

2018-10-17 Thread kys
From: Dexuan Cui 

In kvp_send_key(), we do need call process_ib_ipinfo() if
message->kvp_hdr.operation is KVP_OP_GET_IP_INFO, because it turns out
the userland hv_kvp_daemon needs the info of operation, adapter_id and
addr_family. With the incorrect fc62c3b1977d, the host can't get the
VM's IP via KVP.

And, fc62c3b1977d added a "break;", but actually forgot to initialize
the key_size/value in the case of KVP_OP_SET, so the default key_size of
0 is passed to the kvp daemon, and the pool files
/var/lib/hyperv/.kvp_pool_* can't be updated.

This patch effectively rolls back the previous fc62c3b1977d, and
correctly fixes the "this statement may fall through" warnings.

This patch is tested on WS 2012 R2 and 2016.

Fixes: fc62c3b1977d ("Drivers: hv: kvp: Fix two "this statement may fall 
through" warnings")
Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Cc: 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_kvp.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index a7513a8a8e37..d6106e1a0d4a 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -353,6 +353,9 @@ static void process_ib_ipinfo(void *in_msg, void *out_msg, 
int op)
 
out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled;
 
+   /* fallthrough */
+
+   case KVP_OP_GET_IP_INFO:
utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,
MAX_ADAPTER_ID_SIZE,
UTF16_LITTLE_ENDIAN,
@@ -405,7 +408,11 @@ kvp_send_key(struct work_struct *dummy)
process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);
break;
case KVP_OP_GET_IP_INFO:
-   /* We only need to pass on message->kvp_hdr.operation.  */
+   /*
+* We only need to pass on the info of operation, adapter_id
+* and addr_family to the userland kvp daemon.
+*/
+   process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);
break;
case KVP_OP_SET:
switch (in_msg->body.kvp_set.data.value_type) {
@@ -446,9 +453,9 @@ kvp_send_key(struct work_struct *dummy)
 
}
 
-   break;
-
-   case KVP_OP_GET:
+   /*
+* The key is always a string - utf16 encoding.
+*/
message->body.kvp_set.data.key_size =
utf16s_to_utf8s(
(wchar_t *)in_msg->body.kvp_set.data.key,
@@ -456,6 +463,17 @@ kvp_send_key(struct work_struct *dummy)
UTF16_LITTLE_ENDIAN,
message->body.kvp_set.data.key,
HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
+
+   break;
+
+   case KVP_OP_GET:
+   message->body.kvp_get.data.key_size =
+   utf16s_to_utf8s(
+   (wchar_t *)in_msg->body.kvp_get.data.key,
+   in_msg->body.kvp_get.data.key_size,
+   UTF16_LITTLE_ENDIAN,
+   message->body.kvp_get.data.key,
+   HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
break;
 
case KVP_OP_DELETE:
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 5/5] Tools: hv: kvp: Fix a warning of buffer overflow with gcc 8.0.1

2018-10-17 Thread kys
From: Dexuan Cui 

The patch fixes:

hv_kvp_daemon.c: In function 'kvp_set_ip_info':
hv_kvp_daemon.c:1305:2: note: 'snprintf' output between 41 and 4136 bytes
into a destination of size 4096

The "(unsigned int)str_len" is to avoid:

hv_kvp_daemon.c:1309:30: warning: comparison of integer expressions of
different signedness: 'int' and 'long unsigned int' [-Wsign-compare]

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/hv_kvp_daemon.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index bbb2a8ef367c..d7e06fe0270e 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -1178,6 +1178,7 @@ static int kvp_set_ip_info(char *if_name, struct 
hv_kvp_ipaddr_value *new_val)
FILE *file;
char cmd[PATH_MAX];
char *mac_addr;
+   int str_len;
 
/*
 * Set the configuration for the specified interface with
@@ -1301,8 +1302,18 @@ static int kvp_set_ip_info(char *if_name, struct 
hv_kvp_ipaddr_value *new_val)
 * invoke the external script to do its magic.
 */
 
-   snprintf(cmd, sizeof(cmd), KVP_SCRIPTS_PATH "%s %s",
-"hv_set_ifconfig", if_file);
+   str_len = snprintf(cmd, sizeof(cmd), KVP_SCRIPTS_PATH "%s %s",
+  "hv_set_ifconfig", if_file);
+   /*
+* This is a little overcautious, but it's necessary to suppress some
+* false warnings from gcc 8.0.1.
+*/
+   if (str_len <= 0 || (unsigned int)str_len >= sizeof(cmd)) {
+   syslog(LOG_ERR, "Cmd '%s' (len=%d) may be too long",
+  cmd, str_len);
+   return HV_E_FAIL;
+   }
+
if (system(cmd)) {
syslog(LOG_ERR, "Failed to execute cmd '%s'; error: %d %s",
cmd, errno, strerror(errno));
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 0/5] Drivers: hv: Miscellaneous fixes

2018-10-17 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes.

V2: Addressed comments from Greg.

Dexuan Cui (3):
  Drivers: hv: kvp: Fix the recent regression caused by incorrect
clean-up
  Drivers: hv: kvp: Use %u to print U32
  Tools: hv: kvp: Fix a warning of buffer overflow with gcc 8.0.1

Haiyang Zhang (1):
  hv_utils: update name in struct hv_driver util_drv

K. Y. Srinivasan (1):
  Drivers: hv: vmbus: Get rid of unnecessary state in hv_context

 drivers/hv/hv.c   | 10 +++---
 drivers/hv/hv_kvp.c   | 28 +++-
 drivers/hv/hv_util.c  |  2 +-
 drivers/hv/hyperv_vmbus.h |  2 --
 tools/hv/hv_kvp_daemon.c  | 15 +--
 5 files changed, 40 insertions(+), 17 deletions(-)

-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/5] Drivers: hv: vmbus: Get rid of unnecessary state in hv_context

2018-10-16 Thread kys
From: "K. Y. Srinivasan" 

Currently we are replicating state in struct hv_context that is unnecessary -
this state can be retrieved from the hypervisor. Furthermore, this is a per-cpu
state that is being maintained as a global state in struct hv_context.
Get rid of this state in struct hv_context.

Reply-To: k...@microsoft.com

Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c   | 10 +++---
 drivers/hv/hyperv_vmbus.h |  2 --
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 332d7c34be5c..166c2501de17 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -33,9 +33,7 @@
 #include "hyperv_vmbus.h"
 
 /* The one and only */
-struct hv_context hv_context = {
-   .synic_initialized  = false,
-};
+struct hv_context hv_context;
 
 /*
  * If false, we're using the old mechanism for stimer0 interrupts
@@ -326,8 +324,6 @@ int hv_synic_init(unsigned int cpu)
 
hv_set_synic_state(sctrl.as_uint64);
 
-   hv_context.synic_initialized = true;
-
/*
 * Register the per-cpu clockevent source.
 */
@@ -373,7 +369,8 @@ int hv_synic_cleanup(unsigned int cpu)
bool channel_found = false;
unsigned long flags;
 
-   if (!hv_context.synic_initialized)
+   hv_get_synic_state(sctrl.as_uint64);
+   if (sctrl.enable != 1)
return -EFAULT;
 
/*
@@ -435,7 +432,6 @@ int hv_synic_cleanup(unsigned int cpu)
hv_set_siefp(siefp.as_uint64);
 
/* Disable the global synic bit */
-   hv_get_synic_state(sctrl.as_uint64);
sctrl.enable = 0;
hv_set_synic_state(sctrl.as_uint64);
 
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 72eaba3d50fc..f17c06a5e74b 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -230,8 +230,6 @@ struct hv_context {
 
void *tsc_page;
 
-   bool synic_initialized;
-
struct hv_per_cpu_context __percpu *cpu_context;
 
/*
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/5] Drivers: hv: kvp: Use %u to print U32

2018-10-16 Thread kys
From: Dexuan Cui 

I didn't find a real issue. Let's just make it consistent with the
next "case REG_U64:" where %llu is used.

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Cc: 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_kvp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 9fbb15c62c6c..3b8590ff94ba 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -437,7 +437,7 @@ kvp_send_key(struct work_struct *dummy)
val32 = in_msg->body.kvp_set.data.value_u32;
message->body.kvp_set.data.value_size =
sprintf(message->body.kvp_set.data.value,
-   "%d", val32) + 1;
+   "%u", val32) + 1;
break;
 
case REG_U64:
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/5] Tools: hv: kvp: Fix a warning of buffer overflow with gcc 8.0.1

2018-10-16 Thread kys
From: Dexuan Cui 

The patch fixes:

hv_kvp_daemon.c: In function 'kvp_set_ip_info':
hv_kvp_daemon.c:1305:2: note: 'snprintf' output between 41 and 4136 bytes
into a destination of size 4096

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Cc: 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/hv_kvp_daemon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index bbb2a8ef367c..b7c2cf7eaba5 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -1176,7 +1176,7 @@ static int kvp_set_ip_info(char *if_name, struct 
hv_kvp_ipaddr_value *new_val)
int error = 0;
char if_file[PATH_MAX];
FILE *file;
-   char cmd[PATH_MAX];
+   char cmd[PATH_MAX * 2];
char *mac_addr;
 
/*
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/5] Drivers: hv: kvp: Fix the recent regression caused by incorrect clean-up

2018-10-16 Thread kys
From: Dexuan Cui 

In kvp_send_key(), we do need call process_ib_ipinfo() if
message->kvp_hdr.operation is KVP_OP_GET_IP_INFO, because it turns out
the userland hv_kvp_daemon needs the info of operation, adapter_id and
addr_family. With the incorrect fc62c3b1977d, the host can't get the
VM's IP via KVP.

And, fc62c3b1977d added a "break;", but actually forgot to initialize
the key_size/value in the case of KVP_OP_SET, so the default key_size of
0 is passed to the kvp daemon, and the pool files
/var/lib/hyperv/.kvp_pool_* can't be updated.

This patch effectively rolls back the previous fc62c3b1977d, and
correctly fixes the "this statement may fall through" warnings.

This patch is tested on WS 2012 R2 and 2016.

Fixes: fc62c3b1977d ("Drivers: hv: kvp: Fix two "this statement may fall 
through" warnings")
Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Cc: 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_kvp.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index a7513a8a8e37..9fbb15c62c6c 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -353,6 +353,9 @@ static void process_ib_ipinfo(void *in_msg, void *out_msg, 
int op)
 
out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled;
 
+   __attribute__ ((fallthrough));
+
+   case KVP_OP_GET_IP_INFO:
utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,
MAX_ADAPTER_ID_SIZE,
UTF16_LITTLE_ENDIAN,
@@ -405,7 +408,11 @@ kvp_send_key(struct work_struct *dummy)
process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);
break;
case KVP_OP_GET_IP_INFO:
-   /* We only need to pass on message->kvp_hdr.operation.  */
+   /*
+* We only need to pass on the info of operation, adapter_id
+* and addr_family to the userland kvp daemon.
+*/
+   process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);
break;
case KVP_OP_SET:
switch (in_msg->body.kvp_set.data.value_type) {
@@ -446,9 +453,9 @@ kvp_send_key(struct work_struct *dummy)
 
}
 
-   break;
-
-   case KVP_OP_GET:
+   /*
+* The key is always a string - utf16 encoding.
+*/
message->body.kvp_set.data.key_size =
utf16s_to_utf8s(
(wchar_t *)in_msg->body.kvp_set.data.key,
@@ -456,6 +463,17 @@ kvp_send_key(struct work_struct *dummy)
UTF16_LITTLE_ENDIAN,
message->body.kvp_set.data.key,
HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
+
+   break;
+
+   case KVP_OP_GET:
+   message->body.kvp_get.data.key_size =
+   utf16s_to_utf8s(
+   (wchar_t *)in_msg->body.kvp_get.data.key,
+   in_msg->body.kvp_get.data.key_size,
+   UTF16_LITTLE_ENDIAN,
+   message->body.kvp_get.data.key,
+   HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
break;
 
case KVP_OP_DELETE:
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/5] hv_utils: update name in struct hv_driver util_drv

2018-10-16 Thread kys
From: Haiyang Zhang 

The correct module name is hv_utils. This patch corrects
the name in struct hv_driver util_drv.

Signed-off-by: Haiyang Zhang 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 423205077bf6..f10eeb120c8b 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -483,7 +483,7 @@ MODULE_DEVICE_TABLE(vmbus, id_table);
 
 /* The one and only one */
 static  struct hv_driver util_drv = {
-   .name = "hv_util",
+   .name = "hv_utils",
.id_table = id_table,
.probe =  util_probe,
.remove =  util_remove,
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/5] Drivers: hv: Miscellaneous fixes

2018-10-16 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes.

Dexuan Cui (3):
  Drivers: hv: kvp: Fix the recent regression caused by incorrect
clean-up
  Drivers: hv: kvp: Use %u to print U32
  Tools: hv: kvp: Fix a warning of buffer overflow with gcc 8.0.1

Haiyang Zhang (1):
  hv_utils: update name in struct hv_driver util_drv

K. Y. Srinivasan (1):
  Drivers: hv: vmbus: Get rid of unnecessary state in hv_context

 drivers/hv/hv.c   | 10 +++---
 drivers/hv/hv_kvp.c   | 28 +++-
 drivers/hv/hv_util.c  |  2 +-
 drivers/hv/hyperv_vmbus.h |  2 --
 tools/hv/hv_kvp_daemon.c  |  2 +-
 5 files changed, 28 insertions(+), 16 deletions(-)

-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/4] Drivers: hv: vmbus: Fix the descriptions of some function parameters

2018-09-23 Thread kys
From: Dexuan Cui 

No functional change.

Added descriptions for some parameters.
Fixed some typos.
Removed some out-of-date comments.

Signed-off-by: Dexuan Cui 
Cc: Jonathan Corbet 
Cc: linux-...@vger.kernel.org
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c  | 24 +---
 drivers/hv/channel_mgmt.c | 23 +--
 2 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 741857d80da1..ab92779271d0 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -709,15 +709,16 @@ EXPORT_SYMBOL_GPL(vmbus_close);
 
 /**
  * vmbus_sendpacket() - Send the specified buffer on the given channel
- * @channel: Pointer to vmbus_channel structure.
- * @buffer: Pointer to the buffer you want to receive the data into.
- * @bufferlen: Maximum size of what the the buffer will hold
+ * @channel: Pointer to vmbus_channel structure
+ * @buffer: Pointer to the buffer you want to send the data from.
+ * @bufferlen: Maximum size of what the buffer holds.
  * @requestid: Identifier of the request
- * @type: Type of packet that is being send e.g. negotiate, time
- * packet etc.
+ * @type: Type of packet that is being sent e.g. negotiate, time
+ *   packet etc.
+ * @flags: 0 or VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED
  *
- * Sends data in @buffer directly to hyper-v via the vmbus
- * This will send the data unparsed to hyper-v.
+ * Sends data in @buffer directly to Hyper-V via the vmbus.
+ * This will send the data unparsed to Hyper-V.
  *
  * Mainly used by Hyper-V drivers.
  */
@@ -850,12 +851,13 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel 
*channel,
 EXPORT_SYMBOL_GPL(vmbus_sendpacket_mpb_desc);
 
 /**
- * vmbus_recvpacket() - Retrieve the user packet on the specified channel
- * @channel: Pointer to vmbus_channel structure.
+ * __vmbus_recvpacket() - Retrieve the user packet on the specified channel
+ * @channel: Pointer to vmbus_channel structure
  * @buffer: Pointer to the buffer you want to receive the data into.
- * @bufferlen: Maximum size of what the the buffer will hold
- * @buffer_actual_len: The actual size of the data after it was received
+ * @bufferlen: Maximum size of what the buffer can hold.
+ * @buffer_actual_len: The actual size of the data after it was received.
  * @requestid: Identifier of the request
+ * @raw: true means keep the vmpacket_descriptor header in the received data.
  *
  * Receives directly from the hyper-v vmbus and puts the data it received
  * into Buffer. This will receive the data unparsed from hyper-v.
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 0f0e091c117c..e7598b569bea 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -198,24 +198,19 @@ static u16 hv_get_dev_type(const struct vmbus_channel 
*channel)
 }
 
 /**
- * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate 
message
+ * vmbus_prep_negotiate_resp() - Create default response for Negotiate message
  * @icmsghdrp: Pointer to msg header structure
- * @icmsg_negotiate: Pointer to negotiate message structure
  * @buf: Raw buffer channel data
+ * @fw_version: The framework versions we can support.
+ * @fw_vercnt: The size of @fw_version.
+ * @srv_version: The service versions we can support.
+ * @srv_vercnt: The size of @srv_version.
+ * @nego_fw_version: The selected framework version.
+ * @nego_srv_version: The selected service version.
  *
- * @icmsghdrp is of type &struct icmsg_hdr.
- * Set up and fill in default negotiate response message.
- *
- * The fw_version and fw_vercnt specifies the framework version that
- * we can support.
- *
- * The srv_version and srv_vercnt specifies the service
- * versions we can support.
- *
- * Versions are given in decreasing order.
- *
- * nego_fw_version and nego_srv_version store the selected protocol versions.
+ * Note: Versions are given in decreasing order.
  *
+ * Set up and fill in default negotiate response message.
  * Mainly used by Hyper-V drivers.
  */
 bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/4] Drivers: hv: kvp: Fix two "this statement may fall through" warnings

2018-09-23 Thread kys
From: Dexuan Cui 

We don't need to call process_ib_ipinfo() if message->kvp_hdr.operation is
KVP_OP_GET_IP_INFO in kvp_send_key(), because here we just need to pass on
the op code from the host to the userspace; when the userspace returns
the info requested by the host, we pass the info on to the host in
kvp_respond_to_host() -> process_ob_ipinfo(). BTW, the current buggy code
actually doesn't cause any harm, because only message->kvp_hdr.operation
is used by the userspace, in the case of KVP_OP_GET_IP_INFO.

The patch also adds a missing "break;" in kvp_send_key(). BTW, the current
buggy code actually doesn't cause any harm, because in the case of
KVP_OP_SET, the unexpected fall-through corrupts
message->body.kvp_set.data.key_size, but that is not really used: see
the definition of struct hv_kvp_exchg_msg_value.

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Cc: 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_kvp.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 023bd185d21a..a7513a8a8e37 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -353,7 +353,6 @@ static void process_ib_ipinfo(void *in_msg, void *out_msg, 
int op)
 
out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled;
 
-   default:
utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,
MAX_ADAPTER_ID_SIZE,
UTF16_LITTLE_ENDIAN,
@@ -406,7 +405,7 @@ kvp_send_key(struct work_struct *dummy)
process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);
break;
case KVP_OP_GET_IP_INFO:
-   process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);
+   /* We only need to pass on message->kvp_hdr.operation.  */
break;
case KVP_OP_SET:
switch (in_msg->body.kvp_set.data.value_type) {
@@ -446,6 +445,9 @@ kvp_send_key(struct work_struct *dummy)
break;
 
}
+
+   break;
+
case KVP_OP_GET:
message->body.kvp_set.data.key_size =
utf16s_to_utf8s(
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/4] Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask

2018-09-23 Thread kys
From: Dexuan Cui 

A cpumask structure on the stack can cause a warning with
CONFIG_NR_CPUS=8192 (e.g. Ubuntu 16.04 and 18.04 use this):

drivers/hv//channel_mgmt.c: In function ‘init_vp_index’:
drivers/hv//channel_mgmt.c:702:1: warning: the frame size of 1032 bytes
  is larger than 1024 bytes [-Wframe-larger-than=]

Nowadays it looks most distros enable CONFIG_CPUMASK_OFFSTACK=y, and
hence we can work around the warning by using cpumask_var_t.

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Cc: 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel_mgmt.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index e7598b569bea..d943fa022e34 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -601,16 +601,18 @@ static void init_vp_index(struct vmbus_channel *channel, 
u16 dev_type)
bool perf_chn = vmbus_devs[dev_type].perf_device;
struct vmbus_channel *primary = channel->primary_channel;
int next_node;
-   struct cpumask available_mask;
+   cpumask_var_t available_mask;
struct cpumask *alloced_mask;
 
if ((vmbus_proto_version == VERSION_WS2008) ||
-   (vmbus_proto_version == VERSION_WIN7) || (!perf_chn)) {
+   (vmbus_proto_version == VERSION_WIN7) || (!perf_chn) ||
+   !alloc_cpumask_var(&available_mask, GFP_KERNEL)) {
/*
 * Prior to win8, all channel interrupts are
 * delivered on cpu 0.
 * Also if the channel is not a performance critical
 * channel, bind it to cpu 0.
+* In case alloc_cpumask_var() fails, bind it to cpu 0.
 */
channel->numa_node = 0;
channel->target_cpu = 0;
@@ -648,7 +650,7 @@ static void init_vp_index(struct vmbus_channel *channel, 
u16 dev_type)
cpumask_clear(alloced_mask);
}
 
-   cpumask_xor(&available_mask, alloced_mask,
+   cpumask_xor(available_mask, alloced_mask,
cpumask_of_node(primary->numa_node));
 
cur_cpu = -1;
@@ -666,10 +668,10 @@ static void init_vp_index(struct vmbus_channel *channel, 
u16 dev_type)
}
 
while (true) {
-   cur_cpu = cpumask_next(cur_cpu, &available_mask);
+   cur_cpu = cpumask_next(cur_cpu, available_mask);
if (cur_cpu >= nr_cpu_ids) {
cur_cpu = -1;
-   cpumask_copy(&available_mask,
+   cpumask_copy(available_mask,
 cpumask_of_node(primary->numa_node));
continue;
}
@@ -699,6 +701,8 @@ static void init_vp_index(struct vmbus_channel *channel, 
u16 dev_type)
 
channel->target_cpu = cur_cpu;
channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
+
+   free_cpumask_var(available_mask);
 }
 
 static void vmbus_wait_for_unload(void)
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/4] Drivers: hv: kvp: Fix the indentation of some "break" statements

2018-09-23 Thread kys
From: Dexuan Cui 

No functional change.

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_kvp.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 5eed1e7da15c..023bd185d21a 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -421,7 +421,7 @@ kvp_send_key(struct work_struct *dummy)
UTF16_LITTLE_ENDIAN,
message->body.kvp_set.data.value,
HV_KVP_EXCHANGE_MAX_VALUE_SIZE - 1) + 1;
-   break;
+   break;
 
case REG_U32:
/*
@@ -454,7 +454,7 @@ kvp_send_key(struct work_struct *dummy)
UTF16_LITTLE_ENDIAN,
message->body.kvp_set.data.key,
HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
-   break;
+   break;
 
case KVP_OP_DELETE:
message->body.kvp_delete.key_size =
@@ -464,12 +464,12 @@ kvp_send_key(struct work_struct *dummy)
UTF16_LITTLE_ENDIAN,
message->body.kvp_delete.key,
HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
-   break;
+   break;
 
case KVP_OP_ENUMERATE:
message->body.kvp_enum_data.index =
in_msg->body.kvp_enum_data.index;
-   break;
+   break;
}
 
kvp_transaction.state = HVUTIL_USERSPACE_REQ;
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/4] Drivers: hv: Miscellaneous fixes

2018-09-23 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes.

Dexuan Cui (4):
  Drivers: hv: vmbus: Fix the descriptions of some function parameters
  Drivers: hv: kvp: Fix the indentation of some "break" statements
  Drivers: hv: kvp: Fix two "this statement may fall through" warnings
  Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask

 drivers/hv/channel.c  | 24 +---
 drivers/hv/channel_mgmt.c | 37 ++---
 drivers/hv/hv_kvp.c   | 14 --
 3 files changed, 39 insertions(+), 36 deletions(-)

-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] Drivers: hv: vmbus: Use get/put_cpu() in vmbus_connect()

2018-09-16 Thread kys
From: Dexuan Cui 

With CONFIG_DEBUG_PREEMPT=y, I always see this warning:
BUG: using smp_processor_id() in preemptible []

Fix the false warning by using get/put_cpu().

Here vmbus_connect() sends a message to the host and waits for the
host's response. The host will deliver the response message and an
interrupt on CPU msg->target_vcpu, and later the interrupt handler
will wake up vmbus_connect(). vmbus_connect() doesn't really have
to run on the same cpu as CPU msg->target_vcpu, so it's safe to
call put_cpu() just here.

Signed-off-by: Dexuan Cui 
Cc: sta...@vger.kernel.org
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/connection.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index ced041899456..f4d08c8ac7f8 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -76,6 +76,7 @@ static int vmbus_negotiate_version(struct 
vmbus_channel_msginfo *msginfo,
__u32 version)
 {
int ret = 0;
+   unsigned int cur_cpu;
struct vmbus_channel_initiate_contact *msg;
unsigned long flags;
 
@@ -118,9 +119,10 @@ static int vmbus_negotiate_version(struct 
vmbus_channel_msginfo *msginfo,
 * the CPU attempting to connect may not be CPU 0.
 */
if (version >= VERSION_WIN8_1) {
-   msg->target_vcpu =
-   hv_cpu_number_to_vp_number(smp_processor_id());
-   vmbus_connection.connect_cpu = smp_processor_id();
+   cur_cpu = get_cpu();
+   msg->target_vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   vmbus_connection.connect_cpu = cur_cpu;
+   put_cpu();
} else {
msg->target_vcpu = 0;
vmbus_connection.connect_cpu = 0;
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] tools: hv: fcopy: set 'error' in case an unknown operation was requested

2018-09-16 Thread kys
From: Vitaly Kuznetsov 

'error' variable is left uninitialized in case we see an unknown operation.
As we don't immediately return and proceed to pwrite() we need to set it
to something, HV_E_FAIL sounds good enough.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/hv_fcopy_daemon.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index d78aed86af09..8ff8cb1a11f4 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -234,6 +234,7 @@ int main(int argc, char *argv[])
break;
 
default:
+   error = HV_E_FAIL;
syslog(LOG_ERR, "Unknown operation: %d",
buffer.hdr.operation);
 
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] Drivers: hv: Miscellaneous fixes

2018-09-16 Thread kys
From: "K. Y. Srinivasan" 

Some miscellaneous fixes.

Dexuan Cui (1):
  Drivers: hv: vmbus: Use get/put_cpu() in vmbus_connect()

Vitaly Kuznetsov (1):
  tools: hv: fcopy: set 'error' in case an unknown operation was
requested

 drivers/hv/connection.c| 8 +---
 tools/hv/hv_fcopy_daemon.c | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] vmbus: don't return values for uninitalized channels

2018-08-20 Thread kys
From: Stephen Hemminger 

For unsupported device types, the vmbus channel ringbuffer is never
initialized, and therefore reading the sysfs files will return garbage
or cause a kernel OOPS.

Fixes: c2e5df616e1a ("vmbus: add per-channel sysfs info")

Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
Cc:  # 4.15
---
 drivers/hv/vmbus_drv.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index e6d8fdac6d8b..4bbc420d1213 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1368,6 +1368,9 @@ static ssize_t vmbus_chan_attr_show(struct kobject *kobj,
if (!attribute->show)
return -EIO;
 
+   if (chan->state != CHANNEL_OPENED_STATE)
+   return -EINVAL;
+
return attribute->show(chan, buf);
 }
 
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/5] uio_hv_generic: drop #ifdef DEBUG

2018-08-10 Thread kys
From: Stephen Hemminger 

DEBUG is leftover from the development phase, remove it.

Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/uio/uio_hv_generic.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
index 35678d08d9d8..ab0c0e7e8a44 100644
--- a/drivers/uio/uio_hv_generic.c
+++ b/drivers/uio/uio_hv_generic.c
@@ -19,7 +19,6 @@
  * # echo -n "ed963694-e847-4b2a-85af-bc9cfc11d6f3" \
  *> /sys/bus/vmbus/drivers/uio_hv_generic/bind
  */
-#define DEBUG 1
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include 
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/5] Tools: hv: Fix a bug in the key delete code

2018-08-10 Thread kys
From: "K. Y. Srinivasan" 

Fix a bug in the key delete code - the num_records range
from 0 to num_records-1.

Signed-off-by: K. Y. Srinivasan 
Reported-by: David Binderman 
Cc: 
---
 tools/hv/hv_kvp_daemon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index dbf6e8bd98ba..bbb2a8ef367c 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -286,7 +286,7 @@ static int kvp_key_delete(int pool, const __u8 *key, int 
key_size)
 * Found a match; just move the remaining
 * entries up.
 */
-   if (i == num_records) {
+   if (i == (num_records - 1)) {
kvp_file_info[pool].num_records--;
kvp_update_file(pool);
return 0;
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/5] Drivers: hv: vmbus: Fix synic per-cpu context initialization

2018-08-10 Thread kys
From: Michael Kelley 

If hv_synic_alloc() errors out, the state of the per-cpu context
for some CPUs is unknown since the zero'ing is done as each
CPU is iterated over.  In such case, hv_synic_cleanup() may try to
free memory based on uninitialized values.  Fix this by zero'ing
the per-cpu context for all CPUs before doing any memory
allocations that might fail.

Signed-off-by: Michael Kelley 
Reported-by: Dan Carpenter 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 748a1c4172a6..332d7c34be5c 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -189,6 +189,17 @@ static void hv_init_clockevent_device(struct 
clock_event_device *dev, int cpu)
 int hv_synic_alloc(void)
 {
int cpu;
+   struct hv_per_cpu_context *hv_cpu;
+
+   /*
+* First, zero all per-cpu memory areas so hv_synic_free() can
+* detect what memory has been allocated and cleanup properly
+* after any failures.
+*/
+   for_each_present_cpu(cpu) {
+   hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu);
+   memset(hv_cpu, 0, sizeof(*hv_cpu));
+   }
 
hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask),
 GFP_KERNEL);
@@ -198,10 +209,8 @@ int hv_synic_alloc(void)
}
 
for_each_present_cpu(cpu) {
-   struct hv_per_cpu_context *hv_cpu
-   = per_cpu_ptr(hv_context.cpu_context, cpu);
+   hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu);
 
-   memset(hv_cpu, 0, sizeof(*hv_cpu));
tasklet_init(&hv_cpu->msg_dpc,
 vmbus_on_msg_dpc, (unsigned long) hv_cpu);
 
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/5] vmbus: add driver_override support

2018-08-10 Thread kys
From: Stephen Hemminger 

Add support for overriding the default driver for a VMBus device
in the same way that it can be done for PCI devices. This patch
adds the /sys/bus/vmbus/devices/.../driver_override file
and the logic for matching.

This is used by driverctl tool to do driver override.
https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.com%2Fdriverctl%2Fdriverctl&data=02%7C01%7Ckys%40microsoft.com%7C42e803feb2c544ef6ea908d5fd538878%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636693457619960040&sdata=kEyYHRIjNZCk%2B37moCSqbrZL426YccNQrsWpENcrZdw%3D&reserved=0

Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 Documentation/ABI/testing/sysfs-bus-vmbus |  21 
 drivers/hv/vmbus_drv.c| 115 ++
 include/linux/hyperv.h|   1 +
 3 files changed, 118 insertions(+), 19 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-vmbus

diff --git a/Documentation/ABI/testing/sysfs-bus-vmbus 
b/Documentation/ABI/testing/sysfs-bus-vmbus
new file mode 100644
index ..91e6c065973c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-vmbus
@@ -0,0 +1,21 @@
+What:  /sys/bus/vmbus/devices/.../driver_override
+Date:  August 2019
+Contact:   Stephen Hemminger 
+Description:
+   This file allows the driver for a device to be specified which
+   will override standard static and dynamic ID matching.  When
+   specified, only a driver with a name matching the value written
+   to driver_override will have an opportunity to bind to the
+   device.  The override is specified by writing a string to the
+   driver_override file (echo uio_hv_generic > driver_override) and
+   may be cleared with an empty string (echo > driver_override).
+   This returns the device to standard matching rules binding.
+   Writing to driver_override does not automatically unbind the
+   device from its current driver or make any attempt to
+   automatically load the specified driver.  If no driver with a
+   matching name is currently loaded in the kernel, the device
+   will not bind to any driver.  This also allows devices to
+   opt-out of driver binding using a driver_override name such as
+   "none".  Only a single driver may be specified in the override,
+   there is no support for parsing delimiters.
+
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index b1b548a21f91..e6d8fdac6d8b 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -498,6 +498,54 @@ static ssize_t device_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(device);
 
+static ssize_t driver_override_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t count)
+{
+   struct hv_device *hv_dev = device_to_hv_device(dev);
+   char *driver_override, *old, *cp;
+
+   /* We need to keep extra room for a newline */
+   if (count >= (PAGE_SIZE - 1))
+   return -EINVAL;
+
+   driver_override = kstrndup(buf, count, GFP_KERNEL);
+   if (!driver_override)
+   return -ENOMEM;
+
+   cp = strchr(driver_override, '\n');
+   if (cp)
+   *cp = '\0';
+
+   device_lock(dev);
+   old = hv_dev->driver_override;
+   if (strlen(driver_override)) {
+   hv_dev->driver_override = driver_override;
+   } else {
+   kfree(driver_override);
+   hv_dev->driver_override = NULL;
+   }
+   device_unlock(dev);
+
+   kfree(old);
+
+   return count;
+}
+
+static ssize_t driver_override_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct hv_device *hv_dev = device_to_hv_device(dev);
+   ssize_t len;
+
+   device_lock(dev);
+   len = snprintf(buf, PAGE_SIZE, "%s\n", hv_dev->driver_override);
+   device_unlock(dev);
+
+   return len;
+}
+static DEVICE_ATTR_RW(driver_override);
+
 /* Set up per device attributes in /sys/bus/vmbus/devices/ */
 static struct attribute *vmbus_dev_attrs[] = {
&dev_attr_id.attr,
@@ -528,6 +576,7 @@ static struct attribute *vmbus_dev_attrs[] = {
&dev_attr_channel_vp_mapping.attr,
&dev_attr_vendor.attr,
&dev_attr_device.attr,
+   &dev_attr_driver_override.attr,
NULL,
 };
 ATTRIBUTE_GROUPS(vmbus_dev);
@@ -563,17 +612,26 @@ static inline bool is_null_guid(const uuid_le *guid)
return true;
 }
 
-/*
- * Return a matching hv_vmbus_device_id pointer.
- * If there is no match, return NULL.
- */
-static const struct hv_vmbus_device_id *hv_vmbus_get_id(struct hv_driver *drv,
-   const uuid_le *guid)
+static const struct hv_vmbus_d

[PATCH 3/5] uio_hv_generic: increase size of receive and send buffers

2018-08-10 Thread kys
From: Stephen Hemminger 

When using DPDK there is significant performance boost by using
the largest possible send and receive buffer area.

Unfortunately, with UIO model there is not a good way to configure
this at run time. But it is okay to have a bigger buffer available
even if application only decides to use a smaller piece of it.

Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/uio/uio_hv_generic.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c
index c690d100adcd..35678d08d9d8 100644
--- a/drivers/uio/uio_hv_generic.c
+++ b/drivers/uio/uio_hv_generic.c
@@ -35,13 +35,13 @@
 
 #include "../hv/hyperv_vmbus.h"
 
-#define DRIVER_VERSION "0.02.0"
+#define DRIVER_VERSION "0.02.1"
 #define DRIVER_AUTHOR  "Stephen Hemminger "
 #define DRIVER_DESC"Generic UIO driver for VMBus devices"
 
 #define HV_RING_SIZE512/* pages */
-#define SEND_BUFFER_SIZE (15 * 1024 * 1024)
-#define RECV_BUFFER_SIZE (15 * 1024 * 1024)
+#define SEND_BUFFER_SIZE (16 * 1024 * 1024)
+#define RECV_BUFFER_SIZE (31 * 1024 * 1024)
 
 /*
  * List of resources to be mapped to user space
-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/5] Miscellaneous fixes/enhancements

2018-08-10 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes/enhancements.

K. Y. Srinivasan (1):
  Tools: hv: Fix a bug in the key delete code

Michael Kelley (1):
  Drivers: hv: vmbus: Fix synic per-cpu context initialization

Stephen Hemminger (3):
  vmbus: add driver_override support
  uio_hv_generic: increase size of receive and send buffers
  uio_hv_generic: drop #ifdef DEBUG

 Documentation/ABI/testing/sysfs-bus-vmbus |  21 
 drivers/hv/hv.c   |  15 ++-
 drivers/hv/vmbus_drv.c| 115 ++
 drivers/uio/uio_hv_generic.c  |   7 +-
 include/linux/hyperv.h|   1 +
 tools/hv/hv_kvp_daemon.c  |   2 +-
 6 files changed, 134 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-vmbus

-- 
2.18.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/3] Drivers: hv: vmbus: Cleanup synic memory free path

2018-08-01 Thread kys
From: Michael Kelley 

clk_evt memory is not being freed when the synic is shutdown
or when there is an allocation error.  Add the appropriate
kfree() call, along with a comment to clarify how the memory
gets freed after an allocation error.  Make the free path
consistent by removing checks for NULL since kfree() and
free_page() already do the check.

Signed-off-by: Michael Kelley 
Reported-by: Dan Carpenter 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 312fe5ed7c40..748a1c4172a6 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -242,6 +242,10 @@ int hv_synic_alloc(void)
 
return 0;
 err:
+   /*
+* Any memory allocations that succeeded will be freed when
+* the caller cleans up by calling hv_synic_free()
+*/
return -ENOMEM;
 }
 
@@ -254,12 +258,10 @@ void hv_synic_free(void)
struct hv_per_cpu_context *hv_cpu
= per_cpu_ptr(hv_context.cpu_context, cpu);
 
-   if (hv_cpu->synic_event_page)
-   free_page((unsigned long)hv_cpu->synic_event_page);
-   if (hv_cpu->synic_message_page)
-   free_page((unsigned long)hv_cpu->synic_message_page);
-   if (hv_cpu->post_msg_page)
-   free_page((unsigned long)hv_cpu->post_msg_page);
+   kfree(hv_cpu->clk_evt);
+   free_page((unsigned long)hv_cpu->synic_event_page);
+   free_page((unsigned long)hv_cpu->synic_message_page);
+   free_page((unsigned long)hv_cpu->post_msg_page);
}
 
kfree(hv_context.hv_numa_map);
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/3] Drivers: hv: vmbus: Remove use of slow_virt_to_phys()

2018-08-01 Thread kys
From: Michael Kelley 

slow_virt_to_phys() is only implemented for arch/x86.
Remove its use in arch independent Hyper-V drivers, and
replace with test for vmalloc() address followed by
appropriate v-to-p function. This follows the typical
pattern of other drivers and avoids the need to implement
slow_virt_to_phys() for Hyper-V on ARM64.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c | 27 ---
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index c3949220b770..741857d80da1 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -29,12 +29,26 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "hyperv_vmbus.h"
 
 #define NUM_PAGES_SPANNED(addr, len) \
 ((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT))
 
+static unsigned long virt_to_hvpfn(void *addr)
+{
+   unsigned long paddr;
+
+   if (is_vmalloc_addr(addr))
+   paddr = page_to_phys(vmalloc_to_page(addr)) +
+offset_in_page(addr);
+   else
+   paddr = __pa(addr);
+
+   return  paddr >> PAGE_SHIFT;
+}
+
 /*
  * vmbus_setevent- Trigger an event notification on the specified
  * channel.
@@ -298,8 +312,8 @@ static int create_gpadl_header(void *kbuffer, u32 size,
gpadl_header->range[0].byte_offset = 0;
gpadl_header->range[0].byte_count = size;
for (i = 0; i < pfncount; i++)
-   gpadl_header->range[0].pfn_array[i] = slow_virt_to_phys(
-   kbuffer + PAGE_SIZE * i) >> PAGE_SHIFT;
+   gpadl_header->range[0].pfn_array[i] = virt_to_hvpfn(
+   kbuffer + PAGE_SIZE * i);
*msginfo = msgheader;
 
pfnsum = pfncount;
@@ -350,9 +364,8 @@ static int create_gpadl_header(void *kbuffer, u32 size,
 * so the hypervisor guarantees that this is ok.
 */
for (i = 0; i < pfncurr; i++)
-   gpadl_body->pfn[i] = slow_virt_to_phys(
-   kbuffer + PAGE_SIZE * (pfnsum + i)) >>
-   PAGE_SHIFT;
+   gpadl_body->pfn[i] = virt_to_hvpfn(
+   kbuffer + PAGE_SIZE * (pfnsum + i));
 
/* add to msg header */
list_add_tail(&msgbody->msglistentry,
@@ -380,8 +393,8 @@ static int create_gpadl_header(void *kbuffer, u32 size,
gpadl_header->range[0].byte_offset = 0;
gpadl_header->range[0].byte_count = size;
for (i = 0; i < pagecount; i++)
-   gpadl_header->range[0].pfn_array[i] = slow_virt_to_phys(
-   kbuffer + PAGE_SIZE * i) >> PAGE_SHIFT;
+   gpadl_header->range[0].pfn_array[i] = virt_to_hvpfn(
+   kbuffer + PAGE_SIZE * i);
 
*msginfo = msgheader;
}
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/3] Drivers: hv: vmbus: Reset the channel callback in vmbus_onoffer_rescind()

2018-08-01 Thread kys
From: Dexuan Cui 

Before setting channel->rescind in vmbus_rescind_cleanup(), we should make
sure the channel callback won't run any more, otherwise a high-level
driver like pci_hyperv, which may be infinitely waiting for the host VSP's
response and notices the channel has been rescinded, can't safely give
up: e.g., in hv_pci_protocol_negotiation() -> wait_for_response(), it's
unsafe to exit from wait_for_response() and proceed with the on-stack
variable "comp_pkt" popped. The issue was originally spotted by
Michael Kelley .

In vmbus_close_internal(), the patch also minimizes the range protected by
disabling/enabling channel->callback_event: we don't really need that for
the whole function.

Signed-off-by: Dexuan Cui 
Reviewed-by: Michael Kelley 
Cc: sta...@vger.kernel.org
Cc: K. Y. Srinivasan 
Cc: Stephen Hemminger 
Cc: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel.c  | 40 +++
 drivers/hv/channel_mgmt.c |  6 ++
 include/linux/hyperv.h|  2 ++
 3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index ba0a092ae085..c3949220b770 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -558,11 +558,8 @@ static void reset_channel_cb(void *arg)
channel->onchannel_callback = NULL;
 }
 
-static int vmbus_close_internal(struct vmbus_channel *channel)
+void vmbus_reset_channel_cb(struct vmbus_channel *channel)
 {
-   struct vmbus_channel_close_channel *msg;
-   int ret;
-
/*
 * vmbus_on_event(), running in the per-channel tasklet, can race
 * with vmbus_close_internal() in the case of SMP guest, e.g., when
@@ -572,6 +569,29 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
 */
tasklet_disable(&channel->callback_event);
 
+   channel->sc_creation_callback = NULL;
+
+   /* Stop the callback asap */
+   if (channel->target_cpu != get_cpu()) {
+   put_cpu();
+   smp_call_function_single(channel->target_cpu, reset_channel_cb,
+channel, true);
+   } else {
+   reset_channel_cb(channel);
+   put_cpu();
+   }
+
+   /* Re-enable tasklet for use on re-open */
+   tasklet_enable(&channel->callback_event);
+}
+
+static int vmbus_close_internal(struct vmbus_channel *channel)
+{
+   struct vmbus_channel_close_channel *msg;
+   int ret;
+
+   vmbus_reset_channel_cb(channel);
+
/*
 * In case a device driver's probe() fails (e.g.,
 * util_probe() -> vmbus_open() returns -ENOMEM) and the device is
@@ -585,16 +605,6 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
}
 
channel->state = CHANNEL_OPEN_STATE;
-   channel->sc_creation_callback = NULL;
-   /* Stop callback and cancel the timer asap */
-   if (channel->target_cpu != get_cpu()) {
-   put_cpu();
-   smp_call_function_single(channel->target_cpu, reset_channel_cb,
-channel, true);
-   } else {
-   reset_channel_cb(channel);
-   put_cpu();
-   }
 
/* Send a closing message */
 
@@ -639,8 +649,6 @@ static int vmbus_close_internal(struct vmbus_channel 
*channel)
get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
 
 out:
-   /* re-enable tasklet for use on re-open */
-   tasklet_enable(&channel->callback_event);
return ret;
 }
 
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index f3b551a50653..0f0e091c117c 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -892,6 +892,12 @@ static void vmbus_onoffer_rescind(struct 
vmbus_channel_message_header *hdr)
return;
}
 
+   /*
+* Before setting channel->rescind in vmbus_rescind_cleanup(), we
+* should make sure the channel callback is not running any more.
+*/
+   vmbus_reset_channel_cb(channel);
+
/*
 * Now wait for offer handling to complete.
 */
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 2330f08062c7..efda23cf32c7 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1061,6 +1061,8 @@ extern int vmbus_establish_gpadl(struct vmbus_channel 
*channel,
 extern int vmbus_teardown_gpadl(struct vmbus_channel *channel,
 u32 gpadl_handle);
 
+void vmbus_reset_channel_cb(struct vmbus_channel *channel);
+
 extern int vmbus_recvpacket(struct vmbus_channel *channel,
  void *buffer,
  u32 bufferlen,
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/3] Drivers: hv: vmbus: Miscellaneous fixes

2018-08-01 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes.

Dexuan Cui (1):
  Drivers: hv: vmbus: Reset the channel callback in
vmbus_onoffer_rescind()

Michael Kelley (2):
  Drivers: hv: vmbus: Remove use of slow_virt_to_phys()
  Drivers: hv: vmbus: Cleanup synic memory free path

 drivers/hv/channel.c  | 67 +--
 drivers/hv/channel_mgmt.c |  6 
 drivers/hv/hv.c   | 14 
 include/linux/hyperv.h|  2 ++
 4 files changed, 60 insertions(+), 29 deletions(-)

-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/4] Drivers: hv: vmbus: add numa_node to sysfs

2018-07-28 Thread kys
From: Stephen Hemminger 

Being able to find the numa_node for a device is useful for userspace
drivers (DPDK) and also for diagnosing performance issues.  This makes
vmbus similar to pci.

Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 Documentation/ABI/stable/sysfs-bus-vmbus |  7 +++
 drivers/hv/vmbus_drv.c   | 17 +
 2 files changed, 24 insertions(+)

diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus 
b/Documentation/ABI/stable/sysfs-bus-vmbus
index 3eaffbb2d468..3fed8fdb873d 100644
--- a/Documentation/ABI/stable/sysfs-bus-vmbus
+++ b/Documentation/ABI/stable/sysfs-bus-vmbus
@@ -42,6 +42,13 @@ Contact: K. Y. Srinivasan 
 Description:   The 16 bit vendor ID of the device
 Users: tools/hv/lsvmbus and user level RDMA libraries
 
+What:  /sys/bus/vmbus/devices//numa_node
+Date:  Jul 2018
+KernelVersion: 4.19
+Contact:   Stephen Hemminger 
+Description:   This NUMA node to which the VMBUS device is
+   attached, or -1 if the node is unknown.
+
 What:  /sys/bus/vmbus/devices//channels/
 Date:  September. 2017
 KernelVersion: 4.14
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index db145e1a7049..b1b548a21f91 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -210,6 +210,20 @@ static ssize_t modalias_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(modalias);
 
+#ifdef CONFIG_NUMA
+static ssize_t numa_node_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+   struct hv_device *hv_dev = device_to_hv_device(dev);
+
+   if (!hv_dev->channel)
+   return -ENODEV;
+
+   return sprintf(buf, "%d\n", hv_dev->channel->numa_node);
+}
+static DEVICE_ATTR_RO(numa_node);
+#endif
+
 static ssize_t server_monitor_pending_show(struct device *dev,
   struct device_attribute *dev_attr,
   char *buf)
@@ -492,6 +506,9 @@ static struct attribute *vmbus_dev_attrs[] = {
&dev_attr_class_id.attr,
&dev_attr_device_id.attr,
&dev_attr_modalias.attr,
+#ifdef CONFIG_NUMA
+   &dev_attr_numa_node.attr,
+#endif
&dev_attr_server_monitor_pending.attr,
&dev_attr_client_monitor_pending.attr,
&dev_attr_server_monitor_latency.attr,
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/4] Drivers: hv: vmbus: Fix the issue with freeing up hv_ctl_table_hdr

2018-07-28 Thread kys
From: Sunil Muthuswamy 

The check to free the Hyper-V control table header was reversed. This
fixes it.

Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over 
Hyper-V during panic")

Signed-off-by: Sunil Muthuswamy 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/vmbus_drv.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index a7f33c1f42c5..5e946b1be54c 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1176,11 +1176,8 @@ static int vmbus_bus_init(void)
 
bus_unregister(&hv_bus);
free_page((unsigned long)hv_panic_page);
-   if (!hv_ctl_table_hdr) {
-   unregister_sysctl_table(hv_ctl_table_hdr);
-   hv_ctl_table_hdr = NULL;
-   }
-
+   unregister_sysctl_table(hv_ctl_table_hdr);
+   hv_ctl_table_hdr = NULL;
return ret;
 }
 
@@ -1891,11 +1888,8 @@ static void __exit vmbus_exit(void)
}
 
free_page((unsigned long)hv_panic_page);
-   if (!hv_ctl_table_hdr) {
-   unregister_sysctl_table(hv_ctl_table_hdr);
-   hv_ctl_table_hdr = NULL;
-   }
-
+   unregister_sysctl_table(hv_ctl_table_hdr);
+   hv_ctl_table_hdr = NULL;
bus_unregister(&hv_bus);
 
cpuhp_remove_state(hyperv_cpuhp_online);
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/4] Drivers: hv: vmbus: Get rid of MSR access from vmbus_drv.c

2018-07-28 Thread kys
From: Sunil Muthuswamy 

Get rid of ISA specific code from vmus_drv.c which is common code.

Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over 
Hyper-V during panic")

Signed-off-by: Sunil Muthuswamy 
Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/include/asm/mshyperv.h | 3 +++
 drivers/hv/vmbus_drv.c  | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 156a2e5a97a9..b731c4bf70ed 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -96,6 +96,9 @@ static inline void vmbus_signal_eom(struct hv_message *msg, 
u32 old_msg_type)
 #define hv_set_synint_state(int_num, val) \
wrmsrl(HV_X64_MSR_SINT0 + int_num, val)
 
+#define hv_get_crash_ctl(val) \
+   rdmsrl(HV_X64_MSR_CRASH_CTL, val)
+
 void hyperv_callback_vector(void);
 void hyperv_reenlightenment_vector(void);
 #ifdef CONFIG_TRACING
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 5e946b1be54c..db145e1a7049 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1146,7 +1146,7 @@ static int vmbus_bus_init(void)
 * Register for panic kmsg callback only if the right
 * capability is supported by the hypervisor.
 */
-   rdmsrl(HV_X64_MSR_CRASH_CTL, hyperv_crash_ctl);
+   hv_get_crash_ctl(hyperv_crash_ctl);
if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG) {
hv_panic_page = (void *)get_zeroed_page(GFP_KERNEL);
if (hv_panic_page) {
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/4] Drivers: hv: vmus: Fix the check for return value from kmsg get dump buffer

2018-07-28 Thread kys
From: Sunil Muthuswamy 

The code to support panic control message was checking the return was
checking the return value from kmsg_dump_get_buffer as error value, which
is not what the routine returns. This fixes it.

Fixes: 81b18bce48af ("Drivers: HV: Send one page worth of kmsg dump over 
Hyper-V during panic")

Signed-off-by: Sunil Muthuswamy 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/vmbus_drv.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 05e37283d7c3..a7f33c1f42c5 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1047,13 +1047,10 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
 * Write dump contents to the page. No need to synchronize; panic should
 * be single-threaded.
 */
-   if (!kmsg_dump_get_buffer(dumper, true, hv_panic_page,
- PAGE_SIZE, &bytes_written)) {
-   pr_err("Hyper-V: Unable to get kmsg data for panic\n");
-   return;
-   }
-
-   hyperv_report_panic_msg(panic_pa, bytes_written);
+   kmsg_dump_get_buffer(dumper, true, hv_panic_page, PAGE_SIZE,
+&bytes_written);
+   if (bytes_written)
+   hyperv_report_panic_msg(panic_pa, bytes_written);
 }
 
 static struct kmsg_dumper hv_kmsg_dumper = {
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/4] Drivers: hv: vmbus: Miscellaneous fixes/enhancements

2018-07-28 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes/enhancements

Stephen Hemminger (1):
  Drivers: hv: vmbus: add numa_node to sysfs

Sunil Muthuswamy (3):
  Drivers: hv: vmus: Fix the check for return value from kmsg get dump
buffer
  Drivers: hv: vmbus: Fix the issue with freeing up hv_ctl_table_hdr
  Drivers: hv: vmbus: Get rid of MSR access from vmbus_drv.c

 Documentation/ABI/stable/sysfs-bus-vmbus |  7 
 arch/x86/include/asm/mshyperv.h  |  3 ++
 drivers/hv/vmbus_drv.c   | 44 ++--
 3 files changed, 36 insertions(+), 18 deletions(-)

-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/1] x86/hyper-v: Fix a merge error

2018-07-19 Thread kys
From: "K. Y. Srinivasan" 

When the mapping betwween the Linux notion of CPU ID
to the hypervisor's notion of CPU ID is not initialized,
we should fall back on the non-enligghtened path for IPI.
A merge error introduced this bug; fix it.

Fixes: 1268ed0c474a ("Merge branch 'x86/urgent' into x86/hyperv")

Reported-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_apic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 0c3c9f8fee77..5b0f613428c2 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -168,7 +168,7 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
if (vcpu == VP_INVAL)
-   return true;
+   return false;
 
/*
 * This particular version of the IPI hypercall can
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/1] Drivers: HV: Send one page worth of kmsg dump over Hyper-V during panic

2018-07-07 Thread kys
From: Sunil Muthuswamy 

In the VM mode on Hyper-V, currently, when the kernel panics, an error
code and few register values are populated in an MSR and the Hypervisor
notified. This information is collected on the host. The amount of
information currently collected is found to be limited and not very
actionable. To gather more actionable data, such as stack trace, the
proposal is to write one page worth of kmsg data on an allocated page
and the Hypervisor notified of the page address through the MSR.

- Sysctl option to control the behavior, with ON by default.

Cc: K. Y. Srinivasan 
Cc: Stephen Hemminger 
Signed-off-by: Sunil Muthuswamy 
Signed-off-by: K. Y. Srinivasan 
---
 Documentation/sysctl/kernel.txt|  11 +++
 arch/x86/hyperv/hv_init.c  |  27 +++
 arch/x86/include/asm/hyperv-tlfs.h |   5 +-
 arch/x86/include/asm/mshyperv.h|   1 +
 drivers/hv/vmbus_drv.c | 110 +
 5 files changed, 152 insertions(+), 2 deletions(-)

diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index eded671d55eb..59585030cbaf 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -39,6 +39,7 @@ show up in /proc/sys/kernel:
 - hung_task_check_count
 - hung_task_timeout_secs
 - hung_task_warnings
+- hyperv_record_panic_msg
 - kexec_load_disabled
 - kptr_restrict
 - l2cr[ PPC only ]
@@ -374,6 +375,16 @@ This file shows up if CONFIG_DETECT_HUNG_TASK is enabled.
 
 ==
 
+hyperv_record_panic_msg:
+
+Controls whether the panic kmsg data should be reported to Hyper-V.
+
+0: do not report panic kmsg data.
+
+1: report the panic kmsg data. This is the default behavior.
+
+==
+
 kexec_load_disabled:
 
 A toggle indicating if the kexec_load syscall has been disabled. This
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 595e44e8abaa..9c70018a9906 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -423,6 +423,33 @@ void hyperv_report_panic(struct pt_regs *regs, long err)
 }
 EXPORT_SYMBOL_GPL(hyperv_report_panic);
 
+/**
+ * hyperv_report_panic_msg - report panic message to Hyper-V
+ * @pa: physical address of the panic page containing the message
+ * @size: size of the message in the page
+ */
+void hyperv_report_panic_msg(phys_addr_t pa, size_t size)
+{
+   /*
+* P3 to contain the physical address of the panic page & P4 to
+* contain the size of the panic data in that page. Rest of the
+* registers are no-op when the NOTIFY_MSG flag is set.
+*/
+   wrmsrl(HV_X64_MSR_CRASH_P0, 0);
+   wrmsrl(HV_X64_MSR_CRASH_P1, 0);
+   wrmsrl(HV_X64_MSR_CRASH_P2, 0);
+   wrmsrl(HV_X64_MSR_CRASH_P3, pa);
+   wrmsrl(HV_X64_MSR_CRASH_P4, size);
+
+   /*
+* Let Hyper-V know there is crash data available along with
+* the panic message.
+*/
+   wrmsrl(HV_X64_MSR_CRASH_CTL,
+  (HV_CRASH_CTL_CRASH_NOTIFY | HV_CRASH_CTL_CRASH_NOTIFY_MSG));
+}
+EXPORT_SYMBOL_GPL(hyperv_report_panic_msg);
+
 bool hv_is_hyperv_initialized(void)
 {
union hv_x64_msr_hypercall_contents hypercall_msr;
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 96272e99b64e..6ced78af48da 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -176,9 +176,10 @@
 #define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED(1 << 14)
 
 /*
- * Crash notification flag.
+ * Crash notification flags.
  */
-#define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
+#define HV_CRASH_CTL_CRASH_NOTIFY_MSG  BIT_ULL(62)
+#define HV_CRASH_CTL_CRASH_NOTIFY  BIT_ULL(63)
 
 /* MSR used to identify the guest OS. */
 #define HV_X64_MSR_GUEST_OS_ID 0x4000
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 81e768b8d9eb..156a2e5a97a9 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -299,6 +299,7 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 void __init hyperv_init(void);
 void hyperv_setup_mmu_ops(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
+void hyperv_report_panic_msg(phys_addr_t pa, size_t size);
 bool hv_is_hyperv_initialized(void);
 void hyperv_cleanup(void);
 
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index b10fe26c4891..05e37283d7c3 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -56,6 +56,8 @@ static struct completion probe_event;
 
 static int hyperv_cpuhp_online;
 
+static void *hv_panic_page;
+
 static int hyperv_panic_event(struct notifier_block *nb, unsigned long val,
  void *args)
 {
@@ -1018,6 +1020,75 @@ static void vmbus_isr(void)
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
 }
 
+/*
+ * Boolean to control whether to report

[PATCH 1/1] X86/Hyper-V:: Fix the circular dependency in IPI enlightenment.

2018-07-03 Thread kys
From: "K. Y. Srinivasan" 

The IPI hypercalls depend on being able to map the Linux notion of CPU ID
to the hypervisor's notion of the CPU ID. The array hv_vp_index[] provides
this mapping. Code for populating this array depends on the IPI functionality.
Break this circular dependency.

Fixes: 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments")

Signed-off-by: K. Y. Srinivasan 
Tested-by: Michael Kelley 
---
 arch/x86/hyperv/hv_apic.c   | 5 +
 arch/x86/hyperv/hv_init.c   | 5 -
 arch/x86/include/asm/mshyperv.h | 2 ++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f68855499391..63d7c196739f 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -114,6 +114,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, 
int vector)
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
}
+   if (nr_bank == -1)
+   goto ipi_mask_ex_done;
if (!nr_bank)
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
 
@@ -158,6 +160,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
 
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   if (vcpu == -1)
+   goto ipi_mask_done;
+
/*
 * This particular version of the IPI hypercall can
 * only target upto 64 CPUs.
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 4c431e1c1eff..04159893702e 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -265,7 +265,7 @@ void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
-   int cpuhp;
+   int cpuhp, i;
 
if (x86_hyper_type != X86_HYPER_MS_HYPERV)
return;
@@ -293,6 +293,9 @@ void __init hyperv_init(void)
if (!hv_vp_index)
return;
 
+   for (i = 0; i < num_possible_cpus(); i++)
+   hv_vp_index[i] = -1;
+
hv_vp_assist_page = kcalloc(num_possible_cpus(),
sizeof(*hv_vp_assist_page), GFP_KERNEL);
if (!hv_vp_assist_page) {
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 3cd14311edfa..dee3f7347253 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -281,6 +281,8 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 */
for_each_cpu(cpu, cpus) {
vcpu = hv_cpu_number_to_vp_number(cpu);
+   if (vcpu == -1)
+   return -1;
vcpu_bank = vcpu / 64;
vcpu_offset = vcpu % 64;
__set_bit(vcpu_offset, (unsigned long *)
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/1] X86: Fix the circular dependency in IPI enlightenment.

2018-07-03 Thread kys
From: "K. Y. Srinivasan" 

The IPI hypercalls depend on being able to map the Linux notion of CPU ID
to the hypervisor's notion of the CPU ID. The array hv_vp_index[] provides
this mapping. Code for populating this array depends on the IPI functionality.
Break this circular dependency.

Fixes: 68bb7bfb7985 ("X86/Hyper-V: Enable IPI enlightenments")

Signed-off-by: K. Y. Srinivasan 
Tested-by: Michael Kelley 
---
 arch/x86/hyperv/hv_apic.c   | 5 +
 arch/x86/hyperv/hv_init.c   | 3 +++
 arch/x86/include/asm/mshyperv.h | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f68855499391..63d7c196739f 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -114,6 +114,8 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, 
int vector)
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
}
+   if (nr_bank == -1)
+   goto ipi_mask_ex_done;
if (!nr_bank)
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
 
@@ -158,6 +160,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
 
for_each_cpu(cur_cpu, mask) {
vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   if (vcpu == -1)
+   goto ipi_mask_done;
+
/*
 * This particular version of the IPI hypercall can
 * only target upto 64 CPUs.
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 595e44e8abaa..762ce164d733 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -293,6 +293,9 @@ void __init hyperv_init(void)
if (!hv_vp_index)
return;
 
+   for (i = 0; i < num_possible_cpus(); i++)
+   hv_vp_index[i] = -1;
+
hv_vp_assist_page = kcalloc(num_possible_cpus(),
sizeof(*hv_vp_assist_page), GFP_KERNEL);
if (!hv_vp_assist_page) {
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 81e768b8d9eb..299de3dcc319 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -285,6 +285,8 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 */
for_each_cpu(cpu, cpus) {
vcpu = hv_cpu_number_to_vp_number(cpu);
+   if (vcpu == -1)
+   return -1;
vcpu_bank = vcpu / 64;
vcpu_offset = vcpu % 64;
__set_bit(vcpu_offset, (unsigned long *)
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/8] Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer()

2018-06-05 Thread kys
From: Dexuan Cui 

I didn't really hit a real bug, but just happened to spot the bug:
we have decreased the counter at the beginning of vmbus_process_offer(),
so we mustn't decrease it again.

Fixes: 6f3d791f3006 ("Drivers: hv: vmbus: Fix rescind handling issues")
Signed-off-by: Dexuan Cui 
Cc: sta...@vger.kernel.org
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Cc: Stable  # 4.14 and above
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel_mgmt.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index ecc2bd275a73..f3b551a50653 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -527,10 +527,8 @@ static void vmbus_process_offer(struct vmbus_channel 
*newchannel)
struct hv_device *dev
= newchannel->primary_channel->device_obj;
 
-   if (vmbus_add_channel_kobj(dev, newchannel)) {
-   atomic_dec(&vmbus_connection.offer_in_progress);
+   if (vmbus_add_channel_kobj(dev, newchannel))
goto err_free_chan;
-   }
 
if (channel->sc_creation_callback != NULL)
channel->sc_creation_callback(newchannel);
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/8] Drivers: hv: vmbus: Add comments on ring buffer signaling

2018-06-05 Thread kys
From: Michael Kelley 

Add comments describing intricacies of Hyper-V ring buffer
signaling code.  This information is not in Hyper-V public
documents, so include here to capture the knowledge for
future coders.

There are no code changes in this commit.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c | 65 +---
 include/linux/hyperv.h   | 31 ++-
 2 files changed, 77 insertions(+), 19 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 8699bb969e7e..ce6ea6dad490 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -429,7 +429,24 @@ static u32 hv_pkt_iter_bytes_read(const struct 
hv_ring_buffer_info *rbi,
 }
 
 /*
- * Update host ring buffer after iterating over packets.
+ * Update host ring buffer after iterating over packets. If the host has
+ * stopped queuing new entries because it found the ring buffer full, and
+ * sufficient space is being freed up, signal the host. But be careful to
+ * only signal the host when necessary, both for performance reasons and
+ * because Hyper-V protects itself by throttling guests that signal
+ * inappropriately.
+ *
+ * Determining when to signal is tricky. There are three key data inputs
+ * that must be handled in this order to avoid race conditions:
+ *
+ * 1. Update the read_index
+ * 2. Read the pending_send_sz
+ * 3. Read the current write_index
+ *
+ * The interrupt_mask is not used to determine when to signal. The
+ * interrupt_mask is used only on the guest->host ring buffer when
+ * sending requests to the host. The host does not use it on the host->
+ * guest ring buffer to indicate whether it should be signaled.
  */
 void hv_pkt_iter_close(struct vmbus_channel *channel)
 {
@@ -445,22 +462,30 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
start_read_index = rbi->ring_buffer->read_index;
rbi->ring_buffer->read_index = rbi->priv_read_index;
 
+   /*
+* Older versions of Hyper-V (before WS2102 and Win8) do not
+* implement pending_send_sz and simply poll if the host->guest
+* ring buffer is full.  No signaling is needed or expected.
+*/
if (!rbi->ring_buffer->feature_bits.feat_pending_send_sz)
return;
 
/*
 * Issue a full memory barrier before making the signaling decision.
-* Here is the reason for having this barrier:
-* If the reading of the pend_sz (in this function)
-* were to be reordered and read before we commit the new read
-* index (in the calling function)  we could
-* have a problem. If the host were to set the pending_sz after we
-* have sampled pending_sz and go to sleep before we commit the
+* If reading pending_send_sz were to be reordered and happen
+* before we commit the new read_index, a race could occur.  If the
+* host were to set the pending_send_sz after we have sampled
+* pending_send_sz, and the ring buffer blocks before we commit the
 * read index, we could miss sending the interrupt. Issue a full
 * memory barrier to address this.
 */
virt_mb();
 
+   /*
+* If the pending_send_sz is zero, then the ring buffer is not
+* blocked and there is no need to signal.  This is far by the
+* most common case, so exit quickly for best performance.
+*/
pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
if (!pending_sz)
return;
@@ -474,14 +499,32 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
bytes_read = hv_pkt_iter_bytes_read(rbi, start_read_index);
 
/*
-* If there was space before we began iteration,
-* then host was not blocked.
+* We want to signal the host only if we're transitioning
+* from a "not enough free space" state to a "enough free
+* space" state.  For example, it's possible that this function
+* could run and free up enough space to signal the host, and then
+* run again and free up additional space before the host has a
+* chance to clear the pending_send_sz.  The 2nd invocation would
+* be a null transition from "enough free space" to "enough free
+* space", which doesn't warrant a signal.
+*
+* Exactly filling the ring buffer is treated as "not enough
+* space". The ring buffer always must have at least one byte
+* empty so the empty and full conditions are distinguishable.
+* hv_get_bytes_to_write() doesn't fully tell the truth in
+* this regard.
+*
+* So first check if we were in the "enough free space" state
+* before we began the iteration. If so, the host was not
+* blocked, and there's no need to signal.
 */
-
if (curr_write_sz - bytes_read > pending_sz)
return;
 
-   /

[PATCH 7/8] tools: hv: update lsvmbus to be compatible with python3

2018-06-05 Thread kys
From: Olaf Hering 

Python3 changed the way how 'print' works.
Adjust the code to a syntax that is understood by python2 and python3.

Signed-off-by: Olaf Hering 
Acked-by: Dexuan Cui 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/lsvmbus | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/hv/lsvmbus b/tools/hv/lsvmbus
index 353e56768df8..55e7374bade0 100644
--- a/tools/hv/lsvmbus
+++ b/tools/hv/lsvmbus
@@ -17,7 +17,7 @@ if options.verbose is not None:
 
 vmbus_sys_path = '/sys/bus/vmbus/devices'
 if not os.path.isdir(vmbus_sys_path):
-   print "%s doesn't exist: exiting..." % vmbus_sys_path
+   print("%s doesn't exist: exiting..." % vmbus_sys_path)
exit(-1)
 
 vmbus_dev_dict = {
@@ -93,11 +93,11 @@ format2 = '%2s: Class_ID = %s - %s\n\tDevice_ID = 
%s\n\tSysfs path: %s\n%s'
 
 for d in vmbus_dev_list:
if verbose == 0:
-   print ('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc)
+   print(('VMBUS ID ' + format0) % (d.vmbus_id, d.dev_desc))
elif verbose == 1:
-   print ('VMBUS ID ' + format1) % \
-   (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping)
+   print (('VMBUS ID ' + format1) %\
+   (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping))
else:
-   print ('VMBUS ID ' + format2) % \
+   print (('VMBUS ID ' + format2) % \
(d.vmbus_id, d.class_id, d.dev_desc, \
-   d.device_id, d.sysfs_path, d.chn_vp_mapping)
+   d.device_id, d.sysfs_path, d.chn_vp_mapping))
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/8] Drivers: hv: vmbus: Remove x86 MSR refs in arch independent code

2018-06-05 Thread kys
From: Michael Kelley 

In architecture independent code for manipulating Hyper-V synthetic timers
and synthetic interrupts, pass in an ordinal number identifying the timer
or interrupt, rather than an actual MSR register address.  Then in
x86/x64 specific code, map the ordinal number to the appropriate MSR.
This change facilitates the introduction of an ARM64 version of Hyper-V,
which uses the same synthetic timers and interrupts, but a different
mechanism for accessing them.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/include/asm/mshyperv.h | 12 
 drivers/hv/hv.c | 20 
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index b90e79610cf7..caf9035a2758 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -75,8 +75,10 @@ static inline void vmbus_signal_eom(struct hv_message *msg, 
u32 old_msg_type)
}
 }
 
-#define hv_init_timer(timer, tick) wrmsrl(timer, tick)
-#define hv_init_timer_config(config, val) wrmsrl(config, val)
+#define hv_init_timer(timer, tick) \
+   wrmsrl(HV_X64_MSR_STIMER0_COUNT + (2*timer), tick)
+#define hv_init_timer_config(timer, val) \
+   wrmsrl(HV_X64_MSR_STIMER0_CONFIG + (2*timer), val)
 
 #define hv_get_simp(val) rdmsrl(HV_X64_MSR_SIMP, val)
 #define hv_set_simp(val) wrmsrl(HV_X64_MSR_SIMP, val)
@@ -89,8 +91,10 @@ static inline void vmbus_signal_eom(struct hv_message *msg, 
u32 old_msg_type)
 
 #define hv_get_vp_index(index) rdmsrl(HV_X64_MSR_VP_INDEX, index)
 
-#define hv_get_synint_state(int_num, val) rdmsrl(int_num, val)
-#define hv_set_synint_state(int_num, val) wrmsrl(int_num, val)
+#define hv_get_synint_state(int_num, val) \
+   rdmsrl(HV_X64_MSR_SINT0 + int_num, val)
+#define hv_set_synint_state(int_num, val) \
+   wrmsrl(HV_X64_MSR_SINT0 + int_num, val)
 
 void hyperv_callback_vector(void);
 void hyperv_reenlightenment_vector(void);
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 9b82549cbbc8..96c403a07906 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -127,14 +127,14 @@ static int hv_ce_set_next_event(unsigned long delta,
 
current_tick = hyperv_cs->read(NULL);
current_tick += delta;
-   hv_init_timer(HV_X64_MSR_STIMER0_COUNT, current_tick);
+   hv_init_timer(0, current_tick);
return 0;
 }
 
 static int hv_ce_shutdown(struct clock_event_device *evt)
 {
-   hv_init_timer(HV_X64_MSR_STIMER0_COUNT, 0);
-   hv_init_timer_config(HV_X64_MSR_STIMER0_CONFIG, 0);
+   hv_init_timer(0, 0);
+   hv_init_timer_config(0, 0);
if (direct_mode_enabled)
hv_disable_stimer0_percpu_irq(stimer0_irq);
 
@@ -164,7 +164,7 @@ static int hv_ce_set_oneshot(struct clock_event_device *evt)
timer_cfg.direct_mode = 0;
timer_cfg.sintx = VMBUS_MESSAGE_SINT;
}
-   hv_init_timer_config(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
+   hv_init_timer_config(0, timer_cfg.as_uint64);
return 0;
 }
 
@@ -298,8 +298,7 @@ int hv_synic_init(unsigned int cpu)
hv_set_siefp(siefp.as_uint64);
 
/* Setup the shared SINT. */
-   hv_get_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,
-   shared_sint.as_uint64);
+   hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
shared_sint.masked = false;
@@ -308,8 +307,7 @@ int hv_synic_init(unsigned int cpu)
else
shared_sint.auto_eoi = true;
 
-   hv_set_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,
-   shared_sint.as_uint64);
+   hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
/* Enable the global synic bit */
hv_get_synic_state(sctrl.as_uint64);
@@ -405,15 +403,13 @@ int hv_synic_cleanup(unsigned int cpu)
put_cpu_ptr(hv_cpu);
}
 
-   hv_get_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,
-   shared_sint.as_uint64);
+   hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
shared_sint.masked = 1;
 
/* Need to correctly cleanup in the case of SMP!!! */
/* Disable the interrupt */
-   hv_set_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,
-   shared_sint.as_uint64);
+   hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
hv_get_simp(simp.as_uint64);
simp.simp_enabled = 0;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/8] use the new async probing feature for the hyperv drivers

2018-06-05 Thread kys
From: Arjan van de Ven 

Recent kernels support asynchronous probing; most hyperv drivers
can be probed async easily so set the required flag for this.

Signed-off-by: Arjan van de Ven 
Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hid/hid-hyperv.c  | 3 +++
 drivers/hv/hv_balloon.c   | 3 +++
 drivers/hv/hv_util.c  | 3 +++
 drivers/input/serio/hyperv-keyboard.c | 3 +++
 drivers/net/hyperv/netvsc_drv.c   | 3 +++
 drivers/scsi/storvsc_drv.c| 3 +++
 drivers/video/fbdev/hyperv_fb.c   | 6 ++
 7 files changed, 24 insertions(+)

diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c
index 3aa2bb9f0f81..b372854cf38d 100644
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -598,6 +598,9 @@ static struct  hv_driver mousevsc_drv = {
.id_table = id_table,
.probe = mousevsc_probe,
.remove = mousevsc_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   },
 };
 
 static int __init mousevsc_init(void)
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index b3e9f13f8bc3..b1b788082793 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -1765,6 +1765,9 @@ static  struct hv_driver balloon_drv = {
.id_table = id_table,
.probe =  balloon_probe,
.remove =  balloon_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   },
 };
 
 static int __init init_balloon_drv(void)
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 14dce25c104f..423205077bf6 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -487,6 +487,9 @@ static  struct hv_driver util_drv = {
.id_table = id_table,
.probe =  util_probe,
.remove =  util_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   },
 };
 
 static int hv_ptp_enable(struct ptp_clock_info *info,
diff --git a/drivers/input/serio/hyperv-keyboard.c 
b/drivers/input/serio/hyperv-keyboard.c
index 25151d9214e0..47a0e81a2989 100644
--- a/drivers/input/serio/hyperv-keyboard.c
+++ b/drivers/input/serio/hyperv-keyboard.c
@@ -424,6 +424,9 @@ static struct  hv_driver hv_kbd_drv = {
.id_table = id_table,
.probe = hv_kbd_probe,
.remove = hv_kbd_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   },
 };
 
 static int __init hv_kbd_init(void)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index ecc84954c511..3965c62e79ba 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -2155,6 +2155,9 @@ static struct  hv_driver netvsc_drv = {
.id_table = id_table,
.probe = netvsc_probe,
.remove = netvsc_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   },
 };
 
 /*
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 8c51d628b52e..32027ac60aa4 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1893,6 +1893,9 @@ static struct hv_driver storvsc_drv = {
.id_table = id_table,
.probe = storvsc_probe,
.remove = storvsc_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   },
 };
 
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index 2fd49b2358f8..403d8cd3e582 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -912,6 +912,9 @@ static struct hv_driver hvfb_drv = {
.id_table = id_table,
.probe = hvfb_probe,
.remove = hvfb_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   },
 };
 
 static int hvfb_pci_stub_probe(struct pci_dev *pdev,
@@ -929,6 +932,9 @@ static struct pci_driver hvfb_pci_stub_driver = {
.id_table = pci_stub_id_table,
.probe =hvfb_pci_stub_probe,
.remove =   hvfb_pci_stub_remove,
+   .driver = {
+   .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+   }
 };
 
 static int __init hvfb_drv_init(void)
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 8/8] Tools: hv: vss: fix loop device detection

2018-06-05 Thread kys
From: Vitaly Kuznetsov 

Commit ea81fdf0981d ("Tools: hv: vss: Skip freezing filesystems backed by
loop") added skip for filesystems backed by loop device. However, it seems
the detection of such cases is incomplete.

It was found that with 'devicemapper' storage driver docker creates the
following chain:

NAMEMAJ:MIN
loop0   7:0
..docker-8:4-8473394-pool   253:0
  ..docker-8:4-8473394-eac...   253:1

so when we're looking at the mounted device we see major '253' and not '7'.

Solve the issue by walking /sys/dev/block/*/slaves chain and checking if
there's a loop device somewhere.

Other than that, don't skip mountpoints silently when stat() fails. In case
e.g. SELinux is failing stat we don't want to skip freezing everything
without letting user know about the failure.

Fixes: ea81fdf0981d ("Tools: hv: vss: Skip freezing filesystems backed by loop")
Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/hv_vss_daemon.c | 65 +---
 1 file changed, 61 insertions(+), 4 deletions(-)

diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
index 34031a297f02..b13300172762 100644
--- a/tools/hv/hv_vss_daemon.c
+++ b/tools/hv/hv_vss_daemon.c
@@ -36,6 +36,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /* Don't use syslog() in the function since that can cause write to disk */
 static int vss_do_freeze(char *dir, unsigned int cmd)
@@ -68,6 +70,55 @@ static int vss_do_freeze(char *dir, unsigned int cmd)
return !!ret;
 }
 
+static bool is_dev_loop(const char *blkname)
+{
+   char *buffer;
+   DIR *dir;
+   struct dirent *entry;
+   bool ret = false;
+
+   buffer = malloc(PATH_MAX);
+   if (!buffer) {
+   syslog(LOG_ERR, "Can't allocate memory!");
+   exit(1);
+   }
+
+   snprintf(buffer, PATH_MAX, "%s/loop", blkname);
+   if (!access(buffer, R_OK | X_OK)) {
+   ret = true;
+   goto free_buffer;
+   } else if (errno != ENOENT) {
+   syslog(LOG_ERR, "Can't access: %s; error:%d %s!",
+  buffer, errno, strerror(errno));
+   }
+
+   snprintf(buffer, PATH_MAX, "%s/slaves", blkname);
+   dir = opendir(buffer);
+   if (!dir) {
+   if (errno != ENOENT)
+   syslog(LOG_ERR, "Can't opendir: %s; error:%d %s!",
+  buffer, errno, strerror(errno));
+   goto free_buffer;
+   }
+
+   while ((entry = readdir(dir)) != NULL) {
+   if (strcmp(entry->d_name, ".") == 0 ||
+   strcmp(entry->d_name, "..") == 0)
+   continue;
+
+   snprintf(buffer, PATH_MAX, "%s/slaves/%s", blkname,
+entry->d_name);
+   if (is_dev_loop(buffer)) {
+   ret = true;
+   break;
+   }
+   }
+   closedir(dir);
+free_buffer:
+   free(buffer);
+   return ret;
+}
+
 static int vss_operate(int operation)
 {
char match[] = "/dev/";
@@ -75,6 +126,7 @@ static int vss_operate(int operation)
struct mntent *ent;
struct stat sb;
char errdir[1024] = {0};
+   char blkdir[23]; /* /sys/dev/block/XXX:XXX */
unsigned int cmd;
int error = 0, root_seen = 0, save_errno = 0;
 
@@ -96,10 +148,15 @@ static int vss_operate(int operation)
while ((ent = getmntent(mounts))) {
if (strncmp(ent->mnt_fsname, match, strlen(match)))
continue;
-   if (stat(ent->mnt_fsname, &sb) == -1)
-   continue;
-   if (S_ISBLK(sb.st_mode) && major(sb.st_rdev) == LOOP_MAJOR)
-   continue;
+   if (stat(ent->mnt_fsname, &sb)) {
+   syslog(LOG_ERR, "Can't stat: %s; error:%d %s!",
+  ent->mnt_fsname, errno, strerror(errno));
+   } else {
+   sprintf(blkdir, "/sys/dev/block/%d:%d",
+   major(sb.st_rdev), minor(sb.st_rdev));
+   if (is_dev_loop(blkdir))
+   continue;
+   }
if (hasmntopt(ent, MNTOPT_RO) != NULL)
continue;
if (strcmp(ent->mnt_type, "vfat") == 0)
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 6/8] Drivers: hv: vmbus: Make TLFS #define names architecture neutral

2018-06-05 Thread kys
From: Michael Kelley 

The Hyper-V feature and hint flags in hyperv-tlfs.h are all defined
with the string "X64" in the name.  Some of these flags are indeed
x86/x64 specific, but others are not.  For the ones that are used
in architecture independent Hyper-V driver code, or will be used in
the upcoming support for Hyper-V for ARM64, this patch removes the
"X64" from the name.

This patch changes the flags that are currently known to be
used on multiple architectures. Hyper-V for ARM64 is still a
work-in-progress and the Top Level Functional Spec (TLFS) has not
been separated into x86/x64 and ARM64 areas.  So additional flags
may need to be updated later.

This patch only changes symbol names.  There are no functional
changes.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_init.c  |  4 ++--
 arch/x86/include/asm/hyperv-tlfs.h | 12 ++--
 arch/x86/kernel/cpu/mshyperv.c |  4 ++--
 drivers/hv/hv.c| 10 +-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index cfecc2272f2d..3db87293dce0 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -302,7 +302,7 @@ void hyperv_init(void)
 * Register Hyper-V specific clocksource.
 */
 #ifdef CONFIG_HYPERV_TSCPAGE
-   if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) {
+   if (ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE) {
union hv_x64_msr_hypercall_contents tsc_msr;
 
tsc_pg = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL);
@@ -331,7 +331,7 @@ void hyperv_init(void)
 */
 
hyperv_cs = &hyperv_cs_msr;
-   if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE)
+   if (ms_hyperv.features & HV_MSR_TIME_REF_COUNT_AVAILABLE)
clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
 
return;
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 416cb0e0c496..44657e07fd59 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -35,9 +35,9 @@
 /* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
 #define HV_X64_MSR_VP_RUNTIME_AVAILABLE(1 << 0)
 /* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
-#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE(1 << 1)
+#define HV_MSR_TIME_REF_COUNT_AVAILABLE(1 << 1)
 /* Partition reference TSC MSR is available */
-#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE  (1 << 9)
+#define HV_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
 
 /* A partition's reference time stamp counter (TSC) page */
 #define HV_X64_MSR_REFERENCE_TSC   0x4021
@@ -60,7 +60,7 @@
  * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
  * HV_X64_MSR_STIMER3_COUNT) available
  */
-#define HV_X64_MSR_SYNTIMER_AVAILABLE  (1 << 3)
+#define HV_MSR_SYNTIMER_AVAILABLE  (1 << 3)
 /*
  * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
  * are available
@@ -86,7 +86,7 @@
 #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
 
 /* stimer Direct Mode is available */
-#define HV_X64_STIMER_DIRECT_MODE_AVAILABLE(1 << 19)
+#define HV_STIMER_DIRECT_MODE_AVAILABLE(1 << 19)
 
 /*
  * Feature identification: EBX indicates which flags were specified at
@@ -160,9 +160,9 @@
 #define HV_X64_RELAXED_TIMING_RECOMMENDED  (1 << 5)
 
 /*
- * Virtual APIC support
+ * Recommend not using Auto End-Of-Interrupt feature
  */
-#define HV_X64_DEPRECATING_AEOI_RECOMMENDED(1 << 9)
+#define HV_DEPRECATING_AEOI_RECOMMENDED(1 << 9)
 
 /* Recommend using the newer ExProcessorMasks interface */
 #define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED  (1 << 11)
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 8a49b7ef7b76..ad12733f6058 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -50,7 +50,7 @@ __visible void __irq_entry hyperv_vector_handler(struct 
pt_regs *regs)
if (vmbus_handler)
vmbus_handler();
 
-   if (ms_hyperv.hints & HV_X64_DEPRECATING_AEOI_RECOMMENDED)
+   if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)
ack_APIC_irq();
 
exiting_irq();
@@ -300,7 +300,7 @@ static void __init ms_hyperv_init_platform(void)
hyperv_reenlightenment_vector);
 
/* Setup the IDT for stimer0 */
-   if (ms_hyperv.misc_features & HV_X64_STIMER_DIRECT_MODE_AVAILABLE)
+   if (ms_hyperv.misc_features & HV_STIMER_DIRECT_MODE_AVAILABLE)
alloc_intr_gate(HYPERV_STIMER0_VECTOR,
hv_stimer0_callback_vector);
 #endif
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 96c403a07906..c72e8d7bd7fc 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -64,7 +64,7 @@ int hv_init(void)
   

[PATCH 2/8] x86/hyperv: Add interrupt handler annotations

2018-06-05 Thread kys
From: Michael Kelley 

Add standard interrupt handler annotations to
hyperv_vector_handler(). This does not fix any observed
bug, but avoids potential removal of the code by link
time optimization and makes it consistent with
hv_stimer0_vector_handler in the same source file.

Suggested-by: Thomas Gleixner 
Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/kernel/cpu/mshyperv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 031082c96db8..8a49b7ef7b76 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -41,7 +41,7 @@ static void (*hv_stimer0_handler)(void);
 static void (*hv_kexec_handler)(void);
 static void (*hv_crash_handler)(struct pt_regs *regs);
 
-void hyperv_vector_handler(struct pt_regs *regs)
+__visible void __irq_entry hyperv_vector_handler(struct pt_regs *regs)
 {
struct pt_regs *old_regs = set_irq_regs(regs);
 
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/8] Drivers: hv: Miscellaneous fixes/improvements

2018-06-05 Thread kys
From: "K. Y. Srinivasan" 

Some miscellaneous fixes/improvements. 

Arjan van de Ven (1):
  use the new async probing feature for the hyperv drivers

Dexuan Cui (1):
  Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer()

Michael Kelley (4):
  x86/hyperv: Add interrupt handler annotations
  Drivers: hv: vmbus: Add comments on ring buffer signaling
  Drivers: hv: vmbus: Remove x86 MSR refs in arch independent code
  Drivers: hv: vmbus: Make TLFS #define names architecture neutral

Olaf Hering (1):
  tools: hv: update lsvmbus to be compatible with python3

Vitaly Kuznetsov (1):
  Tools: hv: vss: fix loop device detection

 arch/x86/hyperv/hv_init.c |  4 +-
 arch/x86/include/asm/hyperv-tlfs.h| 12 ++---
 arch/x86/include/asm/mshyperv.h   | 12 +++--
 arch/x86/kernel/cpu/mshyperv.c|  6 +--
 drivers/hid/hid-hyperv.c  |  3 ++
 drivers/hv/channel_mgmt.c |  4 +-
 drivers/hv/hv.c   | 30 ++---
 drivers/hv/hv_balloon.c   |  3 ++
 drivers/hv/hv_util.c  |  3 ++
 drivers/hv/ring_buffer.c  | 65 ++-
 drivers/input/serio/hyperv-keyboard.c |  3 ++
 drivers/net/hyperv/netvsc_drv.c   |  3 ++
 drivers/scsi/storvsc_drv.c|  3 ++
 drivers/video/fbdev/hyperv_fb.c   |  6 +++
 include/linux/hyperv.h| 31 +
 tools/hv/hv_vss_daemon.c  | 65 +--
 tools/hv/lsvmbus  | 12 ++---
 17 files changed, 201 insertions(+), 64 deletions(-)

-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V3 5/5] X86: Hyper-V: Consolidate the allocation of the hypercall input page

2018-05-16 Thread kys
From: "K. Y. Srinivasan" 

Consolidate the allocation of the hypercall input page.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Michael Kelley 
---
 arch/x86/hyperv/hv_init.c   |  2 --
 arch/x86/hyperv/mmu.c   | 30 ++
 arch/x86/include/asm/mshyperv.h |  1 -
 3 files changed, 6 insertions(+), 27 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 6bc90d68ac8b..4c431e1c1eff 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -324,8 +324,6 @@ void __init hyperv_init(void)
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
-   hyper_alloc_mmu();
-
hv_apic_init();
 
/*
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index c9cd28f0bae4..5f053d7d1bd9 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -32,9 +32,6 @@ struct hv_flush_pcpu_ex {
 /* Each gva in gva_list encodes up to 4096 pages to flush */
 #define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
 
-static struct hv_flush_pcpu __percpu **pcpu_flush;
-
-static struct hv_flush_pcpu_ex __percpu **pcpu_flush_ex;
 
 /*
  * Fills in gva_list starting from offset. Returns the number of items added.
@@ -77,7 +74,7 @@ static void hyperv_flush_tlb_others(const struct cpumask 
*cpus,
 
trace_hyperv_mmu_flush_tlb_others(cpus, info);
 
-   if (!pcpu_flush || !hv_hypercall_pg)
+   if (!hv_hypercall_pg)
goto do_native;
 
if (cpumask_empty(cpus))
@@ -85,10 +82,8 @@ static void hyperv_flush_tlb_others(const struct cpumask 
*cpus,
 
local_irq_save(flags);
 
-   flush_pcpu = this_cpu_ptr(pcpu_flush);
-
-   if (unlikely(!*flush_pcpu))
-   *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+   flush_pcpu = (struct hv_flush_pcpu **)
+this_cpu_ptr(hyperv_pcpu_input_arg);
 
flush = *flush_pcpu;
 
@@ -164,7 +159,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
 
trace_hyperv_mmu_flush_tlb_others(cpus, info);
 
-   if (!pcpu_flush_ex || !hv_hypercall_pg)
+   if (!hv_hypercall_pg)
goto do_native;
 
if (cpumask_empty(cpus))
@@ -172,10 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct 
cpumask *cpus,
 
local_irq_save(flags);
 
-   flush_pcpu = this_cpu_ptr(pcpu_flush_ex);
-
-   if (unlikely(!*flush_pcpu))
-   *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+   flush_pcpu = (struct hv_flush_pcpu_ex **)
+this_cpu_ptr(hyperv_pcpu_input_arg);
 
flush = *flush_pcpu;
 
@@ -257,14 +250,3 @@ void hyperv_setup_mmu_ops(void)
pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
}
 }
-
-void hyper_alloc_mmu(void)
-{
-   if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
-   return;
-
-   if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
-   pcpu_flush = alloc_percpu(struct hv_flush_pcpu *);
-   else
-   pcpu_flush_ex = alloc_percpu(struct hv_flush_pcpu_ex *);
-}
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 0ee82519957b..9aaa493f5756 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -294,7 +294,6 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 
 void __init hyperv_init(void);
 void hyperv_setup_mmu_ops(void);
-void hyper_alloc_mmu(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
 bool hv_is_hyperv_initialized(void);
 void hyperv_cleanup(void);
-- 
2.17.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V3 1/5] X86: Hyper-V: Enlighten APIC access

2018-05-16 Thread kys
From: "K. Y. Srinivasan" 

Hyper-V supports MSR based APIC access; implement
the enlightenment.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Michael Kelley 
---
 arch/x86/hyperv/Makefile|   2 +-
 arch/x86/hyperv/hv_apic.c   | 104 
 arch/x86/hyperv/hv_init.c   |   5 +-
 arch/x86/include/asm/mshyperv.h |   4 +-
 4 files changed, 112 insertions(+), 3 deletions(-)
 create mode 100644 arch/x86/hyperv/hv_apic.c

diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index 367a8203cfcf..00ce4df01a09 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -1 +1 @@
-obj-y  := hv_init.o mmu.o
+obj-y  := hv_init.o mmu.o hv_apic.o
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
new file mode 100644
index ..ca20e31d311c
--- /dev/null
+++ b/arch/x86/hyperv/hv_apic.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Hyper-V specific APIC code.
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : K. Y. Srinivasan 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_X86_64
+#if IS_ENABLED(CONFIG_HYPERV)
+
+static u64 hv_apic_icr_read(void)
+{
+   u64 reg_val;
+
+   rdmsrl(HV_X64_MSR_ICR, reg_val);
+   return reg_val;
+}
+
+static void hv_apic_icr_write(u32 low, u32 id)
+{
+   u64 reg_val;
+
+   reg_val = SET_APIC_DEST_FIELD(id);
+   reg_val = reg_val << 32;
+   reg_val |= low;
+
+   wrmsrl(HV_X64_MSR_ICR, reg_val);
+}
+
+static u32 hv_apic_read(u32 reg)
+{
+   u32 reg_val, hi;
+
+   switch (reg) {
+   case APIC_EOI:
+   rdmsr(HV_X64_MSR_EOI, reg_val, hi);
+   return reg_val;
+   case APIC_TASKPRI:
+   rdmsr(HV_X64_MSR_TPR, reg_val, hi);
+   return reg_val;
+
+   default:
+   return native_apic_mem_read(reg);
+   }
+}
+
+static void hv_apic_write(u32 reg, u32 val)
+{
+   switch (reg) {
+   case APIC_EOI:
+   wrmsr(HV_X64_MSR_EOI, val, 0);
+   break;
+   case APIC_TASKPRI:
+   wrmsr(HV_X64_MSR_TPR, val, 0);
+   break;
+   default:
+   native_apic_mem_write(reg, val);
+   }
+}
+
+static void hv_apic_eoi_write(u32 reg, u32 val)
+{
+   wrmsr(HV_X64_MSR_EOI, val, 0);
+}
+
+void __init hv_apic_init(void)
+{
+   if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
+   pr_info("Hyper-V: Using MSR based APIC access\n");
+   apic_set_eoi_write(hv_apic_eoi_write);
+   apic->read  = hv_apic_read;
+   apic->write = hv_apic_write;
+   apic->icr_write = hv_apic_icr_write;
+   apic->icr_read  = hv_apic_icr_read;
+   }
+}
+
+#endif /* CONFIG_HYPERV */
+#endif /* CONFIG_X86_64 */
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index cfecc2272f2d..71e50fc2b7ef 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -242,8 +242,9 @@ static int hv_cpu_die(unsigned int cpu)
  *
  * 1. Setup the hypercall page.
  * 2. Register Hyper-V specific clocksource.
+ * 3. Setup Hyper-V specific APIC entry points.
  */
-void hyperv_init(void)
+void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
@@ -298,6 +299,8 @@ void hyperv_init(void)
 
hyper_alloc_mmu();
 
+   hv_apic_init();
+
/*
 * Register Hyper-V specific clocksource.
 */
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index b90e79610cf7..162977b82e2e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -258,7 +258,7 @@ static inline int hv_cpu_number_to_vp_number(int cpu_number)
return hv_vp_index[cpu_number];
 }
 
-void hyperv_init(void);
+void __init hyperv_init(void);
 void hyperv_setup_mmu_ops(void);
 void hyper_alloc_mmu(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
@@ -269,6 +269,7 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs);
 void set_hv_tscchange_cb(void (*cb)(void));
 void clear_hv_tscchange_cb(void);
 void hyperv_stop_tsc_emulation(void);
+void hv_apic_init(void);
 #else /* CONFIG_HYPERV */
 static inline void hyperv_init(void) {}
 static inline bool hv_is_hyperv_initialized(void) { return false; }
@@ -277,6 +278,7 @@ static inline void hyperv_setup_

[PATCH V3 3/5] X86: Hyper-V: Enhanced IPI enlightenment

2018-05-16 Thread kys
From: "K. Y. Srinivasan" 

Support enhanced IPI enlightenments (to target more than 64 CPUs).

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Michael Kelley 
---
 arch/x86/hyperv/hv_apic.c  | 42 +-
 arch/x86/hyperv/mmu.c  |  2 +-
 arch/x86/include/asm/hyperv-tlfs.h | 15 ++-
 arch/x86/include/asm/mshyperv.h| 33 +++
 4 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 3e0de61f1a7c..192b6ad6a361 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -93,6 +93,40 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
 /*
  * IPI implementation on Hyper-V.
  */
+static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
+{
+   struct ipi_arg_ex **arg;
+   struct ipi_arg_ex *ipi_arg;
+   unsigned long flags;
+   int nr_bank = 0;
+   int ret = 1;
+
+   local_irq_save(flags);
+   arg = (struct ipi_arg_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+   ipi_arg = *arg;
+   if (unlikely(!ipi_arg))
+   goto ipi_mask_ex_done;
+
+   ipi_arg->vector = vector;
+   ipi_arg->reserved = 0;
+   ipi_arg->vp_set.valid_bank_mask = 0;
+
+   if (!cpumask_equal(mask, cpu_present_mask)) {
+   ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
+   nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
+   }
+   if (!nr_bank)
+   ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
+
+   ret = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
+ ipi_arg, NULL);
+
+ipi_mask_ex_done:
+   local_irq_restore(flags);
+   return ((ret == 0) ? true : false);
+}
+
 static bool __send_ipi_mask(const struct cpumask *mask, int vector)
 {
int cur_cpu, vcpu;
@@ -110,6 +144,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
return false;
 
+   if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+   return __send_ipi_mask_ex(mask, vector);
+
local_irq_save(flags);
arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
 
@@ -193,7 +230,10 @@ static void hv_send_ipi_self(int vector)
 void __init hv_apic_init(void)
 {
if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
-   pr_info("Hyper-V: Using IPI hypercalls\n");
+   if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+   pr_info("Hyper-V: Using ext hypercalls for IPI\n");
+   else
+   pr_info("Hyper-V: Using IPI hypercalls\n");
/*
 * Set the IPI entry points.
 */
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index 56c9ebac946f..adee39a7a3f2 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -239,7 +239,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
flush->hv_vp_set.valid_bank_mask = 0;
 
if (!cpumask_equal(cpus, cpu_present_mask)) {
-   flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K;
+   flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vp_set(flush, cpus);
}
 
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 332e786d4deb..3bfa92c2793c 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -344,6 +344,7 @@ struct hv_tsc_emulation_status {
 #define HVCALL_SEND_IPI0x000b
 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX  0x0013
 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX   0x0014
+#define HVCALL_SEND_IPI_EX 0x0015
 #define HVCALL_POST_MESSAGE0x005c
 #define HVCALL_SIGNAL_EVENT0x005d
 
@@ -369,7 +370,7 @@ struct hv_tsc_emulation_status {
 #define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
 
 enum HV_GENERIC_SET_FORMAT {
-   HV_GENERIC_SET_SPARCE_4K,
+   HV_GENERIC_SET_SPARSE_4K,
HV_GENERIC_SET_ALL,
 };
 
@@ -721,4 +722,16 @@ struct ipi_arg_non_ex {
u64 cpu_mask;
 };
 
+struct hv_vpset {
+   u64 format;
+   u64 valid_bank_mask;
+   u64 bank_contents[];
+};
+
+struct ipi_arg_ex {
+   u32 vector;
+   u32 reserved;
+   struct hv_vpset vp_set;
+};
+
 #endif
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 1eff91599c2b..0ee82519957b 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -259,6 +259,39 @@ static inline int hv_cpu_number_to_vp_number(int 
cpu_number)
return hv_vp_index[cpu_number];
 }
 
+static inline int cpumask_to_vpset(struct hv_vpset *vpset,
+   const struct cpumask *cpus)
+{
+   int cpu, vc

[PATCH V3 2/5] X86: Hyper-V: Enable IPI enlightenments

2018-05-16 Thread kys
From: "K. Y. Srinivasan" 

Hyper-V supports hypercalls to implement IPI; use them.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Michael Kelley 
---
 arch/x86/hyperv/hv_apic.c  | 117 +
 arch/x86/hyperv/hv_init.c  |  27 +++
 arch/x86/include/asm/hyperv-tlfs.h |  15 
 arch/x86/include/asm/mshyperv.h|   1 +
 4 files changed, 160 insertions(+)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index ca20e31d311c..3e0de61f1a7c 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -33,6 +33,8 @@
 #ifdef CONFIG_X86_64
 #if IS_ENABLED(CONFIG_HYPERV)
 
+static struct apic orig_apic;
+
 static u64 hv_apic_icr_read(void)
 {
u64 reg_val;
@@ -88,8 +90,123 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
wrmsr(HV_X64_MSR_EOI, val, 0);
 }
 
+/*
+ * IPI implementation on Hyper-V.
+ */
+static bool __send_ipi_mask(const struct cpumask *mask, int vector)
+{
+   int cur_cpu, vcpu;
+   struct ipi_arg_non_ex **arg;
+   struct ipi_arg_non_ex *ipi_arg;
+   int ret = 1;
+   unsigned long flags;
+
+   if (cpumask_empty(mask))
+   return true;
+
+   if (!hv_hypercall_pg)
+   return false;
+
+   if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
+   return false;
+
+   local_irq_save(flags);
+   arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+   ipi_arg = *arg;
+   if (unlikely(!ipi_arg))
+   goto ipi_mask_done;
+
+   ipi_arg->vector = vector;
+   ipi_arg->reserved = 0;
+   ipi_arg->cpu_mask = 0;
+
+   for_each_cpu(cur_cpu, mask) {
+   vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   /*
+* This particular version of the IPI hypercall can
+* only target upto 64 CPUs.
+*/
+   if (vcpu >= 64)
+   goto ipi_mask_done;
+
+   __set_bit(vcpu, (unsigned long *)&ipi_arg->cpu_mask);
+   }
+
+   ret = hv_do_hypercall(HVCALL_SEND_IPI, ipi_arg, NULL);
+
+ipi_mask_done:
+   local_irq_restore(flags);
+   return ((ret == 0) ? true : false);
+}
+
+static bool __send_ipi_one(int cpu, int vector)
+{
+   struct cpumask mask = CPU_MASK_NONE;
+
+   cpumask_set_cpu(cpu, &mask);
+   return __send_ipi_mask(&mask, vector);
+}
+
+static void hv_send_ipi(int cpu, int vector)
+{
+   if (!__send_ipi_one(cpu, vector))
+   orig_apic.send_IPI(cpu, vector);
+}
+
+static void hv_send_ipi_mask(const struct cpumask *mask, int vector)
+{
+   if (!__send_ipi_mask(mask, vector))
+   orig_apic.send_IPI_mask(mask, vector);
+}
+
+static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
+{
+   unsigned int this_cpu = smp_processor_id();
+   struct cpumask new_mask;
+   const struct cpumask *local_mask;
+
+   cpumask_copy(&new_mask, mask);
+   cpumask_clear_cpu(this_cpu, &new_mask);
+   local_mask = &new_mask;
+   if (!__send_ipi_mask(local_mask, vector))
+   orig_apic.send_IPI_mask_allbutself(mask, vector);
+}
+
+static void hv_send_ipi_allbutself(int vector)
+{
+   hv_send_ipi_mask_allbutself(cpu_online_mask, vector);
+}
+
+static void hv_send_ipi_all(int vector)
+{
+   if (!__send_ipi_mask(cpu_online_mask, vector))
+   orig_apic.send_IPI_all(vector);
+}
+
+static void hv_send_ipi_self(int vector)
+{
+   if (!__send_ipi_one(smp_processor_id(), vector))
+   orig_apic.send_IPI_self(vector);
+}
+
 void __init hv_apic_init(void)
 {
+   if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
+   pr_info("Hyper-V: Using IPI hypercalls\n");
+   /*
+* Set the IPI entry points.
+*/
+   orig_apic = *apic;
+
+   apic->send_IPI = hv_send_ipi;
+   apic->send_IPI_mask = hv_send_ipi_mask;
+   apic->send_IPI_mask_allbutself = hv_send_ipi_mask_allbutself;
+   apic->send_IPI_allbutself = hv_send_ipi_allbutself;
+   apic->send_IPI_all = hv_send_ipi_all;
+   apic->send_IPI_self = hv_send_ipi_self;
+   }
+
if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
pr_info("Hyper-V: Using MSR based APIC access\n");
apic_set_eoi_write(hv_apic_eoi_write);
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 71e50fc2b7ef..6bc90d68ac8b 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -91,12 +91,19 @@ EXPORT_SYMBOL_GPL(hv_vp_index);
 struct hv_vp_assist_page **hv_vp_assist_page;
 EXPORT_SYMBOL_GPL(hv_vp_assist_page);
 
+void  __percpu **hyperv_pcpu_input_arg;
+EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
+
 u32 hv_max_vp_index;
 
 static int hv_cpu_init(unsigned int cpu)
 {
u64 msr_vp_index;
struct hv_vp_assist_page **hvp = &hv_vp_assis

[PATCH V3 4/5] X86: Hyper-V: Consolidate code for converting cpumask to vpset

2018-05-16 Thread kys
From: "K. Y. Srinivasan" 

Consolidate code for converting cpumask to vpset.

Signed-off-by: K. Y. Srinivasan 
Reviewed-by: Michael Kelley 
---
 arch/x86/hyperv/mmu.c | 43 ++-
 1 file changed, 2 insertions(+), 41 deletions(-)

diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index adee39a7a3f2..c9cd28f0bae4 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -25,11 +25,7 @@ struct hv_flush_pcpu {
 struct hv_flush_pcpu_ex {
u64 address_space;
u64 flags;
-   struct {
-   u64 format;
-   u64 valid_bank_mask;
-   u64 bank_contents[];
-   } hv_vp_set;
+   struct hv_vpset hv_vp_set;
u64 gva_list[];
 };
 
@@ -70,41 +66,6 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
return gva_n - offset;
 }
 
-/* Return the number of banks in the resulting vp_set */
-static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
-   const struct cpumask *cpus)
-{
-   int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
-
-   /* valid_bank_mask can represent up to 64 banks */
-   if (hv_max_vp_index / 64 >= 64)
-   return 0;
-
-   /*
-* Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
-* structs are not cleared between calls, we risk flushing unneeded
-* vCPUs otherwise.
-*/
-   for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
-   flush->hv_vp_set.bank_contents[vcpu_bank] = 0;
-
-   /*
-* Some banks may end up being empty but this is acceptable.
-*/
-   for_each_cpu(cpu, cpus) {
-   vcpu = hv_cpu_number_to_vp_number(cpu);
-   vcpu_bank = vcpu / 64;
-   vcpu_offset = vcpu % 64;
-   __set_bit(vcpu_offset, (unsigned long *)
- &flush->hv_vp_set.bank_contents[vcpu_bank]);
-   if (vcpu_bank >= nr_bank)
-   nr_bank = vcpu_bank + 1;
-   }
-   flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
-
-   return nr_bank;
-}
-
 static void hyperv_flush_tlb_others(const struct cpumask *cpus,
const struct flush_tlb_info *info)
 {
@@ -240,7 +201,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
 
if (!cpumask_equal(cpus, cpu_present_mask)) {
flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
-   nr_bank = cpumask_to_vp_set(flush, cpus);
+   nr_bank = cpumask_to_vpset(&(flush->hv_vp_set), cpus);
}
 
if (!nr_bank) {
-- 
2.17.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V3 0/5] X86: Hyper-V: APIC enlightenments

2018-05-16 Thread kys
From: "K. Y. Srinivasan" 

Implement APIC related enlightenments.

V2: Addressed comments from Thomas Gleixner 
and Michael Kelley (EOSG) .

V3: Address build issues reported by kbuild test robot 

K. Y. Srinivasan (5):
  X86: Hyper-V: Enlighten APIC access
  X86: Hyper-V: Enable IPI enlightenments
  X86: Hyper-V: Enhanced IPI enlightenment
  X86: Hyper-V: Consolidate code for converting cpumask to vpset
  X86: Hyper-V: Consolidate the allocation of the hypercall input page

 arch/x86/hyperv/Makefile   |   2 +-
 arch/x86/hyperv/hv_apic.c  | 261 +
 arch/x86/hyperv/hv_init.c  |  32 +++-
 arch/x86/hyperv/mmu.c  |  75 +
 arch/x86/include/asm/hyperv-tlfs.h |  30 +++-
 arch/x86/include/asm/mshyperv.h|  39 -
 6 files changed, 367 insertions(+), 72 deletions(-)
 create mode 100644 arch/x86/hyperv/hv_apic.c

-- 
2.17.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/1] Drivers: hv: vmbus: enable VMBus protocol version 5.0

2018-05-12 Thread kys
From: Dexuan Cui 

With VMBus protocol 5.0, we're able to better support new features, e.g.
running two or more VMBus drivers simultaneously in a single VM -- note:
we can't simply load the current VMBus driver twice, instead, a secondary
VMBus driver must be implemented.

This patch adds the support for the new VMBus protocol, which is available
on new Windows hosts, by:

1) We still use SINT2 for compatibility;
2) We must use Connection ID 4 for the Initiate Contact Message, and for
subsequent messages, we must use the Message Connection ID field in
the host-returned VersionResponse Message.

Notes for developers of the secondary VMBus driver:
1) Must use VMBus protocol 5.0 as well;
2) Must use a different SINT number that is not in use.
3) Must use Connection ID 4 for the Initiate Contact Message, and for
subsequent messages, must use the Message Connection ID field in
the host-returned VersionResponse Message.
4) It's possible that the primary VMBus driver using protocol version 4.0
can work with a secondary VMBus driver using protocol version 5.0, but it's
recommended that both should use 5.0 for new Hyper-V features in the future.

Signed-off-by: Dexuan Cui 
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Cc: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/connection.c   | 44 ++--
 drivers/hv/hyperv_vmbus.h |  3 +++
 include/linux/hyperv.h| 26 --
 3 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index 72855182b191..19e046820fda 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -63,6 +63,9 @@ static __u32 vmbus_get_next_version(__u32 current_version)
case (VERSION_WIN10):
return VERSION_WIN8_1;
 
+   case (VERSION_WIN10_V5):
+   return VERSION_WIN10;
+
case (VERSION_WS2008):
default:
return VERSION_INVAL;
@@ -80,9 +83,29 @@ static int vmbus_negotiate_version(struct 
vmbus_channel_msginfo *msginfo,
 
msg = (struct vmbus_channel_initiate_contact *)msginfo->msg;
 
+   memset(msg, 0, sizeof(*msg));
msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
msg->vmbus_version_requested = version;
-   msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
+
+   /*
+* VMBus protocol 5.0 (VERSION_WIN10_V5) requires that we must use
+* VMBUS_MESSAGE_CONNECTION_ID_4 for the Initiate Contact Message,
+* and for subsequent messages, we must use the Message Connection ID
+* field in the host-returned Version Response Message. And, with
+* VERSION_WIN10_V5, we don't use msg->interrupt_page, but we tell
+* the host explicitly that we still use VMBUS_MESSAGE_SINT(2) for
+* compatibility.
+*
+* On old hosts, we should always use VMBUS_MESSAGE_CONNECTION_ID (1).
+*/
+   if (version >= VERSION_WIN10_V5) {
+   msg->msg_sint = VMBUS_MESSAGE_SINT;
+   vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID_4;
+   } else {
+   msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
+   vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID;
+   }
+
msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
/*
@@ -137,6 +160,10 @@ static int vmbus_negotiate_version(struct 
vmbus_channel_msginfo *msginfo,
/* Check if successful */
if (msginfo->response.version_response.version_supported) {
vmbus_connection.conn_state = CONNECTED;
+
+   if (version >= VERSION_WIN10_V5)
+   vmbus_connection.msg_conn_id =
+   msginfo->response.version_response.msg_conn_id;
} else {
return -ECONNREFUSED;
}
@@ -354,13 +381,14 @@ void vmbus_on_event(unsigned long data)
  */
 int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep)
 {
+   struct vmbus_channel_message_header *hdr;
union hv_connection_id conn_id;
int ret = 0;
int retries = 0;
u32 usec = 1;
 
conn_id.asu32 = 0;
-   conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
+   conn_id.u.id = vmbus_connection.msg_conn_id;
 
/*
 * hv_post_message() can have transient failures because of
@@ -372,6 +400,18 @@ int vmbus_post_msg(void *buffer, size_t buflen, bool 
can_sleep)
 
switch (ret) {
case HV_STATUS_INVALID_CONNECTION_ID:
+   /*
+* See vmbus_negotiate_version(): VMBus protocol 5.0
+* requires that we must use
+* VMBUS_MESSAGE_CONNECTION_ID_4 for the Initiate
+* Contact message, but on old hosts that only
+* supp

[PATCH 1/1] doc: fix sysfs ABI documentation

2018-05-12 Thread kys
From: Stephen Hemminger 

In 4.9 kernel, the sysfs files for Hyper-V VMBus changed name but
the documentation files were not updated. The current sysfs file
names are /sys/bus/vmbus/devices//...

See commit 9a56e5d6a0ba ("Drivers: hv: make VMBus bus ids persistent")
and commit f6b2db084b65 ("vmbus: make sysfs names consistent with PCI")

Reported-by: Michael Kelley 
Signed-off-by: Stephen Hemminger 
Cc: sta...@vger.kernel.org
Signed-off-by: K. Y. Srinivasan 
---
 Documentation/ABI/stable/sysfs-bus-vmbus | 40 
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus 
b/Documentation/ABI/stable/sysfs-bus-vmbus
index 0c9d9dcd2151..3eaffbb2d468 100644
--- a/Documentation/ABI/stable/sysfs-bus-vmbus
+++ b/Documentation/ABI/stable/sysfs-bus-vmbus
@@ -1,25 +1,25 @@
-What:  /sys/bus/vmbus/devices/vmbus_*/id
+What:  /sys/bus/vmbus/devices//id
 Date:  Jul 2009
 KernelVersion: 2.6.31
 Contact:   K. Y. Srinivasan 
 Description:   The VMBus child_relid of the device's primary channel
 Users: tools/hv/lsvmbus
 
-What:  /sys/bus/vmbus/devices/vmbus_*/class_id
+What:  /sys/bus/vmbus/devices//class_id
 Date:  Jul 2009
 KernelVersion: 2.6.31
 Contact:   K. Y. Srinivasan 
 Description:   The VMBus interface type GUID of the device
 Users: tools/hv/lsvmbus
 
-What:  /sys/bus/vmbus/devices/vmbus_*/device_id
+What:  /sys/bus/vmbus/devices//device_id
 Date:  Jul 2009
 KernelVersion: 2.6.31
 Contact:   K. Y. Srinivasan 
 Description:   The VMBus interface instance GUID of the device
 Users: tools/hv/lsvmbus
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channel_vp_mapping
+What:  /sys/bus/vmbus/devices//channel_vp_mapping
 Date:  Jul 2015
 KernelVersion: 4.2.0
 Contact:   K. Y. Srinivasan 
@@ -28,112 +28,112 @@ Description:  The mapping of which primary/sub 
channels are bound to which
Format: 
 Users: tools/hv/lsvmbus
 
-What:  /sys/bus/vmbus/devices/vmbus_*/device
+What:  /sys/bus/vmbus/devices//device
 Date:  Dec. 2015
 KernelVersion: 4.5
 Contact:   K. Y. Srinivasan 
 Description:   The 16 bit device ID of the device
 Users: tools/hv/lsvmbus and user level RDMA libraries
 
-What:  /sys/bus/vmbus/devices/vmbus_*/vendor
+What:  /sys/bus/vmbus/devices//vendor
 Date:  Dec. 2015
 KernelVersion: 4.5
 Contact:   K. Y. Srinivasan 
 Description:   The 16 bit vendor ID of the device
 Users: tools/hv/lsvmbus and user level RDMA libraries
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN
+What:  /sys/bus/vmbus/devices//channels/
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
 Description:   Directory for per-channel information
NN is the VMBUS relid associtated with the channel.
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN/cpu
+What:  /sys/bus/vmbus/devices//channels//cpu
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
 Description:   VCPU (sub)channel is affinitized to
 Users: tools/hv/lsvmbus and other debugging tools
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN/cpu
+What:  /sys/bus/vmbus/devices//channels//cpu
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
 Description:   VCPU (sub)channel is affinitized to
 Users: tools/hv/lsvmbus and other debugging tools
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN/in_mask
+What:  /sys/bus/vmbus/devices//channels//in_mask
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
 Description:   Host to guest channel interrupt mask
 Users: Debugging tools
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN/latency
+What:  /sys/bus/vmbus/devices//channels//latency
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
 Description:   Channel signaling latency
 Users: Debugging tools
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN/out_mask
+What:  /sys/bus/vmbus/devices//channels//out_mask
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
 Description:   Guest to host channel interrupt mask
 Users: Debugging tools
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN/pending
+What:  /sys/bus/vmbus/devices//channels//pending
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
 Description:   Channel interrupt pending state
 Users: Debugging tools
 
-What:  /sys/bus/vmbus/devices/vmbus_*/channels/NN/read_avail
+What:  /sys/bus/vmbus/devices//channels//read_avail
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:  

[PATCH V2 2/5] X86: Hyper-V: Enable IPI enlightenments

2018-05-03 Thread kys
From: "K. Y. Srinivasan" 

Hyper-V supports hypercalls to implement IPI; use them.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_apic.c  | 118 +
 arch/x86/hyperv/hv_init.c  |  27 +
 arch/x86/include/asm/hyperv-tlfs.h |  15 +
 arch/x86/include/asm/mshyperv.h|   1 +
 4 files changed, 161 insertions(+)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 41f8b71ca19e..f52d08a7a343 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -31,6 +31,9 @@
 #include 
 
 #if IS_ENABLED(CONFIG_HYPERV)
+
+static struct apic orig_apic;
+
 static u64 hv_apic_icr_read(void)
 {
u64 reg_val;
@@ -86,8 +89,123 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
wrmsr(HV_X64_MSR_EOI, val, 0);
 }
 
+/*
+ * IPI implementation on Hyper-V.
+ */
+static bool __send_ipi_mask(const struct cpumask *mask, int vector)
+{
+   int cur_cpu, vcpu;
+   struct ipi_arg_non_ex **arg;
+   struct ipi_arg_non_ex *ipi_arg;
+   int ret = 1;
+   unsigned long flags;
+
+   if (cpumask_empty(mask))
+   return true;
+
+   if (!hv_hypercall_pg)
+   return false;
+
+   if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
+   return false;
+
+   local_irq_save(flags);
+   arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+   ipi_arg = *arg;
+   if (unlikely(!ipi_arg))
+   goto ipi_mask_done;
+
+   ipi_arg->vector = vector;
+   ipi_arg->reserved = 0;
+   ipi_arg->cpu_mask = 0;
+
+   for_each_cpu(cur_cpu, mask) {
+   vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   /*
+* This particular version of the IPI hypercall can
+* only target upto 64 CPUs.
+*/
+   if (vcpu >= 64)
+   goto ipi_mask_done;
+
+   __set_bit(vcpu, (unsigned long *)&ipi_arg->cpu_mask);
+   }
+
+   ret = hv_do_hypercall(HVCALL_SEND_IPI, ipi_arg, NULL);
+
+ipi_mask_done:
+   local_irq_restore(flags);
+   return ((ret == 0) ? true : false);
+}
+
+static bool __send_ipi_one(int cpu, int vector)
+{
+   struct cpumask mask = CPU_MASK_NONE;
+
+   cpumask_set_cpu(cpu, &mask);
+   return __send_ipi_mask(&mask, vector);
+}
+
+static void hv_send_ipi(int cpu, int vector)
+{
+   if (!__send_ipi_one(cpu, vector))
+   orig_apic.send_IPI(cpu, vector);
+}
+
+static void hv_send_ipi_mask(const struct cpumask *mask, int vector)
+{
+   if (!__send_ipi_mask(mask, vector))
+   orig_apic.send_IPI_mask(mask, vector);
+}
+
+static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
+{
+   unsigned int this_cpu = smp_processor_id();
+   struct cpumask new_mask;
+   const struct cpumask *local_mask;
+
+   cpumask_copy(&new_mask, mask);
+   cpumask_clear_cpu(this_cpu, &new_mask);
+   local_mask = &new_mask;
+   if (!__send_ipi_mask(local_mask, vector))
+   orig_apic.send_IPI_mask_allbutself(mask, vector);
+}
+
+static void hv_send_ipi_allbutself(int vector)
+{
+   hv_send_ipi_mask_allbutself(cpu_online_mask, vector);
+}
+
+static void hv_send_ipi_all(int vector)
+{
+   if (!__send_ipi_mask(cpu_online_mask, vector))
+   orig_apic.send_IPI_all(vector);
+}
+
+static void hv_send_ipi_self(int vector)
+{
+   if (!__send_ipi_one(smp_processor_id(), vector))
+   orig_apic.send_IPI_self(vector);
+}
+
 void __init hv_apic_init(void)
 {
+   if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
+   pr_info("Hyper-V: Using IPI hypercalls\n");
+   /*
+* Set the IPI entry points.
+*/
+   orig_apic = *apic;
+
+   apic->send_IPI = hv_send_ipi;
+   apic->send_IPI_mask = hv_send_ipi_mask;
+   apic->send_IPI_mask_allbutself = hv_send_ipi_mask_allbutself;
+   apic->send_IPI_allbutself = hv_send_ipi_allbutself;
+   apic->send_IPI_all = hv_send_ipi_all;
+   apic->send_IPI_self = hv_send_ipi_self;
+   }
+
if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
pr_info("Hyper-V: Using MSR based APIC access\n");
apic_set_eoi_write(hv_apic_eoi_write);
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 71e50fc2b7ef..6bc90d68ac8b 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -91,12 +91,19 @@ EXPORT_SYMBOL_GPL(hv_vp_index);
 struct hv_vp_assist_page **hv_vp_assist_page;
 EXPORT_SYMBOL_GPL(hv_vp_assist_page);
 
+void  __percpu **hyperv_pcpu_input_arg;
+EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
+
 u32 hv_max_vp_index;
 
 static int hv_cpu_init(unsigned int cpu)
 {
u64 msr_vp_index;
struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];

[PATCH V2 5/5] X86: Hyper-V: Consolidate the allocation of the hypercall input page

2018-05-03 Thread kys
From: "K. Y. Srinivasan" 

Consolidate the allocation of the hypercall input page.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_init.c   |  2 --
 arch/x86/hyperv/mmu.c   | 30 ++
 arch/x86/include/asm/mshyperv.h |  1 -
 3 files changed, 6 insertions(+), 27 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 6bc90d68ac8b..4c431e1c1eff 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -324,8 +324,6 @@ void __init hyperv_init(void)
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
-   hyper_alloc_mmu();
-
hv_apic_init();
 
/*
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index c9cd28f0bae4..5f053d7d1bd9 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -32,9 +32,6 @@ struct hv_flush_pcpu_ex {
 /* Each gva in gva_list encodes up to 4096 pages to flush */
 #define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
 
-static struct hv_flush_pcpu __percpu **pcpu_flush;
-
-static struct hv_flush_pcpu_ex __percpu **pcpu_flush_ex;
 
 /*
  * Fills in gva_list starting from offset. Returns the number of items added.
@@ -77,7 +74,7 @@ static void hyperv_flush_tlb_others(const struct cpumask 
*cpus,
 
trace_hyperv_mmu_flush_tlb_others(cpus, info);
 
-   if (!pcpu_flush || !hv_hypercall_pg)
+   if (!hv_hypercall_pg)
goto do_native;
 
if (cpumask_empty(cpus))
@@ -85,10 +82,8 @@ static void hyperv_flush_tlb_others(const struct cpumask 
*cpus,
 
local_irq_save(flags);
 
-   flush_pcpu = this_cpu_ptr(pcpu_flush);
-
-   if (unlikely(!*flush_pcpu))
-   *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+   flush_pcpu = (struct hv_flush_pcpu **)
+this_cpu_ptr(hyperv_pcpu_input_arg);
 
flush = *flush_pcpu;
 
@@ -164,7 +159,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
 
trace_hyperv_mmu_flush_tlb_others(cpus, info);
 
-   if (!pcpu_flush_ex || !hv_hypercall_pg)
+   if (!hv_hypercall_pg)
goto do_native;
 
if (cpumask_empty(cpus))
@@ -172,10 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct 
cpumask *cpus,
 
local_irq_save(flags);
 
-   flush_pcpu = this_cpu_ptr(pcpu_flush_ex);
-
-   if (unlikely(!*flush_pcpu))
-   *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+   flush_pcpu = (struct hv_flush_pcpu_ex **)
+this_cpu_ptr(hyperv_pcpu_input_arg);
 
flush = *flush_pcpu;
 
@@ -257,14 +250,3 @@ void hyperv_setup_mmu_ops(void)
pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
}
 }
-
-void hyper_alloc_mmu(void)
-{
-   if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
-   return;
-
-   if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
-   pcpu_flush = alloc_percpu(struct hv_flush_pcpu *);
-   else
-   pcpu_flush_ex = alloc_percpu(struct hv_flush_pcpu_ex *);
-}
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 0ee82519957b..9aaa493f5756 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -294,7 +294,6 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 
 void __init hyperv_init(void);
 void hyperv_setup_mmu_ops(void);
-void hyper_alloc_mmu(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
 bool hv_is_hyperv_initialized(void);
 void hyperv_cleanup(void);
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 4/5] X86: Hyper-V: Consolidate code for converting cpumask to vpset

2018-05-03 Thread kys
From: "K. Y. Srinivasan" 

Consolidate code for converting cpumask to vpset.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/mmu.c | 43 ++-
 1 file changed, 2 insertions(+), 41 deletions(-)

diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index adee39a7a3f2..c9cd28f0bae4 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -25,11 +25,7 @@ struct hv_flush_pcpu {
 struct hv_flush_pcpu_ex {
u64 address_space;
u64 flags;
-   struct {
-   u64 format;
-   u64 valid_bank_mask;
-   u64 bank_contents[];
-   } hv_vp_set;
+   struct hv_vpset hv_vp_set;
u64 gva_list[];
 };
 
@@ -70,41 +66,6 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
return gva_n - offset;
 }
 
-/* Return the number of banks in the resulting vp_set */
-static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
-   const struct cpumask *cpus)
-{
-   int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
-
-   /* valid_bank_mask can represent up to 64 banks */
-   if (hv_max_vp_index / 64 >= 64)
-   return 0;
-
-   /*
-* Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
-* structs are not cleared between calls, we risk flushing unneeded
-* vCPUs otherwise.
-*/
-   for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
-   flush->hv_vp_set.bank_contents[vcpu_bank] = 0;
-
-   /*
-* Some banks may end up being empty but this is acceptable.
-*/
-   for_each_cpu(cpu, cpus) {
-   vcpu = hv_cpu_number_to_vp_number(cpu);
-   vcpu_bank = vcpu / 64;
-   vcpu_offset = vcpu % 64;
-   __set_bit(vcpu_offset, (unsigned long *)
- &flush->hv_vp_set.bank_contents[vcpu_bank]);
-   if (vcpu_bank >= nr_bank)
-   nr_bank = vcpu_bank + 1;
-   }
-   flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
-
-   return nr_bank;
-}
-
 static void hyperv_flush_tlb_others(const struct cpumask *cpus,
const struct flush_tlb_info *info)
 {
@@ -240,7 +201,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
 
if (!cpumask_equal(cpus, cpu_present_mask)) {
flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
-   nr_bank = cpumask_to_vp_set(flush, cpus);
+   nr_bank = cpumask_to_vpset(&(flush->hv_vp_set), cpus);
}
 
if (!nr_bank) {
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 1/5] X86: Hyper-V: Enlighten APIC access

2018-05-03 Thread kys
From: "K. Y. Srinivasan" 

Hyper-V supports MSR based APIC access; implement
the enlightenment.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/Makefile|   2 +-
 arch/x86/hyperv/hv_apic.c   | 101 
 arch/x86/hyperv/hv_init.c   |   5 +-
 arch/x86/include/asm/mshyperv.h |   4 +-
 4 files changed, 109 insertions(+), 3 deletions(-)
 create mode 100644 arch/x86/hyperv/hv_apic.c

diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index 367a8203cfcf..00ce4df01a09 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -1 +1 @@
-obj-y  := hv_init.o mmu.o
+obj-y  := hv_init.o mmu.o hv_apic.o
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
new file mode 100644
index ..41f8b71ca19e
--- /dev/null
+++ b/arch/x86/hyperv/hv_apic.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Hyper-V specific APIC code.
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : K. Y. Srinivasan 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#if IS_ENABLED(CONFIG_HYPERV)
+static u64 hv_apic_icr_read(void)
+{
+   u64 reg_val;
+
+   rdmsrl(HV_X64_MSR_ICR, reg_val);
+   return reg_val;
+}
+
+static void hv_apic_icr_write(u32 low, u32 id)
+{
+   u64 reg_val;
+
+   reg_val = SET_APIC_DEST_FIELD(id);
+   reg_val = reg_val << 32;
+   reg_val |= low;
+
+   wrmsrl(HV_X64_MSR_ICR, reg_val);
+}
+
+static u32 hv_apic_read(u32 reg)
+{
+   u32 reg_val, hi;
+
+   switch (reg) {
+   case APIC_EOI:
+   rdmsr(HV_X64_MSR_EOI, reg_val, hi);
+   return reg_val;
+   case APIC_TASKPRI:
+   rdmsr(HV_X64_MSR_TPR, reg_val, hi);
+   return reg_val;
+
+   default:
+   return native_apic_mem_read(reg);
+   }
+}
+
+static void hv_apic_write(u32 reg, u32 val)
+{
+   switch (reg) {
+   case APIC_EOI:
+   wrmsr(HV_X64_MSR_EOI, val, 0);
+   break;
+   case APIC_TASKPRI:
+   wrmsr(HV_X64_MSR_TPR, val, 0);
+   break;
+   default:
+   native_apic_mem_write(reg, val);
+   }
+}
+
+static void hv_apic_eoi_write(u32 reg, u32 val)
+{
+   wrmsr(HV_X64_MSR_EOI, val, 0);
+}
+
+void __init hv_apic_init(void)
+{
+   if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
+   pr_info("Hyper-V: Using MSR based APIC access\n");
+   apic_set_eoi_write(hv_apic_eoi_write);
+   apic->read  = hv_apic_read;
+   apic->write = hv_apic_write;
+   apic->icr_write = hv_apic_icr_write;
+   apic->icr_read  = hv_apic_icr_read;
+   }
+}
+
+#endif /*CONFIG_HYPERV */
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index cfecc2272f2d..71e50fc2b7ef 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -242,8 +242,9 @@ static int hv_cpu_die(unsigned int cpu)
  *
  * 1. Setup the hypercall page.
  * 2. Register Hyper-V specific clocksource.
+ * 3. Setup Hyper-V specific APIC entry points.
  */
-void hyperv_init(void)
+void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
@@ -298,6 +299,8 @@ void hyperv_init(void)
 
hyper_alloc_mmu();
 
+   hv_apic_init();
+
/*
 * Register Hyper-V specific clocksource.
 */
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index b90e79610cf7..162977b82e2e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -258,7 +258,7 @@ static inline int hv_cpu_number_to_vp_number(int cpu_number)
return hv_vp_index[cpu_number];
 }
 
-void hyperv_init(void);
+void __init hyperv_init(void);
 void hyperv_setup_mmu_ops(void);
 void hyper_alloc_mmu(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
@@ -269,6 +269,7 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs);
 void set_hv_tscchange_cb(void (*cb)(void));
 void clear_hv_tscchange_cb(void);
 void hyperv_stop_tsc_emulation(void);
+void hv_apic_init(void);
 #else /* CONFIG_HYPERV */
 static inline void hyperv_init(void) {}
 static inline bool hv_is_hyperv_initialized(void) { return false; }
@@ -277,6 +278,7 @@ static inline void hyperv_setup_mmu_ops(void) {}
 static inline void set_hv_tscchange_cb(void (*cb)(void))

[PATCH V2 3/5] X86: Hyper-V: Enhanced IPI enlightenment

2018-05-03 Thread kys
From: "K. Y. Srinivasan" 

Support enhanced IPI enlightenments (to target more than 64 CPUs).

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_apic.c  | 42 +-
 arch/x86/hyperv/mmu.c  |  2 +-
 arch/x86/include/asm/hyperv-tlfs.h | 15 +-
 arch/x86/include/asm/mshyperv.h| 33 ++
 4 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index f52d08a7a343..1e269a318c27 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -92,6 +92,40 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
 /*
  * IPI implementation on Hyper-V.
  */
+static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector)
+{
+   struct ipi_arg_ex **arg;
+   struct ipi_arg_ex *ipi_arg;
+   unsigned long flags;
+   int nr_bank = 0;
+   int ret = 1;
+
+   local_irq_save(flags);
+   arg = (struct ipi_arg_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+   ipi_arg = *arg;
+   if (unlikely(!ipi_arg))
+   goto ipi_mask_ex_done;
+
+   ipi_arg->vector = vector;
+   ipi_arg->reserved = 0;
+   ipi_arg->vp_set.valid_bank_mask = 0;
+
+   if (!cpumask_equal(mask, cpu_present_mask)) {
+   ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
+   nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
+   }
+   if (!nr_bank)
+   ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
+
+   ret = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
+ ipi_arg, NULL);
+
+ipi_mask_ex_done:
+   local_irq_restore(flags);
+   return ((ret == 0) ? true : false);
+}
+
 static bool __send_ipi_mask(const struct cpumask *mask, int vector)
 {
int cur_cpu, vcpu;
@@ -109,6 +143,9 @@ static bool __send_ipi_mask(const struct cpumask *mask, int 
vector)
if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
return false;
 
+   if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+   return __send_ipi_mask_ex(mask, vector);
+
local_irq_save(flags);
arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
 
@@ -192,7 +229,10 @@ static void hv_send_ipi_self(int vector)
 void __init hv_apic_init(void)
 {
if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
-   pr_info("Hyper-V: Using IPI hypercalls\n");
+   if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+   pr_info("Hyper-V: Using ext hypercalls for IPI\n");
+   else
+   pr_info("Hyper-V: Using IPI hypercalls\n");
/*
 * Set the IPI entry points.
 */
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index 56c9ebac946f..adee39a7a3f2 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -239,7 +239,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
flush->hv_vp_set.valid_bank_mask = 0;
 
if (!cpumask_equal(cpus, cpu_present_mask)) {
-   flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K;
+   flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vp_set(flush, cpus);
}
 
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 332e786d4deb..3bfa92c2793c 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -344,6 +344,7 @@ struct hv_tsc_emulation_status {
 #define HVCALL_SEND_IPI0x000b
 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX  0x0013
 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX   0x0014
+#define HVCALL_SEND_IPI_EX 0x0015
 #define HVCALL_POST_MESSAGE0x005c
 #define HVCALL_SIGNAL_EVENT0x005d
 
@@ -369,7 +370,7 @@ struct hv_tsc_emulation_status {
 #define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
 
 enum HV_GENERIC_SET_FORMAT {
-   HV_GENERIC_SET_SPARCE_4K,
+   HV_GENERIC_SET_SPARSE_4K,
HV_GENERIC_SET_ALL,
 };
 
@@ -721,4 +722,16 @@ struct ipi_arg_non_ex {
u64 cpu_mask;
 };
 
+struct hv_vpset {
+   u64 format;
+   u64 valid_bank_mask;
+   u64 bank_contents[];
+};
+
+struct ipi_arg_ex {
+   u32 vector;
+   u32 reserved;
+   struct hv_vpset vp_set;
+};
+
 #endif
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 1eff91599c2b..0ee82519957b 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -259,6 +259,39 @@ static inline int hv_cpu_number_to_vp_number(int 
cpu_number)
return hv_vp_index[cpu_number];
 }
 
+static inline int cpumask_to_vpset(struct hv_vpset *vpset,
+   const struct cpumask *cpus)
+{
+   int cpu, vcpu, vcpu_ba

[PATCH V2 0/5] X86: Hyper-V: APIC enlightenments

2018-05-03 Thread kys
From: "K. Y. Srinivasan" 

Implement APIC related enlightenments.

V2: Addressed comments from Thomas Gleixner 
and Michael Kelley (EOSG) .

K. Y. Srinivasan (5):
  X86: Hyper-V: Enlighten APIC access
  X86: Hyper-V: Enable IPI enlightenments
  X86: Hyper-V: Enhanced IPI enlightenment
  X86: Hyper-V: Consolidate code for converting cpumask to vpset
  X86: Hyper-V: Consolidate the allocation of the hypercall input page

 arch/x86/hyperv/Makefile   |   2 +-
 arch/x86/hyperv/hv_apic.c  | 259 +
 arch/x86/hyperv/hv_init.c  |  32 -
 arch/x86/hyperv/mmu.c  |  75 ++-
 arch/x86/include/asm/hyperv-tlfs.h |  30 -
 arch/x86/include/asm/mshyperv.h|  39 +-
 6 files changed, 365 insertions(+), 72 deletions(-)
 create mode 100644 arch/x86/hyperv/hv_apic.c

-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/5] X86: Hyper-V: Enhanced IPI enlightenment

2018-04-25 Thread kys
From: "K. Y. Srinivasan" 

Support enhanced IPI enlightenments (to target more than 64 CPUs).

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_apic.c  | 49 --
 arch/x86/include/asm/hyperv-tlfs.h |  1 +
 arch/x86/include/asm/mshyperv.h| 39 ++
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index 7f3322ecfb01..fbb408b91e25 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -36,6 +36,12 @@ struct ipi_arg_non_ex {
u64 cpu_mask;
 };
 
+struct ipi_arg_ex {
+   u32 vector;
+   u32  reserved;
+   struct hv_vpset vp_set;
+};
+
 static struct apic orig_apic;
 
 static u64 hv_apic_icr_read(void)
@@ -97,6 +103,40 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
  * IPI implementation on Hyper-V.
  */
 
+static int __send_ipi_mask_ex(const struct cpumask *mask, int vector)
+{
+   int nr_bank = 0;
+   struct ipi_arg_ex **arg;
+   struct ipi_arg_ex *ipi_arg;
+   int ret = 1;
+   unsigned long flags;
+
+   local_irq_save(flags);
+   arg = (struct ipi_arg_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+   ipi_arg = *arg;
+   if (unlikely(!ipi_arg))
+   goto ipi_mask_ex_done;
+
+   ipi_arg->vector = vector;
+   ipi_arg->reserved = 0;
+   ipi_arg->vp_set.valid_bank_mask = 0;
+
+   if (!cpumask_equal(mask, cpu_present_mask)) {
+   ipi_arg->vp_set.format = HV_GENERIC_SET_SPARCE_4K;
+   nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
+   }
+   if (!nr_bank)
+   ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
+
+   ret = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
+ ipi_arg, NULL);
+
+ipi_mask_ex_done:
+   local_irq_restore(flags);
+   return ret;
+}
+
 static int __send_ipi_mask(const struct cpumask *mask, int vector)
 {
int cur_cpu, vcpu;
@@ -114,6 +154,9 @@ static int __send_ipi_mask(const struct cpumask *mask, int 
vector)
if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
return ret;
 
+   if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+   return __send_ipi_mask_ex(mask, vector);
+
local_irq_save(flags);
arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
 
@@ -196,8 +239,10 @@ void __init hv_apic_init(void)
if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
if (hyperv_pcpu_input_arg == NULL)
goto msr_based_access;
-
-   pr_info("Hyper-V: Using IPI hypercalls\n");
+   if ((ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
+   pr_info("Hyper-V: Using ext hypercalls for IPI\n");
+   else
+   pr_info("Hyper-V: Using IPI hypercalls\n");
/*
 * Set the IPI entry points.
 */
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 646cf2ca2aaa..53ea30d768d9 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -344,6 +344,7 @@ struct hv_tsc_emulation_status {
 #define HVCALL_SEND_IPI0x000b
 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX  0x0013
 #define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX   0x0014
+#define HVCALL_SEND_IPI_EX 0x0015
 #define HVCALL_POST_MESSAGE0x005c
 #define HVCALL_SIGNAL_EVENT0x005d
 
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index f6045f3611de..956e8603bed2 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -259,6 +259,45 @@ static inline int hv_cpu_number_to_vp_number(int 
cpu_number)
return hv_vp_index[cpu_number];
 }
 
+struct hv_vpset {
+   u64 format;
+   u64 valid_bank_mask;
+   u64 bank_contents[];
+};
+
+static inline int cpumask_to_vpset(struct hv_vpset *vpset,
+   const struct cpumask *cpus)
+{
+   int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
+
+   /* valid_bank_mask can represent up to 64 banks */
+   if (hv_max_vp_index / 64 >= 64)
+   return 0;
+
+   /*
+* Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
+* structs are not cleared between calls, we risk flushing unneeded
+* vCPUs otherwise.
+*/
+   for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
+   vpset->bank_contents[vcpu_bank] = 0;
+
+   /*
+* Some banks may end up being empty but this is acceptable.
+*/
+   for_each_cpu(cpu, cpus) {
+   vcpu = hv_cpu_number_to_vp_number(cpu);
+   vcpu_bank = vcpu / 64;
+   vcpu_offset = vcpu % 64;
+   

[PATCH 0/5] X86: Hyper-V: APIC enlightenments

2018-04-25 Thread kys
From: "K. Y. Srinivasan" 

Implement APIC related enlightenments.

K. Y. Srinivasan (5):
  X86: Hyper-V: Enlighten APIC access
  X86: Hyper-V: Enable IPI enlightenments
  X86: Hyper-V: Enhanced IPI enlightenment
  X86: Hyper-V: Consolidate code for converting cpumask to vpset
  X86: Hyper-V: Consolidate the allocation of the hypercall input page

 arch/x86/hyperv/Makefile   |   2 +-
 arch/x86/hyperv/hv_apic.c  | 268 +
 arch/x86/hyperv/hv_init.c  |  22 ++-
 arch/x86/hyperv/mmu.c  |  78 ++-
 arch/x86/include/asm/hyperv-tlfs.h |  12 +-
 arch/x86/include/asm/mshyperv.h|  47 ++-
 6 files changed, 356 insertions(+), 73 deletions(-)
 create mode 100644 arch/x86/hyperv/hv_apic.c

-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/5] X86: Hyper-V: Consolidate the allocation of the hypercall input page

2018-04-25 Thread kys
From: "K. Y. Srinivasan" 

Consolidate the allocation of the hypercall input page.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_init.c   |  2 --
 arch/x86/hyperv/mmu.c   | 33 +
 arch/x86/include/asm/mshyperv.h |  1 -
 3 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index a895662b6b4c..72befd0e2c35 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -314,8 +314,6 @@ void __init hyperv_init(void)
hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
-   hyper_alloc_mmu();
-
hv_apic_init();
 
/*
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index c9cd28f0bae4..c4466af72e77 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -32,9 +32,6 @@ struct hv_flush_pcpu_ex {
 /* Each gva in gva_list encodes up to 4096 pages to flush */
 #define HV_TLB_FLUSH_UNIT (4096 * PAGE_SIZE)
 
-static struct hv_flush_pcpu __percpu **pcpu_flush;
-
-static struct hv_flush_pcpu_ex __percpu **pcpu_flush_ex;
 
 /*
  * Fills in gva_list starting from offset. Returns the number of items added.
@@ -77,7 +74,7 @@ static void hyperv_flush_tlb_others(const struct cpumask 
*cpus,
 
trace_hyperv_mmu_flush_tlb_others(cpus, info);
 
-   if (!pcpu_flush || !hv_hypercall_pg)
+   if (!hv_hypercall_pg)
goto do_native;
 
if (cpumask_empty(cpus))
@@ -85,10 +82,8 @@ static void hyperv_flush_tlb_others(const struct cpumask 
*cpus,
 
local_irq_save(flags);
 
-   flush_pcpu = this_cpu_ptr(pcpu_flush);
-
-   if (unlikely(!*flush_pcpu))
-   *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+   flush_pcpu = (struct hv_flush_pcpu **)
+this_cpu_ptr(hyperv_pcpu_input_arg);
 
flush = *flush_pcpu;
 
@@ -164,7 +159,7 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
 
trace_hyperv_mmu_flush_tlb_others(cpus, info);
 
-   if (!pcpu_flush_ex || !hv_hypercall_pg)
+   if (!hv_hypercall_pg)
goto do_native;
 
if (cpumask_empty(cpus))
@@ -172,10 +167,8 @@ static void hyperv_flush_tlb_others_ex(const struct 
cpumask *cpus,
 
local_irq_save(flags);
 
-   flush_pcpu = this_cpu_ptr(pcpu_flush_ex);
-
-   if (unlikely(!*flush_pcpu))
-   *flush_pcpu = page_address(alloc_page(GFP_ATOMIC));
+   flush_pcpu = (struct hv_flush_pcpu_ex **)
+this_cpu_ptr(hyperv_pcpu_input_arg);
 
flush = *flush_pcpu;
 
@@ -249,6 +242,9 @@ void hyperv_setup_mmu_ops(void)
if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
return;
 
+   if (hyperv_pcpu_input_arg == NULL)
+   return;
+
if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED)) {
pr_info("Using hypercall for remote TLB flush\n");
pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others;
@@ -257,14 +253,3 @@ void hyperv_setup_mmu_ops(void)
pv_mmu_ops.flush_tlb_others = hyperv_flush_tlb_others_ex;
}
 }
-
-void hyper_alloc_mmu(void)
-{
-   if (!(ms_hyperv.hints & HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED))
-   return;
-
-   if (!(ms_hyperv.hints & HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED))
-   pcpu_flush = alloc_percpu(struct hv_flush_pcpu *);
-   else
-   pcpu_flush_ex = alloc_percpu(struct hv_flush_pcpu_ex *);
-}
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 956e8603bed2..9931f9908fe2 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -300,7 +300,6 @@ static inline int cpumask_to_vpset(struct hv_vpset *vpset,
 
 void __init hyperv_init(void);
 void hyperv_setup_mmu_ops(void);
-void hyper_alloc_mmu(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
 bool hv_is_hyperv_initialized(void);
 void hyperv_cleanup(void);
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/5] X86: Hyper-V: Consolidate code for converting cpumask to vpset

2018-04-25 Thread kys
From: "K. Y. Srinivasan" 

Consolidate code for converting cpumask to vpset.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_apic.c  |  2 +-
 arch/x86/hyperv/mmu.c  | 45 +++---
 arch/x86/include/asm/hyperv-tlfs.h |  2 +-
 3 files changed, 5 insertions(+), 44 deletions(-)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index fbb408b91e25..508889c8499e 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -123,7 +123,7 @@ static int __send_ipi_mask_ex(const struct cpumask *mask, 
int vector)
ipi_arg->vp_set.valid_bank_mask = 0;
 
if (!cpumask_equal(mask, cpu_present_mask)) {
-   ipi_arg->vp_set.format = HV_GENERIC_SET_SPARCE_4K;
+   ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
}
if (!nr_bank)
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c
index 56c9ebac946f..c9cd28f0bae4 100644
--- a/arch/x86/hyperv/mmu.c
+++ b/arch/x86/hyperv/mmu.c
@@ -25,11 +25,7 @@ struct hv_flush_pcpu {
 struct hv_flush_pcpu_ex {
u64 address_space;
u64 flags;
-   struct {
-   u64 format;
-   u64 valid_bank_mask;
-   u64 bank_contents[];
-   } hv_vp_set;
+   struct hv_vpset hv_vp_set;
u64 gva_list[];
 };
 
@@ -70,41 +66,6 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
return gva_n - offset;
 }
 
-/* Return the number of banks in the resulting vp_set */
-static inline int cpumask_to_vp_set(struct hv_flush_pcpu_ex *flush,
-   const struct cpumask *cpus)
-{
-   int cpu, vcpu, vcpu_bank, vcpu_offset, nr_bank = 1;
-
-   /* valid_bank_mask can represent up to 64 banks */
-   if (hv_max_vp_index / 64 >= 64)
-   return 0;
-
-   /*
-* Clear all banks up to the maximum possible bank as hv_flush_pcpu_ex
-* structs are not cleared between calls, we risk flushing unneeded
-* vCPUs otherwise.
-*/
-   for (vcpu_bank = 0; vcpu_bank <= hv_max_vp_index / 64; vcpu_bank++)
-   flush->hv_vp_set.bank_contents[vcpu_bank] = 0;
-
-   /*
-* Some banks may end up being empty but this is acceptable.
-*/
-   for_each_cpu(cpu, cpus) {
-   vcpu = hv_cpu_number_to_vp_number(cpu);
-   vcpu_bank = vcpu / 64;
-   vcpu_offset = vcpu % 64;
-   __set_bit(vcpu_offset, (unsigned long *)
- &flush->hv_vp_set.bank_contents[vcpu_bank]);
-   if (vcpu_bank >= nr_bank)
-   nr_bank = vcpu_bank + 1;
-   }
-   flush->hv_vp_set.valid_bank_mask = GENMASK_ULL(nr_bank - 1, 0);
-
-   return nr_bank;
-}
-
 static void hyperv_flush_tlb_others(const struct cpumask *cpus,
const struct flush_tlb_info *info)
 {
@@ -239,8 +200,8 @@ static void hyperv_flush_tlb_others_ex(const struct cpumask 
*cpus,
flush->hv_vp_set.valid_bank_mask = 0;
 
if (!cpumask_equal(cpus, cpu_present_mask)) {
-   flush->hv_vp_set.format = HV_GENERIC_SET_SPARCE_4K;
-   nr_bank = cpumask_to_vp_set(flush, cpus);
+   flush->hv_vp_set.format = HV_GENERIC_SET_SPARSE_4K;
+   nr_bank = cpumask_to_vpset(&(flush->hv_vp_set), cpus);
}
 
if (!nr_bank) {
diff --git a/arch/x86/include/asm/hyperv-tlfs.h 
b/arch/x86/include/asm/hyperv-tlfs.h
index 53ea30d768d9..b32b87945538 100644
--- a/arch/x86/include/asm/hyperv-tlfs.h
+++ b/arch/x86/include/asm/hyperv-tlfs.h
@@ -370,7 +370,7 @@ struct hv_tsc_emulation_status {
 #define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT BIT(3)
 
 enum HV_GENERIC_SET_FORMAT {
-   HV_GENERIC_SET_SPARCE_4K,
+   HV_GENERIC_SET_SPARSE_4K,
HV_GENERIC_SET_ALL,
 };
 
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/5] X86: Hyper-V: Enable IPI enlightenments

2018-04-25 Thread kys
From: "K. Y. Srinivasan" 

Hyper-V supports hypercalls to implement IPI; use them.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/hv_apic.c  | 125 +
 arch/x86/hyperv/hv_init.c  |  17 +
 arch/x86/include/asm/hyperv-tlfs.h |   9 +++
 arch/x86/include/asm/mshyperv.h|   1 +
 4 files changed, 152 insertions(+)

diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
index e0a5b36208fc..7f3322ecfb01 100644
--- a/arch/x86/hyperv/hv_apic.c
+++ b/arch/x86/hyperv/hv_apic.c
@@ -30,6 +30,14 @@
 #include 
 #include 
 
+struct ipi_arg_non_ex {
+   u32 vector;
+   u32 reserved;
+   u64 cpu_mask;
+};
+
+static struct apic orig_apic;
+
 static u64 hv_apic_icr_read(void)
 {
u64 reg_val;
@@ -85,8 +93,125 @@ static void hv_apic_eoi_write(u32 reg, u32 val)
wrmsr(HV_X64_MSR_EOI, val, 0);
 }
 
+/*
+ * IPI implementation on Hyper-V.
+ */
+
+static int __send_ipi_mask(const struct cpumask *mask, int vector)
+{
+   int cur_cpu, vcpu;
+   struct ipi_arg_non_ex **arg;
+   struct ipi_arg_non_ex *ipi_arg;
+   int ret = 1;
+   unsigned long flags;
+
+   if (cpumask_empty(mask))
+   return 0;
+
+   if (!hv_hypercall_pg)
+   return ret;
+
+   if ((vector < HV_IPI_LOW_VECTOR) || (vector > HV_IPI_HIGH_VECTOR))
+   return ret;
+
+   local_irq_save(flags);
+   arg = (struct ipi_arg_non_ex **)this_cpu_ptr(hyperv_pcpu_input_arg);
+
+   ipi_arg = *arg;
+   if (unlikely(!ipi_arg))
+   goto ipi_mask_done;
+
+
+   ipi_arg->vector = vector;
+   ipi_arg->reserved = 0;
+   ipi_arg->cpu_mask = 0;
+
+   for_each_cpu(cur_cpu, mask) {
+   vcpu = hv_cpu_number_to_vp_number(cur_cpu);
+   if (vcpu >= 64)
+   goto ipi_mask_done;
+
+   __set_bit(vcpu, (unsigned long *)&ipi_arg->cpu_mask);
+   }
+
+   ret = hv_do_hypercall(HVCALL_SEND_IPI, ipi_arg, NULL);
+
+ipi_mask_done:
+   local_irq_restore(flags);
+   return ret;
+}
+
+static int __send_ipi_one(int cpu, int vector)
+{
+   struct cpumask mask = CPU_MASK_NONE;
+
+   cpumask_set_cpu(cpu, &mask);
+   return __send_ipi_mask(&mask, vector);
+}
+
+static void hv_send_ipi(int cpu, int vector)
+{
+   if (__send_ipi_one(cpu, vector))
+   orig_apic.send_IPI(cpu, vector);
+}
+
+static void hv_send_ipi_mask(const struct cpumask *mask, int vector)
+{
+   if (__send_ipi_mask(mask, vector))
+   orig_apic.send_IPI_mask(mask, vector);
+}
+
+static void hv_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
+{
+   unsigned int this_cpu = smp_processor_id();
+   struct cpumask new_mask;
+   const struct cpumask *local_mask;
+
+   cpumask_copy(&new_mask, mask);
+   cpumask_clear_cpu(this_cpu, &new_mask);
+   local_mask = &new_mask;
+   if (__send_ipi_mask(local_mask, vector))
+   orig_apic.send_IPI_mask_allbutself(mask, vector);
+}
+
+static void hv_send_ipi_allbutself(int vector)
+{
+   hv_send_ipi_mask_allbutself(cpu_online_mask, vector);
+}
+
+static void hv_send_ipi_all(int vector)
+{
+   if (__send_ipi_mask(cpu_online_mask, vector))
+   orig_apic.send_IPI_all(vector);
+}
+
+static void hv_send_ipi_self(int vector)
+{
+   if (__send_ipi_one(smp_processor_id(), vector))
+   orig_apic.send_IPI_self(vector);
+}
+
 void __init hv_apic_init(void)
 {
+   if (ms_hyperv.hints & HV_X64_CLUSTER_IPI_RECOMMENDED) {
+   if (hyperv_pcpu_input_arg == NULL)
+   goto msr_based_access;
+
+   pr_info("Hyper-V: Using IPI hypercalls\n");
+   /*
+* Set the IPI entry points.
+*/
+   orig_apic = *apic;
+
+   apic->send_IPI = hv_send_ipi;
+   apic->send_IPI_mask = hv_send_ipi_mask;
+   apic->send_IPI_mask_allbutself = hv_send_ipi_mask_allbutself;
+   apic->send_IPI_allbutself = hv_send_ipi_allbutself;
+   apic->send_IPI_all = hv_send_ipi_all;
+   apic->send_IPI_self = hv_send_ipi_self;
+   }
+
+msr_based_access:
if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
pr_info("Hyper-V: Using MSR ased APIC access\n");
apic_set_eoi_write(hv_apic_eoi_write);
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index 71e50fc2b7ef..a895662b6b4c 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -91,12 +91,19 @@ EXPORT_SYMBOL_GPL(hv_vp_index);
 struct hv_vp_assist_page **hv_vp_assist_page;
 EXPORT_SYMBOL_GPL(hv_vp_assist_page);
 
+void  __percpu **hyperv_pcpu_input_arg;
+EXPORT_SYMBOL_GPL(hyperv_pcpu_input_arg);
+
 u32 hv_max_vp_index;
 
 static int hv_cpu_init(unsigned int cpu)
 {
u64 msr_vp_index;
struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()];

[PATCH 1/5] X86: Hyper-V: Enlighten APIC access

2018-04-25 Thread kys
From: "K. Y. Srinivasan" 

Hyper-V supports MSR based APIC access; implement
the enlightenment.

Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/hyperv/Makefile|  2 +-
 arch/x86/hyperv/hv_apic.c   | 98 +
 arch/x86/hyperv/hv_init.c   |  5 ++-
 arch/x86/include/asm/mshyperv.h |  6 ++-
 4 files changed, 107 insertions(+), 4 deletions(-)
 create mode 100644 arch/x86/hyperv/hv_apic.c

diff --git a/arch/x86/hyperv/Makefile b/arch/x86/hyperv/Makefile
index 367a8203cfcf..00ce4df01a09 100644
--- a/arch/x86/hyperv/Makefile
+++ b/arch/x86/hyperv/Makefile
@@ -1 +1 @@
-obj-y  := hv_init.o mmu.o
+obj-y  := hv_init.o mmu.o hv_apic.o
diff --git a/arch/x86/hyperv/hv_apic.c b/arch/x86/hyperv/hv_apic.c
new file mode 100644
index ..e0a5b36208fc
--- /dev/null
+++ b/arch/x86/hyperv/hv_apic.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Hyper-V specific APIC code.
+ *
+ * Copyright (C) 2018, Microsoft, Inc.
+ *
+ * Author : K. Y. Srinivasan 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static u64 hv_apic_icr_read(void)
+{
+   u64 reg_val;
+
+   rdmsrl(HV_X64_MSR_ICR, reg_val);
+   return reg_val;
+}
+
+static void hv_apic_icr_write(u32 low, u32 id)
+{
+   u64 reg_val;
+
+   reg_val = SET_APIC_DEST_FIELD(id);
+   reg_val = reg_val << 32;
+   reg_val |= low;
+
+   wrmsrl(HV_X64_MSR_ICR, reg_val);
+}
+
+static u32 hv_apic_read(u32 reg)
+{
+   u32 reg_val, hi;
+
+   switch (reg) {
+   case APIC_EOI:
+   rdmsr(HV_X64_MSR_EOI, reg_val, hi);
+   return reg_val;
+   case APIC_TASKPRI:
+   rdmsr(HV_X64_MSR_TPR, reg_val, hi);
+   return reg_val;
+
+   default:
+   return native_apic_mem_read(reg);
+   }
+}
+
+static void hv_apic_write(u32 reg, u32 val)
+{
+   switch (reg) {
+   case APIC_EOI:
+   wrmsr(HV_X64_MSR_EOI, val, 0);
+   break;
+   case APIC_TASKPRI:
+   wrmsr(HV_X64_MSR_TPR, val, 0);
+   break;
+   default:
+   native_apic_mem_write(reg, val);
+   }
+}
+
+static void hv_apic_eoi_write(u32 reg, u32 val)
+{
+   wrmsr(HV_X64_MSR_EOI, val, 0);
+}
+
+void __init hv_apic_init(void)
+{
+   if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) {
+   pr_info("Hyper-V: Using MSR ased APIC access\n");
+   apic_set_eoi_write(hv_apic_eoi_write);
+   apic->read  = hv_apic_read;
+   apic->write = hv_apic_write;
+   apic->icr_write = hv_apic_icr_write;
+   apic->icr_read  = hv_apic_icr_read;
+   }
+}
diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
index cfecc2272f2d..71e50fc2b7ef 100644
--- a/arch/x86/hyperv/hv_init.c
+++ b/arch/x86/hyperv/hv_init.c
@@ -242,8 +242,9 @@ static int hv_cpu_die(unsigned int cpu)
  *
  * 1. Setup the hypercall page.
  * 2. Register Hyper-V specific clocksource.
+ * 3. Setup Hyper-V specific APIC entry points.
  */
-void hyperv_init(void)
+void __init hyperv_init(void)
 {
u64 guest_id, required_msrs;
union hv_x64_msr_hypercall_contents hypercall_msr;
@@ -298,6 +299,8 @@ void hyperv_init(void)
 
hyper_alloc_mmu();
 
+   hv_apic_init();
+
/*
 * Register Hyper-V specific clocksource.
 */
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index b90e79610cf7..bcced50037c1 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -258,7 +258,7 @@ static inline int hv_cpu_number_to_vp_number(int cpu_number)
return hv_vp_index[cpu_number];
 }
 
-void hyperv_init(void);
+void __init hyperv_init(void);
 void hyperv_setup_mmu_ops(void);
 void hyper_alloc_mmu(void);
 void hyperv_report_panic(struct pt_regs *regs, long err);
@@ -269,14 +269,16 @@ void hyperv_reenlightenment_intr(struct pt_regs *regs);
 void set_hv_tscchange_cb(void (*cb)(void));
 void clear_hv_tscchange_cb(void);
 void hyperv_stop_tsc_emulation(void);
+void hv_apic_init(void);
 #else /* CONFIG_HYPERV */
-static inline void hyperv_init(void) {}
+static __init  inline void hyperv_init(void) {}
 static inline bool hv_is_hyperv_initialized(void) { return false; }
 static inline void hyperv_cleanup(void) {}
 static inline void hyperv_setup_mmu_ops(void) {}
 static inline void set_hv_tscchange_cb(void

[PATCH 3/4] hv: add SPDX license to trace

2018-03-27 Thread kys
From: Stephen Hemminger 

Missing license on Hyper-V VMBUS tracing files.

Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_trace.c | 2 ++
 drivers/hv/hv_trace.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/hv/hv_trace.c b/drivers/hv/hv_trace.c
index df47acd01a81..38d359cf1e70 100644
--- a/drivers/hv/hv_trace.c
+++ b/drivers/hv/hv_trace.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
+
 #include "hyperv_vmbus.h"
 
 #define CREATE_TRACE_POINTS
diff --git a/drivers/hv/hv_trace.h b/drivers/hv/hv_trace.h
index d635ee95b20d..999f80a63bff 100644
--- a/drivers/hv/hv_trace.h
+++ b/drivers/hv/hv_trace.h
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
+
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM hyperv
 
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/4] Drivers: hv: vmbus: respect what we get from hv_get_synint_state()

2018-03-27 Thread kys
From: Dexuan Cui 

I didn't really hit a bug, but just happened to notice the redundant line.

Signed-off-by: Dexuan Cui 
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index b1f6793acf4c..8137b3885b99 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -302,7 +302,6 @@ int hv_synic_init(unsigned int cpu)
hv_get_synint_state(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT,
shared_sint.as_uint64);
 
-   shared_sint.as_uint64 = 0;
shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
shared_sint.masked = false;
if (ms_hyperv.hints & HV_X64_DEPRECATING_AEOI_RECOMMENDED)
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/4] hv: add SPDX license id to Kconfig

2018-03-27 Thread kys
From: Stephen Hemminger 

Missing license on Kconfig file.

Signed-off-by: Stephen Hemminger 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 50b89ea0e60f..97954f575c3f 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
 menu "Microsoft Hyper-V guest support"
 
 config HYPERV
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/4] Drivers: hv: vmbus: do not mark HV_PCIE as perf_device

2018-03-27 Thread kys
From: Dexuan Cui 

The pci-hyperv driver's channel callback hv_pci_onchannelcallback() is not
really a hot path, so we don't need to mark it as a perf_device, meaning
with this patch all HV_PCIE channels' target_cpu will be CPU0.

Signed-off-by: Dexuan Cui 
Cc: sta...@vger.kernel.org
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel_mgmt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index c6d9d19bc04e..ecc2bd275a73 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -71,7 +71,7 @@ static const struct vmbus_device vmbus_devs[] = {
/* PCIE */
{ .dev_type = HV_PCIE,
  HV_PCIE_GUID,
- .perf_device = true,
+ .perf_device = false,
},
 
/* Synthetic Frame Buffer */
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/4] Drivers: hv: vmbus: Miscellaneous fixes

2018-03-27 Thread kys
From: "K. Y. Srinivasan" 

Some miscellaneous fixes and adjustments.

Dexuan Cui (2):
  Drivers: hv: vmbus: respect what we get from hv_get_synint_state()
  Drivers: hv: vmbus: do not mark HV_PCIE as perf_device

Stephen Hemminger (2):
  hv: add SPDX license to trace
  hv: add SPDX license id to Kconfig

 drivers/hv/Kconfig| 2 ++
 drivers/hv/channel_mgmt.c | 2 +-
 drivers/hv/hv.c   | 1 -
 drivers/hv/hv_trace.c | 2 ++
 drivers/hv/hv_trace.h | 2 ++
 5 files changed, 7 insertions(+), 2 deletions(-)

-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/1] Drivers: hv: vmbus: Fix ring buffer signaling

2018-03-04 Thread kys
From: Michael Kelley 

Fix bugs in signaling the Hyper-V host when freeing space in the
host->guest ring buffer:

1. The interrupt_mask must not be used to determine whether to signal
   on the host->guest ring buffer
2. The ring buffer write_index must be read (via hv_get_bytes_to_write)
   *after* pending_send_sz is read in order to avoid a race condition
3. Comparisons with pending_send_sz must treat the "equals" case as
   not-enough-space
4. Don't signal if the pending_send_sz feature is not present. Older
   versions of Hyper-V that don't implement this feature will poll.

Fixes: 03bad714a161 ("vmbus: more host signalling avoidance")

Cc: Stable  # 4.14 and above
Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c | 52 
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 1aa17795727b..3cd7f29906ae 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -376,13 +376,24 @@ __hv_pkt_iter_next(struct vmbus_channel *channel,
 }
 EXPORT_SYMBOL_GPL(__hv_pkt_iter_next);
 
+/* How many bytes were read in this iterator cycle */
+static u32 hv_pkt_iter_bytes_read(const struct hv_ring_buffer_info *rbi,
+   u32 start_read_index)
+{
+   if (rbi->priv_read_index >= start_read_index)
+   return rbi->priv_read_index - start_read_index;
+   else
+   return rbi->ring_datasize - start_read_index +
+   rbi->priv_read_index;
+}
+
 /*
  * Update host ring buffer after iterating over packets.
  */
 void hv_pkt_iter_close(struct vmbus_channel *channel)
 {
struct hv_ring_buffer_info *rbi = &channel->inbound;
-   u32 orig_write_sz = hv_get_bytes_to_write(rbi);
+   u32 curr_write_sz, pending_sz, bytes_read, start_read_index;
 
/*
 * Make sure all reads are done before we update the read index since
@@ -390,8 +401,12 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
 * is updated.
 */
virt_rmb();
+   start_read_index = rbi->ring_buffer->read_index;
rbi->ring_buffer->read_index = rbi->priv_read_index;
 
+   if (!rbi->ring_buffer->feature_bits.feat_pending_send_sz)
+   return;
+
/*
 * Issue a full memory barrier before making the signaling decision.
 * Here is the reason for having this barrier:
@@ -405,26 +420,29 @@ void hv_pkt_iter_close(struct vmbus_channel *channel)
 */
virt_mb();
 
-   /* If host has disabled notifications then skip */
-   if (rbi->ring_buffer->interrupt_mask)
+   pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+   if (!pending_sz)
return;
 
-   if (rbi->ring_buffer->feature_bits.feat_pending_send_sz) {
-   u32 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
+   /*
+* Ensure the read of write_index in hv_get_bytes_to_write()
+* happens after the read of pending_send_sz.
+*/
+   virt_rmb();
+   curr_write_sz = hv_get_bytes_to_write(rbi);
+   bytes_read = hv_pkt_iter_bytes_read(rbi, start_read_index);
 
-   /*
-* If there was space before we began iteration,
-* then host was not blocked. Also handles case where
-* pending_sz is zero then host has nothing pending
-* and does not need to be signaled.
-*/
-   if (orig_write_sz > pending_sz)
-   return;
+   /*
+* If there was space before we began iteration,
+* then host was not blocked.
+*/
 
-   /* If pending write will not fit, don't give false hope. */
-   if (hv_get_bytes_to_write(rbi) < pending_sz)
-   return;
-   }
+   if (curr_write_sz - bytes_read > pending_sz)
+   return;
+
+   /* If pending write will not fit, don't give false hope. */
+   if (curr_write_sz <= pending_sz)
+   return;
 
vmbus_setevent(channel);
 }
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 08/12] Drivers: hv: vmbus: Implement Direct Mode for stimer0

2018-03-04 Thread kys
From: Michael Kelley 

The 2016 version of Hyper-V offers the option to operate the guest VM
per-vcpu stimer's in Direct Mode, which means the timer interupts on its
own vector rather than queueing a VMbus message. Direct Mode reduces
timer processing overhead in both the hypervisor and the guest, and
avoids having timer interrupts pollute the VMbus interrupt stream for
the synthetic NIC and storage.  This patch enables Direct Mode by
default on stimer0 when running on a version of Hyper-V that supports
it.

In prep for coming support of Hyper-V on ARM64, the arch independent
portion of the code contains calls to routines that will be populated
on ARM64 but are not needed and do nothing on x86.

Signed-off-by: Michael Kelley 
Signed-off-by: K. Y. Srinivasan 
---
 arch/x86/entry/entry_32.S  |  3 ++
 arch/x86/entry/entry_64.S  |  3 ++
 arch/x86/include/asm/hardirq.h |  1 +
 arch/x86/include/asm/irq_vectors.h |  3 +-
 arch/x86/include/asm/mshyperv.h| 13 +
 arch/x86/include/uapi/asm/hyperv.h |  3 ++
 arch/x86/kernel/cpu/mshyperv.c | 40 ++
 arch/x86/kernel/irq.c  |  7 +
 drivers/hv/hv.c| 59 --
 drivers/hv/hyperv_vmbus.h  |  4 ++-
 10 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index 16c2c022540d..e12d60873376 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -903,6 +903,9 @@ BUILD_INTERRUPT3(hyperv_callback_vector, 
HYPERVISOR_CALLBACK_VECTOR,
 BUILD_INTERRUPT3(hyperv_reenlightenment_vector, HYPERV_REENLIGHTENMENT_VECTOR,
 hyperv_reenlightenment_intr)
 
+BUILD_INTERRUPT3(hv_stimer0_callback_vector, HYPERV_STIMER0_VECTOR,
+hv_stimer0_vector_handler)
+
 #endif /* CONFIG_HYPERV */
 
 ENTRY(page_fault)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 8971bd64d515..606118459133 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1106,6 +1106,9 @@ apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
 
 apicinterrupt3 HYPERV_REENLIGHTENMENT_VECTOR \
hyperv_reenlightenment_vector hyperv_reenlightenment_intr
+
+apicinterrupt3 HYPERV_STIMER0_VECTOR \
+   hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=DEBUG_STACK
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 7c341a74ec8c..5ea2afd4c871 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -40,6 +40,7 @@ typedef struct {
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
unsigned int irq_hv_reenlightenment_count;
+   unsigned int hyperv_stimer0_count;
 #endif
 } cacheline_aligned irq_cpustat_t;
 
diff --git a/arch/x86/include/asm/irq_vectors.h 
b/arch/x86/include/asm/irq_vectors.h
index e71c1120426b..404c5fdff859 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -106,9 +106,10 @@
 
 #if IS_ENABLED(CONFIG_HYPERV)
 #define HYPERV_REENLIGHTENMENT_VECTOR  0xee
+#define HYPERV_STIMER0_VECTOR  0xed
 #endif
 
-#define LOCAL_TIMER_VECTOR 0xed
+#define LOCAL_TIMER_VECTOR 0xec
 
 #define NR_VECTORS  256
 
diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index 25283f7eb299..e73c4d0c06ad 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -173,6 +173,19 @@ void hv_remove_kexec_handler(void);
 void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
 void hv_remove_crash_handler(void);
 
+/*
+ * Routines for stimer0 Direct Mode handling.
+ * On x86/x64, there are no percpu actions to take.
+ */
+void hv_stimer0_vector_handler(struct pt_regs *regs);
+void hv_stimer0_callback_vector(void);
+int hv_setup_stimer0_irq(int *irq, int *vector, void (*handler)(void));
+void hv_remove_stimer0_irq(int irq);
+
+static inline void hv_enable_stimer0_percpu_irq(int irq) {}
+static inline void hv_disable_stimer0_percpu_irq(int irq) {}
+
+
 #if IS_ENABLED(CONFIG_HYPERV)
 extern struct clocksource *hyperv_cs;
 extern void *hv_hypercall_pg;
diff --git a/arch/x86/include/uapi/asm/hyperv.h 
b/arch/x86/include/uapi/asm/hyperv.h
index 099414345865..6c0c3a3b631c 100644
--- a/arch/x86/include/uapi/asm/hyperv.h
+++ b/arch/x86/include/uapi/asm/hyperv.h
@@ -77,6 +77,9 @@
 /* Crash MSR available */
 #define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
 
+/* stimer Direct Mode is available */
+#define HV_X64_STIMER_DIRECT_MODE_AVAILABLE(1 << 19)
+
 /*
  * Feature identification: EBX indicates which flags were specified at
  * partition creation. The format is the same as the partition creation
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 9340f41ce8d3..4488cf0dd499 100644
--- a/arch/x86/ker

[PATCH V2 10/12] hv_balloon: simplify hv_online_page()/hv_page_online_one()

2018-03-04 Thread kys
From: Vitaly Kuznetsov 

Instead of doing pfn_to_page() and continuosly casting page to unsigned
long just cache the pfn of the page with page_to_pfn().

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_balloon.c | 27 +--
 1 file changed, 5 insertions(+), 22 deletions(-)

diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 1aece72da9ba..5b8e1ad1bcfe 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -612,28 +612,17 @@ static struct notifier_block hv_memory_nb = {
 /* Check if the particular page is backed and can be onlined and online it. */
 static void hv_page_online_one(struct hv_hotadd_state *has, struct page *pg)
 {
-   unsigned long cur_start_pgp;
-   unsigned long cur_end_pgp;
struct hv_hotadd_gap *gap;
-
-   cur_start_pgp = (unsigned long)pfn_to_page(has->covered_start_pfn);
-   cur_end_pgp = (unsigned long)pfn_to_page(has->covered_end_pfn);
+   unsigned long pfn = page_to_pfn(pg);
 
/* The page is not backed. */
-   if (((unsigned long)pg < cur_start_pgp) ||
-   ((unsigned long)pg >= cur_end_pgp))
+   if ((pfn < has->covered_start_pfn) || (pfn >= has->covered_end_pfn))
return;
 
/* Check for gaps. */
list_for_each_entry(gap, &has->gap_list, list) {
-   cur_start_pgp = (unsigned long)
-   pfn_to_page(gap->start_pfn);
-   cur_end_pgp = (unsigned long)
-   pfn_to_page(gap->end_pfn);
-   if (((unsigned long)pg >= cur_start_pgp) &&
-   ((unsigned long)pg < cur_end_pgp)) {
+   if ((pfn >= gap->start_pfn) && (pfn < gap->end_pfn))
return;
-   }
}
 
/* This frame is currently backed; online the page. */
@@ -726,19 +715,13 @@ static void hv_mem_hot_add(unsigned long start, unsigned 
long size,
 static void hv_online_page(struct page *pg)
 {
struct hv_hotadd_state *has;
-   unsigned long cur_start_pgp;
-   unsigned long cur_end_pgp;
unsigned long flags;
+   unsigned long pfn = page_to_pfn(pg);
 
spin_lock_irqsave(&dm_device.ha_lock, flags);
list_for_each_entry(has, &dm_device.ha_region_list, list) {
-   cur_start_pgp = (unsigned long)
-   pfn_to_page(has->start_pfn);
-   cur_end_pgp = (unsigned long)pfn_to_page(has->end_pfn);
-
/* The page belongs to a different HAS. */
-   if (((unsigned long)pg < cur_start_pgp) ||
-   ((unsigned long)pg >= cur_end_pgp))
+   if ((pfn < has->start_pfn) || (pfn >= has->end_pfn))
continue;
 
hv_page_online_one(has, pg);
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 05/12] tools: hv: include string.h in hv_fcopy_daemon

2018-03-04 Thread kys
From: Olaf Hering 

The usage of strchr requires inclusion of string.h.

Fixes: 0c38cda64aec ("tools: hv: remove unnecessary header files and netlink 
related code")
Signed-off-by: Olaf Hering 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/hv_fcopy_daemon.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index 785f4e95148c..d78aed86af09 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 06/12] vmbus/ring_buffer: remove some redundant helper function.

2018-03-04 Thread kys
From: "lantianyu1...@gmail.com" 

Some hv_get/set** helper functions in ring_buffer code are
only called once or not used. This patch is to clear up these codes.

Signed-off-by: Tianyu Lan 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/ring_buffer.c | 49 
 1 file changed, 4 insertions(+), 45 deletions(-)

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 50e071444a5c..1aa17795727b 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -78,46 +78,6 @@ static void hv_signal_on_write(u32 old_write, struct 
vmbus_channel *channel)
vmbus_setevent(channel);
 }
 
-/* Get the next write location for the specified ring buffer. */
-static inline u32
-hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
-{
-   u32 next = ring_info->ring_buffer->write_index;
-
-   return next;
-}
-
-/* Set the next write location for the specified ring buffer. */
-static inline void
-hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
-u32 next_write_location)
-{
-   ring_info->ring_buffer->write_index = next_write_location;
-}
-
-/* Set the next read location for the specified ring buffer. */
-static inline void
-hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
-   u32 next_read_location)
-{
-   ring_info->ring_buffer->read_index = next_read_location;
-   ring_info->priv_read_index = next_read_location;
-}
-
-/* Get the size of the ring buffer. */
-static inline u32
-hv_get_ring_buffersize(const struct hv_ring_buffer_info *ring_info)
-{
-   return ring_info->ring_datasize;
-}
-
-/* Get the read and write indices as u64 of the specified ring buffer. */
-static inline u64
-hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
-{
-   return (u64)ring_info->ring_buffer->write_index << 32;
-}
-
 /*
  * Helper routine to copy from source to ring buffer.
  * Assume there is enough room. Handles wrap-around in dest case only!!
@@ -129,7 +89,7 @@ static u32 hv_copyto_ringbuffer(
u32 srclen)
 {
void *ring_buffer = hv_get_ring_buffer(ring_info);
-   u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
+   u32 ring_buffer_size = ring_info->ring_datasize;
 
memcpy(ring_buffer + start_write_offset, src, srclen);
 
@@ -275,8 +235,7 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
}
 
/* Write to the ring buffer */
-   next_write_location = hv_get_next_write_location(outring_info);
-
+   next_write_location = outring_info->ring_buffer->write_index;
old_write = next_write_location;
 
for (i = 0; i < kv_count; i++) {
@@ -287,7 +246,7 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
}
 
/* Set previous packet start */
-   prev_indices = hv_get_ring_bufferindices(outring_info);
+   prev_indices = (u64)outring_info->ring_buffer->write_index << 32;
 
next_write_location = hv_copyto_ringbuffer(outring_info,
 next_write_location,
@@ -298,7 +257,7 @@ int hv_ringbuffer_write(struct vmbus_channel *channel,
virt_mb();
 
/* Now, update the write location */
-   hv_set_next_write_location(outring_info, next_write_location);
+   outring_info->ring_buffer->write_index = next_write_location;
 
 
spin_unlock_irqrestore(&outring_info->ring_lock, flags);
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 12/12] hv_balloon: trace post_status

2018-03-04 Thread kys
From: Vitaly Kuznetsov 

Hyper-V balloon driver makes non-trivial calculations to convert Linux's
representation of free/used memory to what Hyper-V host expects to see. Add
a tracepoint to see what's being sent and where the data comes from.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/Makefile   |  1 +
 drivers/hv/hv_balloon.c   |  6 ++
 drivers/hv/hv_trace_balloon.h | 48 +++
 3 files changed, 55 insertions(+)
 create mode 100644 drivers/hv/hv_trace_balloon.h

diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile
index 14c22786b519..a1eec7177c2d 100644
--- a/drivers/hv/Makefile
+++ b/drivers/hv/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_HYPERV_UTILS)  += hv_utils.o
 obj-$(CONFIG_HYPERV_BALLOON)   += hv_balloon.o
 
 CFLAGS_hv_trace.o = -I$(src)
+CFLAGS_hv_balloon.o = -I$(src)
 
 hv_vmbus-y := vmbus_drv.o \
 hv.o connection.o channel.o \
diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 7514a32d0de4..b3e9f13f8bc3 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -34,6 +34,9 @@
 
 #include 
 
+#define CREATE_TRACE_POINTS
+#include "hv_trace_balloon.h"
+
 /*
  * We begin with definitions supporting the Dynamic Memory protocol
  * with the host.
@@ -1159,6 +1162,9 @@ static void post_status(struct hv_dynmem_device *dm)
 dm->num_pages_added - dm->num_pages_onlined : 0) +
compute_balloon_floor();
 
+   trace_balloon_status(status.num_avail, status.num_committed,
+vm_memory_committed(), dm->num_pages_ballooned,
+dm->num_pages_added, dm->num_pages_onlined);
/*
 * If our transaction ID is no longer current, just don't
 * send the status. This can happen if we were interrupted
diff --git a/drivers/hv/hv_trace_balloon.h b/drivers/hv/hv_trace_balloon.h
new file mode 100644
index ..93082888aec3
--- /dev/null
+++ b/drivers/hv/hv_trace_balloon.h
@@ -0,0 +1,48 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM hyperv
+
+#if !defined(_HV_TRACE_BALLOON_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _HV_TRACE_BALLOON_H
+
+#include 
+
+TRACE_EVENT(balloon_status,
+   TP_PROTO(u64 available, u64 committed,
+unsigned long vm_memory_committed,
+unsigned long pages_ballooned,
+unsigned long pages_added,
+unsigned long pages_onlined),
+   TP_ARGS(available, committed, vm_memory_committed,
+   pages_ballooned, pages_added, pages_onlined),
+   TP_STRUCT__entry(
+   __field(u64, available)
+   __field(u64, committed)
+   __field(unsigned long, vm_memory_committed)
+   __field(unsigned long, pages_ballooned)
+   __field(unsigned long, pages_added)
+   __field(unsigned long, pages_onlined)
+   ),
+   TP_fast_assign(
+   __entry->available = available;
+   __entry->committed = committed;
+   __entry->vm_memory_committed = vm_memory_committed;
+   __entry->pages_ballooned = pages_ballooned;
+   __entry->pages_added = pages_added;
+   __entry->pages_onlined = pages_onlined;
+   ),
+   TP_printk("available %lld, committed %lld; vm_memory_committed %ld;"
+ " pages_ballooned %ld, pages_added %ld, pages_onlined 
%ld",
+ __entry->available, __entry->committed,
+ __entry->vm_memory_committed, __entry->pages_ballooned,
+ __entry->pages_added, __entry->pages_onlined
+   )
+   );
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE hv_trace_balloon
+#endif /* _HV_TRACE_BALLOON_H */
+
+/* This part must be outside protection */
+#include 
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 03/12] hv: Synthetic typo correction

2018-03-04 Thread kys
From: Joe Perches 

Just a trivial tyop fix.

Signed-off-by: Joe Perches 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index b6cacc4cccf2..31142b72f1b9 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -217,7 +217,7 @@ void hv_synic_free(void)
 }
 
 /*
- * hv_synic_init - Initialize the Synthethic Interrupt Controller.
+ * hv_synic_init - Initialize the Synthetic Interrupt Controller.
  *
  * If it is already initialized by another entity (ie x2v shim), we need to
  * retrieve the initialized message and event pages.  Otherwise, we create and
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 04/12] tools: hv: fix compiler warnings about major/target_fname

2018-03-04 Thread kys
From: Dexuan Cui 

This patch fixes the below warnings with new glibc and gcc:

hv_vss_daemon.c:100:13: warning: In the GNU C Library, "major" is defined
 by . For historical compatibility, it is currently
defined by  as well, but we plan to  remove this soon.
To use "major", include   directly.

hv_fcopy_daemon.c:42:2: note: 'snprintf' output between 2 and 1040
bytes into a destination of size 260

Signed-off-by: Dexuan Cui 
Cc: Stephen Hemminger 
Cc: K. Y. Srinivasan 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/hv_fcopy_daemon.c | 3 ++-
 tools/hv/hv_vss_daemon.c   | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index 457a1521f32f..785f4e95148c 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -23,13 +23,14 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
 static int target_fd;
-static char target_fname[W_MAX_PATH];
+static char target_fname[PATH_MAX];
 static unsigned long long filesize;
 
 static int hv_start_fcopy(struct hv_start_fcopy *smsg)
diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
index b2b4ebffab8c..34031a297f02 100644
--- a/tools/hv/hv_vss_daemon.c
+++ b/tools/hv/hv_vss_daemon.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 09/12] hv_balloon: fix printk loglevel

2018-03-04 Thread kys
From: Vitaly Kuznetsov 

We have a mix of different ideas of which loglevel should be used. Unify
on the following:
- pr_info() for normal operation
- pr_warn() for 'strange' host behavior
- pr_err() for all errors.

Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_balloon.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index db0e6652d7ef..1aece72da9ba 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -691,7 +691,7 @@ static void hv_mem_hot_add(unsigned long start, unsigned 
long size,
(HA_CHUNK << PAGE_SHIFT));
 
if (ret) {
-   pr_warn("hot_add memory failed error is %d\n", ret);
+   pr_err("hot_add memory failed error is %d\n", ret);
if (ret == -EEXIST) {
/*
 * This error indicates that the error
@@ -1014,7 +1014,7 @@ static void hot_add_req(struct work_struct *dummy)
resp.result = 0;
 
if (!do_hot_add || (resp.page_count == 0))
-   pr_info("Memory hot add failed\n");
+   pr_err("Memory hot add failed\n");
 
dm->state = DM_INITIALIZED;
resp.hdr.trans_id = atomic_inc_return(&trans_id);
@@ -1041,7 +1041,7 @@ static void process_info(struct hv_dynmem_device *dm, 
struct dm_info_msg *msg)
 
break;
default:
-   pr_info("Received Unknown type: %d\n", info_hdr->type);
+   pr_warn("Received Unknown type: %d\n", info_hdr->type);
}
 }
 
@@ -1290,7 +1290,7 @@ static void balloon_up(struct work_struct *dummy)
/*
 * Free up the memory we allocatted.
 */
-   pr_info("Balloon response failed\n");
+   pr_err("Balloon response failed\n");
 
for (i = 0; i < bl_resp->range_count; i++)
free_balloon_pages(&dm_device,
@@ -1421,7 +1421,7 @@ static void cap_resp(struct hv_dynmem_device *dm,
struct dm_capabilities_resp_msg *cap_resp)
 {
if (!cap_resp->is_accepted) {
-   pr_info("Capabilities not accepted by host\n");
+   pr_err("Capabilities not accepted by host\n");
dm->state = DM_INIT_ERROR;
}
complete(&dm->host_event);
@@ -1508,7 +1508,7 @@ static void balloon_onchannelcallback(void *context)
break;
 
default:
-   pr_err("Unhandled message: type: %d\n", dm_hdr->type);
+   pr_warn("Unhandled message: type: %d\n", dm_hdr->type);
 
}
}
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 11/12] hv_balloon: fix bugs in num_pages_onlined accounting

2018-03-04 Thread kys
From: Vitaly Kuznetsov 

Our num_pages_onlined accounting is buggy:
1) In case we're offlining a memory block which was present at boot (e.g.
   when there was no hotplug at all) we subtract 32k from 0 and as
   num_pages_onlined is unsigned get a very big positive number.

2) Commit 6df8d9aaf3af ("Drivers: hv: balloon: Correctly update onlined
   page count") made num_pages_onlined counter accurate on onlining but
   totally incorrect on offlining for partly populated regions: no matter
   how many pages were onlined and what was actually added to
   num_pages_onlined counter we always subtract the full region (32k) so
   again, num_pages_onlined can wrap around zero. By onlining/offlining
   the same partly populated region multiple times we can make the
   situation worse.

Solve these issues by doing accurate accounting on offlining: walk HAS
list, check for covered range and gaps.

Fixes: 6df8d9aaf3af ("Drivers: hv: balloon: Correctly update onlined page 
count")
Signed-off-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv_balloon.c | 82 +
 1 file changed, 69 insertions(+), 13 deletions(-)

diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c
index 5b8e1ad1bcfe..7514a32d0de4 100644
--- a/drivers/hv/hv_balloon.c
+++ b/drivers/hv/hv_balloon.c
@@ -576,11 +576,65 @@ static struct hv_dynmem_device dm_device;
 static void post_status(struct hv_dynmem_device *dm);
 
 #ifdef CONFIG_MEMORY_HOTPLUG
+static inline bool has_pfn_is_backed(struct hv_hotadd_state *has,
+unsigned long pfn)
+{
+   struct hv_hotadd_gap *gap;
+
+   /* The page is not backed. */
+   if ((pfn < has->covered_start_pfn) || (pfn >= has->covered_end_pfn))
+   return false;
+
+   /* Check for gaps. */
+   list_for_each_entry(gap, &has->gap_list, list) {
+   if ((pfn >= gap->start_pfn) && (pfn < gap->end_pfn))
+   return false;
+   }
+
+   return true;
+}
+
+static unsigned long hv_page_offline_check(unsigned long start_pfn,
+  unsigned long nr_pages)
+{
+   unsigned long pfn = start_pfn, count = 0;
+   struct hv_hotadd_state *has;
+   bool found;
+
+   while (pfn < start_pfn + nr_pages) {
+   /*
+* Search for HAS which covers the pfn and when we find one
+* count how many consequitive PFNs are covered.
+*/
+   found = false;
+   list_for_each_entry(has, &dm_device.ha_region_list, list) {
+   while ((pfn >= has->start_pfn) &&
+  (pfn < has->end_pfn) &&
+  (pfn < start_pfn + nr_pages)) {
+   found = true;
+   if (has_pfn_is_backed(has, pfn))
+   count++;
+   pfn++;
+   }
+   }
+
+   /*
+* This PFN is not in any HAS (e.g. we're offlining a region
+* which was present at boot), no need to account for it. Go
+* to the next one.
+*/
+   if (!found)
+   pfn++;
+   }
+
+   return count;
+}
+
 static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
  void *v)
 {
struct memory_notify *mem = (struct memory_notify *)v;
-   unsigned long flags;
+   unsigned long flags, pfn_count;
 
switch (val) {
case MEM_ONLINE:
@@ -593,7 +647,19 @@ static int hv_memory_notifier(struct notifier_block *nb, 
unsigned long val,
 
case MEM_OFFLINE:
spin_lock_irqsave(&dm_device.ha_lock, flags);
-   dm_device.num_pages_onlined -= mem->nr_pages;
+   pfn_count = hv_page_offline_check(mem->start_pfn,
+ mem->nr_pages);
+   if (pfn_count <= dm_device.num_pages_onlined) {
+   dm_device.num_pages_onlined -= pfn_count;
+   } else {
+   /*
+* We're offlining more pages than we managed to online.
+* This is unexpected. In any case don't let
+* num_pages_onlined wrap around zero.
+*/
+   WARN_ON_ONCE(1);
+   dm_device.num_pages_onlined = 0;
+   }
spin_unlock_irqrestore(&dm_device.ha_lock, flags);
break;
case MEM_GOING_ONLINE:
@@ -612,19 +678,9 @@ static struct notifier_block hv_memory_nb = {
 /* Check if the particular page is backed and can be onlined and online it. */
 static void hv_page_online_one(struct hv_hotadd_state *has, struct page *pg)
 {
-   struct hv_hotadd_gap *gap;
-   unsigned long pf

[PATCH V2 01/12] tools/hv: Fix IP reporting by KVP daemon with SRIOV

2018-03-04 Thread kys
From: Haiyang Zhang 

On Hyper-V the VF NIC has the same MAC as the related synthetic NIC.
VF NIC can work under the synthetic NIC transparently, without its
own IP address. The existing KVP daemon only gets IP from the first
NIC matching a MAC address, and may not be able to find the IP in
this case.

This patch fixes the problem by searching the NIC matching the MAC,
and having an IP address. So, the IP address will be found and
reported to the host successfully.

Signed-off-by: Haiyang Zhang 
Signed-off-by: K. Y. Srinivasan 
---
 tools/hv/hv_kvp_daemon.c | 138 ++-
 1 file changed, 65 insertions(+), 73 deletions(-)

diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 4c99c57736ce..dbf6e8bd98ba 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -634,64 +634,6 @@ static char *kvp_if_name_to_mac(char *if_name)
return mac_addr;
 }
 
-
-/*
- * Retrieve the interface name given tha MAC address.
- */
-
-static char *kvp_mac_to_if_name(char *mac)
-{
-   DIR *dir;
-   struct dirent *entry;
-   FILE*file;
-   char*p, *x;
-   char*if_name = NULL;
-   charbuf[256];
-   char dev_id[PATH_MAX];
-   unsigned int i;
-
-   dir = opendir(KVP_NET_DIR);
-   if (dir == NULL)
-   return NULL;
-
-   while ((entry = readdir(dir)) != NULL) {
-   /*
-* Set the state for the next pass.
-*/
-   snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR,
-entry->d_name);
-
-   file = fopen(dev_id, "r");
-   if (file == NULL)
-   continue;
-
-   p = fgets(buf, sizeof(buf), file);
-   if (p) {
-   x = strchr(p, '\n');
-   if (x)
-   *x = '\0';
-
-   for (i = 0; i < strlen(p); i++)
-   p[i] = toupper(p[i]);
-
-   if (!strcmp(p, mac)) {
-   /*
-* Found the MAC match; return the interface
-* name. The caller will free the memory.
-*/
-   if_name = strdup(entry->d_name);
-   fclose(file);
-   break;
-   }
-   }
-   fclose(file);
-   }
-
-   closedir(dir);
-   return if_name;
-}
-
-
 static void kvp_process_ipconfig_file(char *cmd,
char *config_buf, unsigned int len,
int element_size, int offset)
@@ -997,6 +939,70 @@ kvp_get_ip_info(int family, char *if_name, int op,
return error;
 }
 
+/*
+ * Retrieve the IP given the MAC address.
+ */
+static int kvp_mac_to_ip(struct hv_kvp_ipaddr_value *kvp_ip_val)
+{
+   char *mac = (char *)kvp_ip_val->adapter_id;
+   DIR *dir;
+   struct dirent *entry;
+   FILE*file;
+   char*p, *x;
+   char*if_name = NULL;
+   charbuf[256];
+   char dev_id[PATH_MAX];
+   unsigned int i;
+   int error = HV_E_FAIL;
+
+   dir = opendir(KVP_NET_DIR);
+   if (dir == NULL)
+   return HV_E_FAIL;
+
+   while ((entry = readdir(dir)) != NULL) {
+   /*
+* Set the state for the next pass.
+*/
+   snprintf(dev_id, sizeof(dev_id), "%s%s/address", KVP_NET_DIR,
+entry->d_name);
+
+   file = fopen(dev_id, "r");
+   if (file == NULL)
+   continue;
+
+   p = fgets(buf, sizeof(buf), file);
+   fclose(file);
+   if (!p)
+   continue;
+
+   x = strchr(p, '\n');
+   if (x)
+   *x = '\0';
+
+   for (i = 0; i < strlen(p); i++)
+   p[i] = toupper(p[i]);
+
+   if (strcmp(p, mac))
+   continue;
+
+   /*
+* Found the MAC match.
+* A NIC (e.g. VF) matching the MAC, but without IP, is skipped.
+*/
+   if_name = entry->d_name;
+   if (!if_name)
+   continue;
+
+   error = kvp_get_ip_info(0, if_name, KVP_OP_GET_IP_INFO,
+   kvp_ip_val, MAX_IP_ADDR_SIZE * 2);
+
+   if (!error && strlen((char *)kvp_ip_val->ip_addr))
+   break;
+   }
+
+   closedir(dir);
+   return error;
+}
 
 static int expand_ipv6(char *addr, int type)
 {
@@ -1472,26 +1478,12 @@ int main(int argc, char *argv[])
switch (op) {
case KVP_OP_GET_IP_INFO:
kvp_ip_val = &hv_msg->body.kvp_ip_val;
-

[PATCH V2 07/12] hv_vmbus: Correct the stale comments regarding cpu affinity

2018-03-04 Thread kys
From: Haiyang Zhang 

The comments doesn't match what the current code does, also have a
typo. This patch corrects them.

Signed-off-by: Haiyang Zhang 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/channel_mgmt.c | 6 ++
 include/linux/hyperv.h| 2 +-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index c21020b69114..c6d9d19bc04e 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -596,10 +596,8 @@ static int next_numa_node_id;
 /*
  * Starting with Win8, we can statically distribute the incoming
  * channel interrupt load by binding a channel to VCPU.
- * We do this in a hierarchical fashion:
- * First distribute the primary channels across available NUMA nodes
- * and then distribute the subchannels amongst the CPUs in the NUMA
- * node assigned to the primary channel.
+ * We distribute the interrupt loads to one or more NUMA nodes based on
+ * the channel's affinity_policy.
  *
  * For pre-win8 hosts or non-performance critical channels we assign the
  * first CPU in the first NUMA node.
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 93bd6fcd6e62..2048f3c3b68a 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -844,7 +844,7 @@ struct vmbus_channel {
 
/*
 * NUMA distribution policy:
-* We support teo policies:
+* We support two policies:
 * 1) Balanced: Here all performance critical channels are
 *distributed evenly amongst all the NUMA nodes.
 *This policy will be the default policy.
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 02/12] hyper-v: use GFP_KERNEL for hv_context.hv_numa_map

2018-03-04 Thread kys
From: Jia-Ju Bai 

The kzalloc function is called with GFP_ATOMIC.
But according to driver call graph, it is not in atomic context,
namely no spinlock is held nor in an interrupt handler.

This GFP_ATOMIC is unnecessary, and replace with GFP_KERNEL.

Signed-off-by: Jia-Ju Bai 
Reviewed-by: Vitaly Kuznetsov 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index fe96aab9e794..b6cacc4cccf2 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -147,7 +147,7 @@ int hv_synic_alloc(void)
int cpu;
 
hv_context.hv_numa_map = kzalloc(sizeof(struct cpumask) * nr_node_ids,
-GFP_ATOMIC);
+GFP_KERNEL);
if (hv_context.hv_numa_map == NULL) {
pr_err("Unable to allocate NUMA map\n");
goto err;
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH V2 00/12] Drivers: hv: Miscellaneous fixes

2018-03-04 Thread kys
From: "K. Y. Srinivasan" 

Miscellaneous fixes.
V2: Only the patch "Drivers: hv: vmbus: Implement Direct Mode for 
stimer0"
has been modified to address review comments from Dan Carpenter.

Dexuan Cui (1):
  tools: hv: fix compiler warnings about major/target_fname

Haiyang Zhang (2):
  tools/hv: Fix IP reporting by KVP daemon with SRIOV
  hv_vmbus: Correct the stale comments regarding cpu affinity

Jia-Ju Bai (1):
  hyper-v: use GFP_KERNEL for hv_context.hv_numa_map

Joe Perches (1):
  hv: Synthetic typo correction

Michael Kelley (1):
  Drivers: hv: vmbus: Implement Direct Mode for stimer0

Olaf Hering (1):
  tools: hv: include string.h in hv_fcopy_daemon

Vitaly Kuznetsov (4):
  hv_balloon: fix printk loglevel
  hv_balloon: simplify hv_online_page()/hv_page_online_one()
  hv_balloon: fix bugs in num_pages_onlined accounting
  hv_balloon: trace post_status

lantianyu1...@gmail.com (1):
  vmbus/ring_buffer: remove some redundant helper function.

 arch/x86/entry/entry_32.S  |   3 +
 arch/x86/entry/entry_64.S  |   3 +
 arch/x86/include/asm/hardirq.h |   1 +
 arch/x86/include/asm/irq_vectors.h |   3 +-
 arch/x86/include/asm/mshyperv.h|  13 
 arch/x86/include/uapi/asm/hyperv.h |   3 +
 arch/x86/kernel/cpu/mshyperv.c |  40 +++
 arch/x86/kernel/irq.c  |   7 ++
 drivers/hv/Makefile|   1 +
 drivers/hv/channel_mgmt.c  |   6 +-
 drivers/hv/hv.c|  63 +++--
 drivers/hv/hv_balloon.c| 121 ++--
 drivers/hv/hv_trace_balloon.h  |  48 +
 drivers/hv/hyperv_vmbus.h  |   4 +-
 drivers/hv/ring_buffer.c   |  49 ++---
 include/linux/hyperv.h |   2 +-
 tools/hv/hv_fcopy_daemon.c |   4 +-
 tools/hv/hv_kvp_daemon.c   | 138 +
 tools/hv/hv_vss_daemon.c   |   1 +
 19 files changed, 341 insertions(+), 169 deletions(-)
 create mode 100644 drivers/hv/hv_trace_balloon.h

-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 03/12] hv: Synthetic typo correction

2018-02-11 Thread kys
From: Joe Perches 

Just a trivial tyop fix.

Signed-off-by: Joe Perches 
Signed-off-by: K. Y. Srinivasan 
---
 drivers/hv/hv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index b6cacc4cccf2..31142b72f1b9 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -217,7 +217,7 @@ void hv_synic_free(void)
 }
 
 /*
- * hv_synic_init - Initialize the Synthethic Interrupt Controller.
+ * hv_synic_init - Initialize the Synthetic Interrupt Controller.
  *
  * If it is already initialized by another entity (ie x2v shim), we need to
  * retrieve the initialized message and event pages.  Otherwise, we create and
-- 
2.15.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


  1   2   3   4   5   >