xen: branch for v6.13-rc1

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRTLbB6QfY48x44uB6AXGG7T9hjvgUCZzd0YQAKCRCAXGG7T9hj
 vm1JAQDBZKpEkPFrxy969YFNCSUiUj42+rDRI3OJt8y0CGTS2AEA53+B+/DYDm8i
 syw5eaSJv4uohary659ywZUdSljPig4=
 =MHOT
 -----END PGP SIGNATURE-----

Merge tag 'for-linus-6.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen updates from Juergen Gross:

 - a series for booting as a PVH guest, doing some cleanups after the
   previous work to make PVH boot code position independent

 - a fix of the xenbus driver avoiding a leak in an error case

* tag 'for-linus-6.13-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
  xen: Fix the issue of resource not being properly released in xenbus_dev_probe()
  x86/pvh: Avoid absolute symbol references in .head.text
  x86/xen: Avoid relocatable quantities in Xen ELF notes
  x86/pvh: Omit needless clearing of phys_base
  x86/pvh: Use correct size value in GDT descriptor
  x86/pvh: Call C code via the kernel virtual mapping
This commit is contained in:
Linus Torvalds 2024-11-18 18:26:57 -08:00
commit 158f238aa6
5 changed files with 59 additions and 25 deletions

View File

@ -531,3 +531,22 @@ INIT_PER_CPU(irq_stack_backing_store);
#endif
#endif /* CONFIG_X86_64 */
/*
* The symbols below are referenced using relative relocations in the
* respective ELF notes. This produces build time constants that the
* linker will never mark as relocatable. (Using just ABSOLUTE() is not
* sufficient for that).
*/
#ifdef CONFIG_XEN
#ifdef CONFIG_XEN_PV
xen_elfnote_entry_value =
ABSOLUTE(xen_elfnote_entry) + ABSOLUTE(startup_xen);
#endif
xen_elfnote_hypercall_page_value =
ABSOLUTE(xen_elfnote_hypercall_page) + ABSOLUTE(hypercall_page);
#endif
#ifdef CONFIG_PVH
xen_elfnote_phys32_entry_value =
ABSOLUTE(xen_elfnote_phys32_entry) + ABSOLUTE(pvh_start_xen - LOAD_OFFSET);
#endif

View File

@ -6,7 +6,9 @@
.code32
.text
#ifdef CONFIG_X86_32
#define _pa(x) ((x) - __START_KERNEL_map)
#endif
#define rva(x) ((x) - pvh_start_xen)
#include <linux/elfnote.h>
@ -52,7 +54,7 @@
#define PVH_CS_SEL (PVH_GDT_ENTRY_CS * 8)
#define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8)
SYM_CODE_START_LOCAL(pvh_start_xen)
SYM_CODE_START(pvh_start_xen)
UNWIND_HINT_END_OF_STACK
cld
@ -72,8 +74,7 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
movl $0, %esp
leal rva(gdt)(%ebp), %eax
leal rva(gdt_start)(%ebp), %ecx
movl %ecx, 2(%eax)
addl %eax, 2(%eax)
lgdt (%eax)
mov $PVH_DS_SEL,%eax
@ -103,10 +104,23 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
btsl $_EFER_LME, %eax
wrmsr
/*
* Reuse the non-relocatable symbol emitted for the ELF note to
* subtract the build time physical address of pvh_start_xen() from
* its actual runtime address, without relying on absolute 32-bit ELF
* relocations, as these are not supported by the linker when running
* in -pie mode, and should be avoided in .head.text in general.
*/
mov %ebp, %ebx
subl $_pa(pvh_start_xen), %ebx /* offset */
subl rva(xen_elfnote_phys32_entry)(%ebp), %ebx
jz .Lpagetable_done
/*
* Store the resulting load offset in phys_base. __pa() needs
* phys_base set to calculate the hypercall page in xen_pvh_init().
*/
movl %ebx, rva(phys_base)(%ebp)
/* Fixup page-tables for relocation. */
leal rva(pvh_init_top_pgt)(%ebp), %edi
movl $PTRS_PER_PGD, %ecx
@ -165,20 +179,12 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
xor %edx, %edx
wrmsr
/*
* Calculate load offset and store in phys_base. __pa() needs
* phys_base set to calculate the hypercall page in xen_pvh_init().
*/
movq %rbp, %rbx
subq $_pa(pvh_start_xen), %rbx
movq %rbx, phys_base(%rip)
call xen_prepare_pvh
/*
* Clear phys_base. __startup_64 will *add* to its value,
* so reset to 0.
*/
xor %rbx, %rbx
movq %rbx, phys_base(%rip)
/* Call xen_prepare_pvh() via the kernel virtual mapping */
leaq xen_prepare_pvh(%rip), %rax
subq phys_base(%rip), %rax
addq $__START_KERNEL_map, %rax
ANNOTATE_RETPOLINE_SAFE
call *%rax
/* startup_64 expects boot_params in %rsi. */
lea pvh_bootparams(%rip), %rsi
@ -217,8 +223,8 @@ SYM_CODE_END(pvh_start_xen)
.section ".init.data","aw"
.balign 8
SYM_DATA_START_LOCAL(gdt)
.word gdt_end - gdt_start
.long _pa(gdt_start) /* x86-64 will overwrite if relocated. */
.word gdt_end - gdt_start - 1
.long gdt_start - gdt
.word 0
SYM_DATA_END(gdt)
SYM_DATA_START_LOCAL(gdt_start)
@ -300,5 +306,5 @@ SYM_DATA_END(pvh_level2_kernel_pgt)
.long KERNEL_IMAGE_SIZE - 1)
#endif
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY,
_ASM_PTR (pvh_start_xen - __START_KERNEL_map))
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .global xen_elfnote_phys32_entry;
xen_elfnote_phys32_entry: _ASM_PTR xen_elfnote_phys32_entry_value - .)

View File

@ -56,6 +56,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
[S_ABS] =
"^(xen_irq_disable_direct_reloc$|"
"xen_save_fl_direct_reloc$|"
"xen_elfnote_.+_offset$|"
"VDSO|"
"__kcfi_typeid_|"
"__crc_)",

View File

@ -94,7 +94,8 @@ SYM_CODE_END(xen_cpu_bringup_again)
ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, _ASM_PTR __START_KERNEL_map)
/* Map the p2m table to a 512GB-aligned user address. */
ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M, .quad (PUD_SIZE * PTRS_PER_PUD))
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, _ASM_PTR startup_xen)
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .globl xen_elfnote_entry;
xen_elfnote_entry: _ASM_PTR xen_elfnote_entry_value - .)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .ascii "!writable_page_tables")
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes")
ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
@ -115,7 +116,8 @@ SYM_CODE_END(xen_cpu_bringup_again)
#else
# define FEATURES_DOM0 0
#endif
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page)
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .globl xen_elfnote_hypercall_page;
xen_elfnote_hypercall_page: _ASM_PTR xen_elfnote_hypercall_page_value - .)
ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,
.long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0)
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic")

View File

@ -313,7 +313,7 @@ int xenbus_dev_probe(struct device *_dev)
if (err) {
dev_warn(&dev->dev, "watch_otherend on %s failed.\n",
dev->nodename);
return err;
goto fail_remove;
}
dev->spurious_threshold = 1;
@ -322,6 +322,12 @@ int xenbus_dev_probe(struct device *_dev)
dev->nodename);
return 0;
fail_remove:
if (drv->remove) {
down(&dev->reclaim_sem);
drv->remove(dev);
up(&dev->reclaim_sem);
}
fail_put:
module_put(drv->driver.owner);
fail: