From nobody Thu Oct 2 03:34:12 2025 Received: from mail-qk1-f170.google.com (mail-qk1-f170.google.com [209.85.222.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EFCBB257844 for ; Tue, 23 Sep 2025 15:32:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758641523; cv=none; b=lX/IQh4geIP29UyNLktcWFmKjsknNqhD0YGgWRQBY8Sa7r/fme4nJO5FGYV2Z2sDDwUOr2mWyoiDgHgCxvRnGCI7D+EYjDhX/c0SGb5eJto+bihQFCuEKmp++W6FCaBUG8Ovduyhrm3lL2789fV0VekWVnUsexg5OKX5LklIlc8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758641523; c=relaxed/simple; bh=gODZzPD/opn1TM9cf3UdOfrIL0SMTLmEZ7NN+GXHa6I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ONNA3dwmXy+ZZ9XWpsO6YcT5KaWjKWY2CF2jUbd5D5a+/aB7Gu2iYcaSYplOaYrLQ4+9vRxNaWs556Djalhyzj56jzkB7fqoi8KFBPvLMsVnytEUzuB073g1p25R28LUMEFYavqr1w+TEY4qHqJgxjNar6m/j9BPCJn19/nHS/E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com; spf=pass smtp.mailfrom=bytedance.com; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b=PhjyFkfE; arc=none smtp.client-ip=209.85.222.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=bytedance.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bytedance.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bytedance.com header.i=@bytedance.com header.b="PhjyFkfE" Received: by mail-qk1-f170.google.com with SMTP id af79cd13be357-85322d9c606so72591985a.1 for ; Tue, 23 Sep 2025 08:32:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1758641519; x=1759246319; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jNQg6Dmvc7QhPeOGSjQkaaU9Q6+ewyJ1+A+N+0yiv7Q=; b=PhjyFkfESyNWL+OKGPOGUyoNuCEc+jtJZ1Hc5QX2yk/WKg+Mx9fWpHzyRsS8UwNsoj +PQD2mjt/mIepxgl2qwZERaFypJYzgf57q6y7IMGt7LaxVVjDOYA4osTStalc4PRauXq LkS1e9ZSmHFdXatNhS3hswcBUqaJk/Ee/CmtTsU8WRI65W6C//bU+PIj5mGDHCCPShR8 ItxTYHfZp0rN7FBFM7XWA5kmZLDj/cKWGIIC5T2Hw3q5XyeSj7a1uhZfm854u6iG1avl 7tQlECWjMbHQgPfAUHO4W9jCzAFhXa3e2dbM4jRYu5jm/bz8qDeSGXQzZ8y+TLQ1hFQG pmIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758641519; x=1759246319; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jNQg6Dmvc7QhPeOGSjQkaaU9Q6+ewyJ1+A+N+0yiv7Q=; b=dojjkB+Nk7bGrqU7EMwlqWfffOOekOutIRQy2vlWy03I74UuZbxy+l8RH60AWzWVeG 19sRMb+ygH++94HxT/gnJUdoSH7T3ZmLGtWkEAFk26oqJ7VOi6v5K3tg3j9eZYIH4E2F p1r8KMGEMbJ0pBl8j5xpu4NgqgcbS0hkmtghwfdSlWYsz9kA0uj4UJ+N5CPAfiQNkO9Y MFzgyFUiitan8VAN2jec/EbXgso79mcOgVT3vZiM7hJQ/fYUvLQe/iYsk1dhAg819K5w dz2b1Y8h5Q8kFG4Q3szSMduy9a2ivPlg3ZOww8WeDNqpFfG6QtaU71P/qoeWcEUBKMV0 Ni+Q== X-Gm-Message-State: AOJu0YzF4mlg2eOP8aXrfIPppfciFxF/HXrPPkY9rm9USLyCVJFxdT75 1iPIwExOTH4Q9t5UV4GHrK++zFS9LWvnkFxJFGKpPnOFaw2nxjzw+REP1aRX0R7Ca1ZO/jXk/XE eUUJt3KA= X-Gm-Gg: ASbGncuA3C/YeSJwWXhL30T37T9KtfJnJ+dVItKfY2x086j2VlRwBBqyKrfSq7Ob9e0 eTkeL4Au1zLwEIPaHM0Ctc87yBbaNBp0tATGKZSnctkVqLqqfLg2XqJ1p4O5zXSmmc0vSFbeVBF Lp4WQqWpKmF6DKilj85BChL6bDHD6p5U2ClKq84oh9GfzQZ6Ti8/llk1rFX0xHLXEvlO652WW8F qTauJrrgLl1o5I+0+xFLPAL/PuuY/lJ+VsIGpSHC2Gbs361xWve7Jm2Ghxxq+ppT7tJpfkX9CmI ErmJ8TjFFRs68q/TE2cZ/NT62VcN7eGz7o6vpbusDVakY/Fy9dTAmeky6ZpPD1g6NLtLR8+FK0B 0M91NJfOonQkABtS3uuWTqyUozWcf X-Google-Smtp-Source: AGHT+IG3zk1Sk0vaD8CMZLIiKqK7VvkHbQL7KBuD4nbMD4OVDlX0qOxl76RR2+NJ7QBWuWzryzvOrw== X-Received: by 2002:a05:620a:29d2:b0:848:624c:457a with SMTP id af79cd13be357-8516ba5bdf9mr381050785a.33.1758641518908; Tue, 23 Sep 2025 08:31:58 -0700 (PDT) Received: from localhost ([93.115.195.2]) by smtp.gmail.com with ESMTPSA id af79cd13be357-836305769ecsm1021524285a.42.2025.09.23.08.31.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Sep 2025 08:31:58 -0700 (PDT) From: Fam Zheng To: linux-kernel@vger.kernel.org Cc: Lukasz Luba , linyongting@bytedance.com, songmuchun@bytedance.com, satish.kumar@bytedance.com, Borislav Petkov , Thomas Gleixner , yuanzhu@bytedance.com, Ingo Molnar , Daniel Lezcano , fam.zheng@bytedance.com, Zhang Rui , fam@euphon.net, "H. Peter Anvin" , x86@kernel.org, liangma@bytedance.com, Dave Hansen , "Rafael J. Wysocki" , guojinhui.liam@bytedance.com, linux-pm@vger.kernel.org, Thom Hughes Subject: [RFC 4/5] x86/parker: Add parker initialisation code Date: Tue, 23 Sep 2025 15:31:45 +0000 Message-Id: <20250923153146.365015-5-fam.zheng@bytedance.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250923153146.365015-1-fam.zheng@bytedance.com> References: <20250923153146.365015-1-fam.zheng@bytedance.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thom Hughes Signed-off-by: Thom Hughes Signed-off-by: Fam Zheng --- arch/x86/kernel/setup.c | 4 + arch/x86/parker/Makefile | 3 +- arch/x86/parker/Makefile-full | 3 + arch/x86/parker/setup.c | 423 ++++++++++++++++++++++++++++ arch/x86/parker/trampoline.S | 55 ++++ arch/x86/parker/trampoline.h | 10 + drivers/thermal/intel/therm_throt.c | 3 + include/linux/parker-bkup.h | 22 ++ include/linux/parker.h | 15 + 9 files changed, 537 insertions(+), 1 deletion(-) create mode 100644 arch/x86/parker/Makefile-full create mode 100644 arch/x86/parker/setup.c create mode 100644 arch/x86/parker/trampoline.S create mode 100644 arch/x86/parker/trampoline.h create mode 100644 include/linux/parker-bkup.h diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index cebee310e200..a3c7909efaf5 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -917,6 +918,7 @@ void __init setup_arch(char **cmdline_p) * called before cache_bp_init() for setting up MTRR state. */ init_hypervisor_platform(); + parker_init(); =20 tsc_early_init(); x86_init.resources.probe_roms(); @@ -1110,6 +1112,8 @@ void __init setup_arch(char **cmdline_p) =20 if (boot_cpu_has(X86_FEATURE_GBPAGES)) hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); + /* Allocate memory for PARKER kernels */ + parker_cma_reserve(); =20 /* * Reserve memory for crash kernel after SRAT is parsed so that it diff --git a/arch/x86/parker/Makefile b/arch/x86/parker/Makefile index 41c40fc64267..506ad8cbff00 100644 --- a/arch/x86/parker/Makefile +++ b/arch/x86/parker/Makefile @@ -1,2 +1,3 @@ -obj-y +=3D kernfs.o +obj-y +=3D kernfs.o setup.o trampoline.o $(obj)/kernfs.o: $(obj)/internal.h +$(obj)/setup.o: $(obj)/internal.h diff --git a/arch/x86/parker/Makefile-full b/arch/x86/parker/Makefile-full new file mode 100644 index 000000000000..506ad8cbff00 --- /dev/null +++ b/arch/x86/parker/Makefile-full @@ -0,0 +1,3 @@ +obj-y +=3D kernfs.o setup.o trampoline.o +$(obj)/kernfs.o: $(obj)/internal.h +$(obj)/setup.o: $(obj)/internal.h diff --git a/arch/x86/parker/setup.c b/arch/x86/parker/setup.c new file mode 100644 index 000000000000..2d36dac05289 --- /dev/null +++ b/arch/x86/parker/setup.c @@ -0,0 +1,423 @@ +#define pr_fmt(fmt) "parker: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "trampoline.h" + +bool is_parker =3D false; + +static phys_addr_t parker_control_structure_address; +static volatile struct parker_control_structure *parker_control_structure; + +static void (*old_shutdown)(void); +static void (*old_restart)(char*); + +/* Take in parker control page as kernel parameter + * this also indicates we are booting as a parker kernel + * currently assumes that control structure is 1 page */ +static __init int parker_parse_early_param(char *opt) +{ + if (!opt) + return -EINVAL; + char *oldopt =3D opt; + parker_control_structure_address =3D memparse(opt, &opt); + if (oldopt =3D=3D opt) + return -EINVAL; + is_parker =3D true; + return 0; +} +early_param("parker", parker_parse_early_param); + +inline bool is_parker_instance(void) +{ + return is_parker; +} + +static struct resource parker_control_structure_resource =3D { + .name =3D "Parker Control Structure", + .start =3D 0, + .end =3D 0, + .flags =3D IORESOURCE_SYSTEM_RAM, + .desc =3D IORES_DESC_RESERVED +}; + +static struct real_mode_header parker_dummy_real_mode_header; + +static void parker_reserve_control_structure(unsigned long long addr) +{ + parker_control_structure_resource.start =3D addr; + parker_control_structure_resource.end =3D addr + PAGE_SIZE - 1; + insert_resource(&iomem_resource, &parker_control_structure_resource); +} + +static void __init parker_x2apic_init(void) +{ +#ifdef CONFIG_X86_X2APIC + if (!x2apic_enabled()) + return; + x2apic_phys =3D 1; + /* + * This will trigger the switch to apic_x2apic_phys. Empty OEM IDs + * ensure that only this APIC driver picks up the call. + */ + default_acpi_madt_oem_check("", ""); +#endif +} + +/* Setup trampoline pagetable, stack and initial code pointer */ +static int __init parker_init_trampoline(void) +{ + /* Setup trampoline lock or else head_64.S:secondary_startup_64 will cras= h */ + trampoline_lock =3D (u32 *)&parker_trampoline_lock; + WRITE_ONCE(*trampoline_lock, 0); + + /* Map kernel page table so we can access kernel memory */ + for (int i =3D pgd_index(__PAGE_OFFSET); i < PTRS_PER_PGD; i++) + WRITE_ONCE(parker_trampoline_pgt[i], init_top_pgt[i].pgd); + + /* 1:1 map parker_ap_trampoline physical memory so we can jump from host*/ + u64 paddr_map =3D virt_to_phys(parker_ap_trampoline); + pgd_t *pgd =3D (pgd_t*)parker_trampoline_pgt; + p4d_t *p4d; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + pgd +=3D pgd_index(paddr_map); + pgprot_t prot =3D PAGE_KERNEL_EXEC_NOENC; + if (!pgd_present(*pgd)) { + p4d =3D (p4d_t *)memblock_alloc(PAGE_SIZE, PAGE_SIZE); + if (!p4d) + return -ENOMEM; + set_pgd(pgd, __pgd(__pa(p4d) | _KERNPG_TABLE)); + } + p4d =3D p4d_offset(pgd, paddr_map); + if (!p4d_present(*p4d)) { + pud =3D (pud_t *)memblock_alloc(PAGE_SIZE, PAGE_SIZE); + if (!pud) { + memblock_free(p4d, PAGE_SIZE); + return -ENOMEM; + } + set_p4d(p4d, __p4d(__pa(pud) | _KERNPG_TABLE)); + } + pud =3D pud_offset(p4d, paddr_map); + if (!pud_present(*pud)) { + pmd =3D (pmd_t *)memblock_alloc(PAGE_SIZE, PAGE_SIZE); + if (!pmd) { + memblock_free(p4d, PAGE_SIZE); + memblock_free(pud, PAGE_SIZE); + return -ENOMEM; + } + set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE)); + } + pmd =3D pmd_offset(pud, paddr_map); + if (!pmd_present(*pmd)) { + pte =3D (pte_t *)memblock_alloc(PAGE_SIZE, PAGE_SIZE); + if (!pte) { + memblock_free(p4d, PAGE_SIZE); + memblock_free(pud, PAGE_SIZE); + memblock_free(pmd, PAGE_SIZE); + return -ENOMEM; + } + set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE)); + } + pte =3D pte_offset_kernel(pmd, paddr_map); + + if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) + prot =3D PAGE_KERNEL_EXEC; + + set_pte(pte, pfn_pte(paddr_map >> PAGE_SHIFT, prot)); + + /* Write initial code (within parker) for secondary CPU initialisation */ + WRITE_ONCE(parker_trampoline_start, secondary_startup_64); + + /* Store virtual address of top of stack at bottom of stack */ + WRITE_ONCE(parker_trampoline_stack, &parker_trampoline_stack_end); + + /* Synchronise all updates */ + smp_mb(); + + return 0; +} + +static void parker_set_spoof_bsp(bool enabled) +{ + u64 msr; + rdmsrl(MSR_IA32_APICBASE, msr); + msr =3D enabled ? (msr | MSR_IA32_APICBASE_BSP) : + (msr & ~MSR_IA32_APICBASE_BSP); + wrmsrl(MSR_IA32_APICBASE, msr); +} + +static void __init parker_parse_smp_cfg(void) +{ + int ret; + pr_info("smpconfig\n"); + /* Disable legacy PIC */ + pic_mode =3D 0; + + /* Initialize x2apic as ACPI disabled */ + parker_x2apic_init(); + + /* Spoof parker BSP as BSP or kernel thinks it's crash kernel */ + parker_set_spoof_bsp(true); + + /* Assume that lapic address is unchangd */ + register_lapic_address(APIC_DEFAULT_PHYS_BASE); + ret =3D parker_init_trampoline(); + if (ret < 0) { + pr_info("Failed to initialise trampoline.\n"); + smp_found_config =3D 0; + return; + } + + /* Register all APIC ID's for parker APs */ + for (int i =3D 0; i < parker_control_structure->num_cpus; ++i) { + topology_register_apic(READ_ONCE(parker_control_structure->apic_ids[i]), + CPU_ACPIID_INVALID, + true); + } + + smp_found_config =3D 1; +} + +static bool __init parker_x2apic_available(void) +{ + return x2apic_enabled(); +} + +static void parker_init_host_control(void) +{ + parker_reserve_control_structure((unsigned long long)parker_control_struc= ture); + phys_addr_t address =3D parker_control_structure_address; + parker_control_structure =3D early_memremap(address, PAGE_SIZE); + /* Announce trampoline physical address to host kernel */ + phys_addr_t trampoline_phys_addr =3D virt_to_phys(parker_ap_trampoline); + WRITE_ONCE(parker_control_structure->start_address, trampoline_phys_addr); + smp_mb(); +} + +/* Some APIC callback overrides */ +static int parker_wakeup_secondary_cpu_64(u32 apicid, unsigned long _dummy= _start_eip) +{ + WRITE_ONCE(parker_trampoline_apicid, apicid); + smp_mb(); + + /* Wait for APIC id to be reset before continuing, + * ensuring no CPU misses trampoline kick. */ + while (READ_ONCE(parker_trampoline_apicid) !=3D 0) + cpu_relax(); + + return 0; +} + +static void parker_send_IPI_allbutself(int vector) +{ + if (num_online_cpus() < 2) + return; + + __apic_send_IPI_mask_allbutself(cpu_online_mask, vector); +} + +static void parker_send_IPI_all(int vector) +{ + __apic_send_IPI_mask(cpu_online_mask, vector); +} + + +/* Setup real mode header so SMP doesn't dereference null pointer */ +static void __init parker_realmode_init(void) +{ + real_mode_header =3D &parker_dummy_real_mode_header; +} + +static void parker_emergency_restart(void) +{ + pr_notice("Restart not supported, spinning\n"); + for (;;) { + continue; + } +} + +static void parker_offline(void) +{ + /* Remove BSP flag from APIC MSR + * or we crash on second use of BSP in parker kernel */ + parker_set_spoof_bsp(false); + parker_control_structure =3D memremap(parker_control_structure_address, P= AGE_SIZE, MEMREMAP_WB); + if (!parker_control_structure) { + pr_err("Unable to map control structure, unable to tell host we are offl= ine.\n"); + return; + } + WRITE_ONCE(parker_control_structure->online, false); + memunmap((void*)parker_control_structure); +} + +static void parker_shutdown(void) +{ + pr_info("shutting down.\n"); + parker_offline(); + old_shutdown(); +} + +/* No restart occurs, will just effectively shutdown */ +static void parker_restart(char *msg) +{ + pr_info("rebooting\n"); + parker_offline(); + old_restart(msg); +} + +static struct pci_bus __init *parker_pci_init_root_bus(int busno) +{ + struct pci_bus *bus; + struct pci_sysdata *sd; + LIST_HEAD(resources); + + /* If bus exists, continue */ + /* TODO: Is domain always 0? (probably not) */ + bus =3D pci_find_bus(0, busno); + if (bus) + return bus; + + sd =3D kzalloc(sizeof(*sd), GFP_KERNEL); + if (!sd) { + printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busno); + return NULL; + } + + sd->node =3D x86_pci_root_bus_node(busno); + x86_pci_root_bus_resources(busno, &resources); + bus =3D pci_create_root_bus(NULL, busno, &pci_root_ops, sd, &resources); + if (!bus) { + pci_free_resource_list(&resources); + kfree(sd); + return NULL; + } + + return bus; +} + +static int __init parker_pci_init(void) +{ + /* Set to 0 as we are manually setting up and probing busses ourselves */ + pcibios_last_bus =3D 0; + + /* Scan only passed through PCI devices, passing through PCIe port unsupp= ored */ + for (int i =3D 0; i < parker_control_structure->num_pci_devs; ++i) { + u32 dev_id =3D parker_control_structure->pci_dev_ids[i]; + u32 busno =3D PCI_BUS_NUM(dev_id); + u32 devfn =3D dev_id & 0xff; + struct pci_bus *bus =3D parker_pci_init_root_bus(busno); + if (!bus) { + pr_err("Failed to get bus: %d\n", busno); + continue; + } + struct pci_dev *dev =3D pci_scan_single_device(bus, devfn); + if (!dev) { + pr_err("Failed to get dev: %d\n", devfn); + continue; + } + pci_bus_add_device(dev); + } + + /* We can announce online now to host kernel */ + WRITE_ONCE(parker_control_structure->online, 1); + smp_mb(); + + /* PCI initialisation is the last time the early mapped structure is used= */ + early_memunmap((void*)parker_control_structure, PAGE_SIZE); + + /* TODO: Disable rescan! */ + return 0; +} + +static int parker_pci_enable_irq(struct pci_dev *dev) +{ + /* Let's lie to everyone ;) */ + /* TODO: Find drivers that can use MSI only that fail to load without INT= -A + * then we can return -EINVAL; */ + return 0; +} + +static void parker_pci_disable_irq(struct pci_dev *dev) +{ + return; +} + +void __init parker_init() +{ + if (!is_parker_instance()) + return; + + pr_info("parker: Initialising parker..\n"); + /* TODO: Re-enable! */ + legacy_pic =3D &null_legacy_pic; + /* Reserve dummy header so existing smpboot.c:do_boot_cpu code + * doesn't dereference NULL pointer */ + x86_platform.realmode_reserve =3D x86_init_noop; + x86_platform.realmode_init =3D parker_realmode_init; + + /* Disable legacy code */ + x86_platform.legacy.rtc =3D 0; + x86_platform.legacy.warm_reset =3D 0; + x86_platform.legacy.i8042 =3D X86_LEGACY_I8042_PLATFORM_ABSENT; + + /* Disable emergency restart */ + machine_ops.emergency_restart =3D parker_emergency_restart; + + /* Save old machine ops */ + old_shutdown =3D machine_ops.shutdown; + old_restart =3D machine_ops.restart; + + /* Ensure shutdown / restart makes host kernel aware parker is offline */ + machine_ops.shutdown =3D parker_shutdown; + machine_ops.restart =3D parker_restart; + + /* Use control structure for SMP CPU APIC ID enumeration */ + x86_init.mpparse.find_mptable =3D x86_init_noop; + x86_init.mpparse.early_parse_smp_cfg =3D x86_init_noop; + x86_init.mpparse.parse_smp_cfg =3D parker_parse_smp_cfg; + + /* TODO: Investigate x2apic alternative, but requires baremetal */ + x86_init.hyper.x2apic_available =3D parker_x2apic_available; + + /* Disable PCI IRQ handling as we don't support INT-A mode */ + x86_init.pci.init =3D parker_pci_init; + x86_init.pci.init_irq =3D x86_init_noop; + x86_init.pci.fixup_irqs =3D x86_init_noop; + pcibios_enable_irq =3D parker_pci_enable_irq; + pcibios_disable_irq =3D parker_pci_disable_irq; + + /* No ACPI, so no hotplugging (be nice) */ + disable_acpi(); + + /* Setup host kernel control page */ + parker_init_host_control(); + + /* Let smpboot.c:do_boot_cpu use our wakeup routine */ + apic_update_callback(wakeup_secondary_cpu_64, parker_wakeup_secondary_cpu= _64); + + /* Prevent shorthand IPIs */ + apic_update_callback(send_IPI_all, parker_send_IPI_all); + apic_update_callback(send_IPI_allbutself, parker_send_IPI_allbutself); +} diff --git a/arch/x86/parker/trampoline.S b/arch/x86/parker/trampoline.S new file mode 100644 index 000000000000..2107201eb1de --- /dev/null +++ b/arch/x86/parker/trampoline.S @@ -0,0 +1,55 @@ +#include + +#include +#include +#include + +/* NOTE: No SME, host kernel and secondary kernel must match N-level pgt */ +/* NOTE: Changing this file will require a full recompilation as makefile = isn't setup properly */ +.text +.code64 +SYM_CODE_START(parker_ap_trampoline) + UNWIND_HINT_END_OF_STACK + ANNOTATE_NOENDBR +/* Spin for now */ +.Lno_trampoline_start: + mov parker_trampoline_start(%rip), %rcx + test %rcx, %rcx + jz .Lno_trampoline_start + leaq parker_trampoline_pgt(%rip), %rax +.Lno_stack: + /* Store vaddr of stack at top of stack */ + movq parker_trampoline_stack(%rip), %rsp + test %rsp, %rsp + jz .Lno_stack + mov %rax, %cr3 +.Lwrong_apicid: + cmp parker_trampoline_apicid, %esi + jne .Lwrong_apicid +.Ltrampoline_locked: + lock btsl $0, parker_trampoline_lock + jnc .Ltrampoline_unlocked + pause + jmp .Ltrampoline_locked +/* Assume APIC ID 0 is never secondary processor */ +.Ltrampoline_unlocked: + movl $0, parker_trampoline_apicid + ANNOTATE_RETPOLINE_SAFE + call *%rcx + ANNOTATE_UNRET_SAFE + ret + int3 +SYM_CODE_END(parker_ap_trampoline) + +.data +.balign PAGE_SIZE +SYM_DATA(parker_trampoline_pgt, .skip 4096) +SYM_DATA(parker_trampoline_start, .quad 0) +SYM_DATA(parker_trampoline_apicid, .long 0) +SYM_DATA(parker_trampoline_lock, .long 0) +.balign 4096 +/* TODO: Just allocate a stack why waste 4KB */ +SYM_DATA_START(parker_trampoline_stack) + .skip 4096 +SYM_DATA_END_LABEL(parker_trampoline_stack, SYM_L_GLOBAL, parker_trampolin= e_stack_end) +SYM_DATA(parker_trampoline_end, .quad 0) diff --git a/arch/x86/parker/trampoline.h b/arch/x86/parker/trampoline.h new file mode 100644 index 000000000000..b93ca612db99 --- /dev/null +++ b/arch/x86/parker/trampoline.h @@ -0,0 +1,10 @@ +#ifndef _TRAMPOLINE_H +#define _TRAMPOLINE_H +void parker_ap_trampoline(void); +extern u64 parker_trampoline_pgt[]; +extern void *parker_trampoline_start; +extern u32 parker_trampoline_lock; +extern void *parker_trampoline_stack; +extern u32 parker_trampoline_apicid; +extern u64 parker_trampoline_stack_end; +#endif diff --git a/drivers/thermal/intel/therm_throt.c b/drivers/thermal/intel/th= erm_throt.c index e69868e868eb..dabc7e35ff72 100644 --- a/drivers/thermal/intel/therm_throt.c +++ b/drivers/thermal/intel/therm_throt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -690,6 +691,8 @@ void intel_thermal_interrupt(void) /* Thermal monitoring depends on APIC, ACPI and clock modulation */ static int intel_thermal_supported(struct cpuinfo_x86 *c) { + if (is_parker_instance()) + return 0; if (!boot_cpu_has(X86_FEATURE_APIC)) return 0; if (!cpu_has(c, X86_FEATURE_ACPI) || !cpu_has(c, X86_FEATURE_ACC)) diff --git a/include/linux/parker-bkup.h b/include/linux/parker-bkup.h new file mode 100644 index 000000000000..b00833b5a24b --- /dev/null +++ b/include/linux/parker-bkup.h @@ -0,0 +1,22 @@ +#ifndef _LINUX_PARKER_H +#define _LINUX_PARKER_H +#ifdef CONFIG_PARKER +extern void __init parker_cma_reserve(void); +extern void __init parker_init(void); +extern bool is_parker_instance(void); +#else +static inline __init void parker_cma_reserve(void) +{ +} + +static inline __init void parker_init(void) +{ +} + +static inline bool is_parker_instance(void) +{ + return false; +} +#endif /* CONFIG_PARKER */ +#endif /* _LINUX_PARKER_H */ + diff --git a/include/linux/parker.h b/include/linux/parker.h index 4984aefcee0f..b00833b5a24b 100644 --- a/include/linux/parker.h +++ b/include/linux/parker.h @@ -1,7 +1,22 @@ #ifndef _LINUX_PARKER_H #define _LINUX_PARKER_H #ifdef CONFIG_PARKER +extern void __init parker_cma_reserve(void); +extern void __init parker_init(void); +extern bool is_parker_instance(void); +#else +static inline __init void parker_cma_reserve(void) +{ +} =20 +static inline __init void parker_init(void) +{ +} + +static inline bool is_parker_instance(void) +{ + return false; +} #endif /* CONFIG_PARKER */ #endif /* _LINUX_PARKER_H */ =20 --=20 2.39.5