Instead of clearing the bss area in assembly code, use the clear_bss()
function.
This requires to pass the start_info address as parameter to
xen_start_kernel() in order to avoid the xen_start_info being zeroed
again.
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
arch/x86/include/asm/setup.h | 3 +++
arch/x86/kernel/head64.c | 2 +-
arch/x86/xen/enlighten_pv.c | 8 ++++++--
arch/x86/xen/xen-head.S | 10 +---------
4 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index f8b9ee97a891..f37cbff7354c 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -120,6 +120,9 @@ void *extend_brk(size_t size, size_t align);
static char __brk_##name[size]
extern void probe_roms(void);
+
+void clear_bss(void);
+
#ifdef __i386__
asmlinkage void __init i386_start_kernel(void);
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index bd4a34100ed0..e7e233209a8c 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -426,7 +426,7 @@ void __init do_early_exception(struct pt_regs *regs, int trapnr)
/* Don't add a printk in there. printk relies on the PDA which is not initialized
yet. */
-static void __init clear_bss(void)
+void __init clear_bss(void)
{
memset(__bss_start, 0,
(unsigned long) __bss_stop - (unsigned long) __bss_start);
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index e3297b15701c..70fb2ea85e90 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1183,15 +1183,19 @@ static void __init xen_domu_set_legacy_features(void)
extern void early_xen_iret_patch(void);
/* First C function to be called on Xen boot */
-asmlinkage __visible void __init xen_start_kernel(void)
+asmlinkage __visible void __init xen_start_kernel(struct start_info *si)
{
struct physdev_set_iopl set_iopl;
unsigned long initrd_start = 0;
int rc;
- if (!xen_start_info)
+ if (!si)
return;
+ clear_bss();
+
+ xen_start_info = si;
+
__text_gen_insn(&early_xen_iret_patch,
JMP32_INSN_OPCODE, &early_xen_iret_patch, &xen_iret,
JMP32_INSN_SIZE);
diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index 3a2cd93bf059..13af6fe453e3 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -48,15 +48,6 @@ SYM_CODE_START(startup_xen)
ANNOTATE_NOENDBR
cld
- /* Clear .bss */
- xor %eax,%eax
- mov $__bss_start, %rdi
- mov $__bss_stop, %rcx
- sub %rdi, %rcx
- shr $3, %rcx
- rep stosq
-
- mov %rsi, xen_start_info
mov initial_stack(%rip), %rsp
/* Set up %gs.
@@ -71,6 +62,7 @@ SYM_CODE_START(startup_xen)
cdq
wrmsr
+ mov %rsi, %rdi
call xen_start_kernel
SYM_CODE_END(startup_xen)
__FINIT
--
2.35.3
On 23.06.2022 11:46, Juergen Gross wrote:
> --- a/arch/x86/xen/enlighten_pv.c
> +++ b/arch/x86/xen/enlighten_pv.c
> @@ -1183,15 +1183,19 @@ static void __init xen_domu_set_legacy_features(void)
> extern void early_xen_iret_patch(void);
>
> /* First C function to be called on Xen boot */
> -asmlinkage __visible void __init xen_start_kernel(void)
> +asmlinkage __visible void __init xen_start_kernel(struct start_info *si)
> {
> struct physdev_set_iopl set_iopl;
> unsigned long initrd_start = 0;
> int rc;
>
> - if (!xen_start_info)
> + if (!si)
> return;
>
> + clear_bss();
As per subsequent observation, this shouldn't really be needed: The
hypervisor (or tool stack for DomU-s) already does so. While I guess
we want to keep it to be on the safe side, maybe worth a comment?
Jan
On 23.06.22 11:51, Jan Beulich wrote:
> On 23.06.2022 11:46, Juergen Gross wrote:
>> --- a/arch/x86/xen/enlighten_pv.c
>> +++ b/arch/x86/xen/enlighten_pv.c
>> @@ -1183,15 +1183,19 @@ static void __init xen_domu_set_legacy_features(void)
>> extern void early_xen_iret_patch(void);
>>
>> /* First C function to be called on Xen boot */
>> -asmlinkage __visible void __init xen_start_kernel(void)
>> +asmlinkage __visible void __init xen_start_kernel(struct start_info *si)
>> {
>> struct physdev_set_iopl set_iopl;
>> unsigned long initrd_start = 0;
>> int rc;
>>
>> - if (!xen_start_info)
>> + if (!si)
>> return;
>>
>> + clear_bss();
>
> As per subsequent observation, this shouldn't really be needed: The
> hypervisor (or tool stack for DomU-s) already does so. While I guess
> we want to keep it to be on the safe side, maybe worth a comment?
Are you sure all possible boot loaders are clearing alloc-only sections?
I'd rather not count on e.g. grub doing this in all cases.
Juergen
© 2016 - 2026 Red Hat, Inc.