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

Add Svnapot and Svpbmt extensions #393

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

Conversation

ved-rivos
Copy link
Contributor

No description provided.

@ved-rivos ved-rivos mentioned this pull request Jan 21, 2024
Copy link
Collaborator

@jrtc27 jrtc27 left a comment

Choose a reason for hiding this comment

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

extPte is used by sail-cheri-riscv. Being an ext* thing it's not to be used in the standard model lest you break such downstream use cases.

@ved-rivos
Copy link
Contributor Author

ved-rivos commented Jan 21, 2024

extPte is used by sail-cheri-riscv. Being an ext* thing it's not to be used in the standard model lest you break such downstream use cases.

The extPte is a misnomer in the current model as being something to be used for non-standard extensions. These bits are reserved for standard extensions. CHERI use of these will be a non-conforming extension which is fine and CHERI should get added accordingly. Non-tree non-standard extensions should not be using bits reserved for future standard use. I think CHERI should define a new virtual memory system mode where it can put new non-RISC-V interpretations on these bits.

@jrtc27
Copy link
Collaborator

jrtc27 commented Jan 21, 2024

extPte is used by sail-cheri-riscv. Being an ext* thing it's not to be used in the standard model lest you break such downstream use cases.

The extPte is a misnomer in the current model as being something to be used for non-standard extensions. These bits are reserved for standard extensions. CHERI use of these will be a non-conforming extension which is fine and CHERI should get added accordingly. Non-tree non-standard extensions should not be using bits reserved for future standard use. I think CHERI should define a new virtual memory system mode where it can put new non-RISC-V interpretations on these bits.

It's ext not stdExt, and there was no non-reserved way to extend the page table format in a custom extension at the time it was created. I am just asking you to not break existing uses of the model, one that has been around for many years and was developed at the same time and influenced the design of the base Sail model.

@ved-rivos
Copy link
Contributor Author

extPte is used by sail-cheri-riscv. Being an ext* thing it's not to be used in the standard model lest you break such downstream use cases.

The extPte is a misnomer in the current model as being something to be used for non-standard extensions. These bits are reserved for standard extensions. CHERI use of these will be a non-conforming extension which is fine and CHERI should get added accordingly. Non-tree non-standard extensions should not be using bits reserved for future standard use. I think CHERI should define a new virtual memory system mode where it can put new non-RISC-V interpretations on these bits.

It's ext not stdExt, and there was no non-reserved way to extend the page table format in a custom extension at the time it was created. I am just asking you to not break existing uses of the model, one that has been around for many years and was developed at the same time and influenced the design of the base Sail model.

If a custom extension needs to redefine PTE layout then the right way would be to use a custom satp.MODE. The PTE layouts defined in RISC-V apply to the standard modes defined by RISC-V for satp.MODE. The model can then qualify these checks by the satp.MODE and the custom extension can provide its own implementation for validating PTEs. It would be wrong to hold back Svnapot and Svpbmt standard extensions from the golden reference model to avoid breaking an unrelated out of tree usage.

@jrtc27
Copy link
Collaborator

jrtc27 commented Jan 21, 2024

extPte is used by sail-cheri-riscv. Being an ext* thing it's not to be used in the standard model lest you break such downstream use cases.

The extPte is a misnomer in the current model as being something to be used for non-standard extensions. These bits are reserved for standard extensions. CHERI use of these will be a non-conforming extension which is fine and CHERI should get added accordingly. Non-tree non-standard extensions should not be using bits reserved for future standard use. I think CHERI should define a new virtual memory system mode where it can put new non-RISC-V interpretations on these bits.

It's ext not stdExt, and there was no non-reserved way to extend the page table format in a custom extension at the time it was created. I am just asking you to not break existing uses of the model, one that has been around for many years and was developed at the same time and influenced the design of the base Sail model.

If a custom extension needs to redefine PTE layout then the right way would be to use a custom satp.MODE. The PTE layouts defined in RISC-V apply to the standard modes defined by RISC-V for satp.MODE. The model can then qualify these checks by the satp.MODE and the custom extension can provide its own implementation for validating PTEs. It would be wrong to hold back Svnapot and Svpbmt standard extensions from the golden reference model to avoid breaking an unrelated out of tree usage.

CHERI-RISC-V predates all of that. So no, we're not changing what was specified in the past. Ratified CHERI-RISC-V is on the way and will be standard, whatever that means for the design, but we are not changing our current specification. You may not care about CHERI, but CHERI-RISC-V is a big reason the base model exists at all. I'm not saying not to add Svpbmt and Svnapot support, I'm saying to add it in such a way that the existing CHERI-RISC-V model can opt out of it. Otherwise you are breaking a real-world use case that the model has always been intended to support from the very first moment it was written.

@ved-rivos
Copy link
Contributor Author

CHERI-RISC-V predates all of that. So no, we're not changing what was specified in the past. Ratified CHERI-RISC-V is on the way and will be standard, whatever that means for the design, but we are not changing our current specification. You may not care about CHERI, but CHERI-RISC-V is a big reason the base model exists at all. I'm not saying not to add Svpbmt and Svnapot support, I'm saying to add it in such a way that the existing CHERI-RISC-V model can opt out of it. Otherwise you are breaking a real-world use case that the model has always been intended to support from the very first moment it was written.

It likely does predate but this repo is the RISC-V reference model and that is the primary goal. Serving non tree extensions would be secondary goal. As to how to make an out of tree usage that conflicts with the base RISC-V architecture work I lack enough known about CHERI and what its specification is. So suggest you create a PR with a suggestion on how that can be made to work and we can review it here.

@Alasdair
Copy link
Collaborator

@jrtc27 I agree we should not break CHERI, do you have a suggestion for how we can avoid this? It seems to me like we could have something like:

match ext_isInvalidPTE(p, ext) {
  Some(is_valid) => is_valid,
  None() => <standard logic> 
}

The base model would then have an implementation of ext_isInvalidPTE that always returns None(), which could be overridden by CHERI.

The model uses function prefixed ext_ has 'hook' points for out of tree uses to adapt the behavior of the model. I think using EXT or ext as prefix like in EXT_PTE_Bits is probably confusing given this.

@jrtc27
Copy link
Collaborator

jrtc27 commented Jan 21, 2024

@jrtc27 I agree we should not break CHERI, do you have a suggestion for how we can avoid this? It seems to me like we could have something like:

match ext_isInvalidPTE(p, ext) {
  Some(is_valid) => is_valid,
  None() => <standard logic> 
}

The base model would then have an implementation of ext_isInvalidPTE that always returns None(), which could be overridden by CHERI.

The model uses function prefixed ext_ has 'hook' points for out of tree uses to adapt the behavior of the model. I think using EXT or ext as prefix like in EXT_PTE_Bits is probably confusing given this.

That seems sufficient and pretty straightforward.

@ved-rivos
Copy link
Contributor Author

The base model would then have an implementation of ext_isInvalidPTE that always returns None(), which could be overridden by CHERI.

@Alasdair The use of those bits in walk39/walk48 will also need to be qualified by haveSvnapot() otherwise the walk if it finds the N bit set will interpret the PTE to be in Svnapot form. This should be a small update. I will push an update with this idea. The haveSvnapot() however is hard coded to true (like all other extensions). Should that be made a command line switch? Or do the out of tree uses have a way around this?

@jrtc27
Copy link
Collaborator

jrtc27 commented Jan 21, 2024

We don't, so that will need some way to turn it off without modifying non-ext files.

@ved-rivos
Copy link
Contributor Author

I will add a command line switch. Maybe its time to add an isa parser.

I think using EXT or ext as prefix like in EXT_PTE_Bits is probably confusing given this.

extPte can be renamed as pteStdExtAttribs and EXT_PTE_Bits to PTE_StdExt_Bits (and likewise for other names like ext_pte, default_sv32_ext_pte, pte.Ext(). Does that look better?

@jrtc27
Copy link
Collaborator

jrtc27 commented Jan 21, 2024

I will add a command line switch.

That doesn't really help out-of-tree extensions override it, because the command-line switch lives in the .c and .ml files, so you'd be requiring sail-cheri-riscv users to always disable Svnapot on the command-line, which is not a helpful interface. It needs to be disableable statically at build time without modifying non-ext files.

@ved-rivos
Copy link
Contributor Author

ved-rivos commented Jan 21, 2024

I will add a command line switch.

That doesn't really help out-of-tree extensions override it, because the command-line switch lives in the .c and .ml files, so you'd be requiring sail-cheri-riscv users to always disable Svnapot on the command-line, which is not a helpful interface. It needs to be disableable statically at build time without modifying non-ext files.

I planned to have a command line switch to enable it and not disable. The current practice of statically enabling every extension in Sail RISC-V model is a problem because people cannot use it without code modification as a reference model. This switch will be temporary and we should have a ISA string parser so people can customize the reference to their DUT specific configuration without needing source changes.

Copy link

github-actions bot commented Jan 21, 2024

Test Results

712 tests  ±0   712 ✅ ±0   0s ⏱️ ±0s
  6 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 3c09a50. ± Comparison against base commit db5f430.

♻️ This comment has been updated with latest results.

@jrtc27
Copy link
Collaborator

jrtc27 commented Jan 21, 2024

I will add a command line switch.

That doesn't really help out-of-tree extensions override it, because the command-line switch lives in the .c and .ml files, so you'd be requiring sail-cheri-riscv users to always disable Svnapot on the command-line, which is not a helpful interface. It needs to be disableable statically at build time without modifying non-ext files.

I planned to have a command line switch to enable it and not disable. The current practice of statically enabling every extension in Sail RISC-V model is a problem because people cannot use it without code modification as a reference model. This switch will be temporary and we should have a ISA string parser so people can customize the reference to their DUT specific configuration without needing source changes.

Ok, off-by-default works.

@ved-rivos
Copy link
Contributor Author

ved-rivos commented Jan 22, 2024

Updated as follows:

  1. Add --enable-svnapot and --enable-svpbmt command line switches. In tree usages will need to provide the switch to explicitly enable the RISC-V standard extensions. Out of tree usages will not have to do more work.
  2. Add ext_isInvalidPTE - returns invalid, valid, or standard. If custom extension check fails should return invalid. To skip standard extension checks returns valid. Default is to invoke standard extension checks. Renamed ext_pte to std_ext to avoid confusion with name.
  3. Dropped the test while we figure out what the test framework for the model should be and how to integrate that into CI.

@billmcspadden-riscv
Copy link
Collaborator

billmcspadden-riscv commented Jan 22, 2024 via email

@ved-rivos
Copy link
Contributor Author

@jrtc27 - Did that address the change requested?

@martinberger
Copy link
Collaborator

martinberger commented Mar 12, 2024

@ved-rivos Quick question: given that purpose of Svpbmt is overriding of PMAs, how and where do you expect PMA checks to access the relevant bits 62–61 of a leaf page table entry?

@ved-rivos
Copy link
Contributor Author

ved-rivos commented Mar 12, 2024

@martinberger - for each load/store/instruction-fetch, we would first determine the PBMT from bits 62:61 of the PTE entry that provides its system physical address. If the PBMT is IO or NC then those attributes apply. If PBMT=PMA, then the attributes associated with the system physical address apply. In cases where PBMT is IO or NC, rest of the attributes that apply may be those associated with system physical address or an implementation may override them as well (e.g., an implementation may not support AMO PMAs for IO memory).

@jrtc27
Copy link
Collaborator

jrtc27 commented Mar 12, 2024

But where is that being captured in the model?

@ved-rivos
Copy link
Contributor Author

There are no PMAs modeled afaict.

@ved-rivos
Copy link
Contributor Author

Yes, exactly. But right now the PBMT info is not returned to the caller, if I understand the logic of your implementation

When the PMA's are implemented then we would need the PBMT provided to caller. Right now there are no physical memory attributes in the model to provide to the caller.

@martinberger
Copy link
Collaborator

martinberger commented Mar 13, 2024

Yes, exactly. But right now the PBMT info is not returned to the caller, if I understand the logic of your implementation

When the PMA's are implemented then we would need the PBMT provided to caller. Right now there are no physical memory attributes in the model to provide to the caller.

Yes, but a lot of RV companies will have their own local PMP/PMA already, and there will be even more in the future. Why not make the PBMT information export to the caller already? Otherwise each company will cook up their own and upstreaming code becomes a tiny bit more burdensome?

I'm not dogmatic about this, just wondering if we could make the code a tiny big more upstream-friendly

@ved-rivos
Copy link
Contributor Author

Sure. That makes sense. Let me add that to the bundle.

@martinberger
Copy link
Collaborator

Sure. That makes sense. Let me add that to the bundle.

One possible way could be to change TR_Result to something like:


type pbmt_bits = bits(2) // For Svpbmt extension                                                   

union TR_Result('paddr : Type, 'failure : Type) = {
  TR_Address : ('paddr, ext_ptw, pbmt_bits),
  TR_Failure : ('failure, ext_ptw)
}

(This is not the only way)

@ved-rivos
Copy link
Contributor Author

Is there a requirement that unions cannot be > 64 bits. I get this error with:

union TR_Result('paddr : Type, 'failure : Type) = {
  TR_Address : ('paddr, bits(10), ext_ptw),
  TR_Failure : ('failure, ext_ptw)
}
generated_definitions/c/riscv_model_RV64.c: In function ‘ztranslateAddr_priv’:
generated_definitions/c/riscv_model_RV64.c:61152:87: error: incompatible type for argument 1 of ‘convert_fbits_of_lbits’
61152 |         zstd_ext = CONVERT_OF(fbits, lbits)(zgaz32384.zTR_AddresszIUPTW_ErrorzIzKzCbzK.ztup1, true);
      |                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
      |                                                                                       |
      |                                                                                       uint64_t {aka long unsigned int}
In file included from generated_definitions/c/riscv_model_RV64.c:1:
/home/ved/.opam/4.08.0/share/sail/lib/sail.h:311:32: note: expected ‘lbits’ but argument is of type ‘uint64_t’ {aka ‘long unsigned int’}
  311 | fbits CONVERT_OF(fbits, lbits)(const lbits, const bool);
      |                                ^~~~~~~~~~~
generated_definitions/c/riscv_model_RV64.c:61286:86: error: incompatible type for argument 1 of ‘convert_fbits_of_lbits’
61286 |         zuz3309 = CONVERT_OF(fbits, lbits)(zgaz32395.zTR_AddresszIUPTW_ErrorzIzKzCbzK.ztup1, true);
      |                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
      |                                                                                      |
      |                                                                                      uint64_t {aka long unsigned int}
In file included from generated_definitions/c/riscv_model_RV64.c:1:
/home/ved/.opam/4.08.0/share/sail/lib/sail.h:311:32: note: expected ‘lbits’ but argument is of type ‘uint64_t’ {aka ‘long unsigned int’}
  311 | fbits CONVERT_OF(fbits, lbits)(const lbits, const bool);

@martinberger
Copy link
Collaborator

martinberger commented Mar 17, 2024

Is there a requirement that unions cannot be > 64 bits.

There is no such requirement. This looks like a Sail compiler bug because it is the C-compiler complaining. Several such incompatible type problems were recently fixed. What version of the Sail compiler are you using? I hit the same problem a few months back rems-project/sail#401 .

@Alasdair

@ved-rivos
Copy link
Contributor Author

I have - Sail 0.17.1 (sail @ opam-v2.1.2)

@martinberger
Copy link
Collaborator

martinberger commented Mar 18, 2024

I have - Sail 0.17.1 (sail @ opam-v2.1.2)

That's an old version and will fail on the problem I reported in rems-project/sail#401. I think that's the same problem you are seeing. That problem was fixed last year. I suggest that you upgrade to a new version of the compiler. I don't know if the fix has already reached the official version that is distributed with opam.

@jrtc27
Copy link
Collaborator

jrtc27 commented Mar 18, 2024

There isn't a newer version tagged, and opam is just pointing at the 0.17.1 tag. Sounds like we need a new release?

@martinberger
Copy link
Collaborator

There isn't a newer version tagged, and opam is just pointing at the 0.17.1 tag. Sounds like we need a new release?

Yes, a new opam version would be good---Alasdair did a lot of work on the Compiler.

@ved-rivos
Copy link
Contributor Author

Updating the union declaration fixes the error:

union TR_Result('paddr : Type, 'std_ext_bits : Type, 'failure : Type) = {
  TR_Address : ('paddr, 'std_ext_bits, ext_ptw),
  TR_Failure : ('failure, ext_ptw)
}

@ved-rivos
Copy link
Contributor Author

Updated to provide the PBMT bits (and other standard extension bits) along with the translation results to load/store/instruction-fetch.

@ved-rivos
Copy link
Contributor Author

@martinberger - does this look good? Are further changes needed?

@martinberger
Copy link
Collaborator

martinberger commented Mar 23, 2024

does this look good? Are further changes needed?

@ved-rivos LGTM (modulo trimming trailing whitespace etc to get past the code format checkers). We should try and get it in soon.

@billmcspadden-riscv billmcspadden-riscv added the tgmm-agenda Tagged for the next Golden Model meeting agenda. label Mar 25, 2024
@ved-rivos ved-rivos force-pushed the svpbmt1 branch 4 times, most recently from ce59d0a to 9919687 Compare April 21, 2024 16:06
@martinberger
Copy link
Collaborator

@Timmmm and I were thinking that it'd be better to convert the two PBMT bits directly at the source to a suitable symbolic representation and then send that to the PMA checks. That would give us stronger type-checks, and, at the same time, serve as documentation. How about this:

enum PBMT = { PMA, NC, IO }

mapping pbmt_enc : PBMT <-> bits(2) = {
  PMA <-> 0b00,
  NC  <-> 0b01,
  IO  <-> 0b10,
  // 0b11 is reserved.
}

@ved-rivos
Copy link
Contributor Author

@Timmmm and I were thinking that it'd be better to convert the two PBMT bits directly at the source to a suitable symbolic representation and then send that to the PMA checks. That would give us stronger type-checks, and, at the same time, serve as documentation. How about this:

enum PBMT = { PMA, NC, IO }

mapping pbmt_enc : PBMT <-> bits(2) = {
  PMA <-> 0b00,
  NC  <-> 0b01,
  IO  <-> 0b10,
  // 0b11 is reserved.
}

The code presently provides all the extended PTE bits along. The PBMT bits have been checked for reserved encodings at the source. The expectation is that at the destination - such as PMA checks - the extended PTE bits will intrepreted as PTE_Ext_Flags and then mapped to the symbolic name.

Copy link
Collaborator

@Timmmm Timmmm 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 to me. There are some minor style issues but easy to fix.

@@ -837,6 +849,7 @@ register senvcfg : SEnvcfg
function legalize_menvcfg(o : MEnvcfg, v : bits(64)) -> MEnvcfg = {
let v = Mk_MEnvcfg(v);
let o = [o with FIOM = if sys_enable_writable_fiom() then v[FIOM] else 0b0];
let o = [o with PBMTE = if haveSvpbmt() then v[PBMTE] else 0b0];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor style thing but you can just add this into the previous line like

[o with
  FIOM = ...,
  PBMTE = ...
]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

@@ -151,7 +152,10 @@ function pt_walk(sv_params,
let mask_bits = level * sv_params.pte_PPN_j_size_bits;
// Clear the lowest `mask_bits` bits.
let ppns_masked = (ppns >> mask_bits) << mask_bits;
if not(ppns == ppns_masked) then
if haveSvnapot() & ext_pte_flags[N] == 0b1 then
// Superpage NAPOT PTEs are invalid
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it make more sense to pass the level to pte_is_invalid and do this check there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

// Only 64K NAPOT PTEs are valid
PTW_Failure(PTW_Invalid_PTE(), ext_ptw)
} else {
let final_ppn : bits(64) = match (haveSvnapot(), ext_pte_flags[N]) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I really think an if is clearer for these sorts of things. Also you can just reuse the ppns name. And use @ instead of append.

let ppns = if haveSvnapot() & ext_pte_flags[N] == 0b1
  then ppns[63 .. 4] @ vpn_j[3 .. 0]
  else ppns;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

bitfield PTE_Ext_Flags : extPte = {
N : 9,
PBMT : 8 .. 7,
RSVD : 6 .. 0
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor but can we style this like reserved so it doesn't look like it is an actual field?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

@@ -275,8 +286,8 @@ function write_pte forall 'n, 'n in {4, 8} . (
// Result of address translation

// PUBLIC
union TR_Result('paddr : Type, 'failure : Type) = {
TR_Address : ('paddr, ext_ptw),
union TR_Result('paddr : Type, 'ext_pte_bits : Type, 'failure : Type) = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

ext_pte_bits is always extPte - is there any point parameterising it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

please explain more.

@@ -51,10 +58,33 @@ function pte_is_ptr(pte_flags : PTE_Flags) -> bool = (pte_flags[X] == 0b0)
& (pte_flags[W] == 0b0)
& (pte_flags[R] == 0b0)

// Extension hooks can request standard PTE validity checks by returning Ext_PTE_Std
union Ext_isInvalPTE_Check = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

enum

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

pte_ext_flags[N] != 0b0 | pte_ext_flags[PBMT] != 0b00))
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this can be simplified a bit. Here's our version, IIRC I based it on yours.

function pte_is_invalid(pte_flags : PTE_Flags, pte_ext : PTE_Ext) -> bool =
  match ext_pte_validity(pte_flags, pte_ext) {
    Ext_PTE_Invalid => true,
    Ext_PTE_Valid   => false,
    Ext_PTE_Std     =>
        pte_flags[V] == 0b0
      | (pte_flags[W] == 0b1 & pte_flags[R] == 0b0)
      // These bits must be zero unless the relevant extension is supported
      // and this is a leaf node.
      | pte_ext[N]    != zeros() & (not(haveSvnapot()) | pte_is_ptr(pte_flags))
      | pte_ext[PBMT] != zeros() & (not(haveSvpbmt())  | pte_is_ptr(pte_flags))
      // PBMT 0b11 is always reserved. This applies even without PBMT support.
      | pte_ext[PBMT] == 0b11
      // Reserved bits must be 0.
      | pte_ext[reserved] != zeros()
  }

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 version is missing a few things:

  1. A, D, and U flags are reserved in non-leaf PTEs
  2. PBMT is reserved if menvcfg.PBMTE is 0
  3. N bit is reserved for superpage leaf PTEs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Timmmm - let me know if any other changes are needed.

@ved-rivos ved-rivos force-pushed the svpbmt1 branch 2 times, most recently from 75d7b42 to 4ba998f Compare July 6, 2024 18:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tgmm-agenda Tagged for the next Golden Model meeting agenda.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants