* [PATCH v3 0/2] drm/xe/nvm: add survivabilty partiton
@ 2026-09-30 14:14 Alexander Usyskin
2026-09-30 14:14 ` [PATCH v3 1/2] mtd: mtd_intel_dg: add survivability partition Alexander Usyskin
2026-09-30 14:14 ` [PATCH v3 2/2] drm/xe/nvm: define survivabilty partition Alexander Usyskin
0 siblings, 2 replies; 5+ messages in thread
From: Alexander Usyskin @ 2026-09-30 14:14 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Matthew Brost, Thomas Hellström, Rodrigo Vivi, David Airlie,
Simona Vetter
Cc: linux-mtd, linux-kernel, intel-xe, dri-devel, Menachem Adin,
Alexander Usyskin
One of the reasons for the CRI to enter survivability mode
is corrupted storage.
A corrupted storage partition table can make recovery impossible.
A new partition with a pre-defined size, covering the entire storage,
should replace partitions detected from the storage when the card is
in survivability mode to allow a full memory update.
This series intended to be merged via drm tree for consistency
and requires ack from MTD maintainer.
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
Changes in v3:
- Fix minor checkpatch complain
- Add Miquel ack
- Link to v2: https://lore.kernel.org/r/20260916-cri_surviv-v2-0-7de1b5328204@intel.com
Changes in v2:
- Replace usual partitions with survivability one instead of adding
addition partition to avoid problems with two partitons pointing to
the same memory area.
- The change is in the mtd part; Miquel, I feel that this requires
re-review/ack from your side.
- Link to v1: https://lore.kernel.org/r/20260715-cri_surviv-v1-0-61763a6f1076@intel.com
---
Alexander Usyskin (2):
mtd: mtd_intel_dg: add survivability partition
drm/xe/nvm: define survivabilty partition
drivers/gpu/drm/xe/xe_nvm.c | 13 ++++++--
drivers/mtd/devices/mtd_intel_dg.c | 65 ++++++++++++++++++++++++++++----------
include/linux/intel_dg_nvm_aux.h | 1 +
3 files changed, 60 insertions(+), 19 deletions(-)
---
base-commit: 3fc93d311249d5ad969a520dd3aae73bc007d431
change-id: 20260715-cri_surviv-5a6faf7586f1
Best regards,
--
Alexander Usyskin <alexander.usyskin@intel.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] mtd: mtd_intel_dg: add survivability partition
2026-09-30 14:14 [PATCH v3 0/2] drm/xe/nvm: add survivabilty partiton Alexander Usyskin
@ 2026-09-30 14:14 ` Alexander Usyskin
2026-10-08 16:42 ` Rodrigo Vivi
2026-09-30 14:14 ` [PATCH v3 2/2] drm/xe/nvm: define survivabilty partition Alexander Usyskin
1 sibling, 1 reply; 5+ messages in thread
From: Alexander Usyskin @ 2026-09-30 14:14 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Matthew Brost, Thomas Hellström, Rodrigo Vivi, David Airlie,
Simona Vetter
Cc: linux-mtd, linux-kernel, intel-xe, dri-devel, Menachem Adin,
Alexander Usyskin
Add option to expose additional fixed-sized partition starting
from the beginning of storage.
Xe driver can request this partition exposure if firmware or hardware
have detected failure that may involve corrupted partition table.
Fixed-sized partition allows full storage re-write in this situation.
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
drivers/mtd/devices/mtd_intel_dg.c | 65 ++++++++++++++++++++++++++++----------
include/linux/intel_dg_nvm_aux.h | 1 +
2 files changed, 50 insertions(+), 16 deletions(-)
diff --git a/drivers/mtd/devices/mtd_intel_dg.c b/drivers/mtd/devices/mtd_intel_dg.c
index a566e86eb5e3..976246e94e79 100644
--- a/drivers/mtd/devices/mtd_intel_dg.c
+++ b/drivers/mtd/devices/mtd_intel_dg.c
@@ -31,6 +31,7 @@ struct intel_dg_nvm {
void __iomem *base;
void __iomem *base2;
bool non_posted_erase;
+ bool survivability_enabled;
size_t size;
unsigned int nregions;
@@ -430,6 +431,15 @@ static int intel_dg_nvm_init(struct intel_dg_nvm *nvm, struct device *device,
/* clean error register, previous errors are ignored */
idg_nvm_error(nvm);
+ if (nvm->survivability_enabled) {
+ nvm->size = nvm->regions[0].offset + nvm->regions[0].size - 1;
+ dev_dbg(device, "Registered survivability region %s size=%lld\n",
+ nvm->regions[0].name,
+ nvm->regions[0].size);
+ n = 1;
+ goto out;
+ }
+
ret = idg_nvm_is_valid(nvm);
if (ret) {
dev_err(device, "The MEM is not valid %d\n", ret);
@@ -481,6 +491,7 @@ static int intel_dg_nvm_init(struct intel_dg_nvm *nvm, struct device *device,
n++;
}
+out:
nvm->non_posted_erase = non_posted_erase;
dev_dbg(device, "Registered %d regions\n", n);
@@ -753,15 +764,19 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev,
device = &aux_dev->dev;
- /* count available regions */
- for (nregions = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
- if (invm->regions[i].name)
- nregions++;
- }
+ if (invm->survivability_size) {
+ nregions = 1;
+ } else {
+ /* count available regions */
+ for (nregions = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
+ if (invm->regions[i].name)
+ nregions++;
+ }
- if (!nregions) {
- dev_err(device, "no regions defined\n");
- return -ENODEV;
+ if (!nregions) {
+ dev_err(device, "no regions defined\n");
+ return -ENODEV;
+ }
}
nvm = kzalloc_flex(*nvm, regions, nregions);
@@ -771,21 +786,39 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev,
kref_init(&nvm->refcnt);
mutex_init(&nvm->lock);
nvm->nregions = nregions;
+ nvm->survivability_enabled = !!invm->survivability_size;
- for (n = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
- if (!invm->regions[i].name)
- continue;
-
+ if (invm->survivability_size) { /* survivability partition */
char *name = kasprintf(GFP_KERNEL, "%s.%s",
- dev_name(&aux_dev->dev), invm->regions[i].name);
+ dev_name(&aux_dev->dev), "DATA");
if (!name) {
ret = -ENOMEM;
goto err_norpm;
}
- nvm->regions[n].name = name;
- nvm->regions[n].id = i;
- n++;
+ nvm->regions[0].name = name;
+ nvm->regions[0].id = 0;
+ nvm->regions[0].offset = 0;
+ nvm->regions[0].size = invm->survivability_size;
+ nvm->regions[0].is_readable = true;
+ nvm->regions[0].is_writable = true;
+ n = 1;
+ } else {
+ for (n = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
+ if (!invm->regions[i].name)
+ continue;
+
+ char *name = kasprintf(GFP_KERNEL, "%s.%s",
+ dev_name(&aux_dev->dev), invm->regions[i].name);
+ if (!name) {
+ ret = -ENOMEM;
+ goto err_norpm;
+ }
+
+ nvm->regions[n].name = name;
+ nvm->regions[n].id = i;
+ n++;
+ }
}
ret = devm_pm_runtime_enable(device);
diff --git a/include/linux/intel_dg_nvm_aux.h b/include/linux/intel_dg_nvm_aux.h
index 625d46a6b96e..84b5b6e0c4ea 100644
--- a/include/linux/intel_dg_nvm_aux.h
+++ b/include/linux/intel_dg_nvm_aux.h
@@ -21,6 +21,7 @@ struct intel_dg_nvm_dev {
struct auxiliary_device aux_dev;
bool writable_override;
bool non_posted_erase;
+ size_t survivability_size;
struct resource bar;
struct resource bar2;
const struct intel_dg_nvm_region *regions;
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] drm/xe/nvm: define survivabilty partition
2026-09-30 14:14 [PATCH v3 0/2] drm/xe/nvm: add survivabilty partiton Alexander Usyskin
2026-09-30 14:14 ` [PATCH v3 1/2] mtd: mtd_intel_dg: add survivability partition Alexander Usyskin
@ 2026-09-30 14:14 ` Alexander Usyskin
2026-10-08 16:43 ` Rodrigo Vivi
1 sibling, 1 reply; 5+ messages in thread
From: Alexander Usyskin @ 2026-09-30 14:14 UTC (permalink / raw)
To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Matthew Brost, Thomas Hellström, Rodrigo Vivi, David Airlie,
Simona Vetter
Cc: linux-mtd, linux-kernel, intel-xe, dri-devel, Menachem Adin,
Alexander Usyskin
Define 8M survivability partition for CRI when
storage is open for write override.
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
---
drivers/gpu/drm/xe/xe_nvm.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_nvm.c b/drivers/gpu/drm/xe/xe_nvm.c
index 51a1a431ad85..783c3103a8a4 100644
--- a/drivers/gpu/drm/xe/xe_nvm.c
+++ b/drivers/gpu/drm/xe/xe_nvm.c
@@ -56,10 +56,11 @@ static bool xe_nvm_non_posted_erase(struct xe_device *xe)
}
}
-static bool xe_nvm_writable_override(struct xe_device *xe)
+static bool xe_nvm_writable_override(struct xe_device *xe, size_t *survivability_size)
{
struct xe_mmio *mmio = xe_root_tile_mmio(xe);
bool writable_override;
+ size_t s_size = 0;
struct xe_reg reg;
u32 test_bit, test_val;
@@ -68,6 +69,7 @@ static bool xe_nvm_writable_override(struct xe_device *xe)
reg = PCODE_SCRATCH(0);
test_bit = FDO_MODE;
test_val = FDO_MODE;
+ s_size = SZ_8M;
break;
case XE_BATTLEMAGE:
reg = HECI_FWSTS2(DG2_GSC_HECI2_BASE);
@@ -91,12 +93,17 @@ static bool xe_nvm_writable_override(struct xe_device *xe)
break;
default:
drm_err(&xe->drm, "Unknown platform\n");
+ *survivability_size = 0;
return true;
}
writable_override = (xe_mmio_read32(mmio, reg) & test_bit) == test_val;
- if (writable_override)
+ if (writable_override) {
drm_info(&xe->drm, "NVM access overridden by jumper\n");
+ *survivability_size = s_size;
+ } else {
+ *survivability_size = 0;
+ }
return writable_override;
}
@@ -143,7 +150,7 @@ int xe_nvm_init(struct xe_device *xe)
if (!nvm)
return -ENOMEM;
- nvm->writable_override = xe_nvm_writable_override(xe);
+ nvm->writable_override = xe_nvm_writable_override(xe, &nvm->survivability_size);
nvm->non_posted_erase = xe_nvm_non_posted_erase(xe);
nvm->bar.parent = &pdev->resource[0];
nvm->bar.start = GEN12_GUNIT_NVM_BASE + pdev->resource[0].start;
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] mtd: mtd_intel_dg: add survivability partition
2026-09-30 14:14 ` [PATCH v3 1/2] mtd: mtd_intel_dg: add survivability partition Alexander Usyskin
@ 2026-10-08 16:42 ` Rodrigo Vivi
0 siblings, 0 replies; 5+ messages in thread
From: Rodrigo Vivi @ 2026-10-08 16:42 UTC (permalink / raw)
To: Alexander Usyskin
Cc: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Matthew Brost, Thomas Hellström, David Airlie,
Simona Vetter, linux-mtd, linux-kernel, intel-xe, dri-devel,
Menachem Adin
On Wed, Sep 30, 2026 at 05:14:46PM +0300, Alexander Usyskin wrote:
> Add option to expose additional fixed-sized partition starting
> from the beginning of storage.
> Xe driver can request this partition exposure if firmware or hardware
> have detected failure that may involve corrupted partition table.
> Fixed-sized partition allows full storage re-write in this situation.
>
> Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> ---
> drivers/mtd/devices/mtd_intel_dg.c | 65 ++++++++++++++++++++++++++++----------
> include/linux/intel_dg_nvm_aux.h | 1 +
> 2 files changed, 50 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/mtd/devices/mtd_intel_dg.c b/drivers/mtd/devices/mtd_intel_dg.c
> index a566e86eb5e3..976246e94e79 100644
> --- a/drivers/mtd/devices/mtd_intel_dg.c
> +++ b/drivers/mtd/devices/mtd_intel_dg.c
> @@ -31,6 +31,7 @@ struct intel_dg_nvm {
> void __iomem *base;
> void __iomem *base2;
> bool non_posted_erase;
> + bool survivability_enabled;
>
> size_t size;
> unsigned int nregions;
> @@ -430,6 +431,15 @@ static int intel_dg_nvm_init(struct intel_dg_nvm *nvm, struct device *device,
> /* clean error register, previous errors are ignored */
> idg_nvm_error(nvm);
>
> + if (nvm->survivability_enabled) {
> + nvm->size = nvm->regions[0].offset + nvm->regions[0].size - 1;
I see that this offset + region.size - 1 is also used in idg_nvm_get_region()
we could perhaps define a variable with this and document the - 1?!
But it looks right, no blocker...
> + dev_dbg(device, "Registered survivability region %s size=%lld\n",
> + nvm->regions[0].name,
> + nvm->regions[0].size);
> + n = 1;
> + goto out;
> + }
> +
> ret = idg_nvm_is_valid(nvm);
> if (ret) {
> dev_err(device, "The MEM is not valid %d\n", ret);
> @@ -481,6 +491,7 @@ static int intel_dg_nvm_init(struct intel_dg_nvm *nvm, struct device *device,
> n++;
> }
>
> +out:
> nvm->non_posted_erase = non_posted_erase;
>
> dev_dbg(device, "Registered %d regions\n", n);
> @@ -753,15 +764,19 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev,
>
> device = &aux_dev->dev;
>
> - /* count available regions */
> - for (nregions = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
> - if (invm->regions[i].name)
> - nregions++;
> - }
> + if (invm->survivability_size) {
> + nregions = 1;
> + } else {
> + /* count available regions */
> + for (nregions = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
> + if (invm->regions[i].name)
> + nregions++;
> + }
>
> - if (!nregions) {
> - dev_err(device, "no regions defined\n");
> - return -ENODEV;
> + if (!nregions) {
> + dev_err(device, "no regions defined\n");
> + return -ENODEV;
> + }
> }
>
> nvm = kzalloc_flex(*nvm, regions, nregions);
> @@ -771,21 +786,39 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev,
> kref_init(&nvm->refcnt);
> mutex_init(&nvm->lock);
> nvm->nregions = nregions;
> + nvm->survivability_enabled = !!invm->survivability_size;
>
> - for (n = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
> - if (!invm->regions[i].name)
> - continue;
> -
> + if (invm->survivability_size) { /* survivability partition */
> char *name = kasprintf(GFP_KERNEL, "%s.%s",
> - dev_name(&aux_dev->dev), invm->regions[i].name);
> + dev_name(&aux_dev->dev), "DATA");
> if (!name) {
> ret = -ENOMEM;
> goto err_norpm;
> }
>
> - nvm->regions[n].name = name;
> - nvm->regions[n].id = i;
> - n++;
> + nvm->regions[0].name = name;
> + nvm->regions[0].id = 0;
> + nvm->regions[0].offset = 0;
> + nvm->regions[0].size = invm->survivability_size;
> + nvm->regions[0].is_readable = true;
> + nvm->regions[0].is_writable = true;
> + n = 1;
> + } else {
> + for (n = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
> + if (!invm->regions[i].name)
> + continue;
> +
> + char *name = kasprintf(GFP_KERNEL, "%s.%s",
> + dev_name(&aux_dev->dev), invm->regions[i].name);
> + if (!name) {
> + ret = -ENOMEM;
> + goto err_norpm;
> + }
> +
> + nvm->regions[n].name = name;
> + nvm->regions[n].id = i;
> + n++;
> + }
here as well, I believe the if survivability block should only select the
different print name and fix the for delimiter to 1 iteraction, then
you don't duplicate the rest of the code...
but also no blocker from my side:
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> }
>
> ret = devm_pm_runtime_enable(device);
> diff --git a/include/linux/intel_dg_nvm_aux.h b/include/linux/intel_dg_nvm_aux.h
> index 625d46a6b96e..84b5b6e0c4ea 100644
> --- a/include/linux/intel_dg_nvm_aux.h
> +++ b/include/linux/intel_dg_nvm_aux.h
> @@ -21,6 +21,7 @@ struct intel_dg_nvm_dev {
> struct auxiliary_device aux_dev;
> bool writable_override;
> bool non_posted_erase;
> + size_t survivability_size;
> struct resource bar;
> struct resource bar2;
> const struct intel_dg_nvm_region *regions;
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/2] drm/xe/nvm: define survivabilty partition
2026-09-30 14:14 ` [PATCH v3 2/2] drm/xe/nvm: define survivabilty partition Alexander Usyskin
@ 2026-10-08 16:43 ` Rodrigo Vivi
0 siblings, 0 replies; 5+ messages in thread
From: Rodrigo Vivi @ 2026-10-08 16:43 UTC (permalink / raw)
To: Alexander Usyskin
Cc: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
Matthew Brost, Thomas Hellström, David Airlie,
Simona Vetter, linux-mtd, linux-kernel, intel-xe, dri-devel,
Menachem Adin
On Wed, Sep 30, 2026 at 05:14:47PM +0300, Alexander Usyskin wrote:
typo in the subject, but I will fix while merging it.
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Define 8M survivability partition for CRI when
> storage is open for write override.
>
> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
> ---
> drivers/gpu/drm/xe/xe_nvm.c | 13 ++++++++++---
> 1 file changed, 10 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_nvm.c b/drivers/gpu/drm/xe/xe_nvm.c
> index 51a1a431ad85..783c3103a8a4 100644
> --- a/drivers/gpu/drm/xe/xe_nvm.c
> +++ b/drivers/gpu/drm/xe/xe_nvm.c
> @@ -56,10 +56,11 @@ static bool xe_nvm_non_posted_erase(struct xe_device *xe)
> }
> }
>
> -static bool xe_nvm_writable_override(struct xe_device *xe)
> +static bool xe_nvm_writable_override(struct xe_device *xe, size_t *survivability_size)
> {
> struct xe_mmio *mmio = xe_root_tile_mmio(xe);
> bool writable_override;
> + size_t s_size = 0;
> struct xe_reg reg;
> u32 test_bit, test_val;
>
> @@ -68,6 +69,7 @@ static bool xe_nvm_writable_override(struct xe_device *xe)
> reg = PCODE_SCRATCH(0);
> test_bit = FDO_MODE;
> test_val = FDO_MODE;
> + s_size = SZ_8M;
> break;
> case XE_BATTLEMAGE:
> reg = HECI_FWSTS2(DG2_GSC_HECI2_BASE);
> @@ -91,12 +93,17 @@ static bool xe_nvm_writable_override(struct xe_device *xe)
> break;
> default:
> drm_err(&xe->drm, "Unknown platform\n");
> + *survivability_size = 0;
> return true;
> }
>
> writable_override = (xe_mmio_read32(mmio, reg) & test_bit) == test_val;
> - if (writable_override)
> + if (writable_override) {
> drm_info(&xe->drm, "NVM access overridden by jumper\n");
> + *survivability_size = s_size;
> + } else {
> + *survivability_size = 0;
> + }
> return writable_override;
> }
>
> @@ -143,7 +150,7 @@ int xe_nvm_init(struct xe_device *xe)
> if (!nvm)
> return -ENOMEM;
>
> - nvm->writable_override = xe_nvm_writable_override(xe);
> + nvm->writable_override = xe_nvm_writable_override(xe, &nvm->survivability_size);
> nvm->non_posted_erase = xe_nvm_non_posted_erase(xe);
> nvm->bar.parent = &pdev->resource[0];
> nvm->bar.start = GEN12_GUNIT_NVM_BASE + pdev->resource[0].start;
>
> --
> 2.53.0
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-08 16:43 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-30 14:14 [PATCH v3 0/2] drm/xe/nvm: add survivabilty partiton Alexander Usyskin
2026-09-30 14:14 ` [PATCH v3 1/2] mtd: mtd_intel_dg: add survivability partition Alexander Usyskin
2026-10-08 16:42 ` Rodrigo Vivi
2026-09-30 14:14 ` [PATCH v3 2/2] drm/xe/nvm: define survivabilty partition Alexander Usyskin
2026-10-08 16:43 ` Rodrigo Vivi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®