Commit c1f0fcd8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull cxl updates from Dan Williams:
 "Compute Express Link (CXL) updates for 6.2.

  While it may seem backwards, the CXL update this time around includes
  some focus on CXL 1.x enabling where the work to date had been with
  CXL 2.0 (VH topologies) in mind.

  First generation CXL can mostly be supported via BIOS, similar to DDR,
  however it became clear there are use cases for OS native CXL error
  handling and some CXL 3.0 endpoint features can be deployed on CXL 1.x
  hosts (Restricted CXL Host (RCH) topologies). So, this update brings
  RCH topologies into the Linux CXL device model.

  In support of the ongoing CXL 2.0+ enabling two new core kernel
  facilities are added.

  One is the ability for the kernel to flag collisions between userspace
  access to PCI configuration registers and kernel accesses. This is
  brought on by the PCIe Data-Object-Exchange (DOE) facility, a hardware
  mailbox over config-cycles.

  The other is a cpu_cache_invalidate_memregion() API that maps to
  wbinvd_on_all_cpus() on x86. To prevent abuse it is disabled in guest
  VMs and architectures that do not support it yet. The CXL paths that
  need it, dynamic memory region creation and security commands (erase /
  unlock), are disabled when it is not present.

  As for the CXL 2.0+ this cycle the subsystem gains support Persistent
  Memory Security commands, error handling in response to PCIe AER
  notifications, and support for the "XOR" host bridge interleave
  algorithm.

  Summary:

   - Add the cpu_cache_invalidate_memregion() API for cache flushing in
     response to physical memory reconfiguration, or memory-side data
     invalidation from operations like secure erase or memory-device
     unlock.

   - Add a facility for the kernel to warn about collisions between
     kernel and userspace access to PCI configuration registers

   - Add support for Restricted CXL Host (RCH) topologies (formerly CXL
     1.1)

   - Add handling and reporting of CXL errors reported via the PCIe AER
     mechanism

   - Add support for CXL Persistent Memory Security commands

   - Add support for the "XOR" algorithm for CXL host bridge interleave

   - Rework / simplify CXL to NVDIMM interactions

   - Miscellaneous cleanups and fixes"

* tag 'cxl-for-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: (71 commits)
  cxl/region: Fix memdev reuse check
  cxl/pci: Remove endian confusion
  cxl/pci: Add some type-safety to the AER trace points
  cxl/security: Drop security command ioctl uapi
  cxl/mbox: Add variable output size validation for internal commands
  cxl/mbox: Enable cxl_mbox_send_cmd() users to validate output size
  cxl/security: Fix Get Security State output payload endian handling
  cxl: update names for interleave ways conversion macros
  cxl: update names for interleave granularity conversion macros
  cxl/acpi: Warn about an invalid CHBCR in an existing CHBS entry
  tools/testing/cxl: Require cache invalidation bypass
  cxl/acpi: Fail decoder add if CXIMS for HBIG is missing
  cxl/region: Fix spelling mistake "memergion" -> "memregion"
  cxl/regs: Fix sparse warning
  cxl/acpi: Set ACPI's CXL _OSC to indicate RCD mode support
  tools/testing/cxl: Add an RCH topology
  cxl/port: Add RCD endpoint port enumeration
  cxl/mem: Move devm_cxl_add_endpoint() from cxl_core to cxl_mem
  tools/testing/cxl: Add XOR Math support to cxl_test
  cxl/acpi: Support CXL XOR Interleave Math (CXIMS)
  ...
parents 691806e9 f04facfb
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -41,3 +41,17 @@ KernelVersion: 5.18
Contact:        Kajol Jain <kjain@linux.ibm.com>
Description:	(RO) This sysfs file exposes the cpumask which is designated to
		to retrieve nvdimm pmu event counter data.

What:		/sys/bus/nd/devices/nmemX/cxl/id
Date:		November 2022
KernelVersion:	6.2
Contact:	Dave Jiang <dave.jiang@intel.com>
Description:	(RO) Show the id (serial) of the device. This is CXL specific.

What:		/sys/bus/nd/devices/nmemX/cxl/provider
Date:		November 2022
KernelVersion:	6.2
Contact:	Dave Jiang <dave.jiang@intel.com>
Description:	(RO) Shows the CXL bridge device that ties to a CXL memory device
		to this NVDIMM device. I.e. the parent of the device returned is
		a /sys/bus/cxl/devices/memX instance.
+7 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ This structure has the form::
		int (*mmio_enabled)(struct pci_dev *dev);
		int (*slot_reset)(struct pci_dev *dev);
		void (*resume)(struct pci_dev *dev);
		void (*cor_error_detected)(struct pci_dev *dev);
	};

The possible channel states are::
@@ -422,5 +423,11 @@ That is, the recovery API only requires that:
   - drivers/net/cxgb3
   - drivers/net/s2io.c

   The cor_error_detected() callback is invoked in handle_error_source() when
   the error severity is "correctable". The callback is optional and allows
   additional logging to be done if desired. See example:

   - drivers/cxl/pci.c

The End
-------
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ config X86
	select ARCH_ENABLE_THP_MIGRATION if X86_64 && TRANSPARENT_HUGEPAGE
	select ARCH_HAS_ACPI_TABLE_UPGRADE	if ACPI
	select ARCH_HAS_CACHE_LINE_SIZE
	select ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
	select ARCH_HAS_CURRENT_STACK_POINTER
	select ARCH_HAS_DEBUG_VIRTUAL
	select ARCH_HAS_DEBUG_VM_PGTABLE	if !X86_PAE
+18 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/cc_platform.h>
#include <linux/set_memory.h>
#include <linux/memregion.h>

#include <asm/e820/api.h>
#include <asm/processor.h>
@@ -330,6 +331,23 @@ void arch_invalidate_pmem(void *addr, size_t size)
EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
#endif

#ifdef CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION
bool cpu_cache_has_invalidate_memregion(void)
{
	return !cpu_feature_enabled(X86_FEATURE_HYPERVISOR);
}
EXPORT_SYMBOL_NS_GPL(cpu_cache_has_invalidate_memregion, DEVMEM);

int cpu_cache_invalidate_memregion(int res_desc)
{
	if (WARN_ON_ONCE(!cpu_cache_has_invalidate_memregion()))
		return -ENXIO;
	wbinvd_on_all_cpus();
	return 0;
}
EXPORT_SYMBOL_NS_GPL(cpu_cache_invalidate_memregion, DEVMEM);
#endif

static void __cpa_flush_all(void *arg)
{
	unsigned long cache = (unsigned long)arg;
+1 −29
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include <linux/libnvdimm.h>
#include <linux/ndctl.h>
#include <linux/acpi.h>
#include <linux/memregion.h>
#include <asm/smp.h>
#include "intel.h"
#include "nfit.h"
@@ -190,8 +191,6 @@ static int intel_security_change_key(struct nvdimm *nvdimm,
	}
}

static void nvdimm_invalidate_cache(void);

static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm,
		const struct nvdimm_key_data *key_data)
{
@@ -227,9 +226,6 @@ static int __maybe_unused intel_security_unlock(struct nvdimm *nvdimm,
		return -EIO;
	}

	/* DIMM unlocked, invalidate all CPU caches before we read it */
	nvdimm_invalidate_cache();

	return 0;
}

@@ -297,8 +293,6 @@ static int __maybe_unused intel_security_erase(struct nvdimm *nvdimm,
	if (!test_bit(cmd, &nfit_mem->dsm_mask))
		return -ENOTTY;

	/* flush all cache before we erase DIMM */
	nvdimm_invalidate_cache();
	memcpy(nd_cmd.cmd.passphrase, key->data,
			sizeof(nd_cmd.cmd.passphrase));
	rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
@@ -317,8 +311,6 @@ static int __maybe_unused intel_security_erase(struct nvdimm *nvdimm,
		return -ENXIO;
	}

	/* DIMM erased, invalidate all CPU caches before we read it */
	nvdimm_invalidate_cache();
	return 0;
}

@@ -354,8 +346,6 @@ static int __maybe_unused intel_security_query_overwrite(struct nvdimm *nvdimm)
		return -ENXIO;
	}

	/* flush all cache before we make the nvdimms available */
	nvdimm_invalidate_cache();
	return 0;
}

@@ -380,8 +370,6 @@ static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm,
	if (!test_bit(NVDIMM_INTEL_OVERWRITE, &nfit_mem->dsm_mask))
		return -ENOTTY;

	/* flush all cache before we erase DIMM */
	nvdimm_invalidate_cache();
	memcpy(nd_cmd.cmd.passphrase, nkey->data,
			sizeof(nd_cmd.cmd.passphrase));
	rc = nvdimm_ctl(nvdimm, ND_CMD_CALL, &nd_cmd, sizeof(nd_cmd), NULL);
@@ -401,22 +389,6 @@ static int __maybe_unused intel_security_overwrite(struct nvdimm *nvdimm,
	}
}

/*
 * TODO: define a cross arch wbinvd equivalent when/if
 * NVDIMM_FAMILY_INTEL command support arrives on another arch.
 */
#ifdef CONFIG_X86
static void nvdimm_invalidate_cache(void)
{
	wbinvd_on_all_cpus();
}
#else
static void nvdimm_invalidate_cache(void)
{
	WARN_ON_ONCE("cache invalidation required after unlock\n");
}
#endif

static const struct nvdimm_security_ops __intel_security_ops = {
	.get_flags = intel_security_flags,
	.freeze = intel_security_freeze,
Loading