History

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

Pull hyperv fixes from Wei Liu: - Correctly propagate coherence information for VMbus devices (Michael Kelley) - Disable balloon and memory hot-add on ARM64 temporarily (Boqun Feng) - Use barrier to prevent reording when reading ring buffer (Michael Kelley) - Use virt_store_mb in favour of smp_store_mb (Andrea Parri) - Fix VMbus device object initialization (Andrea Parri) - Deactivate sysctl_record_panic_msg on isolated guest (Andrea Parri) - Fix a crash when unloading VMbus module (Guilherme G. Piccoli) * tag 'hyperv-fixes-signed-20220407' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: Drivers: hv: vmbus: Replace smp_store_mb() with virt_store_mb() Drivers: hv: balloon: Disable balloon and hot-add accordingly Drivers: hv: balloon: Support status report for larger page sizes Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer PCI: hv: Propagate coherence from VMbus device to PCI device Drivers: hv: vmbus: Propagate VMbus coherence to each VMbus device Drivers: hv: vmbus: Fix potential crash on module unload Drivers: hv: vmbus: Fix initialization of device object in vmbus_device_register() Drivers: hv: vmbus: Deactivate sysctl_record_panic_msg by default in isolated guests

Linus Torvalds committed 4 years ago

Commit 42e7a032 parents 3638bd9 eaa03d37 files · +132 −20Browse files

Unified · Split

7 files
  1. drivers/hv/channel_mgmt.c +3 −3
  2. drivers/hv/hv_balloon.c +44 −5
  3. drivers/hv/hv_common.c +11 −0
  4. drivers/hv/ring_buffer.c +10 −1
  5. drivers/hv/vmbus_drv.c +54 −11
  6. drivers/pci/controller/pci-hyperv.c +9 −0
  7. include/asm-generic/mshyperv.h +1 −0
drivers/hv/channel_mgmt.c+3−3
@@ -380,7 +380,7 @@ void vmbus_channel_map_relid(struct vmbus_channel *channel) · 379 unmodified lines
380 * execute:380 * execute:
381 *381 *
382 * (a) In the "normal (i.e., not resuming from hibernation)" path,382 * (a) In the "normal (i.e., not resuming from hibernation)" path,
383 * the full barrier in smp_store_mb() guarantees that the store383 * the full barrier in virt_store_mb() guarantees that the store
384 * is propagated to all CPUs before the add_channel_work work384 * is propagated to all CPUs before the add_channel_work work
385 * is queued. In turn, add_channel_work is queued before the385 * is queued. In turn, add_channel_work is queued before the
386 * channel's ring buffer is allocated/initialized and the386 * channel's ring buffer is allocated/initialized and the
@@ -392,14 +392,14 @@ void vmbus_channel_map_relid(struct vmbus_channel *channel) · 5 unmodified lines
392 * recv_int_page before retrieving the channel pointer from the392 * recv_int_page before retrieving the channel pointer from the
393 * array of channels.393 * array of channels.
394 *394 *
395 * (b) In the "resuming from hibernation" path, the smp_store_mb()395 * (b) In the "resuming from hibernation" path, the virt_store_mb()
396 * guarantees that the store is propagated to all CPUs before396 * guarantees that the store is propagated to all CPUs before
397 * the VMBus connection is marked as ready for the resume event397 * the VMBus connection is marked as ready for the resume event
398 * (cf. check_ready_for_resume_event()). The interrupt handler398 * (cf. check_ready_for_resume_event()). The interrupt handler
399 * of the VMBus driver and vmbus_chan_sched() can not run before399 * of the VMBus driver and vmbus_chan_sched() can not run before
400 * vmbus_bus_resume() has completed execution (cf. resume_noirq).400 * vmbus_bus_resume() has completed execution (cf. resume_noirq).
401 */401 */
402 smp_store_mb(402 virt_store_mb(
403 vmbus_connection.channels[channel->offermsg.child_relid],403 vmbus_connection.channels[channel->offermsg.child_relid],
404 channel);404 channel);
405}405}
drivers/hv/hv_balloon.c+44−5
@@ -17,6 +17,7 @@ · 16 unmodified lines
17#include <linux/slab.h>17#include <linux/slab.h>
18#include <linux/kthread.h>18#include <linux/kthread.h>
19#include <linux/completion.h>19#include <linux/completion.h>
20#include <linux/count_zeros.h>
20#include <linux/memory_hotplug.h>21#include <linux/memory_hotplug.h>
21#include <linux/memory.h>22#include <linux/memory.h>
22#include <linux/notifier.h>23#include <linux/notifier.h>
@@ -1130,6 +1131,7 @@ static void post_status(struct hv_dynmem_device *dm) · 1107 unmodified lines
1130 struct dm_status status;1131 struct dm_status status;
1131 unsigned long now = jiffies;1132 unsigned long now = jiffies;
1132 unsigned long last_post = last_post_time;1133 unsigned long last_post = last_post_time;
1134 unsigned long num_pages_avail, num_pages_committed;
1133 1135
1134 if (pressure_report_delay > 0) {1136 if (pressure_report_delay > 0) {
1135 --pressure_report_delay;1137 --pressure_report_delay;
@@ -1154,16 +1156,21 @@ static void post_status(struct hv_dynmem_device *dm) · 18 unmodified lines
1154 * num_pages_onlined) as committed to the host, otherwise it can try1156 * num_pages_onlined) as committed to the host, otherwise it can try
1155 * asking us to balloon them out.1157 * asking us to balloon them out.
1156 */1158 */
1157 status.num_avail = si_mem_available();1159 num_pages_avail = si_mem_available();
1158 status.num_committed = vm_memory_committed() +1160 num_pages_committed = vm_memory_committed() +
1159 dm->num_pages_ballooned +1161 dm->num_pages_ballooned +
1160 (dm->num_pages_added > dm->num_pages_onlined ?1162 (dm->num_pages_added > dm->num_pages_onlined ?
1161 dm->num_pages_added - dm->num_pages_onlined : 0) +1163 dm->num_pages_added - dm->num_pages_onlined : 0) +
1162 compute_balloon_floor();1164 compute_balloon_floor();
1163 1165
1164 trace_balloon_status(status.num_avail, status.num_committed,1166 trace_balloon_status(num_pages_avail, num_pages_committed,
1165 vm_memory_committed(), dm->num_pages_ballooned,1167 vm_memory_committed(), dm->num_pages_ballooned,
1166 dm->num_pages_added, dm->num_pages_onlined);1168 dm->num_pages_added, dm->num_pages_onlined);
1169
1170 /* Convert numbers of pages into numbers of HV_HYP_PAGEs. */
1171 status.num_avail = num_pages_avail * NR_HV_HYP_PAGES_IN_PAGE;
1172 status.num_committed = num_pages_committed * NR_HV_HYP_PAGES_IN_PAGE;
1173
1167 /*1174 /*
1168 * If our transaction ID is no longer current, just don't1175 * If our transaction ID is no longer current, just don't
1169 * send the status. This can happen if we were interrupted1176 * send the status. This can happen if we were interrupted
@@ -1653,6 +1660,38 @@ static void disable_page_reporting(void) · 483 unmodified lines
1653 }1660 }
1654}1661}
1655 1662
1663static int ballooning_enabled(void)
1664{
1665 /*
1666 * Disable ballooning if the page size is not 4k (HV_HYP_PAGE_SIZE),
1667 * since currently it's unclear to us whether an unballoon request can
1668 * make sure all page ranges are guest page size aligned.
1669 */
1670 if (PAGE_SIZE != HV_HYP_PAGE_SIZE) {
1671 pr_info("Ballooning disabled because page size is not 4096 bytes\n");
1672 return 0;
1673 }
1674
1675 return 1;
1676}
1677
1678static int hot_add_enabled(void)
1679{
1680 /*
1681 * Disable hot add on ARM64, because we currently rely on
1682 * memory_add_physaddr_to_nid() to get a node id of a hot add range,
1683 * however ARM64's memory_add_physaddr_to_nid() always return 0 and
1684 * DM_MEM_HOT_ADD_REQUEST doesn't have the NUMA node information for
1685 * add_memory().
1686 */
1687 if (IS_ENABLED(CONFIG_ARM64)) {
1688 pr_info("Memory hot add disabled on ARM64\n");
1689 return 0;
1690 }
1691
1692 return 1;
1693}
1694
1656static int balloon_connect_vsp(struct hv_device *dev)1695static int balloon_connect_vsp(struct hv_device *dev)
1657{1696{
1658 struct dm_version_request version_req;1697 struct dm_version_request version_req;
@@ -1724,8 +1763,8 @@ static int balloon_connect_vsp(struct hv_device *dev) · 65 unmodified lines
1724 * currently still requires the bits to be set, so we have to add code1763 * currently still requires the bits to be set, so we have to add code
1725 * to fail the host's hot-add and balloon up/down requests, if any.1764 * to fail the host's hot-add and balloon up/down requests, if any.
1726 */1765 */
1727 cap_msg.caps.cap_bits.balloon = 1;1766 cap_msg.caps.cap_bits.balloon = ballooning_enabled();
1728 cap_msg.caps.cap_bits.hot_add = 1;1767 cap_msg.caps.cap_bits.hot_add = hot_add_enabled();
1729 1768
1730 /*1769 /*
1731 * Specify our alignment requirements as it relates1770 * Specify our alignment requirements as it relates
drivers/hv/hv_common.c+11−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include <linux/panic_notifier.h>20#include <linux/panic_notifier.h>
21#include <linux/ptrace.h>21#include <linux/ptrace.h>
22#include <linux/slab.h>22#include <linux/slab.h>
23#include <linux/dma-map-ops.h>
23#include <asm/hyperv-tlfs.h>24#include <asm/hyperv-tlfs.h>
24#include <asm/mshyperv.h>25#include <asm/mshyperv.h>
25 26
@@ -218,6 +219,16 @@ bool hv_query_ext_cap(u64 cap_query) · 192 unmodified lines
218}219}
219EXPORT_SYMBOL_GPL(hv_query_ext_cap);220EXPORT_SYMBOL_GPL(hv_query_ext_cap);
220 221
222void hv_setup_dma_ops(struct device *dev, bool coherent)
223{
224 /*
225 * Hyper-V does not offer a vIOMMU in the guest
226 * VM, so pass 0/NULL for the IOMMU settings
227 */
228 arch_setup_dma_ops(dev, 0, 0, NULL, coherent);
229}
230EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
231
221bool hv_is_hibernation_supported(void)232bool hv_is_hibernation_supported(void)
222{233{
223 return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4);234 return !hv_root_partition && acpi_sleep_state_supported(ACPI_STATE_S4);
drivers/hv/ring_buffer.c+10−1
@@ -439,7 +439,16 @@ int hv_ringbuffer_read(struct vmbus_channel *channel, · 438 unmodified lines
439static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)439static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
440{440{
441 u32 priv_read_loc = rbi->priv_read_index;441 u32 priv_read_loc = rbi->priv_read_index;
442 u32 write_loc = READ_ONCE(rbi->ring_buffer->write_index);442 u32 write_loc;
443
444 /*
445 * The Hyper-V host writes the packet data, then uses
446 * store_release() to update the write_index. Use load_acquire()
447 * here to prevent loads of the packet data from being re-ordered
448 * before the read of the write_index and potentially getting
449 * stale data.
450 */
451 write_loc = virt_load_acquire(&rbi->ring_buffer->write_index);
443 452
444 if (write_loc >= priv_read_loc)453 if (write_loc >= priv_read_loc)
445 return write_loc - priv_read_loc;454 return write_loc - priv_read_loc;
drivers/hv/vmbus_drv.c+54−11
@@ -77,8 +77,8 @@ static int hyperv_panic_event(struct notifier_block *nb, unsigned long val, · 76 unmodified lines
77 77
78 /*78 /*
79 * Hyper-V should be notified only once about a panic. If we will be79 * Hyper-V should be notified only once about a panic. If we will be
80 * doing hyperv_report_panic_msg() later with kmsg data, don't do80 * doing hv_kmsg_dump() with kmsg data later, don't do the notification
81 * the notification here.81 * here.
82 */82 */
83 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE83 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
84 && hyperv_report_reg()) {84 && hyperv_report_reg()) {
@@ -100,8 +100,8 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val, · 15 unmodified lines
100 100
101 /*101 /*
102 * Hyper-V should be notified only once about a panic. If we will be102 * Hyper-V should be notified only once about a panic. If we will be
103 * doing hyperv_report_panic_msg() later with kmsg data, don't do103 * doing hv_kmsg_dump() with kmsg data later, don't do the notification
104 * the notification here.104 * here.
105 */105 */
106 if (hyperv_report_reg())106 if (hyperv_report_reg())
107 hyperv_report_panic(regs, val, true);107 hyperv_report_panic(regs, val, true);
@@ -920,6 +920,21 @@ static int vmbus_probe(struct device *child_device) · 812 unmodified lines
920 return ret;920 return ret;
921}921}
922 922
923/*
924 * vmbus_dma_configure -- Configure DMA coherence for VMbus device
925 */
926static int vmbus_dma_configure(struct device *child_device)
927{
928 /*
929 * On ARM64, propagate the DMA coherence setting from the top level
930 * VMbus ACPI device to the child VMbus device being added here.
931 * On x86/x64 coherence is assumed and these calls have no effect.
932 */
933 hv_setup_dma_ops(child_device,
934 device_get_dma_attr(&hv_acpi_dev->dev) == DEV_DMA_COHERENT);
935 return 0;
936}
937
923/*938/*
924 * vmbus_remove - Remove a vmbus device939 * vmbus_remove - Remove a vmbus device
925 */940 */
@@ -1040,6 +1055,7 @@ static struct bus_type hv_bus = { · 114 unmodified lines
1040 .remove = vmbus_remove,1055 .remove = vmbus_remove,
1041 .probe = vmbus_probe,1056 .probe = vmbus_probe,
1042 .uevent = vmbus_uevent,1057 .uevent = vmbus_uevent,
1058 .dma_configure = vmbus_dma_configure,
1043 .dev_groups = vmbus_dev_groups,1059 .dev_groups = vmbus_dev_groups,
1044 .drv_groups = vmbus_drv_groups,1060 .drv_groups = vmbus_drv_groups,
1045 .bus_groups = vmbus_bus_groups,1061 .bus_groups = vmbus_bus_groups,
@@ -1546,14 +1562,20 @@ static int vmbus_bus_init(void) · 500 unmodified lines
1546 if (ret)1562 if (ret)
1547 goto err_connect;1563 goto err_connect;
1548 1564
1565 if (hv_is_isolation_supported())
1566 sysctl_record_panic_msg = 0;
1567
1549 /*1568 /*
1550 * Only register if the crash MSRs are available1569 * Only register if the crash MSRs are available
1551 */1570 */
1552 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {1571 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
1553 u64 hyperv_crash_ctl;1572 u64 hyperv_crash_ctl;
1554 /*1573 /*
1555 * Sysctl registration is not fatal, since by default1574 * Panic message recording (sysctl_record_panic_msg)
1556 * reporting is enabled.1575 * is enabled by default in non-isolated guests and
1576 * disabled by default in isolated guests; the panic
1577 * message recording won't be available in isolated
1578 * guests should the following registration fail.
1557 */1579 */
1558 hv_ctl_table_hdr = register_sysctl_table(hv_root_table);1580 hv_ctl_table_hdr = register_sysctl_table(hv_root_table);
1559 if (!hv_ctl_table_hdr)1581 if (!hv_ctl_table_hdr)
@@ -2097,6 +2119,10 @@ int vmbus_device_register(struct hv_device *child_device_obj) · 537 unmodified lines
2097 child_device_obj->device.parent = &hv_acpi_dev->dev;2119 child_device_obj->device.parent = &hv_acpi_dev->dev;
2098 child_device_obj->device.release = vmbus_device_release;2120 child_device_obj->device.release = vmbus_device_release;
2099 2121
2122 child_device_obj->device.dma_parms = &child_device_obj->dma_parms;
2123 child_device_obj->device.dma_mask = &child_device_obj->dma_mask;
2124 dma_set_mask(&child_device_obj->device, DMA_BIT_MASK(64));
2125
2100 /*2126 /*
2101 * Register with the LDM. This will kick off the driver/device2127 * Register with the LDM. This will kick off the driver/device
2102 * binding...which will eventually call vmbus_match() and vmbus_probe()2128 * binding...which will eventually call vmbus_match() and vmbus_probe()
@@ -2122,9 +2148,6 @@ int vmbus_device_register(struct hv_device *child_device_obj) · 19 unmodified lines
2122 }2148 }
2123 hv_debug_add_dev_dir(child_device_obj);2149 hv_debug_add_dev_dir(child_device_obj);
2124 2150
2125 child_device_obj->device.dma_parms = &child_device_obj->dma_parms;
2126 child_device_obj->device.dma_mask = &child_device_obj->dma_mask;
2127 dma_set_mask(&child_device_obj->device, DMA_BIT_MASK(64));
2128 return 0;2151 return 0;
2129 2152
2130err_kset_unregister:2153err_kset_unregister:
@@ -2428,6 +2451,21 @@ static int vmbus_acpi_add(struct acpi_device *device) · 297 unmodified lines
2428 2451
2429 hv_acpi_dev = device;2452 hv_acpi_dev = device;
2430 2453
2454 /*
2455 * Older versions of Hyper-V for ARM64 fail to include the _CCA
2456 * method on the top level VMbus device in the DSDT. But devices
2457 * are hardware coherent in all current Hyper-V use cases, so fix
2458 * up the ACPI device to behave as if _CCA is present and indicates
2459 * hardware coherence.
2460 */
2461 ACPI_COMPANION_SET(&device->dev, device);
2462 if (IS_ENABLED(CONFIG_ACPI_CCA_REQUIRED) &&
2463 device_get_dma_attr(&device->dev) == DEV_DMA_NOT_SUPPORTED) {
2464 pr_info("No ACPI _CCA found; assuming coherent device I/O\n");
2465 device->flags.cca_seen = true;
2466 device->flags.coherent_dma = true;
2467 }
2468
2431 result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,2469 result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
2432 vmbus_walk_resources, NULL);2470 vmbus_walk_resources, NULL);
2433 2471
@@ -2780,10 +2818,15 @@ static void __exit vmbus_exit(void) · 346 unmodified lines
2780 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {2818 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
2781 kmsg_dump_unregister(&hv_kmsg_dumper);2819 kmsg_dump_unregister(&hv_kmsg_dumper);
2782 unregister_die_notifier(&hyperv_die_block);2820 unregister_die_notifier(&hyperv_die_block);
2783 atomic_notifier_chain_unregister(&panic_notifier_list,
2784 &hyperv_panic_block);
2785 }2821 }
2786 2822
2823 /*
2824 * The panic notifier is always registered, hence we should
2825 * also unconditionally unregister it here as well.
2826 */
2827 atomic_notifier_chain_unregister(&panic_notifier_list,
2828 &hyperv_panic_block);
2829
2787 free_page((unsigned long)hv_panic_page);2830 free_page((unsigned long)hv_panic_page);
2788 unregister_sysctl_table(hv_ctl_table_hdr);2831 unregister_sysctl_table(hv_ctl_table_hdr);
2789 hv_ctl_table_hdr = NULL;2832 hv_ctl_table_hdr = NULL;
drivers/pci/controller/pci-hyperv.c+9−0
@@ -3407,6 +3407,15 @@ static int hv_pci_probe(struct hv_device *hdev, · 3406 unmodified lines
3407 hbus->bridge->domain_nr = dom;3407 hbus->bridge->domain_nr = dom;
3408#ifdef CONFIG_X863408#ifdef CONFIG_X86
3409 hbus->sysdata.domain = dom;3409 hbus->sysdata.domain = dom;
3410#elif defined(CONFIG_ARM64)
3411 /*
3412 * Set the PCI bus parent to be the corresponding VMbus
3413 * device. Then the VMbus device will be assigned as the
3414 * ACPI companion in pcibios_root_bridge_prepare() and
3415 * pci_dma_configure() will propagate device coherence
3416 * information to devices created on the bus.
3417 */
3418 hbus->sysdata.parent = hdev->device.parent;
3410#endif3419#endif
3411 3420
3412 hbus->hdev = hdev;3421 hbus->hdev = hdev;
include/asm-generic/mshyperv.h+1−0
@@ -269,6 +269,7 @@ bool hv_isolation_type_snp(void); · 268 unmodified lines
269u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size);269u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size);
270void hyperv_cleanup(void);270void hyperv_cleanup(void);
271bool hv_query_ext_cap(u64 cap_query);271bool hv_query_ext_cap(u64 cap_query);
272void hv_setup_dma_ops(struct device *dev, bool coherent);
272void *hv_map_memory(void *addr, unsigned long size);273void *hv_map_memory(void *addr, unsigned long size);
273void hv_unmap_memory(void *addr);274void hv_unmap_memory(void *addr);
274#else /* CONFIG_HYPERV */275#else /* CONFIG_HYPERV */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t