[PATCH v2 0/3] powernv:stop: Use psscr_val,mask provided by firmware
From: "Gautham R. Shenoy" Hi, This is the second iteration of the patchset to use the psscr_val and psscr_mask provided by the firmware for each of the stop states. The previous version can be found here: https://lkml.org/lkml/2016/9/29/45 The main changes in this version are: 1) Add a helper function in powernv-cpuidle.c to help initialize the powernv_states cpuidle table. 2) Handle the older firmware which populates only the Requested Level (RL) fields of the psscr and psscr_mask in the device tree. This patchset ensures that in the presence of the older firmware, the other fields of PSSCR are initalized to sane default values. Synopsis == In the current implementation, the code for ISA v3.0 stop implementation has a couple of shortcomings. a) The code hand-codes the values for ESL,EC,TR,MTL bits of PSSCR and uses only the RL field from the firmware. While this is not incorrect, since the hand-coded values are legitimate, it is not a very flexible design since the firmware has the capability to communicate these values via the "ibm,cpu-idle-state-psscr" and "ibm,cpu-idle-state-psscr-mask" properties. In case where the firmware provides values for these fields that is different from the hand-coded values, the current code will not work as intended. b) Due to issue a), the current code assumes that ESL=EC=1 for all the stop states and hence the wakeup from the stop instruction will happen at 0x100, the system-reset vector. However, the ISA v3.0 allows the ESL=EC=0 behaviour where the corresponding stop-state loses no state and wakes up from the subsequent instruction. The current code doesn't handle this case. This patch series addresses these issues. The first patch in the series renames the existing IDLE_STATE_ENTER_SEQ macro to IDLE_STATE_ENTER_SEQ_NORET. It reuses the name IDLE_STATE_ENTER_SEQ for entering into stop-states which wake up at the subsequent instruction. The second patch adds a helper function in cpuidle-powernv.c for initializing entries of the powernv_states[] table that is passed to the cpu-idle core. This eliminates some of the code duplication in the function that discovers and initializes the stop states. The third patch in the series fixes issues a) and b) by ensuring that the psscr-value and the psscr-mask provided by the firmware are what will be used to set a particular stop state. It also adds support for handling wake-up from stop states which were entered with ESL=EC=0. The third patch also handles the older firmware which sets only the Requested Level (RL) field in the psscr and psscr-mask exposed in the device tree. In the presence of such older firmware, this patch will set the default sane values for for remaining PSSCR fields (i.e PSLL, MTL, ESL, EC, and TR). The skiboot patch populates all the relevant fields in the PSSCR values and the mask for all the stop states can be found here: https://lists.ozlabs.org/pipermail/skiboot/2016-September/004869.html The patches are based on top of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git fixes Gautham R. Shenoy (3): powernv:idle: Add IDLE_STATE_ENTER_SEQ_NORET macro cpuidle:powernv: Add helper function to populate powernv idle states. powernv: Pass PSSCR value and mask to power9_idle_stop arch/powerpc/include/asm/cpuidle.h | 42 +++- arch/powerpc/include/asm/processor.h | 3 +- arch/powerpc/kernel/exceptions-64s.S | 6 +- arch/powerpc/kernel/idle_book3s.S| 41 +++- arch/powerpc/platforms/powernv/idle.c| 81 +++ arch/powerpc/platforms/powernv/powernv.h | 3 +- arch/powerpc/platforms/powernv/smp.c | 14 ++-- drivers/cpuidle/cpuidle-powernv.c| 110 --- include/linux/cpuidle.h | 1 + 9 files changed, 220 insertions(+), 81 deletions(-) -- 1.9.4
[PATCH v2 1/3] powernv:idle: Add IDLE_STATE_ENTER_SEQ_NORET macro
From: "Gautham R. Shenoy" Currently all the low-power idle states are expected to wake up at reset vector 0x100. Which is why the macro IDLE_STATE_ENTER_SEQ that puts the CPU to an idle state and never returns. On ISA_300, when the ESL and EC bits in the PSSCR are zero, the CPU is expected to wake up at the next instruction of the idle instruction. This patch adds a new macro named IDLE_STATE_ENTER_SEQ_NORET for the no-return variant and reuses the name IDLE_STATE_ENTER_SEQ for a variant that allows resuming operation at the instruction next to the idle-instruction. Signed-off-by: Gautham R. Shenoy --- arch/powerpc/include/asm/cpuidle.h | 5 - arch/powerpc/kernel/exceptions-64s.S | 6 +++--- arch/powerpc/kernel/idle_book3s.S| 10 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/cpuidle.h b/arch/powerpc/include/asm/cpuidle.h index 3919332..0a3255b 100644 --- a/arch/powerpc/include/asm/cpuidle.h +++ b/arch/powerpc/include/asm/cpuidle.h @@ -21,7 +21,7 @@ /* Idle state entry routines */ #ifdef CONFIG_PPC_P7_NAP -#defineIDLE_STATE_ENTER_SEQ(IDLE_INST) \ +#define IDLE_STATE_ENTER_SEQ(IDLE_INST) \ /* Magic NAP/SLEEP/WINKLE mode enter sequence */\ std r0,0(r1); \ ptesync;\ @@ -29,6 +29,9 @@ 1: cmpdcr0,r0,r0; \ bne 1b; \ IDLE_INST; \ + +#defineIDLE_STATE_ENTER_SEQ_NORET(IDLE_INST) \ + IDLE_STATE_ENTER_SEQ(IDLE_INST) \ b . #endif /* CONFIG_PPC_P7_NAP */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index f129408..7a71cdf 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -366,12 +366,12 @@ EXC_COMMON_BEGIN(machine_check_handle_early) lbz r3,PACA_THREAD_IDLE_STATE(r13) cmpwi r3,PNV_THREAD_NAP bgt 10f - IDLE_STATE_ENTER_SEQ(PPC_NAP) + IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP) /* No return */ 10: cmpwi r3,PNV_THREAD_SLEEP bgt 2f - IDLE_STATE_ENTER_SEQ(PPC_SLEEP) + IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP) /* No return */ 2: @@ -385,7 +385,7 @@ EXC_COMMON_BEGIN(machine_check_handle_early) */ ori r13,r13,1 SET_PACA(r13) - IDLE_STATE_ENTER_SEQ(PPC_WINKLE) + IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE) /* No return */ 4: #endif diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index 72dac0b..be90e2f 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -205,7 +205,7 @@ pnv_enter_arch207_idle_mode: stb r3,PACA_THREAD_IDLE_STATE(r13) cmpwi cr3,r3,PNV_THREAD_SLEEP bge cr3,2f - IDLE_STATE_ENTER_SEQ(PPC_NAP) + IDLE_STATE_ENTER_SEQ_NORET(PPC_NAP) /* No return */ 2: /* Sleep or winkle */ @@ -239,7 +239,7 @@ pnv_fastsleep_workaround_at_entry: common_enter: /* common code for all the threads entering sleep or winkle */ bgt cr3,enter_winkle - IDLE_STATE_ENTER_SEQ(PPC_SLEEP) + IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP) fastsleep_workaround_at_entry: ori r15,r15,PNV_CORE_IDLE_LOCK_BIT @@ -261,7 +261,7 @@ fastsleep_workaround_at_entry: enter_winkle: bl save_sprs_to_stack - IDLE_STATE_ENTER_SEQ(PPC_WINKLE) + IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE) /* * r3 - requested stop state @@ -280,7 +280,7 @@ power_enter_stop: ld r4,ADDROFF(pnv_first_deep_stop_state)(r5) cmpdr3,r4 bge 2f - IDLE_STATE_ENTER_SEQ(PPC_STOP) + IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP) 2: /* * Entering deep idle state. @@ -302,7 +302,7 @@ lwarx_loop_stop: bl save_sprs_to_stack - IDLE_STATE_ENTER_SEQ(PPC_STOP) + IDLE_STATE_ENTER_SEQ_NORET(PPC_STOP) _GLOBAL(power7_idle) /* Now check if user or arch enabled NAP mode */ -- 1.9.4
[PATCH v2 2/3] cpuidle:powernv: Add helper function to populate powernv idle states.
From: "Gautham R. Shenoy" In the current code for powernv_add_idle_states, there is a lot of code duplication while initializing an idle state in powernv_states table. Add an inline helper function to populate the powernv_states[] table for a given idle state. Invoke this for populating the "Nap", "Fastsleep" and the stop states in powernv_add_idle_states. Signed-off-by: Gautham R. Shenoy --- drivers/cpuidle/cpuidle-powernv.c | 82 +++ include/linux/cpuidle.h | 1 + 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index 7fe442c..11b22b9 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -167,6 +167,28 @@ static int powernv_cpuidle_driver_init(void) return 0; } +static inline void add_powernv_state(int index, const char *name, +unsigned int flags, +int (*idle_fn)(struct cpuidle_device *, + struct cpuidle_driver *, + int), +unsigned int target_residency, +unsigned int exit_latency, +u64 psscr_val) +{ + strncpy(powernv_states[index].name, name, CPUIDLE_NAME_LEN); + strncpy(powernv_states[index].desc, name, CPUIDLE_NAME_LEN); + powernv_states[index].flags = flags; + powernv_states[index].target_residency = target_residency; + powernv_states[index].exit_latency = exit_latency; + powernv_states[index].enter = idle_fn; + + if (idle_fn != stop_loop) + return; + + stop_psscr_table[index] = psscr_val; +} + static int powernv_add_idle_states(void) { struct device_node *power_mgt; @@ -236,6 +258,7 @@ static int powernv_add_idle_states(void) "ibm,cpu-idle-state-residency-ns", residency_ns, dt_idle_states); for (i = 0; i < dt_idle_states; i++) { + unsigned int exit_latency, target_residency; /* * If an idle state has exit latency beyond * POWERNV_THRESHOLD_LATENCY_NS then don't use it @@ -244,27 +267,30 @@ static int powernv_add_idle_states(void) if (latency_ns[i] > POWERNV_THRESHOLD_LATENCY_NS) continue; + exit_latency = ((unsigned int)latency_ns[i]) / 1000; + target_residency = (!rc) ? ((unsigned int)residency_ns[i]) : 0; + /* +* Firmware passes residency values in ns. +* cpuidle expects it in us. +*/ + target_residency /= 1000; + /* * Cpuidle accepts exit_latency and target_residency in us. * Use default target_residency values if f/w does not expose it. */ if (flags[i] & OPAL_PM_NAP_ENABLED) { + target_residency = 100; /* Add NAP state */ - strcpy(powernv_states[nr_idle_states].name, "Nap"); - strcpy(powernv_states[nr_idle_states].desc, "Nap"); - powernv_states[nr_idle_states].flags = 0; - powernv_states[nr_idle_states].target_residency = 100; - powernv_states[nr_idle_states].enter = nap_loop; + add_powernv_state(nr_idle_states, "Nap", + CPUIDLE_FLAG_NONE, nap_loop, + target_residency, exit_latency, 0); } else if ((flags[i] & OPAL_PM_STOP_INST_FAST) && !(flags[i] & OPAL_PM_TIMEBASE_STOP)) { - strncpy(powernv_states[nr_idle_states].name, - names[i], CPUIDLE_NAME_LEN); - strncpy(powernv_states[nr_idle_states].desc, - names[i], CPUIDLE_NAME_LEN); - powernv_states[nr_idle_states].flags = 0; - - powernv_states[nr_idle_states].enter = stop_loop; - stop_psscr_table[nr_idle_states] = psscr_val[i]; + add_powernv_state(nr_idle_states, names[i], + CPUIDLE_FLAG_NONE, stop_loop, + target_residency, exit_latency, + psscr_val[i]); } /* @@ -274,32 +300,20 @@ static int powernv_add_idle_states(void) #ifdef CONFIG_TICK_ONESHOT if (flags[i] & OPAL_PM_SLEEP_ENABLED || flags[i] & OPAL_PM_SLEEP_ENABLED_ER1) { + target_residency = 30; /* Add FASTSLEEP state */ -
[PATCH v2 3/3] powernv: Pass PSSCR value and mask to power9_idle_stop
From: "Gautham R. Shenoy" The power9_idle_stop method currently takes only the requested stop level as a parameter and picks up the rest of the PSSCR bits from a hand-coded macro. This is not a very flexible design, especially when the firmware has the capability to communicate the psscr value and the mask associated with a particular stop state via device tree. This patch modifies the power9_idle_stop API to take as parameters the PSSCR value and the PSSCR mask corresponding to the stop state that needs to be set. These PSSCR value and mask are respectively obtained by parsing the "ibm,cpu-idle-state-psscr" and "ibm,cpu-idle-state-psscr-mask" fields from the device tree. In addition to this, the patch adds support for handling stop states for which ESL and EC bits in the PSSCR are zero. As per the architecture, a wakeup from these stop states resumes execution from the subsequent instruction as opposed to waking up at the System Vector. The older firmware sets only the Requested Level (RL) field in the psscr and psscr-mask exposed in the device tree. For older firmware where psscr-mask=0xf, this patch will set the default sane values that the set for for remaining PSSCR fields (i.e PSLL, MTL, ESL, EC, and TR). This skiboot patch that exports fully populated PSSCR values and the mask for all the stop states can be found here: https://lists.ozlabs.org/pipermail/skiboot/2016-September/004869.html Signed-off-by: Gautham R. Shenoy --- arch/powerpc/include/asm/cpuidle.h | 37 +++ arch/powerpc/include/asm/processor.h | 3 +- arch/powerpc/kernel/idle_book3s.S| 31 +++- arch/powerpc/platforms/powernv/idle.c| 81 ++-- arch/powerpc/platforms/powernv/powernv.h | 3 +- arch/powerpc/platforms/powernv/smp.c | 14 +++--- drivers/cpuidle/cpuidle-powernv.c| 40 +++- 7 files changed, 165 insertions(+), 44 deletions(-) diff --git a/arch/powerpc/include/asm/cpuidle.h b/arch/powerpc/include/asm/cpuidle.h index 0a3255b..41b5d27 100644 --- a/arch/powerpc/include/asm/cpuidle.h +++ b/arch/powerpc/include/asm/cpuidle.h @@ -10,11 +10,48 @@ #define PNV_CORE_IDLE_LOCK_BIT 0x100 #define PNV_CORE_IDLE_THREAD_BITS 0x0FF +/* + * By default we set the ESL and EC bits in the PSSCR. + * + * The MTL and PSLL are set to the maximum value possible as per the + * ISA, i.e 15. + * + * The Transition Rate is set to the Maximum value 3. + */ +#define PSSCR_HV_DEFAULT_VAL(PSSCR_ESL | PSSCR_EC |\ + PSSCR_PSLL_MASK | PSSCR_TR_MASK | \ + PSSCR_MTL_MASK) + +#define PSSCR_HV_DEFAULT_MASK (PSSCR_ESL | PSSCR_EC |\ + PSSCR_PSLL_MASK | PSSCR_TR_MASK | \ + PSSCR_MTL_MASK | PSSCR_RL_MASK) + #ifndef __ASSEMBLY__ extern u32 pnv_fastsleep_workaround_at_entry[]; extern u32 pnv_fastsleep_workaround_at_exit[]; extern u64 pnv_first_deep_stop_state; + +/* + * Older firmware only populates the RL field in psscr_val and + * psscr_mask. + * + * Set the remaining fields to the default value in case of the + * older firmware. + */ +static inline u64 compute_psscr_val(u64 psscr_val, u64 psscr_mask) +{ + if (psscr_mask == 0xf) + return psscr_val | PSSCR_HV_DEFAULT_VAL; + return psscr_val; +} + +static inline u64 compute_psscr_mask(u64 psscr_mask) +{ + if (psscr_mask == 0xf) + return PSSCR_HV_DEFAULT_MASK; + return psscr_mask; +} #endif #endif diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index c07c31b..422becd 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -458,7 +458,8 @@ static inline unsigned long get_clean_sp(unsigned long sp, int is_32) extern unsigned long power7_nap(int check_irq); extern unsigned long power7_sleep(void); extern unsigned long power7_winkle(void); -extern unsigned long power9_idle_stop(unsigned long stop_level); +extern unsigned long power9_idle_stop(unsigned long stop_psscr_val, + unsigned long stop_psscr_mask); extern void flush_instruction_cache(void); extern void hard_reset_now(void); diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index be90e2f..37ee533 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -40,9 +40,7 @@ #define _WORC GPR11 #define _PTCR GPR12 -#define PSSCR_HV_TEMPLATE PSSCR_ESL | PSSCR_EC | \ - PSSCR_PSLL_MASK | PSSCR_TR_MASK | \ - PSSCR_MTL_MASK +#define PSSCR_EC_ESL_MASK_SHIFTED (PSSCR_EC | PSSCR_ESL) >> 16 .text @@ -264,7 +262,7 @@ enter_winkle: IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE) /* - * r3 - requested stop state + * r3 - PSSCR value corresponding to the requested s
Re: [PATCH 2/2] powerpc/kvm: Update kvmppc_set_arch_compat() for ISA v3.00
Suraj Jitindar Singh writes: > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c > index 3686471..f9ae3fb 100644 > --- a/arch/powerpc/kvm/book3s_hv.c > +++ b/arch/powerpc/kvm/book3s_hv.c > @@ -311,24 +311,38 @@ static int kvmppc_set_arch_compat(struct kvm_vcpu > *vcpu, u32 arch_compat) >* If an arch bit is set in PCR, all the defined >* higher-order arch bits also have to be set. >*/ > - pcr = PCR_ARCH_206 | PCR_ARCH_205; > + pcr = PCR_ARCH_207 | PCR_ARCH_206 | PCR_ARCH_205; > break; > case PVR_ARCH_206: > case PVR_ARCH_206p: > - pcr = PCR_ARCH_206; > + /* Must be at least v2.06 to emulate it */ > + if (!cpu_has_feature(CPU_FTR_ARCH_206)) > + return -EINVAL; > + pcr = PCR_ARCH_207 | PCR_ARCH_206; > break; > case PVR_ARCH_207: > + /* Must be at least v2.07 to emulate it */ > + if (!cpu_has_feature(CPU_FTR_ARCH_207S)) > + return -EINVAL; > + pcr = PCR_ARCH_207; > break; > + case PVR_ARCH_300: > + /* Must be at least v3.00 to emulate it */ > + if (!cpu_has_feature(CPU_FTR_ARCH_300)) > + return -EINVAL; > default: > return -EINVAL; > } > > - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) { > - /* POWER7 can't emulate POWER8 */ > - if (!(pcr & PCR_ARCH_206)) > - return -EINVAL; > - pcr &= ~PCR_ARCH_206; > - } > + /* > + * Mask the pcr bits which the current processor knows about > + * v2.06 and above knows about the v2.05 compat bit > + * v2,07 and above knows about the v2.06 compat bit > + * v3.00 and above knows about the v2.07 compat bit > + */ > + pcr &= (cpu_has_feature(CPU_FTR_ARCH_300) << 3) | > + (cpu_has_feature(CPU_FTR_ARCH_207S) << 2) | > + (cpu_has_feature(CPU_FTR_ARCH_206) << 1); cpu_has_feature() returns a bool, so shifting the result of it is dubious. It also uses jump labels these days, so I have no idea what code that is going to generate. Better to just do it the simple way IMHO. cheers
Re: powerpc/64s: relocation, register save fixes for system reset interrupt
On Thu, 2016-13-10 at 02:17:14 UTC, Nicholas Piggin wrote: > This patch does a couple of things. First of all, powernv immediately > explodes when running a relocated kernel, because the system reset > exception for handling sleeps does not do correct relocated branches. > > Secondly, the sleep handling code trashes the condition and cfar > registers, which we would like to preserve for debugging purposes (for > non-sleep case exception). > > This patch changes the exception to use the standard format that saves > registers before any tests or branches are made. It adds the test for > idle-wakeup as an "extra" to break out of the normal exception path. > Then it branches to a relocated idle handler that calls the various > idle handling functions. > > After this patch, POWER8 CPU simulator now boots powernv kernel that is > running at non-zero. > > Cc: Balbir Singh > Cc: Shreyas B. Prabhu > Cc: Gautham R. Shenoy > Signed-off-by: Nicholas Piggin > Acked-by: Gautham R. Shenoy > Acked-by: Balbir Singh Applied to powerpc fixes, thanks. https://git.kernel.org/powerpc/c/fb479e44a9e240a23c2d208c2ace23 cheers
Re: powerpc/mm: Use tlbiel only if we ever ran on the current cpu
On Mon, 2016-24-10 at 03:20:43 UTC, "Aneesh Kumar K.V" wrote: > Before this patch, we used tlbiel, if we ever ran only on this core. > That was mostly derived from the nohash usage of the same. But the > ISA 3.0 clarifies tlbiel such that > > "All TLB entries that have all of the following properties are made > invalid on the thread executing the tlbiel instruction" > > Hence use tlbiel, if we only ever ran on just the current cpu. > > Signed-off-by: Aneesh Kumar K.V Applied to powerpc fixes, thanks. https://git.kernel.org/powerpc/c/bd77c4498616e27d5725b5959d880c cheers
Re: [PATCH v6 1/3] powerpc/pseries: Correct possible read beyond dlpar sysfs buffer
On 10/18/2016 12:20 PM, Nathan Fontenot wrote: > The pasrsing of data written to the dlpar file in sysfs does not correctly > account for the possibility of reading past the end of the buffer. Correct > this by updating the buffer parsing code to make a local copy and use the > strsep() and sysfs_streq() routines to parse the buffer. This also > separates the parsing code into subroutines to make cleaner. > > Signed-off-by: Nathan Fontenot > --- Reviewed-by: John Allen
Re: [PATCH v6 3/3] powerpc/pseries: Implement indexed-count hotplug memory remove
On 10/18/2016 12:21 PM, Nathan Fontenot wrote: > From: Sahil Mehta > > Indexed-count remove for memory hotplug guarantees that a contiguous block > of lmbs beginning at a specified will be unassigned (NOT > that lmbs will be removed). Because of Qemu's per-DIMM memory > management, the removal of a contiguous block of memory currently > requires a series of individual calls. Indexed-count remove reduces > this series into a single call. > > Signed-off-by: Sahil Mehta > Signed-off-by: Nathan Fontenot > --- Reviewed-by: John Allen
Re: [PATCH v6 2/3] powerpc/pseries: Implement indexed-count hotplug memory add
On 10/18/2016 12:20 PM, Nathan Fontenot wrote: > From: Sahil Mehta > > Indexed-count add for memory hotplug guarantees that a contiguous block > of lmbs beginning at a specified will be assigned (NOT > that lmbs will be added). Because of Qemu's per-DIMM memory > management, the addition of a contiguous block of memory currently > requires a series of individual calls. Indexed-count add reduces > this series into a single call. > > Signed-off-by: Sahil Mehta > Signed-off-by: Nathan Fontenot > --- Reviewed-by: John Allen
[PATCH V8 2/8] powerpc/memory: Parse new memory property to register blocks.
powerpc/memory: Add parallel routines to parse the new property "ibm,dynamic-memory-v2" property when it is present, and then to register the relevant memory blocks with the operating system. This property format is intended to provide a more compact representation of memory when communicating with the front end processor, especially when describing vast amounts of RAM. [V2: Revise contant names.] [V3: Fix error parsing the new memory block sets.] [V4: Move a couple of function prototypes from header file a later patch where first used. Amend some comments. Change a firmware architure vec check for scan actual device tree. Compress some common code.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/include/asm/prom.h | 24 -- arch/powerpc/kernel/prom.c | 97 --- arch/powerpc/mm/numa.c | 22 - 3 files changed, 129 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index bc7c4b5..43a002b 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -69,6 +69,8 @@ struct boot_param_header { * OF address retreival & translation */ +extern int n_mem_addr_cells; + /* Parse the ibm,dma-window property of an OF node into the busno, phys and * size parameters. */ @@ -81,8 +83,9 @@ extern void of_instantiate_rtc(void); extern int of_get_ibm_chip_id(struct device_node *np); /* The of_drconf_cell struct defines the layout of the LMB array - * specified in the device tree property - * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory + * specified in the device tree properties, + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory-v2 */ struct of_drconf_cell { u64 base_addr; @@ -92,9 +95,20 @@ struct of_drconf_cell { u32 flags; }; -#define DRCONF_MEM_ASSIGNED0x0008 -#define DRCONF_MEM_AI_INVALID 0x0040 -#define DRCONF_MEM_RESERVED0x0080 +#define DRCONF_MEM_ASSIGNED0x0008 +#define DRCONF_MEM_AI_INVALID 0x0040 +#define DRCONF_MEM_RESERVED0x0080 + +struct of_drconf_cell_v2 { + u32 num_seq_lmbs; + u64 base_addr; + u32 drc_index; + u32 aa_index; + u32 flags; +} __attribute__((packed)); + +extern void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem, + const __be32 **cellp); /* * There are two methods for telling firmware what our capabilities are. diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index b0245be..2d49887 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -443,23 +443,34 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node, #ifdef CONFIG_PPC_PSERIES /* - * Interpret the ibm,dynamic-memory property in the - * /ibm,dynamic-reconfiguration-memory node. + * Retrieve and validate the ibm,lmb-size property for drconf memory + * from the flattened device tree. + */ +static u64 __init get_lmb_size(unsigned long node) +{ + const __be32 *ls; + int len; + ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &len); + if (!ls || len < dt_root_size_cells * sizeof(__be32)) + return 0; + return dt_mem_next_cell(dt_root_size_cells, &ls); +} + +/* + * Interpret the ibm,dynamic-memory property/ibm,dynamic-memory-v2 + * in the /ibm,dynamic-reconfiguration-memory node. * This contains a list of memory blocks along with NUMA affinity * information. */ -static int __init early_init_dt_scan_drconf_memory(unsigned long node) +static int __init early_init_dt_scan_drconf_memory_v1(unsigned long node) { - const __be32 *dm, *ls, *usm; + const __be32 *dm, *usm; int l; unsigned long n, flags; u64 base, size, memblock_size; unsigned int is_kexec_kdump = 0, rngs; - ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l); - if (ls == NULL || l < dt_root_size_cells * sizeof(__be32)) - return 0; - memblock_size = dt_mem_next_cell(dt_root_size_cells, &ls); + memblock_size = get_lmb_size(node); dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l); if (dm == NULL || l < sizeof(__be32)) @@ -518,6 +529,76 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node) memblock_dump_all(); return 0; } + +static int __init early_init_dt_scan_drconf_memory_v2(unsigned long node) +{ + const __be32 *dm; + int l; + unsigned long num_sets; + u64 size, base, memblock_size; + + memblock_size = get_lmb_size(node); + + dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory-v2", &l); + if (dm == NULL || l < sizeof(__be32)) +
[PATCH V8 6/8] hotplug/drc-info: Add code to search new devtree properties
rpadlpar_core.c: Provide parallel routines to search the older device- tree properties ("ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains"), or the new property "ibm,drc-info". The interface to examine the DRC information is changed from a "get" function that returns values for local verification elsewhere, to a "check" function that validates the 'name' and/or 'type' of a device node. This update hides the format of the underlying device-tree properties, and concentrates the value checks into a single function without requiring the user to verify whether a search was successful. [V2: Revise contant names.] [V3: Amend comments. Simplify code cleanup.] [V4: Update comments.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- drivers/pci/hotplug/rpadlpar_core.c | 13 ++-- drivers/pci/hotplug/rpaphp.h|4 + drivers/pci/hotplug/rpaphp_core.c | 109 +++ 3 files changed, 91 insertions(+), 35 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index dc67f39..bea9723 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "../pci.h" #include "rpaphp.h" @@ -44,15 +45,14 @@ static struct device_node *find_vio_slot_node(char *drc_name) { struct device_node *parent = of_find_node_by_name(NULL, "vdevice"); struct device_node *dn = NULL; - char *name; int rc; if (!parent) return NULL; while ((dn = of_get_next_child(parent, dn))) { - rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL); - if ((rc == 0) && (!strcmp(drc_name, name))) + rc = rpaphp_check_drc_props(dn, drc_name, NULL); + if (rc == 0) break; } @@ -64,15 +64,12 @@ static struct device_node *find_php_slot_pci_node(char *drc_name, char *drc_type) { struct device_node *np = NULL; - char *name; - char *type; int rc; while ((np = of_find_node_by_name(np, "pci"))) { - rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL); + rc = rpaphp_check_drc_props(np, drc_name, drc_type); if (rc == 0) - if (!strcmp(drc_name, name) && !strcmp(drc_type, type)) - break; + break; } return np; diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 7db024e..8db5f2e 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -91,8 +91,8 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ int rpaphp_add_slot(struct device_node *dn); -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, - char **drc_name, char **drc_type, int *drc_power_domain); +int rpaphp_check_drc_props(struct device_node *dn, char *drc_name, + char *drc_type); /* rpaphp_slot.c */ void dealloc_slot_struct(struct slot *slot); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 8d13202..85ad2ae 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -30,6 +30,7 @@ #include #include #include +#include #include/* for eeh_add_device() */ #include /* rtas_call */ #include /* for pci_controller */ @@ -196,25 +197,21 @@ static int get_children_props(struct device_node *dn, const int **drc_indexes, return 0; } -/* To get the DRC props describing the current node, first obtain it's - * my-drc-index property. Next obtain the DRC list from it's parent. Use - * the my-drc-index for correlation, and obtain the requested properties. + +/* Verify the existence of 'drc_name' and/or 'drc_type' within the + * current node. First obtain it's my-drc-index property. Next, + * obtain the DRC info from it's parent. Use the my-drc-index for + * correlation, and obtain/validate the requested properties. */ -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, - char **drc_name, char **drc_type, int *drc_power_domain) + +static int rpaphp_check_drc_props_v1(struct device_node *dn, char *drc_name, + char *drc_type, unsigned int my_index) { + char *name_tmp, *type_tmp; const int *indexes, *names; const int *types, *domains; - const unsigned int *my_index; - char *name_tmp, *type_tmp; int i, rc; - my_index = of_get_property(dn, "ibm,my-drc-index", NULL); - if (!my_index) { - /* Node isn't DLPAR/hotplug capable */ - return -EINVAL; - } -
[PATCH V8 1/8] powerpc/firmware: Add definitions for new firmware features.
Firmware Features: Define new bit flags representing the presence of new device tree properties "ibm,drc-info", and "ibm,dynamic-memory-v2". These flags are used to tell the front end processor when the Linux kernel supports the new properties, and by the front end processor to tell the Linux kernel that the new properties are present in the devie tree. [V2: Revise constant names for improved clarity.] [V3: Fix comments] [V4: Fix some spacing] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h |2 ++ arch/powerpc/platforms/pseries/firmware.c |2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 1e0b5a5..6b5cf38 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -51,6 +51,8 @@ #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x8000) #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0001) #define FW_FEATURE_PRRNASM_CONST(0x0002) +#define FW_FEATURE_DYN_MEM_V2 ASM_CONST(0x0004) +#define FW_FEATURE_DRC_INFOASM_CONST(0x0008) #ifndef __ASSEMBLY__ @@ -66,7 +68,8 @@ enum { FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO | FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | - FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, + FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN | + FW_FEATURE_DYN_MEM_V2 | FW_FEATURE_DRC_INFO, FW_FEATURE_PSERIES_ALWAYS = 0, FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL, FW_FEATURE_POWERNV_ALWAYS = 0, diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 7f436ba..bc7c4b5 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -155,6 +155,8 @@ struct of_drconf_cell { #define OV5_PFO_HW_842 0x0E40 /* PFO Compression Accelerator */ #define OV5_PFO_HW_ENCR0x0E20 /* PFO Encryption Accelerator */ #define OV5_SUB_PROCESSORS 0x0F01 /* 1,2,or 4 Sub-Processors supported */ +#define OV5_DYN_MEM_V2 0x1680 /* Redef Prop Structures: dyn-mem-v2 */ +#define OV5_DRC_INFO 0x1640 /* Redef Prop Structures: drc-info */ /* Option Vector 6: IBM PAPR hints */ #define OV6_LINUX 0x02/* Linux is our OS */ diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index ea7f09b..d2d23f5 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c @@ -113,6 +113,8 @@ static __initdata struct vec5_fw_feature vec5_fw_features_table[] = { {FW_FEATURE_TYPE1_AFFINITY, OV5_TYPE1_AFFINITY}, {FW_FEATURE_PRRN, OV5_PRRN}, + {FW_FEATURE_DYN_MEM_V2, OV5_DYN_MEM_V2}, + {FW_FEATURE_DRC_INFO, OV5_DRC_INFO}, }; static void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
[PATCH V8 5/8] pseries/drc-info: Search new DRC properties for CPU indexes
pseries/drc-info: Provide parallel routines to convert between drc_index and CPU numbers at runtime, using the older device-tree properties ("ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains"), or the new property "ibm,drc-info". [V2: Revise contant names.] [V3: No change.] [V4: No change.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- 1 file changed, 165 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c index 164a13d..05fb5e8 100644 --- a/arch/powerpc/platforms/pseries/pseries_energy.c +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -35,10 +35,73 @@ static int sysfs_entries; /* Helper Routines to convert between drc_index to cpu numbers */ +void read_one_drc_info(int **info, char **dtype, char **dname, + unsigned long int *drc_index_start_p, + unsigned long int *num_sequential_elems_p, + unsigned long int *sequential_inc_p, + unsigned long int *last_drc_index_p) +{ + char *drc_type, *drc_name_prefix, *pc; + u32 drc_index_start, num_sequential_elems; + u32 sequential_inc, last_drc_index; + + drc_index_start = num_sequential_elems = 0; + sequential_inc = last_drc_index = 0; + + /* Get drc-type:encode-string */ + pc = (char *)info; + drc_type = pc; + pc += (strlen(drc_type) + 1); + + /* Get drc-name-prefix:encode-string */ + drc_name_prefix = (char *)pc; + pc += (strlen(drc_name_prefix) + 1); + + /* Get drc-index-start:encode-int */ + memcpy(&drc_index_start, pc, 4); + drc_index_start = be32_to_cpu(drc_index_start); + pc += 4; + + /* Get/skip drc-name-suffix-start:encode-int */ + pc += 4; + + /* Get number-sequential-elements:encode-int */ + memcpy(&num_sequential_elems, pc, 4); + num_sequential_elems = be32_to_cpu(num_sequential_elems); + pc += 4; + + /* Get sequential-increment:encode-int */ + memcpy(&sequential_inc, pc, 4); + sequential_inc = be32_to_cpu(sequential_inc); + pc += 4; + + /* Get/skip drc-power-domain:encode-int */ + pc += 4; + + /* Should now know end of current entry */ + last_drc_index = drc_index_start + + ((num_sequential_elems-1)*sequential_inc); + + (*info) = (int *)pc; + + if (dtype) + *dtype = drc_type; + if (dname) + *dname = drc_name_prefix; + if (drc_index_start_p) + *drc_index_start_p = drc_index_start; + if (num_sequential_elems_p) + *num_sequential_elems_p = num_sequential_elems; + if (sequential_inc_p) + *sequential_inc_p = sequential_inc; + if (last_drc_index_p) + *last_drc_index_p = last_drc_index; +} +EXPORT_SYMBOL(read_one_drc_info); + static u32 cpu_to_drc_index(int cpu) { struct device_node *dn = NULL; - const int *indexes; int i; int rc = 1; u32 ret = 0; @@ -46,18 +109,60 @@ static u32 cpu_to_drc_index(int cpu) dn = of_find_node_by_path("/cpus"); if (dn == NULL) goto err; - indexes = of_get_property(dn, "ibm,drc-indexes", NULL); - if (indexes == NULL) - goto err_of_node_put; + /* Convert logical cpu number to core number */ i = cpu_core_index_of_thread(cpu); - /* -* The first element indexes[0] is the number of drc_indexes -* returned in the list. Hence i+1 will get the drc_index -* corresponding to core number i. -*/ - WARN_ON(i > indexes[0]); - ret = indexes[i + 1]; + + if (firmware_has_feature(FW_FEATURE_DRC_INFO)) { + int *info = (int *)4; + unsigned long int num_set_entries, j, check_val = i; + unsigned long int drc_index_start = 0; + unsigned long int last_drc_index = 0; + unsigned long int num_sequential_elems = 0; + unsigned long int sequential_inc = 0; + char *dtype; + char *dname; + + info = (int *)of_get_property(dn, "ibm,drc-info", NULL); + if (info == NULL) + goto err_of_node_put; + + num_set_entries = be32_to_cpu(*info++); + + for (j = 0; j < num_set_entries; j++) { + + read_one_drc_info(&info, &dtype, &dname, + &drc_index_start, + &num_sequential_elems, + &sequential_inc, &last_drc_index); + if (strcmp(dtype, "CPU")) +
[PATCH V8 3/8] powerpc/memory: Parse new memory property to initialize structures.
powerpc/memory: Add parallel routines to parse the new property "ibm,dynamic-memory-v2" property when it is present, and then to finish initialization of the relevant memory structures with the operating system. This code is shared between the boot-time initialization functions and the runtime functions for memory hotplug, so it needs to be able to handle both formats. [V2: Revise contant names.] [V3: Fix loop that needed to scan all blocks defined by new, compressed memory definition. [V4: Added external function prototype definitions to header file "prom.h" for use in other files. Change a firmware architure vec check for scan actual device tree. Delete an unused variable. Small cleanups to comments.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/include/asm/prom.h | 12 +++ arch/powerpc/mm/numa.c | 146 +-- 2 files changed, 135 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 43a002b..7907c38 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -110,6 +110,18 @@ struct of_drconf_cell_v2 { extern void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem, const __be32 **cellp); +extern void read_one_drc_info(int **info, char **drc_type, char **drc_name, + unsigned long int *fdi_p, unsigned long int *nsl_p, + unsigned long int *si_p, unsigned long int *ldi_p); + +static inline int dyn_mem_v2_len(int entries) +{ + int drconf_v2_cells = (n_mem_addr_cells + 4); + int drconf_v2_cells_len = (drconf_v2_cells * sizeof(unsigned int)); + return (((entries) * drconf_v2_cells_len) + +(1 * sizeof(unsigned int))); +} + /* * There are two methods for telling firmware what our capabilities are. * Newer machines have an "ibm,client-architecture-support" method on the diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index fe8e6e7..d3cf353 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -427,30 +427,55 @@ void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem, const __be32 **cellp) EXPORT_SYMBOL(read_drconf_cell_v2); /* - * Retrieve and validate the ibm,dynamic-memory property of the device tree. + * Retrieve and validate the ibm,dynamic-memory[-v2] property of the + * device tree. + * + * The layout of the ibm,dynamic-memory property is a number N of memory + * block description list entries followed by N memory block description + * list entries. Each memory block description list entry contains + * information as laid out in the of_drconf_cell struct above. * - * The layout of the ibm,dynamic-memory property is a number N of memblock - * list entries followed by N memblock list entries. Each memblock list entry - * contains information as laid out in the of_drconf_cell struct above. + * The layout of the ibm,dynamic-memory-v2 property is a number N of memory + * block set description list entries, followed by N memory block set + * description set entries. */ static int of_get_drconf_memory(struct device_node *memory, const __be32 **dm) { const __be32 *prop; u32 len, entries; - prop = of_get_property(memory, "ibm,dynamic-memory", &len); - if (!prop || len < sizeof(unsigned int)) - return 0; + if (firmware_has_feature(FW_FEATURE_DYN_MEM_V2)) { - entries = of_read_number(prop++, 1); + prop = of_get_property(memory, "ibm,dynamic-memory-v2", &len); + if (!prop || len < sizeof(unsigned int)) + return 0; - /* Now that we know the number of entries, revalidate the size -* of the property read in to ensure we have everything -*/ - if (len < (entries * (n_mem_addr_cells + 4) + 1) * sizeof(unsigned int)) - return 0; + entries = of_read_number(prop++, 1); + + /* Now that we know the number of set entries, revalidate the +* size of the property read in to ensure we have everything. +*/ + if (len < dyn_mem_v2_len(entries)) + return 0; + + *dm = prop; + } else { + prop = of_get_property(memory, "ibm,dynamic-memory", &len); + if (!prop || len < sizeof(unsigned int)) + return 0; + + entries = of_read_number(prop++, 1); + + /* Now that we know the number of entries, revalidate the size +* of the property read in to ensure we have everything +*/ + if (len < (entries * (n_mem_addr_cells + 4) + 1) * + sizeof(unsigned int)) + return 0; + + *dm =
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-)
[PATCH V8 4/8] pseries/hotplug init: Convert new DRC memory property for hotplug runtime
hotplug_init: Simplify the code needed for runtime memory hotplug and maintenance with a conversion routine that transforms the compressed property "ibm,dynamic-memory-v2" to the form of "ibm,dynamic-memory" within the "ibm,dynamic-reconfiguration-memory" property. Thus only a single set of routines should be required at runtime to parse, edit, and manipulate the memory representation in the device tree. Similarly, any userspace applications that need this information will only need to recognize the older format to be able to continue to operate. [V2: Revise contant names.] [V3: Replace use of in-code compile flag encompassing file by Makefile mod.] [V4: Remove unneeded code braces. Simplify allocation of a couple of loop index variables.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/Makefile |4 - arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index fedc2ccf0..e74cf6c 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -5,14 +5,14 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \ of_helpers.o \ setup.o iommu.o event_sources.o ras.o \ firmware.o power.o dlpar.o mobility.o rng.o \ - pci.o pci_dlpar.o eeh_pseries.o msi.o + pci.o pci_dlpar.o eeh_pseries.o msi.o \ + hotplug-memory.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_KEXEC)+= kexec.o obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o -obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 76ec104..461f883 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -24,6 +24,8 @@ #include #include "pseries.h" +#ifdef CONFIG_MEMORY_HOTPLUG + static bool rtas_hp_event; unsigned long pseries_memory_block_size(void) @@ -887,11 +889,102 @@ static int pseries_memory_notifier(struct notifier_block *nb, static struct notifier_block pseries_mem_nb = { .notifier_call = pseries_memory_notifier, }; +#endif /* CONFIG_MEMORY_HOTPLUG */ + +static int pseries_rewrite_dynamic_memory_v2(void) +{ + unsigned long memblock_size; + struct device_node *dn; + struct property *prop, *prop_v2; + __be32 *p; + struct of_drconf_cell *lmbs; + u32 num_lmb_desc_sets, num_lmbs; + int i, j, k; + + dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (!dn) + return -EINVAL; + + prop_v2 = of_find_property(dn, "ibm,dynamic-memory-v2", NULL); + if (!prop_v2) + return -EINVAL; + + memblock_size = pseries_memory_block_size(); + if (!memblock_size) + return -EINVAL; + + /* The first int of the property is the number of lmb sets +* described by the property. +*/ + p = (__be32 *)prop_v2->value; + num_lmb_desc_sets = be32_to_cpu(*p++); + + /* Count the number of LMBs for generating the alternate format +*/ + for (i = 0, num_lmbs = 0; i < num_lmb_desc_sets; i++) { + struct of_drconf_cell_v2 drmem; + + read_drconf_cell_v2(&drmem, (const __be32 **)&p); + num_lmbs += drmem.num_seq_lmbs; + } + + /* Create an empty copy of the new 'ibm,dynamic-memory' property +*/ + prop = kzalloc(sizeof(*prop), GFP_KERNEL); + if (!prop) + return -ENOMEM; + prop->name = kstrdup("ibm,dynamic-memory", GFP_KERNEL); + prop->length = dyn_mem_v2_len(num_lmbs); + prop->value = kzalloc(prop->length, GFP_KERNEL); + + /* Copy/expand the ibm,dynamic-memory-v2 format to produce the +* ibm,dynamic-memory format. +*/ + p = (__be32 *)prop->value; + *p = cpu_to_be32(num_lmbs); + p++; + lmbs = (struct of_drconf_cell *)p; + + p = (__be32 *)prop_v2->value; + p++; + + for (i = 0, k = 0; i < num_lmb_desc_sets; i++) { + struct of_drconf_cell_v2 drmem; + + read_drconf_cell_v2(&drmem, (const __be32 **)&p); + + for (j = 0; j < drmem.num_seq_lmbs; j++) { + lmbs[k+j].base_addr = be64_to_cpu(drmem.base_addr); + lmbs[k+j].drc_index = be32_to_cpu(drmem.drc_index); +
[PATCH V8 7/8] powerpc: Check arch.vec earlier during boot for memory features
architecture.vec5 features: The boot-time memory management needs to know the form of the "ibm,dynamic-memory-v2" property early during scanning of the flattened device tree. This patch moves execution of the function pseries_probe_fw_features() early enough to be before the scanning of the memory properties in the device tree to allow recognition of the supported properties. [V2: No change] [V3: Updated after commit 3808a88985b4f5f5e947c364debce4441a380fb8.] [V4: Update comments] [V5: Resynchronize/resubmit] [V6: Resync to v4.7 kernel code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/kernel/prom.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 2d49887..bd07157 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -759,6 +759,9 @@ void __init early_init_devtree(void *params) */ of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line); + /* Now try to figure out if we are running on LPAR and so on */ + pseries_probe_fw_features(); + /* Scan memory nodes and rebuild MEMBLOCKs */ of_scan_flat_dt(early_init_dt_scan_root, NULL); of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); @@ -826,9 +829,6 @@ void __init early_init_devtree(void *params) #endif epapr_paravirt_early_init(); - /* Now try to figure out if we are running on LPAR and so on */ - pseries_probe_fw_features(); - #ifdef CONFIG_PPC_PS3 /* Identify PS3 firmware */ if (of_flat_dt_is_compatible(of_get_flat_dt_root(), "sony,ps3"))
Re: [PATCH net-next] ibmveth: v1 calculate correct gso_size and set gso_type
On 10/25/2016 07:09 PM, Jon Maxwell wrote: > We recently encountered a bug where a few customers using ibmveth on the > same LPAR hit an issue where a TCP session hung when large receive was > enabled. Closer analysis revealed that the session was stuck because the > one side was advertising a zero window repeatedly. > > We narrowed this down to the fact the ibmveth driver did not set gso_size > which is translated by TCP into the MSS later up the stack. The MSS is > used to calculate the TCP window size and as that was abnormally large, > it was calculating a zero window, even although the sockets receive buffer > was completely empty. > > We were able to reproduce this and worked with IBM to fix this. Thanks Tom > and Marcelo for all your help and review on this. > > The patch fixes both our internal reproduction tests and our customers tests. > > Signed-off-by: Jon Maxwell Thanks, Jon. Acked-by: Thomas Falcon > --- > drivers/net/ethernet/ibm/ibmveth.c | 20 > 1 file changed, 20 insertions(+) > > diff --git a/drivers/net/ethernet/ibm/ibmveth.c > b/drivers/net/ethernet/ibm/ibmveth.c > index 29c05d0..c51717e 100644 > --- a/drivers/net/ethernet/ibm/ibmveth.c > +++ b/drivers/net/ethernet/ibm/ibmveth.c > @@ -1182,6 +1182,8 @@ static int ibmveth_poll(struct napi_struct *napi, int > budget) > int frames_processed = 0; > unsigned long lpar_rc; > struct iphdr *iph; > + bool large_packet = 0; > + u16 hdr_len = ETH_HLEN + sizeof(struct tcphdr); > > restart_poll: > while (frames_processed < budget) { > @@ -1236,10 +1238,28 @@ static int ibmveth_poll(struct napi_struct *napi, int > budget) > iph->check = 0; > iph->check = > ip_fast_csum((unsigned char *)iph, iph->ihl); > adapter->rx_large_packets++; > + large_packet = 1; > } > } > } > > + if (skb->len > netdev->mtu) { > + iph = (struct iphdr *)skb->data; > + if (be16_to_cpu(skb->protocol) == ETH_P_IP && > + iph->protocol == IPPROTO_TCP) { > + hdr_len += sizeof(struct iphdr); > + skb_shinfo(skb)->gso_type = > SKB_GSO_TCPV4; > + skb_shinfo(skb)->gso_size = netdev->mtu > - hdr_len; > + } else if (be16_to_cpu(skb->protocol) == > ETH_P_IPV6 && > +iph->protocol == IPPROTO_TCP) { > + hdr_len += sizeof(struct ipv6hdr); > + skb_shinfo(skb)->gso_type = > SKB_GSO_TCPV6; > + skb_shinfo(skb)->gso_size = netdev->mtu > - hdr_len; > + } > + if (!large_packet) > + adapter->rx_large_packets++; > + } > + > napi_gro_receive(napi, skb);/* send it up */ > > netdev->stats.rx_packets++;
[PATCH V8 8/8] powerpc: Enable support for new DRC devtree properties
prom_init.c: Enable support for new DRC device tree properties "ibm,drc-info" and "ibm,dynamic-memory-v2" in initial handshake between the Linux kernel and the front end processor. [V2: Revise constant names.] [V3: No change.] [V4: Update comments] [V5: Resynchronize/resubmit] [V6: Resynchronize to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/kernel/prom_init.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d3eff99..28a5ea2 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -695,7 +695,7 @@ unsigned char ibm_architecture_vec[] = { OV4_MIN_ENT_CAP,/* minimum VP entitled capacity */ /* option vector 5: PAPR/OF options */ - VECTOR_LENGTH(21), /* length */ + VECTOR_LENGTH(22), /* length */ 0, /* don't ignore, don't halt */ OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) | OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) | @@ -731,6 +731,7 @@ unsigned char ibm_architecture_vec[] = { 0, /* Byte 19 */ 0, /* Byte 20 */ OV5_FEAT(OV5_SUB_PROCESSORS), /* Byte 21 */ + OV5_FEAT(OV5_DYN_MEM_V2) | OV5_FEAT(OV5_DRC_INFO), /* Byte 22 */ /* option vector 6: IBM PAPR hints */ VECTOR_LENGTH(3), /* length */
[PATCH V8 5/8] pseries/drc-info: Search new DRC properties for CPU indexes
pseries/drc-info: Provide parallel routines to convert between drc_index and CPU numbers at runtime, using the older device-tree properties ("ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains"), or the new property "ibm,drc-info". [V2: Revise contant names.] [V3: No change.] [V4: No change.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- 1 file changed, 165 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c index 164a13d..05fb5e8 100644 --- a/arch/powerpc/platforms/pseries/pseries_energy.c +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -35,10 +35,73 @@ static int sysfs_entries; /* Helper Routines to convert between drc_index to cpu numbers */ +void read_one_drc_info(int **info, char **dtype, char **dname, + unsigned long int *drc_index_start_p, + unsigned long int *num_sequential_elems_p, + unsigned long int *sequential_inc_p, + unsigned long int *last_drc_index_p) +{ + char *drc_type, *drc_name_prefix, *pc; + u32 drc_index_start, num_sequential_elems; + u32 sequential_inc, last_drc_index; + + drc_index_start = num_sequential_elems = 0; + sequential_inc = last_drc_index = 0; + + /* Get drc-type:encode-string */ + pc = (char *)info; + drc_type = pc; + pc += (strlen(drc_type) + 1); + + /* Get drc-name-prefix:encode-string */ + drc_name_prefix = (char *)pc; + pc += (strlen(drc_name_prefix) + 1); + + /* Get drc-index-start:encode-int */ + memcpy(&drc_index_start, pc, 4); + drc_index_start = be32_to_cpu(drc_index_start); + pc += 4; + + /* Get/skip drc-name-suffix-start:encode-int */ + pc += 4; + + /* Get number-sequential-elements:encode-int */ + memcpy(&num_sequential_elems, pc, 4); + num_sequential_elems = be32_to_cpu(num_sequential_elems); + pc += 4; + + /* Get sequential-increment:encode-int */ + memcpy(&sequential_inc, pc, 4); + sequential_inc = be32_to_cpu(sequential_inc); + pc += 4; + + /* Get/skip drc-power-domain:encode-int */ + pc += 4; + + /* Should now know end of current entry */ + last_drc_index = drc_index_start + + ((num_sequential_elems-1)*sequential_inc); + + (*info) = (int *)pc; + + if (dtype) + *dtype = drc_type; + if (dname) + *dname = drc_name_prefix; + if (drc_index_start_p) + *drc_index_start_p = drc_index_start; + if (num_sequential_elems_p) + *num_sequential_elems_p = num_sequential_elems; + if (sequential_inc_p) + *sequential_inc_p = sequential_inc; + if (last_drc_index_p) + *last_drc_index_p = last_drc_index; +} +EXPORT_SYMBOL(read_one_drc_info); + static u32 cpu_to_drc_index(int cpu) { struct device_node *dn = NULL; - const int *indexes; int i; int rc = 1; u32 ret = 0; @@ -46,18 +109,60 @@ static u32 cpu_to_drc_index(int cpu) dn = of_find_node_by_path("/cpus"); if (dn == NULL) goto err; - indexes = of_get_property(dn, "ibm,drc-indexes", NULL); - if (indexes == NULL) - goto err_of_node_put; + /* Convert logical cpu number to core number */ i = cpu_core_index_of_thread(cpu); - /* -* The first element indexes[0] is the number of drc_indexes -* returned in the list. Hence i+1 will get the drc_index -* corresponding to core number i. -*/ - WARN_ON(i > indexes[0]); - ret = indexes[i + 1]; + + if (firmware_has_feature(FW_FEATURE_DRC_INFO)) { + int *info = (int *)4; + unsigned long int num_set_entries, j, check_val = i; + unsigned long int drc_index_start = 0; + unsigned long int last_drc_index = 0; + unsigned long int num_sequential_elems = 0; + unsigned long int sequential_inc = 0; + char *dtype; + char *dname; + + info = (int *)of_get_property(dn, "ibm,drc-info", NULL); + if (info == NULL) + goto err_of_node_put; + + num_set_entries = be32_to_cpu(*info++); + + for (j = 0; j < num_set_entries; j++) { + + read_one_drc_info(&info, &dtype, &dname, + &drc_index_start, + &num_sequential_elems, + &sequential_inc, &last_drc_index); + if (strcmp(dtype, "CPU")) +
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-)
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-) -- Michael W. Bringmann Linux Technology Center IBM Corporation m...@linux.vnet.ibm.com
[PATCH V8 3/8] powerpc/memory: Parse new memory property to initialize structures.
powerpc/memory: Add parallel routines to parse the new property "ibm,dynamic-memory-v2" property when it is present, and then to finish initialization of the relevant memory structures with the operating system. This code is shared between the boot-time initialization functions and the runtime functions for memory hotplug, so it needs to be able to handle both formats. [V2: Revise contant names.] [V3: Fix loop that needed to scan all blocks defined by new, compressed memory definition. [V4: Added external function prototype definitions to header file "prom.h" for use in other files. Change a firmware architure vec check for scan actual device tree. Delete an unused variable. Small cleanups to comments.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/include/asm/prom.h | 12 +++ arch/powerpc/mm/numa.c | 146 +-- 2 files changed, 135 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 43a002b..7907c38 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -110,6 +110,18 @@ struct of_drconf_cell_v2 { extern void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem, const __be32 **cellp); +extern void read_one_drc_info(int **info, char **drc_type, char **drc_name, + unsigned long int *fdi_p, unsigned long int *nsl_p, + unsigned long int *si_p, unsigned long int *ldi_p); + +static inline int dyn_mem_v2_len(int entries) +{ + int drconf_v2_cells = (n_mem_addr_cells + 4); + int drconf_v2_cells_len = (drconf_v2_cells * sizeof(unsigned int)); + return (((entries) * drconf_v2_cells_len) + +(1 * sizeof(unsigned int))); +} + /* * There are two methods for telling firmware what our capabilities are. * Newer machines have an "ibm,client-architecture-support" method on the diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index fe8e6e7..d3cf353 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -427,30 +427,55 @@ void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem, const __be32 **cellp) EXPORT_SYMBOL(read_drconf_cell_v2); /* - * Retrieve and validate the ibm,dynamic-memory property of the device tree. + * Retrieve and validate the ibm,dynamic-memory[-v2] property of the + * device tree. + * + * The layout of the ibm,dynamic-memory property is a number N of memory + * block description list entries followed by N memory block description + * list entries. Each memory block description list entry contains + * information as laid out in the of_drconf_cell struct above. * - * The layout of the ibm,dynamic-memory property is a number N of memblock - * list entries followed by N memblock list entries. Each memblock list entry - * contains information as laid out in the of_drconf_cell struct above. + * The layout of the ibm,dynamic-memory-v2 property is a number N of memory + * block set description list entries, followed by N memory block set + * description set entries. */ static int of_get_drconf_memory(struct device_node *memory, const __be32 **dm) { const __be32 *prop; u32 len, entries; - prop = of_get_property(memory, "ibm,dynamic-memory", &len); - if (!prop || len < sizeof(unsigned int)) - return 0; + if (firmware_has_feature(FW_FEATURE_DYN_MEM_V2)) { - entries = of_read_number(prop++, 1); + prop = of_get_property(memory, "ibm,dynamic-memory-v2", &len); + if (!prop || len < sizeof(unsigned int)) + return 0; - /* Now that we know the number of entries, revalidate the size -* of the property read in to ensure we have everything -*/ - if (len < (entries * (n_mem_addr_cells + 4) + 1) * sizeof(unsigned int)) - return 0; + entries = of_read_number(prop++, 1); + + /* Now that we know the number of set entries, revalidate the +* size of the property read in to ensure we have everything. +*/ + if (len < dyn_mem_v2_len(entries)) + return 0; + + *dm = prop; + } else { + prop = of_get_property(memory, "ibm,dynamic-memory", &len); + if (!prop || len < sizeof(unsigned int)) + return 0; + + entries = of_read_number(prop++, 1); + + /* Now that we know the number of entries, revalidate the size +* of the property read in to ensure we have everything +*/ + if (len < (entries * (n_mem_addr_cells + 4) + 1) * + sizeof(unsigned int)) + return 0; + + *dm =
[PATCH V8 8/8] powerpc: Enable support for new DRC devtree properties
prom_init.c: Enable support for new DRC device tree properties "ibm,drc-info" and "ibm,dynamic-memory-v2" in initial handshake between the Linux kernel and the front end processor. [V2: Revise constant names.] [V3: No change.] [V4: Update comments] [V5: Resynchronize/resubmit] [V6: Resynchronize to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/kernel/prom_init.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d3eff99..28a5ea2 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -695,7 +695,7 @@ unsigned char ibm_architecture_vec[] = { OV4_MIN_ENT_CAP,/* minimum VP entitled capacity */ /* option vector 5: PAPR/OF options */ - VECTOR_LENGTH(21), /* length */ + VECTOR_LENGTH(22), /* length */ 0, /* don't ignore, don't halt */ OV5_FEAT(OV5_LPAR) | OV5_FEAT(OV5_SPLPAR) | OV5_FEAT(OV5_LARGE_PAGES) | OV5_FEAT(OV5_DRCONF_MEMORY) | OV5_FEAT(OV5_DONATE_DEDICATE_CPU) | @@ -731,6 +731,7 @@ unsigned char ibm_architecture_vec[] = { 0, /* Byte 19 */ 0, /* Byte 20 */ OV5_FEAT(OV5_SUB_PROCESSORS), /* Byte 21 */ + OV5_FEAT(OV5_DYN_MEM_V2) | OV5_FEAT(OV5_DRC_INFO), /* Byte 22 */ /* option vector 6: IBM PAPR hints */ VECTOR_LENGTH(3), /* length */
[PATCH V8 6/8] hotplug/drc-info: Add code to search new devtree properties
rpadlpar_core.c: Provide parallel routines to search the older device- tree properties ("ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains"), or the new property "ibm,drc-info". The interface to examine the DRC information is changed from a "get" function that returns values for local verification elsewhere, to a "check" function that validates the 'name' and/or 'type' of a device node. This update hides the format of the underlying device-tree properties, and concentrates the value checks into a single function without requiring the user to verify whether a search was successful. [V2: Revise contant names.] [V3: Amend comments. Simplify code cleanup.] [V4: Update comments.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- drivers/pci/hotplug/rpadlpar_core.c | 13 ++-- drivers/pci/hotplug/rpaphp.h|4 + drivers/pci/hotplug/rpaphp_core.c | 109 +++ 3 files changed, 91 insertions(+), 35 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index dc67f39..bea9723 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "../pci.h" #include "rpaphp.h" @@ -44,15 +45,14 @@ static struct device_node *find_vio_slot_node(char *drc_name) { struct device_node *parent = of_find_node_by_name(NULL, "vdevice"); struct device_node *dn = NULL; - char *name; int rc; if (!parent) return NULL; while ((dn = of_get_next_child(parent, dn))) { - rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL); - if ((rc == 0) && (!strcmp(drc_name, name))) + rc = rpaphp_check_drc_props(dn, drc_name, NULL); + if (rc == 0) break; } @@ -64,15 +64,12 @@ static struct device_node *find_php_slot_pci_node(char *drc_name, char *drc_type) { struct device_node *np = NULL; - char *name; - char *type; int rc; while ((np = of_find_node_by_name(np, "pci"))) { - rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL); + rc = rpaphp_check_drc_props(np, drc_name, drc_type); if (rc == 0) - if (!strcmp(drc_name, name) && !strcmp(drc_type, type)) - break; + break; } return np; diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 7db024e..8db5f2e 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -91,8 +91,8 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ int rpaphp_add_slot(struct device_node *dn); -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, - char **drc_name, char **drc_type, int *drc_power_domain); +int rpaphp_check_drc_props(struct device_node *dn, char *drc_name, + char *drc_type); /* rpaphp_slot.c */ void dealloc_slot_struct(struct slot *slot); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 8d13202..85ad2ae 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -30,6 +30,7 @@ #include #include #include +#include #include/* for eeh_add_device() */ #include /* rtas_call */ #include /* for pci_controller */ @@ -196,25 +197,21 @@ static int get_children_props(struct device_node *dn, const int **drc_indexes, return 0; } -/* To get the DRC props describing the current node, first obtain it's - * my-drc-index property. Next obtain the DRC list from it's parent. Use - * the my-drc-index for correlation, and obtain the requested properties. + +/* Verify the existence of 'drc_name' and/or 'drc_type' within the + * current node. First obtain it's my-drc-index property. Next, + * obtain the DRC info from it's parent. Use the my-drc-index for + * correlation, and obtain/validate the requested properties. */ -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, - char **drc_name, char **drc_type, int *drc_power_domain) + +static int rpaphp_check_drc_props_v1(struct device_node *dn, char *drc_name, + char *drc_type, unsigned int my_index) { + char *name_tmp, *type_tmp; const int *indexes, *names; const int *types, *domains; - const unsigned int *my_index; - char *name_tmp, *type_tmp; int i, rc; - my_index = of_get_property(dn, "ibm,my-drc-index", NULL); - if (!my_index) { - /* Node isn't DLPAR/hotplug capable */ - return -EINVAL; - } -
[PATCH V8 2/8] powerpc/memory: Parse new memory property to register blocks.
powerpc/memory: Add parallel routines to parse the new property "ibm,dynamic-memory-v2" property when it is present, and then to register the relevant memory blocks with the operating system. This property format is intended to provide a more compact representation of memory when communicating with the front end processor, especially when describing vast amounts of RAM. [V2: Revise contant names.] [V3: Fix error parsing the new memory block sets.] [V4: Move a couple of function prototypes from header file a later patch where first used. Amend some comments. Change a firmware architure vec check for scan actual device tree. Compress some common code.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/include/asm/prom.h | 24 -- arch/powerpc/kernel/prom.c | 97 --- arch/powerpc/mm/numa.c | 22 - 3 files changed, 129 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index bc7c4b5..43a002b 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -69,6 +69,8 @@ struct boot_param_header { * OF address retreival & translation */ +extern int n_mem_addr_cells; + /* Parse the ibm,dma-window property of an OF node into the busno, phys and * size parameters. */ @@ -81,8 +83,9 @@ extern void of_instantiate_rtc(void); extern int of_get_ibm_chip_id(struct device_node *np); /* The of_drconf_cell struct defines the layout of the LMB array - * specified in the device tree property - * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory + * specified in the device tree properties, + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory + * ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory-v2 */ struct of_drconf_cell { u64 base_addr; @@ -92,9 +95,20 @@ struct of_drconf_cell { u32 flags; }; -#define DRCONF_MEM_ASSIGNED0x0008 -#define DRCONF_MEM_AI_INVALID 0x0040 -#define DRCONF_MEM_RESERVED0x0080 +#define DRCONF_MEM_ASSIGNED0x0008 +#define DRCONF_MEM_AI_INVALID 0x0040 +#define DRCONF_MEM_RESERVED0x0080 + +struct of_drconf_cell_v2 { + u32 num_seq_lmbs; + u64 base_addr; + u32 drc_index; + u32 aa_index; + u32 flags; +} __attribute__((packed)); + +extern void read_drconf_cell_v2(struct of_drconf_cell_v2 *drmem, + const __be32 **cellp); /* * There are two methods for telling firmware what our capabilities are. diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index b0245be..2d49887 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -443,23 +443,34 @@ static int __init early_init_dt_scan_chosen_ppc(unsigned long node, #ifdef CONFIG_PPC_PSERIES /* - * Interpret the ibm,dynamic-memory property in the - * /ibm,dynamic-reconfiguration-memory node. + * Retrieve and validate the ibm,lmb-size property for drconf memory + * from the flattened device tree. + */ +static u64 __init get_lmb_size(unsigned long node) +{ + const __be32 *ls; + int len; + ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &len); + if (!ls || len < dt_root_size_cells * sizeof(__be32)) + return 0; + return dt_mem_next_cell(dt_root_size_cells, &ls); +} + +/* + * Interpret the ibm,dynamic-memory property/ibm,dynamic-memory-v2 + * in the /ibm,dynamic-reconfiguration-memory node. * This contains a list of memory blocks along with NUMA affinity * information. */ -static int __init early_init_dt_scan_drconf_memory(unsigned long node) +static int __init early_init_dt_scan_drconf_memory_v1(unsigned long node) { - const __be32 *dm, *ls, *usm; + const __be32 *dm, *usm; int l; unsigned long n, flags; u64 base, size, memblock_size; unsigned int is_kexec_kdump = 0, rngs; - ls = of_get_flat_dt_prop(node, "ibm,lmb-size", &l); - if (ls == NULL || l < dt_root_size_cells * sizeof(__be32)) - return 0; - memblock_size = dt_mem_next_cell(dt_root_size_cells, &ls); + memblock_size = get_lmb_size(node); dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l); if (dm == NULL || l < sizeof(__be32)) @@ -518,6 +529,76 @@ static int __init early_init_dt_scan_drconf_memory(unsigned long node) memblock_dump_all(); return 0; } + +static int __init early_init_dt_scan_drconf_memory_v2(unsigned long node) +{ + const __be32 *dm; + int l; + unsigned long num_sets; + u64 size, base, memblock_size; + + memblock_size = get_lmb_size(node); + + dm = of_get_flat_dt_prop(node, "ibm,dynamic-memory-v2", &l); + if (dm == NULL || l < sizeof(__be32)) +
[PATCH V8 4/8] pseries/hotplug init: Convert new DRC memory property for hotplug runtime
hotplug_init: Simplify the code needed for runtime memory hotplug and maintenance with a conversion routine that transforms the compressed property "ibm,dynamic-memory-v2" to the form of "ibm,dynamic-memory" within the "ibm,dynamic-reconfiguration-memory" property. Thus only a single set of routines should be required at runtime to parse, edit, and manipulate the memory representation in the device tree. Similarly, any userspace applications that need this information will only need to recognize the older format to be able to continue to operate. [V2: Revise contant names.] [V3: Replace use of in-code compile flag encompassing file by Makefile mod.] [V4: Remove unneeded code braces. Simplify allocation of a couple of loop index variables.] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/platforms/pseries/Makefile |4 - arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index fedc2ccf0..e74cf6c 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -5,14 +5,14 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \ of_helpers.o \ setup.o iommu.o event_sources.o ras.o \ firmware.o power.o dlpar.o mobility.o rng.o \ - pci.o pci_dlpar.o eeh_pseries.o msi.o + pci.o pci_dlpar.o eeh_pseries.o msi.o \ + hotplug-memory.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_KEXEC)+= kexec.o obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o -obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 76ec104..461f883 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -24,6 +24,8 @@ #include #include "pseries.h" +#ifdef CONFIG_MEMORY_HOTPLUG + static bool rtas_hp_event; unsigned long pseries_memory_block_size(void) @@ -887,11 +889,102 @@ static int pseries_memory_notifier(struct notifier_block *nb, static struct notifier_block pseries_mem_nb = { .notifier_call = pseries_memory_notifier, }; +#endif /* CONFIG_MEMORY_HOTPLUG */ + +static int pseries_rewrite_dynamic_memory_v2(void) +{ + unsigned long memblock_size; + struct device_node *dn; + struct property *prop, *prop_v2; + __be32 *p; + struct of_drconf_cell *lmbs; + u32 num_lmb_desc_sets, num_lmbs; + int i, j, k; + + dn = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (!dn) + return -EINVAL; + + prop_v2 = of_find_property(dn, "ibm,dynamic-memory-v2", NULL); + if (!prop_v2) + return -EINVAL; + + memblock_size = pseries_memory_block_size(); + if (!memblock_size) + return -EINVAL; + + /* The first int of the property is the number of lmb sets +* described by the property. +*/ + p = (__be32 *)prop_v2->value; + num_lmb_desc_sets = be32_to_cpu(*p++); + + /* Count the number of LMBs for generating the alternate format +*/ + for (i = 0, num_lmbs = 0; i < num_lmb_desc_sets; i++) { + struct of_drconf_cell_v2 drmem; + + read_drconf_cell_v2(&drmem, (const __be32 **)&p); + num_lmbs += drmem.num_seq_lmbs; + } + + /* Create an empty copy of the new 'ibm,dynamic-memory' property +*/ + prop = kzalloc(sizeof(*prop), GFP_KERNEL); + if (!prop) + return -ENOMEM; + prop->name = kstrdup("ibm,dynamic-memory", GFP_KERNEL); + prop->length = dyn_mem_v2_len(num_lmbs); + prop->value = kzalloc(prop->length, GFP_KERNEL); + + /* Copy/expand the ibm,dynamic-memory-v2 format to produce the +* ibm,dynamic-memory format. +*/ + p = (__be32 *)prop->value; + *p = cpu_to_be32(num_lmbs); + p++; + lmbs = (struct of_drconf_cell *)p; + + p = (__be32 *)prop_v2->value; + p++; + + for (i = 0, k = 0; i < num_lmb_desc_sets; i++) { + struct of_drconf_cell_v2 drmem; + + read_drconf_cell_v2(&drmem, (const __be32 **)&p); + + for (j = 0; j < drmem.num_seq_lmbs; j++) { + lmbs[k+j].base_addr = be64_to_cpu(drmem.base_addr); + lmbs[k+j].drc_index = be32_to_cpu(drmem.drc_index); +
[PATCH V8 7/8] powerpc: Check arch.vec earlier during boot for memory features
architecture.vec5 features: The boot-time memory management needs to know the form of the "ibm,dynamic-memory-v2" property early during scanning of the flattened device tree. This patch moves execution of the function pseries_probe_fw_features() early enough to be before the scanning of the memory properties in the device tree to allow recognition of the supported properties. [V2: No change] [V3: Updated after commit 3808a88985b4f5f5e947c364debce4441a380fb8.] [V4: Update comments] [V5: Resynchronize/resubmit] [V6: Resync to v4.7 kernel code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/kernel/prom.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 2d49887..bd07157 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -759,6 +759,9 @@ void __init early_init_devtree(void *params) */ of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line); + /* Now try to figure out if we are running on LPAR and so on */ + pseries_probe_fw_features(); + /* Scan memory nodes and rebuild MEMBLOCKs */ of_scan_flat_dt(early_init_dt_scan_root, NULL); of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL); @@ -826,9 +829,6 @@ void __init early_init_devtree(void *params) #endif epapr_paravirt_early_init(); - /* Now try to figure out if we are running on LPAR and so on */ - pseries_probe_fw_features(); - #ifdef CONFIG_PPC_PS3 /* Identify PS3 firmware */ if (of_flat_dt_is_compatible(of_get_flat_dt_root(), "sony,ps3"))
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-)
[PATCH V8 1/8] powerpc/firmware: Add definitions for new firmware features.
Firmware Features: Define new bit flags representing the presence of new device tree properties "ibm,drc-info", and "ibm,dynamic-memory-v2". These flags are used to tell the front end processor when the Linux kernel supports the new properties, and by the front end processor to tell the Linux kernel that the new properties are present in the devie tree. [V2: Revise constant names for improved clarity.] [V3: Fix comments] [V4: Fix some spacing] [V5: Resynchronize/resubmit] [V6: No change] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h |2 ++ arch/powerpc/platforms/pseries/firmware.c |2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 1e0b5a5..6b5cf38 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -51,6 +51,8 @@ #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x8000) #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0001) #define FW_FEATURE_PRRNASM_CONST(0x0002) +#define FW_FEATURE_DYN_MEM_V2 ASM_CONST(0x0004) +#define FW_FEATURE_DRC_INFOASM_CONST(0x0008) #ifndef __ASSEMBLY__ @@ -66,7 +68,8 @@ enum { FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO | FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | - FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, + FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN | + FW_FEATURE_DYN_MEM_V2 | FW_FEATURE_DRC_INFO, FW_FEATURE_PSERIES_ALWAYS = 0, FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL, FW_FEATURE_POWERNV_ALWAYS = 0, diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 7f436ba..bc7c4b5 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -155,6 +155,8 @@ struct of_drconf_cell { #define OV5_PFO_HW_842 0x0E40 /* PFO Compression Accelerator */ #define OV5_PFO_HW_ENCR0x0E20 /* PFO Encryption Accelerator */ #define OV5_SUB_PROCESSORS 0x0F01 /* 1,2,or 4 Sub-Processors supported */ +#define OV5_DYN_MEM_V2 0x1680 /* Redef Prop Structures: dyn-mem-v2 */ +#define OV5_DRC_INFO 0x1640 /* Redef Prop Structures: drc-info */ /* Option Vector 6: IBM PAPR hints */ #define OV6_LINUX 0x02/* Linux is our OS */ diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index ea7f09b..d2d23f5 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c @@ -113,6 +113,8 @@ static __initdata struct vec5_fw_feature vec5_fw_features_table[] = { {FW_FEATURE_TYPE1_AFFINITY, OV5_TYPE1_AFFINITY}, {FW_FEATURE_PRRN, OV5_PRRN}, + {FW_FEATURE_DYN_MEM_V2, OV5_DYN_MEM_V2}, + {FW_FEATURE_DRC_INFO, OV5_DRC_INFO}, }; static void __init fw_vec5_feature_init(const char *vec5, unsigned long len)
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-)
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-) -- Michael W. Bringmann Linux Technology Center IBM Corporation m...@linux.vnet.ibm.com
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-) -- Michael W. Bringmann Linux Technology Center IBM Corporation m...@linux.vnet.ibm.com
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-)
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-)
Re: [PATCH net-next] ibmveth: v1 calculate correct gso_size and set gso_type
On Wed, 2016-10-26 at 11:09 +1100, Jon Maxwell wrote: > We recently encountered a bug where a few customers using ibmveth on the > same LPAR hit an issue where a TCP session hung when large receive was > enabled. Closer analysis revealed that the session was stuck because the > one side was advertising a zero window repeatedly. > > We narrowed this down to the fact the ibmveth driver did not set gso_size > which is translated by TCP into the MSS later up the stack. The MSS is > used to calculate the TCP window size and as that was abnormally large, > it was calculating a zero window, even although the sockets receive buffer > was completely empty. > > We were able to reproduce this and worked with IBM to fix this. Thanks Tom > and Marcelo for all your help and review on this. > > The patch fixes both our internal reproduction tests and our customers tests. > > Signed-off-by: Jon Maxwell > --- > drivers/net/ethernet/ibm/ibmveth.c | 20 > 1 file changed, 20 insertions(+) > > diff --git a/drivers/net/ethernet/ibm/ibmveth.c > b/drivers/net/ethernet/ibm/ibmveth.c > index 29c05d0..c51717e 100644 > --- a/drivers/net/ethernet/ibm/ibmveth.c > +++ b/drivers/net/ethernet/ibm/ibmveth.c > @@ -1182,6 +1182,8 @@ static int ibmveth_poll(struct napi_struct *napi, int > budget) > int frames_processed = 0; > unsigned long lpar_rc; > struct iphdr *iph; > + bool large_packet = 0; > + u16 hdr_len = ETH_HLEN + sizeof(struct tcphdr); > > restart_poll: > while (frames_processed < budget) { > @@ -1236,10 +1238,28 @@ static int ibmveth_poll(struct napi_struct *napi, int > budget) > iph->check = 0; > iph->check = > ip_fast_csum((unsigned char *)iph, iph->ihl); > adapter->rx_large_packets++; > + large_packet = 1; > } > } > } > > + if (skb->len > netdev->mtu) { > + iph = (struct iphdr *)skb->data; > + if (be16_to_cpu(skb->protocol) == ETH_P_IP && > + iph->protocol == IPPROTO_TCP) { > + hdr_len += sizeof(struct iphdr); > + skb_shinfo(skb)->gso_type = > SKB_GSO_TCPV4; > + skb_shinfo(skb)->gso_size = netdev->mtu > - hdr_len; > + } else if (be16_to_cpu(skb->protocol) == > ETH_P_IPV6 && > +iph->protocol == IPPROTO_TCP) { > + hdr_len += sizeof(struct ipv6hdr); > + skb_shinfo(skb)->gso_type = > SKB_GSO_TCPV6; > + skb_shinfo(skb)->gso_size = netdev->mtu > - hdr_len; > + } > + if (!large_packet) > + adapter->rx_large_packets++; > + } > + > This might break forwarding and PMTU discovery. You force gso_size to device mtu, regardless of real MSS used by the TCP sender. Don't you have the MSS provided in RX descriptor, instead of guessing the value ?
[PATCH V8 0/8] powerpc/devtree: Add support for 2 new DRC properties
Several properties in the DRC device tree format are replaced by more compact representations to allow, for example, for the encoding of vast amounts of memory, and or reduced duplication of information in related data structures. "ibm,drc-info": This property, when present, replaces the following four properties: "ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" and "ibm,drc-power-domains". This property is defined for all dynamically reconfigurable platform nodes. The "ibm,drc-info" elements are intended to provide a more compact representation, and reduce some search overhead. "ibm,dynamic-memory-v2": This property replaces the "ibm,dynamic-memory" node representation within the "ibm,dynamic-reconfiguration-memory" property provided by the BMC. This element format is intended to provide a more compact representation of memory, especially, for systems with massive amounts of RAM. To simplify portability, this property is converted to the "ibm,dynamic-memory" property during system boot. "ibm,architecture.vec": Bidirectional communication mechanism between the host system and the front end processor indicating what features the host system supports and what features the front end processor will actually provide. In this case, we are indicating that the host system can support the new device tree structures "ibm,drc-info" and "ibm,dynamic-memory-v2". [V1: Initial presentation of PAPR 2.7 changes to device tree.] [V2: Revise constant names. Fix some syntax errors. Improve comments.] [V3: Revise tests for presence of new properties to always scan devicetree instead of depending upon architecture vec, due to reboot issues.] [V4: Rearrange some code changes in patches to better match application, and other code cleanup.] [V5: Resynchronize patches.] [V6: Resync to latest kernel commit code] [V7: Correct mail threading] [v8: Insert more useful variable names] Signed-off-by: Michael Bringmann --- Michael Bringmann (8): powerpc/firmware: Add definitions for new firmware features. powerpc/memory: Parse new memory property to register blocks. powerpc/memory: Parse new memory property to initialize structures. pseries/hotplug init: Convert new DRC memory property for hotplug runtime pseries/drc-info: Search new DRC properties for CPU indexes hotplug/drc-info: Add code to search new devtree properties powerpc: Check arch.vec earlier during boot for memory features powerpc: Enable support for new DRC devtree properties arch/powerpc/include/asm/firmware.h |5 - arch/powerpc/include/asm/prom.h | 38 - arch/powerpc/kernel/prom.c | 103 +++-- arch/powerpc/kernel/prom_init.c |3 arch/powerpc/mm/numa.c | 168 ++-- arch/powerpc/platforms/pseries/Makefile |4 arch/powerpc/platforms/pseries/firmware.c |2 arch/powerpc/platforms/pseries/hotplug-memory.c | 93 +++ arch/powerpc/platforms/pseries/pseries_energy.c | 189 --- drivers/pci/hotplug/rpadlpar_core.c | 13 +- drivers/pci/hotplug/rpaphp.h|4 drivers/pci/hotplug/rpaphp_core.c | 109 ++--- 12 files changed, 628 insertions(+), 103 deletions(-) -- Signature
[PATCHv3 0/8] powerpc/mm: refactor vDSO mapping code
Changes since v1, v2: - use vdso64_pages only under CONFIG_PPC64 (32-bit build fix) - remove arch_vma_name helper as not needed anymore, simplify vdso_base pointer initializing in map_vdso() Cleanup patches for vDSO on powerpc. Originally, I wanted to add vDSO remapping on arm/aarch64 and I decided to cleanup that part on powerpc. I've add a hook for vm_ops for vDSO just like I did for x86, which makes cross-arch arch_mremap hook no more needed. Other changes - reduce exhaustive code duplication by separating the common vdso code. No visible to userspace changes expected. Tested on qemu with buildroot rootfs. Dmitry Safonov (8): powerpc/vdso: unify return paths in setup_additional_pages powerpc/vdso: remove unused params in vdso_do_func_patch{32,64} powerpc/vdso: separate common code in vdso_common powerpc/vdso: introduce init_vdso{32,64}_pagelist powerpc/vdso: split map_vdso from arch_setup_additional_pages powerpc/vdso: switch from legacy_special_mapping_vmops mm: kill arch_mremap powerpc/vdso: remove arch_vma_name arch/alpha/include/asm/Kbuild| 1 - arch/arc/include/asm/Kbuild | 1 - arch/arm/include/asm/Kbuild | 1 - arch/arm64/include/asm/Kbuild| 1 - arch/avr32/include/asm/Kbuild| 1 - arch/blackfin/include/asm/Kbuild | 1 - arch/c6x/include/asm/Kbuild | 1 - arch/cris/include/asm/Kbuild | 1 - arch/frv/include/asm/Kbuild | 1 - arch/h8300/include/asm/Kbuild| 1 - arch/hexagon/include/asm/Kbuild | 1 - arch/ia64/include/asm/Kbuild | 1 - arch/m32r/include/asm/Kbuild | 1 - arch/m68k/include/asm/Kbuild | 1 - arch/metag/include/asm/Kbuild| 1 - arch/microblaze/include/asm/Kbuild | 1 - arch/mips/include/asm/Kbuild | 1 - arch/mn10300/include/asm/Kbuild | 1 - arch/nios2/include/asm/Kbuild| 1 - arch/openrisc/include/asm/Kbuild | 1 - arch/parisc/include/asm/Kbuild | 1 - arch/powerpc/include/asm/mm-arch-hooks.h | 28 -- arch/powerpc/kernel/vdso.c | 502 +-- arch/powerpc/kernel/vdso_common.c| 248 +++ arch/s390/include/asm/Kbuild | 1 - arch/score/include/asm/Kbuild| 1 - arch/sh/include/asm/Kbuild | 1 - arch/sparc/include/asm/Kbuild| 1 - arch/tile/include/asm/Kbuild | 1 - arch/um/include/asm/Kbuild | 1 - arch/unicore32/include/asm/Kbuild| 1 - arch/x86/include/asm/Kbuild | 1 - arch/xtensa/include/asm/Kbuild | 1 - include/asm-generic/mm-arch-hooks.h | 16 - include/linux/mm-arch-hooks.h| 25 -- mm/mremap.c | 4 - 36 files changed, 324 insertions(+), 529 deletions(-) delete mode 100644 arch/powerpc/include/asm/mm-arch-hooks.h create mode 100644 arch/powerpc/kernel/vdso_common.c delete mode 100644 include/asm-generic/mm-arch-hooks.h delete mode 100644 include/linux/mm-arch-hooks.h -- 2.10.1
[PATCHv3 1/8] powerpc/vdso: unify return paths in setup_additional_pages
Impact: cleanup Rename `rc' variable which doesn't seems to mean anything into kernel-known `ret'. Combine two function returns into one as it's also easier to read. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/powerpc/kernel/vdso.c | 19 +++ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 4111d30badfa..4ffb82a2d9e9 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -154,7 +154,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) struct page **vdso_pagelist; unsigned long vdso_pages; unsigned long vdso_base; - int rc; + int ret = 0; if (!vdso_ready) return 0; @@ -203,8 +203,8 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) ((VDSO_ALIGNMENT - 1) & PAGE_MASK), 0, 0); if (IS_ERR_VALUE(vdso_base)) { - rc = vdso_base; - goto fail_mmapsem; + ret = vdso_base; + goto out_up_mmap_sem; } /* Add required alignment. */ @@ -227,21 +227,16 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * It's fine to use that for setting breakpoints in the vDSO code * pages though. */ - rc = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, + ret = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, vdso_pagelist); - if (rc) { + if (ret) current->mm->context.vdso_base = 0; - goto fail_mmapsem; - } - - up_write(&mm->mmap_sem); - return 0; - fail_mmapsem: +out_up_mmap_sem: up_write(&mm->mmap_sem); - return rc; + return ret; } const char *arch_vma_name(struct vm_area_struct *vma) -- 2.10.1
[PATCHv3 4/8] powerpc/vdso: introduce init_vdso{32,64}_pagelist
Impact: cleanup Move allocation/initialization of vDSO's pagelist for 32/64-bit vDSO into common vdso code, introducing a function for that. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/powerpc/kernel/vdso.c| 27 ++- arch/powerpc/kernel/vdso_common.c | 22 ++ 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 8010a0d82049..25d03d773c49 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -382,8 +382,6 @@ early_initcall(vdso_getcpu_init); static int __init vdso_init(void) { - int i; - #ifdef CONFIG_PPC64 /* * Fill up the "systemcfg" stuff for backward compatibility @@ -454,32 +452,11 @@ static int __init vdso_init(void) } #ifdef CONFIG_VDSO32 - /* Make sure pages are in the correct state */ - vdso32_pagelist = kzalloc(sizeof(struct page *) * (vdso32_pages + 2), - GFP_KERNEL); - BUG_ON(vdso32_pagelist == NULL); - for (i = 0; i < vdso32_pages; i++) { - struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE); - ClearPageReserved(pg); - get_page(pg); - vdso32_pagelist[i] = pg; - } - vdso32_pagelist[i++] = virt_to_page(vdso_data); - vdso32_pagelist[i] = NULL; + init_vdso32_pagelist(); #endif #ifdef CONFIG_PPC64 - vdso64_pagelist = kzalloc(sizeof(struct page *) * (vdso64_pages + 2), - GFP_KERNEL); - BUG_ON(vdso64_pagelist == NULL); - for (i = 0; i < vdso64_pages; i++) { - struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE); - ClearPageReserved(pg); - get_page(pg); - vdso64_pagelist[i] = pg; - } - vdso64_pagelist[i++] = virt_to_page(vdso_data); - vdso64_pagelist[i] = NULL; + init_vdso64_pagelist(); #endif /* CONFIG_PPC64 */ get_page(virt_to_page(vdso_data)); diff --git a/arch/powerpc/kernel/vdso_common.c b/arch/powerpc/kernel/vdso_common.c index ac25d66134fb..c97c30606b3f 100644 --- a/arch/powerpc/kernel/vdso_common.c +++ b/arch/powerpc/kernel/vdso_common.c @@ -14,6 +14,7 @@ #define VDSO_LBASE CONCAT3(VDSO, BITS, _LBASE) #define vdso_kbase CONCAT3(vdso, BITS, _kbase) #define vdso_pages CONCAT3(vdso, BITS, _pages) +#define vdso_pagelist CONCAT3(vdso, BITS, _pagelist) #undef pr_fmt #define pr_fmt(fmt)"vDSO" __stringify(BITS) ": " fmt @@ -202,6 +203,25 @@ static __init int vdso_setup(struct lib_elfinfo *v) return 0; } +#define init_vdso_pagelist CONCAT3(init_vdso, BITS, _pagelist) +static __init void init_vdso_pagelist(void) +{ + int i; + + /* Make sure pages are in the correct state */ + vdso_pagelist = kzalloc(sizeof(struct page *) * (vdso_pages + 2), + GFP_KERNEL); + BUG_ON(vdso_pagelist == NULL); + for (i = 0; i < vdso_pages; i++) { + struct page *pg = virt_to_page(vdso_kbase + i*PAGE_SIZE); + + ClearPageReserved(pg); + get_page(pg); + vdso_pagelist[i] = pg; + } + vdso_pagelist[i++] = virt_to_page(vdso_data); + vdso_pagelist[i] = NULL; +} #undef find_section #undef find_symbol @@ -211,10 +231,12 @@ static __init int vdso_setup(struct lib_elfinfo *v) #undef vdso_fixup_datapage #undef vdso_fixup_features #undef vdso_setup +#undef init_vdso_pagelist #undef VDSO_LBASE #undef vdso_kbase #undef vdso_pages +#undef vdso_pagelist #undef lib_elfinfo #undef BITS #undef _CONCAT3 -- 2.10.1
[PATCHv3 3/8] powerpc/vdso: separate common code in vdso_common
Impact: cleanup There are common functions for handeling 32-bit and 64-bit vDSO ELF files: find_section{32,64}, find_symbol{32,64}, find_function{32,64}, vdso_do_func_patch{32,64}, vdso_do_find_sections{32,64}, vdso_fixup_datapag{32,64}, vdso_fixup_features{32,64}, vdso_setup{32,64} which all do the same work with the only difference is using structures for 32 or 64 bit ELF. Let's combine them into common code, reducing copy'n'paste code. Small changes: I also switched usage of printk(KERNEL_,...) on pr_(...) and used pr_fmt() macro for "vDSO{32,64}: " prefix. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/powerpc/kernel/vdso.c| 352 ++ arch/powerpc/kernel/vdso_common.c | 221 2 files changed, 234 insertions(+), 339 deletions(-) create mode 100644 arch/powerpc/kernel/vdso_common.c diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 278b9aa25a1c..8010a0d82049 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -51,13 +51,13 @@ #define VDSO_ALIGNMENT (1 << 16) static unsigned int vdso32_pages; -static void *vdso32_kbase; static struct page **vdso32_pagelist; unsigned long vdso32_sigtramp; unsigned long vdso32_rt_sigtramp; #ifdef CONFIG_VDSO32 extern char vdso32_start, vdso32_end; +static void *vdso32_kbase; #endif #ifdef CONFIG_PPC64 @@ -246,250 +246,16 @@ const char *arch_vma_name(struct vm_area_struct *vma) return NULL; } - - #ifdef CONFIG_VDSO32 -static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname, - unsigned long *size) -{ - Elf32_Shdr *sechdrs; - unsigned int i; - char *secnames; - - /* Grab section headers and strings so we can tell who is who */ - sechdrs = (void *)ehdr + ehdr->e_shoff; - secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset; - - /* Find the section they want */ - for (i = 1; i < ehdr->e_shnum; i++) { - if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0) { - if (size) - *size = sechdrs[i].sh_size; - return (void *)ehdr + sechdrs[i].sh_offset; - } - } - *size = 0; - return NULL; -} - -static Elf32_Sym * __init find_symbol32(struct lib32_elfinfo *lib, - const char *symname) -{ - unsigned int i; - char name[MAX_SYMNAME], *c; - - for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) { - if (lib->dynsym[i].st_name == 0) - continue; - strlcpy(name, lib->dynstr + lib->dynsym[i].st_name, - MAX_SYMNAME); - c = strchr(name, '@'); - if (c) - *c = 0; - if (strcmp(symname, name) == 0) - return &lib->dynsym[i]; - } - return NULL; -} - -/* Note that we assume the section is .text and the symbol is relative to - * the library base - */ -static unsigned long __init find_function32(struct lib32_elfinfo *lib, - const char *symname) -{ - Elf32_Sym *sym = find_symbol32(lib, symname); - - if (sym == NULL) { - printk(KERN_WARNING "vDSO32: function %s not found !\n", - symname); - return 0; - } - return sym->st_value - VDSO32_LBASE; -} - -static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - const char *orig, const char *fix) -{ - Elf32_Sym *sym32_gen, *sym32_fix; - - sym32_gen = find_symbol32(v32, orig); - if (sym32_gen == NULL) { - printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", orig); - return -1; - } - if (fix == NULL) { - sym32_gen->st_name = 0; - return 0; - } - sym32_fix = find_symbol32(v32, fix); - if (sym32_fix == NULL) { - printk(KERN_ERR "vDSO32: Can't find symbol %s !\n", fix); - return -1; - } - sym32_gen->st_value = sym32_fix->st_value; - sym32_gen->st_size = sym32_fix->st_size; - sym32_gen->st_info = sym32_fix->st_info; - sym32_gen->st_other = sym32_fix->st_other; - sym32_gen->st_shndx = sym32_fix->st_shndx; - - return 0; -} -#else /* !CONFIG_VDSO32 */ -static unsigned long __init find_function32(struct lib32_elfinfo *lib, - const char *symname) -{ - return 0; -} - -static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - const char *orig, const char *fix) -{ - return 0; -} +#include "vdso_common.
[PATCHv3 5/8] powerpc/vdso: split map_vdso from arch_setup_additional_pages
Impact: cleanup I'll be easier to introduce vm_special_mapping struct in a smaller map_vdso() function (see the next patches). The same way it's handeled on x86. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/powerpc/kernel/vdso.c | 67 +- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 25d03d773c49..e68601ffc9ad 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -143,52 +143,23 @@ struct lib64_elfinfo unsigned long text; }; - -/* - * This is called from binfmt_elf, we create the special vma for the - * vDSO and insert it into the mm struct tree - */ -int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +static int map_vdso(struct page **vdso_pagelist, unsigned long vdso_pages, + unsigned long vdso_base) { struct mm_struct *mm = current->mm; - struct page **vdso_pagelist; - unsigned long vdso_pages; - unsigned long vdso_base; int ret = 0; - if (!vdso_ready) - return 0; - -#ifdef CONFIG_PPC64 - if (is_32bit_task()) { - vdso_pagelist = vdso32_pagelist; - vdso_pages = vdso32_pages; - vdso_base = VDSO32_MBASE; - } else { - vdso_pagelist = vdso64_pagelist; - vdso_pages = vdso64_pages; - /* -* On 64bit we don't have a preferred map address. This -* allows get_unmapped_area to find an area near other mmaps -* and most likely share a SLB entry. -*/ - vdso_base = 0; - } -#else - vdso_pagelist = vdso32_pagelist; - vdso_pages = vdso32_pages; - vdso_base = VDSO32_MBASE; -#endif - - current->mm->context.vdso_base = 0; + mm->context.vdso_base = 0; - /* vDSO has a problem and was disabled, just don't "enable" it for the + /* +* vDSO has a problem and was disabled, just don't "enable" it for the * process */ if (vdso_pages == 0) return 0; + /* Add a page to the vdso size for the data page */ - vdso_pages ++; + vdso_pages++; /* * pick a base address for the vDSO in process space. We try to put it @@ -239,6 +210,30 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) return ret; } +/* + * This is called from binfmt_elf, we create the special vma for the + * vDSO and insert it into the mm struct tree + */ +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) +{ + if (!vdso_ready) + return 0; + + if (is_32bit_task()) + return map_vdso(vdso32_pagelist, vdso32_pages, VDSO32_MBASE); +#ifdef CONFIG_PPC64 + else + /* +* On 64bit we don't have a preferred map address. This +* allows get_unmapped_area to find an area near other mmaps +* and most likely share a SLB entry. +*/ + return map_vdso(vdso64_pagelist, vdso64_pages, 0); +#endif + WARN_ONCE(1, "task is not 32-bit on non PPC64 kernel"); + return -1; +} + const char *arch_vma_name(struct vm_area_struct *vma) { if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base) -- 2.10.1
[PATCHv3 6/8] powerpc/vdso: switch from legacy_special_mapping_vmops
This will allow to handle vDSO vma like special_mapping, that has it's name and hooks. Needed for mremap hook, which will replace arch_mremap helper, also for removing arch_vma_name. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/powerpc/kernel/vdso.c| 19 +++ arch/powerpc/kernel/vdso_common.c | 8 ++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index e68601ffc9ad..9ee3fd65c6e9 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -51,7 +51,7 @@ #define VDSO_ALIGNMENT (1 << 16) static unsigned int vdso32_pages; -static struct page **vdso32_pagelist; +static struct vm_special_mapping vdso32_mapping; unsigned long vdso32_sigtramp; unsigned long vdso32_rt_sigtramp; @@ -64,7 +64,7 @@ static void *vdso32_kbase; extern char vdso64_start, vdso64_end; static void *vdso64_kbase = &vdso64_start; static unsigned int vdso64_pages; -static struct page **vdso64_pagelist; +static struct vm_special_mapping vdso64_mapping; unsigned long vdso64_rt_sigtramp; #endif /* CONFIG_PPC64 */ @@ -143,10 +143,11 @@ struct lib64_elfinfo unsigned long text; }; -static int map_vdso(struct page **vdso_pagelist, unsigned long vdso_pages, +static int map_vdso(struct vm_special_mapping *vsm, unsigned long vdso_pages, unsigned long vdso_base) { struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; int ret = 0; mm->context.vdso_base = 0; @@ -198,12 +199,14 @@ static int map_vdso(struct page **vdso_pagelist, unsigned long vdso_pages, * It's fine to use that for setting breakpoints in the vDSO code * pages though. */ - ret = install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, + vma = _install_special_mapping(mm, vdso_base, vdso_pages << PAGE_SHIFT, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, -vdso_pagelist); - if (ret) +vsm); + if (IS_ERR(vma)) { + ret = PTR_ERR(vma); current->mm->context.vdso_base = 0; + } out_up_mmap_sem: up_write(&mm->mmap_sem); @@ -220,7 +223,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) return 0; if (is_32bit_task()) - return map_vdso(vdso32_pagelist, vdso32_pages, VDSO32_MBASE); + return map_vdso(&vdso32_mapping, vdso32_pages, VDSO32_MBASE); #ifdef CONFIG_PPC64 else /* @@ -228,7 +231,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) * allows get_unmapped_area to find an area near other mmaps * and most likely share a SLB entry. */ - return map_vdso(vdso64_pagelist, vdso64_pages, 0); + return map_vdso(&vdso64_mapping, vdso64_pages, 0); #endif WARN_ONCE(1, "task is not 32-bit on non PPC64 kernel"); return -1; diff --git a/arch/powerpc/kernel/vdso_common.c b/arch/powerpc/kernel/vdso_common.c index c97c30606b3f..047f6b8b230f 100644 --- a/arch/powerpc/kernel/vdso_common.c +++ b/arch/powerpc/kernel/vdso_common.c @@ -14,7 +14,7 @@ #define VDSO_LBASE CONCAT3(VDSO, BITS, _LBASE) #define vdso_kbase CONCAT3(vdso, BITS, _kbase) #define vdso_pages CONCAT3(vdso, BITS, _pages) -#define vdso_pagelist CONCAT3(vdso, BITS, _pagelist) +#define vdso_mapping CONCAT3(vdso, BITS, _mapping) #undef pr_fmt #define pr_fmt(fmt)"vDSO" __stringify(BITS) ": " fmt @@ -207,6 +207,7 @@ static __init int vdso_setup(struct lib_elfinfo *v) static __init void init_vdso_pagelist(void) { int i; + struct page **vdso_pagelist; /* Make sure pages are in the correct state */ vdso_pagelist = kzalloc(sizeof(struct page *) * (vdso_pages + 2), @@ -221,6 +222,9 @@ static __init void init_vdso_pagelist(void) } vdso_pagelist[i++] = virt_to_page(vdso_data); vdso_pagelist[i] = NULL; + + vdso_mapping.pages = vdso_pagelist; + vdso_mapping.name = "[vdso]"; } #undef find_section @@ -236,7 +240,7 @@ static __init void init_vdso_pagelist(void) #undef VDSO_LBASE #undef vdso_kbase #undef vdso_pages -#undef vdso_pagelist +#undef vdso_mapping #undef lib_elfinfo #undef BITS #undef _CONCAT3 -- 2.10.1
[PATCHv3 2/8] powerpc/vdso: remove unused params in vdso_do_func_patch{32, 64}
Impact: cleanup vdso_do_func_patch{32,64} only use {v32,v64} parameter accordingly. Remove not needed parameters. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/powerpc/kernel/vdso.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 4ffb82a2d9e9..278b9aa25a1c 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -309,7 +309,6 @@ static unsigned long __init find_function32(struct lib32_elfinfo *lib, } static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, const char *orig, const char *fix) { Elf32_Sym *sym32_gen, *sym32_fix; @@ -344,7 +343,6 @@ static unsigned long __init find_function32(struct lib32_elfinfo *lib, } static int __init vdso_do_func_patch32(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, const char *orig, const char *fix) { return 0; @@ -419,8 +417,7 @@ static unsigned long __init find_function64(struct lib64_elfinfo *lib, #endif } -static int __init vdso_do_func_patch64(struct lib32_elfinfo *v32, - struct lib64_elfinfo *v64, +static int __init vdso_do_func_patch64(struct lib64_elfinfo *v64, const char *orig, const char *fix) { Elf64_Sym *sym64_gen, *sym64_fix; @@ -619,11 +616,9 @@ static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32, * It would be easy to do, but doesn't seem to be necessary, * patching the OPD symbol is enough. */ - vdso_do_func_patch32(v32, v64, patch->gen_name, -patch->fix_name); + vdso_do_func_patch32(v32, patch->gen_name, patch->fix_name); #ifdef CONFIG_PPC64 - vdso_do_func_patch64(v32, v64, patch->gen_name, -patch->fix_name); + vdso_do_func_patch64(v64, patch->gen_name, patch->fix_name); #endif /* CONFIG_PPC64 */ } -- 2.10.1
[PATCHv3 8/8] powerpc/vdso: remove arch_vma_name
It's not needed since vdso is inserted with vm_special_mapping which contains vma name. This also reverts commit f2053f1a7bf6 ("powerpc/perf_counter: Fix vdso detection") as not needed anymore. See also commit f7b6eb3fa072 ("x86: Set context.vdso before installing the mapping"). Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/powerpc/kernel/vdso.c | 20 +++- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 431bdf7ec68e..f66f52aa94de 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -208,13 +208,6 @@ static int map_vdso(struct vm_special_mapping *vsm, unsigned long vdso_pages, vdso_base = ALIGN(vdso_base, VDSO_ALIGNMENT); /* -* Put vDSO base into mm struct. We need to do this before calling -* install_special_mapping or the perf counter mmap tracking code -* will fail to recognise it as a vDSO (since arch_vma_name fails). -*/ - current->mm->context.vdso_base = vdso_base; - - /* * our vma flags don't have VM_WRITE so by default, the process isn't * allowed to write those pages. * gdb can break that with ptrace interface, and thus trigger COW on @@ -228,10 +221,10 @@ static int map_vdso(struct vm_special_mapping *vsm, unsigned long vdso_pages, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, vsm); - if (IS_ERR(vma)) { + if (IS_ERR(vma)) ret = PTR_ERR(vma); - current->mm->context.vdso_base = 0; - } + else + current->mm->context.vdso_base = vdso_base; out_up_mmap_sem: up_write(&mm->mmap_sem); @@ -262,13 +255,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) return -1; } -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base) - return "[vdso]"; - return NULL; -} - #ifdef CONFIG_VDSO32 #include "vdso_common.c" #endif /* CONFIG_VDSO32 */ -- 2.10.1
[PATCHv3 7/8] mm: kill arch_mremap
This reverts commit 4abad2ca4a4d ("mm: new arch_remap() hook") and commit 2ae416b142b6 ("mm: new mm hook framework"). It also keeps the same functionality of mremapping vDSO blob with introducing vm_special_mapping mremap op for powerpc. The same way it's being handled on x86. Cc: Laurent Dufour Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: "Kirill A. Shutemov" Cc: Andy Lutomirski Cc: Oleg Nesterov Cc: Andrew Morton Cc: linuxppc-dev@lists.ozlabs.org Cc: linux...@kvack.org Signed-off-by: Dmitry Safonov --- arch/alpha/include/asm/Kbuild| 1 - arch/arc/include/asm/Kbuild | 1 - arch/arm/include/asm/Kbuild | 1 - arch/arm64/include/asm/Kbuild| 1 - arch/avr32/include/asm/Kbuild| 1 - arch/blackfin/include/asm/Kbuild | 1 - arch/c6x/include/asm/Kbuild | 1 - arch/cris/include/asm/Kbuild | 1 - arch/frv/include/asm/Kbuild | 1 - arch/h8300/include/asm/Kbuild| 1 - arch/hexagon/include/asm/Kbuild | 1 - arch/ia64/include/asm/Kbuild | 1 - arch/m32r/include/asm/Kbuild | 1 - arch/m68k/include/asm/Kbuild | 1 - arch/metag/include/asm/Kbuild| 1 - arch/microblaze/include/asm/Kbuild | 1 - arch/mips/include/asm/Kbuild | 1 - arch/mn10300/include/asm/Kbuild | 1 - arch/nios2/include/asm/Kbuild| 1 - arch/openrisc/include/asm/Kbuild | 1 - arch/parisc/include/asm/Kbuild | 1 - arch/powerpc/include/asm/mm-arch-hooks.h | 28 arch/powerpc/kernel/vdso.c | 25 + arch/powerpc/kernel/vdso_common.c| 1 + arch/s390/include/asm/Kbuild | 1 - arch/score/include/asm/Kbuild| 1 - arch/sh/include/asm/Kbuild | 1 - arch/sparc/include/asm/Kbuild| 1 - arch/tile/include/asm/Kbuild | 1 - arch/um/include/asm/Kbuild | 1 - arch/unicore32/include/asm/Kbuild| 1 - arch/x86/include/asm/Kbuild | 1 - arch/xtensa/include/asm/Kbuild | 1 - include/asm-generic/mm-arch-hooks.h | 16 include/linux/mm-arch-hooks.h| 25 - mm/mremap.c | 4 36 files changed, 26 insertions(+), 103 deletions(-) delete mode 100644 arch/powerpc/include/asm/mm-arch-hooks.h delete mode 100644 include/asm-generic/mm-arch-hooks.h delete mode 100644 include/linux/mm-arch-hooks.h diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild index bf8475ce85ee..0a5e0ec2842b 100644 --- a/arch/alpha/include/asm/Kbuild +++ b/arch/alpha/include/asm/Kbuild @@ -6,7 +6,6 @@ generic-y += exec.h generic-y += export.h generic-y += irq_work.h generic-y += mcs_spinlock.h -generic-y += mm-arch-hooks.h generic-y += preempt.h generic-y += sections.h generic-y += trace_clock.h diff --git a/arch/arc/include/asm/Kbuild b/arch/arc/include/asm/Kbuild index c332604606dd..e6059a808463 100644 --- a/arch/arc/include/asm/Kbuild +++ b/arch/arc/include/asm/Kbuild @@ -22,7 +22,6 @@ generic-y += kvm_para.h generic-y += local.h generic-y += local64.h generic-y += mcs_spinlock.h -generic-y += mm-arch-hooks.h generic-y += mman.h generic-y += msgbuf.h generic-y += msi.h diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 0745538b26d3..44b717cb4a55 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -15,7 +15,6 @@ generic-y += irq_regs.h generic-y += kdebug.h generic-y += local.h generic-y += local64.h -generic-y += mm-arch-hooks.h generic-y += msgbuf.h generic-y += msi.h generic-y += param.h diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild index 44e1d7f10add..a42a1367aea4 100644 --- a/arch/arm64/include/asm/Kbuild +++ b/arch/arm64/include/asm/Kbuild @@ -20,7 +20,6 @@ generic-y += kvm_para.h generic-y += local.h generic-y += local64.h generic-y += mcs_spinlock.h -generic-y += mm-arch-hooks.h generic-y += mman.h generic-y += msgbuf.h generic-y += msi.h diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index 241b9b9729d8..519810d0d5e1 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -12,7 +12,6 @@ generic-y += irq_work.h generic-y += local.h generic-y += local64.h generic-y += mcs_spinlock.h -generic-y += mm-arch-hooks.h generic-y += param.h generic-y += percpu.h generic-y += preempt.h diff --git a/arch/blackfin/include/asm/Kbuild b/arch/blackfin/include/asm/Kbuild index 91d49c0a3118..c80181e4454f 100644 --- a/arch/blackfin/include/asm/Kbuild +++ b/arch/blackfin/include/asm/Kbuild @@ -21,7 +21,6 @@ generic-y += kvm_para.h generic-y += local.h generic-y += local64.h generic-y += mcs_spinlock.h -generic-y += mm-arch-hooks.h generic-y += mman.h generic-y += msgbuf.h
Re: [PATCH net-next] ibmveth: v1 calculate correct gso_size and set gso_type
On 10/27/2016 10:26 AM, Eric Dumazet wrote: > On Wed, 2016-10-26 at 11:09 +1100, Jon Maxwell wrote: >> We recently encountered a bug where a few customers using ibmveth on the >> same LPAR hit an issue where a TCP session hung when large receive was >> enabled. Closer analysis revealed that the session was stuck because the >> one side was advertising a zero window repeatedly. >> >> We narrowed this down to the fact the ibmveth driver did not set gso_size >> which is translated by TCP into the MSS later up the stack. The MSS is >> used to calculate the TCP window size and as that was abnormally large, >> it was calculating a zero window, even although the sockets receive buffer >> was completely empty. >> >> We were able to reproduce this and worked with IBM to fix this. Thanks Tom >> and Marcelo for all your help and review on this. >> >> The patch fixes both our internal reproduction tests and our customers tests. >> >> Signed-off-by: Jon Maxwell >> --- >> drivers/net/ethernet/ibm/ibmveth.c | 20 >> 1 file changed, 20 insertions(+) >> >> diff --git a/drivers/net/ethernet/ibm/ibmveth.c >> b/drivers/net/ethernet/ibm/ibmveth.c >> index 29c05d0..c51717e 100644 >> --- a/drivers/net/ethernet/ibm/ibmveth.c >> +++ b/drivers/net/ethernet/ibm/ibmveth.c >> @@ -1182,6 +1182,8 @@ static int ibmveth_poll(struct napi_struct *napi, int >> budget) >> int frames_processed = 0; >> unsigned long lpar_rc; >> struct iphdr *iph; >> +bool large_packet = 0; >> +u16 hdr_len = ETH_HLEN + sizeof(struct tcphdr); >> >> restart_poll: >> while (frames_processed < budget) { >> @@ -1236,10 +1238,28 @@ static int ibmveth_poll(struct napi_struct *napi, >> int budget) >> iph->check = 0; >> iph->check = >> ip_fast_csum((unsigned char *)iph, iph->ihl); >> adapter->rx_large_packets++; >> +large_packet = 1; >> } >> } >> } >> >> +if (skb->len > netdev->mtu) { >> +iph = (struct iphdr *)skb->data; >> +if (be16_to_cpu(skb->protocol) == ETH_P_IP && >> +iph->protocol == IPPROTO_TCP) { >> +hdr_len += sizeof(struct iphdr); >> +skb_shinfo(skb)->gso_type = >> SKB_GSO_TCPV4; >> +skb_shinfo(skb)->gso_size = netdev->mtu >> - hdr_len; >> +} else if (be16_to_cpu(skb->protocol) == >> ETH_P_IPV6 && >> + iph->protocol == IPPROTO_TCP) { >> +hdr_len += sizeof(struct ipv6hdr); >> +skb_shinfo(skb)->gso_type = >> SKB_GSO_TCPV6; >> +skb_shinfo(skb)->gso_size = netdev->mtu >> - hdr_len; >> +} >> +if (!large_packet) >> +adapter->rx_large_packets++; >> +} >> + >> > This might break forwarding and PMTU discovery. > > You force gso_size to device mtu, regardless of real MSS used by the TCP > sender. > > Don't you have the MSS provided in RX descriptor, instead of guessing > the value ? > > > The MSS is not always available unfortunately, so this is the best solution there is at the moment.
Re: [PATCH net-next] ibmveth: v1 calculate correct gso_size and set gso_type
On Thu, 2016-10-27 at 12:54 -0500, Thomas Falcon wrote: > On 10/27/2016 10:26 AM, Eric Dumazet wrote: > > On Wed, 2016-10-26 at 11:09 +1100, Jon Maxwell wrote: > >> We recently encountered a bug where a few customers using ibmveth on the > >> same LPAR hit an issue where a TCP session hung when large receive was > >> enabled. Closer analysis revealed that the session was stuck because the > >> one side was advertising a zero window repeatedly. > >> > >> We narrowed this down to the fact the ibmveth driver did not set gso_size > >> which is translated by TCP into the MSS later up the stack. The MSS is > >> used to calculate the TCP window size and as that was abnormally large, > >> it was calculating a zero window, even although the sockets receive buffer > >> was completely empty. > >> > >> We were able to reproduce this and worked with IBM to fix this. Thanks Tom > >> and Marcelo for all your help and review on this. > >> > >> The patch fixes both our internal reproduction tests and our customers > >> tests. > >> > >> Signed-off-by: Jon Maxwell > >> --- > >> drivers/net/ethernet/ibm/ibmveth.c | 20 > >> 1 file changed, 20 insertions(+) > >> > >> diff --git a/drivers/net/ethernet/ibm/ibmveth.c > >> b/drivers/net/ethernet/ibm/ibmveth.c > >> index 29c05d0..c51717e 100644 > >> --- a/drivers/net/ethernet/ibm/ibmveth.c > >> +++ b/drivers/net/ethernet/ibm/ibmveth.c > >> @@ -1182,6 +1182,8 @@ static int ibmveth_poll(struct napi_struct *napi, > >> int budget) > >>int frames_processed = 0; > >>unsigned long lpar_rc; > >>struct iphdr *iph; > >> + bool large_packet = 0; > >> + u16 hdr_len = ETH_HLEN + sizeof(struct tcphdr); > >> > >> restart_poll: > >>while (frames_processed < budget) { > >> @@ -1236,10 +1238,28 @@ static int ibmveth_poll(struct napi_struct *napi, > >> int budget) > >>iph->check = 0; > >>iph->check = > >> ip_fast_csum((unsigned char *)iph, iph->ihl); > >>adapter->rx_large_packets++; > >> + large_packet = 1; > >>} > >>} > >>} > >> > >> + if (skb->len > netdev->mtu) { > >> + iph = (struct iphdr *)skb->data; > >> + if (be16_to_cpu(skb->protocol) == ETH_P_IP && > >> + iph->protocol == IPPROTO_TCP) { > >> + hdr_len += sizeof(struct iphdr); > >> + skb_shinfo(skb)->gso_type = > >> SKB_GSO_TCPV4; > >> + skb_shinfo(skb)->gso_size = netdev->mtu > >> - hdr_len; > >> + } else if (be16_to_cpu(skb->protocol) == > >> ETH_P_IPV6 && > >> + iph->protocol == IPPROTO_TCP) { > >> + hdr_len += sizeof(struct ipv6hdr); > >> + skb_shinfo(skb)->gso_type = > >> SKB_GSO_TCPV6; > >> + skb_shinfo(skb)->gso_size = netdev->mtu > >> - hdr_len; > >> + } > >> + if (!large_packet) > >> + adapter->rx_large_packets++; > >> + } > >> + > >> > > This might break forwarding and PMTU discovery. > > > > You force gso_size to device mtu, regardless of real MSS used by the TCP > > sender. > > > > Don't you have the MSS provided in RX descriptor, instead of guessing > > the value ? > > > > > > > The MSS is not always available unfortunately, so this is the best solution > there is at the moment. Hmm... then what about skb_shinfo(skb)->gso_segs ? ip_rcv() for example has : __IP_ADD_STATS(net, IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK), max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs)); Also prefer : (skb->protocol == htons(ETH_P_IP)) tests And the ipv6 test is wrong : } else if (be16_to_cpu(skb->protocol) == ETH_P_IPV6 && iph->protocol == IPPROTO_TCP) { Since iph is a pointer to ipv4 iphdr .
Re: [PATCH 0/7] powerpc/mm: refactor vDSO mapping code
2016-10-25 18:50 GMT+03:00 Dmitry Safonov : > Cleanup patches for vDSO on powerpc. > Originally, I wanted to add vDSO remapping on arm/aarch64 and > I decided to cleanup that part on powerpc. > I've add a hook for vm_ops for vDSO just like I did for x86. > Other changes - reduce exhaustive code duplication. > No visible to userspace changes expected. > > Tested on qemu with buildroot rootfs. > > Dmitry Safonov (7): > powerpc/vdso: unify return paths in setup_additional_pages > powerpc/vdso: remove unused params in vdso_do_func_patch{32,64} > powerpc/vdso: separate common code in vdso_common > powerpc/vdso: introduce init_vdso{32,64}_pagelist > powerpc/vdso: split map_vdso from arch_setup_additional_pages > powerpc/vdso: switch from legacy_special_mapping_vmops > mm: kill arch_mremap Ignore this version, please - I've just sent v3 with some new fixes.
[v13, 1/8] dt: bindings: update Freescale DCFG compatible
Update Freescale DCFG compatible with 'fsl,-dcfg' instead of 'fsl,ls1021a-dcfg' to include more chips such as ls1021a, ls1043a, and ls2080a. Signed-off-by: Yangbo Lu Acked-by: Rob Herring Signed-off-by: Scott Wood --- Changes for v8: - Added this patch Changes for v9: - Added a list for the possible compatibles Changes for v10: - None Changes for v11: - Added 'Acked-by: Rob Herring' - Updated commit message by Scott Changes for v12: - None Changes for v13: - None --- Documentation/devicetree/bindings/arm/fsl.txt | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt index dbbc095..713c1ae 100644 --- a/Documentation/devicetree/bindings/arm/fsl.txt +++ b/Documentation/devicetree/bindings/arm/fsl.txt @@ -119,7 +119,11 @@ Freescale DCFG configuration and status for the device. Such as setting the secondary core start address and release the secondary core from holdoff and startup. Required properties: - - compatible: should be "fsl,ls1021a-dcfg" + - compatible: should be "fsl,-dcfg" +Possible compatibles: + "fsl,ls1021a-dcfg" + "fsl,ls1043a-dcfg" + "fsl,ls2080a-dcfg" - reg : should contain base address and length of DCFG memory-mapped registers Example: -- 2.1.0.27.g96db324
[v13, 0/8] Fix eSDHC host version register bug
This patchset is used to fix a host version register bug in the T4240-R1.0-R2.0 eSDHC controller. To match the SoC version and revision, 10 previous version patchsets had tried many methods but all of them were rejected by reviewers. Such as - dts compatible method - syscon method - ifdef PPC method - GUTS driver getting SVR method Anrd suggested a soc_device_match method in v10, and this is the only available method left now. This v11 patchset introduces the soc_device_match interface in soc driver. The first six patches of Yangbo are to add the GUTS driver. This is used to register a soc device which contain soc version and revision information. The other two patches introduce the soc_device_match method in soc driver and apply it on esdhc driver to fix this bug. Arnd Bergmann (1): base: soc: introduce soc_device_match() interface Yangbo Lu (7): dt: bindings: update Freescale DCFG compatible ARM64: dts: ls2080a: add device configuration node dt: bindings: move guts devicetree doc out of powerpc directory powerpc/fsl: move mpc85xx.h to include/linux/fsl soc: fsl: add GUTS driver for QorIQ platforms MAINTAINERS: add entry for Freescale SoC drivers mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0 Documentation/devicetree/bindings/arm/fsl.txt | 6 +- .../bindings/{powerpc => soc}/fsl/guts.txt | 3 + MAINTAINERS| 11 +- arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- drivers/base/Kconfig | 1 + drivers/base/soc.c | 66 ++ drivers/clk/clk-qoriq.c| 3 +- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/iommu/fsl_pamu.c | 3 +- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-esdhc.c | 20 ++ drivers/net/ethernet/freescale/gianfar.c | 2 +- drivers/soc/Kconfig| 3 +- drivers/soc/fsl/Kconfig| 18 ++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/guts.c | 236 + include/linux/fsl/guts.h | 125 ++- .../asm/mpc85xx.h => include/linux/fsl/svr.h | 4 +- include/linux/sys_soc.h| 3 + 21 files changed, 456 insertions(+), 62 deletions(-) rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%) create mode 100644 drivers/soc/fsl/Kconfig create mode 100644 drivers/soc/fsl/guts.c rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%) -- 2.1.0.27.g96db324
[v13, 2/8] ARM64: dts: ls2080a: add device configuration node
Add the dts node for device configuration unit that provides general purpose configuration and status for the device. Signed-off-by: Yangbo Lu Acked-by: Scott Wood --- Changes for v5: - Added this patch Changes for v6: - None Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - None Changes for v12: - None Changes for v13: - None --- arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index 337da90..c03b099 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -215,6 +215,12 @@ clocks = <&sysclk>; }; + dcfg: dcfg@1e0 { + compatible = "fsl,ls2080a-dcfg", "syscon"; + reg = <0x0 0x1e0 0x0 0x1>; + little-endian; + }; + serial0: serial@21c0500 { compatible = "fsl,ns16550", "ns16550a"; reg = <0x0 0x21c0500 0x0 0x100>; -- 2.1.0.27.g96db324
[v13, 3/8] dt: bindings: move guts devicetree doc out of powerpc directory
Move guts devicetree doc to Documentation/devicetree/bindings/soc/fsl/ since it's used by not only PowerPC but also ARM. And add a specification for 'little-endian' property. Signed-off-by: Yangbo Lu Acked-by: Rob Herring Acked-by: Scott Wood --- Changes for v4: - Added this patch Changes for v5: - Modified the description for little-endian property Changes for v6: - None Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' - Added 'Acked-by: Rob Herring' Changes for v9: - None Changes for v10: - None Changes for v11: - None Changes for v12: - None Changes for v13: - None --- Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt | 3 +++ 1 file changed, 3 insertions(+) rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt b/Documentation/devicetree/bindings/soc/fsl/guts.txt similarity index 91% rename from Documentation/devicetree/bindings/powerpc/fsl/guts.txt rename to Documentation/devicetree/bindings/soc/fsl/guts.txt index b71b203..07adca9 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt +++ b/Documentation/devicetree/bindings/soc/fsl/guts.txt @@ -25,6 +25,9 @@ Recommended properties: - fsl,liodn-bits : Indicates the number of defined bits in the LIODN registers, for those SOCs that have a PAMU device. + - little-endian : Indicates that the global utilities block is little + endian. The default is big endian. + Examples: global-utilities@e {/* global utilities block */ compatible = "fsl,mpc8548-guts"; -- 2.1.0.27.g96db324
[v13, 4/8] powerpc/fsl: move mpc85xx.h to include/linux/fsl
Move mpc85xx.h to include/linux/fsl and rename it to svr.h as a common header file. This SVR numberspace is used on some ARM chips as well as PPC, and even to check for a PPC SVR multi-arch drivers would otherwise need to ifdef the header inclusion and all references to the SVR symbols. Signed-off-by: Yangbo Lu Acked-by: Wolfram Sang Acked-by: Stephen Boyd Acked-by: Joerg Roedel [scottwood: update description] Signed-off-by: Scott Wood --- Changes for v2: - None Changes for v3: - None Changes for v4: - None Changes for v5: - Changed to Move mpc85xx.h to include/linux/fsl/ - Adjusted '#include ' position in file Changes for v6: - None Changes for v7: - Added 'Acked-by: Wolfram Sang' for I2C part - Also applied to arch/powerpc/kernel/cpu_setup_fsl_booke.S Changes for v8: - Added 'Acked-by: Stephen Boyd' for clk part - Added 'Acked-by: Scott Wood' - Added 'Acked-by: Joerg Roedel' for iommu part Changes for v9: - None Changes for v10: - None Changes for v11: - Updated description by Scott Changes for v12: - None Changes for v13: - None --- arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- drivers/clk/clk-qoriq.c | 3 +-- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/iommu/fsl_pamu.c | 3 +-- drivers/net/ethernet/freescale/gianfar.c | 2 +- arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h | 4 ++-- 7 files changed, 8 insertions(+), 10 deletions(-) rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%) diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index 462aed9..2b0284e 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -13,13 +13,13 @@ * */ +#include #include #include #include #include #include #include -#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index d3a5974..cb0efea 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 20b1055..dc778e8 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -1153,8 +1154,6 @@ static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data) } #ifdef CONFIG_PPC -#include - static const u32 a4510_svrs[] __initconst = { (SVR_P2040 << 8) | 0x10,/* P2040 1.0 */ (SVR_P2040 << 8) | 0x11,/* P2040 1.1 */ diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 565a49a..e791c51 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -27,9 +27,9 @@ #include #include #include +#include #include -#include #include #define DRV_NAME "mpc-i2c" diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index a34355f..af8fb27 100644 --- a/drivers/iommu/fsl_pamu.c +++ b/drivers/iommu/fsl_pamu.c @@ -21,11 +21,10 @@ #include "fsl_pamu.h" #include +#include #include #include -#include - /* define indexes for each operation mapping scenario */ #define OMI_QMAN0x00 #define OMI_FMAN0x01 diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4b4f5bc..55be5ce 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -86,11 +86,11 @@ #include #include #include +#include #include #ifdef CONFIG_PPC #include -#include #endif #include #include diff --git a/arch/powerpc/include/asm/mpc85xx.h b/include/linux/fsl/svr.h similarity index 97% rename from arch/powerpc/include/asm/mpc85xx.h rename to include/linux/fsl/svr.h index 213f3a8..8d13836 100644 --- a/arch/powerpc/include/asm/mpc85xx.h +++ b/include/linux/fsl/svr.h @@ -9,8 +9,8 @@ * (at your option) any later version. */ -#ifndef __ASM_PPC_MPC85XX_H -#define __ASM_PPC_MPC85XX_H +#ifndef FSL_SVR_H +#define FSL_SVR_H #define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ #define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ -- 2.1.0.27.g96db324
[v13, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
The global utilities block controls power management, I/O device enabling, power-onreset(POR) configuration monitoring, alternate function selection for multiplexed signals,and clock control. This patch adds a driver to manage and access global utilities block. Initially only reading SVR and registering soc device are supported. Other guts accesses, such as reading RCW, should eventually be moved into this driver as well. Signed-off-by: Yangbo Lu --- Changes for v4: - Added this patch Changes for v5: - Modified copyright info - Changed MODULE_LICENSE to GPL - Changed EXPORT_SYMBOL_GPL to EXPORT_SYMBOL - Made FSL_GUTS user-invisible - Added a complete compatible list for GUTS - Stored guts info in file-scope variable - Added mfspr() getting SVR - Redefined GUTS APIs - Called fsl_guts_init rather than using platform driver - Removed useless parentheses - Removed useless 'extern' key words Changes for v6: - Made guts thread safe in fsl_guts_init Changes for v7: - Removed 'ifdef' for function declaration in guts.h Changes for v8: - Fixes lines longer than 80 characters checkpatch issue - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - Changed to platform driver Changes for v12: - Removed "signed-off-by: Scott" - Defined fsl_soc_die_attr struct array instead of soc_device_attribute - Re-designed soc_device_attribute for QorIQ SoC - Other minor fixes Changes for v13: - Rebased - Removed text after 'bool' in Kconfig - Removed ARCH ifdefs - Added more bits for ls1021a mask - Used devm --- drivers/soc/Kconfig | 3 +- drivers/soc/fsl/Kconfig | 18 drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/guts.c | 236 +++ include/linux/fsl/guts.h | 125 +++-- 5 files changed, 333 insertions(+), 50 deletions(-) create mode 100644 drivers/soc/fsl/Kconfig create mode 100644 drivers/soc/fsl/guts.c diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index e6e90e8..f31bceb 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,8 +1,7 @@ menu "SOC (System On Chip) specific Drivers" source "drivers/soc/bcm/Kconfig" -source "drivers/soc/fsl/qbman/Kconfig" -source "drivers/soc/fsl/qe/Kconfig" +source "drivers/soc/fsl/Kconfig" source "drivers/soc/mediatek/Kconfig" source "drivers/soc/qcom/Kconfig" source "drivers/soc/rockchip/Kconfig" diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig new file mode 100644 index 000..7a9fb9b --- /dev/null +++ b/drivers/soc/fsl/Kconfig @@ -0,0 +1,18 @@ +# +# Freescale SOC drivers +# + +source "drivers/soc/fsl/qbman/Kconfig" +source "drivers/soc/fsl/qe/Kconfig" + +config FSL_GUTS + bool + select SOC_BUS + help + The global utilities block controls power management, I/O device + enabling, power-onreset(POR) configuration monitoring, alternate + function selection for multiplexed signals,and clock control. + This driver is to manage and access global utilities block. + Initially only reading SVR and registering soc device are supported. + Other guts accesses, such as reading RCW, should eventually be moved + into this driver as well. diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 75e1f53..44b3beb 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_GUTS) += guts.o diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c new file mode 100644 index 000..1f356ed --- /dev/null +++ b/drivers/soc/fsl/guts.c @@ -0,0 +1,236 @@ +/* + * Freescale QorIQ Platforms GUTS Driver + * + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct guts { + struct ccsr_guts __iomem *regs; + bool little_endian; +}; + +struct fsl_soc_die_attr { + char*die; + u32 svr; + u32 mask; +}; + +static struct guts *guts; +static struct soc_device_attribute soc_dev_attr; +static struct soc_device *soc_dev; + + +/* SoC die attribute definition for QorIQ platform */ +static const struct fsl_soc_die_attr fsl_soc_die[] = { + /* +* Power Architecture-based SoCs T Series +*/ + + /* Die: T4240, SoC: T4240/T4160
[v13, 6/8] MAINTAINERS: add entry for Freescale SoC drivers
Add maintainer entry for Freescale SoC drivers including the QE library and the GUTS driver now. Also add maintainer for QE library. Signed-off-by: Yangbo Lu Acked-by: Scott Wood Acked-by: Qiang Zhao --- Changes for v8: - Added this patch Changes for v9: - Added linux-arm mail list - Removed GUTS driver entry Changes for v10: - Changed 'DRIVER' to 'DRIVERS' - Added 'Acked-by' of Scott and Qiang Changes for v11: - None Changes for v12: - None Changes for v13: - None --- MAINTAINERS | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c72fa18..cf3aaee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5037,9 +5037,18 @@ S: Maintained F: drivers/net/ethernet/freescale/fman F: Documentation/devicetree/bindings/powerpc/fsl/fman.txt +FREESCALE SOC DRIVERS +M: Scott Wood +L: linuxppc-dev@lists.ozlabs.org +L: linux-arm-ker...@lists.infradead.org +S: Maintained +F: drivers/soc/fsl/ +F: include/linux/fsl/ + FREESCALE QUICC ENGINE LIBRARY +M: Qiang Zhao L: linuxppc-dev@lists.ozlabs.org -S: Orphan +S: Maintained F: drivers/soc/fsl/qe/ F: include/soc/fsl/*qe*.h F: include/soc/fsl/*ucc*.h -- 2.1.0.27.g96db324
[v13, 7/8] base: soc: introduce soc_device_match() interface
From: Arnd Bergmann We keep running into cases where device drivers want to know the exact version of the a SoC they are currently running on. In the past, this has usually been done through a vendor specific API that can be called by a driver, or by directly accessing some kind of version register that is not part of the device itself but that belongs to a global register area of the chip. Common reasons for doing this include: - A machine is not using devicetree or similar for passing data about on-chip devices, but just announces their presence using boot-time platform devices, and the machine code itself does not care about the revision. - There is existing firmware or boot loaders with existing DT binaries with generic compatible strings that do not identify the particular revision of each device, but the driver knows which SoC revisions include which part. - A prerelease version of a chip has some quirks and we are using the same version of the bootloader and the DT blob on both the prerelease and the final version. An update of the DT binding seems inappropriate because that would involve maintaining multiple copies of the dts and/or bootloader. This patch introduces the soc_device_match() interface that is meant to work like of_match_node() but instead of identifying the version of a device, it identifies the SoC itself using a vendor-agnostic interface. Unlike of_match_node(), we do not do an exact string compare but instead use glob_match() to allow wildcards in strings. Signed-off-by: Arnd Bergmann Signed-off-by: Yangbo Lu Acked-by: Greg Kroah-Hartman --- Changes for v11: - Added this patch for soc match Changes for v12: - Corrected the author - Rewrited soc_device_match with while loop Changes for v13: - Added ack from Greg --- drivers/base/Kconfig| 1 + drivers/base/soc.c | 66 + include/linux/sys_soc.h | 3 +++ 3 files changed, 70 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index fdf44ca..991b21e 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -235,6 +235,7 @@ config GENERIC_CPU_AUTOPROBE config SOC_BUS bool + select GLOB source "drivers/base/regmap/Kconfig" diff --git a/drivers/base/soc.c b/drivers/base/soc.c index b63f23e..0c5cf87 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -13,6 +13,7 @@ #include #include #include +#include static DEFINE_IDA(soc_ida); @@ -159,3 +160,68 @@ static int __init soc_bus_register(void) return bus_register(&soc_bus_type); } core_initcall(soc_bus_register); + +static int soc_device_match_one(struct device *dev, void *arg) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + const struct soc_device_attribute *match = arg; + + if (match->machine && + !glob_match(match->machine, soc_dev->attr->machine)) + return 0; + + if (match->family && + !glob_match(match->family, soc_dev->attr->family)) + return 0; + + if (match->revision && + !glob_match(match->revision, soc_dev->attr->revision)) + return 0; + + if (match->soc_id && + !glob_match(match->soc_id, soc_dev->attr->soc_id)) + return 0; + + return 1; +} + +/* + * soc_device_match - identify the SoC in the machine + * @matches: zero-terminated array of possible matches + * + * returns the first matching entry of the argument array, or NULL + * if none of them match. + * + * This function is meant as a helper in place of of_match_node() + * in cases where either no device tree is available or the information + * in a device node is insufficient to identify a particular variant + * by its compatible strings or other properties. For new devices, + * the DT binding should always provide unique compatible strings + * that allow the use of of_match_node() instead. + * + * The calling function can use the .data entry of the + * soc_device_attribute to pass a structure or function pointer for + * each entry. + */ +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches) +{ + int ret = 0; + + if (!matches) + return NULL; + + while (!ret) { + if (!(matches->machine || matches->family || + matches->revision || matches->soc_id)) + break; + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, + soc_device_match_one); + if (!ret) + matches++; + else + return matches; + } + return NULL; +} +EXPORT_SYMBOL_GPL(soc_device_match); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 2739ccb..9f5eb06 100644 --- a/include/linux/sys_soc.h +++ b/include/linux/sys_soc.h
[v13, 8/8] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
The eSDHC of T4240-R1.0-R2.0 has incorrect vender version and spec version. Acturally the right version numbers should be VVN=0x13 and SVN = 0x1. This patch adds the GUTS driver support for eSDHC driver to match SoC. And fix host version to avoid that incorrect version numbers break down the ADMA data transfer. Signed-off-by: Yangbo Lu Acked-by: Ulf Hansson Acked-by: Scott Wood --- Changes for v2: - Got SVR through iomap instead of dts Changes for v3: - Managed GUTS through syscon instead of iomap in eSDHC driver Changes for v4: - Got SVR by GUTS driver instead of SYSCON Changes for v5: - Changed to get SVR through API fsl_guts_get_svr() - Combined patch 4, patch 5 and patch 6 into one Changes for v6: - Added 'Acked-by: Ulf Hansson' Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - Changed to use soc_device_match Changes for v12: - Matched soc through .family field instead of .soc_id Changes for v13: - None --- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-esdhc.c | 20 2 files changed, 21 insertions(+) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 5274f50..a1135a9 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -144,6 +144,7 @@ config MMC_SDHCI_OF_ESDHC depends on MMC_SDHCI_PLTFM depends on PPC || ARCH_MXC || ARCH_LAYERSCAPE select MMC_SDHCI_IO_ACCESSORS + select FSL_GUTS help This selects the Freescale eSDHC controller support. diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index fb71c86..57bdb9e 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" @@ -28,6 +29,7 @@ struct sdhci_esdhc { u8 vendor_ver; u8 spec_ver; + bool quirk_incorrect_hostver; }; /** @@ -73,6 +75,8 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host, static u16 esdhc_readw_fixup(struct sdhci_host *host, int spec_reg, u32 value) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); u16 ret; int shift = (spec_reg & 0x2) * 8; @@ -80,6 +84,12 @@ static u16 esdhc_readw_fixup(struct sdhci_host *host, ret = value & 0x; else ret = (value >> shift) & 0x; + /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect +* vendor version and spec version information. +*/ + if ((spec_reg == SDHCI_HOST_VERSION) && + (esdhc->quirk_incorrect_hostver)) + ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200; return ret; } @@ -558,6 +568,12 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { .ops = &sdhci_esdhc_le_ops, }; +static struct soc_device_attribute soc_incorrect_hostver[] = { + { .family = "QorIQ T4240", .revision = "1.0", }, + { .family = "QorIQ T4240", .revision = "2.0", }, + { }, +}; + static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host; @@ -571,6 +587,10 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK; + if (soc_device_match(soc_incorrect_hostver)) + esdhc->quirk_incorrect_hostver = true; + else + esdhc->quirk_incorrect_hostver = false; } static int sdhci_esdhc_probe(struct platform_device *pdev) -- 2.1.0.27.g96db324
[PATCH v6 00/11] implement vcpu preempted check
change from v5: spilt x86/kvm patch into guest/host part. introduce kvm_write_guest_offset_cached. fix some typos. rebase patch onto 4.9.2 change from v4: spilt x86 kvm vcpu preempted check into two patches. add documentation patch. add x86 vcpu preempted check patch under xen add s390 vcpu preempted check patch change from v3: add x86 vcpu preempted check patch change from v2: no code change, fix typos, update some comments change from v1: a simplier definition of default vcpu_is_preempted skip mahcine type check on ppc, and add config. remove dedicated macro. add one patch to drop overload of rwsem_spin_on_owner and mutex_spin_on_owner. add more comments thanks boqun and Peter's suggestion. This patch set aims to fix lock holder preemption issues. test-case: perf record -a perf bench sched messaging -g 400 -p && perf report 18.09% sched-messaging [kernel.vmlinux] [k] osq_lock 12.28% sched-messaging [kernel.vmlinux] [k] rwsem_spin_on_owner 5.27% sched-messaging [kernel.vmlinux] [k] mutex_unlock 3.89% sched-messaging [kernel.vmlinux] [k] wait_consider_task 3.64% sched-messaging [kernel.vmlinux] [k] _raw_write_lock_irq 3.41% sched-messaging [kernel.vmlinux] [k] mutex_spin_on_owner.is 2.49% sched-messaging [kernel.vmlinux] [k] system_call We introduce interface bool vcpu_is_preempted(int cpu) and use it in some spin loops of osq_lock, rwsem_spin_on_owner and mutex_spin_on_owner. These spin_on_onwer variant also cause rcu stall before we apply this patch set We also have observed some performace improvements in uninx benchmark tests. PPC test result: 1 copy - 0.94% 2 copy - 7.17% 4 copy - 11.9% 8 copy - 3.04% 16 copy - 15.11% details below: Without patch: 1 copy - File Write 4096 bufsize 8000 maxblocks 2188223.0 KBps (30.0 s, 1 samples) 2 copy - File Write 4096 bufsize 8000 maxblocks 1804433.0 KBps (30.0 s, 1 samples) 4 copy - File Write 4096 bufsize 8000 maxblocks 1237257.0 KBps (30.0 s, 1 samples) 8 copy - File Write 4096 bufsize 8000 maxblocks 1032658.0 KBps (30.0 s, 1 samples) 16 copy - File Write 4096 bufsize 8000 maxblocks 768000.0 KBps (30.1 s, 1 samples) With patch: 1 copy - File Write 4096 bufsize 8000 maxblocks 2209189.0 KBps (30.0 s, 1 samples) 2 copy - File Write 4096 bufsize 8000 maxblocks 1943816.0 KBps (30.0 s, 1 samples) 4 copy - File Write 4096 bufsize 8000 maxblocks 1405591.0 KBps (30.0 s, 1 samples) 8 copy - File Write 4096 bufsize 8000 maxblocks 1065080.0 KBps (30.0 s, 1 samples) 16 copy - File Write 4096 bufsize 8000 maxblocks 904762.0 KBps (30.0 s, 1 samples) X86 test result: test-case after-patch before-patch Execl Throughput |18307.9 lps |11701.6 lps File Copy 1024 bufsize 2000 maxblocks | 1352407.3 KBps | 790418.9 KBps File Copy 256 bufsize 500 maxblocks| 367555.6 KBps | 222867.7 KBps File Copy 4096 bufsize 8000 maxblocks | 3675649.7 KBps | 1780614.4 KBps Pipe Throughput| 11872208.7 lps | 11855628.9 lps Pipe-based Context Switching | 1495126.5 lps | 1490533.9 lps Process Creation |29881.2 lps |28572.8 lps Shell Scripts (1 concurrent) |23224.3 lpm |22607.4 lpm Shell Scripts (8 concurrent) | 3531.4 lpm | 3211.9 lpm System Call Overhead | 10385653.0 lps | 10419979.0 lps Christian Borntraeger (1): s390/spinlock: Provide vcpu_is_preempted Juergen Gross (1): x86, xen: support vcpu preempted check Pan Xinhui (9): kernel/sched: introduce vcpu preempted check interface locking/osq: Drop the overload of osq_lock() kernel/locking: Drop the overload of {mutex,rwsem}_spin_on_owner powerpc/spinlock: support vcpu preempted check x86, paravirt: Add interface to support kvm/xen vcpu preempted check KVM: Introduce kvm_write_guest_offset_cached x86, kvm/x86.c: support vcpu preempted check x86, kernel/kvm.c: support vcpu preempted check Documentation: virtual: kvm: Support vcpu preempted check Documentation/virtual/kvm/msr.txt | 9 - arch/powerpc/include/asm/spinlock.h | 8 arch/s390/include/asm/spinlock.h | 8 arch/s390/kernel/smp.c| 9 +++-- arch/s390/lib/spinlock.c | 25 - arch/x86/include/asm/paravirt_types.h | 2 ++ arch/x86/include/asm/spinlock.h | 8 arch/x86/include/uapi/asm/kvm_para.h | 4 +++- arch/x86/kernel/kvm.c | 12 arch/x86/kernel/paravirt-spinlocks.c | 6 ++ arch/x86/kvm/x86.c| 16 arch/x86/xen/spinlock.c | 3 ++- include/linux/kvm_host.h | 2 ++ include/linux/sched.h | 12 kern
[PATCH v6 01/11] kernel/sched: introduce vcpu preempted check interface
This patch support to fix lock holder preemption issue. For kernel users, we could use bool vcpu_is_preempted(int cpu) to detech if one vcpu is preempted or not. The default implementation is a macro defined by false. So compiler can wrap it out if arch dose not support such vcpu pteempted check. Suggested-by: Peter Zijlstra (Intel) Signed-off-by: Pan Xinhui Acked-by: Christian Borntraeger Tested-by: Juergen Gross --- include/linux/sched.h | 12 1 file changed, 12 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index 348f51b..44c1ce7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -3506,6 +3506,18 @@ static inline void set_task_cpu(struct task_struct *p, unsigned int cpu) #endif /* CONFIG_SMP */ +/* + * In order to deal with a various lock holder preemption issues provide an + * interface to see if a vCPU is currently running or not. + * + * This allows us to terminate optimistic spin loops and block, analogous to + * the native optimistic spin heuristic of testing if the lock owner task is + * running or not. + */ +#ifndef vcpu_is_preempted +#define vcpu_is_preempted(cpu) false +#endif + extern long sched_setaffinity(pid_t pid, const struct cpumask *new_mask); extern long sched_getaffinity(pid_t pid, struct cpumask *mask); -- 2.4.11
[PATCH v6 02/11] locking/osq: Drop the overload of osq_lock()
An over-committed guest with more vCPUs than pCPUs has a heavy overload in osq_lock(). This is because vCPU A hold the osq lock and yield out, vCPU B wait per_cpu node->locked to be set. IOW, vCPU B wait vCPU A to run and unlock the osq lock. Kernel has an interface bool vcpu_is_preempted(int cpu) to see if a vCPU is currently running or not. So break the spin loops on true condition. test case: perf record -a perf bench sched messaging -g 400 -p && perf report before patch: 18.09% sched-messaging [kernel.vmlinux] [k] osq_lock 12.28% sched-messaging [kernel.vmlinux] [k] rwsem_spin_on_owner 5.27% sched-messaging [kernel.vmlinux] [k] mutex_unlock 3.89% sched-messaging [kernel.vmlinux] [k] wait_consider_task 3.64% sched-messaging [kernel.vmlinux] [k] _raw_write_lock_irq 3.41% sched-messaging [kernel.vmlinux] [k] mutex_spin_on_owner.is 2.49% sched-messaging [kernel.vmlinux] [k] system_call after patch: 20.68% sched-messaging [kernel.vmlinux] [k] mutex_spin_on_owner 8.45% sched-messaging [kernel.vmlinux] [k] mutex_unlock 4.12% sched-messaging [kernel.vmlinux] [k] system_call 3.01% sched-messaging [kernel.vmlinux] [k] system_call_common 2.83% sched-messaging [kernel.vmlinux] [k] copypage_power7 2.64% sched-messaging [kernel.vmlinux] [k] rwsem_spin_on_owner 2.00% sched-messaging [kernel.vmlinux] [k] osq_lock Suggested-by: Boqun Feng Signed-off-by: Pan Xinhui Acked-by: Christian Borntraeger Tested-by: Juergen Gross --- kernel/locking/osq_lock.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/kernel/locking/osq_lock.c b/kernel/locking/osq_lock.c index 05a3785..39d1385 100644 --- a/kernel/locking/osq_lock.c +++ b/kernel/locking/osq_lock.c @@ -21,6 +21,11 @@ static inline int encode_cpu(int cpu_nr) return cpu_nr + 1; } +static inline int node_cpu(struct optimistic_spin_node *node) +{ + return node->cpu - 1; +} + static inline struct optimistic_spin_node *decode_cpu(int encoded_cpu_val) { int cpu_nr = encoded_cpu_val - 1; @@ -118,8 +123,11 @@ bool osq_lock(struct optimistic_spin_queue *lock) while (!READ_ONCE(node->locked)) { /* * If we need to reschedule bail... so we can block. +* Use vcpu_is_preempted to detech lock holder preemption issue +* and break. vcpu_is_preempted is a macro defined by false if +* arch does not support vcpu preempted check, */ - if (need_resched()) + if (need_resched() || vcpu_is_preempted(node_cpu(node->prev))) goto unqueue; cpu_relax_lowlatency(); -- 2.4.11
[PATCH v6 03/11] kernel/locking: Drop the overload of {mutex, rwsem}_spin_on_owner
An over-committed guest with more vCPUs than pCPUs has a heavy overload in the two spin_on_owner. This blames on the lock holder preemption issue. Kernel has an interface bool vcpu_is_preempted(int cpu) to see if a vCPU is currently running or not. So break the spin loops on true condition. test-case: perf record -a perf bench sched messaging -g 400 -p && perf report before patch: 20.68% sched-messaging [kernel.vmlinux] [k] mutex_spin_on_owner 8.45% sched-messaging [kernel.vmlinux] [k] mutex_unlock 4.12% sched-messaging [kernel.vmlinux] [k] system_call 3.01% sched-messaging [kernel.vmlinux] [k] system_call_common 2.83% sched-messaging [kernel.vmlinux] [k] copypage_power7 2.64% sched-messaging [kernel.vmlinux] [k] rwsem_spin_on_owner 2.00% sched-messaging [kernel.vmlinux] [k] osq_lock after patch: 9.99% sched-messaging [kernel.vmlinux] [k] mutex_unlock 5.28% sched-messaging [unknown] [H] 0xc00768e0 4.27% sched-messaging [kernel.vmlinux] [k] __copy_tofrom_user_power7 3.77% sched-messaging [kernel.vmlinux] [k] copypage_power7 3.24% sched-messaging [kernel.vmlinux] [k] _raw_write_lock_irq 3.02% sched-messaging [kernel.vmlinux] [k] system_call 2.69% sched-messaging [kernel.vmlinux] [k] wait_consider_task Signed-off-by: Pan Xinhui Acked-by: Christian Borntraeger Tested-by: Juergen Gross --- kernel/locking/mutex.c | 15 +-- kernel/locking/rwsem-xadd.c | 16 +--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index a70b90d..82108f5 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -236,7 +236,13 @@ bool mutex_spin_on_owner(struct mutex *lock, struct task_struct *owner) */ barrier(); - if (!owner->on_cpu || need_resched()) { + /* +* Use vcpu_is_preempted to detech lock holder preemption issue +* and break. vcpu_is_preempted is a macro defined by false if +* arch does not support vcpu preempted check, +*/ + if (!owner->on_cpu || need_resched() || + vcpu_is_preempted(task_cpu(owner))) { ret = false; break; } @@ -261,8 +267,13 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock) rcu_read_lock(); owner = READ_ONCE(lock->owner); + + /* +* As lock holder preemption issue, we both skip spinning if task is not +* on cpu or its cpu is preempted +*/ if (owner) - retval = owner->on_cpu; + retval = owner->on_cpu && !vcpu_is_preempted(task_cpu(owner)); rcu_read_unlock(); /* * if lock->owner is not set, the mutex owner may have just acquired diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 2337b4b..0897179 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c @@ -336,7 +336,11 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) goto done; } - ret = owner->on_cpu; + /* +* As lock holder preemption issue, we both skip spinning if task is not +* on cpu or its cpu is preempted +*/ + ret = owner->on_cpu && !vcpu_is_preempted(task_cpu(owner)); done: rcu_read_unlock(); return ret; @@ -362,8 +366,14 @@ static noinline bool rwsem_spin_on_owner(struct rw_semaphore *sem) */ barrier(); - /* abort spinning when need_resched or owner is not running */ - if (!owner->on_cpu || need_resched()) { + /* +* abort spinning when need_resched or owner is not running or +* owner's cpu is preempted. vcpu_is_preempted is a macro +* defined by false if arch does not support vcpu preempted +* check +*/ + if (!owner->on_cpu || need_resched() || + vcpu_is_preempted(task_cpu(owner))) { rcu_read_unlock(); return false; } -- 2.4.11
[PATCH v6 04/11] powerpc/spinlock: support vcpu preempted check
This is to fix some lock holder preemption issues. Some other locks implementation do a spin loop before acquiring the lock itself. Currently kernel has an interface of bool vcpu_is_preempted(int cpu). It takes the cpu as parameter and return true if the cpu is preempted. Then kernel can break the spin loops upon on the retval of vcpu_is_preempted. As kernel has used this interface, So lets support it. Only pSeries need support it. And the fact is powerNV are built into same kernel image with pSeries. So we need return false if we are runnig as powerNV. The another fact is that lppaca->yiled_count keeps zero on powerNV. So we can just skip the machine type check. Suggested-by: Boqun Feng Suggested-by: Peter Zijlstra (Intel) Signed-off-by: Pan Xinhui --- arch/powerpc/include/asm/spinlock.h | 8 1 file changed, 8 insertions(+) diff --git a/arch/powerpc/include/asm/spinlock.h b/arch/powerpc/include/asm/spinlock.h index fa37fe9..8c1b913 100644 --- a/arch/powerpc/include/asm/spinlock.h +++ b/arch/powerpc/include/asm/spinlock.h @@ -52,6 +52,14 @@ #define SYNC_IO #endif +#ifdef CONFIG_PPC_PSERIES +#define vcpu_is_preempted vcpu_is_preempted +static inline bool vcpu_is_preempted(int cpu) +{ + return !!(be32_to_cpu(lppaca_of(cpu).yield_count) & 1); +} +#endif + static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock) { return lock.slock == 0; -- 2.4.11
[PATCH v6 05/11] s390/spinlock: Provide vcpu_is_preempted
From: Christian Borntraeger this implements the s390 backend for commit "kernel/sched: introduce vcpu preempted check interface" by reworking the existing smp_vcpu_scheduled into arch_vcpu_is_preempted. We can then also get rid of the local cpu_is_preempted function by moving the CIF_ENABLED_WAIT test into arch_vcpu_is_preempted. Signed-off-by: Christian Borntraeger Acked-by: Heiko Carstens --- arch/s390/include/asm/spinlock.h | 8 arch/s390/kernel/smp.c | 9 +++-- arch/s390/lib/spinlock.c | 25 - 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index 7e9e09f..7ecd890 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h @@ -23,6 +23,14 @@ _raw_compare_and_swap(unsigned int *lock, unsigned int old, unsigned int new) return __sync_bool_compare_and_swap(lock, old, new); } +#ifndef CONFIG_SMP +static inline bool arch_vcpu_is_preempted(int cpu) { return false; } +#else +bool arch_vcpu_is_preempted(int cpu); +#endif + +#define vcpu_is_preempted arch_vcpu_is_preempted + /* * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 35531fe..b988ed1 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -368,10 +368,15 @@ int smp_find_processor_id(u16 address) return -1; } -int smp_vcpu_scheduled(int cpu) +bool arch_vcpu_is_preempted(int cpu) { - return pcpu_running(pcpu_devices + cpu); + if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu)) + return false; + if (pcpu_running(pcpu_devices + cpu)) + return false; + return true; } +EXPORT_SYMBOL(arch_vcpu_is_preempted); void smp_yield_cpu(int cpu) { diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index e5f50a7..e48a48e 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -37,15 +37,6 @@ static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old) asm(".insn rsy,0xeb22,%0,0,%1" : : "d" (old), "Q" (*lock)); } -static inline int cpu_is_preempted(int cpu) -{ - if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu)) - return 0; - if (smp_vcpu_scheduled(cpu)) - return 0; - return 1; -} - void arch_spin_lock_wait(arch_spinlock_t *lp) { unsigned int cpu = SPINLOCK_LOCKVAL; @@ -62,7 +53,7 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) continue; } /* First iteration: check if the lock owner is running. */ - if (first_diag && cpu_is_preempted(~owner)) { + if (first_diag && arch_vcpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; continue; @@ -81,7 +72,7 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) { + if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; } @@ -108,7 +99,7 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) continue; } /* Check if the lock owner is running. */ - if (first_diag && cpu_is_preempted(~owner)) { + if (first_diag && arch_vcpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; continue; @@ -127,7 +118,7 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) * yield the CPU unconditionally. For LPAR rely on the * sense running status. */ - if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) { + if (!MACHINE_IS_LPAR || arch_vcpu_is_preempted(~owner)) { smp_yield_cpu(~owner); first_diag = 0; } @@ -165,7 +156,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) owner = 0; while (1) { if (count-- <= 0) { - if (owner && cpu_is_preempted(~owner)) + if (owner && arch_vcpu_is_preempted(~owner)) smp_yield_cpu(~owner); count = spin_retry; } @@ -211,7 +202,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev) owner = 0; while (1) { if (count-- <= 0) { - if (owner && cpu_is_preempted(~owner)) + if
[PATCH v6 06/11] x86, paravirt: Add interface to support kvm/xen vcpu preempted check
This is to fix some lock holder preemption issues. Some other locks implementation do a spin loop before acquiring the lock itself. Currently kernel has an interface of bool vcpu_is_preempted(int cpu). It takes the cpu as parameter and return true if the cpu is preempted. Then kernel can break the spin loops upon on the retval of vcpu_is_preempted. As kernel has used this interface, So lets support it. To deal with kernel and kvm/xen, add vcpu_is_preempted into struct pv_lock_ops. Then kvm or xen could provide their own implementation to support vcpu_is_preempted. Signed-off-by: Pan Xinhui --- arch/x86/include/asm/paravirt_types.h | 2 ++ arch/x86/include/asm/spinlock.h | 8 arch/x86/kernel/paravirt-spinlocks.c | 6 ++ 3 files changed, 16 insertions(+) diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 0f400c0..38c3bb7 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -310,6 +310,8 @@ struct pv_lock_ops { void (*wait)(u8 *ptr, u8 val); void (*kick)(int cpu); + + bool (*vcpu_is_preempted)(int cpu); }; /* This contains all the paravirt structures: we get a convenient diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h index 921bea7..0526f59 100644 --- a/arch/x86/include/asm/spinlock.h +++ b/arch/x86/include/asm/spinlock.h @@ -26,6 +26,14 @@ extern struct static_key paravirt_ticketlocks_enabled; static __always_inline bool static_key_false(struct static_key *key); +#ifdef CONFIG_PARAVIRT_SPINLOCKS +#define vcpu_is_preempted vcpu_is_preempted +static inline bool vcpu_is_preempted(int cpu) +{ + return pv_lock_ops.vcpu_is_preempted(cpu); +} +#endif + #include /* diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 2c55a00..2f204dd 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c +++ b/arch/x86/kernel/paravirt-spinlocks.c @@ -21,12 +21,18 @@ bool pv_is_native_spin_unlock(void) __raw_callee_save___native_queued_spin_unlock; } +static bool native_vcpu_is_preempted(int cpu) +{ + return 0; +} + struct pv_lock_ops pv_lock_ops = { #ifdef CONFIG_SMP .queued_spin_lock_slowpath = native_queued_spin_lock_slowpath, .queued_spin_unlock = PV_CALLEE_SAVE(__native_queued_spin_unlock), .wait = paravirt_nop, .kick = paravirt_nop, + .vcpu_is_preempted = native_vcpu_is_preempted, #endif /* SMP */ }; EXPORT_SYMBOL(pv_lock_ops); -- 2.4.11
[PATCH v6 07/11] KVM: Introduce kvm_write_guest_offset_cached
It allows us to update some status or field of one struct partially. We can also save one kvm_read_guest_cached if we just update one filed of the struct regardless of its current value. Signed-off-by: Pan Xinhui --- include/linux/kvm_host.h | 2 ++ virt/kvm/kvm_main.c | 20 ++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 01c0b9c..6f00237 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -645,6 +645,8 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, unsigned long len); int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, void *data, unsigned long len); +int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + void *data, int offset, unsigned long len); int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, gpa_t gpa, unsigned long len); int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2907b7b..95308ee 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1972,30 +1972,38 @@ int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, } EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init); -int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, - void *data, unsigned long len) +int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + void *data, int offset, unsigned long len) { struct kvm_memslots *slots = kvm_memslots(kvm); int r; + gpa_t gpa = ghc->gpa + offset; - BUG_ON(len > ghc->len); + BUG_ON(len + offset > ghc->len); if (slots->generation != ghc->generation) kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len); if (unlikely(!ghc->memslot)) - return kvm_write_guest(kvm, ghc->gpa, data, len); + return kvm_write_guest(kvm, gpa, data, len); if (kvm_is_error_hva(ghc->hva)) return -EFAULT; - r = __copy_to_user((void __user *)ghc->hva, data, len); + r = __copy_to_user((void __user *)ghc->hva + offset, data, len); if (r) return -EFAULT; - mark_page_dirty_in_slot(ghc->memslot, ghc->gpa >> PAGE_SHIFT); + mark_page_dirty_in_slot(ghc->memslot, gpa >> PAGE_SHIFT); return 0; } +EXPORT_SYMBOL_GPL(kvm_write_guest_offset_cached); + +int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, + void *data, unsigned long len) +{ + return kvm_write_guest_offset_cached(kvm, ghc, data, 0, len); +} EXPORT_SYMBOL_GPL(kvm_write_guest_cached); int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, -- 2.4.11
[PATCH v6 08/11] x86, kvm/x86.c: support vcpu preempted check
Support the vcpu_is_preempted() functionality under KVM. This will enhance lock performance on overcommitted hosts (more runnable vcpus than physical cpus in the system) as doing busy waits for preempted vcpus will hurt system performance far worse than early yielding. Use one field of struct kvm_steal_time ::preempted to indicate that if one vcpu is running or not. Signed-off-by: Pan Xinhui --- arch/x86/include/uapi/asm/kvm_para.h | 4 +++- arch/x86/kvm/x86.c | 16 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/uapi/asm/kvm_para.h b/arch/x86/include/uapi/asm/kvm_para.h index 94dc8ca..1421a65 100644 --- a/arch/x86/include/uapi/asm/kvm_para.h +++ b/arch/x86/include/uapi/asm/kvm_para.h @@ -45,7 +45,9 @@ struct kvm_steal_time { __u64 steal; __u32 version; __u32 flags; - __u32 pad[12]; + __u8 preempted; + __u8 u8_pad[3]; + __u32 pad[11]; }; #define KVM_STEAL_ALIGNMENT_BITS 5 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e375235..f06e115 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2057,6 +2057,8 @@ static void record_steal_time(struct kvm_vcpu *vcpu) &vcpu->arch.st.steal, sizeof(struct kvm_steal_time return; + vcpu->arch.st.steal.preempted = 0; + if (vcpu->arch.st.steal.version & 1) vcpu->arch.st.steal.version += 1; /* first time write, random junk */ @@ -2810,8 +2812,22 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); } +static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu) +{ + if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED)) + return; + + vcpu->arch.st.steal.preempted = 1; + + kvm_write_guest_offset_cached(vcpu->kvm, &vcpu->arch.st.stime, + &vcpu->arch.st.steal.preempted, + offsetof(struct kvm_steal_time, preempted), + sizeof(vcpu->arch.st.steal.preempted)); +} + void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { + kvm_steal_time_set_preempted(vcpu); kvm_x86_ops->vcpu_put(vcpu); kvm_put_guest_fpu(vcpu); vcpu->arch.last_host_tsc = rdtsc(); -- 2.4.11
[PATCH v6 09/11] x86, kernel/kvm.c: support vcpu preempted check
Support the vcpu_is_preempted() functionality under KVM. This will enhance lock performance on overcommitted hosts (more runnable vcpus than physical cpus in the system) as doing busy waits for preempted vcpus will hurt system performance far worse than early yielding. struct kvm_steal_time::preempted indicate that if one vcpu is running or not after commit("x86, kvm/x86.c: support vcpu preempted check"). unix benchmark result: host: kernel 4.8.1, i5-4570, 4 cpus guest: kernel 4.8.1, 8 vcpus test-case after-patch before-patch Execl Throughput |18307.9 lps |11701.6 lps File Copy 1024 bufsize 2000 maxblocks | 1352407.3 KBps | 790418.9 KBps File Copy 256 bufsize 500 maxblocks| 367555.6 KBps | 222867.7 KBps File Copy 4096 bufsize 8000 maxblocks | 3675649.7 KBps | 1780614.4 KBps Pipe Throughput| 11872208.7 lps | 11855628.9 lps Pipe-based Context Switching | 1495126.5 lps | 1490533.9 lps Process Creation |29881.2 lps |28572.8 lps Shell Scripts (1 concurrent) |23224.3 lpm |22607.4 lpm Shell Scripts (8 concurrent) | 3531.4 lpm | 3211.9 lpm System Call Overhead | 10385653.0 lps | 10419979.0 lps Signed-off-by: Pan Xinhui --- arch/x86/kernel/kvm.c | 12 1 file changed, 12 insertions(+) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index edbbfc8..0b48dd2 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -415,6 +415,15 @@ void kvm_disable_steal_time(void) wrmsr(MSR_KVM_STEAL_TIME, 0, 0); } +static bool kvm_vcpu_is_preempted(int cpu) +{ + struct kvm_steal_time *src; + + src = &per_cpu(steal_time, cpu); + + return !!src->preempted; +} + #ifdef CONFIG_SMP static void __init kvm_smp_prepare_boot_cpu(void) { @@ -471,6 +480,9 @@ void __init kvm_guest_init(void) if (kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { has_steal_clock = 1; pv_time_ops.steal_clock = kvm_steal_clock; +#ifdef CONFIG_PARAVIRT_SPINLOCKS + pv_lock_ops.vcpu_is_preempted = kvm_vcpu_is_preempted; +#endif } if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) -- 2.4.11
[PATCH v6 10/11] x86, xen: support vcpu preempted check
From: Juergen Gross Support the vcpu_is_preempted() functionality under Xen. This will enhance lock performance on overcommitted hosts (more runnable vcpus than physical cpus in the system) as doing busy waits for preempted vcpus will hurt system performance far worse than early yielding. A quick test (4 vcpus on 1 physical cpu doing a parallel build job with "make -j 8") reduced system time by about 5% with this patch. Signed-off-by: Juergen Gross Signed-off-by: Pan Xinhui --- arch/x86/xen/spinlock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 3d6e006..74756bb 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -114,7 +114,6 @@ void xen_uninit_lock_cpu(int cpu) per_cpu(irq_name, cpu) = NULL; } - /* * Our init of PV spinlocks is split in two init functions due to us * using paravirt patching and jump labels patching and having to do @@ -137,6 +136,8 @@ void __init xen_init_spinlocks(void) pv_lock_ops.queued_spin_unlock = PV_CALLEE_SAVE(__pv_queued_spin_unlock); pv_lock_ops.wait = xen_qlock_wait; pv_lock_ops.kick = xen_qlock_kick; + + pv_lock_ops.vcpu_is_preempted = xen_vcpu_stolen; } /* -- 2.4.11
[PATCH v6 11/11] Documentation: virtual: kvm: Support vcpu preempted check
Commit ("x86, kvm: support vcpu preempted check") add one field "__u8 preempted" into struct kvm_steal_time. This field tells if one vcpu is running or not. It is zero if 1) some old KVM deos not support this filed. 2) the vcpu is not preempted. Other values means the vcpu has been preempted. Signed-off-by: Pan Xinhui Acked-by: Radim Krčmář --- Documentation/virtual/kvm/msr.txt | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/virtual/kvm/msr.txt b/Documentation/virtual/kvm/msr.txt index 2a71c8f..ab2ab76 100644 --- a/Documentation/virtual/kvm/msr.txt +++ b/Documentation/virtual/kvm/msr.txt @@ -208,7 +208,9 @@ MSR_KVM_STEAL_TIME: 0x4b564d03 __u64 steal; __u32 version; __u32 flags; - __u32 pad[12]; + __u8 preempted; + __u8 u8_pad[3]; + __u32 pad[11]; } whose data will be filled in by the hypervisor periodically. Only one @@ -232,6 +234,11 @@ MSR_KVM_STEAL_TIME: 0x4b564d03 nanoseconds. Time during which the vcpu is idle, will not be reported as steal time. + preempted: indicate the VCPU who owns this struct is running or + not. Non-zero values mean the VCPU has been preempted. Zero + means the VCPU is not preempted. NOTE, it is always zero if the + the hypervisor doesn't support this field. + MSR_KVM_EOI_EN: 0x4b564d04 data: Bit 0 is 1 when PV end of interrupt is enabled on the vcpu; 0 when disabled. Bit 1 is reserved and must be zero. When PV end of -- 2.4.11
Re: [v13, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
On Fri, 2016-10-28 at 11:32 +0800, Yangbo Lu wrote: > + guts->regs = of_iomap(np, 0); > + if (!guts->regs) > + return -ENOMEM; > + > + /* Register soc device */ > + machine = of_flat_dt_get_machine_name(); > + if (machine) > + soc_dev_attr.machine = devm_kstrdup(dev, machine, > GFP_KERNEL); > + > + svr = fsl_guts_get_svr(); > + soc_die = fsl_soc_die_match(svr, fsl_soc_die); > + if (soc_die) { > + soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, > + "QorIQ %s", soc_die- > >die); > + } else { > + soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, > "QorIQ"); > + } > + soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL, > + "svr:0x%08x", svr); > + soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", > + SVR_MAJ(svr), SVR_MIN(svr)); > + > + soc_dev = soc_device_register(&soc_dev_attr); > + if (IS_ERR(soc_dev)) > + return PTR_ERR(soc_dev); ioremap leaks on this error path. Use devm_ioremap_resource(). -Scott
[v14, 0/8] Fix eSDHC host version register bug
This patchset is used to fix a host version register bug in the T4240-R1.0-R2.0 eSDHC controller. To match the SoC version and revision, 10 previous version patchsets had tried many methods but all of them were rejected by reviewers. Such as - dts compatible method - syscon method - ifdef PPC method - GUTS driver getting SVR method Anrd suggested a soc_device_match method in v10, and this is the only available method left now. This v11 patchset introduces the soc_device_match interface in soc driver. The first six patches of Yangbo are to add the GUTS driver. This is used to register a soc device which contain soc version and revision information. The other two patches introduce the soc_device_match method in soc driver and apply it on esdhc driver to fix this bug. Arnd Bergmann (1): base: soc: introduce soc_device_match() interface Yangbo Lu (7): dt: bindings: update Freescale DCFG compatible ARM64: dts: ls2080a: add device configuration node dt: bindings: move guts devicetree doc out of powerpc directory powerpc/fsl: move mpc85xx.h to include/linux/fsl soc: fsl: add GUTS driver for QorIQ platforms MAINTAINERS: add entry for Freescale SoC drivers mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0 Documentation/devicetree/bindings/arm/fsl.txt | 6 +- .../bindings/{powerpc => soc}/fsl/guts.txt | 3 + MAINTAINERS| 11 +- arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 + arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- drivers/base/Kconfig | 1 + drivers/base/soc.c | 66 ++ drivers/clk/clk-qoriq.c| 3 +- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/iommu/fsl_pamu.c | 3 +- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-esdhc.c | 20 ++ drivers/net/ethernet/freescale/gianfar.c | 2 +- drivers/soc/Kconfig| 3 +- drivers/soc/fsl/Kconfig| 18 ++ drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/guts.c | 238 + include/linux/fsl/guts.h | 125 ++- .../asm/mpc85xx.h => include/linux/fsl/svr.h | 4 +- include/linux/sys_soc.h| 3 + 21 files changed, 458 insertions(+), 62 deletions(-) rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%) create mode 100644 drivers/soc/fsl/Kconfig create mode 100644 drivers/soc/fsl/guts.c rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%) -- 2.1.0.27.g96db324
[v14, 1/8] dt: bindings: update Freescale DCFG compatible
Update Freescale DCFG compatible with 'fsl,-dcfg' instead of 'fsl,ls1021a-dcfg' to include more chips such as ls1021a, ls1043a, and ls2080a. Signed-off-by: Yangbo Lu Acked-by: Rob Herring Signed-off-by: Scott Wood --- Changes for v8: - Added this patch Changes for v9: - Added a list for the possible compatibles Changes for v10: - None Changes for v11: - Added 'Acked-by: Rob Herring' - Updated commit message by Scott Changes for v12: - None Changes for v13: - None Changes for v14: - None --- Documentation/devicetree/bindings/arm/fsl.txt | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt index dbbc095..713c1ae 100644 --- a/Documentation/devicetree/bindings/arm/fsl.txt +++ b/Documentation/devicetree/bindings/arm/fsl.txt @@ -119,7 +119,11 @@ Freescale DCFG configuration and status for the device. Such as setting the secondary core start address and release the secondary core from holdoff and startup. Required properties: - - compatible: should be "fsl,ls1021a-dcfg" + - compatible: should be "fsl,-dcfg" +Possible compatibles: + "fsl,ls1021a-dcfg" + "fsl,ls1043a-dcfg" + "fsl,ls2080a-dcfg" - reg : should contain base address and length of DCFG memory-mapped registers Example: -- 2.1.0.27.g96db324
[v14, 2/8] ARM64: dts: ls2080a: add device configuration node
Add the dts node for device configuration unit that provides general purpose configuration and status for the device. Signed-off-by: Yangbo Lu Acked-by: Scott Wood --- Changes for v5: - Added this patch Changes for v6: - None Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - None Changes for v12: - None Changes for v13: - None Changes for v14: - None --- arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index 337da90..c03b099 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -215,6 +215,12 @@ clocks = <&sysclk>; }; + dcfg: dcfg@1e0 { + compatible = "fsl,ls2080a-dcfg", "syscon"; + reg = <0x0 0x1e0 0x0 0x1>; + little-endian; + }; + serial0: serial@21c0500 { compatible = "fsl,ns16550", "ns16550a"; reg = <0x0 0x21c0500 0x0 0x100>; -- 2.1.0.27.g96db324
[v14, 3/8] dt: bindings: move guts devicetree doc out of powerpc directory
Move guts devicetree doc to Documentation/devicetree/bindings/soc/fsl/ since it's used by not only PowerPC but also ARM. And add a specification for 'little-endian' property. Signed-off-by: Yangbo Lu Acked-by: Rob Herring Acked-by: Scott Wood --- Changes for v4: - Added this patch Changes for v5: - Modified the description for little-endian property Changes for v6: - None Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' - Added 'Acked-by: Rob Herring' Changes for v9: - None Changes for v10: - None Changes for v11: - None Changes for v12: - None Changes for v13: - None Changes for v14: - None --- Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt | 3 +++ 1 file changed, 3 insertions(+) rename Documentation/devicetree/bindings/{powerpc => soc}/fsl/guts.txt (91%) diff --git a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt b/Documentation/devicetree/bindings/soc/fsl/guts.txt similarity index 91% rename from Documentation/devicetree/bindings/powerpc/fsl/guts.txt rename to Documentation/devicetree/bindings/soc/fsl/guts.txt index b71b203..07adca9 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/guts.txt +++ b/Documentation/devicetree/bindings/soc/fsl/guts.txt @@ -25,6 +25,9 @@ Recommended properties: - fsl,liodn-bits : Indicates the number of defined bits in the LIODN registers, for those SOCs that have a PAMU device. + - little-endian : Indicates that the global utilities block is little + endian. The default is big endian. + Examples: global-utilities@e {/* global utilities block */ compatible = "fsl,mpc8548-guts"; -- 2.1.0.27.g96db324
[v14, 4/8] powerpc/fsl: move mpc85xx.h to include/linux/fsl
Move mpc85xx.h to include/linux/fsl and rename it to svr.h as a common header file. This SVR numberspace is used on some ARM chips as well as PPC, and even to check for a PPC SVR multi-arch drivers would otherwise need to ifdef the header inclusion and all references to the SVR symbols. Signed-off-by: Yangbo Lu Acked-by: Wolfram Sang Acked-by: Stephen Boyd Acked-by: Joerg Roedel [scottwood: update description] Signed-off-by: Scott Wood --- Changes for v2: - None Changes for v3: - None Changes for v4: - None Changes for v5: - Changed to Move mpc85xx.h to include/linux/fsl/ - Adjusted '#include ' position in file Changes for v6: - None Changes for v7: - Added 'Acked-by: Wolfram Sang' for I2C part - Also applied to arch/powerpc/kernel/cpu_setup_fsl_booke.S Changes for v8: - Added 'Acked-by: Stephen Boyd' for clk part - Added 'Acked-by: Scott Wood' - Added 'Acked-by: Joerg Roedel' for iommu part Changes for v9: - None Changes for v10: - None Changes for v11: - Updated description by Scott Changes for v12: - None Changes for v13: - None Changes for v14: - None --- arch/powerpc/kernel/cpu_setup_fsl_booke.S | 2 +- arch/powerpc/sysdev/fsl_pci.c | 2 +- drivers/clk/clk-qoriq.c | 3 +-- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/iommu/fsl_pamu.c | 3 +-- drivers/net/ethernet/freescale/gianfar.c | 2 +- arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h | 4 ++-- 7 files changed, 8 insertions(+), 10 deletions(-) rename arch/powerpc/include/asm/mpc85xx.h => include/linux/fsl/svr.h (97%) diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index 462aed9..2b0284e 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -13,13 +13,13 @@ * */ +#include #include #include #include #include #include #include -#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index d3a5974..cb0efea 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index 20b1055..dc778e8 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -1153,8 +1154,6 @@ static struct clk *clockgen_clk_get(struct of_phandle_args *clkspec, void *data) } #ifdef CONFIG_PPC -#include - static const u32 a4510_svrs[] __initconst = { (SVR_P2040 << 8) | 0x10,/* P2040 1.0 */ (SVR_P2040 << 8) | 0x11,/* P2040 1.1 */ diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 565a49a..e791c51 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -27,9 +27,9 @@ #include #include #include +#include #include -#include #include #define DRV_NAME "mpc-i2c" diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index a34355f..af8fb27 100644 --- a/drivers/iommu/fsl_pamu.c +++ b/drivers/iommu/fsl_pamu.c @@ -21,11 +21,10 @@ #include "fsl_pamu.h" #include +#include #include #include -#include - /* define indexes for each operation mapping scenario */ #define OMI_QMAN0x00 #define OMI_FMAN0x01 diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 4b4f5bc..55be5ce 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -86,11 +86,11 @@ #include #include #include +#include #include #ifdef CONFIG_PPC #include -#include #endif #include #include diff --git a/arch/powerpc/include/asm/mpc85xx.h b/include/linux/fsl/svr.h similarity index 97% rename from arch/powerpc/include/asm/mpc85xx.h rename to include/linux/fsl/svr.h index 213f3a8..8d13836 100644 --- a/arch/powerpc/include/asm/mpc85xx.h +++ b/include/linux/fsl/svr.h @@ -9,8 +9,8 @@ * (at your option) any later version. */ -#ifndef __ASM_PPC_MPC85XX_H -#define __ASM_PPC_MPC85XX_H +#ifndef FSL_SVR_H +#define FSL_SVR_H #define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ #define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ -- 2.1.0.27.g96db324
[v14, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
The global utilities block controls power management, I/O device enabling, power-onreset(POR) configuration monitoring, alternate function selection for multiplexed signals,and clock control. This patch adds a driver to manage and access global utilities block. Initially only reading SVR and registering soc device are supported. Other guts accesses, such as reading RCW, should eventually be moved into this driver as well. Signed-off-by: Yangbo Lu --- Changes for v4: - Added this patch Changes for v5: - Modified copyright info - Changed MODULE_LICENSE to GPL - Changed EXPORT_SYMBOL_GPL to EXPORT_SYMBOL - Made FSL_GUTS user-invisible - Added a complete compatible list for GUTS - Stored guts info in file-scope variable - Added mfspr() getting SVR - Redefined GUTS APIs - Called fsl_guts_init rather than using platform driver - Removed useless parentheses - Removed useless 'extern' key words Changes for v6: - Made guts thread safe in fsl_guts_init Changes for v7: - Removed 'ifdef' for function declaration in guts.h Changes for v8: - Fixes lines longer than 80 characters checkpatch issue - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - Changed to platform driver Changes for v12: - Removed "signed-off-by: Scott" - Defined fsl_soc_die_attr struct array instead of soc_device_attribute - Re-designed soc_device_attribute for QorIQ SoC - Other minor fixes Changes for v13: - Rebased - Removed text after 'bool' in Kconfig - Removed ARCH ifdefs - Added more bits for ls1021a mask - Used devm Changes for v14: - Used devm_ioremap_resource --- drivers/soc/Kconfig | 3 +- drivers/soc/fsl/Kconfig | 18 drivers/soc/fsl/Makefile | 1 + drivers/soc/fsl/guts.c | 237 +++ include/linux/fsl/guts.h | 125 +++-- 5 files changed, 334 insertions(+), 50 deletions(-) create mode 100644 drivers/soc/fsl/Kconfig create mode 100644 drivers/soc/fsl/guts.c diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index e6e90e8..f31bceb 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,8 +1,7 @@ menu "SOC (System On Chip) specific Drivers" source "drivers/soc/bcm/Kconfig" -source "drivers/soc/fsl/qbman/Kconfig" -source "drivers/soc/fsl/qe/Kconfig" +source "drivers/soc/fsl/Kconfig" source "drivers/soc/mediatek/Kconfig" source "drivers/soc/qcom/Kconfig" source "drivers/soc/rockchip/Kconfig" diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig new file mode 100644 index 000..7a9fb9b --- /dev/null +++ b/drivers/soc/fsl/Kconfig @@ -0,0 +1,18 @@ +# +# Freescale SOC drivers +# + +source "drivers/soc/fsl/qbman/Kconfig" +source "drivers/soc/fsl/qe/Kconfig" + +config FSL_GUTS + bool + select SOC_BUS + help + The global utilities block controls power management, I/O device + enabling, power-onreset(POR) configuration monitoring, alternate + function selection for multiplexed signals,and clock control. + This driver is to manage and access global utilities block. + Initially only reading SVR and registering soc device are supported. + Other guts accesses, such as reading RCW, should eventually be moved + into this driver as well. diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 75e1f53..44b3beb 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_FSL_DPAA) += qbman/ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ +obj-$(CONFIG_FSL_GUTS) += guts.o diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c new file mode 100644 index 000..16d9744 --- /dev/null +++ b/drivers/soc/fsl/guts.c @@ -0,0 +1,237 @@ +/* + * Freescale QorIQ Platforms GUTS Driver + * + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct guts { + struct ccsr_guts __iomem *regs; + bool little_endian; +}; + +struct fsl_soc_die_attr { + char*die; + u32 svr; + u32 mask; +}; + +static struct guts *guts; +static struct soc_device_attribute soc_dev_attr; +static struct soc_device *soc_dev; + + +/* SoC die attribute definition for QorIQ platform */ +static const struct fsl_soc_die_attr fsl_soc_die[] = { + /* +* Power Architecture-based SoCs T Series
[v14, 6/8] MAINTAINERS: add entry for Freescale SoC drivers
Add maintainer entry for Freescale SoC drivers including the QE library and the GUTS driver now. Also add maintainer for QE library. Signed-off-by: Yangbo Lu Acked-by: Scott Wood Acked-by: Qiang Zhao --- Changes for v8: - Added this patch Changes for v9: - Added linux-arm mail list - Removed GUTS driver entry Changes for v10: - Changed 'DRIVER' to 'DRIVERS' - Added 'Acked-by' of Scott and Qiang Changes for v11: - None Changes for v12: - None Changes for v13: - None Changes for v14: - None --- MAINTAINERS | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index c72fa18..cf3aaee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5037,9 +5037,18 @@ S: Maintained F: drivers/net/ethernet/freescale/fman F: Documentation/devicetree/bindings/powerpc/fsl/fman.txt +FREESCALE SOC DRIVERS +M: Scott Wood +L: linuxppc-dev@lists.ozlabs.org +L: linux-arm-ker...@lists.infradead.org +S: Maintained +F: drivers/soc/fsl/ +F: include/linux/fsl/ + FREESCALE QUICC ENGINE LIBRARY +M: Qiang Zhao L: linuxppc-dev@lists.ozlabs.org -S: Orphan +S: Maintained F: drivers/soc/fsl/qe/ F: include/soc/fsl/*qe*.h F: include/soc/fsl/*ucc*.h -- 2.1.0.27.g96db324
[v14, 7/8] base: soc: introduce soc_device_match() interface
From: Arnd Bergmann We keep running into cases where device drivers want to know the exact version of the a SoC they are currently running on. In the past, this has usually been done through a vendor specific API that can be called by a driver, or by directly accessing some kind of version register that is not part of the device itself but that belongs to a global register area of the chip. Common reasons for doing this include: - A machine is not using devicetree or similar for passing data about on-chip devices, but just announces their presence using boot-time platform devices, and the machine code itself does not care about the revision. - There is existing firmware or boot loaders with existing DT binaries with generic compatible strings that do not identify the particular revision of each device, but the driver knows which SoC revisions include which part. - A prerelease version of a chip has some quirks and we are using the same version of the bootloader and the DT blob on both the prerelease and the final version. An update of the DT binding seems inappropriate because that would involve maintaining multiple copies of the dts and/or bootloader. This patch introduces the soc_device_match() interface that is meant to work like of_match_node() but instead of identifying the version of a device, it identifies the SoC itself using a vendor-agnostic interface. Unlike of_match_node(), we do not do an exact string compare but instead use glob_match() to allow wildcards in strings. Signed-off-by: Arnd Bergmann Signed-off-by: Yangbo Lu Acked-by: Greg Kroah-Hartman --- Changes for v11: - Added this patch for soc match Changes for v12: - Corrected the author - Rewrited soc_device_match with while loop Changes for v13: - Added ack from Greg Changes for v14: - None --- drivers/base/Kconfig| 1 + drivers/base/soc.c | 66 + include/linux/sys_soc.h | 3 +++ 3 files changed, 70 insertions(+) diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index fdf44ca..991b21e 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -235,6 +235,7 @@ config GENERIC_CPU_AUTOPROBE config SOC_BUS bool + select GLOB source "drivers/base/regmap/Kconfig" diff --git a/drivers/base/soc.c b/drivers/base/soc.c index b63f23e..0c5cf87 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -13,6 +13,7 @@ #include #include #include +#include static DEFINE_IDA(soc_ida); @@ -159,3 +160,68 @@ static int __init soc_bus_register(void) return bus_register(&soc_bus_type); } core_initcall(soc_bus_register); + +static int soc_device_match_one(struct device *dev, void *arg) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + const struct soc_device_attribute *match = arg; + + if (match->machine && + !glob_match(match->machine, soc_dev->attr->machine)) + return 0; + + if (match->family && + !glob_match(match->family, soc_dev->attr->family)) + return 0; + + if (match->revision && + !glob_match(match->revision, soc_dev->attr->revision)) + return 0; + + if (match->soc_id && + !glob_match(match->soc_id, soc_dev->attr->soc_id)) + return 0; + + return 1; +} + +/* + * soc_device_match - identify the SoC in the machine + * @matches: zero-terminated array of possible matches + * + * returns the first matching entry of the argument array, or NULL + * if none of them match. + * + * This function is meant as a helper in place of of_match_node() + * in cases where either no device tree is available or the information + * in a device node is insufficient to identify a particular variant + * by its compatible strings or other properties. For new devices, + * the DT binding should always provide unique compatible strings + * that allow the use of of_match_node() instead. + * + * The calling function can use the .data entry of the + * soc_device_attribute to pass a structure or function pointer for + * each entry. + */ +const struct soc_device_attribute *soc_device_match( + const struct soc_device_attribute *matches) +{ + int ret = 0; + + if (!matches) + return NULL; + + while (!ret) { + if (!(matches->machine || matches->family || + matches->revision || matches->soc_id)) + break; + ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, + soc_device_match_one); + if (!ret) + matches++; + else + return matches; + } + return NULL; +} +EXPORT_SYMBOL_GPL(soc_device_match); diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h index 2739ccb..9f5eb06 100644 --- a/include/linux/sys_soc
[v14, 8/8] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
The eSDHC of T4240-R1.0-R2.0 has incorrect vender version and spec version. Acturally the right version numbers should be VVN=0x13 and SVN = 0x1. This patch adds the GUTS driver support for eSDHC driver to match SoC. And fix host version to avoid that incorrect version numbers break down the ADMA data transfer. Signed-off-by: Yangbo Lu Acked-by: Ulf Hansson Acked-by: Scott Wood --- Changes for v2: - Got SVR through iomap instead of dts Changes for v3: - Managed GUTS through syscon instead of iomap in eSDHC driver Changes for v4: - Got SVR by GUTS driver instead of SYSCON Changes for v5: - Changed to get SVR through API fsl_guts_get_svr() - Combined patch 4, patch 5 and patch 6 into one Changes for v6: - Added 'Acked-by: Ulf Hansson' Changes for v7: - None Changes for v8: - Added 'Acked-by: Scott Wood' Changes for v9: - None Changes for v10: - None Changes for v11: - Changed to use soc_device_match Changes for v12: - Matched soc through .family field instead of .soc_id Changes for v13: - None Changes for v14: - None --- drivers/mmc/host/Kconfig | 1 + drivers/mmc/host/sdhci-of-esdhc.c | 20 2 files changed, 21 insertions(+) diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 5274f50..a1135a9 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -144,6 +144,7 @@ config MMC_SDHCI_OF_ESDHC depends on MMC_SDHCI_PLTFM depends on PPC || ARCH_MXC || ARCH_LAYERSCAPE select MMC_SDHCI_IO_ACCESSORS + select FSL_GUTS help This selects the Freescale eSDHC controller support. diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index fb71c86..57bdb9e 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "sdhci-pltfm.h" #include "sdhci-esdhc.h" @@ -28,6 +29,7 @@ struct sdhci_esdhc { u8 vendor_ver; u8 spec_ver; + bool quirk_incorrect_hostver; }; /** @@ -73,6 +75,8 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host, static u16 esdhc_readw_fixup(struct sdhci_host *host, int spec_reg, u32 value) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host); u16 ret; int shift = (spec_reg & 0x2) * 8; @@ -80,6 +84,12 @@ static u16 esdhc_readw_fixup(struct sdhci_host *host, ret = value & 0x; else ret = (value >> shift) & 0x; + /* Workaround for T4240-R1.0-R2.0 eSDHC which has incorrect +* vendor version and spec version information. +*/ + if ((spec_reg == SDHCI_HOST_VERSION) && + (esdhc->quirk_incorrect_hostver)) + ret = (VENDOR_V_23 << SDHCI_VENDOR_VER_SHIFT) | SDHCI_SPEC_200; return ret; } @@ -558,6 +568,12 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { .ops = &sdhci_esdhc_le_ops, }; +static struct soc_device_attribute soc_incorrect_hostver[] = { + { .family = "QorIQ T4240", .revision = "1.0", }, + { .family = "QorIQ T4240", .revision = "2.0", }, + { }, +}; + static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host; @@ -571,6 +587,10 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) esdhc->vendor_ver = (host_ver & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; esdhc->spec_ver = host_ver & SDHCI_SPEC_VER_MASK; + if (soc_device_match(soc_incorrect_hostver)) + esdhc->quirk_incorrect_hostver = true; + else + esdhc->quirk_incorrect_hostver = false; } static int sdhci_esdhc_probe(struct platform_device *pdev) -- 2.1.0.27.g96db324
RE: [v13, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
> -Original Message- > From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc- > ow...@vger.kernel.org] On Behalf Of Scott Wood > Sent: Friday, October 28, 2016 12:46 PM > To: Y.B. Lu; linux-...@vger.kernel.org; ulf.hans...@linaro.org; Arnd > Bergmann > Cc: linuxppc-dev@lists.ozlabs.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-ker...@vger.kernel.org; linux- > c...@vger.kernel.org; linux-...@vger.kernel.org; iommu@lists.linux- > foundation.org; net...@vger.kernel.org; Greg Kroah-Hartman; Mark Rutland; > Rob Herring; Russell King; Jochen Friedrich; Joerg Roedel; Claudiu Manoil; > Bhupesh Sharma; Qiang Zhao; Kumar Gala; Santosh Shilimkar; Leo Li; X.B. > Xie; M.H. Lian > Subject: Re: [v13, 5/8] soc: fsl: add GUTS driver for QorIQ platforms > > On Fri, 2016-10-28 at 11:32 +0800, Yangbo Lu wrote: > > + guts->regs = of_iomap(np, 0); > > + if (!guts->regs) > > + return -ENOMEM; > > + > > + /* Register soc device */ > > + machine = of_flat_dt_get_machine_name(); > > + if (machine) > > + soc_dev_attr.machine = devm_kstrdup(dev, machine, > > GFP_KERNEL); > > + > > + svr = fsl_guts_get_svr(); > > + soc_die = fsl_soc_die_match(svr, fsl_soc_die); > > + if (soc_die) { > > + soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, > > + "QorIQ %s", soc_die- > > >die); > > + } else { > > + soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, > > "QorIQ"); > > + } > > + soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL, > > + "svr:0x%08x", svr); > > + soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", > > + SVR_MAJ(svr), SVR_MIN(svr)); > > + > > + soc_dev = soc_device_register(&soc_dev_attr); > > + if (IS_ERR(soc_dev)) > > + return PTR_ERR(soc_dev); > > ioremap leaks on this error path. Use devm_ioremap_resource(). > [Lu Yangbo-B47093] Ok. I have fixed it in v14. Thanks :) > -Scott > > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" in > the body of a message to majord...@vger.kernel.org More majordomo info at > http://vger.kernel.org/majordomo-info.html
RE: [v13, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
> -Original Message- > From: Y.B. Lu > Sent: Friday, October 28, 2016 2:00 PM > To: 'Scott Wood'; linux-...@vger.kernel.org; ulf.hans...@linaro.org; Arnd > Bergmann > Cc: linuxppc-dev@lists.ozlabs.org; devicet...@vger.kernel.org; linux-arm- > ker...@lists.infradead.org; linux-ker...@vger.kernel.org; linux- > c...@vger.kernel.org; linux-...@vger.kernel.org; iommu@lists.linux- > foundation.org; net...@vger.kernel.org; Greg Kroah-Hartman; Mark Rutland; > Rob Herring; Russell King; Jochen Friedrich; Joerg Roedel; Claudiu Manoil; > Bhupesh Sharma; Qiang Zhao; Kumar Gala; Santosh Shilimkar; Leo Li; X.B. > Xie; M.H. Lian > Subject: RE: [v13, 5/8] soc: fsl: add GUTS driver for QorIQ platforms > > > > > -Original Message- > > From: linux-mmc-ow...@vger.kernel.org [mailto:linux-mmc- > > ow...@vger.kernel.org] On Behalf Of Scott Wood > > Sent: Friday, October 28, 2016 12:46 PM > > To: Y.B. Lu; linux-...@vger.kernel.org; ulf.hans...@linaro.org; Arnd > > Bergmann > > Cc: linuxppc-dev@lists.ozlabs.org; devicet...@vger.kernel.org; > > linux-arm- ker...@lists.infradead.org; linux-ker...@vger.kernel.org; > > linux- c...@vger.kernel.org; linux-...@vger.kernel.org; > > iommu@lists.linux- foundation.org; net...@vger.kernel.org; Greg > > Kroah-Hartman; Mark Rutland; Rob Herring; Russell King; Jochen > > Friedrich; Joerg Roedel; Claudiu Manoil; Bhupesh Sharma; Qiang Zhao; > Kumar Gala; Santosh Shilimkar; Leo Li; X.B. > > Xie; M.H. Lian > > Subject: Re: [v13, 5/8] soc: fsl: add GUTS driver for QorIQ platforms > > > > On Fri, 2016-10-28 at 11:32 +0800, Yangbo Lu wrote: > > > + guts->regs = of_iomap(np, 0); > > > + if (!guts->regs) > > > + return -ENOMEM; > > > + > > > + /* Register soc device */ > > > + machine = of_flat_dt_get_machine_name(); > > > + if (machine) > > > + soc_dev_attr.machine = devm_kstrdup(dev, machine, > > > GFP_KERNEL); > > > + > > > + svr = fsl_guts_get_svr(); > > > + soc_die = fsl_soc_die_match(svr, fsl_soc_die); > > > + if (soc_die) { > > > + soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, > > > + "QorIQ %s", soc_die- > > > >die); > > > + } else { > > > + soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, > > > "QorIQ"); > > > + } > > > + soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL, > > > + "svr:0x%08x", svr); > > > + soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", > > > + SVR_MAJ(svr), SVR_MIN(svr)); > > > + > > > + soc_dev = soc_device_register(&soc_dev_attr); > > > + if (IS_ERR(soc_dev)) > > > + return PTR_ERR(soc_dev); > > > > ioremap leaks on this error path. Use devm_ioremap_resource(). > > > > [Lu Yangbo-B47093] Ok. I have fixed it in v14. Thanks :) [Lu Yangbo-B47093] Sorry, used the wrong error code... Will resent it > > > -Scott > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-mmc" > > in the body of a message to majord...@vger.kernel.org More majordomo > > info at http://vger.kernel.org/majordomo-info.html
[PATCH] powerpc/64: Used named initialisers for ibm_pa_features
The ibm_pa_features array consists of structures that describe which bit and byte in the ibm,pa-features property toggles one or more flags in either the CPU, MMU, or user visible feature flags. Each one consists of 7 values, which are all unsigned long, int or char, meaning the compiler gives us no warning if we assign the wrong values to the wrong elements. In fact we have had a bug here in the past, where we were setting incorrect bits, see commit 6997e57d693b ("powerpc: scan_features() updates incorrect bits for REAL_LE"). So switch to using named initialisers for the structure elements, to reduce the likelihood of future bugs, and hopefully improve readability also. Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) I've tested this but I would appreciate if someone can verify I didn't typo anything when transcribing it. diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index b0245bed6f54..a7b87b6b4ef4 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -156,21 +156,22 @@ static struct ibm_pa_feature { unsigned char pabit; /* bit number (big-endian) */ unsigned char invert; /* if 1, pa bit set => clear feature */ } ibm_pa_features[] __initdata = { - {0, 0, PPC_FEATURE_HAS_MMU, 0, 0, 0, 0}, - {0, 0, PPC_FEATURE_HAS_FPU, 0, 0, 1, 0}, - {CPU_FTR_CTRL, 0, 0, 0, 0, 3, 0}, - {CPU_FTR_NOEXECUTE, 0, 0, 0,0, 6, 0}, - {CPU_FTR_NODSISRALIGN, 0, 0, 0, 1, 1, 1}, - {0, MMU_FTR_CI_LARGE_PAGE, 0, 0,1, 2, 0}, - {CPU_FTR_REAL_LE, 0, PPC_FEATURE_TRUE_LE, 0, 5, 0, 0}, + { .pabyte = 0, .pabit = 0, .cpu_user_ftrs = PPC_FEATURE_HAS_MMU }, + { .pabyte = 0, .pabit = 1, .cpu_user_ftrs = PPC_FEATURE_HAS_FPU }, + { .pabyte = 0, .pabit = 3, .cpu_features = CPU_FTR_CTRL }, + { .pabyte = 0, .pabit = 6, .cpu_features = CPU_FTR_NOEXECUTE }, + { .pabyte = 1, .pabit = 2, .mmu_features = MMU_FTR_CI_LARGE_PAGE }, + { .pabyte = 40, .pabit = 0, .mmu_features = MMU_FTR_TYPE_RADIX }, + { .pabyte = 1, .pabit = 1, .invert = 1, .cpu_features = CPU_FTR_NODSISRALIGN }, + { .pabyte = 5, .pabit = 0, .cpu_features = CPU_FTR_REAL_LE, + .cpu_user_ftrs = PPC_FEATURE_TRUE_LE }, /* * If the kernel doesn't support TM (ie CONFIG_PPC_TRANSACTIONAL_MEM=n), * we don't want to turn on TM here, so we use the *_COMP versions * which are 0 if the kernel doesn't support TM. */ - {CPU_FTR_TM_COMP, 0, 0, -PPC_FEATURE2_HTM_COMP|PPC_FEATURE2_HTM_NOSC_COMP, 22, 0, 0}, - {0, MMU_FTR_TYPE_RADIX, 0, 0, 40, 0, 0}, + { .pabyte = 22, .pabit = 0, .cpu_features = CPU_FTR_TM_COMP, + .cpu_user_ftrs2 = PPC_FEATURE2_HTM_COMP | PPC_FEATURE2_HTM_NOSC_COMP }, }; static void __init scan_features(unsigned long node, const unsigned char *ftrs, -- 2.7.4