mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
7c3dc440b1
- CXL RAM region enumeration: instantiate 'struct cxl_region' objects for platform firmware created memory regions - CXL RAM region provisioning: complement the existing PMEM region creation support with RAM region support - "Soft Reservation" policy change: Online (memory hot-add) soft-reserved memory (EFI_MEMORY_SP) by default, but still allow for setting aside such memory for dedicated access via device-dax. - CXL Events and Interrupts: Takeover CXL event handling from platform-firmware (ACPI calls this CXL Memory Error Reporting) and export CXL Events via Linux Trace Events. - Convey CXL _OSC results to drivers: Similar to PCI, let the CXL subsystem interrogate the result of CXL _OSC negotiation. - Emulate CXL DVSEC Range Registers as "decoders": Allow for first-generation devices that pre-date the definition of the CXL HDM Decoder Capability to translate the CXL DVSEC Range Registers into 'struct cxl_decoder' objects. - Set timestamp: Per spec, set the device timestamp in case of hotplug, or if platform-firwmare failed to set it. - General fixups: linux-next build issues, non-urgent fixes for pre-production hardware, unit test fixes, spelling and debug message improvements. -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSbo+XnGs+rwLz9XGXfioYZHlFsZwUCY/WYcgAKCRDfioYZHlFs Z6m3APkBUtiEEm1o8ikdu5llUS1OTLBwqjJDwGMTyf8X/WDXhgD+J2mLsCgARS7X 5IS0RAtefutrW5sQpUucPM7QiLuraAY= =kOXC -----END PGP SIGNATURE----- Merge tag 'cxl-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl Pull Compute Express Link (CXL) updates from Dan Williams: "To date Linux has been dependent on platform-firmware to map CXL RAM regions and handle events / errors from devices. With this update we can now parse / update the CXL memory layout, and report events / errors from devices. This is a precursor for the CXL subsystem to handle the end-to-end "RAS" flow for CXL memory. i.e. the flow that for DDR-attached-DRAM is handled by the EDAC driver where it maps system physical address events to a field-replaceable-unit (FRU / endpoint device). In general, CXL has the potential to standardize what has historically been a pile of memory-controller-specific error handling logic. Another change of note is the default policy for handling RAM-backed device-dax instances. Previously the default access mode was "device", mmap(2) a device special file to access memory. The new default is "kmem" where the address range is assigned to the core-mm via add_memory_driver_managed(). This saves typical users from wondering why their platform memory is not visible via free(1) and stuck behind a device-file. At the same time it allows expert users to deploy policy to, for example, get dedicated access to high performance memory, or hide low performance memory from general purpose kernel allocations. This affects not only CXL, but also systems with high-bandwidth-memory that platform-firmware tags with the EFI_MEMORY_SP (special purpose) designation. Summary: - CXL RAM region enumeration: instantiate 'struct cxl_region' objects for platform firmware created memory regions - CXL RAM region provisioning: complement the existing PMEM region creation support with RAM region support - "Soft Reservation" policy change: Online (memory hot-add) soft-reserved memory (EFI_MEMORY_SP) by default, but still allow for setting aside such memory for dedicated access via device-dax. - CXL Events and Interrupts: Takeover CXL event handling from platform-firmware (ACPI calls this CXL Memory Error Reporting) and export CXL Events via Linux Trace Events. - Convey CXL _OSC results to drivers: Similar to PCI, let the CXL subsystem interrogate the result of CXL _OSC negotiation. - Emulate CXL DVSEC Range Registers as "decoders": Allow for first-generation devices that pre-date the definition of the CXL HDM Decoder Capability to translate the CXL DVSEC Range Registers into 'struct cxl_decoder' objects. - Set timestamp: Per spec, set the device timestamp in case of hotplug, or if platform-firwmare failed to set it. - General fixups: linux-next build issues, non-urgent fixes for pre-production hardware, unit test fixes, spelling and debug message improvements" * tag 'cxl-for-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: (66 commits) dax/kmem: Fix leak of memory-hotplug resources cxl/mem: Add kdoc param for event log driver state cxl/trace: Add serial number to trace points cxl/trace: Add host output to trace points cxl/trace: Standardize device information output cxl/pci: Remove locked check for dvsec_range_allowed() cxl/hdm: Add emulation when HDM decoders are not committed cxl/hdm: Create emulated cxl_hdm for devices that do not have HDM decoders cxl/hdm: Emulate HDM decoder from DVSEC range registers cxl/pci: Refactor cxl_hdm_decode_init() cxl/port: Export cxl_dvsec_rr_decode() to cxl_port cxl/pci: Break out range register decoding from cxl_hdm_decode_init() cxl: add RAS status unmasking for CXL cxl: remove unnecessary calling of pci_enable_pcie_error_reporting() dax/hmem: build hmem device support as module if possible dax: cxl: add CXL_REGION dependency cxl: avoid returning uninitialized error code cxl/pmem: Fix nvdimm registration races cxl/mem: Fix UAPI command comment cxl/uapi: Tag commands from cxl_query_cmd() ...
166 lines
5.4 KiB
C
166 lines
5.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
|
|
*/
|
|
#ifndef __ND_CORE_H__
|
|
#define __ND_CORE_H__
|
|
#include <linux/libnvdimm.h>
|
|
#include <linux/device.h>
|
|
#include <linux/sizes.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/nd.h>
|
|
#include "nd.h"
|
|
|
|
extern struct list_head nvdimm_bus_list;
|
|
extern struct mutex nvdimm_bus_list_mutex;
|
|
extern int nvdimm_major;
|
|
extern struct workqueue_struct *nvdimm_wq;
|
|
|
|
struct nvdimm_bus {
|
|
struct nvdimm_bus_descriptor *nd_desc;
|
|
wait_queue_head_t wait;
|
|
struct list_head list;
|
|
struct device dev;
|
|
int id, probe_active;
|
|
atomic_t ioctl_active;
|
|
struct list_head mapping_list;
|
|
struct mutex reconfig_mutex;
|
|
struct badrange badrange;
|
|
};
|
|
|
|
struct nvdimm {
|
|
unsigned long flags;
|
|
void *provider_data;
|
|
unsigned long cmd_mask;
|
|
struct device dev;
|
|
atomic_t busy;
|
|
int id, num_flush;
|
|
struct resource *flush_wpq;
|
|
const char *dimm_id;
|
|
struct {
|
|
const struct nvdimm_security_ops *ops;
|
|
unsigned long flags;
|
|
unsigned long ext_flags;
|
|
unsigned int overwrite_tmo;
|
|
struct kernfs_node *overwrite_state;
|
|
} sec;
|
|
struct delayed_work dwork;
|
|
const struct nvdimm_fw_ops *fw_ops;
|
|
};
|
|
|
|
static inline unsigned long nvdimm_security_flags(
|
|
struct nvdimm *nvdimm, enum nvdimm_passphrase_type ptype)
|
|
{
|
|
u64 flags;
|
|
const u64 state_flags = 1UL << NVDIMM_SECURITY_DISABLED
|
|
| 1UL << NVDIMM_SECURITY_LOCKED
|
|
| 1UL << NVDIMM_SECURITY_UNLOCKED
|
|
| 1UL << NVDIMM_SECURITY_OVERWRITE;
|
|
|
|
if (!nvdimm->sec.ops)
|
|
return 0;
|
|
|
|
flags = nvdimm->sec.ops->get_flags(nvdimm, ptype);
|
|
/* disabled, locked, unlocked, and overwrite are mutually exclusive */
|
|
dev_WARN_ONCE(&nvdimm->dev, hweight64(flags & state_flags) > 1,
|
|
"reported invalid security state: %#llx\n",
|
|
(unsigned long long) flags);
|
|
return flags;
|
|
}
|
|
int nvdimm_security_freeze(struct nvdimm *nvdimm);
|
|
#if IS_ENABLED(CONFIG_NVDIMM_KEYS)
|
|
ssize_t nvdimm_security_store(struct device *dev, const char *buf, size_t len);
|
|
void nvdimm_security_overwrite_query(struct work_struct *work);
|
|
#else
|
|
static inline ssize_t nvdimm_security_store(struct device *dev,
|
|
const char *buf, size_t len)
|
|
{
|
|
return -EOPNOTSUPP;
|
|
}
|
|
static inline void nvdimm_security_overwrite_query(struct work_struct *work)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
bool is_nvdimm(const struct device *dev);
|
|
bool is_nd_pmem(const struct device *dev);
|
|
bool is_nd_volatile(const struct device *dev);
|
|
static inline bool is_nd_region(const struct device *dev)
|
|
{
|
|
return is_nd_pmem(dev) || is_nd_volatile(dev);
|
|
}
|
|
static inline bool is_memory(const struct device *dev)
|
|
{
|
|
return is_nd_pmem(dev) || is_nd_volatile(dev);
|
|
}
|
|
struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev);
|
|
int __init nvdimm_bus_init(void);
|
|
void nvdimm_bus_exit(void);
|
|
void nvdimm_devs_exit(void);
|
|
struct nd_region;
|
|
void nd_region_advance_seeds(struct nd_region *nd_region, struct device *dev);
|
|
void nd_region_create_ns_seed(struct nd_region *nd_region);
|
|
void nd_region_create_btt_seed(struct nd_region *nd_region);
|
|
void nd_region_create_pfn_seed(struct nd_region *nd_region);
|
|
void nd_region_create_dax_seed(struct nd_region *nd_region);
|
|
int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus);
|
|
void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus);
|
|
void nd_synchronize(void);
|
|
void nd_device_register(struct device *dev);
|
|
void nd_device_register_sync(struct device *dev);
|
|
struct nd_label_id;
|
|
char *nd_label_gen_id(struct nd_label_id *label_id, const uuid_t *uuid,
|
|
u32 flags);
|
|
bool nd_is_uuid_unique(struct device *dev, uuid_t *uuid);
|
|
struct nd_region;
|
|
struct nvdimm_drvdata;
|
|
struct nd_mapping;
|
|
void nd_mapping_free_labels(struct nd_mapping *nd_mapping);
|
|
|
|
int __reserve_free_pmem(struct device *dev, void *data);
|
|
void release_free_pmem(struct nvdimm_bus *nvdimm_bus,
|
|
struct nd_mapping *nd_mapping);
|
|
|
|
resource_size_t nd_pmem_max_contiguous_dpa(struct nd_region *nd_region,
|
|
struct nd_mapping *nd_mapping);
|
|
resource_size_t nd_region_allocatable_dpa(struct nd_region *nd_region);
|
|
resource_size_t nd_pmem_available_dpa(struct nd_region *nd_region,
|
|
struct nd_mapping *nd_mapping);
|
|
resource_size_t nd_region_available_dpa(struct nd_region *nd_region);
|
|
int nd_region_conflict(struct nd_region *nd_region, resource_size_t start,
|
|
resource_size_t size);
|
|
resource_size_t nvdimm_allocated_dpa(struct nvdimm_drvdata *ndd,
|
|
struct nd_label_id *label_id);
|
|
int nvdimm_num_label_slots(struct nvdimm_drvdata *ndd);
|
|
void get_ndd(struct nvdimm_drvdata *ndd);
|
|
resource_size_t __nvdimm_namespace_capacity(struct nd_namespace_common *ndns);
|
|
void nd_detach_ndns(struct device *dev, struct nd_namespace_common **_ndns);
|
|
void __nd_detach_ndns(struct device *dev, struct nd_namespace_common **_ndns);
|
|
bool nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
|
|
struct nd_namespace_common **_ndns);
|
|
bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
|
|
struct nd_namespace_common **_ndns);
|
|
ssize_t nd_namespace_store(struct device *dev,
|
|
struct nd_namespace_common **_ndns, const char *buf,
|
|
size_t len);
|
|
struct nd_pfn *to_nd_pfn_safe(struct device *dev);
|
|
bool is_nvdimm_bus(struct device *dev);
|
|
|
|
#if IS_ENABLED(CONFIG_ND_CLAIM)
|
|
int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio,
|
|
resource_size_t size);
|
|
void devm_nsio_disable(struct device *dev, struct nd_namespace_io *nsio);
|
|
#else
|
|
static inline int devm_nsio_enable(struct device *dev,
|
|
struct nd_namespace_io *nsio, resource_size_t size)
|
|
{
|
|
return -ENXIO;
|
|
}
|
|
|
|
static inline void devm_nsio_disable(struct device *dev,
|
|
struct nd_namespace_io *nsio)
|
|
{
|
|
}
|
|
#endif
|
|
#endif /* __ND_CORE_H__ */
|