if (!r)
                return rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl.membw.mba_sc;
 
+       /*
+        * The software controller support is only applicable to MBA resource.
+        * Make sure to check for resource type.
+        */
+       if (r->rid != RDT_RESOURCE_MBA)
+               return false;
+
        return r->membw.mba_sc;
 }
 
        struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
        union cpuid_0x10_3_eax eax;
        union cpuid_0x10_x_edx edx;
-       u32 ebx, ecx;
+       u32 ebx, ecx, subleaf;
 
-       cpuid_count(0x80000020, 1, &eax.full, &ebx, &ecx, &edx.full);
+       /*
+        * Query CPUID_Fn80000020_EDX_x01 for MBA and
+        * CPUID_Fn80000020_EDX_x02 for SMBA
+        */
+       subleaf = (r->rid == RDT_RESOURCE_SMBA) ? 2 :  1;
+
+       cpuid_count(0x80000020, subleaf, &eax.full, &ebx, &ecx, &edx.full);
        hw_res->num_closid = edx.split.cos_max + 1;
        r->default_ctrl = MAX_MBA_BW_AMD;
 
        return false;
 }
 
+static __init bool get_slow_mem_config(void)
+{
+       struct rdt_hw_resource *hw_res = &rdt_resources_all[RDT_RESOURCE_SMBA];
+
+       if (!rdt_cpu_has(X86_FEATURE_SMBA))
+               return false;
+
+       if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+               return __rdt_get_mem_config_amd(&hw_res->r_resctrl);
+
+       return false;
+}
+
 static __init bool get_rdt_alloc_resources(void)
 {
        struct rdt_resource *r;
        if (get_mem_config())
                ret = true;
 
+       if (get_slow_mem_config())
+               ret = true;
+
        return ret;
 }
 
                } else if (r->rid == RDT_RESOURCE_MBA) {
                        hw_res->msr_base = MSR_IA32_MBA_BW_BASE;
                        hw_res->msr_update = mba_wrmsr_amd;
+               } else if (r->rid == RDT_RESOURCE_SMBA) {
+                       hw_res->msr_base = MSR_IA32_SMBA_BW_BASE;
+                       hw_res->msr_update = mba_wrmsr_amd;
                }
        }
 }
 
 
        list_for_each_entry(s, &resctrl_schema_all, list) {
                r = s->res;
-               if (r->rid == RDT_RESOURCE_MBA)
+               if (r->rid == RDT_RESOURCE_MBA || r->rid == RDT_RESOURCE_SMBA)
                        continue;
                has_cache = true;
                list_for_each_entry(d, &r->domains, list) {
                                        ctrl = resctrl_arch_get_config(r, d,
                                                                       closid,
                                                                       type);
-                               if (r->rid == RDT_RESOURCE_MBA)
+                               if (r->rid == RDT_RESOURCE_MBA ||
+                                   r->rid == RDT_RESOURCE_SMBA)
                                        size = ctrl;
                                else
                                        size = rdtgroup_cbm_to_size(r, d, ctrl);
 
        list_for_each_entry(s, &resctrl_schema_all, list) {
                r = s->res;
-               if (r->rid == RDT_RESOURCE_MBA) {
+               if (r->rid == RDT_RESOURCE_MBA ||
+                   r->rid == RDT_RESOURCE_SMBA) {
                        rdtgroup_init_mba(r, rdtgrp->closid);
                        if (is_mba_sc(r))
                                continue;