From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EE5B426B08F for ; Sun, 2 Aug 2026 16:17:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.21 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687446; cv=none; b=mFCHXdbMawgXPAVqh4P3djUWO10Eenp8VgoNi0jpQ93zM8CrWBG1Aqt3SOZAqkRZzk3ZsuRVRWtpTBP55H0wMdBQCq/8w4bxkOSGqmsZkYc3X3IYW1Jt9BThrhz303Xv+x7EXdUCq+JmAJ7QBlvJ/EMkLwgVaBPzpiQUYau3NMU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687446; c=relaxed/simple; bh=1H1QRHYUayUBXX+0tBflmIxyaExiupdj9yDRGcohDk8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BMBDPmcKQI508/c1HsxxQ/YKRx10KGQpVm5tpwz6miUPKwwlLA/ZTk+RLMHEfWMShIhCDQm09QymP9goNu0vQq1JyuZTqYadBmnRa+s7CJg7TYFtAarFS3bo3Tj+7Uty9ie/Xr8AIMKEXvjTpPRDQhJH9Jq8XN1V1+65tSra76k= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=eku36Ost; arc=none smtp.client-ip=198.175.65.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="eku36Ost" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1785687444; x=1817223444; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1H1QRHYUayUBXX+0tBflmIxyaExiupdj9yDRGcohDk8=; b=eku36Ostw36GY5Zkce02/VyHNmNx5kbkKQrOUVvLhRAxE79FxAl6zkHZ JOuKh27mLdHBaBvIGg1w8SQJWi2F3OT0m1YX0O8riDCDy3nWSrIVbZv6y vY025mwC/CkV+7/ZdG6nGhPO68UwZZhqgjx3v4H1Ny9qXLwOiXRnd8Qjf DmMasqWdnqXcdjoj7VXGIqrr2EU2VB//jhzWn89efKOSDbUbrW1TptXPH nDOJRNybIuePRRp4RFWTEMT+N44eN9cMUbHq9JPpz76zUNrDFfPPc8/zn T7bsA4bH0v8EcLr+SfHXXJW7UV9VRjl9bmYjckC7V2vmD7NskISPgQ9wY A==; X-CSE-ConnectionGUID: YGyF/K9iRwazYgOSQ4JSuA== X-CSE-MsgGUID: xqIqYsXHRFSqA9fSji2OCg== X-IronPort-AV: E=McAfee;i="6800,10657,11863"; a="86101099" X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="86101099" Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by orvoesa113.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2026 09:17:23 -0700 X-CSE-ConnectionGUID: MX+RG2qdTZqvE8rC94f80w== X-CSE-MsgGUID: b1KsnqQTSFOYpmUqb0SroQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="285634184" Received: from chenyu-dev.sh.intel.com ([10.239.62.107]) by fmviesa001.fm.intel.com with ESMTP; 02 Aug 2026 09:17:20 -0700 From: Chen Yu To: Reinette Chatre , Tony Luck Cc: Ben Horgan , "James Morse" , Dave Martin , Babu Moger , Fenghua Yu , Borislav Petkov , Thomas Gleixner , "Dave Hansen" , Peter Newman , chen.yu@linux.dev, x86@kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 25/31] x86/resctrl: Introduce region-based MBA write implementation on MMIO space Date: Mon, 3 Aug 2026 00:07:38 +0800 Message-Id: <003c5ab0a49d3bd5d0dec0af50632073c378b6e8.1785680802.git.yu.c.chen@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Implement the marc_hw_update() callback to program per-region MBA bandwidth values via MMIO. The MARC register layout packs 4 regions into each 64-bit register, with a 9-bit bandwidth field per region at (region % 4) * 16 bits. The MMIO address for a given CLOSID is calculated using the MARC index function 1: addr = base + Floor(Region / 4) * 512 + CLOS * 8 Each controller handles a single (region, type) pair, but a write always touches the whole 64-bit register. The callback therefore does a read-modify-write: it changes only its own region's field and writes every other bit back exactly as it was read, so the reserved bits keep their original values. A shadow copy of the register (marc_buf) holds the value last written, which spares the read on later updates. Signed-off-by: Chen Yu --- arch/x86/kernel/cpu/resctrl/erdt.c | 52 ++++++++++++++++++++++++++ arch/x86/kernel/cpu/resctrl/internal.h | 4 ++ 2 files changed, 56 insertions(+) diff --git a/arch/x86/kernel/cpu/resctrl/erdt.c b/arch/x86/kernel/cpu/resctrl/erdt.c index 38720c3b4a3d..c25aff805b12 100644 --- a/arch/x86/kernel/cpu/resctrl/erdt.c +++ b/arch/x86/kernel/cpu/resctrl/erdt.c @@ -275,6 +275,49 @@ struct erdt_domain_info *erdt_find_domain_info(int cpu) static void marc_hw_update(struct hw_param *m) { + struct rdt_hw_ctrl_domain *hw_dom = resctrl_to_arch_ctrl_dom(m->dom); + struct resctrl_hw_ctrl *hw_ctrl = resctrl_to_arch_ctrl(m->ctrl); + enum resctrl_ctrl_name name = hw_ctrl->r_ctrl.name; + unsigned int offset, region, type, region_offset_bits; + struct erdt_domain_info *d = hw_dom->d_info; + enum erdt_mmio_type mmio_type; + void __iomem *addr; + int closid_idx; + unsigned int i; + u64 val; + + if (!d || !d->marc) + return; + + offset = name - RESCTRL_CTRL_NAME_REGION0_OPT; + region = offset / RESCTRL_CTRL_REGION_NR_CTRLS; + type = offset % RESCTRL_CTRL_REGION_NR_CTRLS; + mmio_type = ERDT_MMIO_MARC_OPT + type; + region_offset_bits = (region % 4) * 16; + + if (d->marc_buf_type != mmio_type) { + memset(d->marc_buf, 0, + d->marc->mba_reg_size * 512 * sizeof(u64)); + d->marc_buf_type = mmio_type; + } + + for (i = m->low; i < m->high; i++) { + closid_idx = (region / 4) * 64 + i; + addr = d->base[mmio_type] + closid_idx * 8; + + /* The cached value retains the reserved bits to be preserved. */ + val = d->marc_buf[closid_idx]; + if (!val) + val = readq(addr); + + if (WARN_ON_ONCE(!val)) + return; + + val &= ~(0x1ffULL << region_offset_bits); + val |= (u64)(hw_dom->ctrl_val[i] & 0x1ff) << region_offset_bits; + d->marc_buf[closid_idx] = val; + writeq(val, addr); + } } __init bool erdt_get_mem_config(struct rdt_resource *r) @@ -364,6 +407,7 @@ static void erdt_iounmap_domain(struct erdt_domain_info *domain) static void cleanup_one_domain(struct erdt_domain_info *d) { erdt_iounmap_domain(d); + kfree(d->marc_buf); kfree(d->cmrc); kfree(d->mmrc); kfree(d->marc); @@ -520,6 +564,14 @@ static __init int marc_init(struct acpi_subtbl_hdr_16 *subtbl, if (!domain_info->marc) goto unmap; + domain_info->marc_buf = kcalloc(marc->mba_reg_size * 512, sizeof(u64), + GFP_KERNEL); + if (!domain_info->marc_buf) { + kfree(domain_info->marc); + domain_info->marc = NULL; + goto unmap; + } + return 0; unmap: diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index e9602525e4bd..2f6173692d0c 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -52,6 +52,8 @@ enum erdt_mmio_type { * @cmrc: Copy of the ACPI CMRC sub-table for this domain * @mmrc: Copy of the ACPI MMRC sub-table for this domain * @marc: Copy of the ACPI MARC sub-table for this domain + * @marc_buf: Shadow copy of the MARC MMIO registers for read-modify-write + * @marc_buf_type: MARC MMIO region currently cached in @marc_buf * @cpu_mask: CPUs belonging to this resource management domain * @max_rmid: Maximum RMID supported by this domain * @dom_id: L3 cache ID shared by all CPUs in this domain (-1 if unset) @@ -62,6 +64,8 @@ struct erdt_domain_info { struct acpi_erdt_cmrc *cmrc; struct acpi_erdt_mmrc *mmrc; struct acpi_erdt_marc *marc; + u64 *marc_buf; + enum erdt_mmio_type marc_buf_type; struct cpumask cpu_mask; u32 max_rmid; int dom_id; -- 2.43.0