Skip to content

Commit b9c6ff9

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Re-factor guest virtual APIC (de-)activation code
Re-factore the logic for activate/deactivate guest virtual APIC mode (GAM) into helper functions, and export them for other drivers (e.g. SVM). to support run-time activate/deactivate of SVM AVIC. Cc: Joerg Roedel <[email protected]> Signed-off-by: Suravee Suthikulpanit <[email protected]> Signed-off-by: Joerg Roedel <[email protected]>
1 parent e21a712 commit b9c6ff9

File tree

3 files changed

+82
-24
lines changed

3 files changed

+82
-24
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4313,13 +4313,62 @@ static const struct irq_domain_ops amd_ir_domain_ops = {
43134313
.deactivate = irq_remapping_deactivate,
43144314
};
43154315

4316+
int amd_iommu_activate_guest_mode(void *data)
4317+
{
4318+
struct amd_ir_data *ir_data = (struct amd_ir_data *)data;
4319+
struct irte_ga *entry = (struct irte_ga *) ir_data->entry;
4320+
4321+
if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) ||
4322+
!entry || entry->lo.fields_vapic.guest_mode)
4323+
return 0;
4324+
4325+
entry->lo.val = 0;
4326+
entry->hi.val = 0;
4327+
4328+
entry->lo.fields_vapic.guest_mode = 1;
4329+
entry->lo.fields_vapic.ga_log_intr = 1;
4330+
entry->hi.fields.ga_root_ptr = ir_data->ga_root_ptr;
4331+
entry->hi.fields.vector = ir_data->ga_vector;
4332+
entry->lo.fields_vapic.ga_tag = ir_data->ga_tag;
4333+
4334+
return modify_irte_ga(ir_data->irq_2_irte.devid,
4335+
ir_data->irq_2_irte.index, entry, NULL);
4336+
}
4337+
EXPORT_SYMBOL(amd_iommu_activate_guest_mode);
4338+
4339+
int amd_iommu_deactivate_guest_mode(void *data)
4340+
{
4341+
struct amd_ir_data *ir_data = (struct amd_ir_data *)data;
4342+
struct irte_ga *entry = (struct irte_ga *) ir_data->entry;
4343+
struct irq_cfg *cfg = ir_data->cfg;
4344+
4345+
if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) ||
4346+
!entry || !entry->lo.fields_vapic.guest_mode)
4347+
return 0;
4348+
4349+
entry->lo.val = 0;
4350+
entry->hi.val = 0;
4351+
4352+
entry->lo.fields_remap.dm = apic->irq_dest_mode;
4353+
entry->lo.fields_remap.int_type = apic->irq_delivery_mode;
4354+
entry->hi.fields.vector = cfg->vector;
4355+
entry->lo.fields_remap.destination =
4356+
APICID_TO_IRTE_DEST_LO(cfg->dest_apicid);
4357+
entry->hi.fields.destination =
4358+
APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
4359+
4360+
return modify_irte_ga(ir_data->irq_2_irte.devid,
4361+
ir_data->irq_2_irte.index, entry, NULL);
4362+
}
4363+
EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode);
4364+
43164365
static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
43174366
{
4367+
int ret;
43184368
struct amd_iommu *iommu;
43194369
struct amd_iommu_pi_data *pi_data = vcpu_info;
43204370
struct vcpu_data *vcpu_pi_info = pi_data->vcpu_data;
43214371
struct amd_ir_data *ir_data = data->chip_data;
4322-
struct irte_ga *irte = (struct irte_ga *) ir_data->entry;
43234372
struct irq_2_irte *irte_info = &ir_data->irq_2_irte;
43244373
struct iommu_dev_data *dev_data = search_dev_data(irte_info->devid);
43254374

@@ -4330,6 +4379,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
43304379
if (!dev_data || !dev_data->use_vapic)
43314380
return 0;
43324381

4382+
ir_data->cfg = irqd_cfg(data);
43334383
pi_data->ir_data = ir_data;
43344384

43354385
/* Note:
@@ -4348,37 +4398,24 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
43484398

43494399
pi_data->prev_ga_tag = ir_data->cached_ga_tag;
43504400
if (pi_data->is_guest_mode) {
4351-
/* Setting */
4352-
irte->hi.fields.ga_root_ptr = (pi_data->base >> 12);
4353-
irte->hi.fields.vector = vcpu_pi_info->vector;
4354-
irte->lo.fields_vapic.ga_log_intr = 1;
4355-
irte->lo.fields_vapic.guest_mode = 1;
4356-
irte->lo.fields_vapic.ga_tag = pi_data->ga_tag;
4357-
4358-
ir_data->cached_ga_tag = pi_data->ga_tag;
4401+
ir_data->ga_root_ptr = (pi_data->base >> 12);
4402+
ir_data->ga_vector = vcpu_pi_info->vector;
4403+
ir_data->ga_tag = pi_data->ga_tag;
4404+
ret = amd_iommu_activate_guest_mode(ir_data);
4405+
if (!ret)
4406+
ir_data->cached_ga_tag = pi_data->ga_tag;
43594407
} else {
4360-
/* Un-Setting */
4361-
struct irq_cfg *cfg = irqd_cfg(data);
4362-
4363-
irte->hi.val = 0;
4364-
irte->lo.val = 0;
4365-
irte->hi.fields.vector = cfg->vector;
4366-
irte->lo.fields_remap.guest_mode = 0;
4367-
irte->lo.fields_remap.destination =
4368-
APICID_TO_IRTE_DEST_LO(cfg->dest_apicid);
4369-
irte->hi.fields.destination =
4370-
APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
4371-
irte->lo.fields_remap.int_type = apic->irq_delivery_mode;
4372-
irte->lo.fields_remap.dm = apic->irq_dest_mode;
4408+
ret = amd_iommu_deactivate_guest_mode(ir_data);
43734409

43744410
/*
43754411
* This communicates the ga_tag back to the caller
43764412
* so that it can do all the necessary clean up.
43774413
*/
4378-
ir_data->cached_ga_tag = 0;
4414+
if (!ret)
4415+
ir_data->cached_ga_tag = 0;
43794416
}
43804417

4381-
return modify_irte_ga(irte_info->devid, irte_info->index, irte, ir_data);
4418+
return ret;
43824419
}
43834420

43844421

drivers/iommu/amd_iommu_types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,15 @@ struct amd_ir_data {
873873
struct msi_msg msi_entry;
874874
void *entry; /* Pointer to union irte or struct irte_ga */
875875
void *ref; /* Pointer to the actual irte */
876+
877+
/**
878+
* Store information for activate/de-activate
879+
* Guest virtual APIC mode during runtime.
880+
*/
881+
struct irq_cfg *cfg;
882+
int ga_vector;
883+
int ga_root_ptr;
884+
int ga_tag;
876885
};
877886

878887
struct amd_irte_ops {

include/linux/amd-iommu.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ extern int amd_iommu_register_ga_log_notifier(int (*notifier)(u32));
184184
extern int
185185
amd_iommu_update_ga(int cpu, bool is_run, void *data);
186186

187+
extern int amd_iommu_activate_guest_mode(void *data);
188+
extern int amd_iommu_deactivate_guest_mode(void *data);
189+
187190
#else /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
188191

189192
static inline int
@@ -198,6 +201,15 @@ amd_iommu_update_ga(int cpu, bool is_run, void *data)
198201
return 0;
199202
}
200203

204+
static inline int amd_iommu_activate_guest_mode(void *data)
205+
{
206+
return 0;
207+
}
208+
209+
static inline int amd_iommu_deactivate_guest_mode(void *data)
210+
{
211+
return 0;
212+
}
201213
#endif /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
202214

203215
#endif /* _ASM_X86_AMD_IOMMU_H */

0 commit comments

Comments
 (0)