Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc: Fix hcall tracepoint recursion powerpc/numa: Fix bug in unmap_cpu_from_node powerpc/numa: Disable VPHN on dedicated processor partitions powerpc/numa: Add length when creating OF properties via VPHN powerpc/numa: Check for all VPHN changes powerpc/numa: Only use active VPHN count fields powerpc/pseries: Remove unnecessary variable initializations in numa.c powerpc/pseries: Fix brace placement in numa.c powerpc/pseries: Fix typo in VPHN comments powerpc: Fix some 6xx/7xxx CPU setup functions powerpc: Pass the right cpu_spec to ->setup_cpu() on 64-bit powerpc/book3e: Protect complex macro args in mmu-book3e.h powerpc: Fix pfn_valid() when memory starts at a non-zero address
This commit is contained in:
commit
eee4da2cef
|
@ -40,8 +40,8 @@
|
||||||
|
|
||||||
/* MAS registers bit definitions */
|
/* MAS registers bit definitions */
|
||||||
|
|
||||||
#define MAS0_TLBSEL(x) ((x << 28) & 0x30000000)
|
#define MAS0_TLBSEL(x) (((x) << 28) & 0x30000000)
|
||||||
#define MAS0_ESEL(x) ((x << 16) & 0x0FFF0000)
|
#define MAS0_ESEL(x) (((x) << 16) & 0x0FFF0000)
|
||||||
#define MAS0_NV(x) ((x) & 0x00000FFF)
|
#define MAS0_NV(x) ((x) & 0x00000FFF)
|
||||||
#define MAS0_HES 0x00004000
|
#define MAS0_HES 0x00004000
|
||||||
#define MAS0_WQ_ALLWAYS 0x00000000
|
#define MAS0_WQ_ALLWAYS 0x00000000
|
||||||
|
@ -50,12 +50,12 @@
|
||||||
|
|
||||||
#define MAS1_VALID 0x80000000
|
#define MAS1_VALID 0x80000000
|
||||||
#define MAS1_IPROT 0x40000000
|
#define MAS1_IPROT 0x40000000
|
||||||
#define MAS1_TID(x) ((x << 16) & 0x3FFF0000)
|
#define MAS1_TID(x) (((x) << 16) & 0x3FFF0000)
|
||||||
#define MAS1_IND 0x00002000
|
#define MAS1_IND 0x00002000
|
||||||
#define MAS1_TS 0x00001000
|
#define MAS1_TS 0x00001000
|
||||||
#define MAS1_TSIZE_MASK 0x00000f80
|
#define MAS1_TSIZE_MASK 0x00000f80
|
||||||
#define MAS1_TSIZE_SHIFT 7
|
#define MAS1_TSIZE_SHIFT 7
|
||||||
#define MAS1_TSIZE(x) ((x << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK)
|
#define MAS1_TSIZE(x) (((x) << MAS1_TSIZE_SHIFT) & MAS1_TSIZE_MASK)
|
||||||
|
|
||||||
#define MAS2_EPN 0xFFFFF000
|
#define MAS2_EPN 0xFFFFF000
|
||||||
#define MAS2_X0 0x00000040
|
#define MAS2_X0 0x00000040
|
||||||
|
|
|
@ -101,7 +101,7 @@ extern phys_addr_t kernstart_addr;
|
||||||
|
|
||||||
#ifdef CONFIG_FLATMEM
|
#ifdef CONFIG_FLATMEM
|
||||||
#define ARCH_PFN_OFFSET (MEMORY_START >> PAGE_SHIFT)
|
#define ARCH_PFN_OFFSET (MEMORY_START >> PAGE_SHIFT)
|
||||||
#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < (ARCH_PFN_OFFSET + max_mapnr))
|
#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
|
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
|
|
||||||
_GLOBAL(__setup_cpu_603)
|
_GLOBAL(__setup_cpu_603)
|
||||||
mflr r4
|
mflr r5
|
||||||
BEGIN_MMU_FTR_SECTION
|
BEGIN_MMU_FTR_SECTION
|
||||||
li r10,0
|
li r10,0
|
||||||
mtspr SPRN_SPRG_603_LRU,r10 /* init SW LRU tracking */
|
mtspr SPRN_SPRG_603_LRU,r10 /* init SW LRU tracking */
|
||||||
|
@ -27,60 +27,60 @@ BEGIN_FTR_SECTION
|
||||||
bl __init_fpu_registers
|
bl __init_fpu_registers
|
||||||
END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
|
END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
_GLOBAL(__setup_cpu_604)
|
_GLOBAL(__setup_cpu_604)
|
||||||
mflr r4
|
mflr r5
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
bl setup_604_hid0
|
bl setup_604_hid0
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
_GLOBAL(__setup_cpu_750)
|
_GLOBAL(__setup_cpu_750)
|
||||||
mflr r4
|
mflr r5
|
||||||
bl __init_fpu_registers
|
bl __init_fpu_registers
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
bl setup_750_7400_hid0
|
bl setup_750_7400_hid0
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
_GLOBAL(__setup_cpu_750cx)
|
_GLOBAL(__setup_cpu_750cx)
|
||||||
mflr r4
|
mflr r5
|
||||||
bl __init_fpu_registers
|
bl __init_fpu_registers
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
bl setup_750_7400_hid0
|
bl setup_750_7400_hid0
|
||||||
bl setup_750cx
|
bl setup_750cx
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
_GLOBAL(__setup_cpu_750fx)
|
_GLOBAL(__setup_cpu_750fx)
|
||||||
mflr r4
|
mflr r5
|
||||||
bl __init_fpu_registers
|
bl __init_fpu_registers
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
bl setup_750_7400_hid0
|
bl setup_750_7400_hid0
|
||||||
bl setup_750fx
|
bl setup_750fx
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
_GLOBAL(__setup_cpu_7400)
|
_GLOBAL(__setup_cpu_7400)
|
||||||
mflr r4
|
mflr r5
|
||||||
bl __init_fpu_registers
|
bl __init_fpu_registers
|
||||||
bl setup_7400_workarounds
|
bl setup_7400_workarounds
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
bl setup_750_7400_hid0
|
bl setup_750_7400_hid0
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
_GLOBAL(__setup_cpu_7410)
|
_GLOBAL(__setup_cpu_7410)
|
||||||
mflr r4
|
mflr r5
|
||||||
bl __init_fpu_registers
|
bl __init_fpu_registers
|
||||||
bl setup_7410_workarounds
|
bl setup_7410_workarounds
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
bl setup_750_7400_hid0
|
bl setup_750_7400_hid0
|
||||||
li r3,0
|
li r3,0
|
||||||
mtspr SPRN_L2CR2,r3
|
mtspr SPRN_L2CR2,r3
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
_GLOBAL(__setup_cpu_745x)
|
_GLOBAL(__setup_cpu_745x)
|
||||||
mflr r4
|
mflr r5
|
||||||
bl setup_common_caches
|
bl setup_common_caches
|
||||||
bl setup_745x_specifics
|
bl setup_745x_specifics
|
||||||
mtlr r4
|
mtlr r5
|
||||||
blr
|
blr
|
||||||
|
|
||||||
/* Enable caches for 603's, 604, 750 & 7400 */
|
/* Enable caches for 603's, 604, 750 & 7400 */
|
||||||
|
@ -194,10 +194,10 @@ setup_750cx:
|
||||||
cror 4*cr0+eq,4*cr0+eq,4*cr1+eq
|
cror 4*cr0+eq,4*cr0+eq,4*cr1+eq
|
||||||
cror 4*cr0+eq,4*cr0+eq,4*cr2+eq
|
cror 4*cr0+eq,4*cr0+eq,4*cr2+eq
|
||||||
bnelr
|
bnelr
|
||||||
lwz r6,CPU_SPEC_FEATURES(r5)
|
lwz r6,CPU_SPEC_FEATURES(r4)
|
||||||
li r7,CPU_FTR_CAN_NAP
|
li r7,CPU_FTR_CAN_NAP
|
||||||
andc r6,r6,r7
|
andc r6,r6,r7
|
||||||
stw r6,CPU_SPEC_FEATURES(r5)
|
stw r6,CPU_SPEC_FEATURES(r4)
|
||||||
blr
|
blr
|
||||||
|
|
||||||
/* 750fx specific
|
/* 750fx specific
|
||||||
|
@ -225,12 +225,12 @@ BEGIN_FTR_SECTION
|
||||||
andis. r11,r11,L3CR_L3E@h
|
andis. r11,r11,L3CR_L3E@h
|
||||||
beq 1f
|
beq 1f
|
||||||
END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
|
END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
|
||||||
lwz r6,CPU_SPEC_FEATURES(r5)
|
lwz r6,CPU_SPEC_FEATURES(r4)
|
||||||
andi. r0,r6,CPU_FTR_L3_DISABLE_NAP
|
andi. r0,r6,CPU_FTR_L3_DISABLE_NAP
|
||||||
beq 1f
|
beq 1f
|
||||||
li r7,CPU_FTR_CAN_NAP
|
li r7,CPU_FTR_CAN_NAP
|
||||||
andc r6,r6,r7
|
andc r6,r6,r7
|
||||||
stw r6,CPU_SPEC_FEATURES(r5)
|
stw r6,CPU_SPEC_FEATURES(r4)
|
||||||
1:
|
1:
|
||||||
mfspr r11,SPRN_HID0
|
mfspr r11,SPRN_HID0
|
||||||
|
|
||||||
|
|
|
@ -2076,8 +2076,8 @@ static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s)
|
||||||
* pointer on ppc64 and booke as we are running at 0 in real mode
|
* pointer on ppc64 and booke as we are running at 0 in real mode
|
||||||
* on ppc64 and reloc_offset is always 0 on booke.
|
* on ppc64 and reloc_offset is always 0 on booke.
|
||||||
*/
|
*/
|
||||||
if (s->cpu_setup) {
|
if (t->cpu_setup) {
|
||||||
s->cpu_setup(offset, s);
|
t->cpu_setup(offset, t);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
|
#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ static void unmap_cpu_from_node(unsigned long cpu)
|
||||||
dbg("removing cpu %lu from node %d\n", cpu, node);
|
dbg("removing cpu %lu from node %d\n", cpu, node);
|
||||||
|
|
||||||
if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) {
|
if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) {
|
||||||
cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
|
cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
|
printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
|
||||||
cpu, node);
|
cpu, node);
|
||||||
|
@ -1289,10 +1289,9 @@ u64 memory_hotplug_max(void)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_MEMORY_HOTPLUG */
|
#endif /* CONFIG_MEMORY_HOTPLUG */
|
||||||
|
|
||||||
/* Vrtual Processor Home Node (VPHN) support */
|
/* Virtual Processor Home Node (VPHN) support */
|
||||||
#ifdef CONFIG_PPC_SPLPAR
|
#ifdef CONFIG_PPC_SPLPAR
|
||||||
#define VPHN_NR_CHANGE_CTRS (8)
|
static u8 vphn_cpu_change_counts[NR_CPUS][MAX_DISTANCE_REF_POINTS];
|
||||||
static u8 vphn_cpu_change_counts[NR_CPUS][VPHN_NR_CHANGE_CTRS];
|
|
||||||
static cpumask_t cpu_associativity_changes_mask;
|
static cpumask_t cpu_associativity_changes_mask;
|
||||||
static int vphn_enabled;
|
static int vphn_enabled;
|
||||||
static void set_topology_timer(void);
|
static void set_topology_timer(void);
|
||||||
|
@ -1303,16 +1302,18 @@ static void set_topology_timer(void);
|
||||||
*/
|
*/
|
||||||
static void setup_cpu_associativity_change_counters(void)
|
static void setup_cpu_associativity_change_counters(void)
|
||||||
{
|
{
|
||||||
int cpu = 0;
|
int cpu;
|
||||||
|
|
||||||
|
/* The VPHN feature supports a maximum of 8 reference points */
|
||||||
|
BUILD_BUG_ON(MAX_DISTANCE_REF_POINTS > 8);
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
int i = 0;
|
int i;
|
||||||
u8 *counts = vphn_cpu_change_counts[cpu];
|
u8 *counts = vphn_cpu_change_counts[cpu];
|
||||||
volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
|
volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
|
||||||
|
|
||||||
for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) {
|
for (i = 0; i < distance_ref_points_depth; i++)
|
||||||
counts[i] = hypervisor_counts[i];
|
counts[i] = hypervisor_counts[i];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1329,7 +1330,7 @@ static void setup_cpu_associativity_change_counters(void)
|
||||||
*/
|
*/
|
||||||
static int update_cpu_associativity_changes_mask(void)
|
static int update_cpu_associativity_changes_mask(void)
|
||||||
{
|
{
|
||||||
int cpu = 0, nr_cpus = 0;
|
int cpu, nr_cpus = 0;
|
||||||
cpumask_t *changes = &cpu_associativity_changes_mask;
|
cpumask_t *changes = &cpu_associativity_changes_mask;
|
||||||
|
|
||||||
cpumask_clear(changes);
|
cpumask_clear(changes);
|
||||||
|
@ -1339,8 +1340,8 @@ static int update_cpu_associativity_changes_mask(void)
|
||||||
u8 *counts = vphn_cpu_change_counts[cpu];
|
u8 *counts = vphn_cpu_change_counts[cpu];
|
||||||
volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
|
volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts;
|
||||||
|
|
||||||
for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) {
|
for (i = 0; i < distance_ref_points_depth; i++) {
|
||||||
if (hypervisor_counts[i] > counts[i]) {
|
if (hypervisor_counts[i] != counts[i]) {
|
||||||
counts[i] = hypervisor_counts[i];
|
counts[i] = hypervisor_counts[i];
|
||||||
changed = 1;
|
changed = 1;
|
||||||
}
|
}
|
||||||
|
@ -1354,8 +1355,11 @@ static int update_cpu_associativity_changes_mask(void)
|
||||||
return nr_cpus;
|
return nr_cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 6 64-bit registers unpacked into 12 32-bit associativity values */
|
/*
|
||||||
#define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32))
|
* 6 64-bit registers unpacked into 12 32-bit associativity values. To form
|
||||||
|
* the complete property we have to add the length in the first cell.
|
||||||
|
*/
|
||||||
|
#define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32) + 1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert the associativity domain numbers returned from the hypervisor
|
* Convert the associativity domain numbers returned from the hypervisor
|
||||||
|
@ -1363,15 +1367,14 @@ static int update_cpu_associativity_changes_mask(void)
|
||||||
*/
|
*/
|
||||||
static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked)
|
static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i, nr_assoc_doms = 0;
|
||||||
int nr_assoc_doms = 0;
|
|
||||||
const u16 *field = (const u16*) packed;
|
const u16 *field = (const u16*) packed;
|
||||||
|
|
||||||
#define VPHN_FIELD_UNUSED (0xffff)
|
#define VPHN_FIELD_UNUSED (0xffff)
|
||||||
#define VPHN_FIELD_MSB (0x8000)
|
#define VPHN_FIELD_MSB (0x8000)
|
||||||
#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB)
|
#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB)
|
||||||
|
|
||||||
for (i = 0; i < VPHN_ASSOC_BUFSIZE; i++) {
|
for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) {
|
||||||
if (*field == VPHN_FIELD_UNUSED) {
|
if (*field == VPHN_FIELD_UNUSED) {
|
||||||
/* All significant fields processed, and remaining
|
/* All significant fields processed, and remaining
|
||||||
* fields contain the reserved value of all 1's.
|
* fields contain the reserved value of all 1's.
|
||||||
|
@ -1379,14 +1382,12 @@ static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked)
|
||||||
*/
|
*/
|
||||||
unpacked[i] = *((u32*)field);
|
unpacked[i] = *((u32*)field);
|
||||||
field += 2;
|
field += 2;
|
||||||
}
|
} else if (*field & VPHN_FIELD_MSB) {
|
||||||
else if (*field & VPHN_FIELD_MSB) {
|
|
||||||
/* Data is in the lower 15 bits of this field */
|
/* Data is in the lower 15 bits of this field */
|
||||||
unpacked[i] = *field & VPHN_FIELD_MASK;
|
unpacked[i] = *field & VPHN_FIELD_MASK;
|
||||||
field++;
|
field++;
|
||||||
nr_assoc_doms++;
|
nr_assoc_doms++;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* Data is in the lower 15 bits of this field
|
/* Data is in the lower 15 bits of this field
|
||||||
* concatenated with the next 16 bit field
|
* concatenated with the next 16 bit field
|
||||||
*/
|
*/
|
||||||
|
@ -1396,6 +1397,9 @@ static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The first cell contains the length of the property */
|
||||||
|
unpacked[0] = nr_assoc_doms;
|
||||||
|
|
||||||
return nr_assoc_doms;
|
return nr_assoc_doms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1405,7 +1409,7 @@ static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked)
|
||||||
*/
|
*/
|
||||||
static long hcall_vphn(unsigned long cpu, unsigned int *associativity)
|
static long hcall_vphn(unsigned long cpu, unsigned int *associativity)
|
||||||
{
|
{
|
||||||
long rc = 0;
|
long rc;
|
||||||
long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
|
long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
|
||||||
u64 flags = 1;
|
u64 flags = 1;
|
||||||
int hwcpu = get_hard_smp_processor_id(cpu);
|
int hwcpu = get_hard_smp_processor_id(cpu);
|
||||||
|
@ -1419,7 +1423,7 @@ static long hcall_vphn(unsigned long cpu, unsigned int *associativity)
|
||||||
static long vphn_get_associativity(unsigned long cpu,
|
static long vphn_get_associativity(unsigned long cpu,
|
||||||
unsigned int *associativity)
|
unsigned int *associativity)
|
||||||
{
|
{
|
||||||
long rc = 0;
|
long rc;
|
||||||
|
|
||||||
rc = hcall_vphn(cpu, associativity);
|
rc = hcall_vphn(cpu, associativity);
|
||||||
|
|
||||||
|
@ -1445,9 +1449,9 @@ static long vphn_get_associativity(unsigned long cpu,
|
||||||
*/
|
*/
|
||||||
int arch_update_cpu_topology(void)
|
int arch_update_cpu_topology(void)
|
||||||
{
|
{
|
||||||
int cpu = 0, nid = 0, old_nid = 0;
|
int cpu, nid, old_nid;
|
||||||
unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
|
unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
|
||||||
struct sys_device *sysdev = NULL;
|
struct sys_device *sysdev;
|
||||||
|
|
||||||
for_each_cpu_mask(cpu, cpu_associativity_changes_mask) {
|
for_each_cpu_mask(cpu, cpu_associativity_changes_mask) {
|
||||||
vphn_get_associativity(cpu, associativity);
|
vphn_get_associativity(cpu, associativity);
|
||||||
|
@ -1512,7 +1516,8 @@ int start_topology_update(void)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (firmware_has_feature(FW_FEATURE_VPHN)) {
|
if (firmware_has_feature(FW_FEATURE_VPHN) &&
|
||||||
|
get_lppaca()->shared_proc) {
|
||||||
vphn_enabled = 1;
|
vphn_enabled = 1;
|
||||||
setup_cpu_associativity_change_counters();
|
setup_cpu_associativity_change_counters();
|
||||||
init_timer_deferrable(&topology_timer);
|
init_timer_deferrable(&topology_timer);
|
||||||
|
|
|
@ -713,6 +713,13 @@ EXPORT_SYMBOL(arch_free_page);
|
||||||
/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
|
/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
|
||||||
extern long hcall_tracepoint_refcount;
|
extern long hcall_tracepoint_refcount;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since the tracing code might execute hcalls we need to guard against
|
||||||
|
* recursion. One example of this are spinlocks calling H_YIELD on
|
||||||
|
* shared processor partitions.
|
||||||
|
*/
|
||||||
|
static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
|
||||||
|
|
||||||
void hcall_tracepoint_regfunc(void)
|
void hcall_tracepoint_regfunc(void)
|
||||||
{
|
{
|
||||||
hcall_tracepoint_refcount++;
|
hcall_tracepoint_refcount++;
|
||||||
|
@ -725,12 +732,42 @@ void hcall_tracepoint_unregfunc(void)
|
||||||
|
|
||||||
void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
|
void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned int *depth;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
depth = &__get_cpu_var(hcall_trace_depth);
|
||||||
|
|
||||||
|
if (*depth)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
(*depth)++;
|
||||||
trace_hcall_entry(opcode, args);
|
trace_hcall_entry(opcode, args);
|
||||||
|
(*depth)--;
|
||||||
|
|
||||||
|
out:
|
||||||
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __trace_hcall_exit(long opcode, unsigned long retval,
|
void __trace_hcall_exit(long opcode, unsigned long retval,
|
||||||
unsigned long *retbuf)
|
unsigned long *retbuf)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
unsigned int *depth;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
depth = &__get_cpu_var(hcall_trace_depth);
|
||||||
|
|
||||||
|
if (*depth)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
(*depth)++;
|
||||||
trace_hcall_exit(opcode, retval, retbuf);
|
trace_hcall_exit(opcode, retval, retbuf);
|
||||||
|
(*depth)--;
|
||||||
|
|
||||||
|
out:
|
||||||
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue