Commit 158f238a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents ba1f9c8f afc545da
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -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
+28 −22
Original line number Diff line number Diff line
@@ -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 - .)
+1 −0
Original line number Diff line number Diff line
@@ -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_)",
+4 −2
Original line number Diff line number Diff line
@@ -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")
+7 −1
Original line number Diff line number Diff line
@@ -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: