On 12/20/21, Greg KH <gregkh@xxxxxxxxxxxxxxxxxxx> wrote: > On Thu, Dec 16, 2021 at 04:22:20PM -0300, Martin Fernandez wrote: >> diff --git a/arch/x86/include/asm/e820/types.h >> b/arch/x86/include/asm/e820/types.h >> index 314f75d886d0..7b510dffd3b9 100644 >> --- a/arch/x86/include/asm/e820/types.h >> +++ b/arch/x86/include/asm/e820/types.h >> @@ -56,6 +56,7 @@ struct e820_entry { >> u64 addr; >> u64 size; >> enum e820_type type; >> + u8 crypto_capable; > > Why isn't this a bool? It was a bool initially, but Andy Shevchenko told me that it couldn't be that way because boolean may not be part of firmware ABIs. >> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c >> index bc0657f0deed..001d64686938 100644 >> --- a/arch/x86/kernel/e820.c >> +++ b/arch/x86/kernel/e820.c >> @@ -163,7 +163,7 @@ int e820__get_entry_type(u64 start, u64 end) >> /* >> * Add a memory region to the kernel E820 map. >> */ >> -static void __init __e820__range_add(struct e820_table *table, u64 start, >> u64 size, enum e820_type type) >> +static void __init __e820__range_add(struct e820_table *table, u64 start, >> u64 size, enum e820_type type, u8 crypto_capable) > > Horrid api change, but it's internal to this file so oh well :( > > Hint, don't add flags to functions like this, it forces you to have to > always remember what those flags are when you read the code. Right now > you stuck "0" and "1" in the function call, which is not instructional > at all. > > Heck, why not make it an enum to have it be self-describing? Like the > type is here. that would make it much better and easier to understand > and maintain over time. > Yes, an enum will absolutely improve things. I'll do that. >> @@ -327,6 +330,7 @@ int __init e820__update_table(struct e820_table >> *table) >> unsigned long long last_addr; >> u32 new_nr_entries, overlap_entries; >> u32 i, chg_idx, chg_nr; >> + u8 current_crypto, last_crypto; >> >> /* If there's only one memory region, don't bother: */ >> if (table->nr_entries < 2) >> @@ -367,6 +371,7 @@ int __init e820__update_table(struct e820_table >> *table) >> new_nr_entries = 0; /* Index for creating new map entries */ >> last_type = 0; /* Start with undefined memory type */ >> last_addr = 0; /* Start with 0 as last starting address */ >> + last_crypto = 0; >> >> /* Loop through change-points, determining effect on the new map: */ >> for (chg_idx = 0; chg_idx < chg_nr; chg_idx++) { >> @@ -388,13 +393,17 @@ int __init e820__update_table(struct e820_table >> *table) >> * 1=usable, 2,3,4,4+=unusable) >> */ >> current_type = 0; >> + current_crypto = 1; >> for (i = 0; i < overlap_entries; i++) { >> + current_crypto = current_crypto && overlap_list[i]->crypto_capable; > > Is it a u8 or not? You treat it as a boolean a lot :( > >> if (overlap_list[i]->type > current_type) >> current_type = overlap_list[i]->type; >> } >> >> /* Continue building up new map based on this information: */ >> - if (current_type != last_type || e820_nomerge(current_type)) { >> + if (current_type != last_type || >> + current_crypto != last_crypto || >> + e820_nomerge(current_type)) { > > Why check it before calling e820_nomerge()? Is that required? > I don't see how the order of the checks matter, am I missing something? >> if (last_type != 0) { >> new_entries[new_nr_entries].size = change_point[chg_idx]->addr - >> last_addr; >> /* Move forward only if the new size was non-zero: */ >> @@ -406,9 +415,12 @@ int __init e820__update_table(struct e820_table >> *table) >> if (current_type != 0) { >> new_entries[new_nr_entries].addr = change_point[chg_idx]->addr; >> new_entries[new_nr_entries].type = current_type; >> + new_entries[new_nr_entries].crypto_capable = current_crypto; >> + >> last_addr = change_point[chg_idx]->addr; >> } >> last_type = current_type; >> + last_crypto = current_crypto; >> } >> } >> >> @@ -459,14 +471,20 @@ static int __init append_e820_table(struct >> boot_e820_entry *entries, u32 nr_entr >> return __append_e820_table(entries, nr_entries); >> } >> >> +/* >> + * Update a memory range. >> + * >> + * If old_type and new_type are the same then ignore the types and >> + * just change crypto_capable. >> + */ >> static u64 __init >> -__e820__range_update(struct e820_table *table, u64 start, u64 size, enum >> e820_type old_type, enum e820_type new_type) >> +__e820__range_update(struct e820_table *table, u64 start, u64 size, enum >> e820_type old_type, enum e820_type new_type, u8 crypto_capable) > > Same api comment here. > >> { >> u64 end; >> unsigned int i; >> u64 real_updated_size = 0; >> >> - BUG_ON(old_type == new_type); > > No more bug? > No, >> + bool update_crypto = new_type == old_type; > > if statement? This looks really odd and is easy to overlook. > because now I'm using those cases where new_type is equal to old_type to change crypto_capable, because I don't care about the type if I want to change crypto_capable. This is what I'm checking here, to ignore the types inside the for and just leave them as they are. I'm not really happy with this change, maybe a new function will be better, although it will be pretty similar to this one and its implementation is quite fragile, for checking the cases and adding/removing the regions, so I decided to just have only one ugly fragile function, instead of two fragile functions. I can do the new function if you prefer. >> >> if (size > (ULLONG_MAX - start)) >> size = ULLONG_MAX - start; >> @@ -476,6 +494,8 @@ __e820__range_update(struct e820_table *table, u64 >> start, u64 size, enum e820_ty >> e820_print_type(old_type); >> pr_cont(" ==> "); >> e820_print_type(new_type); >> + if (crypto_capable) >> + pr_cont("; crypto-capable"); >> pr_cont("\n"); >> >> for (i = 0; i < table->nr_entries; i++) { >> @@ -483,22 +503,27 @@ __e820__range_update(struct e820_table *table, u64 >> start, u64 size, enum e820_ty >> u64 final_start, final_end; >> u64 entry_end; >> >> - if (entry->type != old_type) >> + if (entry->type != old_type && !update_crypto) >> continue; >> >> + if (update_crypto) >> + new_type = entry->type; >> + >> entry_end = entry->addr + entry->size; >> >> /* Completely covered by new range? */ >> if (entry->addr >= start && entry_end <= end) { >> entry->type = new_type; >> + entry->crypto_capable = crypto_capable; >> real_updated_size += entry->size; >> continue; >> } >> >> /* New range is completely covered? */ >> if (entry->addr < start && entry_end > end) { >> - __e820__range_add(table, start, size, new_type); >> - __e820__range_add(table, end, entry_end - end, entry->type); >> + __e820__range_add(table, start, size, new_type, crypto_capable); >> + __e820__range_add(table, end, entry_end - end, >> + entry->type, entry->crypto_capable); >> entry->size = start - entry->addr; >> real_updated_size += size; >> continue; >> @@ -510,7 +535,8 @@ __e820__range_update(struct e820_table *table, u64 >> start, u64 size, enum e820_ty >> if (final_start >= final_end) >> continue; >> >> - __e820__range_add(table, final_start, final_end - final_start, >> new_type); >> + __e820__range_add(table, final_start, final_end - final_start, >> + new_type, crypto_capable); >> >> real_updated_size += final_end - final_start; >> >> @@ -527,14 +553,19 @@ __e820__range_update(struct e820_table *table, u64 >> start, u64 size, enum e820_ty >> return real_updated_size; >> } >> >> +u64 __init e820__range_mark_as_crypto_capable(u64 start, u64 size) >> +{ >> + return __e820__range_update(e820_table, start, size, 0, 0, true); >> +} >> + >> u64 __init e820__range_update(u64 start, u64 size, enum e820_type >> old_type, enum e820_type new_type) >> { >> - return __e820__range_update(e820_table, start, size, old_type, >> new_type); >> + return __e820__range_update(e820_table, start, size, old_type, new_type, >> false); > > See, what does "false" here mean? You have to now go look that up. > > thanks, > > greg k-h >