diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index c98cc134ff9ad323bec12539d215d16bb2a66737..34a7234ab983908b122c9f88a800984ed566a4b0 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -358,6 +358,25 @@ static void mpam_enable_squash_features(void) } } +static int mpam_allocate_config(void) +{ + struct mpam_class *class; + struct mpam_component *comp; + + lockdep_assert_held(&mpam_devices_lock); + + list_for_each_entry(class, &mpam_classes, classes_list) { + list_for_each_entry(comp, &class->components, class_list) { + comp->cfg = kcalloc(mpam_sysprops_num_partid(), sizeof(*comp->cfg), + GFP_KERNEL); + if (!comp->cfg) + return -ENOMEM; + } + } + + return 0; +} + /* * Enable mpam once all devices have been probed. * Scheduled by mpam_discovery_complete() once all devices have been created. @@ -365,6 +384,7 @@ static void mpam_enable_squash_features(void) */ static void __init mpam_enable(struct work_struct *work) { + int err; unsigned long flags; struct mpam_device *dev; bool all_devices_probed = true; @@ -387,6 +407,9 @@ static void __init mpam_enable(struct work_struct *work) mutex_lock(&mpam_devices_lock); mpam_enable_squash_features(); + err = mpam_allocate_config(); + if (err) + return; mutex_unlock(&mpam_devices_lock); } @@ -511,6 +534,7 @@ static void mpam_class_destroy(struct mpam_class *class) list_for_each_entry_safe(comp, tmp, &class->components, class_list) { mpam_devices_destroy(comp); list_del(&comp->class_list); + kfree(comp->cfg); kfree(comp); } } diff --git a/arch/arm64/kernel/mpam/mpam_device.h b/arch/arm64/kernel/mpam/mpam_device.h index 05f8431c71fcbb7180dbf86c4299ff50b9e7ddcd..a98c3474237414803bc2108de0d0964161194c0a 100644 --- a/arch/arm64/kernel/mpam/mpam_device.h +++ b/arch/arm64/kernel/mpam/mpam_device.h @@ -7,6 +7,8 @@ #include #include "mpam_internal.h" +struct mpam_config; + /* * Size of the memory mapped registers: 4K of feature page * then 2x 4K bitmap registers @@ -74,6 +76,8 @@ struct mpam_component { struct cpumask fw_affinity; + struct mpam_config *cfg; + /* member of mpam_class:components */ struct list_head class_list; }; diff --git a/arch/arm64/kernel/mpam/mpam_internal.h b/arch/arm64/kernel/mpam/mpam_internal.h index 2579d111d7dfddc35afe6b07140c362237e91a25..53df10e84554b3c9c3285192a1a4767caf9d5683 100644 --- a/arch/arm64/kernel/mpam/mpam_internal.h +++ b/arch/arm64/kernel/mpam/mpam_internal.h @@ -4,6 +4,37 @@ typedef u32 mpam_features_t; +/* + * MPAM component config Structure + */ +struct mpam_config { + + /* + * The biggest config we could pass around is 4K, but resctrl's max + * cbm is u32, so we only need the full-size config during reset. + * Just in case a cache with a >u32 bitmap is exported for another + * reason, we need to track which bits of the configuration are valid. + */ + mpam_features_t valid; + + u32 cpbm; + u32 mbw_pbm; + u16 mbw_max; + + /* + * dspri is downstream priority, intpri is internal priority. + */ + u16 dspri; + u16 intpri; + + /* + * hardlimit or not + */ + bool hdl; + + u32 intpartid; +}; + /* Bits for mpam_features_t */ enum mpam_device_features { mpam_feat_ccap_part = 0,