Merge branch 'for-4.6/pfn' into libnvdimm-for-next

This commit is contained in:
Dan Williams
2016-03-09 17:15:43 -08:00
41 changed files with 536 additions and 253 deletions

View File

@@ -62,7 +62,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
if (count < 0) {
return NULL;
} else if (count > 0) {
resources = kmalloc(count * sizeof(struct resource),
resources = kzalloc(count * sizeof(struct resource),
GFP_KERNEL);
if (!resources) {
dev_err(&adev->dev, "No memory for resources\n");

View File

@@ -519,7 +519,7 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
u64 param3, u64 param4)
{
int rc;
unsigned long pfn;
u64 base_addr, size;
/* If user manually set "flags", make sure it is legal */
if (flags && (flags &
@@ -545,10 +545,17 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
/*
* Disallow crazy address masks that give BIOS leeway to pick
* injection address almost anywhere. Insist on page or
* better granularity and that target address is normal RAM.
* better granularity and that target address is normal RAM or
* NVDIMM.
*/
pfn = PFN_DOWN(param1 & param2);
if (!page_is_ram(pfn) || ((param2 & PAGE_MASK) != PAGE_MASK))
base_addr = param1 & param2;
size = ~param2 + 1;
if (((param2 & PAGE_MASK) != PAGE_MASK) ||
((region_intersects(base_addr, size, IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
!= REGION_INTERSECTS) &&
(region_intersects(base_addr, size, IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY)
!= REGION_INTERSECTS)))
return -EINVAL;
inject:

View File

@@ -1658,6 +1658,48 @@ static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus,
return 0;
}
static void acpi_nfit_remove_resource(void *data)
{
struct resource *res = data;
remove_resource(res);
}
static int acpi_nfit_insert_resource(struct acpi_nfit_desc *acpi_desc,
struct nd_region_desc *ndr_desc)
{
struct resource *res, *nd_res = ndr_desc->res;
int is_pmem, ret;
/* No operation if the region is already registered as PMEM */
is_pmem = region_intersects(nd_res->start, resource_size(nd_res),
IORESOURCE_MEM, IORES_DESC_PERSISTENT_MEMORY);
if (is_pmem == REGION_INTERSECTS)
return 0;
res = devm_kzalloc(acpi_desc->dev, sizeof(*res), GFP_KERNEL);
if (!res)
return -ENOMEM;
res->name = "Persistent Memory";
res->start = nd_res->start;
res->end = nd_res->end;
res->flags = IORESOURCE_MEM;
res->desc = IORES_DESC_PERSISTENT_MEMORY;
ret = insert_resource(&iomem_resource, res);
if (ret)
return ret;
ret = devm_add_action(acpi_desc->dev, acpi_nfit_remove_resource, res);
if (ret) {
remove_resource(res);
return ret;
}
return 0;
}
static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc,
struct nd_mapping *nd_mapping, struct nd_region_desc *ndr_desc,
struct acpi_nfit_memory_map *memdev,
@@ -1773,6 +1815,14 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
nvdimm_bus = acpi_desc->nvdimm_bus;
if (nfit_spa_type(spa) == NFIT_SPA_PM) {
rc = acpi_nfit_insert_resource(acpi_desc, ndr_desc);
if (rc) {
dev_warn(acpi_desc->dev,
"failed to insert pmem resource to iomem: %d\n",
rc);
goto out;
}
nfit_spa->nd_region = nvdimm_pmem_region_create(nvdimm_bus,
ndr_desc);
if (!nfit_spa->nd_region)