Merge branch 'x86/urgent' into x86/asm to pick up dependent fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
95a8e746f8
|
@ -0,0 +1,27 @@
|
|||
Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature
|
||||
which will be found on future Intel CPUs.
|
||||
|
||||
Memory Protection Keys provides a mechanism for enforcing page-based
|
||||
protections, but without requiring modification of the page tables
|
||||
when an application changes protection domains. It works by
|
||||
dedicating 4 previously ignored bits in each page table entry to a
|
||||
"protection key", giving 16 possible keys.
|
||||
|
||||
There is also a new user-accessible register (PKRU) with two separate
|
||||
bits (Access Disable and Write Disable) for each key. Being a CPU
|
||||
register, PKRU is inherently thread-local, potentially giving each
|
||||
thread a different set of protections from every other thread.
|
||||
|
||||
There are two new instructions (RDPKRU/WRPKRU) for reading and writing
|
||||
to the new register. The feature is only available in 64-bit mode,
|
||||
even though there is theoretically space in the PAE PTEs. These
|
||||
permissions are enforced on data access only and have no effect on
|
||||
instruction fetches.
|
||||
|
||||
=========================== Config Option ===========================
|
||||
|
||||
This config option adds approximately 1.5kb of text. and 50 bytes of
|
||||
data to the executable. A workload which does large O_DIRECT reads
|
||||
of holes in XFS files was run to exercise get_user_pages_fast(). No
|
||||
performance delta was observed with the config option
|
||||
enabled or disabled.
|
|
@ -0,0 +1,208 @@
|
|||
x86 Topology
|
||||
============
|
||||
|
||||
This documents and clarifies the main aspects of x86 topology modelling and
|
||||
representation in the kernel. Update/change when doing changes to the
|
||||
respective code.
|
||||
|
||||
The architecture-agnostic topology definitions are in
|
||||
Documentation/cputopology.txt. This file holds x86-specific
|
||||
differences/specialities which must not necessarily apply to the generic
|
||||
definitions. Thus, the way to read up on Linux topology on x86 is to start
|
||||
with the generic one and look at this one in parallel for the x86 specifics.
|
||||
|
||||
Needless to say, code should use the generic functions - this file is *only*
|
||||
here to *document* the inner workings of x86 topology.
|
||||
|
||||
Started by Thomas Gleixner <tglx@linutronix.de> and Borislav Petkov <bp@alien8.de>.
|
||||
|
||||
The main aim of the topology facilities is to present adequate interfaces to
|
||||
code which needs to know/query/use the structure of the running system wrt
|
||||
threads, cores, packages, etc.
|
||||
|
||||
The kernel does not care about the concept of physical sockets because a
|
||||
socket has no relevance to software. It's an electromechanical component. In
|
||||
the past a socket always contained a single package (see below), but with the
|
||||
advent of Multi Chip Modules (MCM) a socket can hold more than one package. So
|
||||
there might be still references to sockets in the code, but they are of
|
||||
historical nature and should be cleaned up.
|
||||
|
||||
The topology of a system is described in the units of:
|
||||
|
||||
- packages
|
||||
- cores
|
||||
- threads
|
||||
|
||||
* Package:
|
||||
|
||||
Packages contain a number of cores plus shared resources, e.g. DRAM
|
||||
controller, shared caches etc.
|
||||
|
||||
AMD nomenclature for package is 'Node'.
|
||||
|
||||
Package-related topology information in the kernel:
|
||||
|
||||
- cpuinfo_x86.x86_max_cores:
|
||||
|
||||
The number of cores in a package. This information is retrieved via CPUID.
|
||||
|
||||
- cpuinfo_x86.phys_proc_id:
|
||||
|
||||
The physical ID of the package. This information is retrieved via CPUID
|
||||
and deduced from the APIC IDs of the cores in the package.
|
||||
|
||||
- cpuinfo_x86.logical_id:
|
||||
|
||||
The logical ID of the package. As we do not trust BIOSes to enumerate the
|
||||
packages in a consistent way, we introduced the concept of logical package
|
||||
ID so we can sanely calculate the number of maximum possible packages in
|
||||
the system and have the packages enumerated linearly.
|
||||
|
||||
- topology_max_packages():
|
||||
|
||||
The maximum possible number of packages in the system. Helpful for per
|
||||
package facilities to preallocate per package information.
|
||||
|
||||
|
||||
* Cores:
|
||||
|
||||
A core consists of 1 or more threads. It does not matter whether the threads
|
||||
are SMT- or CMT-type threads.
|
||||
|
||||
AMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses
|
||||
"core".
|
||||
|
||||
Core-related topology information in the kernel:
|
||||
|
||||
- smp_num_siblings:
|
||||
|
||||
The number of threads in a core. The number of threads in a package can be
|
||||
calculated by:
|
||||
|
||||
threads_per_package = cpuinfo_x86.x86_max_cores * smp_num_siblings
|
||||
|
||||
|
||||
* Threads:
|
||||
|
||||
A thread is a single scheduling unit. It's the equivalent to a logical Linux
|
||||
CPU.
|
||||
|
||||
AMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always
|
||||
uses "thread".
|
||||
|
||||
Thread-related topology information in the kernel:
|
||||
|
||||
- topology_core_cpumask():
|
||||
|
||||
The cpumask contains all online threads in the package to which a thread
|
||||
belongs.
|
||||
|
||||
The number of online threads is also printed in /proc/cpuinfo "siblings."
|
||||
|
||||
- topology_sibling_mask():
|
||||
|
||||
The cpumask contains all online threads in the core to which a thread
|
||||
belongs.
|
||||
|
||||
- topology_logical_package_id():
|
||||
|
||||
The logical package ID to which a thread belongs.
|
||||
|
||||
- topology_physical_package_id():
|
||||
|
||||
The physical package ID to which a thread belongs.
|
||||
|
||||
- topology_core_id();
|
||||
|
||||
The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo
|
||||
"core_id."
|
||||
|
||||
|
||||
|
||||
System topology examples
|
||||
|
||||
Note:
|
||||
|
||||
The alternative Linux CPU enumeration depends on how the BIOS enumerates the
|
||||
threads. Many BIOSes enumerate all threads 0 first and then all threads 1.
|
||||
That has the "advantage" that the logical Linux CPU numbers of threads 0 stay
|
||||
the same whether threads are enabled or not. That's merely an implementation
|
||||
detail and has no practical impact.
|
||||
|
||||
1) Single Package, Single Core
|
||||
|
||||
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
|
||||
|
||||
2) Single Package, Dual Core
|
||||
|
||||
a) One thread per core
|
||||
|
||||
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 1
|
||||
|
||||
b) Two threads per core
|
||||
|
||||
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
|
||||
-> [thread 1] -> Linux CPU 1
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 2
|
||||
-> [thread 1] -> Linux CPU 3
|
||||
|
||||
Alternative enumeration:
|
||||
|
||||
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
|
||||
-> [thread 1] -> Linux CPU 2
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 1
|
||||
-> [thread 1] -> Linux CPU 3
|
||||
|
||||
AMD nomenclature for CMT systems:
|
||||
|
||||
[node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
|
||||
-> [Compute Unit Core 1] -> Linux CPU 1
|
||||
-> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
|
||||
-> [Compute Unit Core 1] -> Linux CPU 3
|
||||
|
||||
4) Dual Package, Dual Core
|
||||
|
||||
a) One thread per core
|
||||
|
||||
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 1
|
||||
|
||||
[package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 3
|
||||
|
||||
b) Two threads per core
|
||||
|
||||
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
|
||||
-> [thread 1] -> Linux CPU 1
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 2
|
||||
-> [thread 1] -> Linux CPU 3
|
||||
|
||||
[package 1] -> [core 0] -> [thread 0] -> Linux CPU 4
|
||||
-> [thread 1] -> Linux CPU 5
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 6
|
||||
-> [thread 1] -> Linux CPU 7
|
||||
|
||||
Alternative enumeration:
|
||||
|
||||
[package 0] -> [core 0] -> [thread 0] -> Linux CPU 0
|
||||
-> [thread 1] -> Linux CPU 4
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 1
|
||||
-> [thread 1] -> Linux CPU 5
|
||||
|
||||
[package 1] -> [core 0] -> [thread 0] -> Linux CPU 2
|
||||
-> [thread 1] -> Linux CPU 6
|
||||
-> [core 1] -> [thread 0] -> Linux CPU 3
|
||||
-> [thread 1] -> Linux CPU 7
|
||||
|
||||
AMD nomenclature for CMT systems:
|
||||
|
||||
[node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0
|
||||
-> [Compute Unit Core 1] -> Linux CPU 1
|
||||
-> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2
|
||||
-> [Compute Unit Core 1] -> Linux CPU 3
|
||||
|
||||
[node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4
|
||||
-> [Compute Unit Core 1] -> Linux CPU 5
|
||||
-> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6
|
||||
-> [Compute Unit Core 1] -> Linux CPU 7
|
|
@ -26,7 +26,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
|
|||
vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
|
||||
|
||||
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
|
||||
KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
|
||||
KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
|
||||
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
|
||||
cflags-$(CONFIG_X86_32) := -march=i386
|
||||
cflags-$(CONFIG_X86_64) := -mcmodel=small
|
||||
|
@ -40,6 +40,18 @@ GCOV_PROFILE := n
|
|||
UBSAN_SANITIZE :=n
|
||||
|
||||
LDFLAGS := -m elf_$(UTS_MACHINE)
|
||||
ifeq ($(CONFIG_RELOCATABLE),y)
|
||||
# If kernel is relocatable, build compressed kernel as PIE.
|
||||
ifeq ($(CONFIG_X86_32),y)
|
||||
LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker)
|
||||
else
|
||||
# To build 64-bit compressed kernel as PIE, we disable relocation
|
||||
# overflow check to avoid relocation overflow error with a new linker
|
||||
# command-line option, -z noreloc-overflow.
|
||||
LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \
|
||||
&& echo "-z noreloc-overflow -pie --no-dynamic-linker")
|
||||
endif
|
||||
endif
|
||||
LDFLAGS_vmlinux := -T
|
||||
|
||||
hostprogs-y := mkpiggy
|
||||
|
|
|
@ -31,6 +31,34 @@
|
|||
#include <asm/asm-offsets.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
||||
/*
|
||||
* The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X
|
||||
* relocation to get the symbol address in PIC. When the compressed x86
|
||||
* kernel isn't built as PIC, the linker optimizes R_386_GOT32X
|
||||
* relocations to their fixed symbol addresses. However, when the
|
||||
* compressed x86 kernel is loaded at a different address, it leads
|
||||
* to the following load failure:
|
||||
*
|
||||
* Failed to allocate space for phdrs
|
||||
*
|
||||
* during the decompression stage.
|
||||
*
|
||||
* If the compressed x86 kernel is relocatable at run-time, it should be
|
||||
* compiled with -fPIE, instead of -fPIC, if possible and should be built as
|
||||
* Position Independent Executable (PIE) so that linker won't optimize
|
||||
* R_386_GOT32X relocation to its fixed symbol address. Older
|
||||
* linkers generate R_386_32 relocations against locally defined symbols,
|
||||
* _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less
|
||||
* optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle
|
||||
* R_386_32 relocations when relocating the kernel. To generate
|
||||
* R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as
|
||||
* hidden:
|
||||
*/
|
||||
.hidden _bss
|
||||
.hidden _ebss
|
||||
.hidden _got
|
||||
.hidden _egot
|
||||
|
||||
__HEAD
|
||||
ENTRY(startup_32)
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
|
|
|
@ -33,6 +33,14 @@
|
|||
#include <asm/asm-offsets.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
||||
/*
|
||||
* Locally defined symbols should be marked hidden:
|
||||
*/
|
||||
.hidden _bss
|
||||
.hidden _ebss
|
||||
.hidden _got
|
||||
.hidden _egot
|
||||
|
||||
__HEAD
|
||||
.code32
|
||||
ENTRY(startup_32)
|
||||
|
|
|
@ -369,7 +369,7 @@ static int amd_pmu_cpu_prepare(int cpu)
|
|||
|
||||
WARN_ON_ONCE(cpuc->amd_nb);
|
||||
|
||||
if (boot_cpu_data.x86_max_cores < 2)
|
||||
if (!x86_pmu.amd_nb_constraints)
|
||||
return NOTIFY_OK;
|
||||
|
||||
cpuc->amd_nb = amd_alloc_nb(cpu);
|
||||
|
@ -388,7 +388,7 @@ static void amd_pmu_cpu_starting(int cpu)
|
|||
|
||||
cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY;
|
||||
|
||||
if (boot_cpu_data.x86_max_cores < 2)
|
||||
if (!x86_pmu.amd_nb_constraints)
|
||||
return;
|
||||
|
||||
nb_id = amd_get_nb_id(cpu);
|
||||
|
@ -414,7 +414,7 @@ static void amd_pmu_cpu_dead(int cpu)
|
|||
{
|
||||
struct cpu_hw_events *cpuhw;
|
||||
|
||||
if (boot_cpu_data.x86_max_cores < 2)
|
||||
if (!x86_pmu.amd_nb_constraints)
|
||||
return;
|
||||
|
||||
cpuhw = &per_cpu(cpu_hw_events, cpu);
|
||||
|
@ -648,6 +648,8 @@ static __initconst const struct x86_pmu amd_pmu = {
|
|||
.cpu_prepare = amd_pmu_cpu_prepare,
|
||||
.cpu_starting = amd_pmu_cpu_starting,
|
||||
.cpu_dead = amd_pmu_cpu_dead,
|
||||
|
||||
.amd_nb_constraints = 1,
|
||||
};
|
||||
|
||||
static int __init amd_core_pmu_init(void)
|
||||
|
@ -674,6 +676,11 @@ static int __init amd_core_pmu_init(void)
|
|||
x86_pmu.eventsel = MSR_F15H_PERF_CTL;
|
||||
x86_pmu.perfctr = MSR_F15H_PERF_CTR;
|
||||
x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE;
|
||||
/*
|
||||
* AMD Core perfctr has separate MSRs for the NB events, see
|
||||
* the amd/uncore.c driver.
|
||||
*/
|
||||
x86_pmu.amd_nb_constraints = 0;
|
||||
|
||||
pr_cont("core perfctr, ");
|
||||
return 0;
|
||||
|
@ -693,6 +700,14 @@ __init int amd_pmu_init(void)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (num_possible_cpus() == 1) {
|
||||
/*
|
||||
* No point in allocating data structures to serialize
|
||||
* against other CPUs, when there is only the one CPU.
|
||||
*/
|
||||
x86_pmu.amd_nb_constraints = 0;
|
||||
}
|
||||
|
||||
/* Events are common for all AMDs */
|
||||
memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,
|
||||
sizeof(hw_cache_event_ids));
|
||||
|
|
|
@ -607,6 +607,11 @@ struct x86_pmu {
|
|||
*/
|
||||
atomic_t lbr_exclusive[x86_lbr_exclusive_max];
|
||||
|
||||
/*
|
||||
* AMD bits
|
||||
*/
|
||||
unsigned int amd_nb_constraints : 1;
|
||||
|
||||
/*
|
||||
* Extra registers for events
|
||||
*/
|
||||
|
|
|
@ -190,6 +190,7 @@
|
|||
#define MSR_PP1_ENERGY_STATUS 0x00000641
|
||||
#define MSR_PP1_POLICY 0x00000642
|
||||
|
||||
/* Config TDP MSRs */
|
||||
#define MSR_CONFIG_TDP_NOMINAL 0x00000648
|
||||
#define MSR_CONFIG_TDP_LEVEL_1 0x00000649
|
||||
#define MSR_CONFIG_TDP_LEVEL_2 0x0000064A
|
||||
|
@ -210,13 +211,6 @@
|
|||
#define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
|
||||
#define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
|
||||
|
||||
/* Config TDP MSRs */
|
||||
#define MSR_CONFIG_TDP_NOMINAL 0x00000648
|
||||
#define MSR_CONFIG_TDP_LEVEL1 0x00000649
|
||||
#define MSR_CONFIG_TDP_LEVEL2 0x0000064A
|
||||
#define MSR_CONFIG_TDP_CONTROL 0x0000064B
|
||||
#define MSR_TURBO_ACTIVATION_RATIO 0x0000064C
|
||||
|
||||
/* Hardware P state interface */
|
||||
#define MSR_PPERF 0x0000064e
|
||||
#define MSR_PERF_LIMIT_REASONS 0x0000064f
|
||||
|
|
|
@ -132,8 +132,6 @@ struct cpuinfo_x86 {
|
|||
u16 logical_proc_id;
|
||||
/* Core id: */
|
||||
u16 cpu_core_id;
|
||||
/* Compute unit id */
|
||||
u8 compute_unit_id;
|
||||
/* Index into per_cpu list: */
|
||||
u16 cpu_index;
|
||||
u32 microcode;
|
||||
|
|
|
@ -155,6 +155,7 @@ static inline int wbinvd_on_all_cpus(void)
|
|||
wbinvd();
|
||||
return 0;
|
||||
}
|
||||
#define smp_num_siblings 1
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
extern unsigned disabled_cpus;
|
||||
|
|
|
@ -276,11 +276,9 @@ static inline bool is_ia32_task(void)
|
|||
*/
|
||||
#define force_iret() set_thread_flag(TIF_NOTIFY_RESUME)
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void arch_task_cache_init(void);
|
||||
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
|
||||
extern void arch_release_task_struct(struct task_struct *tsk);
|
||||
#endif
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_X86_THREAD_INFO_H */
|
||||
|
|
|
@ -170,15 +170,13 @@ int amd_get_subcaches(int cpu)
|
|||
{
|
||||
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
|
||||
unsigned int mask;
|
||||
int cuid;
|
||||
|
||||
if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING))
|
||||
return 0;
|
||||
|
||||
pci_read_config_dword(link, 0x1d4, &mask);
|
||||
|
||||
cuid = cpu_data(cpu).compute_unit_id;
|
||||
return (mask >> (4 * cuid)) & 0xf;
|
||||
return (mask >> (4 * cpu_data(cpu).cpu_core_id)) & 0xf;
|
||||
}
|
||||
|
||||
int amd_set_subcaches(int cpu, unsigned long mask)
|
||||
|
@ -204,7 +202,7 @@ int amd_set_subcaches(int cpu, unsigned long mask)
|
|||
pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000);
|
||||
}
|
||||
|
||||
cuid = cpu_data(cpu).compute_unit_id;
|
||||
cuid = cpu_data(cpu).cpu_core_id;
|
||||
mask <<= 4 * cuid;
|
||||
mask |= (0xf ^ (1 << cuid)) << 26;
|
||||
|
||||
|
|
|
@ -300,7 +300,6 @@ static int nearby_node(int apicid)
|
|||
#ifdef CONFIG_SMP
|
||||
static void amd_get_topology(struct cpuinfo_x86 *c)
|
||||
{
|
||||
u32 cores_per_cu = 1;
|
||||
u8 node_id;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
|
@ -313,8 +312,8 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
|
|||
|
||||
/* get compute unit information */
|
||||
smp_num_siblings = ((ebx >> 8) & 3) + 1;
|
||||
c->compute_unit_id = ebx & 0xff;
|
||||
cores_per_cu += ((ebx >> 8) & 3);
|
||||
c->x86_max_cores /= smp_num_siblings;
|
||||
c->cpu_core_id = ebx & 0xff;
|
||||
} else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
|
||||
u64 value;
|
||||
|
||||
|
@ -325,19 +324,16 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
|
|||
|
||||
/* fixup multi-node processor information */
|
||||
if (nodes_per_socket > 1) {
|
||||
u32 cores_per_node;
|
||||
u32 cus_per_node;
|
||||
|
||||
set_cpu_cap(c, X86_FEATURE_AMD_DCM);
|
||||
cores_per_node = c->x86_max_cores / nodes_per_socket;
|
||||
cus_per_node = cores_per_node / cores_per_cu;
|
||||
cus_per_node = c->x86_max_cores / nodes_per_socket;
|
||||
|
||||
/* store NodeID, use llc_shared_map to store sibling info */
|
||||
per_cpu(cpu_llc_id, cpu) = node_id;
|
||||
|
||||
/* core id has to be in the [0 .. cores_per_node - 1] range */
|
||||
c->cpu_core_id %= cores_per_node;
|
||||
c->compute_unit_id %= cus_per_node;
|
||||
c->cpu_core_id %= cus_per_node;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,7 @@ static char gen_pool_buf[MCE_POOLSZ];
|
|||
void mce_gen_pool_process(void)
|
||||
{
|
||||
struct llist_node *head;
|
||||
struct mce_evt_llist *node;
|
||||
struct mce_evt_llist *node, *tmp;
|
||||
struct mce *mce;
|
||||
|
||||
head = llist_del_all(&mce_event_llist);
|
||||
|
@ -37,7 +37,7 @@ void mce_gen_pool_process(void)
|
|||
return;
|
||||
|
||||
head = llist_reverse_order(head);
|
||||
llist_for_each_entry(node, head, llnode) {
|
||||
llist_for_each_entry_safe(node, tmp, head, llnode) {
|
||||
mce = &node->mce;
|
||||
atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
|
||||
gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node));
|
||||
|
|
|
@ -18,4 +18,6 @@ const char *const x86_power_flags[32] = {
|
|||
"", /* tsc invariant mapped to constant_tsc */
|
||||
"cpb", /* core performance boost */
|
||||
"eff_freq_ro", /* Readonly aperf/mperf */
|
||||
"proc_feedback", /* processor feedback interface */
|
||||
"acc_power", /* accumulated power mechanism */
|
||||
};
|
||||
|
|
|
@ -422,7 +422,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
|
|||
|
||||
if (c->phys_proc_id == o->phys_proc_id &&
|
||||
per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2) &&
|
||||
c->compute_unit_id == o->compute_unit_id)
|
||||
c->cpu_core_id == o->cpu_core_id)
|
||||
return topology_sane(c, o, "smt");
|
||||
|
||||
} else if (c->phys_proc_id == o->phys_proc_id &&
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/mce.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/irq_vectors.h>
|
||||
|
||||
|
@ -206,7 +207,7 @@ static u32 get_nbc_for_node(int node_id)
|
|||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
u32 cores_per_node;
|
||||
|
||||
cores_per_node = c->x86_max_cores / amd_get_nodes_per_socket();
|
||||
cores_per_node = (c->x86_max_cores * smp_num_siblings) / amd_get_nodes_per_socket();
|
||||
|
||||
return cores_per_node * node_id;
|
||||
}
|
||||
|
|
|
@ -331,7 +331,7 @@ void set_interrupt(struct lg_cpu *cpu, unsigned int irq)
|
|||
* Actually now I think of it, it's possible that Ron *is* half the Plan 9
|
||||
* userbase. Oh well.
|
||||
*/
|
||||
static bool could_be_syscall(unsigned int num)
|
||||
bool could_be_syscall(unsigned int num)
|
||||
{
|
||||
/* Normal Linux IA32_SYSCALL_VECTOR or reserved vector? */
|
||||
return num == IA32_SYSCALL_VECTOR || num == syscall_vector;
|
||||
|
@ -416,6 +416,10 @@ bool deliver_trap(struct lg_cpu *cpu, unsigned int num)
|
|||
*
|
||||
* This routine indicates if a particular trap number could be delivered
|
||||
* directly.
|
||||
*
|
||||
* Unfortunately, Linux 4.6 started using an interrupt gate instead of a
|
||||
* trap gate for syscalls, so this trick is ineffective. See Mastery for
|
||||
* how we could do this anyway...
|
||||
*/
|
||||
static bool direct_trap(unsigned int num)
|
||||
{
|
||||
|
|
|
@ -167,6 +167,7 @@ void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta);
|
|||
bool send_notify_to_eventfd(struct lg_cpu *cpu);
|
||||
void init_clockdev(struct lg_cpu *cpu);
|
||||
bool check_syscall_vector(struct lguest *lg);
|
||||
bool could_be_syscall(unsigned int num);
|
||||
int init_interrupts(void);
|
||||
void free_interrupts(void);
|
||||
|
||||
|
|
|
@ -429,8 +429,12 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
|
|||
return;
|
||||
break;
|
||||
case 32 ... 255:
|
||||
/* This might be a syscall. */
|
||||
if (could_be_syscall(cpu->regs->trapnum))
|
||||
break;
|
||||
|
||||
/*
|
||||
* These values mean a real interrupt occurred, in which case
|
||||
* Other values mean a real interrupt occurred, in which case
|
||||
* the Host handler has already been run. We just do a
|
||||
* friendly check if another process should now be run, then
|
||||
* return to run the Guest again.
|
||||
|
|
Loading…
Reference in New Issue