Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull Hyper-V fixes from Wei Liu:

- Some cosmetic changes for hv.c and balloon.c (Aditya Nagesh)

- Two documentation updates (Michael Kelley)

- Suppress the invalid warning for packed member alignment (Saurabh
Sengar)

- Two hv_balloon fixes (Michael Kelley)

* tag 'hyperv-fixes-signed-20240616' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
Drivers: hv: Cosmetic changes for hv.c and balloon.c
Documentation: hyperv: Improve synic and interrupt handling description
Documentation: hyperv: Update spelling and fix typo
tools: hv: suppress the invalid warning for packed member alignment
hv_balloon: Enable hot-add for memblock sizes > 128 MiB
hv_balloon: Use kernel macros to simplify open coded sequences

+207 -205
+15 -6
Documentation/virt/hyperv/clocks.rst
··· 62 62 space code performs the same algorithm of reading the TSC and 63 63 applying the scale and offset to get the constant 10 MHz clock. 64 64 65 - Linux clockevents are based on Hyper-V synthetic timer 0. While 66 - Hyper-V offers 4 synthetic timers for each CPU, Linux only uses 67 - timer 0. Interrupts from stimer0 are recorded on the "HVS" line in 68 - /proc/interrupts. Clockevents based on the virtualized PIT and 69 - local APIC timer also work, but the Hyper-V synthetic timer is 70 - preferred. 65 + Linux clockevents are based on Hyper-V synthetic timer 0 (stimer0). 66 + While Hyper-V offers 4 synthetic timers for each CPU, Linux only uses 67 + timer 0. In older versions of Hyper-V, an interrupt from stimer0 68 + results in a VMBus control message that is demultiplexed by 69 + vmbus_isr() as described in the Documentation/virt/hyperv/vmbus.rst 70 + documentation. In newer versions of Hyper-V, stimer0 interrupts can 71 + be mapped to an architectural interrupt, which is referred to as 72 + "Direct Mode". Linux prefers to use Direct Mode when available. Since 73 + x86/x64 doesn't support per-CPU interrupts, Direct Mode statically 74 + allocates an x86 interrupt vector (HYPERV_STIMER0_VECTOR) across all CPUs 75 + and explicitly codes it to call the stimer0 interrupt handler. Hence 76 + interrupts from stimer0 are recorded on the "HVS" line in /proc/interrupts 77 + rather than being associated with a Linux IRQ. Clockevents based on the 78 + virtualized PIT and local APIC timer also work, but Hyper-V stimer0 79 + is preferred. 71 80 72 81 The driver for the Hyper-V synthetic system clock and timers is 73 82 drivers/clocksource/hyperv_timer.c.
+11 -11
Documentation/virt/hyperv/overview.rst
··· 40 40 arm64, these synthetic registers must be accessed using explicit 41 41 hypercalls. 42 42 43 - * VMbus: VMbus is a higher-level software construct that is built on 43 + * VMBus: VMBus is a higher-level software construct that is built on 44 44 the other 3 mechanisms. It is a message passing interface between 45 45 the Hyper-V host and the Linux guest. It uses memory that is shared 46 46 between Hyper-V and the guest, along with various signaling ··· 54 54 55 55 .. _Hyper-V Top Level Functional Spec (TLFS): https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs 56 56 57 - VMbus is not documented. This documentation provides a high-level 58 - overview of VMbus and how it works, but the details can be discerned 57 + VMBus is not documented. This documentation provides a high-level 58 + overview of VMBus and how it works, but the details can be discerned 59 59 only from the code. 60 60 61 61 Sharing Memory ··· 74 74 physical address space. How Hyper-V is told about the GPA or list 75 75 of GPAs varies. In some cases, a single GPA is written to a 76 76 synthetic register. In other cases, a GPA or list of GPAs is sent 77 - in a VMbus message. 77 + in a VMBus message. 78 78 79 79 * Hyper-V translates the GPAs into "real" physical memory addresses, 80 80 and creates a virtual mapping that it can use to access the memory. ··· 133 133 any hot-add CPUs. 134 134 135 135 A Linux guest CPU may be taken offline using the normal Linux 136 - mechanisms, provided no VMbus channel interrupts are assigned to 137 - the CPU. See the section on VMbus Interrupts for more details 138 - on how VMbus channel interrupts can be re-assigned to permit 136 + mechanisms, provided no VMBus channel interrupts are assigned to 137 + the CPU. See the section on VMBus Interrupts for more details 138 + on how VMBus channel interrupts can be re-assigned to permit 139 139 taking a CPU offline. 140 140 141 141 32-bit and 64-bit ··· 169 169 via flags in synthetic MSRs that Hyper-V provides to the guest, 170 170 and the guest code tests these flags. 171 171 172 - VMbus has its own protocol version that is negotiated during the 173 - initial VMbus connection from the guest to Hyper-V. This version 172 + VMBus has its own protocol version that is negotiated during the 173 + initial VMBus connection from the guest to Hyper-V. This version 174 174 number is also output to dmesg during boot. This version number 175 175 is checked in a few places in the code to determine if specific 176 176 functionality is present. 177 177 178 - Furthermore, each synthetic device on VMbus also has a protocol 179 - version that is separate from the VMbus protocol version. Device 178 + Furthermore, each synthetic device on VMBus also has a protocol 179 + version that is separate from the VMBus protocol version. Device 180 180 drivers for these synthetic devices typically negotiate the device 181 181 protocol version, and may test that protocol version to determine 182 182 if specific device functionality is present.
+82 -59
Documentation/virt/hyperv/vmbus.rst
··· 1 1 .. SPDX-License-Identifier: GPL-2.0 2 2 3 - VMbus 3 + VMBus 4 4 ===== 5 - VMbus is a software construct provided by Hyper-V to guest VMs. It 5 + VMBus is a software construct provided by Hyper-V to guest VMs. It 6 6 consists of a control path and common facilities used by synthetic 7 7 devices that Hyper-V presents to guest VMs. The control path is 8 8 used to offer synthetic devices to the guest VM and, in some cases, ··· 12 12 signaling primitives to allow Hyper-V and the guest to interrupt 13 13 each other. 14 14 15 - VMbus is modeled in Linux as a bus, with the expected /sys/bus/vmbus 16 - entry in a running Linux guest. The VMbus driver (drivers/hv/vmbus_drv.c) 17 - establishes the VMbus control path with the Hyper-V host, then 15 + VMBus is modeled in Linux as a bus, with the expected /sys/bus/vmbus 16 + entry in a running Linux guest. The VMBus driver (drivers/hv/vmbus_drv.c) 17 + establishes the VMBus control path with the Hyper-V host, then 18 18 registers itself as a Linux bus driver. It implements the standard 19 19 bus functions for adding and removing devices to/from the bus. 20 20 ··· 49 49 the synthetic SCSI controller is "storvsc". These drivers contain 50 50 functions with names like "storvsc_connect_to_vsp". 51 51 52 - VMbus channels 52 + VMBus channels 53 53 -------------- 54 - An instance of a synthetic device uses VMbus channels to communicate 54 + An instance of a synthetic device uses VMBus channels to communicate 55 55 between the VSP and the VSC. Channels are bi-directional and used 56 56 for passing messages. Most synthetic devices use a single channel, 57 57 but the synthetic SCSI controller and synthetic NIC may use multiple ··· 73 73 actual ring. The size of the ring is determined by the VSC in the 74 74 guest and is specific to each synthetic device. The list of GPAs 75 75 making up the ring is communicated to the Hyper-V host over the 76 - VMbus control path as a GPA Descriptor List (GPADL). See function 76 + VMBus control path as a GPA Descriptor List (GPADL). See function 77 77 vmbus_establish_gpadl(). 78 78 79 79 Each ring buffer is mapped into contiguous Linux kernel virtual ··· 102 102 approximately 1280 Mbytes. For versions prior to Windows Server 103 103 2019, the limit is approximately 384 Mbytes. 104 104 105 - VMbus messages 106 - -------------- 107 - All VMbus messages have a standard header that includes the message 108 - length, the offset of the message payload, some flags, and a 105 + VMBus channel messages 106 + ---------------------- 107 + All messages sent in a VMBus channel have a standard header that includes 108 + the message length, the offset of the message payload, some flags, and a 109 109 transactionID. The portion of the message after the header is 110 110 unique to each VSP/VSC pair. 111 111 ··· 137 137 buffer. For example, the storvsc driver uses this approach to 138 138 specify the data buffers to/from which disk I/O is done. 139 139 140 - Three functions exist to send VMbus messages: 140 + Three functions exist to send VMBus channel messages: 141 141 142 142 1. vmbus_sendpacket(): Control-only messages and messages with 143 143 embedded data -- no GPAs ··· 154 154 and valid messages, and Linux drivers for synthetic devices did not 155 155 fully validate messages. With the introduction of processor 156 156 technologies that fully encrypt guest memory and that allow the 157 - guest to not trust the hypervisor (AMD SNP-SEV, Intel TDX), trusting 157 + guest to not trust the hypervisor (AMD SEV-SNP, Intel TDX), trusting 158 158 the Hyper-V host is no longer a valid assumption. The drivers for 159 - VMbus synthetic devices are being updated to fully validate any 159 + VMBus synthetic devices are being updated to fully validate any 160 160 values read from memory that is shared with Hyper-V, which includes 161 - messages from VMbus devices. To facilitate such validation, 161 + messages from VMBus devices. To facilitate such validation, 162 162 messages read by the guest from the "in" ring buffer are copied to a 163 163 temporary buffer that is not shared with Hyper-V. Validation is 164 164 performed in this temporary buffer without the risk of Hyper-V 165 165 maliciously modifying the message after it is validated but before 166 166 it is used. 167 167 168 - VMbus interrupts 168 + Synthetic Interrupt Controller (synic) 169 + -------------------------------------- 170 + Hyper-V provides each guest CPU with a synthetic interrupt controller 171 + that is used by VMBus for host-guest communication. While each synic 172 + defines 16 synthetic interrupts (SINT), Linux uses only one of the 16 173 + (VMBUS_MESSAGE_SINT). All interrupts related to communication between 174 + the Hyper-V host and a guest CPU use that SINT. 175 + 176 + The SINT is mapped to a single per-CPU architectural interrupt (i.e, 177 + an 8-bit x86/x64 interrupt vector, or an arm64 PPI INTID). Because 178 + each CPU in the guest has a synic and may receive VMBus interrupts, 179 + they are best modeled in Linux as per-CPU interrupts. This model works 180 + well on arm64 where a single per-CPU Linux IRQ is allocated for 181 + VMBUS_MESSAGE_SINT. This IRQ appears in /proc/interrupts as an IRQ labelled 182 + "Hyper-V VMbus". Since x86/x64 lacks support for per-CPU IRQs, an x86 183 + interrupt vector is statically allocated (HYPERVISOR_CALLBACK_VECTOR) 184 + across all CPUs and explicitly coded to call vmbus_isr(). In this case, 185 + there's no Linux IRQ, and the interrupts are visible in aggregate in 186 + /proc/interrupts on the "HYP" line. 187 + 188 + The synic provides the means to demultiplex the architectural interrupt into 189 + one or more logical interrupts and route the logical interrupt to the proper 190 + VMBus handler in Linux. This demultiplexing is done by vmbus_isr() and 191 + related functions that access synic data structures. 192 + 193 + The synic is not modeled in Linux as an irq chip or irq domain, 194 + and the demultiplexed logical interrupts are not Linux IRQs. As such, 195 + they don't appear in /proc/interrupts or /proc/irq. The CPU 196 + affinity for one of these logical interrupts is controlled via an 197 + entry under /sys/bus/vmbus as described below. 198 + 199 + VMBus interrupts 169 200 ---------------- 170 - VMbus provides a mechanism for the guest to interrupt the host when 201 + VMBus provides a mechanism for the guest to interrupt the host when 171 202 the guest has queued new messages in a ring buffer. The host 172 203 expects that the guest will send an interrupt only when an "out" 173 204 ring buffer transitions from empty to non-empty. If the guest sends ··· 207 176 interrupts, the host may throttle that guest by suspending its 208 177 execution for a few seconds to prevent a denial-of-service attack. 209 178 210 - Similarly, the host will interrupt the guest when it sends a new 211 - message on the VMbus control path, or when a VMbus channel "in" ring 212 - buffer transitions from empty to non-empty. Each CPU in the guest 213 - may receive VMbus interrupts, so they are best modeled as per-CPU 214 - interrupts in Linux. This model works well on arm64 where a single 215 - per-CPU IRQ is allocated for VMbus. Since x86/x64 lacks support for 216 - per-CPU IRQs, an x86 interrupt vector is statically allocated (see 217 - HYPERVISOR_CALLBACK_VECTOR) across all CPUs and explicitly coded to 218 - call the VMbus interrupt service routine. These interrupts are 219 - visible in /proc/interrupts on the "HYP" line. 179 + Similarly, the host will interrupt the guest via the synic when 180 + it sends a new message on the VMBus control path, or when a VMBus 181 + channel "in" ring buffer transitions from empty to non-empty due to 182 + the host inserting a new VMBus channel message. The control message stream 183 + and each VMBus channel "in" ring buffer are separate logical interrupts 184 + that are demultiplexed by vmbus_isr(). It demultiplexes by first checking 185 + for channel interrupts by calling vmbus_chan_sched(), which looks at a synic 186 + bitmap to determine which channels have pending interrupts on this CPU. 187 + If multiple channels have pending interrupts for this CPU, they are 188 + processed sequentially. When all channel interrupts have been processed, 189 + vmbus_isr() checks for and processes any messages received on the VMBus 190 + control path. 220 191 221 - The guest CPU that a VMbus channel will interrupt is selected by the 192 + The guest CPU that a VMBus channel will interrupt is selected by the 222 193 guest when the channel is created, and the host is informed of that 223 - selection. VMbus devices are broadly grouped into two categories: 194 + selection. VMBus devices are broadly grouped into two categories: 224 195 225 - 1. "Slow" devices that need only one VMbus channel. The devices 196 + 1. "Slow" devices that need only one VMBus channel. The devices 226 197 (such as keyboard, mouse, heartbeat, and timesync) generate 227 - relatively few interrupts. Their VMbus channels are all 198 + relatively few interrupts. Their VMBus channels are all 228 199 assigned to interrupt the VMBUS_CONNECT_CPU, which is always 229 200 CPU 0. 230 201 231 - 2. "High speed" devices that may use multiple VMbus channels for 202 + 2. "High speed" devices that may use multiple VMBus channels for 232 203 higher parallelism and performance. These devices include the 233 - synthetic SCSI controller and synthetic NIC. Their VMbus 204 + synthetic SCSI controller and synthetic NIC. Their VMBus 234 205 channels interrupts are assigned to CPUs that are spread out 235 206 among the available CPUs in the VM so that interrupts on 236 207 multiple channels can be processed in parallel. 237 208 238 - The assignment of VMbus channel interrupts to CPUs is done in the 209 + The assignment of VMBus channel interrupts to CPUs is done in the 239 210 function init_vp_index(). This assignment is done outside of the 240 211 normal Linux interrupt affinity mechanism, so the interrupts are 241 212 neither "unmanaged" nor "managed" interrupts. 242 213 243 - The CPU that a VMbus channel will interrupt can be seen in 214 + The CPU that a VMBus channel will interrupt can be seen in 244 215 /sys/bus/vmbus/devices/<deviceGUID>/ channels/<channelRelID>/cpu. 245 216 When running on later versions of Hyper-V, the CPU can be changed 246 - by writing a new value to this sysfs entry. Because the interrupt 247 - assignment is done outside of the normal Linux affinity mechanism, 248 - there are no entries in /proc/irq corresponding to individual 249 - VMbus channel interrupts. 217 + by writing a new value to this sysfs entry. Because VMBus channel 218 + interrupts are not Linux IRQs, there are no entries in /proc/interrupts 219 + or /proc/irq corresponding to individual VMBus channel interrupts. 250 220 251 221 An online CPU in a Linux guest may not be taken offline if it has 252 - VMbus channel interrupts assigned to it. Any such channel 222 + VMBus channel interrupts assigned to it. Any such channel 253 223 interrupts must first be manually reassigned to another CPU as 254 224 described above. When no channel interrupts are assigned to the 255 225 CPU, it can be taken offline. 256 226 257 - When a guest CPU receives a VMbus interrupt from the host, the 258 - function vmbus_isr() handles the interrupt. It first checks for 259 - channel interrupts by calling vmbus_chan_sched(), which looks at a 260 - bitmap setup by the host to determine which channels have pending 261 - interrupts on this CPU. If multiple channels have pending 262 - interrupts for this CPU, they are processed sequentially. When all 263 - channel interrupts have been processed, vmbus_isr() checks for and 264 - processes any message received on the VMbus control path. 265 - 266 - The VMbus channel interrupt handling code is designed to work 227 + The VMBus channel interrupt handling code is designed to work 267 228 correctly even if an interrupt is received on a CPU other than the 268 229 CPU assigned to the channel. Specifically, the code does not use 269 230 CPU-based exclusion for correctness. In normal operation, Hyper-V ··· 265 242 even if there is a time lag before Hyper-V starts interrupting the 266 243 new CPU. See comments in target_cpu_store(). 267 244 268 - VMbus device creation/deletion 245 + VMBus device creation/deletion 269 246 ------------------------------ 270 247 Hyper-V and the Linux guest have a separate message-passing path 271 248 that is used for synthetic device creation and deletion. This 272 - path does not use a VMbus channel. See vmbus_post_msg() and 249 + path does not use a VMBus channel. See vmbus_post_msg() and 273 250 vmbus_on_msg_dpc(). 274 251 275 252 The first step is for the guest to connect to the generic 276 - Hyper-V VMbus mechanism. As part of establishing this connection, 277 - the guest and Hyper-V agree on a VMbus protocol version they will 253 + Hyper-V VMBus mechanism. As part of establishing this connection, 254 + the guest and Hyper-V agree on a VMBus protocol version they will 278 255 use. This negotiation allows newer Linux kernels to run on older 279 256 Hyper-V versions, and vice versa. 280 257 281 258 The guest then tells Hyper-V to "send offers". Hyper-V sends an 282 259 offer message to the guest for each synthetic device that the VM 283 - is configured to have. Each VMbus device type has a fixed GUID 284 - known as the "class ID", and each VMbus device instance is also 260 + is configured to have. Each VMBus device type has a fixed GUID 261 + known as the "class ID", and each VMBus device instance is also 285 262 identified by a GUID. The offer message from Hyper-V contains 286 263 both GUIDs to uniquely (within the VM) identify the device. 287 264 There is one offer message for each device instance, so a VM with ··· 298 275 the device. Driver/device matching is performed using the standard 299 276 Linux mechanism. 300 277 301 - The device driver probe function opens the primary VMbus channel to 278 + The device driver probe function opens the primary VMBus channel to 302 279 the corresponding VSP. It allocates guest memory for the channel 303 280 ring buffers and shares the ring buffer with the Hyper-V host by 304 281 giving the host a list of GPAs for the ring buffer memory. See ··· 308 285 setup messages via the primary channel. These messages may include 309 286 negotiating the device protocol version to be used between the Linux 310 287 VSC and the VSP on the Hyper-V host. The setup messages may also 311 - include creating additional VMbus channels, which are somewhat 288 + include creating additional VMBus channels, which are somewhat 312 289 mis-named as "sub-channels" since they are functionally 313 290 equivalent to the primary channel once they are created. 314 291
+18 -19
drivers/hv/hv.c
··· 45 45 * This involves a hypercall. 46 46 */ 47 47 int hv_post_message(union hv_connection_id connection_id, 48 - enum hv_message_type message_type, 49 - void *payload, size_t payload_size) 48 + enum hv_message_type message_type, 49 + void *payload, size_t payload_size) 50 50 { 51 51 struct hv_input_post_message *aligned_msg; 52 52 unsigned long flags; ··· 86 86 status = HV_STATUS_INVALID_PARAMETER; 87 87 } else { 88 88 status = hv_do_hypercall(HVCALL_POST_MESSAGE, 89 - aligned_msg, NULL); 89 + aligned_msg, NULL); 90 90 } 91 91 92 92 local_irq_restore(flags); ··· 111 111 112 112 hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask), 113 113 GFP_KERNEL); 114 - if (hv_context.hv_numa_map == NULL) { 114 + if (!hv_context.hv_numa_map) { 115 115 pr_err("Unable to allocate NUMA map\n"); 116 116 goto err; 117 117 } ··· 120 120 hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); 121 121 122 122 tasklet_init(&hv_cpu->msg_dpc, 123 - vmbus_on_msg_dpc, (unsigned long) hv_cpu); 123 + vmbus_on_msg_dpc, (unsigned long)hv_cpu); 124 124 125 125 if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) { 126 126 hv_cpu->post_msg_page = (void *)get_zeroed_page(GFP_ATOMIC); 127 - if (hv_cpu->post_msg_page == NULL) { 127 + if (!hv_cpu->post_msg_page) { 128 128 pr_err("Unable to allocate post msg page\n"); 129 129 goto err; 130 130 } ··· 147 147 if (!ms_hyperv.paravisor_present && !hv_root_partition) { 148 148 hv_cpu->synic_message_page = 149 149 (void *)get_zeroed_page(GFP_ATOMIC); 150 - if (hv_cpu->synic_message_page == NULL) { 150 + if (!hv_cpu->synic_message_page) { 151 151 pr_err("Unable to allocate SYNIC message page\n"); 152 152 goto err; 153 153 } 154 154 155 155 hv_cpu->synic_event_page = 156 156 (void *)get_zeroed_page(GFP_ATOMIC); 157 - if (hv_cpu->synic_event_page == NULL) { 157 + if (!hv_cpu->synic_event_page) { 158 158 pr_err("Unable to allocate SYNIC event page\n"); 159 159 160 160 free_page((unsigned long)hv_cpu->synic_message_page); ··· 203 203 return ret; 204 204 } 205 205 206 - 207 206 void hv_synic_free(void) 208 207 { 209 208 int cpu, ret; 210 209 211 210 for_each_present_cpu(cpu) { 212 - struct hv_per_cpu_context *hv_cpu 213 - = per_cpu_ptr(hv_context.cpu_context, cpu); 211 + struct hv_per_cpu_context *hv_cpu = 212 + per_cpu_ptr(hv_context.cpu_context, cpu); 214 213 215 214 /* It's better to leak the page if the encryption fails. */ 216 215 if (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) { ··· 261 262 */ 262 263 void hv_synic_enable_regs(unsigned int cpu) 263 264 { 264 - struct hv_per_cpu_context *hv_cpu 265 - = per_cpu_ptr(hv_context.cpu_context, cpu); 265 + struct hv_per_cpu_context *hv_cpu = 266 + per_cpu_ptr(hv_context.cpu_context, cpu); 266 267 union hv_synic_simp simp; 267 268 union hv_synic_siefp siefp; 268 269 union hv_synic_sint shared_sint; ··· 276 277 /* Mask out vTOM bit. ioremap_cache() maps decrypted */ 277 278 u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) & 278 279 ~ms_hyperv.shared_gpa_boundary; 279 - hv_cpu->synic_message_page 280 - = (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); 280 + hv_cpu->synic_message_page = 281 + (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); 281 282 if (!hv_cpu->synic_message_page) 282 283 pr_err("Fail to map synic message page.\n"); 283 284 } else { ··· 295 296 /* Mask out vTOM bit. ioremap_cache() maps decrypted */ 296 297 u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) & 297 298 ~ms_hyperv.shared_gpa_boundary; 298 - hv_cpu->synic_event_page 299 - = (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); 299 + hv_cpu->synic_event_page = 300 + (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); 300 301 if (!hv_cpu->synic_event_page) 301 302 pr_err("Fail to map synic event page.\n"); 302 303 } else { ··· 347 348 */ 348 349 void hv_synic_disable_regs(unsigned int cpu) 349 350 { 350 - struct hv_per_cpu_context *hv_cpu 351 - = per_cpu_ptr(hv_context.cpu_context, cpu); 351 + struct hv_per_cpu_context *hv_cpu = 352 + per_cpu_ptr(hv_context.cpu_context, cpu); 352 353 union hv_synic_sint shared_sint; 353 354 union hv_synic_simp simp; 354 355 union hv_synic_siefp siefp;
+80 -110
drivers/hv/hv_balloon.c
··· 25 25 #include <linux/notifier.h> 26 26 #include <linux/percpu_counter.h> 27 27 #include <linux/page_reporting.h> 28 + #include <linux/sizes.h> 28 29 29 30 #include <linux/hyperv.h> 30 31 #include <asm/hyperv-tlfs.h> ··· 41 40 * 42 41 * Begin protocol definitions. 43 42 */ 44 - 45 - 46 43 47 44 /* 48 45 * Protocol versions. The low word is the minor version, the high word the major ··· 70 71 DYNMEM_PROTOCOL_VERSION_CURRENT = DYNMEM_PROTOCOL_VERSION_WIN10 71 72 }; 72 73 73 - 74 - 75 74 /* 76 75 * Message Types 77 76 */ ··· 98 101 DM_VERSION_1_MAX = 12 99 102 }; 100 103 101 - 102 104 /* 103 105 * Structures defining the dynamic memory management 104 106 * protocol. ··· 110 114 }; 111 115 __u32 version; 112 116 } __packed; 113 - 114 117 115 118 union dm_caps { 116 119 struct { ··· 143 148 __u64 page_range; 144 149 } __packed; 145 150 146 - 147 - 148 151 /* 149 152 * The header for all dynamic memory messages: 150 153 * ··· 166 173 struct dm_header hdr; 167 174 __u8 data[]; /* enclosed message */ 168 175 } __packed; 169 - 170 176 171 177 /* 172 178 * Specific message types supporting the dynamic memory protocol. ··· 263 271 __u32 io_diff; 264 272 } __packed; 265 273 266 - 267 274 /* 268 275 * Message to ask the guest to allocate memory - balloon up message. 269 276 * This message is sent from the host to the guest. The guest may not be ··· 277 286 __u32 reservedz; 278 287 } __packed; 279 288 280 - 281 289 /* 282 290 * Balloon response message; this message is sent from the guest 283 291 * to the host in response to the balloon message. 284 292 * 285 293 * reservedz: Reserved; must be set to zero. 286 294 * more_pages: If FALSE, this is the last message of the transaction. 287 - * if TRUE there will atleast one more message from the guest. 295 + * if TRUE there will be at least one more message from the guest. 288 296 * 289 297 * range_count: The number of ranges in the range array. 290 298 * ··· 304 314 * to the guest to give guest more memory. 305 315 * 306 316 * more_pages: If FALSE, this is the last message of the transaction. 307 - * if TRUE there will atleast one more message from the guest. 317 + * if TRUE there will be at least one more message from the guest. 308 318 * 309 319 * reservedz: Reserved; must be set to zero. 310 320 * ··· 331 341 struct dm_unballoon_response { 332 342 struct dm_header hdr; 333 343 } __packed; 334 - 335 344 336 345 /* 337 346 * Hot add request message. Message sent from the host to the guest. ··· 379 390 MAX_INFO_TYPE 380 391 }; 381 392 382 - 383 393 /* 384 394 * Header for the information message. 385 395 */ ··· 413 425 * The range start_pfn : end_pfn specifies the range 414 426 * that the host has asked us to hot add. The range 415 427 * start_pfn : ha_end_pfn specifies the range that we have 416 - * currently hot added. We hot add in multiples of 128M 417 - * chunks; it is possible that we may not be able to bring 418 - * online all the pages in the region. The range 428 + * currently hot added. We hot add in chunks equal to the 429 + * memory block size; it is possible that we may not be able 430 + * to bring online all the pages in the region. The range 419 431 * covered_start_pfn:covered_end_pfn defines the pages that can 420 - * be brough online. 432 + * be brought online. 421 433 */ 422 434 423 435 struct hv_hotadd_state { ··· 468 480 469 481 static int hv_hypercall_multi_failure; 470 482 471 - module_param(hot_add, bool, (S_IRUGO | S_IWUSR)); 483 + module_param(hot_add, bool, 0644); 472 484 MODULE_PARM_DESC(hot_add, "If set attempt memory hot_add"); 473 485 474 - module_param(pressure_report_delay, uint, (S_IRUGO | S_IWUSR)); 486 + module_param(pressure_report_delay, uint, 0644); 475 487 MODULE_PARM_DESC(pressure_report_delay, "Delay in secs in reporting pressure"); 476 488 static atomic_t trans_id = ATOMIC_INIT(0); 477 489 ··· 490 502 DM_INIT_ERROR 491 503 }; 492 504 493 - 494 505 static __u8 recv_buffer[HV_HYP_PAGE_SIZE]; 495 506 static __u8 balloon_up_send_buffer[HV_HYP_PAGE_SIZE]; 507 + 508 + static unsigned long ha_pages_in_chunk; 509 + #define HA_BYTES_IN_CHUNK (ha_pages_in_chunk << PAGE_SHIFT) 510 + 496 511 #define PAGES_IN_2M (2 * 1024 * 1024 / PAGE_SIZE) 497 - #define HA_CHUNK (128 * 1024 * 1024 / PAGE_SIZE) 498 512 499 513 struct hv_dynmem_device { 500 514 struct hv_device *dev; ··· 585 595 struct hv_hotadd_gap *gap; 586 596 587 597 /* The page is not backed. */ 588 - if ((pfn < has->covered_start_pfn) || (pfn >= has->covered_end_pfn)) 598 + if (pfn < has->covered_start_pfn || pfn >= has->covered_end_pfn) 589 599 return false; 590 600 591 601 /* Check for gaps. */ 592 602 list_for_each_entry(gap, &has->gap_list, list) { 593 - if ((pfn >= gap->start_pfn) && (pfn < gap->end_pfn)) 603 + if (pfn >= gap->start_pfn && pfn < gap->end_pfn) 594 604 return false; 595 605 } 596 606 ··· 714 724 unsigned long processed_pfn; 715 725 unsigned long total_pfn = pfn_count; 716 726 717 - for (i = 0; i < (size/HA_CHUNK); i++) { 718 - start_pfn = start + (i * HA_CHUNK); 727 + for (i = 0; i < (size/ha_pages_in_chunk); i++) { 728 + start_pfn = start + (i * ha_pages_in_chunk); 719 729 720 730 scoped_guard(spinlock_irqsave, &dm_device.ha_lock) { 721 - has->ha_end_pfn += HA_CHUNK; 722 - 723 - if (total_pfn > HA_CHUNK) { 724 - processed_pfn = HA_CHUNK; 725 - total_pfn -= HA_CHUNK; 726 - } else { 727 - processed_pfn = total_pfn; 728 - total_pfn = 0; 729 - } 730 - 731 - has->covered_end_pfn += processed_pfn; 731 + has->ha_end_pfn += ha_pages_in_chunk; 732 + processed_pfn = umin(total_pfn, ha_pages_in_chunk); 733 + total_pfn -= processed_pfn; 734 + has->covered_end_pfn += processed_pfn; 732 735 } 733 736 734 737 reinit_completion(&dm_device.ol_waitevent); 735 738 736 739 nid = memory_add_physaddr_to_nid(PFN_PHYS(start_pfn)); 737 740 ret = add_memory(nid, PFN_PHYS((start_pfn)), 738 - (HA_CHUNK << PAGE_SHIFT), MHP_MERGE_RESOURCE); 741 + HA_BYTES_IN_CHUNK, MHP_MERGE_RESOURCE); 739 742 740 743 if (ret) { 741 744 pr_err("hot_add memory failed error is %d\n", ret); ··· 743 760 do_hot_add = false; 744 761 } 745 762 scoped_guard(spinlock_irqsave, &dm_device.ha_lock) { 746 - has->ha_end_pfn -= HA_CHUNK; 763 + has->ha_end_pfn -= ha_pages_in_chunk; 747 764 has->covered_end_pfn -= processed_pfn; 748 765 } 749 766 break; ··· 770 787 guard(spinlock_irqsave)(&dm_device.ha_lock); 771 788 list_for_each_entry(has, &dm_device.ha_region_list, list) { 772 789 /* The page belongs to a different HAS. */ 773 - if ((pfn < has->start_pfn) || 774 - (pfn + (1UL << order) > has->end_pfn)) 790 + if (pfn < has->start_pfn || 791 + (pfn + (1UL << order) > has->end_pfn)) 775 792 continue; 776 793 777 794 hv_bring_pgs_online(has, pfn, 1UL << order); ··· 783 800 { 784 801 struct hv_hotadd_state *has; 785 802 struct hv_hotadd_gap *gap; 786 - unsigned long residual, new_inc; 803 + unsigned long residual; 787 804 int ret = 0; 788 805 789 806 guard(spinlock_irqsave)(&dm_device.ha_lock); ··· 819 836 * our current limit; extend it. 820 837 */ 821 838 if ((start_pfn + pfn_cnt) > has->end_pfn) { 839 + /* Extend the region by multiples of ha_pages_in_chunk */ 822 840 residual = (start_pfn + pfn_cnt - has->end_pfn); 823 - /* 824 - * Extend the region by multiples of HA_CHUNK. 825 - */ 826 - new_inc = (residual / HA_CHUNK) * HA_CHUNK; 827 - if (residual % HA_CHUNK) 828 - new_inc += HA_CHUNK; 829 - 830 - has->end_pfn += new_inc; 841 + has->end_pfn += ALIGN(residual, ha_pages_in_chunk); 831 842 } 832 843 833 844 ret = 1; ··· 832 855 } 833 856 834 857 static unsigned long handle_pg_range(unsigned long pg_start, 835 - unsigned long pg_count) 858 + unsigned long pg_count) 836 859 { 837 860 unsigned long start_pfn = pg_start; 838 861 unsigned long pfn_cnt = pg_count; ··· 843 866 unsigned long res = 0, flags; 844 867 845 868 pr_debug("Hot adding %lu pages starting at pfn 0x%lx.\n", pg_count, 846 - pg_start); 869 + pg_start); 847 870 848 871 spin_lock_irqsave(&dm_device.ha_lock, flags); 849 872 list_for_each_entry(has, &dm_device.ha_region_list, list) { ··· 879 902 if (start_pfn > has->start_pfn && 880 903 online_section_nr(pfn_to_section_nr(start_pfn))) 881 904 hv_bring_pgs_online(has, start_pfn, pgs_ol); 882 - 883 905 } 884 906 885 - if ((has->ha_end_pfn < has->end_pfn) && (pfn_cnt > 0)) { 907 + if (has->ha_end_pfn < has->end_pfn && pfn_cnt > 0) { 886 908 /* 887 909 * We have some residual hot add range 888 910 * that needs to be hot added; hot add 889 911 * it now. Hot add a multiple of 890 - * HA_CHUNK that fully covers the pages 912 + * ha_pages_in_chunk that fully covers the pages 891 913 * we have. 892 914 */ 893 915 size = (has->end_pfn - has->ha_end_pfn); 894 916 if (pfn_cnt <= size) { 895 - size = ((pfn_cnt / HA_CHUNK) * HA_CHUNK); 896 - if (pfn_cnt % HA_CHUNK) 897 - size += HA_CHUNK; 917 + size = ALIGN(pfn_cnt, ha_pages_in_chunk); 898 918 } else { 899 919 pfn_cnt = size; 900 920 } ··· 984 1010 rg_start = dm->ha_wrk.ha_region_range.finfo.start_page; 985 1011 rg_sz = dm->ha_wrk.ha_region_range.finfo.page_cnt; 986 1012 987 - if ((rg_start == 0) && (!dm->host_specified_ha_region)) { 988 - unsigned long region_size; 989 - unsigned long region_start; 990 - 1013 + if (rg_start == 0 && !dm->host_specified_ha_region) { 991 1014 /* 992 1015 * The host has not specified the hot-add region. 993 1016 * Based on the hot-add page range being specified, ··· 992 1021 * that need to be hot-added while ensuring the alignment 993 1022 * and size requirements of Linux as it relates to hot-add. 994 1023 */ 995 - region_size = (pfn_cnt / HA_CHUNK) * HA_CHUNK; 996 - if (pfn_cnt % HA_CHUNK) 997 - region_size += HA_CHUNK; 998 - 999 - region_start = (pg_start / HA_CHUNK) * HA_CHUNK; 1000 - 1001 - rg_start = region_start; 1002 - rg_sz = region_size; 1024 + rg_start = ALIGN_DOWN(pg_start, ha_pages_in_chunk); 1025 + rg_sz = ALIGN(pfn_cnt, ha_pages_in_chunk); 1003 1026 } 1004 1027 1005 1028 if (do_hot_add) 1006 1029 resp.page_count = process_hot_add(pg_start, pfn_cnt, 1007 - rg_start, rg_sz); 1030 + rg_start, rg_sz); 1008 1031 1009 1032 dm->num_pages_added += resp.page_count; 1010 1033 #endif ··· 1176 1211 sizeof(struct dm_status), 1177 1212 (unsigned long)NULL, 1178 1213 VM_PKT_DATA_INBAND, 0); 1179 - 1180 1214 } 1181 1215 1182 1216 static void free_balloon_pages(struct hv_dynmem_device *dm, 1183 - union dm_mem_page_range *range_array) 1217 + union dm_mem_page_range *range_array) 1184 1218 { 1185 1219 int num_pages = range_array->finfo.page_cnt; 1186 1220 __u64 start_frame = range_array->finfo.start_page; ··· 1194 1230 adjust_managed_page_count(pg, 1); 1195 1231 } 1196 1232 } 1197 - 1198 - 1199 1233 1200 1234 static unsigned int alloc_balloon_pages(struct hv_dynmem_device *dm, 1201 1235 unsigned int num_pages, ··· 1240 1278 page_to_pfn(pg); 1241 1279 bl_resp->range_array[i].finfo.page_cnt = alloc_unit; 1242 1280 bl_resp->hdr.size += sizeof(union dm_mem_page_range); 1243 - 1244 1281 } 1245 1282 1246 1283 return i * alloc_unit; ··· 1293 1332 1294 1333 if (num_ballooned == 0 || num_ballooned == num_pages) { 1295 1334 pr_debug("Ballooned %u out of %u requested pages.\n", 1296 - num_pages, dm_device.balloon_wrk.num_pages); 1335 + num_pages, dm_device.balloon_wrk.num_pages); 1297 1336 1298 1337 bl_resp->more_pages = 0; 1299 1338 done = true; ··· 1327 1366 1328 1367 for (i = 0; i < bl_resp->range_count; i++) 1329 1368 free_balloon_pages(&dm_device, 1330 - &bl_resp->range_array[i]); 1369 + &bl_resp->range_array[i]); 1331 1370 1332 1371 done = true; 1333 1372 } 1334 1373 } 1335 - 1336 1374 } 1337 1375 1338 1376 static void balloon_down(struct hv_dynmem_device *dm, 1339 - struct dm_unballoon_request *req) 1377 + struct dm_unballoon_request *req) 1340 1378 { 1341 1379 union dm_mem_page_range *range_array = req->range_array; 1342 1380 int range_count = req->range_count; ··· 1349 1389 } 1350 1390 1351 1391 pr_debug("Freed %u ballooned pages.\n", 1352 - prev_pages_ballooned - dm->num_pages_ballooned); 1392 + prev_pages_ballooned - dm->num_pages_ballooned); 1353 1393 1354 1394 if (req->more_pages == 1) 1355 1395 return; ··· 1374 1414 struct hv_dynmem_device *dm = dm_dev; 1375 1415 1376 1416 while (!kthread_should_stop()) { 1377 - wait_for_completion_interruptible_timeout( 1378 - &dm_device.config_event, 1*HZ); 1417 + wait_for_completion_interruptible_timeout(&dm_device.config_event, 1 * HZ); 1379 1418 /* 1380 1419 * The host expects us to post information on the memory 1381 1420 * pressure every second. ··· 1398 1439 return 0; 1399 1440 } 1400 1441 1401 - 1402 1442 static void version_resp(struct hv_dynmem_device *dm, 1403 - struct dm_version_response *vresp) 1443 + struct dm_version_response *vresp) 1404 1444 { 1405 1445 struct dm_version_request version_req; 1406 1446 int ret; ··· 1460 1502 } 1461 1503 1462 1504 static void cap_resp(struct hv_dynmem_device *dm, 1463 - struct dm_capabilities_resp_msg *cap_resp) 1505 + struct dm_capabilities_resp_msg *cap_resp) 1464 1506 { 1465 1507 if (!cap_resp->is_accepted) { 1466 1508 pr_err("Capabilities not accepted by host\n"); ··· 1493 1535 switch (dm_hdr->type) { 1494 1536 case DM_VERSION_RESPONSE: 1495 1537 version_resp(dm, 1496 - (struct dm_version_response *)dm_msg); 1538 + (struct dm_version_response *)dm_msg); 1497 1539 break; 1498 1540 1499 1541 case DM_CAPABILITIES_RESPONSE: ··· 1523 1565 1524 1566 dm->state = DM_BALLOON_DOWN; 1525 1567 balloon_down(dm, 1526 - (struct dm_unballoon_request *)recv_buffer); 1568 + (struct dm_unballoon_request *)recv_buffer); 1527 1569 break; 1528 1570 1529 1571 case DM_MEM_HOT_ADD_REQUEST: ··· 1561 1603 1562 1604 default: 1563 1605 pr_warn_ratelimited("Unhandled message: type: %d\n", dm_hdr->type); 1564 - 1565 1606 } 1566 1607 } 1567 - 1568 1608 } 1569 1609 1570 1610 #define HV_LARGE_REPORTING_ORDER 9 1571 1611 #define HV_LARGE_REPORTING_LEN (HV_HYP_PAGE_SIZE << \ 1572 1612 HV_LARGE_REPORTING_ORDER) 1573 1613 static int hv_free_page_report(struct page_reporting_dev_info *pr_dev_info, 1574 - struct scatterlist *sgl, unsigned int nents) 1614 + struct scatterlist *sgl, unsigned int nents) 1575 1615 { 1576 1616 unsigned long flags; 1577 1617 struct hv_memory_hint *hint; ··· 1604 1648 */ 1605 1649 1606 1650 /* page reporting for pages 2MB or higher */ 1607 - if (order >= HV_LARGE_REPORTING_ORDER ) { 1651 + if (order >= HV_LARGE_REPORTING_ORDER) { 1608 1652 range->page.largepage = 1; 1609 1653 range->page_size = HV_GPA_PAGE_RANGE_PAGE_SIZE_2MB; 1610 1654 range->base_large_pfn = page_to_hvpfn( ··· 1618 1662 range->page.additional_pages = 1619 1663 (sg->length / HV_HYP_PAGE_SIZE) - 1; 1620 1664 } 1621 - 1622 1665 } 1623 1666 1624 1667 status = hv_do_rep_hypercall(HV_EXT_CALL_MEMORY_HEAT_HINT, nents, 0, 1625 1668 hint, NULL); 1626 1669 local_irq_restore(flags); 1627 1670 if (!hv_result_success(status)) { 1628 - 1629 1671 pr_err("Cold memory discard hypercall failed with status %llx\n", 1630 - status); 1672 + status); 1631 1673 if (hv_hypercall_multi_failure > 0) 1632 1674 hv_hypercall_multi_failure++; 1633 1675 1634 1676 if (hv_result(status) == HV_STATUS_INVALID_PARAMETER) { 1635 1677 pr_err("Underlying Hyper-V does not support order less than 9. Hypercall failed\n"); 1636 1678 pr_err("Defaulting to page_reporting_order %d\n", 1637 - pageblock_order); 1679 + pageblock_order); 1638 1680 page_reporting_order = pageblock_order; 1639 1681 hv_hypercall_multi_failure++; 1640 1682 return -EINVAL; ··· 1666 1712 pr_err("Failed to enable cold memory discard: %d\n", ret); 1667 1713 } else { 1668 1714 pr_info("Cold memory discard hint enabled with order %d\n", 1669 - page_reporting_order); 1715 + page_reporting_order); 1670 1716 } 1671 1717 } 1672 1718 ··· 1749 1795 if (ret) 1750 1796 goto out; 1751 1797 1752 - t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); 1798 + t = wait_for_completion_timeout(&dm_device.host_event, 5 * HZ); 1753 1799 if (t == 0) { 1754 1800 ret = -ETIMEDOUT; 1755 1801 goto out; ··· 1785 1831 cap_msg.caps.cap_bits.hot_add = hot_add_enabled(); 1786 1832 1787 1833 /* 1788 - * Specify our alignment requirements as it relates 1789 - * memory hot-add. Specify 128MB alignment. 1834 + * Specify our alignment requirements for memory hot-add. The value is 1835 + * the log base 2 of the number of megabytes in a chunk. For example, 1836 + * with 256 MiB chunks, the value is 8. The number of MiB in a chunk 1837 + * must be a power of 2. 1790 1838 */ 1791 - cap_msg.caps.cap_bits.hot_add_alignment = 7; 1839 + cap_msg.caps.cap_bits.hot_add_alignment = 1840 + ilog2(HA_BYTES_IN_CHUNK / SZ_1M); 1792 1841 1793 1842 /* 1794 1843 * Currently the host does not use these ··· 1807 1850 if (ret) 1808 1851 goto out; 1809 1852 1810 - t = wait_for_completion_timeout(&dm_device.host_event, 5*HZ); 1853 + t = wait_for_completion_timeout(&dm_device.host_event, 5 * HZ); 1811 1854 if (t == 0) { 1812 1855 ret = -ETIMEDOUT; 1813 1856 goto out; ··· 1848 1891 char *sname; 1849 1892 1850 1893 seq_printf(f, "%-22s: %u.%u\n", "host_version", 1851 - DYNMEM_MAJOR_VERSION(dm->version), 1852 - DYNMEM_MINOR_VERSION(dm->version)); 1894 + DYNMEM_MAJOR_VERSION(dm->version), 1895 + DYNMEM_MINOR_VERSION(dm->version)); 1853 1896 1854 1897 seq_printf(f, "%-22s:", "capabilities"); 1855 1898 if (ballooning_enabled()) ··· 1898 1941 seq_printf(f, "%-22s: %u\n", "pages_ballooned", dm->num_pages_ballooned); 1899 1942 1900 1943 seq_printf(f, "%-22s: %lu\n", "total_pages_committed", 1901 - get_pages_committed(dm)); 1944 + get_pages_committed(dm)); 1902 1945 1903 1946 seq_printf(f, "%-22s: %llu\n", "max_dynamic_page_count", 1904 - dm->max_dynamic_page_count); 1947 + dm->max_dynamic_page_count); 1905 1948 1906 1949 return 0; 1907 1950 } ··· 1911 1954 static void hv_balloon_debugfs_init(struct hv_dynmem_device *b) 1912 1955 { 1913 1956 debugfs_create_file("hv-balloon", 0444, NULL, b, 1914 - &hv_balloon_debug_fops); 1957 + &hv_balloon_debug_fops); 1915 1958 } 1916 1959 1917 1960 static void hv_balloon_debugfs_exit(struct hv_dynmem_device *b) ··· 1941 1984 hot_add = false; 1942 1985 1943 1986 #ifdef CONFIG_MEMORY_HOTPLUG 1987 + /* 1988 + * Hot-add must operate in chunks that are of size equal to the 1989 + * memory block size because that's what the core add_memory() 1990 + * interface requires. The Hyper-V interface requires that the memory 1991 + * block size be a power of 2, which is guaranteed by the check in 1992 + * memory_dev_init(). 1993 + */ 1994 + ha_pages_in_chunk = memory_block_size_bytes() / PAGE_SIZE; 1944 1995 do_hot_add = hot_add; 1945 1996 #else 1997 + /* 1998 + * Without MEMORY_HOTPLUG, the guest returns a failure status for all 1999 + * hot add requests from Hyper-V, and the chunk size is used only to 2000 + * specify alignment to Hyper-V as required by the host/guest protocol. 2001 + * Somewhat arbitrarily, use 128 MiB. 2002 + */ 2003 + ha_pages_in_chunk = SZ_128M / PAGE_SIZE; 1946 2004 do_hot_add = false; 1947 2005 #endif 1948 2006 dm_device.dev = dev; ··· 2069 2097 tasklet_enable(&hv_dev->channel->callback_event); 2070 2098 2071 2099 return 0; 2072 - 2073 2100 } 2074 2101 2075 2102 static int balloon_resume(struct hv_device *dev) ··· 2127 2156 2128 2157 static int __init init_balloon_drv(void) 2129 2158 { 2130 - 2131 2159 return vmbus_driver_register(&balloon_drv); 2132 2160 } 2133 2161
+1
tools/hv/Makefile
··· 17 17 MAKEFLAGS += -r 18 18 19 19 override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include 20 + override CFLAGS += -Wno-address-of-packed-member 20 21 21 22 ALL_TARGETS := hv_kvp_daemon hv_vss_daemon 22 23 ifneq ($(ARCH), aarch64)