Skip to content

Commit 40c93d7

Browse files
committed
Merge tag 'x86-urgent-2021-11-21' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: - Move the command line preparation and the early command line parsing earlier so that the command line parameters which affect early_reserve_memory(), e.g. efi=nosftreserve, are taken into account. This was broken when the invocation of early_reserve_memory() was moved recently. - Use an atomic type for the SGX page accounting, which is read and written locklessly, to plug various race conditions related to it. * tag 'x86-urgent-2021-11-21' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/sgx: Fix free page accounting x86/boot: Pull up cmdline preparation and early param parsing
2 parents af16bde + ac5d272 commit 40c93d7

File tree

2 files changed

+45
-33
lines changed

2 files changed

+45
-33
lines changed

arch/x86/kernel/cpu/sgx/main.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ static DECLARE_WAIT_QUEUE_HEAD(ksgxd_waitq);
2828
static LIST_HEAD(sgx_active_page_list);
2929
static DEFINE_SPINLOCK(sgx_reclaimer_lock);
3030

31-
/* The free page list lock protected variables prepend the lock. */
32-
static unsigned long sgx_nr_free_pages;
31+
static atomic_long_t sgx_nr_free_pages = ATOMIC_LONG_INIT(0);
3332

3433
/* Nodes with one or more EPC sections. */
3534
static nodemask_t sgx_numa_mask;
@@ -403,14 +402,15 @@ static void sgx_reclaim_pages(void)
403402

404403
spin_lock(&node->lock);
405404
list_add_tail(&epc_page->list, &node->free_page_list);
406-
sgx_nr_free_pages++;
407405
spin_unlock(&node->lock);
406+
atomic_long_inc(&sgx_nr_free_pages);
408407
}
409408
}
410409

411410
static bool sgx_should_reclaim(unsigned long watermark)
412411
{
413-
return sgx_nr_free_pages < watermark && !list_empty(&sgx_active_page_list);
412+
return atomic_long_read(&sgx_nr_free_pages) < watermark &&
413+
!list_empty(&sgx_active_page_list);
414414
}
415415

416416
static int ksgxd(void *p)
@@ -471,9 +471,9 @@ static struct sgx_epc_page *__sgx_alloc_epc_page_from_node(int nid)
471471

472472
page = list_first_entry(&node->free_page_list, struct sgx_epc_page, list);
473473
list_del_init(&page->list);
474-
sgx_nr_free_pages--;
475474

476475
spin_unlock(&node->lock);
476+
atomic_long_dec(&sgx_nr_free_pages);
477477

478478
return page;
479479
}
@@ -625,9 +625,9 @@ void sgx_free_epc_page(struct sgx_epc_page *page)
625625
spin_lock(&node->lock);
626626

627627
list_add_tail(&page->list, &node->free_page_list);
628-
sgx_nr_free_pages++;
629628

630629
spin_unlock(&node->lock);
630+
atomic_long_inc(&sgx_nr_free_pages);
631631
}
632632

633633
static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,

arch/x86/kernel/setup.c

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,28 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
742742
return 0;
743743
}
744744

745+
static char *prepare_command_line(void)
746+
{
747+
#ifdef CONFIG_CMDLINE_BOOL
748+
#ifdef CONFIG_CMDLINE_OVERRIDE
749+
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
750+
#else
751+
if (builtin_cmdline[0]) {
752+
/* append boot loader cmdline to builtin */
753+
strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
754+
strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
755+
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
756+
}
757+
#endif
758+
#endif
759+
760+
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
761+
762+
parse_early_param();
763+
764+
return command_line;
765+
}
766+
745767
/*
746768
* Determine if we were loaded by an EFI loader. If so, then we have also been
747769
* passed the efi memmap, systab, etc., so we should use these data structures
@@ -830,6 +852,23 @@ void __init setup_arch(char **cmdline_p)
830852

831853
x86_init.oem.arch_setup();
832854

855+
/*
856+
* x86_configure_nx() is called before parse_early_param() (called by
857+
* prepare_command_line()) to detect whether hardware doesn't support
858+
* NX (so that the early EHCI debug console setup can safely call
859+
* set_fixmap()). It may then be called again from within noexec_setup()
860+
* during parsing early parameters to honor the respective command line
861+
* option.
862+
*/
863+
x86_configure_nx();
864+
865+
/*
866+
* This parses early params and it needs to run before
867+
* early_reserve_memory() because latter relies on such settings
868+
* supplied as early params.
869+
*/
870+
*cmdline_p = prepare_command_line();
871+
833872
/*
834873
* Do some memory reservations *before* memory is added to memblock, so
835874
* memblock allocations won't overwrite it.
@@ -863,33 +902,6 @@ void __init setup_arch(char **cmdline_p)
863902
bss_resource.start = __pa_symbol(__bss_start);
864903
bss_resource.end = __pa_symbol(__bss_stop)-1;
865904

866-
#ifdef CONFIG_CMDLINE_BOOL
867-
#ifdef CONFIG_CMDLINE_OVERRIDE
868-
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
869-
#else
870-
if (builtin_cmdline[0]) {
871-
/* append boot loader cmdline to builtin */
872-
strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
873-
strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
874-
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
875-
}
876-
#endif
877-
#endif
878-
879-
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
880-
*cmdline_p = command_line;
881-
882-
/*
883-
* x86_configure_nx() is called before parse_early_param() to detect
884-
* whether hardware doesn't support NX (so that the early EHCI debug
885-
* console setup can safely call set_fixmap()). It may then be called
886-
* again from within noexec_setup() during parsing early parameters
887-
* to honor the respective command line option.
888-
*/
889-
x86_configure_nx();
890-
891-
parse_early_param();
892-
893905
#ifdef CONFIG_MEMORY_HOTPLUG
894906
/*
895907
* Memory used by the kernel cannot be hot-removed because Linux

0 commit comments

Comments
 (0)