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
380380 * execute:
381381 *
382382 * (a) In the "normal (i.e., not resuming from hibernation)" path,
383− * the full barrier in smp_store_mb() guarantees that the store
383+ * the full barrier in virt_store_mb() guarantees that the store
384384 * is propagated to all CPUs before the add_channel_work work
385385 * is queued. In turn, add_channel_work is queued before the
386386 * 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
392392 * recv_int_page before retrieving the channel pointer from the
393393 * array of channels.
394394 *
395− * (b) In the "resuming from hibernation" path, the smp_store_mb()
395+ * (b) In the "resuming from hibernation" path, the virt_store_mb()
396396 * guarantees that the store is propagated to all CPUs before
397397 * the VMBus connection is marked as ready for the resume event
398398 * (cf. check_ready_for_resume_event()). The interrupt handler
399399 * of the VMBus driver and vmbus_chan_sched() can not run before
400400 * vmbus_bus_resume() has completed execution (cf. resume_noirq).
401401 */
402− smp_store_mb(
402+ virt_store_mb(
403403 vmbus_connection.channels[channel->offermsg.child_relid],
404404 channel);
405405 }
drivers/hv/hv_balloon.c+44−5
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <linux/slab.h>
1818 #include <linux/kthread.h>
1919 #include <linux/completion.h>
20+#include <linux/count_zeros.h>
2021 #include <linux/memory_hotplug.h>
2122 #include <linux/memory.h>
2223 #include <linux/notifier.h>
@@ -1130,6 +1131,7 @@ static void post_status(struct hv_dynmem_device *dm) · 1107 unmodified lines
11301131 struct dm_status status;
11311132 unsigned long now = jiffies;
11321133 unsigned long last_post = last_post_time;
1134+ unsigned long num_pages_avail, num_pages_committed;
11331135
11341136 if (pressure_report_delay > 0) {
11351137 --pressure_report_delay;
@@ -1154,16 +1156,21 @@ static void post_status(struct hv_dynmem_device *dm) · 18 unmodified lines
11541156 * num_pages_onlined) as committed to the host, otherwise it can try
11551157 * asking us to balloon them out.
11561158 */
1157− status.num_avail = si_mem_available();
1158− status.num_committed = vm_memory_committed() +
1159+ num_pages_avail = si_mem_available();
1160+ num_pages_committed = vm_memory_committed() +
11591161 dm->num_pages_ballooned +
11601162 (dm->num_pages_added > dm->num_pages_onlined ?
11611163 dm->num_pages_added - dm->num_pages_onlined : 0) +
11621164 compute_balloon_floor();
11631165
1164− trace_balloon_status(status.num_avail, status.num_committed,
1166+ trace_balloon_status(num_pages_avail, num_pages_committed,
11651167 vm_memory_committed(), dm->num_pages_ballooned,
11661168 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+
11671174 /*
11681175 * If our transaction ID is no longer current, just don't
11691176 * send the status. This can happen if we were interrupted
@@ -1653,6 +1660,38 @@ static void disable_page_reporting(void) · 483 unmodified lines
16531660 }
16541661 }
16551662
1663+static 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+
1678+static 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+
16561695 static int balloon_connect_vsp(struct hv_device *dev)
16571696 {
16581697 struct dm_version_request version_req;
@@ -1724,8 +1763,8 @@ static int balloon_connect_vsp(struct hv_device *dev) · 65 unmodified lines
17241763 * currently still requires the bits to be set, so we have to add code
17251764 * to fail the host's hot-add and balloon up/down requests, if any.
17261765 */
1727− cap_msg.caps.cap_bits.balloon = 1;
1728− cap_msg.caps.cap_bits.hot_add = 1;
1766+ cap_msg.caps.cap_bits.balloon = ballooning_enabled();
1767+ cap_msg.caps.cap_bits.hot_add = hot_add_enabled();
17291768
17301769 /*
17311770 * Specify our alignment requirements as it relates
drivers/hv/hv_common.c+11−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/panic_notifier.h>
2121 #include <linux/ptrace.h>
2222 #include <linux/slab.h>
23+#include <linux/dma-map-ops.h>
2324 #include <asm/hyperv-tlfs.h>
2425 #include <asm/mshyperv.h>
2526
@@ -218,6 +219,16 @@ bool hv_query_ext_cap(u64 cap_query) · 192 unmodified lines
218219 }
219220 EXPORT_SYMBOL_GPL(hv_query_ext_cap);
220221
222+void 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+}
230+EXPORT_SYMBOL_GPL(hv_setup_dma_ops);
231+
221232 bool hv_is_hibernation_supported(void)
222233 {
223234 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
439439 static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
440440 {
441441 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);
443452
444453 if (write_loc >= priv_read_loc)
445454 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
7777
7878 /*
7979 * 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 do
81− * the notification here.
80+ * doing hv_kmsg_dump() with kmsg data later, don't do the notification
81+ * here.
8282 */
8383 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE
8484 && hyperv_report_reg()) {
@@ -100,8 +100,8 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val, · 15 unmodified lines
100100
101101 /*
102102 * 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 do
104− * the notification here.
103+ * doing hv_kmsg_dump() with kmsg data later, don't do the notification
104+ * here.
105105 */
106106 if (hyperv_report_reg())
107107 hyperv_report_panic(regs, val, true);
@@ -920,6 +920,21 @@ static int vmbus_probe(struct device *child_device) · 812 unmodified lines
920920 return ret;
921921 }
922922
923+/*
924+ * vmbus_dma_configure -- Configure DMA coherence for VMbus device
925+ */
926+static 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+
923938 /*
924939 * vmbus_remove - Remove a vmbus device
925940 */
@@ -1040,6 +1055,7 @@ static struct bus_type hv_bus = { · 114 unmodified lines
10401055 .remove = vmbus_remove,
10411056 .probe = vmbus_probe,
10421057 .uevent = vmbus_uevent,
1058+ .dma_configure = vmbus_dma_configure,
10431059 .dev_groups = vmbus_dev_groups,
10441060 .drv_groups = vmbus_drv_groups,
10451061 .bus_groups = vmbus_bus_groups,
@@ -1546,14 +1562,20 @@ static int vmbus_bus_init(void) · 500 unmodified lines
15461562 if (ret)
15471563 goto err_connect;
15481564
1565+ if (hv_is_isolation_supported())
1566+ sysctl_record_panic_msg = 0;
1567+
15491568 /*
15501569 * Only register if the crash MSRs are available
15511570 */
15521571 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
15531572 u64 hyperv_crash_ctl;
15541573 /*
1555− * Sysctl registration is not fatal, since by default
1556− * reporting is enabled.
1574+ * Panic message recording (sysctl_record_panic_msg)
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.
15571579 */
15581580 hv_ctl_table_hdr = register_sysctl_table(hv_root_table);
15591581 if (!hv_ctl_table_hdr)
@@ -2097,6 +2119,10 @@ int vmbus_device_register(struct hv_device *child_device_obj) · 537 unmodified lines
20972119 child_device_obj->device.parent = &hv_acpi_dev->dev;
20982120 child_device_obj->device.release = vmbus_device_release;
20992121
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+
21002126 /*
21012127 * Register with the LDM. This will kick off the driver/device
21022128 * 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
21222148 }
21232149 hv_debug_add_dev_dir(child_device_obj);
21242150
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));
21282151 return 0;
21292152
21302153 err_kset_unregister:
@@ -2428,6 +2451,21 @@ static int vmbus_acpi_add(struct acpi_device *device) · 297 unmodified lines
24282451
24292452 hv_acpi_dev = device;
24302453
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+
24312469 result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
24322470 vmbus_walk_resources, NULL);
24332471
@@ -2780,10 +2818,15 @@ static void __exit vmbus_exit(void) · 346 unmodified lines
27802818 if (ms_hyperv.misc_features & HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE) {
27812819 kmsg_dump_unregister(&hv_kmsg_dumper);
27822820 unregister_die_notifier(&hyperv_die_block);
2783− atomic_notifier_chain_unregister(&panic_notifier_list,
2784− &hyperv_panic_block);
27852821 }
27862822
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+
27872830 free_page((unsigned long)hv_panic_page);
27882831 unregister_sysctl_table(hv_ctl_table_hdr);
27892832 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
34073407 hbus->bridge->domain_nr = dom;
34083408 #ifdef CONFIG_X86
34093409 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;
34103419 #endif
34113420
34123421 hbus->hdev = hdev;
include/asm-generic/mshyperv.h+1−0
@@ -269,6 +269,7 @@ bool hv_isolation_type_snp(void); · 268 unmodified lines
269269 u64 hv_ghcb_hypercall(u64 control, void *input, void *output, u32 input_size);
270270 void hyperv_cleanup(void);
271271 bool hv_query_ext_cap(u64 cap_query);
272+void hv_setup_dma_ops(struct device *dev, bool coherent);
272273 void *hv_map_memory(void *addr, unsigned long size);
273274 void hv_unmap_memory(void *addr);
274275 #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