Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf_security: cracen: Improve DCACHE handling #20419

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

karstenkoenig
Copy link
Contributor

Calling plain invalidate isn't always safe, as there might be pending writes in the cache line that just get thrown away. Just switch to full cache line evasion, so writeback + invalidate just to be safe. Also iterate over the out descriptors to make sure all the buffers are cache handled on completing of the cracen operations.

@karstenkoenig karstenkoenig added DNM CI-disable Disable CI for this PR labels Feb 17, 2025
@github-actions github-actions bot added the changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. label Feb 17, 2025
@NordicBuilder
Copy link
Contributor

NordicBuilder commented Feb 17, 2025

CI Information

To view the history of this post, clich the 'edited' button above
Build number: 6

Inputs:

Sources:

sdk-nrf: PR head: 87a880672b6fc8800949ba36a59c73e59237597f

more details

sdk-nrf:

PR head: 87a880672b6fc8800949ba36a59c73e59237597f
merge base: 609ac31a15f174eeeb0bc2495a96b2c8d2eb9685
target head (main): 5697b09d308397c7b849dfbe8aeaf15b81a16b9e
Diff

Github labels

Enabled Name Description
ci-disabled Disable the ci execution
ci-all-test Run all of ci, no test spec filtering will be done
ci-force-downstream Force execution of downstream even if twister fails
ci-run-twister Force run twister
ci-run-zephyr-twister Force run zephyr twister
List of changed files detected by CI (6)
subsys
│  ├── nrf_security
│  │  ├── src
│  │  │  ├── drivers
│  │  │  │  ├── cracen
│  │  │  │  │  ├── sxsymcrypt
│  │  │  │  │  │  ├── src
│  │  │  │  │  │  │  ├── aead.c
│  │  │  │  │  │  │  ├── blkcipher.c
│  │  │  │  │  │  │  ├── cmdma.c
│  │  │  │  │  │  │  ├── cmdma.h
│  │  │  │  │  │  │  ├── hash.c
│  │  │  │  │  │  │  │ mac.c

Outputs:

Toolchain

Version: aedb4c0245
Build docker image: docker-dtr.nordicsemi.no/sw-production/ncs-build:aedb4c0245_bece0367df

Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped; ⚠️ Quarantine

  • ◻️ Toolchain - Skipped: existing toolchain is used
  • ✅ Build twister
    • sdk-nrf test count: 1716
  • ✅ Integration tests
    • ✅ test-fw-nrfconnect-chip
    • ✅ test-fw-nrfconnect-nrf-iot_cloud
    • ✅ test-fw-nrfconnect-nrf_crypto
    • ✅ test-fw-nrfconnect-tfm
    • ✅ test-sdk-find-my
    • ✅ test-sdk-sidewalk
    • ✅ test-sdk-dfu
Disabled integration tests
    • desktop52_verification
    • doc-internal
    • test_ble_nrf_config
    • test-fw-nrfconnect-apps
    • test-fw-nrfconnect-ble_mesh
    • test-fw-nrfconnect-ble_samples
    • test-fw-nrfconnect-boot
    • test-fw-nrfconnect-fem
    • test-fw-nrfconnect-nfc
    • test-fw-nrfconnect-nrf-iot_libmodem-nrf
    • test-fw-nrfconnect-nrf-iot_lwm2m
    • test-fw-nrfconnect-nrf-iot_mosh
    • test-fw-nrfconnect-nrf-iot_positioning
    • test-fw-nrfconnect-nrf-iot_samples
    • test-fw-nrfconnect-nrf-iot_serial_lte_modem
    • test-fw-nrfconnect-nrf-iot_thingy91
    • test-fw-nrfconnect-nrf-iot_zephyr_lwm2m
    • test-fw-nrfconnect-proprietary_esb
    • test-fw-nrfconnect-ps
    • test-fw-nrfconnect-rpc
    • test-fw-nrfconnect-rs
    • test-fw-nrfconnect-thread
    • test-fw-nrfconnect-zigbee
    • test-low-level
    • test-sdk-audio
    • test-sdk-mcuboot
    • test-sdk-pmic-samples
    • test-sdk-wifi
    • test-secdom-samples-public

Note: This message is automatically posted and updated by the CI

sys_cache_data_flush_range(&out_desc, sizeof(out_desc));
sys_cache_data_flush_range(input, input_size);
sys_cache_data_flush_range(output, output_size);
sys_cache_data_flush_and_invd_range(in_descs, sizeof(in_descs));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is overkill, flush would be enough, only output needs to be invalidated and that is done once the sx_cmdma_check() returned ok

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's overkill why not continue using sys_cache_data_flush_range() where it's okay?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry yes that is the plan I just wanted some initial feedback on the changes in general. I used sys_cache_data_flush_and_invd_range as I wanted to avoid any optimization in a first pass to see if it makes CI pass when DCACHE is enabled. It still doesn't so I was hoping to get more eyes onto it first

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just noticed these aren't correct, they just flush the descriptors, not the buffers itself, needs to be reworked

@@ -381,7 +381,9 @@ int sx_blkcipher_status(struct sxblkcipher *c)
}

#if CONFIG_DCACHE
sys_cache_data_invd_range((void *)&c->extramem, sizeof(c->extramem));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invalidate range should be avoided as it could lead to memory loss on that cacheline if something else on the line was written by the core, e.g. if extramem is somewhere on the stack

@karstenkoenig karstenkoenig removed DNM CI-disable Disable CI for this PR labels Feb 20, 2025
@karstenkoenig karstenkoenig marked this pull request as ready for review February 20, 2025 13:43
@karstenkoenig karstenkoenig requested a review from a team as a code owner February 20, 2025 13:43
Copy link
Contributor

@tomi-font tomi-font left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

sys_cache_data_flush_range(&out_desc, sizeof(out_desc));
sys_cache_data_flush_range(input, input_size);
sys_cache_data_flush_range(output, output_size);
sys_cache_data_flush_and_invd_range(in_descs, sizeof(in_descs));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's overkill why not continue using sys_cache_data_flush_range() where it's okay?

@karstenkoenig karstenkoenig force-pushed the dcache_cracen branch 3 times, most recently from 976946a to b0abce8 Compare February 24, 2025 13:22
@@ -474,7 +474,8 @@ int sx_aead_status(struct sxaead *c)
}

#if CONFIG_DCACHE
sys_cache_data_invd_range((void *)&c->extramem, sizeof(c->extramem));
sx_cmdma_outdescs_flush_and_invd_dcache(&c->dma);
sys_cache_data_flush_and_invd_range((void *)&c->extramem, sizeof(c->extramem));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this patch it is my understanding that the driver would do this:

sx_cmdma_check(); // Wait for CRACEN to write to RAM

sys_cache_data_invd_range(); // Invalidate the datacache, as it is now outdated wrt. what CRACEN wrote to RAM.

sx_memdiff(c->expectedtag, c->extramem); // Read from RAM what CRACEN wrote

In this new version we will do this:

sx_cmdma_check(); // Wait for CRACEN to write to RAM

sys_cache_data_flush_and_invd_range(); // Write the affected cachelines to RAM, and then invalidate those cachelines

Won't the sys_cache_data_flush_and_invd_range overwrite what CRAECN just wrote to RAM? Or am I misreading this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm thanks for raising this to my attention again, I thought this would be perfect as sys_cache_data_flush_and_invd_range is the same as cache eviction and that might happen at any time anyways and makes sure all the data the core has written to gets properly stored. A cacheline can be shared between output buffer and other data structures from the core, and if the core wrote to that other data it isn't allowed to get lost either.

But there is still chance for failure. The granularity for our data cache isn't a full cacheline, but a data unit, so sharing a cache line between local data structures and an output buffer for dma can be ok as long as the output buffer is 32bit aligned and is a multiple of 32bits in size.
But if the output buffer and some other date share the same dataunit in a cacheline you can get a conflict, but then both operations (data_flush_and_invd_range and invd_range) are wrong, as they both lead to a data loss, as this will either throw away the dirty memory inside the cores data cache, or write out the full 32bit word on a flush overwriting part of the output buffer. Need to take another round through this, and also the client side then.

Calling plain invalidate isn't always safe, as there might be pending
writes in the cache line that just get thrown away. Just switch to full
cache line evasion, so writeback + invalidate just to be safe.
Also iterate over the out descriptors to make sure all the buffers are
cache handled on completing of the cracen operations.

Signed-off-by: Karsten Koenig <karsten.koenig@nordicsemi.no>
Copy link
Contributor

@tomi-font tomi-font left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good for now.

Copy link

This pull request has been marked as stale because it has been open (more than) 30 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 7 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions bot added the Stale label Mar 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. DNM Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants