Skip to content

Conversation

mkeeter
Copy link
Collaborator

@mkeeter mkeeter commented Feb 7, 2025

hf.bonus_sector_erase(offset)
.map_err(|err| APOBError::EraseFailed { offset, err })?;
} else {
// Read back the page and confirm that it's all empty
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this fail if there's a blip in the IPCC path and the host resends an APOB request? (I'm not sure what the expectations are for the offsets the host is providing.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This has changed a bunch since February; messages should now all be idempotent.

@mkeeter mkeeter marked this pull request as draft February 7, 2025 17:08
Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

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

Some mostly kind of annoying nitpicks.

Comment on lines 1079 to 1083
fn apob_write(
hf: &HostFlash,
mut offset: u64,
data: &[u8],
) -> Result<(), ApobError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

So we need something in the broader API to discover what the erase size granularity is or at least make sure that we're sending stuff that is page size aligned. This gets to what @jgallagher gets at below. But if the host sent things that wasn't page aligned then we'd erase the entire page because our API is not doing a read-modify-write.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This has all changed now – we ensure that the to-be-written page is erased when the state machine starts, and writes are idempotent.

@mkeeter mkeeter force-pushed the mkeeter/ipcc-apob branch 3 times, most recently from 14165d3 to b0acdc3 Compare September 26, 2025 15:37
@mkeeter mkeeter force-pushed the mkeeter/ipcc-apob branch from f7e8314 to 4a07f2b Compare October 1, 2025 14:00
@mkeeter mkeeter marked this pull request as ready for review October 1, 2025 14:13
@mkeeter mkeeter force-pushed the mkeeter/ipcc-apob branch from ded1fa1 to ad93477 Compare October 1, 2025 14:27
Copy link
Collaborator

@labbott labbott left a comment

Choose a reason for hiding this comment

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

Will probably do another pass later

/// Either 0 or 1; directly translatable to [`ApobSlot`]
pub slot_select: u32,

/// CRC-32 over the rest of the data using the iSCSI polynomial
Copy link
Collaborator

Choose a reason for hiding this comment

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

Any significance to the choice of polynomial? (curiosity more than anything)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I copied what we used for HfRawPersistentData 😄

checksum: 0, // dummy value
};
out.checksum = out.expected_checksum();
assert!(out.is_valid());
Copy link
Collaborator

Choose a reason for hiding this comment

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

assert becomes panic, is that the behavior we want here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think so; the only way this should panic is if someone has broken the code in a dramatic way (e.g. editing the implementation of is_valid so that previously valid data is no longer valid).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But this is also copied from HfRawPersistentData, so I didn't think about it too much!

Comment on lines +265 to +267
/// Either 0 or 1; directly translatable to [`ApobSlot`]
pub slot_select: u32,
Copy link
Collaborator

Choose a reason for hiding this comment

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

There are a couple of places where we have unreachable because of using the u32, maaaybe an enum would be cleaner and reduce a few checks? Or is the issue this needs to match exactly what the host is expecting?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This isn't seen at all by the host, but we're reading / writing this object directly to disk, so we need zerocopy-friendly types.

Copy link
Member

Choose a reason for hiding this comment

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

FWIW, zerocopy::TryFromBytes can be derived for enums (though I'm not sure how annoying that would be to actually use here)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think it would be usable, but the docs seem to imply that you shouldn't it when round-tripping through bytes (?!).

I've opened google/zerocopy#2722 to ask for clarification

fn fail(err: drv_hf_api::HfError) {
let mut buffer = [0; hf::idl::INCOMING_SIZE];
let mut server = hf::idl::FailServer::new(err);
let mut server = hf::FailServer(err);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmm, do we lose the idl generation of this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah – I switched to finer-grained error types for a few methods, which means that the IDL generator can't make a FailServer (which assumes a single error type).

pub(crate) fn write(
&mut self,
drv: &mut FlashDriver,
offset: u64,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need the u64 everywhere? It seems like everything gets converted/checked against u32 anyway

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The initial u64 is sent by the host, but I pushed the u32 conversion upstream into host_sp_comms.

@mkeeter mkeeter force-pushed the mkeeter/ipcc-apob branch 2 times, most recently from 49afe3d to 695c7d5 Compare October 2, 2025 14:30
@citrus-it
Copy link
Contributor

@mkeeter - here are the IPCC messages which are expected to be seen before the host is finished with APOB. Anything else incoming from the host should trigger the lockdown.

humility: ring buffer task_host_sp_comms::__RINGBUF in host_sp_comms:
   TOTAL VARIANT
      99 Request(ApobRead)
      96 Request(ApobData)
       2 Request(KeyLookup)
       1 Request(GetBootStorageUnit)
       1 Request(GetIdentity)
       1 Request(GetStatus)
       1 Request(AckSpStart)
       1 Request(ApobBegin)
       1 Request(ApobCommit)

@mkeeter mkeeter force-pushed the mkeeter/ipcc-apob branch from efc7039 to 8d35455 Compare October 2, 2025 20:35
@mkeeter
Copy link
Collaborator Author

mkeeter commented Oct 2, 2025

@citrus-it Great, thanks! I've pushed this list to Hubris and to RFD 593.

@mkeeter mkeeter force-pushed the mkeeter/ipcc-apob branch from 8d35455 to 58e761d Compare October 2, 2025 20:40
@mkeeter mkeeter force-pushed the mkeeter/ipcc-apob branch from 58e761d to f883776 Compare October 3, 2025 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants