The name "cpu" in the parameter is misleading as it represents the physical apicid of the cpu. Hence rename it. Introduce flags to determine the state of the vCPU (running or not) and posted interrupts. This is useful as following patch overloads the apicid (formerly cpu) field to determine GAPPI destination when vCPU is not running and it can no longer be used to determine if vCPU is running or not. Signed-off-by: Sairaj Kodilkar --- arch/x86/include/asm/irq_remapping.h | 4 ++-- arch/x86/kvm/svm/avic.c | 22 ++++++++++++++-------- drivers/iommu/amd/iommu.c | 24 ++++++++++++------------ include/linux/amd-iommu.h | 14 ++++++++++---- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/arch/x86/include/asm/irq_remapping.h b/arch/x86/include/asm/irq_remapping.h index 37b94f484ef3..40a2206a33c0 100644 --- a/arch/x86/include/asm/irq_remapping.h +++ b/arch/x86/include/asm/irq_remapping.h @@ -35,8 +35,8 @@ struct amd_iommu_pi_data { u64 vapic_addr; /* Physical address of the vCPU's vAPIC. */ u32 ga_tag; u32 vector; /* Guest vector of the interrupt */ - int cpu; - bool ga_log_intr; + int apicid; + int flags; bool is_guest_mode; void *ir_data; }; diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index cdd5a6dc646f..7862b13c5409 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -932,6 +932,7 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm, struct vcpu_svm *svm = to_svm(vcpu); u64 entry; int ret; + int posted_intr; /* * Prevent the vCPU from being scheduled out or migrated until @@ -949,10 +950,11 @@ int avic_pi_update_irte(struct kvm_kernel_irqfd *irqfd, struct kvm *kvm, */ entry = svm->avic_physical_id_entry; if (entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK) { - pi_data.cpu = entry & AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK; + pi_data.apicid = entry & AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK; + pi_data.flags = AMD_IOMMU_FLAG_VCPU_RUNNING; } else { - pi_data.cpu = -1; - pi_data.ga_log_intr = entry & AVIC_PHYSICAL_ID_ENTRY_GA_LOG_INTR; + posted_intr = !!(entry & AVIC_PHYSICAL_ID_ENTRY_GA_LOG_INTR); + pi_data.flags = posted_intr << AMD_IOMMU_FLAG_POSTED_INTR_SHIFT; } ret = irq_set_vcpu_affinity(host_irq, &pi_data); @@ -1004,10 +1006,14 @@ enum avic_vcpu_action { AVIC_START_BLOCKING = BIT(1), }; -static void avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, +static void avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int apicid, enum avic_vcpu_action action) { - bool ga_log_intr = (action & AVIC_START_BLOCKING); + int posted_intr = !!(action & AVIC_START_BLOCKING) << + AMD_IOMMU_FLAG_POSTED_INTR_SHIFT; + int is_vcpu_running = (apicid >= 0) << + AMD_IOMMU_FLAG_VCPU_RUNNING_SHIFT; + int flags = posted_intr | is_vcpu_running; struct vcpu_svm *svm = to_svm(vcpu); struct kvm_kernel_irqfd *irqfd; @@ -1024,9 +1030,9 @@ static void avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, void *data = irqfd->irq_bypass_data; if (!(action & AVIC_TOGGLE_ON_OFF)) - WARN_ON_ONCE(amd_iommu_update_ga(data, cpu, ga_log_intr)); - else if (cpu >= 0) - WARN_ON_ONCE(amd_iommu_activate_guest_mode(data, cpu, ga_log_intr)); + WARN_ON_ONCE(amd_iommu_update_ga(data, apicid, flags)); + else if (is_vcpu_running) + WARN_ON_ONCE(amd_iommu_activate_guest_mode(data, apicid, flags)); else WARN_ON_ONCE(amd_iommu_deactivate_guest_mode(data)); } diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index 57dc8fabc7d9..76f0e469490e 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -3959,19 +3959,19 @@ static const struct irq_domain_ops amd_ir_domain_ops = { .deactivate = irq_remapping_deactivate, }; -static void __amd_iommu_update_ga(struct irte_ga *entry, int cpu, - bool ga_log_intr) +static void __amd_iommu_update_ga(struct irte_ga *entry, int apicid, int flags) { - if (cpu >= 0) { + if (flags & AMD_IOMMU_FLAG_VCPU_RUNNING) { entry->lo.fields_vapic.destination = - APICID_TO_IRTE_DEST_LO(cpu); + APICID_TO_IRTE_DEST_LO(apicid); entry->hi.fields.destination = - APICID_TO_IRTE_DEST_HI(cpu); + APICID_TO_IRTE_DEST_HI(apicid); entry->lo.fields_vapic.is_run = true; entry->lo.fields_vapic.ga_log_intr = false; } else { entry->lo.fields_vapic.is_run = false; - entry->lo.fields_vapic.ga_log_intr = ga_log_intr; + entry->lo.fields_vapic.ga_log_intr = !!(flags & + AMD_IOMMU_FLAG_POSTED_INTR); } } @@ -3992,7 +3992,7 @@ static void __amd_iommu_update_ga(struct irte_ga *entry, int cpu, * and thus don't require an invalidation to ensure the IOMMU consumes fresh * information. */ -int amd_iommu_update_ga(void *data, int cpu, bool ga_log_intr) +int amd_iommu_update_ga(void *data, int apicid, int flags) { struct amd_ir_data *ir_data = (struct amd_ir_data *)data; struct irte_ga *entry = (struct irte_ga *) ir_data->entry; @@ -4006,14 +4006,14 @@ int amd_iommu_update_ga(void *data, int cpu, bool ga_log_intr) if (!ir_data->iommu) return -ENODEV; - __amd_iommu_update_ga(entry, cpu, ga_log_intr); + __amd_iommu_update_ga(entry, apicid, flags); return __modify_irte_ga(ir_data->iommu, ir_data->irq_2_irte.devid, ir_data->irq_2_irte.index, entry); } EXPORT_SYMBOL(amd_iommu_update_ga); -int amd_iommu_activate_guest_mode(void *data, int cpu, bool ga_log_intr) +int amd_iommu_activate_guest_mode(void *data, int apicid, int flags) { struct amd_ir_data *ir_data = (struct amd_ir_data *)data; struct irte_ga *entry = (struct irte_ga *) ir_data->entry; @@ -4036,7 +4036,7 @@ int amd_iommu_activate_guest_mode(void *data, int cpu, bool ga_log_intr) entry->hi.fields.vector = ir_data->ga_vector; entry->lo.fields_vapic.ga_tag = ir_data->ga_tag; - __amd_iommu_update_ga(entry, cpu, ga_log_intr); + __amd_iommu_update_ga(entry, apicid, flags); return modify_irte_ga(ir_data->iommu, ir_data->irq_2_irte.devid, ir_data->irq_2_irte.index, entry); @@ -4107,8 +4107,8 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *info) ir_data->ga_vector = pi_data->vector; ir_data->ga_tag = pi_data->ga_tag; if (pi_data->is_guest_mode) - ret = amd_iommu_activate_guest_mode(ir_data, pi_data->cpu, - pi_data->ga_log_intr); + ret = amd_iommu_activate_guest_mode(ir_data, pi_data->apicid, + pi_data->flags); else ret = amd_iommu_deactivate_guest_mode(ir_data); } else { diff --git a/include/linux/amd-iommu.h b/include/linux/amd-iommu.h index edcee9f5335a..3dd9074e5967 100644 --- a/include/linux/amd-iommu.h +++ b/include/linux/amd-iommu.h @@ -30,8 +30,8 @@ static inline void amd_iommu_detect(void) { } /* IOMMU AVIC Function */ extern int amd_iommu_register_ga_log_notifier(int (*notifier)(u32)); -extern int amd_iommu_update_ga(void *data, int cpu, bool ga_log_intr); -extern int amd_iommu_activate_guest_mode(void *data, int cpu, bool ga_log_intr); +extern int amd_iommu_update_ga(void *data, int apicid, int flags); +extern int amd_iommu_activate_guest_mode(void *data, int apicid, int flags); extern int amd_iommu_deactivate_guest_mode(void *data); #else /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */ @@ -42,12 +42,12 @@ amd_iommu_register_ga_log_notifier(int (*notifier)(u32)) return 0; } -static inline int amd_iommu_update_ga(void *data, int cpu, bool ga_log_intr) +static inline int amd_iommu_update_ga(void *data, int apicid, int flags) { return 0; } -static inline int amd_iommu_activate_guest_mode(void *data, int cpu, bool ga_log_intr) +static inline int amd_iommu_activate_guest_mode(void *data, int apicid, int flags) { return 0; } @@ -76,4 +76,10 @@ static inline int amd_iommu_snp_disable(void) { return 0; } static inline bool amd_iommu_sev_tio_supported(void) { return false; } #endif +#define AMD_IOMMU_FLAG_VCPU_RUNNING_SHIFT 0 +#define AMD_IOMMU_FLAG_VCPU_RUNNING BIT(0) + +#define AMD_IOMMU_FLAG_POSTED_INTR_SHIFT 1 +#define AMD_IOMMU_FLAG_POSTED_INTR BIT(1) + #endif /* _ASM_X86_AMD_IOMMU_H */ -- 2.34.1