Skip to content

Commit a494aef

Browse files
dcuiliuw
authored andcommitted
PCI: hv: Replace retarget_msi_interrupt_params with hyperv_pcpu_input_arg
4 commits are involved here: A (2016): commit 0de8ce3 ("PCI: hv: Allocate physically contiguous hypercall params buffer") B (2017): commit be66b67 ("PCI: hv: Use page allocation for hbus structure") C (2019): commit 877b911 ("PCI: hv: Avoid a kmemleak false positive caused by the hbus buffer") D (2018): commit 68bb7bf ("X86/Hyper-V: Enable IPI enlightenments") Patch D introduced the per-CPU hypercall input page "hyperv_pcpu_input_arg" in 2018. With patch D, we no longer need the per-Hyper-V-PCI-bus hypercall input page "hbus->retarget_msi_interrupt_params" that was added in patch A, and the issue addressed by patch B is no longer an issue, and we can also get rid of patch C. The change here is required for PCI device assignment to work for Confidential VMs (CVMs) running without a paravisor, because otherwise we would have to call set_memory_decrypted() for "hbus->retarget_msi_interrupt_params" before calling the hypercall HVCALL_RETARGET_INTERRUPT. Signed-off-by: Dexuan Cui <decui@microsoft.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Acked-by: Lorenzo Pieralisi <lpieralisi@kernel.org> Link: https://lore.kernel.org/r/20230421013025.17152-1-decui@microsoft.com Signed-off-by: Wei Liu <wei.liu@kernel.org>
1 parent 9c318a1 commit a494aef

1 file changed

Lines changed: 7 additions & 41 deletions

File tree

drivers/pci/controller/pci-hyperv.c

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -508,20 +508,11 @@ struct hv_pcibus_device {
508508
struct msi_domain_info msi_info;
509509
struct irq_domain *irq_domain;
510510

511-
spinlock_t retarget_msi_interrupt_lock;
512-
513511
struct workqueue_struct *wq;
514512

515513
/* Highest slot of child device with resources allocated */
516514
int wslot_res_allocated;
517515
bool use_calls; /* Use hypercalls to access mmio cfg space */
518-
519-
/* hypercall arg, must not cross page boundary */
520-
struct hv_retarget_device_interrupt retarget_msi_interrupt_params;
521-
522-
/*
523-
* Don't put anything here: retarget_msi_interrupt_params must be last
524-
*/
525516
};
526517

527518
/*
@@ -645,9 +636,9 @@ static void hv_arch_irq_unmask(struct irq_data *data)
645636
hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
646637
int_desc = data->chip_data;
647638

648-
spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags);
639+
local_irq_save(flags);
649640

650-
params = &hbus->retarget_msi_interrupt_params;
641+
params = *this_cpu_ptr(hyperv_pcpu_input_arg);
651642
memset(params, 0, sizeof(*params));
652643
params->partition_id = HV_PARTITION_ID_SELF;
653644
params->int_entry.source = HV_INTERRUPT_SOURCE_MSI;
@@ -680,7 +671,7 @@ static void hv_arch_irq_unmask(struct irq_data *data)
680671

681672
if (!alloc_cpumask_var(&tmp, GFP_ATOMIC)) {
682673
res = 1;
683-
goto exit_unlock;
674+
goto out;
684675
}
685676

686677
cpumask_and(tmp, dest, cpu_online_mask);
@@ -689,7 +680,7 @@ static void hv_arch_irq_unmask(struct irq_data *data)
689680

690681
if (nr_bank <= 0) {
691682
res = 1;
692-
goto exit_unlock;
683+
goto out;
693684
}
694685

695686
/*
@@ -708,8 +699,8 @@ static void hv_arch_irq_unmask(struct irq_data *data)
708699
res = hv_do_hypercall(HVCALL_RETARGET_INTERRUPT | (var_size << 17),
709700
params, NULL);
710701

711-
exit_unlock:
712-
spin_unlock_irqrestore(&hbus->retarget_msi_interrupt_lock, flags);
702+
out:
703+
local_irq_restore(flags);
713704

714705
/*
715706
* During hibernation, when a CPU is offlined, the kernel tries
@@ -3598,35 +3589,11 @@ static int hv_pci_probe(struct hv_device *hdev,
35983589
bool enter_d0_retry = true;
35993590
int ret;
36003591

3601-
/*
3602-
* hv_pcibus_device contains the hypercall arguments for retargeting in
3603-
* hv_irq_unmask(). Those must not cross a page boundary.
3604-
*/
3605-
BUILD_BUG_ON(sizeof(*hbus) > HV_HYP_PAGE_SIZE);
3606-
36073592
bridge = devm_pci_alloc_host_bridge(&hdev->device, 0);
36083593
if (!bridge)
36093594
return -ENOMEM;
36103595

3611-
/*
3612-
* With the recent 59bb47985c1d ("mm, sl[aou]b: guarantee natural
3613-
* alignment for kmalloc(power-of-two)"), kzalloc() is able to allocate
3614-
* a 4KB buffer that is guaranteed to be 4KB-aligned. Here the size and
3615-
* alignment of hbus is important because hbus's field
3616-
* retarget_msi_interrupt_params must not cross a 4KB page boundary.
3617-
*
3618-
* Here we prefer kzalloc to get_zeroed_page(), because a buffer
3619-
* allocated by the latter is not tracked and scanned by kmemleak, and
3620-
* hence kmemleak reports the pointer contained in the hbus buffer
3621-
* (i.e. the hpdev struct, which is created in new_pcichild_device() and
3622-
* is tracked by hbus->children) as memory leak (false positive).
3623-
*
3624-
* If the kernel doesn't have 59bb47985c1d, get_zeroed_page() *must* be
3625-
* used to allocate the hbus buffer and we can avoid the kmemleak false
3626-
* positive by using kmemleak_alloc() and kmemleak_free() to ask
3627-
* kmemleak to track and scan the hbus buffer.
3628-
*/
3629-
hbus = kzalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
3596+
hbus = kzalloc(sizeof(*hbus), GFP_KERNEL);
36303597
if (!hbus)
36313598
return -ENOMEM;
36323599

@@ -3683,7 +3650,6 @@ static int hv_pci_probe(struct hv_device *hdev,
36833650
INIT_LIST_HEAD(&hbus->dr_list);
36843651
spin_lock_init(&hbus->config_lock);
36853652
spin_lock_init(&hbus->device_list_lock);
3686-
spin_lock_init(&hbus->retarget_msi_interrupt_lock);
36873653
hbus->wq = alloc_ordered_workqueue("hv_pci_%x", 0,
36883654
hbus->bridge->domain_nr);
36893655
if (!hbus->wq) {

0 commit comments

Comments
 (0)