Re: [PATCH 1/1] linux-next: drivers: staging: most: Fix return value
On Fri, 31 Jul 2015 22:18:17 +0200 Michael Hornung wrote: > * Fix sparse warning "Using plain integer as NULL pointer" > > Signed-off-by: Michael Hornung Acked-by: Christian Gromm > --- > drivers/staging/most/aim-network/networking.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/most/aim-network/networking.c > b/drivers/staging/most/aim-network/networking.c > index 4639c49..c8ab239 100644 > --- a/drivers/staging/most/aim-network/networking.c > +++ b/drivers/staging/most/aim-network/networking.c > @@ -311,7 +311,7 @@ static struct net_dev_context *get_net_dev_context( > } > } > spin_unlock(&list_lock); > - return 0; > + return NULL; > } > > static int aim_probe_channel(struct most_interface *iface, int channel_idx, ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: most: replace pr_*() functions by dev_*()
On Fri, 31 Jul 2015 17:14:32 +0530 Sudip Mukherjee wrote: > On Thu, Jul 30, 2015 at 06:19:41PM +0200, Christian Gromm wrote: > > This patch replaces pr_*() functions with dev_*(). > > > > Reported-by: Greg Kroah-Hartman > > Signed-off-by: Christian Gromm > > --- > > > + dev_notice(dev, > > + "Channel %d - rouding buffer size to %d bytes, " > > + "channel config says %d bytes\n", > user visible strings should not be splitted. This is a dilemma. Either cracking the 80 character boarder or splitting the string. Not sure what's worse. Thanks, Chris > > regards > sudip ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: most: replace pr_*() functions by dev_*()
On Sat, Aug 01, 2015 at 01:04:48PM +0200, Christian Gromm wrote: > On Fri, 31 Jul 2015 17:14:32 +0530 > Sudip Mukherjee wrote: > > > On Thu, Jul 30, 2015 at 06:19:41PM +0200, Christian Gromm wrote: > > > This patch replaces pr_*() functions with dev_*(). > > > > > > Reported-by: Greg Kroah-Hartman > > > Signed-off-by: Christian Gromm > > > --- > > > > > + dev_notice(dev, > > > +"Channel %d - rouding buffer size to %d bytes, " > > > +"channel config says %d bytes\n", > > user visible strings should not be splitted. > > This is a dilemma. Either cracking the 80 character boarder or splitting the > string. > Not sure what's worse. checkpatch should not give you warning for uservisible strings of more than 80 char. CodingStyle says "However, never break user-visible strings such as printk messages, because that breaks the ability to grep for them." regards sudip > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] staging: unisys: visornic: Convert to using napi
On Fri, Jul 31, 2015 at 09:41:10PM -0400, Neil Horman wrote: > On Fri, Jul 31, 2015 at 06:56:33PM -0400, Benjamin Romer wrote: > > From: Neil Horman > > > > Switch the visornic over to use napi. Currently there is a kernel > > thread > > that sits and waits on a wait queue to get notified of incoming virtual > > interrupts. It would be nice if we could handle frame reception using > > the > > standard napi processing instead. This patch creates our napi instance > > and has the rx thread schedule it > > > > Given that the unisys hypervisor currently requires that queue servicing > > be done by a polling loop that wakes up every 2ms, lets instead also > > convert that to a timer, which is simpler, and allows us to remove all > > the thread starting and stopping code. > > > > Signed-off-by: Neil Horman > > Signed-off-by: Benjamin Romer > > I assume you just didn't copy me on patch 1/2? I don't see it anywhere. > > Neil > Sorry, scratch that, it just showed up late. for the series: Acked-by: Neil Horman ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] lustre: Include unaligned.h instead of access_ok.h
Including access_ok.h causes the ia64:allmodconfig build (and maybe others) to fail with include/linux/unaligned/le_struct.h:6:19: error: redefinition of 'get_unaligned_le16' include/linux/unaligned/access_ok.h:7:19: note: previous definition of 'get_unaligned_le16' was here include/linux/unaligned/le_struct.h:26:20: error: redefinition of 'put_unaligned_le32' include/linux/unaligned/access_ok.h:42:20: note: previous definition of 'put_unaligned_le32' was here include/linux/unaligned/le_struct.h:31:20: error: redefinition of 'put_unaligned_le64' include/linux/unaligned/access_ok.h:47:20: note: previous definition of 'put_unaligned_le64' was here Include unaligned.h instead and leave it up to the architecture to decide how to implement unaligned accesses. Fixes: 8c4f136497315 ("Staging: lustre: Use put_unaligned_le64") Cc: Vaishali Thakkar Signed-off-by: Guenter Roeck --- drivers/staging/lustre/lustre/obdclass/debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/obdclass/debug.c b/drivers/staging/lustre/lustre/obdclass/debug.c index 9c934e6d2ea1..c61add46b426 100644 --- a/drivers/staging/lustre/lustre/obdclass/debug.c +++ b/drivers/staging/lustre/lustre/obdclass/debug.c @@ -40,7 +40,7 @@ #define DEBUG_SUBSYSTEM D_OTHER -#include +#include #include "../include/obd_support.h" #include "../include/lustre_debug.h" -- 2.1.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] staging: unisys: visornic: Convert to using napi
On Sat, Aug 01, 2015 at 09:36:19AM -0400, Neil Horman wrote: > On Fri, Jul 31, 2015 at 09:41:10PM -0400, Neil Horman wrote: > > On Fri, Jul 31, 2015 at 06:56:33PM -0400, Benjamin Romer wrote: > > > From: Neil Horman > > > > > > Switch the visornic over to use napi. Currently there is a kernel > > > thread > > > that sits and waits on a wait queue to get notified of incoming virtual > > > interrupts. It would be nice if we could handle frame reception using > > > the > > > standard napi processing instead. This patch creates our napi instance > > > and has the rx thread schedule it > > > > > > Given that the unisys hypervisor currently requires that queue servicing > > > be done by a polling loop that wakes up every 2ms, lets instead also > > > convert that to a timer, which is simpler, and allows us to remove all > > > the thread starting and stopping code. > > > > > > Signed-off-by: Neil Horman > > > Signed-off-by: Benjamin Romer > > > > I assume you just didn't copy me on patch 1/2? I don't see it anywhere. > > > > Neil > > > > Sorry, scratch that, it just showed up late. > > for the series: > Acked-by: Neil Horman Why are you acking a series that you already signed off on? That seems redundant... ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging:wilc1000 :Remove typedef from struct
On Sat, Aug 01, 2015 at 10:25:26AM +0530, Sudip Mukherjee wrote: > On Fri, Jul 31, 2015 at 01:52:13PM -0700, Greg Kroah-Hartman wrote: > > On Fri, Jul 31, 2015 at 11:08:47AM +0530, Shraddha Barke wrote: > > > This patch fixes the following checkpatch.pl warning: > > > > > > WARNING: do not add new typedefs > > > > > > Signed-off-by: Shraddha Barke > > > --- > > > > -typedef enum { > > > +enum { > > > CLASS1_FRAME_TYPE = 0x00, > > > CLASS2_FRAME_TYPE = 0x01, > > > CLASS3_FRAME_TYPE = 0x02, > > > > Did you test-build this change? > This enum is not used anywhere. So did not affect the build. Then it should be deleted :) ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 2/6] staging: unisys: visornic - prevent lock recursion after IO recovery
The threading is messed up. If you are only going to resend one patch then you have to use the --in-reply-to option. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
drivres/hv
Greg, over the last two months we have sent numerous Hyper-V patches and these are yet to be comitted (all review comments have been addressed for these patches). Please let me know if I should resend these patches. Regards, K. Y ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: drivres/hv
On Sat, Aug 01, 2015 at 12:46:10PM -0700, K. Y. Srinivasan wrote: > > Greg, over the last two months we have sent numerous Hyper-V patches and > these are yet to be comitted (all review comments have been addressed > for these patches). Please let me know if I should resend these patches. They are in my queue, I've been slow at getting to them, sorry. If you want to resend them so that I know exactly which ones to apply, instead of having to dig through the different 'resend' and 'v2' series, that would be most appreciated. thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
RE: drivres/hv
> -Original Message- > From: Greg KH [mailto:gre...@linuxfoundation.org] > Sent: Saturday, August 1, 2015 11:36 AM > To: KY Srinivasan > Cc: linux-ker...@vger.kernel.org; de...@linuxdriverproject.org; > o...@aepfle.de; a...@canonical.com; vkuzn...@redhat.com; > jasow...@redhat.com > Subject: Re: drivres/hv > > On Sat, Aug 01, 2015 at 12:46:10PM -0700, K. Y. Srinivasan wrote: > > > > Greg, over the last two months we have sent numerous Hyper-V patches > and > > these are yet to be comitted (all review comments have been addressed > > for these patches). Please let me know if I should resend these patches. > > They are in my queue, I've been slow at getting to them, sorry. If you > want to resend them so that I know exactly which ones to apply, instead > of having to dig through the different 'resend' and 'v2' series, that > would be most appreciated. Thanks Greg; I can understand. I will send them out right away as one large set. Regards, K. Y > > thanks, > > greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: vme_ca91cx42 doesn't touch VMEbus on read with vme_user
It seems that GE does some extra FPGA trickery for VME. Could it be that you need vmivme7805 driver? > On 01 Aug 2015, at 01:28, Eisch, Jonathan D [PHYSA] > wrote: > > Hello DriverDev, > > I recently installed the latest Debian with Kernel 3.16 including all the vme > drivers (and vme_user in staging) on a GE VME7807RC. Using Martyn Welch’s > example from 12 March 2013 on this list as a guide, I tried reading out 32 > bytes from one of my boards, but I just got a bunch of 0xFF bytes. > > I monitored the bus with a diagnostics board, and didn’t see any activity at > all (no addresses, no data) from power-up through booting and trying to read > from the bus. Attempting the same reads with another VME7807 using the GE > provided driver lit up the same diagnostics board like a christmas tree > (well, the lower 16 bits). > > I hope I’m missing something basic, as I don’t see any error messages > anywhere to guide my way. > > Thanks for your help, > -Jonathan > > $ sudo modprobe vme_ca91cx42 > $ sudo modprobe vme_user bus=0 > $ dmesg | grep vme > [ 632.942457] vme_ca91cx42 :01:0d.0: found PCI INT A -> IRQ 14 > [ 632.942523] vme_ca91cx42 :01:0d.0: Board is the VME system controller > [ 632.942526] vme_ca91cx42 :01:0d.0: Slot ID is 0 > [ 632.942529] vme_ca91cx42 :01:0d.0: CR/CSR Offset: 0 > [ 632.942533] vme_ca91cx42 :01:0d.0: Slot number is unset, not > configuring CR/CSR space > [ 632.942537] vme_ca91cx42 :01:0d.0: CR/CSR configuration failed. > [ 640.990642] vme_user: module is from the staging directory, the quality is > unknown, you have been warned. > [ 640.991404] vme_user: VME User Space Access Driver > $ sudo ./vmetest > Simple VME User Module Test > WARNING: Only read 32 bytes > : ff ff ff ff ff ff ff ff > 0008: ff ff ff ff ff ff ff ff > 0010: ff ff ff ff ff ff ff ff > 0018: ff ff ff ff ff ff ff ff > > $ cat main.c > /* > * main.c > * > * Created on: Jul 29, 2015 > * > * Copied from: > http://driverdev.linuxdriverproject.org/pipermail/driverdev-devel/2013-April/037460.html > * > */ > > #define _XOPEN_SOURCE 500 > #include > #include > #include > #include > #include > #include > #include > #include "vme_user.h" > int main(int argc, char *argv[]) > { >int fd; >int i; >int retval; >unsigned char data[512]; > >struct vme_master master; > >printf("Simple VME User Module Test\n"); > >fd = open("/dev/bus/vme/m0", O_RDONLY); >if (fd == -1) { >perror("ERROR: Opening window device file"); >return 1; >} > //master.enable = 1; > //master.vme_addr = 2*0x800; > //master.size = 0x10; > //master.aspace = 0x4; // VME_A32 > //master.cycle = 0x2000 | 0x8000; // Unprivileged data access > //master.dwidth = 0x4; // 32 bit word access >master.enable = 1; >master.vme_addr = 0xE000; >master.size = 0x1000; >master.aspace = 0x1; // VME_A16 >master.cycle = 0x2000; // Unprivileged data access >master.dwidth = 0x2; // 16 bit word access > >retval = ioctl(fd, VME_SET_MASTER, &master); >if (retval != 0) { >printf("retval=%d\n", retval); >perror("ERROR: Failed to configure window"); >return 1; >} > >/* > * Reading first 32 bytes > */ >for (i=0; i<32; i++) { >data[i] = 0; >} > >retval = pread(fd, data, 32, 0); >if (retval < 512) { >printf("WARNING: Only read %d bytes", retval); >} > >for(i=0; iif (i % 8 == 0) { >printf("\n""%4.4x: ", i); >} >printf("%2.2x ", data[i]); >} >printf("\n"); > >close(fd); > >return 0; > } > > > > Jonathan Eisch > Research Associate > Physics & Astronomy > Iowa State University > ___ > devel mailing list > de...@linuxdriverproject.org > http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 00/28] Drivers: hv: vmbus
Miscellaneous fixes/improvements. The patches that were sent over the last couple of months have been consolidated in this submission. All review comments have been addressed. Alex Ng (1): Drivers: hv: balloon: Enable dynamic memory protocol negotiation with Windows 10 hosts Christopher Oo (1): Drivers: hv_vmbus: Fix signal to host condition Dan Carpenter (1): hv: util: checking the wrong variable Denis V. Lunev (1): mshyperv: fix recognition of Hyper-V guest crash MSR's Dexuan Cui (4): Drivers: hv: vmbus: Further improve CPU affiliation logic Drivers: hv: vmbus: add a sysfs attr to show the binding of channel/VP tools: hv: add a python script lsvmbus to list VMBus devices Drivers: hv: vmbus: document the VMBus sysfs files K. Y. Srinivasan (4): Drivers: hv: vmbus: Permit sending of packets without payload Drivers: hv: vmbus: Consider ND NIC in binding channels to CPUs Drivers: hv: vmbus: Improve the CPU affiliation for channels Drivers: hv: vmbus: Implement a clocksource based on the TSC page Nik Nyby (1): Drivers: hv: vmbus: fix typo in hv_port_info struct Viresh Kumar (1): drivers/hv: Migrate to new 'set-state' interface Vitaly Kuznetsov (12): Drivers: hv: vmbus: remove hv_synic_free_cpu() call from hv_synic_cleanup() kexec: define kexec_in_progress in !CONFIG_KEXEC case Drivers: hv: vmbus: add special kexec handler Drivers: hv: don't do hypercalls when hypercall_page is NULL Drivers: hv: vmbus: add special crash handler Drivers: hv: vmbus: prefer 'die' notification chain to 'panic' Drivers: hv: kvp: check kzalloc return value Drivers: hv: fcopy: dynamically allocate smsg_out in fcopy_send_data() Drivers: hv: vmbus: don't send CHANNELMSG_UNLOAD on pre-Win2012R2 hosts cpu-hotplug: convert cpu_hotplug_disabled to a counter cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable Drivers: hv: vmbus: use cpu_hotplug_enable/disable ja...@microsoft.com (2): drivers:hv: Modify hv_vmbus to search for all MMIO ranges available. drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus Documentation/ABI/stable/sysfs-bus-vmbus | 29 ++ Documentation/power/suspend-and-cpuhotplug.txt |6 +- MAINTAINERS|1 + arch/x86/include/asm/mshyperv.h|5 + arch/x86/include/uapi/asm/hyperv.h |2 + arch/x86/kernel/cpu/mshyperv.c | 47 drivers/hv/channel.c |4 +- drivers/hv/channel_mgmt.c | 34 ++- drivers/hv/hv.c| 152 --- drivers/hv/hv_balloon.c| 26 ++- drivers/hv/hv_fcopy.c | 21 +- drivers/hv/hv_kvp.c|3 + drivers/hv/hv_utils_transport.c|2 +- drivers/hv/hyperv_vmbus.h | 16 +- drivers/hv/ring_buffer.c | 14 +- drivers/hv/vmbus_drv.c | 353 +++- drivers/video/fbdev/hyperv_fb.c| 46 ++-- include/linux/hyperv.h |7 +- include/linux/kexec.h |1 + kernel/cpu.c | 24 +- tools/hv/lsvmbus | 101 +++ 21 files changed, 718 insertions(+), 176 deletions(-) create mode 100644 Documentation/ABI/stable/sysfs-bus-vmbus create mode 100644 tools/hv/lsvmbus -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 05/28] Drivers: hv: vmbus: add special crash handler
From: Vitaly Kuznetsov Full kernel hang is observed when kdump kernel starts after a crash. This hang happens in vmbus_negotiate_version() function on wait_for_completion() as Hyper-V host (Win2012R2 in my testing) never responds to CHANNELMSG_INITIATE_CONTACT as it thinks the connection is already established. We need to perform some mandatory minimalistic cleanup before we start new kernel. Reported-by: K. Y. Srinivasan Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- arch/x86/include/asm/mshyperv.h |2 ++ arch/x86/kernel/cpu/mshyperv.c | 22 ++ drivers/hv/vmbus_drv.c | 14 ++ 3 files changed, 38 insertions(+), 0 deletions(-) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index d3db910..d02f9c9 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -22,4 +22,6 @@ void hv_remove_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)); +void hv_remove_crash_handler(void); #endif diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index fa483ed..5ea5bbc 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -35,6 +35,7 @@ struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); static void (*hv_kexec_handler)(void); +static void (*hv_crash_handler)(struct pt_regs *regs); #if IS_ENABLED(CONFIG_HYPERV) static void (*vmbus_handler)(void); @@ -83,6 +84,18 @@ void hv_remove_kexec_handler(void) hv_kexec_handler = NULL; } EXPORT_SYMBOL_GPL(hv_remove_kexec_handler); + +void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs)) +{ + hv_crash_handler = handler; +} +EXPORT_SYMBOL_GPL(hv_setup_crash_handler); + +void hv_remove_crash_handler(void) +{ + hv_crash_handler = NULL; +} +EXPORT_SYMBOL_GPL(hv_remove_crash_handler); #endif static void hv_machine_shutdown(void) @@ -92,6 +105,14 @@ static void hv_machine_shutdown(void) native_machine_shutdown(); } +static void hv_machine_crash_shutdown(struct pt_regs *regs) +{ + if (hv_crash_handler) + hv_crash_handler(regs); + native_machine_crash_shutdown(regs); +} + + static uint32_t __init ms_hyperv_platform(void) { u32 eax; @@ -165,6 +186,7 @@ static void __init ms_hyperv_init_platform(void) #endif machine_ops.shutdown = hv_machine_shutdown; + machine_ops.crash_shutdown = hv_machine_crash_shutdown; } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 31748a2..1ed9b32 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1071,6 +1071,18 @@ static void hv_kexec_handler(void) hv_cleanup(); }; +static void hv_crash_handler(struct pt_regs *regs) +{ + vmbus_initiate_unload(); + /* +* In crash handler we can't schedule synic cleanup for all CPUs, +* doing the cleanup for current CPU only. This should be sufficient +* for kdump. +*/ + hv_synic_cleanup(NULL); + hv_cleanup(); +}; + static int __init hv_acpi_init(void) { int ret, t; @@ -1104,6 +1116,7 @@ static int __init hv_acpi_init(void) goto cleanup; hv_setup_kexec_handler(hv_kexec_handler); + hv_setup_crash_handler(hv_crash_handler); return 0; @@ -1118,6 +1131,7 @@ static void __exit vmbus_exit(void) int cpu; hv_remove_kexec_handler(); + hv_remove_crash_handler(); vmbus_connection.conn_state = DISCONNECTED; hv_synic_clockevents_cleanup(); vmbus_disconnect(); -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 10/28] Drivers: hv: vmbus: Permit sending of packets without payload
The guest may have to send a completion packet back to the host. To support this usage, permit sending a packet without a payload - we would be only sending the descriptor in this case. Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 603ce97..c4dcab0 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -601,6 +601,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, u64 aligned_data = 0; int ret; bool signal = false; + int num_vecs = ((bufferlen != 0) ? 3 : 1); /* Setup the descriptor */ @@ -618,7 +619,8 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, bufferlist[2].iov_base = &aligned_data; bufferlist[2].iov_len = (packetlen_aligned - packetlen); - ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); + ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs, + &signal); /* * Signalling the host is conditional on many factors: -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 09/28] Drivers: hv: balloon: Enable dynamic memory protocol negotiation with Windows 10 hosts
From: Alex Ng Support Win10 protocol for Dynamic Memory. Thia patch allows guests on Win10 hosts to hot-add memory even when dynamic memory is not enabled on the guest. Signed-off-by: Alex Ng Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv_balloon.c | 26 -- 1 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 8a725cd..b853b4b 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -62,11 +62,13 @@ enum { DYNMEM_PROTOCOL_VERSION_1 = DYNMEM_MAKE_VERSION(0, 3), DYNMEM_PROTOCOL_VERSION_2 = DYNMEM_MAKE_VERSION(1, 0), + DYNMEM_PROTOCOL_VERSION_3 = DYNMEM_MAKE_VERSION(2, 0), DYNMEM_PROTOCOL_VERSION_WIN7 = DYNMEM_PROTOCOL_VERSION_1, DYNMEM_PROTOCOL_VERSION_WIN8 = DYNMEM_PROTOCOL_VERSION_2, + DYNMEM_PROTOCOL_VERSION_WIN10 = DYNMEM_PROTOCOL_VERSION_3, - DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN8 + DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN10 }; @@ -1296,13 +1298,25 @@ static void version_resp(struct hv_dynmem_device *dm, if (dm->next_version == 0) goto version_error; - dm->next_version = 0; memset(&version_req, 0, sizeof(struct dm_version_request)); version_req.hdr.type = DM_VERSION_REQUEST; version_req.hdr.size = sizeof(struct dm_version_request); version_req.hdr.trans_id = atomic_inc_return(&trans_id); - version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN7; - version_req.is_last_attempt = 1; + version_req.version.version = dm->next_version; + + /* +* Set the next version to try in case current version fails. +* Win7 protocol ought to be the last one to try. +*/ + switch (version_req.version.version) { + case DYNMEM_PROTOCOL_VERSION_WIN8: + dm->next_version = DYNMEM_PROTOCOL_VERSION_WIN7; + version_req.is_last_attempt = 0; + break; + default: + dm->next_version = 0; + version_req.is_last_attempt = 1; + } ret = vmbus_sendpacket(dm->dev->channel, &version_req, sizeof(struct dm_version_request), @@ -1442,7 +1456,7 @@ static int balloon_probe(struct hv_device *dev, dm_device.dev = dev; dm_device.state = DM_INITIALIZING; - dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN7; + dm_device.next_version = DYNMEM_PROTOCOL_VERSION_WIN8; init_completion(&dm_device.host_event); init_completion(&dm_device.config_event); INIT_LIST_HEAD(&dm_device.ha_region_list); @@ -1474,7 +1488,7 @@ static int balloon_probe(struct hv_device *dev, version_req.hdr.type = DM_VERSION_REQUEST; version_req.hdr.size = sizeof(struct dm_version_request); version_req.hdr.trans_id = atomic_inc_return(&trans_id); - version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN8; + version_req.version.version = DYNMEM_PROTOCOL_VERSION_WIN10; version_req.is_last_attempt = 0; ret = vmbus_sendpacket(dev->channel, &version_req, -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 24/28] tools: hv: add a python script lsvmbus to list VMBus devices
From: Dexuan Cui By default lsvmbus lists all the devices in the VMBus. With -v or -vv, more information is printed, including the VMBus Rel_ID, class ID, device ID and which channel is bound to which virtual processor, etc. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- tools/hv/lsvmbus | 101 ++ 1 files changed, 101 insertions(+), 0 deletions(-) create mode 100644 tools/hv/lsvmbus diff --git a/tools/hv/lsvmbus b/tools/hv/lsvmbus new file mode 100644 index 000..162a378 --- /dev/null +++ b/tools/hv/lsvmbus @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +import os +from optparse import OptionParser + +parser = OptionParser() +parser.add_option("-v", "--verbose", dest="verbose", + help="print verbose messages. Try -vv, -vvv for \ + more verbose messages", action="count") + +(options, args) = parser.parse_args() + +verbose = 0 +if options.verbose is not None: + verbose = options.verbose + +vmbus_sys_path = '/sys/bus/vmbus/devices' +if not os.path.isdir(vmbus_sys_path): + print "%s doesn't exist: exiting..." % vmbus_sys_path + exit(-1) + +vmbus_dev_dict = { + '{0e0b6031-5213-4934-818b-38d90ced39db}' : '[Operating system shutdown]', + '{9527e630-d0ae-497b-adce-e80ab0175caf}' : '[Time Synchronization]', + '{57164f39-9115-4e78-ab55-382f3bd5422d}' : '[Heartbeat]', + '{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}' : '[Data Exchange]', + '{35fa2e29-ea23-4236-96ae-3a6ebacba440}' : '[Backup (volume checkpoint)]', + '{34d14be3-dee4-41c8-9ae7-6b174977c192}' : '[Guest services]', + '{525074dc-8985-46e2-8057-a307dc18a502}' : '[Dynamic Memory]', + '{cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}' : 'Synthetic mouse', + '{f912ad6d-2b17-48ea-bd65-f927a61c7684}' : 'Synthetic keyboard', + '{da0a7802-e377-4aac-8e77-0558eb1073f8}' : 'Synthetic framebuffer adapter', + '{f8615163-df3e-46c5-913f-f2d2f965ed0e}' : 'Synthetic network adapter', + '{32412632-86cb-44a2-9b5c-50d1417354f5}' : 'Synthetic IDE Controller', + '{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}' : 'Synthetic SCSI Controller', + '{2f9bcc4a-0069-4af3-b76b-6fd0be528cda}' : 'Synthetic fiber channel adapter', + '{8c2eaf3d-32a7-4b09-ab99-bd1f1c86b501}' : 'Synthetic RDMA adapter', + '{276aacf4-ac15-426c-98dd-7521ad3f01fe}' : '[Reserved system device]', + '{f8e65716-3cb3-4a06-9a60-1889c5cccab5}' : '[Reserved system device]', + '{3375baf4-9e15-4b30-b765-67acb10d607b}' : '[Reserved system device]', +} + +def get_vmbus_dev_attr(dev_name, attr): + try: + f = open('%s/%s/%s' % (vmbus_sys_path, dev_name, attr), 'r') + lines = f.readlines() + f.close() + except IOError: + lines = [] + + return lines + +class VMBus_Dev: + pass + + +vmbus_dev_list = [] + +for f in os.listdir(vmbus_sys_path): + vmbus_id = get_vmbus_dev_attr(f, 'id')[0].strip() + class_id = get_vmbus_dev_attr(f, 'class_id')[0].strip() + device_id = get_vmbus_dev_attr(f, 'device_id')[0].strip() + dev_desc = vmbus_dev_dict.get(class_id, 'Unknown') + + chn_vp_mapping = get_vmbus_dev_attr(f, 'channel_vp_mapping') + chn_vp_mapping = [c.strip() for c in chn_vp_mapping] + chn_vp_mapping = sorted(chn_vp_mapping, + key = lambda c : int(c.split(':')[0])) + + chn_vp_mapping = ['\tRel_ID=%s, target_cpu=%s' % + (c.split(':')[0], c.split(':')[1]) + for c in chn_vp_mapping] + d = VMBus_Dev() + d.sysfs_path = '%s/%s' % (vmbus_sys_path, f) + d.vmbus_id = vmbus_id + d.class_id = class_id + d.device_id = device_id + d.dev_desc = dev_desc + d.chn_vp_mapping = '\n'.join(chn_vp_mapping) + if d.chn_vp_mapping: + d.chn_vp_mapping += '\n' + + vmbus_dev_list.append(d) + + +vmbus_dev_list = sorted(vmbus_dev_list, key = lambda d : int(d.vmbus_id)) + +format0 = '%2s: %s' +format1 = '%2s: Class_ID = %s - %s\n%s' +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) + elif verbose == 1: + print ('VMBUS ID ' + format1) % \ + (d.vmbus_id, d.class_id, d.dev_desc, d.chn_vp_mapping) + else: + print ('VMBUS ID ' + format2) % \ + (d.vmbus_id, d.class_id, d.dev_desc, \ + d.device_id, d.sysfs_path, d.chn_vp_mapping) -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 18/28] Drivers: hv: vmbus: Improve the CPU affiliation for channels
The current code tracks the assigned CPUs within a NUMA node in the context of the primary channel. So, if we have a VM with a single NUMA node with 8 VCPUs, we may end up unevenly distributing the channel load. Fix the issue by tracking affiliations globally. Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel_mgmt.c | 11 ++- drivers/hv/hv.c |9 + drivers/hv/hyperv_vmbus.h |5 + include/linux/hyperv.h|1 - 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 30613df..39c5afc 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -392,6 +392,7 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui struct vmbus_channel *primary = channel->primary_channel; int next_node; struct cpumask available_mask; + struct cpumask *alloced_mask; for (i = IDE; i < MAX_PERF_CHN; i++) { if (!memcmp(type_guid->b, hp_devs[i].guid, @@ -409,7 +410,6 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui * channel, bind it to cpu 0. */ channel->numa_node = 0; - cpumask_set_cpu(0, &channel->alloced_cpus_in_node); channel->target_cpu = 0; channel->target_vp = hv_context.vp_index[0]; return; @@ -434,21 +434,22 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui channel->numa_node = next_node; primary = channel; } + alloced_mask = &hv_context.hv_numa_map[primary->numa_node]; - if (cpumask_weight(&primary->alloced_cpus_in_node) == + if (cpumask_weight(alloced_mask) == cpumask_weight(cpumask_of_node(primary->numa_node))) { /* * We have cycled through all the CPUs in the node; * reset the alloced map. */ - cpumask_clear(&primary->alloced_cpus_in_node); + cpumask_clear(alloced_mask); } - cpumask_xor(&available_mask, &primary->alloced_cpus_in_node, + cpumask_xor(&available_mask, alloced_mask, cpumask_of_node(primary->numa_node)); cur_cpu = cpumask_next(-1, &available_mask); - cpumask_set_cpu(cur_cpu, &primary->alloced_cpus_in_node); + cpumask_set_cpu(cur_cpu, alloced_mask); channel->target_cpu = cur_cpu; channel->target_vp = hv_context.vp_index[cur_cpu]; diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 41d8072..fd93cfd 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -332,6 +332,13 @@ int hv_synic_alloc(void) size_t ced_size = sizeof(struct clock_event_device); int cpu; + hv_context.hv_numa_map = kzalloc(sizeof(struct cpumask) * nr_node_ids, +GFP_ATOMIC); + if (hv_context.hv_numa_map == NULL) { + pr_err("Unable to allocate NUMA map\n"); + goto err; + } + for_each_online_cpu(cpu) { hv_context.event_dpc[cpu] = kmalloc(size, GFP_ATOMIC); if (hv_context.event_dpc[cpu] == NULL) { @@ -345,6 +352,7 @@ int hv_synic_alloc(void) pr_err("Unable to allocate clock event device\n"); goto err; } + hv_init_clockevent_device(hv_context.clk_evt[cpu], cpu); hv_context.synic_message_page[cpu] = @@ -393,6 +401,7 @@ void hv_synic_free(void) { int cpu; + kfree(hv_context.hv_numa_map); for_each_online_cpu(cpu) hv_synic_free_cpu(cpu); } diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index 6383707..6f25825 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -551,6 +551,11 @@ struct hv_context { * Support PV clockevent device. */ struct clock_event_device *clk_evt[NR_CPUS]; + /* +* To manage allocations in a NUMA node. +* Array indexed by numa node ID. +*/ + struct cpumask *hv_numa_map; }; extern struct hv_context hv_context; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 54733d5..5a3df5a 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -699,7 +699,6 @@ struct vmbus_channel { /* * State to manage the CPU affiliation of channels. */ - struct cpumask alloced_cpus_in_node; int numa_node; /* * Support for sub-channels. For high performance devices, -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 11/28] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
From: ja...@microsoft.com This patch changes the logic in hv_vmbus to record all of the ranges in the VM's firmware (BIOS or UEFI) that offer regions of memory-mapped I/O space for use by paravirtual front-end drivers. The old logic just found one range above 4GB and called it good. This logic will find any ranges above 1MB. It would have been possible with this patch to just use existing resource allocation functions, rather than keep track of the entire set of Hyper-V related MMIO regions in VMBus. This strategy, however, is not sufficient when the resource allocator needs to be aware of the constraints of a Hyper-V virtual machine, which is what happens in the next patch in the series. So this first patch exists to show the first steps in reworking the MMIO allocation paths for Hyper-V front-end drivers. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan --- drivers/hv/vmbus_drv.c | 116 ++- drivers/video/fbdev/hyperv_fb.c |2 +- include/linux/hyperv.h |2 +- 3 files changed, 92 insertions(+), 28 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index b6114cc..21bb287 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -102,10 +102,7 @@ static struct notifier_block hyperv_panic_block = { .notifier_call = hyperv_panic_event, }; -struct resource hyperv_mmio = { - .name = "hyperv mmio", - .flags = IORESOURCE_MEM, -}; +struct resource *hyperv_mmio; EXPORT_SYMBOL_GPL(hyperv_mmio); static int vmbus_exists(void) @@ -1013,30 +1010,105 @@ void vmbus_device_unregister(struct hv_device *device_obj) /* - * VMBUS is an acpi enumerated device. Get the the information we + * VMBUS is an acpi enumerated device. Get the information we * need from DSDT. */ - +#define VTPM_BASE_ADDRESS 0xfed4 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) { + resource_size_t start = 0; + resource_size_t end = 0; + struct resource *new_res; + struct resource **old_res = &hyperv_mmio; + struct resource **prev_res = NULL; + switch (res->type) { case ACPI_RESOURCE_TYPE_IRQ: irq = res->data.irq.interrupts[0]; + return AE_OK; + + /* +* "Address" descriptors are for bus windows. Ignore +* "memory" descriptors, which are for registers on +* devices. +*/ + case ACPI_RESOURCE_TYPE_ADDRESS32: + start = res->data.address32.address.minimum; + end = res->data.address32.address.maximum; break; case ACPI_RESOURCE_TYPE_ADDRESS64: - hyperv_mmio.start = res->data.address64.address.minimum; - hyperv_mmio.end = res->data.address64.address.maximum; + start = res->data.address64.address.minimum; + end = res->data.address64.address.maximum; break; + + default: + /* Unused resource type */ + return AE_OK; + } + /* +* Ignore ranges that are below 1MB, as they're not +* necessary or useful here. +*/ + if (end < 0x10) + return AE_OK; + + new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC); + if (!new_res) + return AE_NO_MEMORY; + + /* If this range overlaps the virtual TPM, truncate it. */ + if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS) + end = VTPM_BASE_ADDRESS; + + new_res->name = "hyperv mmio"; + new_res->flags = IORESOURCE_MEM; + new_res->start = start; + new_res->end = end; + + do { + if (!*old_res) { + *old_res = new_res; + break; + } + + if ((*old_res)->end < new_res->start) { + new_res->sibling = *old_res; + if (prev_res) + (*prev_res)->sibling = new_res; + *old_res = new_res; + break; + } + + prev_res = old_res; + old_res = &(*old_res)->sibling; + + } while (1); return AE_OK; } +static int vmbus_acpi_remove(struct acpi_device *device) +{ + struct resource *cur_res; + struct resource *next_res; + + if (hyperv_mmio) { + for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) { + next_res = cur_res->sibling; + kfree(cur_res); + } + } + + return 0; +} + static int vmbus_acpi_add(struct acpi_device *device) { acpi_status result; int ret_val = -ENODEV; + struct acpi_device *ancestor; hv_acpi_dev = device; @@ -1046,35 +1118,27 @@ static int vmbus_acpi_add(struct acpi_device *device) if (ACPI_FAILURE(result)) goto acpi_walk_err;
[PATCH 17/28] Drivers: hv: vmbus: Consider ND NIC in binding channels to CPUs
We cycle through all the "high performance" channels to distribute load across the available CPUs. Process the NetworkDirect as a high performance device. Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel_mgmt.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 00ba3f3..30613df 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -347,6 +347,7 @@ enum { IDE = 0, SCSI, NIC, + ND_NIC, MAX_PERF_CHN, }; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 04/28] Drivers: hv: don't do hypercalls when hypercall_page is NULL
From: Vitaly Kuznetsov At the very late stage of kexec a driver (which are not being unloaded) can try to post a message or signal an event. This will crash the kernel as we already did hv_cleanup() and the hypercall page is NULL. Move all common (between 32 and 64 bit code) declarations to the beginning of the do_hypercall() function. Unfortunately we have to write the !hypercall_page check twice to not mix declarations and code. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv.c | 13 - 1 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 5b87042..41d8072 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -93,11 +93,14 @@ static int query_hypervisor_info(void) */ static u64 do_hypercall(u64 control, void *input, void *output) { -#ifdef CONFIG_X86_64 - u64 hv_status = 0; u64 input_address = (input) ? virt_to_phys(input) : 0; u64 output_address = (output) ? virt_to_phys(output) : 0; void *hypercall_page = hv_context.hypercall_page; +#ifdef CONFIG_X86_64 + u64 hv_status = 0; + + if (!hypercall_page) + return (u64)ULLONG_MAX; __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); __asm__ __volatile__("call *%3" : "=a" (hv_status) : @@ -112,13 +115,13 @@ static u64 do_hypercall(u64 control, void *input, void *output) u32 control_lo = control & 0x; u32 hv_status_hi = 1; u32 hv_status_lo = 1; - u64 input_address = (input) ? virt_to_phys(input) : 0; u32 input_address_hi = input_address >> 32; u32 input_address_lo = input_address & 0x; - u64 output_address = (output) ? virt_to_phys(output) : 0; u32 output_address_hi = output_address >> 32; u32 output_address_lo = output_address & 0x; - void *hypercall_page = hv_context.hypercall_page; + + if (!hypercall_page) + return (u64)ULLONG_MAX; __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), "=a"(hv_status_lo) : "d" (control_hi), -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 28/28] Drivers: hv: vmbus: use cpu_hotplug_enable/disable
From: Vitaly Kuznetsov Commit e513229b4c38 ("Drivers: hv: vmbus: prevent cpu offlining on newer hypervisors") was altering smp_ops.cpu_disable to prevent CPU offlining. We can bo better by using cpu_hotplug_enable/disable functions instead of such hard-coding. Reported-by: Radim Kr.má Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/vmbus_drv.c | 38 -- 1 files changed, 4 insertions(+), 34 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 45d6d7a..f19b6f7 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -828,38 +828,6 @@ static void vmbus_isr(void) } } -#ifdef CONFIG_HOTPLUG_CPU -static int hyperv_cpu_disable(void) -{ - return -ENOSYS; -} - -static void hv_cpu_hotplug_quirk(bool vmbus_loaded) -{ - static void *previous_cpu_disable; - - /* -* Offlining a CPU when running on newer hypervisors (WS2012R2, Win8, -* ...) is not supported at this moment as channel interrupts are -* distributed across all of them. -*/ - - if ((vmbus_proto_version == VERSION_WS2008) || - (vmbus_proto_version == VERSION_WIN7)) - return; - - if (vmbus_loaded) { - previous_cpu_disable = smp_ops.cpu_disable; - smp_ops.cpu_disable = hyperv_cpu_disable; - pr_notice("CPU offlining is not supported by hypervisor\n"); - } else if (previous_cpu_disable) - smp_ops.cpu_disable = previous_cpu_disable; -} -#else -static void hv_cpu_hotplug_quirk(bool vmbus_loaded) -{ -} -#endif /* * vmbus_bus_init -Main vmbus driver initialization routine. @@ -901,7 +869,8 @@ static int vmbus_bus_init(int irq) if (ret) goto err_alloc; - hv_cpu_hotplug_quirk(true); + if (vmbus_proto_version > VERSION_WIN7) + cpu_hotplug_disable(); /* * Only register if the crash MSRs are available @@ -1364,7 +1333,8 @@ static void __exit vmbus_exit(void) } hv_synic_free(); acpi_bus_unregister_driver(&vmbus_acpi_driver); - hv_cpu_hotplug_quirk(false); + if (vmbus_proto_version > VERSION_WIN7) + cpu_hotplug_enable(); } -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 27/28] cpu-hotplug: export cpu_hotplug_enable/cpu_hotplug_disable
From: Vitaly Kuznetsov Hyper-V module needs to disable cpu hotplug (offlining) as there is no support from hypervisor side to reassign already opened event channels to a different CPU. Currently it is been done by altering smp_ops.cpu_disable but it is hackish. Signed-off-by: Vitaly Kuznetsov Reviewed-by: Thomas Gleixner Signed-off-by: K. Y. Srinivasan --- kernel/cpu.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/kernel/cpu.c b/kernel/cpu.c index 1225fc2..18f00ae 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -194,6 +194,7 @@ void cpu_hotplug_disable(void) cpu_hotplug_disabled++; cpu_maps_update_done(); } +EXPORT_SYMBOL_GPL(cpu_hotplug_disable); void cpu_hotplug_enable(void) { @@ -201,7 +202,7 @@ void cpu_hotplug_enable(void) WARN_ON(--cpu_hotplug_disabled < 0); cpu_maps_update_done(); } - +EXPORT_SYMBOL_GPL(cpu_hotplug_enable); #endif /* CONFIG_HOTPLUG_CPU */ /* Need to know about CPUs going up/down? */ -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 21/28] drivers/hv: Migrate to new 'set-state' interface
From: Viresh Kumar Migrate hv driver to the new 'set-state' interface provided by clockevents core, the earlier 'set-mode' interface is marked obsolete now. This also enables us to implement callbacks for new states of clockevent devices, for example: ONESHOT_STOPPED. Cc: "K. Y. Srinivasan" Cc: Haiyang Zhang Cc: de...@linuxdriverproject.org Signed-off-by: Viresh Kumar Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv.c | 45 +++-- 1 files changed, 19 insertions(+), 26 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index fd93cfd..c641faf 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -274,7 +274,7 @@ static int hv_ce_set_next_event(unsigned long delta, { cycle_t current_tick; - WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT); + WARN_ON(!clockevent_state_oneshot(evt)); rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick); current_tick += delta; @@ -282,31 +282,24 @@ static int hv_ce_set_next_event(unsigned long delta, return 0; } -static void hv_ce_setmode(enum clock_event_mode mode, - struct clock_event_device *evt) +static int hv_ce_shutdown(struct clock_event_device *evt) +{ + wrmsrl(HV_X64_MSR_STIMER0_COUNT, 0); + wrmsrl(HV_X64_MSR_STIMER0_CONFIG, 0); + + return 0; +} + +static int hv_ce_set_oneshot(struct clock_event_device *evt) { union hv_timer_config timer_cfg; - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - /* unsupported */ - break; - - case CLOCK_EVT_MODE_ONESHOT: - timer_cfg.enable = 1; - timer_cfg.auto_enable = 1; - timer_cfg.sintx = VMBUS_MESSAGE_SINT; - wrmsrl(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64); - break; - - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - wrmsrl(HV_X64_MSR_STIMER0_COUNT, 0); - wrmsrl(HV_X64_MSR_STIMER0_CONFIG, 0); - break; - case CLOCK_EVT_MODE_RESUME: - break; - } + timer_cfg.enable = 1; + timer_cfg.auto_enable = 1; + timer_cfg.sintx = VMBUS_MESSAGE_SINT; + wrmsrl(HV_X64_MSR_STIMER0_CONFIG, timer_cfg.as_uint64); + + return 0; } static void hv_init_clockevent_device(struct clock_event_device *dev, int cpu) @@ -321,7 +314,8 @@ static void hv_init_clockevent_device(struct clock_event_device *dev, int cpu) * references to the hv_vmbus module making it impossible to unload. */ - dev->set_mode = hv_ce_setmode; + dev->set_state_shutdown = hv_ce_shutdown; + dev->set_state_oneshot = hv_ce_set_oneshot; dev->set_next_event = hv_ce_set_next_event; } @@ -515,8 +509,7 @@ void hv_synic_cleanup(void *arg) /* Turn off clockevent device */ if (ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE) - hv_ce_setmode(CLOCK_EVT_MODE_SHUTDOWN, - hv_context.clk_evt[cpu]); + hv_ce_shutdown(hv_context.clk_evt[cpu]); rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 22/28] Drivers: hv: vmbus: Implement a clocksource based on the TSC page
The current Hyper-V clock source is based on the per-partition reference counter and this counter is being accessed via s synthetic MSR - HV_X64_MSR_TIME_REF_COUNT. Hyper-V has a more efficient way of computing the per-partition reference counter value that does not involve reading a synthetic MSR. We implement a time source based on this mechanism. Tested-by: Vivek Yadav Signed-off-by: K. Y. Srinivasan --- arch/x86/include/uapi/asm/hyperv.h |2 + drivers/hv/hv.c| 83 drivers/hv/hyperv_vmbus.h |9 3 files changed, 94 insertions(+), 0 deletions(-) diff --git a/arch/x86/include/uapi/asm/hyperv.h b/arch/x86/include/uapi/asm/hyperv.h index 8fba544..89f15e3 100644 --- a/arch/x86/include/uapi/asm/hyperv.h +++ b/arch/x86/include/uapi/asm/hyperv.h @@ -27,6 +27,8 @@ #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) +/* Partition reference TSC MSR is available */ +#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9) /* A partition's reference time stamp counter (TSC) page */ #define HV_X64_MSR_REFERENCE_TSC 0x4021 diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index c641faf..6341be8 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -133,6 +133,56 @@ static u64 do_hypercall(u64 control, void *input, void *output) #endif /* !x86_64 */ } +#ifdef CONFIG_X86_64 +static cycle_t read_hv_clock_tsc(struct clocksource *arg) +{ + cycle_t current_tick; + struct ms_hyperv_tsc_page *tsc_pg = hv_context.tsc_page; + + if (tsc_pg->tsc_sequence != -1) { + /* +* Use the tsc page to compute the value. +*/ + + while (1) { + cycle_t tmp; + u32 sequence = tsc_pg->tsc_sequence; + u64 cur_tsc; + u64 scale = tsc_pg->tsc_scale; + s64 offset = tsc_pg->tsc_offset; + + rdtscll(cur_tsc); + /* current_tick = ((cur_tsc *scale) >> 64) + offset */ + asm("mulq %3" + : "=d" (current_tick), "=a" (tmp) + : "a" (cur_tsc), "r" (scale)); + + current_tick += offset; + if (tsc_pg->tsc_sequence == sequence) + return current_tick; + + if (tsc_pg->tsc_sequence != -1) + continue; + /* +* Fallback using MSR method. +*/ + break; + } + } + rdmsrl(HV_X64_MSR_TIME_REF_COUNT, current_tick); + return current_tick; +} + +static struct clocksource hyperv_cs_tsc = { + .name = "hyperv_clocksource_tsc_page", + .rating = 425, + .read = read_hv_clock_tsc, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; +#endif + + /* * hv_init - Main initialization routine. * @@ -142,7 +192,9 @@ int hv_init(void) { int max_leaf; union hv_x64_msr_hypercall_contents hypercall_msr; + union hv_x64_msr_hypercall_contents tsc_msr; void *virtaddr = NULL; + void *va_tsc = NULL; memset(hv_context.synic_event_page, 0, sizeof(void *) * NR_CPUS); memset(hv_context.synic_message_page, 0, @@ -186,6 +238,22 @@ int hv_init(void) hv_context.hypercall_page = virtaddr; +#ifdef CONFIG_X86_64 + if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) { + va_tsc = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL); + if (!va_tsc) + goto cleanup; + hv_context.tsc_page = va_tsc; + + rdmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64); + + tsc_msr.enable = 1; + tsc_msr.guest_physical_address = vmalloc_to_pfn(va_tsc); + + wrmsrl(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64); + clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100); + } +#endif return 0; cleanup: @@ -219,6 +287,21 @@ void hv_cleanup(void) vfree(hv_context.hypercall_page); hv_context.hypercall_page = NULL; } + +#ifdef CONFIG_X86_64 + /* +* Cleanup the TSC page based CS. +*/ + if (ms_hyperv.features & HV_X64_MSR_REFERENCE_TSC_AVAILABLE) { + clocksource_change_rating(&hyperv_cs_tsc, 10); + clocksource_unregister(&hyperv_cs_tsc); + + hypercall_msr.as_uint64 = 0; + wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64); + vfree(hv
[PATCH 13/28] hv: util: checking the wrong variable
From: Dan Carpenter We don't catch this allocation failure because there is a typo and we check the wrong variable. Fixes: 14b50f80c32d ('Drivers: hv: util: introduce hv_utils_transport abstraction') Signed-off-by: Dan Carpenter Reviewed-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv_utils_transport.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index ea7ba5e..6a9d80a 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -186,7 +186,7 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) return -EINVAL; } else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { cn_msg = kzalloc(sizeof(*cn_msg) + len, GFP_ATOMIC); - if (!msg) + if (!cn_msg) return -ENOMEM; cn_msg->id.idx = hvt->cn_id.idx; cn_msg->id.val = hvt->cn_id.val; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 25/28] Drivers: hv: vmbus: document the VMBus sysfs files
From: Dexuan Cui The 4 sysfs files should be stable ABIs to the user space. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- Documentation/ABI/stable/sysfs-bus-vmbus | 29 + MAINTAINERS |1 + 2 files changed, 30 insertions(+), 0 deletions(-) create mode 100644 Documentation/ABI/stable/sysfs-bus-vmbus diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus b/Documentation/ABI/stable/sysfs-bus-vmbus new file mode 100644 index 000..636e938 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-bus-vmbus @@ -0,0 +1,29 @@ +What: /sys/bus/vmbus/devices/vmbus_*/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 +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 +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 +Date: Jul 2015 +KernelVersion: 4.2.0 +Contact: K. Y. Srinivasan +Description: The mapping of which primary/sub channels are bound to which + Virtual Processors. + Format: +Users: tools/hv/lsvmbus diff --git a/MAINTAINERS b/MAINTAINERS index fd60784..45ef1e1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4956,6 +4956,7 @@ F:drivers/scsi/storvsc_drv.c F: drivers/video/fbdev/hyperv_fb.c F: include/linux/hyperv.h F: tools/hv/ +F: Documentation/ABI/stable/sysfs-bus-vmbus I2C OVER PARALLEL PORT M: Jean Delvare -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 15/28] Drivers: hv: vmbus: don't send CHANNELMSG_UNLOAD on pre-Win2012R2 hosts
From: Vitaly Kuznetsov Pre-Win2012R2 hosts don't properly handle CHANNELMSG_UNLOAD and wait_for_completion() hangs. Avoid sending such request on old hosts. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel_mgmt.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 4506a66..00ba3f3 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -469,6 +469,10 @@ void vmbus_initiate_unload(void) { struct vmbus_channel_message_header hdr; + /* Pre-Win2012R2 hosts don't support reconnect */ + if (vmbus_proto_version < VERSION_WIN8_1) + return; + init_completion(&vmbus_connection.unload_event); memset(&hdr, 0, sizeof(struct vmbus_channel_message_header)); hdr.msgtype = CHANNELMSG_UNLOAD; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 23/28] Drivers: hv: vmbus: add a sysfs attr to show the binding of channel/VP
From: Dexuan Cui This is useful to analyze performance issue. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- drivers/hv/vmbus_drv.c | 38 ++ 1 files changed, 38 insertions(+), 0 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 8c3eaee..45d6d7a 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -441,6 +441,43 @@ static ssize_t in_write_bytes_avail_show(struct device *dev, } static DEVICE_ATTR_RO(in_write_bytes_avail); +static ssize_t channel_vp_mapping_show(struct device *dev, + struct device_attribute *dev_attr, + char *buf) +{ + struct hv_device *hv_dev = device_to_hv_device(dev); + struct vmbus_channel *channel = hv_dev->channel, *cur_sc; + unsigned long flags; + int buf_size = PAGE_SIZE, n_written, tot_written; + struct list_head *cur; + + if (!channel) + return -ENODEV; + + tot_written = snprintf(buf, buf_size, "%u:%u\n", + channel->offermsg.child_relid, channel->target_cpu); + + spin_lock_irqsave(&channel->lock, flags); + + list_for_each(cur, &channel->sc_list) { + if (tot_written >= buf_size - 1) + break; + + cur_sc = list_entry(cur, struct vmbus_channel, sc_list); + n_written = scnprintf(buf + tot_written, +buf_size - tot_written, +"%u:%u\n", +cur_sc->offermsg.child_relid, +cur_sc->target_cpu); + tot_written += n_written; + } + + spin_unlock_irqrestore(&channel->lock, flags); + + return tot_written; +} +static DEVICE_ATTR_RO(channel_vp_mapping); + /* Set up per device attributes in /sys/bus/vmbus/devices/ */ static struct attribute *vmbus_attrs[] = { &dev_attr_id.attr, @@ -465,6 +502,7 @@ static struct attribute *vmbus_attrs[] = { &dev_attr_in_write_index.attr, &dev_attr_in_read_bytes_avail.attr, &dev_attr_in_write_bytes_avail.attr, + &dev_attr_channel_vp_mapping.attr, NULL, }; ATTRIBUTE_GROUPS(vmbus); -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 02/28] kexec: define kexec_in_progress in !CONFIG_KEXEC case
From: Vitaly Kuznetsov If some piece of code wants to check kexec_in_progress it has to be put in #ifdef CONFIG_KEXEC block to not break the build in !CONFIG_KEXEC case. Overcome this limitation by defining kexec_in_progress to false. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- include/linux/kexec.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index e804306..b63218f 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -323,6 +323,7 @@ struct pt_regs; struct task_struct; static inline void crash_kexec(struct pt_regs *regs) { } static inline int kexec_should_crash(struct task_struct *p) { return 0; } +#define kexec_in_progress false #endif /* CONFIG_KEXEC */ #endif /* !defined(__ASSEBMLY__) */ -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 01/28] Drivers: hv: vmbus: remove hv_synic_free_cpu() call from hv_synic_cleanup()
From: Vitaly Kuznetsov We already have hv_synic_free() which frees all per-cpu pages for all CPUs, let's remove the hv_synic_free_cpu() call from hv_synic_cleanup() so it will be possible to do separate cleanup (writing to MSRs) and final freeing. This is going to be used to assist kexec. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv.c|2 -- drivers/hv/vmbus_drv.c |1 + 2 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index d3943bc..5b87042 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -530,6 +530,4 @@ void hv_synic_cleanup(void *arg) rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64); sctrl.enable = 0; wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64); - - hv_synic_free_cpu(cpu); } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index cf20400..00d5158 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1120,6 +1120,7 @@ static void __exit vmbus_exit(void) tasklet_kill(hv_context.event_dpc[cpu]); smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); } + hv_synic_free(); acpi_bus_unregister_driver(&vmbus_acpi_driver); hv_cpu_hotplug_quirk(false); } -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 20/28] Drivers: hv_vmbus: Fix signal to host condition
From: Christopher Oo Fixes a bug where previously hv_ringbuffer_read would pass in the old number of bytes available to read instead of the expected old read index when calculating when to signal to the host that the ringbuffer is empty. Since the previous write size is already saved, also changes the hv_need_to_signal_on_read to use the previously read value rather than recalculating it. Signed-off-by: Christopher Oo Signed-off-by: K. Y. Srinivasan --- drivers/hv/ring_buffer.c | 14 +++--- 1 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 6361d12..70a1a9a 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -103,10 +103,9 @@ static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi) *there is room for the producer to send the pending packet. */ -static bool hv_need_to_signal_on_read(u32 old_rd, -struct hv_ring_buffer_info *rbi) +static bool hv_need_to_signal_on_read(u32 prev_write_sz, + struct hv_ring_buffer_info *rbi) { - u32 prev_write_sz; u32 cur_write_sz; u32 r_size; u32 write_loc = rbi->ring_buffer->write_index; @@ -123,10 +122,6 @@ static bool hv_need_to_signal_on_read(u32 old_rd, cur_write_sz = write_loc >= read_loc ? r_size - (write_loc - read_loc) : read_loc - write_loc; - prev_write_sz = write_loc >= old_rd ? r_size - (write_loc - old_rd) : - old_rd - write_loc; - - if ((prev_write_sz < pending_sz) && (cur_write_sz >= pending_sz)) return true; @@ -517,7 +512,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, u32 next_read_location = 0; u64 prev_indices = 0; unsigned long flags; - u32 old_read; if (buflen <= 0) return -EINVAL; @@ -528,8 +522,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, &bytes_avail_toread, &bytes_avail_towrite); - old_read = bytes_avail_toread; - /* Make sure there is something to read */ if (bytes_avail_toread < buflen) { spin_unlock_irqrestore(&inring_info->ring_lock, flags); @@ -560,7 +552,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, spin_unlock_irqrestore(&inring_info->ring_lock, flags); - *signal = hv_need_to_signal_on_read(old_read, inring_info); + *signal = hv_need_to_signal_on_read(bytes_avail_towrite, inring_info); return 0; } -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 03/28] Drivers: hv: vmbus: add special kexec handler
From: Vitaly Kuznetsov When general-purpose kexec (not kdump) is being performed in Hyper-V guest the newly booted kernel fails with an MCE error coming from the host. It is the same error which was fixed in the "Drivers: hv: vmbus: Implement the protocol for tearing down vmbus state" commit - monitor pages remain special and when they're being written to (as the new kernel doesn't know these pages are special) bad things happen. We need to perform some minimalistic cleanup before booting a new kernel on kexec. To do so we need to register a special machine_ops.shutdown handler to be executed before the native_machine_shutdown(). Registering a shutdown notification handler via the register_reboot_notifier() call is not sufficient as it happens to early for our purposes. machine_ops is not being exported to modules (and I don't think we want to export it) so let's do this in mshyperv.c The minimalistic cleanup consists of cleaning up clockevents, synic MSRs, guest os id MSR, and hypercall MSR. Kdump doesn't require all this stuff as it lives in a separate memory space. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- arch/x86/include/asm/mshyperv.h |2 ++ arch/x86/kernel/cpu/mshyperv.c | 24 drivers/hv/vmbus_drv.c | 14 ++ 3 files changed, 40 insertions(+), 0 deletions(-) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index c163215..d3db910 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -20,4 +20,6 @@ void hyperv_vector_handler(struct pt_regs *regs); void hv_setup_vmbus_irq(void (*handler)(void)); void hv_remove_vmbus_irq(void); +void hv_setup_kexec_handler(void (*handler)(void)); +void hv_remove_kexec_handler(void); #endif diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index aad4bd8..fa483ed 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -28,10 +29,13 @@ #include #include #include +#include struct ms_hyperv_info ms_hyperv; EXPORT_SYMBOL_GPL(ms_hyperv); +static void (*hv_kexec_handler)(void); + #if IS_ENABLED(CONFIG_HYPERV) static void (*vmbus_handler)(void); @@ -67,8 +71,27 @@ void hv_remove_vmbus_irq(void) } EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq); EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq); + +void hv_setup_kexec_handler(void (*handler)(void)) +{ + hv_kexec_handler = handler; +} +EXPORT_SYMBOL_GPL(hv_setup_kexec_handler); + +void hv_remove_kexec_handler(void) +{ + hv_kexec_handler = NULL; +} +EXPORT_SYMBOL_GPL(hv_remove_kexec_handler); #endif +static void hv_machine_shutdown(void) +{ + if (kexec_in_progress && hv_kexec_handler) + hv_kexec_handler(); + native_machine_shutdown(); +} + static uint32_t __init ms_hyperv_platform(void) { u32 eax; @@ -141,6 +164,7 @@ static void __init ms_hyperv_init_platform(void) no_timer_check = 1; #endif + machine_ops.shutdown = hv_machine_shutdown; } const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 00d5158..31748a2 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1060,6 +1060,17 @@ static struct acpi_driver vmbus_acpi_driver = { }, }; +static void hv_kexec_handler(void) +{ + int cpu; + + hv_synic_clockevents_cleanup(); + vmbus_initiate_unload(); + for_each_online_cpu(cpu) + smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1); + hv_cleanup(); +}; + static int __init hv_acpi_init(void) { int ret, t; @@ -1092,6 +1103,8 @@ static int __init hv_acpi_init(void) if (ret) goto cleanup; + hv_setup_kexec_handler(hv_kexec_handler); + return 0; cleanup: @@ -1104,6 +1117,7 @@ static void __exit vmbus_exit(void) { int cpu; + hv_remove_kexec_handler(); vmbus_connection.conn_state = DISCONNECTED; hv_synic_clockevents_cleanup(); vmbus_disconnect(); -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 07/28] Drivers: hv: kvp: check kzalloc return value
From: Vitaly Kuznetsov kzalloc() return value check was accidentally lost in 11bc3a5fa91f: "Drivers: hv: kvp: convert to hv_utils_transport" commit. We don't need to reset kvp_transaction.state here as we have the kvp_timeout_func() timeout function and in case we're in OOM situation it is preferable to wait. Reported-by: Dan Carpenter Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv_kvp.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index d85798d..74c38a9 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -353,6 +353,9 @@ kvp_send_key(struct work_struct *dummy) return; message = kzalloc(sizeof(*message), GFP_KERNEL); + if (!message) + return; + message->kvp_hdr.operation = operation; message->kvp_hdr.pool = pool; in_msg = kvp_transaction.kvp_msg; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 12/28] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus
From: ja...@microsoft.com This patch deletes the logic from hyperv_fb which picked a range of MMIO space for the frame buffer and adds new logic to hv_vmbus which picks ranges for child drivers. The new logic isn't quite the same as the old, as it considers more possible ranges. Signed-off-by: Jake Oshins Signed-off-by: K. Y. Srinivasan --- drivers/hv/vmbus_drv.c | 88 +-- drivers/video/fbdev/hyperv_fb.c | 46 +--- include/linux/hyperv.h |7 ++- 3 files changed, 110 insertions(+), 31 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 21bb287..83759c1 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "hyperv_vmbus.h" @@ -103,7 +104,6 @@ static struct notifier_block hyperv_panic_block = { }; struct resource *hyperv_mmio; -EXPORT_SYMBOL_GPL(hyperv_mmio); static int vmbus_exists(void) { @@ -891,8 +891,8 @@ err_cleanup: } /** - * __vmbus_child_driver_register - Register a vmbus's driver - * @drv: Pointer to driver structure you want to register + * __vmbus_child_driver_register() - Register a vmbus's driver + * @hv_driver: Pointer to driver structure you want to register * @owner: owner module of the drv * @mod_name: module name string * @@ -924,7 +924,8 @@ EXPORT_SYMBOL_GPL(__vmbus_driver_register); /** * vmbus_driver_unregister() - Unregister a vmbus's driver - * @drv: Pointer to driver structure you want to un-register + * @hv_driver: Pointer to driver structure you want to + * un-register * * Un-register the given driver that was previous registered with a call to * vmbus_driver_register() @@ -1104,6 +1105,85 @@ static int vmbus_acpi_remove(struct acpi_device *device) return 0; } +/** + * vmbus_allocate_mmio() - Pick a memory-mapped I/O range. + * @new: If successful, supplied a pointer to the + * allocated MMIO space. + * @device_obj:Identifies the caller + * @min: Minimum guest physical address of the + * allocation + * @max: Maximum guest physical address + * @size: Size of the range to be allocated + * @align: Alignment of the range to be allocated + * @fb_overlap_ok: Whether this allocation can be allowed + * to overlap the video frame buffer. + * + * This function walks the resources granted to VMBus by the + * _CRS object in the ACPI namespace underneath the parent + * "bridge" whether that's a root PCI bus in the Generation 1 + * case or a Module Device in the Generation 2 case. It then + * attempts to allocate from the global MMIO pool in a way that + * matches the constraints supplied in these parameters and by + * that _CRS. + * + * Return: 0 on success, -errno on failure + */ +int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, + resource_size_t min, resource_size_t max, + resource_size_t size, resource_size_t align, + bool fb_overlap_ok) +{ + struct resource *iter; + resource_size_t range_min, range_max, start, local_min, local_max; + const char *dev_n = dev_name(&device_obj->device); + u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1); + int i; + + for (iter = hyperv_mmio; iter; iter = iter->sibling) { + if ((iter->start >= max) || (iter->end <= min)) + continue; + + range_min = iter->start; + range_max = iter->end; + + /* If this range overlaps the frame buffer, split it into + two tries. */ + for (i = 0; i < 2; i++) { + local_min = range_min; + local_max = range_max; + if (fb_overlap_ok || (range_min >= fb_end) || + (range_max <= screen_info.lfb_base)) { + i++; + } else { + if ((range_min <= screen_info.lfb_base) && + (range_max >= screen_info.lfb_base)) { + /* +* The frame buffer is in this window, +* so trim this into the part that +* preceeds the frame buffer. +*/ + local_max = screen_info.lfb_base - 1; + range_min = fb_end; + } else { + range_min = fb_end; + continue; + } + } + + start
[PATCH 19/28] Drivers: hv: vmbus: Further improve CPU affiliation logic
From: Dexuan Cui Keep track of CPU affiliations of sub-channels within the scope of the primary channel. This will allow us to better distribute the load amongst available CPUs. Signed-off-by: Dexuan Cui Signed-off-by: K. Y. Srinivasan --- drivers/hv/channel_mgmt.c | 20 ++-- include/linux/hyperv.h|1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 39c5afc..2f9aead 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -448,8 +448,24 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui cpumask_xor(&available_mask, alloced_mask, cpumask_of_node(primary->numa_node)); - cur_cpu = cpumask_next(-1, &available_mask); - cpumask_set_cpu(cur_cpu, alloced_mask); + cur_cpu = -1; + while (true) { + cur_cpu = cpumask_next(cur_cpu, &available_mask); + if (cur_cpu >= nr_cpu_ids) { + cur_cpu = -1; + cpumask_copy(&available_mask, +cpumask_of_node(primary->numa_node)); + continue; + } + + if (!cpumask_test_cpu(cur_cpu, + &primary->alloced_cpus_in_node)) { + cpumask_set_cpu(cur_cpu, + &primary->alloced_cpus_in_node); + cpumask_set_cpu(cur_cpu, alloced_mask); + break; + } + } channel->target_cpu = cur_cpu; channel->target_vp = hv_context.vp_index[cur_cpu]; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 5a3df5a..54733d5 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -699,6 +699,7 @@ struct vmbus_channel { /* * State to manage the CPU affiliation of channels. */ + struct cpumask alloced_cpus_in_node; int numa_node; /* * Support for sub-channels. For high performance devices, -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 08/28] Drivers: hv: fcopy: dynamically allocate smsg_out in fcopy_send_data()
From: Vitaly Kuznetsov struct hv_start_fcopy is too big to be on stack on i386, the following warning is reported: >> drivers/hv/hv_fcopy.c:159:1: warning: the frame size of 1088 bytes is larger >> than 1024 bytes [-Wframe-larger-than=] Reported-by: kbuild test robot Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv_fcopy.c | 21 + 1 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/hv/hv_fcopy.c b/drivers/hv/hv_fcopy.c index b50dd33..db4b887 100644 --- a/drivers/hv/hv_fcopy.c +++ b/drivers/hv/hv_fcopy.c @@ -116,7 +116,7 @@ static int fcopy_handle_handshake(u32 version) static void fcopy_send_data(struct work_struct *dummy) { - struct hv_start_fcopy smsg_out; + struct hv_start_fcopy *smsg_out = NULL; int operation = fcopy_transaction.fcopy_msg->operation; struct hv_start_fcopy *smsg_in; void *out_src; @@ -136,21 +136,24 @@ static void fcopy_send_data(struct work_struct *dummy) switch (operation) { case START_FILE_COPY: out_len = sizeof(struct hv_start_fcopy); - memset(&smsg_out, 0, out_len); - smsg_out.hdr.operation = operation; + smsg_out = kzalloc(sizeof(*smsg_out), GFP_KERNEL); + if (!smsg_out) + return; + + smsg_out->hdr.operation = operation; smsg_in = (struct hv_start_fcopy *)fcopy_transaction.fcopy_msg; utf16s_to_utf8s((wchar_t *)smsg_in->file_name, W_MAX_PATH, UTF16_LITTLE_ENDIAN, - (__u8 *)&smsg_out.file_name, W_MAX_PATH - 1); + (__u8 *)&smsg_out->file_name, W_MAX_PATH - 1); utf16s_to_utf8s((wchar_t *)smsg_in->path_name, W_MAX_PATH, UTF16_LITTLE_ENDIAN, - (__u8 *)&smsg_out.path_name, W_MAX_PATH - 1); + (__u8 *)&smsg_out->path_name, W_MAX_PATH - 1); - smsg_out.copy_flags = smsg_in->copy_flags; - smsg_out.file_size = smsg_in->file_size; - out_src = &smsg_out; + smsg_out->copy_flags = smsg_in->copy_flags; + smsg_out->file_size = smsg_in->file_size; + out_src = smsg_out; break; default: @@ -168,6 +171,8 @@ static void fcopy_send_data(struct work_struct *dummy) fcopy_transaction.state = HVUTIL_READY; } } + kfree(smsg_out); + return; } -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 06/28] Drivers: hv: vmbus: prefer 'die' notification chain to 'panic'
From: Vitaly Kuznetsov current_pt_regs() sometimes returns regs of the userspace process and in case of a kernel crash this is not what we need to report. E.g. when we trigger crash with sysrq we see the following: ... RIP: 0010:[] [] sysrq_handle_crash+0x16/0x20 RSP: 0018:8800db0a7d88 EFLAGS: 00010246 RAX: 000f RBX: 820a0660 RCX: ... at the same time current_pt_regs() give us: ip=7f899ea7e9e0, ax=ffda, bx=26c81a0, cx=7f899ea7e9e0, ... These registers come from the userspace process triggered the crash. As we don't even know which process it was this information is rather useless. When kernel crash happens through 'die' proper regs are being passed to all receivers on the die_chain (and panic_notifier_list is being notified with the string passed to panic() only). If panic() is called manually (e.g. on BUG()) we won't get 'die' notification so keep the 'panic' notification reporter as well but guard against double reporting. Signed-off-by: Vitaly Kuznetsov Signed-off-by: K. Y. Srinivasan --- drivers/hv/vmbus_drv.c | 40 1 files changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 1ed9b32..b6114cc 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "hyperv_vmbus.h" static struct acpi_device *hv_acpi_dev; @@ -48,12 +49,18 @@ static struct completion probe_event; static int irq; -static int hyperv_panic_event(struct notifier_block *nb, - unsigned long event, void *ptr) +static void hyperv_report_panic(struct pt_regs *regs) { - struct pt_regs *regs; + static bool panic_reported; - regs = current_pt_regs(); + /* +* We prefer to report panic on 'die' chain as we have proper +* registers to report, but if we miss it (e.g. on BUG()) we need +* to report it on 'panic'. +*/ + if (panic_reported) + return; + panic_reported = true; wrmsrl(HV_X64_MSR_CRASH_P0, regs->ip); wrmsrl(HV_X64_MSR_CRASH_P1, regs->ax); @@ -65,9 +72,32 @@ static int hyperv_panic_event(struct notifier_block *nb, * Let Hyper-V know there is crash data available */ wrmsrl(HV_X64_MSR_CRASH_CTL, HV_CRASH_CTL_CRASH_NOTIFY); +} + +static int hyperv_panic_event(struct notifier_block *nb, unsigned long val, + void *args) +{ + struct pt_regs *regs; + + regs = current_pt_regs(); + + hyperv_report_panic(regs); return NOTIFY_DONE; } +static int hyperv_die_event(struct notifier_block *nb, unsigned long val, + void *args) +{ + struct die_args *die = (struct die_args *)args; + struct pt_regs *regs = die->regs; + + hyperv_report_panic(regs); + return NOTIFY_DONE; +} + +static struct notifier_block hyperv_die_block = { + .notifier_call = hyperv_die_event, +}; static struct notifier_block hyperv_panic_block = { .notifier_call = hyperv_panic_event, }; @@ -842,6 +872,7 @@ static int vmbus_bus_init(int irq) * Only register if the crash MSRs are available */ if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { + register_die_notifier(&hyperv_die_block); atomic_notifier_chain_register(&panic_notifier_list, &hyperv_panic_block); } @@ -1139,6 +1170,7 @@ static void __exit vmbus_exit(void) tasklet_kill(&msg_dpc); vmbus_free_channels(); if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { + unregister_die_notifier(&hyperv_die_block); atomic_notifier_chain_unregister(&panic_notifier_list, &hyperv_panic_block); } -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 16/28] mshyperv: fix recognition of Hyper-V guest crash MSR's
From: Denis V. Lunev Hypervisor Top Level Functional Specification v3.1/4.0 notes that cpuid (0x4003) EDX's 10th bit should be used to check that Hyper-V guest crash MSR's functionality available. This patch should fix this recognition. Currently the code checks EAX register instead of EDX. Signed-off-by: Andrey Smetanin Signed-off-by: Denis V. Lunev Signed-off-by: K. Y. Srinivasan --- arch/x86/include/asm/mshyperv.h |1 + arch/x86/kernel/cpu/mshyperv.c |1 + drivers/hv/vmbus_drv.c |4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index d02f9c9..aaf59b7 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -7,6 +7,7 @@ struct ms_hyperv_info { u32 features; + u32 misc_features; u32 hints; }; diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 5ea5bbc..f794bfa 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -158,6 +158,7 @@ static void __init ms_hyperv_init_platform(void) * Extract the features and hints */ ms_hyperv.features = cpuid_eax(HYPERV_CPUID_FEATURES); + ms_hyperv.misc_features = cpuid_edx(HYPERV_CPUID_FEATURES); ms_hyperv.hints= cpuid_eax(HYPERV_CPUID_ENLIGHTMENT_INFO); printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n", diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 83759c1..8c3eaee 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -868,7 +868,7 @@ static int vmbus_bus_init(int irq) /* * Only register if the crash MSRs are available */ - if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { register_die_notifier(&hyperv_die_block); atomic_notifier_chain_register(&panic_notifier_list, &hyperv_panic_block); @@ -1313,7 +1313,7 @@ static void __exit vmbus_exit(void) hv_remove_vmbus_irq(); tasklet_kill(&msg_dpc); vmbus_free_channels(); - if (ms_hyperv.features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { + if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) { unregister_die_notifier(&hyperv_die_block); atomic_notifier_chain_unregister(&panic_notifier_list, &hyperv_panic_block); -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 26/28] cpu-hotplug: convert cpu_hotplug_disabled to a counter
From: Vitaly Kuznetsov As a prerequisite to exporting cpu_hotplug_enable/cpu_hotplug_disable functions to modules we need to convert cpu_hotplug_disabled to a counter to properly support disable -> disable -> enable call sequences. E.g. after Hyper-V vmbus module (which is supposed to be the first user of exported cpu_hotplug_enable/cpu_hotplug_disable) did cpu_hotplug_disable() hibernate path calls disable_nonboot_cpus() and if we hit an error in _cpu_down() enable_nonboot_cpus() will be called on the failure path (thus making cpu_hotplug_disabled = 0 and leaving cpu hotplug in 'enabled' state). Same problem is possible if more than 1 module use cpu_hotplug_disable/cpu_hotplug_enable on their load/unload paths. When one of these modules is been unloaded it is logical to leave cpu hotplug in 'disabled' state. To support the change we need to increse cpu_hotplug_disabled counter in disable_nonboot_cpus() unconditionally as all users of disable_nonboot_cpus() are supposed to do enable_nonboot_cpus() in case an error was returned. Signed-off-by: Vitaly Kuznetsov Reviewed-by: Thomas Gleixner Signed-off-by: K. Y. Srinivasan --- Documentation/power/suspend-and-cpuhotplug.txt |6 +++--- kernel/cpu.c | 21 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/Documentation/power/suspend-and-cpuhotplug.txt b/Documentation/power/suspend-and-cpuhotplug.txt index 2850df3..2fc9095 100644 --- a/Documentation/power/suspend-and-cpuhotplug.txt +++ b/Documentation/power/suspend-and-cpuhotplug.txt @@ -72,7 +72,7 @@ More details follow: | v Disable regular cpu hotplug -by setting cpu_hotplug_disabled=1 +by increasing cpu_hotplug_disabled | v Release cpu_add_remove_lock @@ -89,7 +89,7 @@ Resuming back is likewise, with the counterparts being (in the order of execution during resume): * enable_nonboot_cpus() which involves: | Acquire cpu_add_remove_lock - | Reset cpu_hotplug_disabled to 0, thereby enabling regular cpu hotplug + | Decrease cpu_hotplug_disabled, thereby enabling regular cpu hotplug | Call _cpu_up() [for all those cpus in the frozen_cpus mask, in a loop] | Release cpu_add_remove_lock v @@ -120,7 +120,7 @@ after the entire cycle is complete (i.e., suspend + resume). Acquire cpu_add_remove_lock | v - If cpu_hotplug_disabled is 1 + If cpu_hotplug_disabled > 0 return gracefully | | diff --git a/kernel/cpu.c b/kernel/cpu.c index 6a37454..1225fc2 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -191,14 +191,14 @@ void cpu_hotplug_done(void) void cpu_hotplug_disable(void) { cpu_maps_update_begin(); - cpu_hotplug_disabled = 1; + cpu_hotplug_disabled++; cpu_maps_update_done(); } void cpu_hotplug_enable(void) { cpu_maps_update_begin(); - cpu_hotplug_disabled = 0; + WARN_ON(--cpu_hotplug_disabled < 0); cpu_maps_update_done(); } @@ -617,13 +617,18 @@ int disable_nonboot_cpus(void) } } - if (!error) { + if (!error) BUG_ON(num_online_cpus() > 1); - /* Make sure the CPUs won't be enabled by someone else */ - cpu_hotplug_disabled = 1; - } else { + else pr_err("Non-boot CPUs are not disabled\n"); - } + + /* +* Make sure the CPUs won't be enabled by someone else. We need to do +* this even in case of failure as all disable_nonboot_cpus() users are +* supposed to do enable_nonboot_cpus() on the failure path. +*/ + cpu_hotplug_disabled++; + cpu_maps_update_done(); return error; } @@ -642,7 +647,7 @@ void __ref enable_nonboot_cpus(void) /* Allow everyone to use the CPU hotplug again */ cpu_maps_update_begin(); - cpu_hotplug_disabled = 0; + WARN_ON(--cpu_hotplug_disabled < 0); if (cpumask_empty(frozen_cpus)) goto out; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 14/28] Drivers: hv: vmbus: fix typo in hv_port_info struct
From: Nik Nyby This fixes a typo: base_flag_bumber to base_flag_number Signed-off-by: Nik Nyby Signed-off-by: K. Y. Srinivasan --- drivers/hv/hyperv_vmbus.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index cddc0c9..6383707 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -141,7 +141,7 @@ struct hv_port_info { struct { u32 target_sint; u32 target_vp; - u16 base_flag_bumber; + u16 base_flag_number; u16 flag_count; u32 rsvdz; } event_port_info; -- 1.7.4.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/2] staging: unisys: visornic: Convert to using napi
On Sat, Aug 01, 2015 at 08:55:09AM -0700, Greg KH wrote: > On Sat, Aug 01, 2015 at 09:36:19AM -0400, Neil Horman wrote: > > On Fri, Jul 31, 2015 at 09:41:10PM -0400, Neil Horman wrote: > > > On Fri, Jul 31, 2015 at 06:56:33PM -0400, Benjamin Romer wrote: > > > > From: Neil Horman > > > > > > > > Switch the visornic over to use napi. Currently there is a kernel > > > > thread > > > > that sits and waits on a wait queue to get notified of incoming virtual > > > > interrupts. It would be nice if we could handle frame reception using > > > > the > > > > standard napi processing instead. This patch creates our napi instance > > > > and has the rx thread schedule it > > > > > > > > Given that the unisys hypervisor currently requires that queue servicing > > > > be done by a polling loop that wakes up every 2ms, lets instead also > > > > convert that to a timer, which is simpler, and allows us to remove all > > > > the thread starting and stopping code. > > > > > > > > Signed-off-by: Neil Horman > > > > Signed-off-by: Benjamin Romer > > > > > > I assume you just didn't copy me on patch 1/2? I don't see it anywhere. > > > > > > Neil > > > > > > > Sorry, scratch that, it just showed up late. > > > > for the series: > > Acked-by: Neil Horman > > Why are you acking a series that you already signed off on? That seems > redundant... > I suppose it is, but it always strikes me as a bit out of place when someone else posts patches for you, so I thought you might like to know this was in fact mine, so I acked it. Feel free to ignore it. Neil ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
qkfyu
äîáðûé äåíü! Bàì ïðèøëî ïðèãëàøåíèå íà áåñïëàòíûé âåáèíàð ïî ïðîäàæàì òîâàðîâ èç Êèòàÿ. Mû âûáðàëè âàñ ñðåäè òûñÿ÷è ïîòåíöèàëüíûõ áèçíåñìåíîâ, òàê êàê ðàáîòà â äàííîé èíäóñòðèè òðåáóåò öåëåóñòðåìëåííîñòè è æåëàíèÿ äîáèâàòüñÿ ñâîåãî. http://usatuk.ru Hàáîð íà íàøè êóðñû âñå åùå áåñïëàòíûé, íåò ñìûñëà îòêëàäûâàòü íà ïîòîì. Xîðîøåé Âàì íåäåëè! ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/4] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through
From: Jake Oshins This patch defines the channel type for a paravirtual PCI front-end within a Hyper-V VM. Signed-off-by: Jake Oshins --- include/linux/hyperv.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 02393b6..ab17332 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1139,6 +1139,17 @@ int vmbus_cpu_number_to_vp_number(int cpu_number); } /* + * PCI Express Pass Through + * {44C4F61D--4400-9D52-802E27EDE19F} + */ + +#define HV_PCIE_GUID \ + .guid = { \ + 0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \ + 0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \ + } + +/* * Common header for Hyper-V ICs */ -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/4] drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs
From: Jake Oshins This patch introduces a driver which exposes a root PCI bus whenever a PCI Express device is passed through to a Hyper-V VM. The device can be single- or multi-function. The interrupts for the devices are managed by an IRQ domain, implemented within this driver. Signed-off-by: Jake Oshins --- MAINTAINERS|1 + drivers/pci/Kconfig|7 + drivers/pci/host/Makefile |1 + drivers/pci/host/hv_pcifront.c | 2228 4 files changed, 2237 insertions(+) create mode 100644 drivers/pci/host/hv_pcifront.c diff --git a/MAINTAINERS b/MAINTAINERS index 1b7917d..fa3a818 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4957,6 +4957,7 @@ F:arch/x86/kernel/cpu/mshyperv.c F: drivers/hid/hid-hyperv.c F: drivers/hv/ F: drivers/input/serio/hyperv-keyboard.c +F: drivers/pci/host/hv_pcifront.c F: drivers/net/hyperv/ F: drivers/scsi/storvsc_drv.c F: drivers/video/fbdev/hyperv_fb.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 73de4ef..9b82d93 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -118,4 +118,11 @@ config PCI_LABEL def_bool y if (DMI || ACPI) select NLS +config HYPERV_VPCI +tristate "Hyper-V PCI Frontend" +depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN +help + The PCI device frontend driver allows the kernel to import arbitrary + PCI devices from a PCI backend to support PCI driver domains. + source "drivers/pci/host/Kconfig" diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 140d66f..39581fb 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o obj-$(CONFIG_PCI_IMX6) += pci-imx6.o +obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c new file mode 100644 index 000..24c252a --- /dev/null +++ b/drivers/pci/host/hv_pcifront.c @@ -0,0 +1,2228 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * Author: + * Jake Oshins + * + * 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. + * + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* + * Protocol versions. The low word is the minor version, the high word the major + * version. + */ + +#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major))) +#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16) +#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff) + +enum { + PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1), + PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1 +}; + +#define PCI_CONFIG_MMIO_LENGTH 0x2000 +#define MAX_SUPPORTED_MSI_MESSAGES 0x400 + +/* + * Message Types + */ + +enum pci_message_type { + /* +* Version 1.1 +*/ + PCI_MESSAGE_BASE= 0x4249, + PCI_BUS_RELATIONS = PCI_MESSAGE_BASE + 0, + PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1, + PCI_POWER_STATE_CHANGE = PCI_MESSAGE_BASE + 4, + PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5, + PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6, + PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7, + PCI_BUS_D0EXIT = PCI_MESSAGE_BASE + 8, + PCI_READ_BLOCK = PCI_MESSAGE_BASE + 9, + PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA, + PCI_EJECT = PCI_MESSAGE_BASE + 0xB, + PCI_QUERY_STOP = PCI_MESSAGE_BASE + 0xC, + PCI_REENABLE= PCI_MESSAGE_BASE + 0xD, + PCI_QUERY_STOP_FAILED = PCI_MESSAGE_BASE + 0xE, + PCI_EJECTION_COMPLETE = PCI_MESSAGE_BASE + 0xF, + PCI_RESOURCES_ASSIGNED = PCI_MESSAGE_BASE + 0x10, + PCI_RESOURCES_RELEASED = PCI_MESSAGE_BASE + 0x11, + PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12, + PCI_QUERY_PROTOCOL_VERSION = PCI_MESSAGE_BASE + 0x13, + PC
[PATCH 3/4] drivers:x86:pci: Make it possible to implement a PCI MSI IRQ Domain in a module.
From: Jake Oshins The Linux kernel already has the concept of IRQ domain, wherein a component can expose a set of IRQs which are managed by a particular interrupt controller chip or other subsystem. The PCI driver exposes the notion of an IRQ domain for Message-Signaled Interrupts (MSI) from PCI Express devices. This patch exposes the functions which are necessary to do this within a module, rather than just linked into the kernel itself. I felt it made more sense to deliver an MSI IRQ domain as a module both so that the code wouldn't be loaded except when needed and also because the driver which needs this (which is the next patch in this series) is a module and itself depends on another module. Signed-off-by: Jake Oshins --- arch/x86/kernel/apic/vector.c | 2 ++ drivers/pci/msi.c | 1 + kernel/irq/chip.c | 1 + 3 files changed, 4 insertions(+) diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index f47069e..67f7e68 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -29,6 +29,7 @@ struct apic_chip_data { }; struct irq_domain *x86_vector_domain; +EXPORT_SYMBOL_GPL(x86_vector_domain); static DEFINE_RAW_SPINLOCK(vector_lock); static cpumask_var_t vector_cpumask; static struct irq_chip lapic_controller; @@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data) return data ? &data->cfg : NULL; } +EXPORT_SYMBOL_GPL(irqd_cfg); struct irq_cfg *irq_cfg(unsigned int irq) { diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 566de05..b118be1 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -1276,6 +1276,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct device_node *node, return msi_create_irq_domain(node, info, parent); } +EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain); /** * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 76f199d..3c82c44 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -935,6 +935,7 @@ void irq_chip_ack_parent(struct irq_data *data) data = data->parent_data; data->chip->irq_ack(data); } +EXPORT_SYMBOL_GPL(irq_chip_ack_parent); /** * irq_chip_mask_parent - Mask the parent interrupt -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/4] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num
From: Jake Oshins This patch exposes the mapping between Linux CPU number and Hyper-V virtual processor number. This is necessary because the hypervisor needs to know which virtual processors to target when making a mapping in the Interrupt Redirection Table in the I/O MMU. Signed-off-by: Jake Oshins --- drivers/hv/vmbus_drv.c | 17 + include/linux/hyperv.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 2064f31..5b1a019 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -1153,6 +1153,23 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, } EXPORT_SYMBOL_GPL(vmbus_allocate_mmio); +/** + * vmbus_cpu_number_to_vp_number() - Map CPU to VP. + * @cpu_number: CPU number in Linux terms + * + * This function returns the mapping between the Linux processor + * number and the hypervisor's virtual processor number, useful + * in making hypercalls and such that talk about specific + * processors. + * + * Return: Virtual processor number in Hyper-V terms + */ +int vmbus_cpu_number_to_vp_number(int cpu_number) +{ + return hv_context.vp_index[cpu_number]; +} +EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number); + static int vmbus_acpi_add(struct acpi_device *device) { acpi_status result; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 54733d5..02393b6 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -982,6 +982,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj, resource_size_t size, resource_size_t align, bool fb_overlap_ok); +int vmbus_cpu_number_to_vp_number(int cpu_number); + /** * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device * -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/4] New Paravirtual front-end for PCI in a Hyper-V VM
From: Jake Oshins This patch series exposes the primitives necessary for an interrupt domain in a module and then introduces a new driver. This driver exposes a root PCI bus when running in a Hyper-V VM for each device which is passed through to the VM from the physical host. This patch series differs from an earlier patch series in that the way interrupts are managed for the devices has been rewritten, this time to use IRQ domains, which allows the patches to be applied to the linux-next tree. Jake Oshins (4): drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num drivers:hv: Define the channel type for Hyper-V PCI Express pass-through drivers:x86:pci: Make it possible to implement a PCI MSI IRQ Domain in a module. drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs MAINTAINERS|1 + arch/x86/kernel/apic/vector.c |2 + drivers/hv/vmbus_drv.c | 17 + drivers/pci/Kconfig|7 + drivers/pci/host/Makefile |1 + drivers/pci/host/hv_pcifront.c | 2228 drivers/pci/msi.c |1 + include/linux/hyperv.h | 13 + kernel/irq/chip.c |1 + 9 files changed, 2271 insertions(+) create mode 100644 drivers/pci/host/hv_pcifront.c -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel