Re: [RESEND PATCH v2 3/3] powerpc/powernv: Parse device tree, population of SPR support

2020-01-12 Thread Ram Pai
On Mon, Jan 13, 2020 at 09:15:09AM +0530, Pratik Rajesh Sampat wrote:
> Parse the device tree for nodes self-save, self-restore and populate
> support for the preferred SPRs based what was advertised by the device
> tree.
> 
> Signed-off-by: Pratik Rajesh Sampat 
> ---
>  arch/powerpc/platforms/powernv/idle.c | 104 ++
>  1 file changed, 104 insertions(+)
> 
> diff --git a/arch/powerpc/platforms/powernv/idle.c 
> b/arch/powerpc/platforms/powernv/idle.c
> index d67d4d0b169b..e910ff40b7e6 100644
> --- a/arch/powerpc/platforms/powernv/idle.c
> +++ b/arch/powerpc/platforms/powernv/idle.c
> @@ -1429,6 +1429,107 @@ static void __init pnv_probe_idle_states(void)
>   supported_cpuidle_states |= pnv_idle_states[i].flags;
>  }
> 
> +/*
> + * Extracts and populates the self save or restore capabilities
> + * passed from the device tree node
> + */
> +static int extract_save_restore_state_dt(struct device_node *np, int type)
> +{
> + int nr_sprns = 0, i, bitmask_index;
> + int rc = 0;
> + u64 *temp_u64;
> + const char *state_prop;
> + u64 bit_pos;
> +
> + state_prop = of_get_property(np, "status", NULL);
> + if (!state_prop) {
> + pr_warn("opal: failed to find the active value for self 
> save/restore node");
> + return -EINVAL;
> + }
> + if (strncmp(state_prop, "disabled", 8) == 0) {
> + /*
> +  * if the feature is not active, strip the preferred_sprs from
> +  * that capability.
> +  */
> + if (type == SELF_RESTORE_TYPE) {
> + for (i = 0; i < nr_preferred_sprs; i++) {
> + preferred_sprs[i].supported_mode &=
> + ~SELF_RESTORE_STRICT;
> + }
> + } else {
> + for (i = 0; i < nr_preferred_sprs; i++) {
> + preferred_sprs[i].supported_mode &=
> + ~SELF_SAVE_STRICT;
> + }
> + }
> + return 0;
> + }
> + nr_sprns = of_property_count_u64_elems(np, "sprn-bitmask");
> + if (nr_sprns <= 0)
> + return rc;
> + temp_u64 = kcalloc(nr_sprns, sizeof(u64), GFP_KERNEL);
> + if (of_property_read_u64_array(np, "sprn-bitmask",
> +temp_u64, nr_sprns)) {
> + pr_warn("cpuidle-powernv: failed to find registers in DT\n");
> + kfree(temp_u64);
> + return -EINVAL;
> + }
> + /*
> +  * Populate acknowledgment of support for the sprs in the global vector
> +  * gotten by the registers supplied by the firmware.
> +  * The registers are in a bitmask, bit index within
> +  * that specifies the SPR
> +  */
> + for (i = 0; i < nr_preferred_sprs; i++) {
> + bitmask_index = preferred_sprs[i].spr / 64;
> + bit_pos = preferred_sprs[i].spr % 64;
> + if ((temp_u64[bitmask_index] & (1UL << bit_pos)) == 0) {
> + if (type == SELF_RESTORE_TYPE)
> + preferred_sprs[i].supported_mode &=
> + ~SELF_RESTORE_STRICT;
> + else
> + preferred_sprs[i].supported_mode &=
> + ~SELF_SAVE_STRICT;
> + continue;
> + }
> + if (type == SELF_RESTORE_TYPE) {
> + preferred_sprs[i].supported_mode |=
> + SELF_RESTORE_STRICT;
> + } else {
> + preferred_sprs[i].supported_mode |=
> + SELF_SAVE_STRICT;
> + }
> + }
> +
> + kfree(temp_u64);
> + return rc;
> +}
> +
> +static int pnv_parse_deepstate_dt(void)
> +{
> + struct device_node *np, *np1;
> + int rc = 0;
> +
> + /* Self restore register population */
> + np = of_find_node_by_path("/ibm,opal/power-mgt/self-restore");
> + if (!np) {
> + pr_warn("opal: self restore Node not found");
> + } else {
> + rc = extract_save_restore_state_dt(np, SELF_RESTORE_TYPE);
> + if (rc != 0)
> + return rc;
> + }
> + /* Self save register population */
> + np1 = of_find_node_by_path("/ibm,opal/power-mgt/self-save");

'np' can be reused?  'np1' is not needed.


Otherwise looks good.

Reviewed-by: Ram Pai 

RP



Re: [RESEND PATCH v2 2/3] powerpc/powernv: Introduce Self save support

2020-01-12 Thread Ram Pai
On Mon, Jan 13, 2020 at 09:15:08AM +0530, Pratik Rajesh Sampat wrote:
> This commit introduces and leverages the Self save API which OPAL now
> supports.
> 
> Add the new Self Save OPAL API call in the list of OPAL calls.
> Implement the self saving of the SPRs based on the support populated
> while respecting it's preferences.
> 
> This implementation allows mixing of support for the SPRs, which
> means that a SPR can be self restored while another SPR be self saved if
> they support and prefer it to be so.
> 
> Signed-off-by: Pratik Rajesh Sampat 
> ---
>  arch/powerpc/include/asm/opal-api.h| 3 ++-
>  arch/powerpc/include/asm/opal.h| 1 +
>  arch/powerpc/platforms/powernv/idle.c  | 2 ++
>  arch/powerpc/platforms/powernv/opal-call.c | 1 +
>  4 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/include/asm/opal-api.h 
> b/arch/powerpc/include/asm/opal-api.h
> index c1f25a760eb1..1b6e1a68d431 100644
> --- a/arch/powerpc/include/asm/opal-api.h
> +++ b/arch/powerpc/include/asm/opal-api.h
> @@ -214,7 +214,8 @@
>  #define OPAL_SECVAR_GET  176
>  #define OPAL_SECVAR_GET_NEXT 177
>  #define OPAL_SECVAR_ENQUEUE_UPDATE   178
> -#define OPAL_LAST178
> +#define OPAL_SLW_SELF_SAVE_REG   181
> +#define OPAL_LAST181
> 
>  #define QUIESCE_HOLD 1 /* Spin all calls at entry */
>  #define QUIESCE_REJECT   2 /* Fail all calls with 
> OPAL_BUSY */
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 9986ac34b8e2..389a85b63805 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -203,6 +203,7 @@ int64_t opal_handle_hmi(void);
>  int64_t opal_handle_hmi2(__be64 *out_flags);
>  int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end);
>  int64_t opal_unregister_dump_region(uint32_t id);
> +int64_t opal_slw_self_save_reg(uint64_t cpu_pir, uint64_t sprn);
>  int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);
>  int64_t opal_config_cpu_idle_state(uint64_t state, uint64_t flag);
>  int64_t opal_pci_set_phb_cxl_mode(uint64_t phb_id, uint64_t mode, uint64_t 
> pe_number);
> diff --git a/arch/powerpc/platforms/powernv/idle.c 
> b/arch/powerpc/platforms/powernv/idle.c
> index 2f328403b0dc..d67d4d0b169b 100644
> --- a/arch/powerpc/platforms/powernv/idle.c
> +++ b/arch/powerpc/platforms/powernv/idle.c
> @@ -1172,6 +1172,8 @@ void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 
> lpcr_val)
>   if (!is_lpcr_self_save)
>   opal_slw_set_reg(pir, SPRN_LPCR,
>lpcr_val);
> + else
> + opal_slw_self_save_reg(pir, SPRN_LPCR);

opal_slw_self_save_reg() was used in the prior patch too. How did it
compile, if the definition is in this patch?


Reviewed-by: Ram Pai 

RP



Re: [RESEND PATCH v2 1/3] powerpc/powernv: Interface to define support and preference for a SPR

2020-01-12 Thread Ram Pai
On Mon, Jan 13, 2020 at 09:15:07AM +0530, Pratik Rajesh Sampat wrote:
> Define a bitmask interface to determine support for the Self Restore,
> Self Save or both.
> 
> Also define an interface to determine the preference of that SPR to
> be strictly saved or restored or encapsulated with an order of preference.
> 
> The preference bitmask is shown as below:
> 
> |... | 2nd pref | 1st pref |
> 
> MSB LSB
> 
> The preference from higher to lower is from LSB to MSB with a shift of 8
> bits.
> Example:
> Prefer self save first, if not available then prefer self
> restore
> The preference mask for this scenario will be seen as below.
> ((SELF_RESTORE_STRICT << PREFERENCE_SHIFT) | SELF_SAVE_STRICT)
> -
> |... | Self restore | Self save |
> -
> MSB   LSB
> 
> Finally, declare a list of preferred SPRs which encapsulate the bitmaks
> for preferred and supported with defaults of both being set to support
> legacy firmware.
> 
> This commit also implements using the above interface and retains the
> legacy functionality of self restore.
> 
> Signed-off-by: Pratik Rajesh Sampat 
> ---
>  arch/powerpc/platforms/powernv/idle.c | 327 +-
>  1 file changed, 271 insertions(+), 56 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/powernv/idle.c 
> b/arch/powerpc/platforms/powernv/idle.c
> index 78599bca66c2..2f328403b0dc 100644
> --- a/arch/powerpc/platforms/powernv/idle.c
> +++ b/arch/powerpc/platforms/powernv/idle.c
> @@ -32,9 +32,106 @@
>  #define P9_STOP_SPR_MSR 2000
>  #define P9_STOP_SPR_PSSCR  855
> 
> +/* Interface for the stop state supported and preference */
> +#define SELF_RESTORE_TYPE0
> +#define SELF_SAVE_TYPE   1
> +
> +#define NR_PREFERENCES2
> +#define PREFERENCE_SHIFT  4
> +#define PREFERENCE_MASK   0xf
> +
> +#define UNSUPPORTED 0x0
> +#define SELF_RESTORE_STRICT 0x1
> +#define SELF_SAVE_STRICT0x2
> +
> +/*
> + * Bitmask defining the kind of preferences available.
> + * Note : The higher to lower preference is from LSB to MSB, with a shift of
> + * 4 bits.
> + * 
> + * || 2nd pref | 1st pref |
> + * 
> + * MSB LSB
> + */
> +/* Prefer Restore if available, otherwise unsupported */
> +#define PREFER_SELF_RESTORE_ONLY SELF_RESTORE_STRICT
> +/* Prefer Save if available, otherwise unsupported */
> +#define PREFER_SELF_SAVE_ONLYSELF_SAVE_STRICT
> +/* Prefer Restore when available, otherwise prefer Save */
> +#define PREFER_RESTORE_SAVE  ((SELF_SAVE_STRICT << \
> +   PREFERENCE_SHIFT)\
> +   | SELF_RESTORE_STRICT)
> +/* Prefer Save when available, otherwise prefer Restore*/
> +#define PREFER_SAVE_RESTORE  ((SELF_RESTORE_STRICT <<\
> +   PREFERENCE_SHIFT)\
> +   | SELF_SAVE_STRICT)
>  static u32 supported_cpuidle_states;
>  struct pnv_idle_states_t *pnv_idle_states;
>  int nr_pnv_idle_states;
> +/* Caching the lpcr & ptcr support to use later */
> +static bool is_lpcr_self_save;
> +static bool is_ptcr_self_save;
> +
> +struct preferred_sprs {
> + u64 spr;
> + u32 preferred_mode;
> + u32 supported_mode;
> +};
> +
> +struct preferred_sprs preferred_sprs[] = {
> + {
> + .spr = SPRN_HSPRG0,
> + .preferred_mode = PREFER_RESTORE_SAVE,
> + .supported_mode = SELF_RESTORE_STRICT,
> + },
> + {
> + .spr = SPRN_LPCR,
> + .preferred_mode = PREFER_RESTORE_SAVE,
> + .supported_mode = SELF_RESTORE_STRICT,
> + },
> + {
> + .spr = SPRN_PTCR,
> + .preferred_mode = PREFER_SAVE_RESTORE,
> + .supported_mode = SELF_RESTORE_STRICT,
> + },

This confuses me.  It says SAVE takes precedence over RESTORE.
and than it says it is strictly 'RESTORE' only.

Maybe you should not initialize the 'supported_mode' ?
or put a comment somewhere here, saying this value will be overwritten
during system initialization?


Otherwise the code looks correct.

Reviewed-by: Ram Pai 
RP



Re: [RFC PATCH v2 07/10] lib: vdso: don't use READ_ONCE() in __c_kernel_time()

2020-01-12 Thread Christophe Leroy




Le 11/01/2020 à 12:07, Thomas Gleixner a écrit :

Christophe Leroy  writes:


With READ_ONCE() the 64 bits are being read:

Without the READ_ONCE() only 32 bits are read. That's the most optimal.

Without READ_ONCE() but with a barrier() after the read, we should get
the same result but GCC (GCC 8.1) does less good:

Assuming both part of the 64 bits data will fall into a single
cacheline, the second read is in the noise.


They definitely are in the same cacheline.


So agreed to drop this change.


We could be smart about this and force the compiler to issue a 32bit
read for 32bit builds. See below. Not sure whether it's worth it, but
OTOH it will take quite a while until the 32bit time interfaces die
completely.


I don't think it is worth something so big to just save 1 or 2 cycles in 
time() function. Lets keep it as it is.


Thanks,
Christophe



Thanks,

 tglx

8<
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -21,6 +21,18 @@
  #define CS_RAW1
  #define CS_BASES  (CS_RAW + 1)
  
+#ifdef __LITTLE_ENDIAN

+struct sec_hl {
+   u32 sec_l;
+   u32 sec_h;
+};
+#else
+struct sec_hl {
+   u32 sec_h;
+   u32 sec_l;
+};
+#endif
+
  /**
   * struct vdso_timestamp - basetime per clock_id
   * @sec:  seconds
@@ -35,7 +47,10 @@
   * vdso_data.cs[x].shift.
   */
  struct vdso_timestamp {
-   u64 sec;
+   union {
+   u64 sec;
+   struct sec_hl   sec_hl;
+   };
u64 nsec;
  };
  
--- a/lib/vdso/gettimeofday.c

+++ b/lib/vdso/gettimeofday.c
@@ -165,8 +165,13 @@ static __maybe_unused int
  static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t 
*time)
  {
const struct vdso_data *vd = __arch_get_vdso_data();
-   __kernel_old_time_t t = 
READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
+   __kernel_old_time_t t;
  
+#if BITS_PER_LONG == 32

+   t = READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec_hl.sec_l);
+#else
+   t = READ_ONCE(vd[CS_HRES_COARSE].basetime[CLOCK_REALTIME].sec);
+#endif
if (time)
*time = t;
  



Re: [PATCH 05/18] powerpc sstep: Prepare to support prefixed instructions

2020-01-12 Thread Balamuruhan S
On Tue, Nov 26, 2019 at 04:21:28PM +1100, Jordan Niethe wrote:
> Currently all instructions are a single word long. A future ISA version
> will include prefixed instructions which have a double word length. The
> functions used for analysing and emulating instructions need to be
> modified so that they can handle these new instruction types.
> 
> A prefixed instruction is a word prefix followed by a word suffix. All
> prefixes uniquely have the primary op-code 1. Suffixes may be valid word
> instructions or instructions that only exist as suffixes.
> 
> In handling prefixed instructions it will be convenient to treat the
> suffix and prefix as separate words. To facilitate this modify
> analyse_instr() and emulate_step() to take a take a suffix as a

typo - s/take a take a/take a

> parameter. For word instructions it does not matter what is passed in
> here - it will be ignored.
> 
> We also define a new flag, PREFIXED, to be used in instruction_op:type.
> This flag will indicate when emulating an analysed instruction if the
> NIP should be advanced by word length or double word length.
> 
> The callers of analyse_instr() and emulate_step() will need their own
> changes to be able to support prefixed instructions. For now modify them
> to pass in 0 as a suffix.
> 
> Note that at this point no prefixed instructions are emulated or
> analysed - this is just making it possible to do so.
> 
> Signed-off-by: Jordan Niethe 
> ---
>  arch/powerpc/include/asm/ppc-opcode.h |  3 +++
>  arch/powerpc/include/asm/sstep.h  |  8 +--
>  arch/powerpc/include/asm/uaccess.h| 30 +++
>  arch/powerpc/kernel/align.c   |  2 +-
>  arch/powerpc/kernel/hw_breakpoint.c   |  4 ++--
>  arch/powerpc/kernel/kprobes.c |  2 +-
>  arch/powerpc/kernel/mce_power.c   |  2 +-
>  arch/powerpc/kernel/optprobes.c   |  2 +-
>  arch/powerpc/kernel/uprobes.c |  2 +-
>  arch/powerpc/kvm/emulate_loadstore.c  |  2 +-
>  arch/powerpc/lib/sstep.c  | 12 ++-
>  arch/powerpc/lib/test_emulate_step.c  | 30 +--
>  arch/powerpc/xmon/xmon.c  |  4 ++--
>  13 files changed, 71 insertions(+), 32 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
> b/arch/powerpc/include/asm/ppc-opcode.h
> index c1df75edde44..a1dfa4bdd22f 100644
> --- a/arch/powerpc/include/asm/ppc-opcode.h
> +++ b/arch/powerpc/include/asm/ppc-opcode.h
> @@ -377,6 +377,9 @@
>  #define PPC_INST_VCMPEQUD0x10c7
>  #define PPC_INST_VCMPEQUB0x1006
>  
> +/* macro to check if a word is a prefix */
> +#define IS_PREFIX(x) (((x) >> 26) == 1)
> +
>  /* macros to insert fields into opcodes */
>  #define ___PPC_RA(a) (((a) & 0x1f) << 16)
>  #define ___PPC_RB(b) (((b) & 0x1f) << 11)
> diff --git a/arch/powerpc/include/asm/sstep.h 
> b/arch/powerpc/include/asm/sstep.h
> index 769f055509c9..6d4cb602e231 100644
> --- a/arch/powerpc/include/asm/sstep.h
> +++ b/arch/powerpc/include/asm/sstep.h
> @@ -89,6 +89,9 @@ enum instruction_type {
>  #define VSX_LDLEFT   4   /* load VSX register from left */
>  #define VSX_CHECK_VEC8   /* check MSR_VEC not MSR_VSX for reg >= 
> 32 */
>  
> +/* Prefixed flag, ORed in with type */
> +#define PREFIXED 0x800
> +
>  /* Size field in type word */
>  #define SIZE(n)  ((n) << 12)
>  #define GETSIZE(w)   ((w) >> 12)
> @@ -132,7 +135,7 @@ union vsx_reg {
>   * otherwise.
>   */
>  extern int analyse_instr(struct instruction_op *op, const struct pt_regs 
> *regs,
> -  unsigned int instr);
> +  unsigned int instr, unsigned int sufx);
>  
>  /*
>   * Emulate an instruction that can be executed just by updating
> @@ -149,7 +152,8 @@ void emulate_update_regs(struct pt_regs *reg, struct 
> instruction_op *op);
>   * 0 if it could not be emulated, or -1 for an instruction that
>   * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.).
>   */
> -extern int emulate_step(struct pt_regs *regs, unsigned int instr);
> +extern int emulate_step(struct pt_regs *regs, unsigned int instr,
> + unsigned int sufx);
>  
>  /*
>   * Emulate a load or store instruction by reading/writing the
> diff --git a/arch/powerpc/include/asm/uaccess.h 
> b/arch/powerpc/include/asm/uaccess.h
> index 15002b51ff18..bc585399e0c7 100644
> --- a/arch/powerpc/include/asm/uaccess.h
> +++ b/arch/powerpc/include/asm/uaccess.h
> @@ -423,4 +423,34 @@ extern long __copy_from_user_flushcache(void *dst, const 
> void __user *src,
>  extern void memcpy_page_flushcache(char *to, struct page *page, size_t 
> offset,
>  size_t len);
>  
> +/*
> + * When reading an instruction iff it is a prefix, the suffix needs to be 
> also
> + * loaded.
> + */
> +#define __get_user_instr(x, y, ptr)  \

It will be better to have `__get_user_instr()` and
`__get_user_instr_inatomic()` in separate commit or squashed with patch
[PATCH 10/18] 

[PATCH v2 3/3] powerpc test_emulate_step: add testcases for divde[.] and divdeu[.] instructions

2020-01-12 Thread Balamuruhan S
add testcases for divde, divde., divdeu, divdeu. emulated
instructions to cover few scenarios,
* with same dividend and divisor to have undefine RT
  for divdeu[.]
* with divide by zero to have undefine RT for both
  divde[.] and divdeu[.]
* with negative dividend to cover -|divisor| < r <= 0 if
  the dividend is negative for divde[.]
* normal case with proper dividend and divisor for both
  divde[.] and divdeu[.]

Reviewed-by: Sandipan Das 
Signed-off-by: Balamuruhan S 
---
 arch/powerpc/lib/test_emulate_step.c | 164 +++
 1 file changed, 164 insertions(+)

diff --git a/arch/powerpc/lib/test_emulate_step.c 
b/arch/powerpc/lib/test_emulate_step.c
index 42347067739c..552b62a70e55 100644
--- a/arch/powerpc/lib/test_emulate_step.c
+++ b/arch/powerpc/lib/test_emulate_step.c
@@ -53,6 +53,14 @@
___PPC_RA(a) | ___PPC_RB(b))
 #define TEST_ADDC_DOT(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \
___PPC_RA(a) | ___PPC_RB(b) | 0x1)
+#define TEST_DIVDE(t, a, b)(PPC_INST_DIVDE | ___PPC_RT(t) |\
+   ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_DIVDE_DOT(t, a, b)(PPC_INST_DIVDE_DOT | ___PPC_RT(t) |
\
+   ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_DIVDEU(t, a, b)   (PPC_INST_DIVDEU | ___PPC_RT(t) |   \
+   ___PPC_RA(a) | ___PPC_RB(b))
+#define TEST_DIVDEU_DOT(t, a, b)(PPC_INST_DIVDEU_DOT | ___PPC_RT(t) |  \
+   ___PPC_RA(a) | ___PPC_RB(b))
 
 #define MAX_SUBTESTS   16
 
@@ -837,6 +845,162 @@ static struct compute_test compute_tests[] = {
}
}
}
+   },
+   {
+   .mnemonic = "divde",
+   .subtests = {
+   {
+   .descr = "RA = LONG_MIN, RB = LONG_MIN",
+   .instr = TEST_DIVDE(20, 21, 22),
+   .regs = {
+   .gpr[21] = LONG_MIN,
+   .gpr[22] = LONG_MIN,
+   }
+   },
+   {
+   .descr = "RA = 1L, RB = 0",
+   .instr = TEST_DIVDE(20, 21, 22),
+   .flags = IGNORE_GPR(20),
+   .regs = {
+   .gpr[21] = 1L,
+   .gpr[22] = 0,
+   }
+   },
+   {
+   .descr = "RA = LONG_MIN, RB = LONG_MAX",
+   .instr = TEST_DIVDE(20, 21, 22),
+   .regs = {
+   .gpr[21] = LONG_MIN,
+   .gpr[22] = LONG_MAX,
+   }
+   }
+   }
+   },
+   {
+   .mnemonic = "divde.",
+   .subtests = {
+   {
+   .descr = "RA = LONG_MIN, RB = LONG_MIN",
+   .instr = TEST_DIVDE_DOT(20, 21, 22),
+   .regs = {
+   .gpr[21] = LONG_MIN,
+   .gpr[22] = LONG_MIN,
+   }
+   },
+   {
+   .descr = "RA = 1L, RB = 0",
+   .instr = TEST_DIVDE_DOT(20, 21, 22),
+   .flags = IGNORE_GPR(20),
+   .regs = {
+   .gpr[21] = 1L,
+   .gpr[22] = 0,
+   }
+   },
+   {
+   .descr = "RA = LONG_MIN, RB = LONG_MAX",
+   .instr = TEST_DIVDE_DOT(20, 21, 22),
+   .regs = {
+   .gpr[21] = LONG_MIN,
+   .gpr[22] = LONG_MAX,
+   }
+   }
+   }
+   },
+   {
+   .mnemonic = "divdeu",
+   .subtests = {
+   {
+   .descr = "RA = LONG_MIN, RB = LONG_MIN",
+   .instr = TEST_DIVDEU(20, 21, 22),
+   .flags = IGNORE_GPR(20),
+   .regs = {
+   .gpr[21] = LONG_MIN,
+   .gpr[22] = LONG_MIN,
+   

[PATCH v2 2/3] powerpc sstep: add support for divde[.] and divdeu[.] instructions

2020-01-12 Thread Balamuruhan S
This patch adds emulation support for divde, divdeu instructions,
* Divide Doubleword Extended (divde[.])
* Divide Doubleword Extended Unsigned (divdeu[.])

Reviewed-by: Sandipan Das 
Signed-off-by: Balamuruhan S 
---
 arch/powerpc/lib/sstep.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index c077acb983a1..2cac71a71878 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1736,7 +1736,18 @@ int analyse_instr(struct instruction_op *op, const 
struct pt_regs *regs,
op->val = (int) regs->gpr[ra] /
(int) regs->gpr[rb];
goto arith_done;
-
+#ifdef __powerpc64__
+   case 425:   /* divde[.] */
+   asm volatile(PPC_DIVDE(%0, %1, %2) :
+   "=r" (op->val) : "r" (regs->gpr[ra]),
+   "r" (regs->gpr[rb]));
+   goto arith_done;
+   case 393:   /* divdeu[.] */
+   asm volatile(PPC_DIVDEU(%0, %1, %2) :
+   "=r" (op->val) : "r" (regs->gpr[ra]),
+   "r" (regs->gpr[rb]));
+   goto arith_done;
+#endif
case 755:   /* darn */
if (!cpu_has_feature(CPU_FTR_ARCH_300))
return -1;
-- 
2.14.5



[PATCH v2 1/3] powerpc ppc-opcode: add divde, divde_dot, divdeu and divdeu_dot opcodes

2020-01-12 Thread Balamuruhan S
include instruction opcodes for divde, divde_dot, divideu and
divideu_dot as macros.

Reviewed-by: Sandipan Das 
Signed-off-by: Balamuruhan S 
---
 arch/powerpc/include/asm/ppc-opcode.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/arch/powerpc/include/asm/ppc-opcode.h 
b/arch/powerpc/include/asm/ppc-opcode.h
index c1df75edde44..0acd01afd5b7 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -339,6 +339,10 @@
 #define PPC_INST_DIVWU 0x7c000396
 #define PPC_INST_DIVD  0x7c0003d2
 #define PPC_INST_DIVDU 0x7c000392
+#define PPC_INST_DIVDE 0x7c000352
+#define PPC_INST_DIVDE_DOT 0x7c000353
+#define PPC_INST_DIVDEU0x7c000312
+#define PPC_INST_DIVDEU_DOT0x7c000313
 #define PPC_INST_RLWINM0x5400
 #define PPC_INST_RLWINM_DOT0x5401
 #define PPC_INST_RLWIMI0x5000
@@ -439,6 +443,12 @@
__PPC_RA(a) | __PPC_RB(b))
 #definePPC_DCBZL(a, b) stringify_in_c(.long PPC_INST_DCBZL | \
__PPC_RA(a) | __PPC_RB(b))
+#define PPC_DIVDE(t, a, b) stringify_in_c(.long PPC_INST_DIVDE | \
+   ___PPC_RT(t) | ___PPC_RA(a) | \
+   ___PPC_RB(b))
+#define PPC_DIVDEU(t, a, b)stringify_in_c(.long PPC_INST_DIVDEU| \
+   ___PPC_RT(t) | ___PPC_RA(a) | \
+   ___PPC_RB(b))
 #define PPC_LQARX(t, a, b, eh) stringify_in_c(.long PPC_INST_LQARX | \
___PPC_RT(t) | ___PPC_RA(a) | \
___PPC_RB(b) | __PPC_EH(eh))
-- 
2.14.5



[PATCH v2 0/3] Add support for divde[.] and divdeu[.] instruction emulation

2020-01-12 Thread Balamuruhan S
Hi All,

This patchset adds support to emulate divde, divde., divdeu and divdeu.
instructions and testcases for it.

Changes in v2:
-
* Fix review comments from Paul to make divde_dot and divdeu_dot simple
  by using divde and divdeu, then goto `arith_done` instead of
  `compute_done`.
* Include `Reviewed-by` tag from Sandipan Das.
* Rebase with recent mpe's merge tree.

I would request for your review and suggestions for making it better.

Boot Log:


:: ::
:: ::
[2.777518] emulate_step_test: divde  : RA = LONG_MIN, RB = LONG_MIN 
PASS
[2.777882] emulate_step_test: divde  : RA = 1L, RB = 0  
PASS
[2.778432] emulate_step_test: divde  : RA = LONG_MIN, RB = LONG_MAX 
PASS
[2.778880] emulate_step_test: divde. : RA = LONG_MIN, RB = LONG_MIN 
PASS
[2.780172] emulate_step_test: divde. : RA = 1L, RB = 0  
PASS
[2.780582] emulate_step_test: divde. : RA = LONG_MIN, RB = LONG_MAX 
PASS
[2.780983] emulate_step_test: divdeu : RA = LONG_MIN, RB = LONG_MIN 
PASS
[2.781276] emulate_step_test: divdeu : RA = 1L, RB = 0  
PASS
[2.781579] emulate_step_test: divdeu : RA = LONG_MIN, RB = LONG_MAX 
PASS
[2.781820] emulate_step_test: divdeu : RA = LONG_MAX - 1, RB = 
LONG_MAX PASS
[2.782056] emulate_step_test: divdeu : RA = LONG_MIN + 1, RB = 
LONG_MIN PASS
[2.782296] emulate_step_test: divdeu.: RA = LONG_MIN, RB = LONG_MIN 
PASS
[2.782556] emulate_step_test: divdeu.: RA = 1L, RB = 0  
PASS
[2.783502] emulate_step_test: divdeu.: RA = LONG_MIN, RB = LONG_MAX 
PASS
[2.783748] emulate_step_test: divdeu.: RA = LONG_MAX - 1, RB = 
LONG_MAX PASS
[2.783973] emulate_step_test: divdeu.: RA = LONG_MIN + 1, RB = 
LONG_MIN PASS
[2.789617] registered taskstats version 1
[2.794779] printk: console [netcon0] enabled
[2.794931] netconsole: network logging started
[2.795327] hctosys: unable to open rtc device (rtc0)
[2.953449] Freeing unused kernel memory: 5120K
[2.953639] This architecture does not have kernel memory protection.
[2.953918] Run /init as init process
[3.173573] mount (54) used greatest stack depth: 12576 bytes left
[3.252465] mount (55) used greatest stack depth: 12544 bytes left

Welcome to Buildroot
buildroot login:

Balamuruhan S (3):
  powerpc ppc-opcode: add divde, divde_dot, divdeu and divdeu_dot
opcodes
  powerpc sstep: add support for divde[.] and divdeu[.] instructions
  powerpc test_emulate_step: add testcases for divde[.] and divdeu[.]
instructions

 arch/powerpc/include/asm/ppc-opcode.h |  10 +++
 arch/powerpc/lib/sstep.c  |  13 ++-
 arch/powerpc/lib/test_emulate_step.c  | 164 ++
 3 files changed, 186 insertions(+), 1 deletion(-)


base-commit: 20862247a368dbb75d6e97d82345999adaacf3cc
-- 
2.14.5



Re: linux-next: build warning after merge of the bpf-next tree

2020-01-12 Thread Zong Li
On Sat, Jan 11, 2020 at 10:31 PM Alexandre Ghiti  wrote:
>
>
> On 1/10/20 7:20 PM, Palmer Dabbelt wrote:
> > On Fri, 10 Jan 2020 14:28:17 PST (-0800), alexan...@ghiti.fr wrote:
> >> Hi guys,
> >>
> >> On 10/27/19 8:02 PM, Stephen Rothwell wrote:
> >>> Hi all,
> >>>
> >>> On Fri, 18 Oct 2019 10:56:57 +1100 Stephen Rothwell
> >>>  wrote:
>  Hi all,
> 
>  After merging the bpf-next tree, today's linux-next build (powerpc
>  ppc64_defconfig) produced this warning:
> 
>  WARNING: 2 bad relocations
>  c1998a48 R_PPC64_ADDR64 _binary__btf_vmlinux_bin_start
>  c1998a50 R_PPC64_ADDR64 _binary__btf_vmlinux_bin_end
> 
>  Introduced by commit
> 
> 8580ac9404f6 ("bpf: Process in-kernel BTF")
> >>> This warning now appears in the net-next tree build.
> >>>
> >>>
> >> I bump that thread up because Zong also noticed that 2 new
> >> relocations for
> >> those symbols appeared in my riscv relocatable kernel branch following
> >> that commit.
> >>
> >> I also noticed 2 new relocations R_AARCH64_ABS64 appearing in arm64
> >> kernel.
> >>
> >> Those 2 weak undefined symbols have existed since commit
> >> 341dfcf8d78e ("btf: expose BTF info through sysfs") but this is the fact
> >> to declare those symbols into btf.c that produced those relocations.
> >>
> >> I'm not sure what this all means, but this is not something I expected
> >> for riscv for
> >> a kernel linked with -shared/-fpie. Maybe should we just leave them to
> >> zero ?
> >>
> >> I think that deserves a deeper look if someone understands all this
> >> better than I do.
> >
> > Can you give me a pointer to your tree and how to build a relocatable
> > kernel?
> > Weak undefined symbols have the absolute value 0,
>
>
> So according to you the 2 new relocations R_RISCV_64 are normal and
> should not
> be modified at runtime right ?
>
>
> > but the kernel is linked at
> > an address such that 0 can't be reached by normal means.  When I added
> > support
> > to binutils for this I did it in a way that required almost no code --
> > essetially I just stopped dissallowing x0 as a possible base register
> > for PCREL
> > relocations, which results in 0 always being accessible.  I just
> > wanted to get
> > the kernel to build again, so I didn't worry about chasing around all the
> > addressing modes.  The PIC/PIE support generates different relocations
> > and I
> > wouldn't be surprised if I just missed one (or more likely all) of them.
> >
> > It's probably a simple fix, though I feel like every time I say that
> > about the
> > linker I end up spending a month in there...
>
> You can find it here:
>
> https://github.com/AlexGhiti/riscv-linux/tree/int/alex/riscv_relocatable_v1
>
> Zong fixed the bug introduced by those 2 new relocations and everything
> works
> like a charm, so I'm not sure you have to dig in the linker :)
>

I'm not quite familiar with btf, so I have no idea why there are two
weak symbols be added in 8580ac9404f6 ("bpf: Process in-kernel BTF")
as well, According on relocation mechanism, maybe it is unnecessary to
handle weak undefined symbol at this time, because there is no
substantive help to relocate the absolute value 0. I just simply
ignore the non-relative relocation types to make processing can go
forward, and it works for me based on v5.5-rc5.

> Alex
>


[RESEND PATCH v2 3/3] powerpc/powernv: Parse device tree, population of SPR support

2020-01-12 Thread Pratik Rajesh Sampat
Parse the device tree for nodes self-save, self-restore and populate
support for the preferred SPRs based what was advertised by the device
tree.

Signed-off-by: Pratik Rajesh Sampat 
---
 arch/powerpc/platforms/powernv/idle.c | 104 ++
 1 file changed, 104 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index d67d4d0b169b..e910ff40b7e6 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -1429,6 +1429,107 @@ static void __init pnv_probe_idle_states(void)
supported_cpuidle_states |= pnv_idle_states[i].flags;
 }
 
+/*
+ * Extracts and populates the self save or restore capabilities
+ * passed from the device tree node
+ */
+static int extract_save_restore_state_dt(struct device_node *np, int type)
+{
+   int nr_sprns = 0, i, bitmask_index;
+   int rc = 0;
+   u64 *temp_u64;
+   const char *state_prop;
+   u64 bit_pos;
+
+   state_prop = of_get_property(np, "status", NULL);
+   if (!state_prop) {
+   pr_warn("opal: failed to find the active value for self 
save/restore node");
+   return -EINVAL;
+   }
+   if (strncmp(state_prop, "disabled", 8) == 0) {
+   /*
+* if the feature is not active, strip the preferred_sprs from
+* that capability.
+*/
+   if (type == SELF_RESTORE_TYPE) {
+   for (i = 0; i < nr_preferred_sprs; i++) {
+   preferred_sprs[i].supported_mode &=
+   ~SELF_RESTORE_STRICT;
+   }
+   } else {
+   for (i = 0; i < nr_preferred_sprs; i++) {
+   preferred_sprs[i].supported_mode &=
+   ~SELF_SAVE_STRICT;
+   }
+   }
+   return 0;
+   }
+   nr_sprns = of_property_count_u64_elems(np, "sprn-bitmask");
+   if (nr_sprns <= 0)
+   return rc;
+   temp_u64 = kcalloc(nr_sprns, sizeof(u64), GFP_KERNEL);
+   if (of_property_read_u64_array(np, "sprn-bitmask",
+  temp_u64, nr_sprns)) {
+   pr_warn("cpuidle-powernv: failed to find registers in DT\n");
+   kfree(temp_u64);
+   return -EINVAL;
+   }
+   /*
+* Populate acknowledgment of support for the sprs in the global vector
+* gotten by the registers supplied by the firmware.
+* The registers are in a bitmask, bit index within
+* that specifies the SPR
+*/
+   for (i = 0; i < nr_preferred_sprs; i++) {
+   bitmask_index = preferred_sprs[i].spr / 64;
+   bit_pos = preferred_sprs[i].spr % 64;
+   if ((temp_u64[bitmask_index] & (1UL << bit_pos)) == 0) {
+   if (type == SELF_RESTORE_TYPE)
+   preferred_sprs[i].supported_mode &=
+   ~SELF_RESTORE_STRICT;
+   else
+   preferred_sprs[i].supported_mode &=
+   ~SELF_SAVE_STRICT;
+   continue;
+   }
+   if (type == SELF_RESTORE_TYPE) {
+   preferred_sprs[i].supported_mode |=
+   SELF_RESTORE_STRICT;
+   } else {
+   preferred_sprs[i].supported_mode |=
+   SELF_SAVE_STRICT;
+   }
+   }
+
+   kfree(temp_u64);
+   return rc;
+}
+
+static int pnv_parse_deepstate_dt(void)
+{
+   struct device_node *np, *np1;
+   int rc = 0;
+
+   /* Self restore register population */
+   np = of_find_node_by_path("/ibm,opal/power-mgt/self-restore");
+   if (!np) {
+   pr_warn("opal: self restore Node not found");
+   } else {
+   rc = extract_save_restore_state_dt(np, SELF_RESTORE_TYPE);
+   if (rc != 0)
+   return rc;
+   }
+   /* Self save register population */
+   np1 = of_find_node_by_path("/ibm,opal/power-mgt/self-save");
+   if (!np1) {
+   pr_warn("opal: self save Node not found");
+   pr_warn("Legacy firmware. Assuming default self-restore 
support");
+   } else {
+   rc = extract_save_restore_state_dt(np1, SELF_SAVE_TYPE);
+   }
+   return rc;
+}
+
 /*
  * This function parses device-tree and populates all the information
  * into pnv_idle_states structure. It also sets up nr_pnv_idle_states
@@ -1577,6 +1678,9 @@ static int __init pnv_init_idle_states(void)
return rc;
pnv_probe_idle_states();
 
+   rc = pnv_parse_deepstate_dt();
+   if (rc)
+   return rc;
if (!cpu_has_feature(CPU_FTR_ARCH_300)) {
   

[RESEND PATCH v2 2/3] powerpc/powernv: Introduce Self save support

2020-01-12 Thread Pratik Rajesh Sampat
This commit introduces and leverages the Self save API which OPAL now
supports.

Add the new Self Save OPAL API call in the list of OPAL calls.
Implement the self saving of the SPRs based on the support populated
while respecting it's preferences.

This implementation allows mixing of support for the SPRs, which
means that a SPR can be self restored while another SPR be self saved if
they support and prefer it to be so.

Signed-off-by: Pratik Rajesh Sampat 
---
 arch/powerpc/include/asm/opal-api.h| 3 ++-
 arch/powerpc/include/asm/opal.h| 1 +
 arch/powerpc/platforms/powernv/idle.c  | 2 ++
 arch/powerpc/platforms/powernv/opal-call.c | 1 +
 4 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index c1f25a760eb1..1b6e1a68d431 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -214,7 +214,8 @@
 #define OPAL_SECVAR_GET176
 #define OPAL_SECVAR_GET_NEXT   177
 #define OPAL_SECVAR_ENQUEUE_UPDATE 178
-#define OPAL_LAST  178
+#define OPAL_SLW_SELF_SAVE_REG 181
+#define OPAL_LAST  181
 
 #define QUIESCE_HOLD   1 /* Spin all calls at entry */
 #define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9986ac34b8e2..389a85b63805 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -203,6 +203,7 @@ int64_t opal_handle_hmi(void);
 int64_t opal_handle_hmi2(__be64 *out_flags);
 int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end);
 int64_t opal_unregister_dump_region(uint32_t id);
+int64_t opal_slw_self_save_reg(uint64_t cpu_pir, uint64_t sprn);
 int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);
 int64_t opal_config_cpu_idle_state(uint64_t state, uint64_t flag);
 int64_t opal_pci_set_phb_cxl_mode(uint64_t phb_id, uint64_t mode, uint64_t 
pe_number);
diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 2f328403b0dc..d67d4d0b169b 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -1172,6 +1172,8 @@ void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 
lpcr_val)
if (!is_lpcr_self_save)
opal_slw_set_reg(pir, SPRN_LPCR,
 lpcr_val);
+   else
+   opal_slw_self_save_reg(pir, SPRN_LPCR);
}
 }
 
diff --git a/arch/powerpc/platforms/powernv/opal-call.c 
b/arch/powerpc/platforms/powernv/opal-call.c
index 5cd0f52d258f..11e0ceb90de0 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -223,6 +223,7 @@ OPAL_CALL(opal_handle_hmi,  
OPAL_HANDLE_HMI);
 OPAL_CALL(opal_handle_hmi2,OPAL_HANDLE_HMI2);
 OPAL_CALL(opal_config_cpu_idle_state,  OPAL_CONFIG_CPU_IDLE_STATE);
 OPAL_CALL(opal_slw_set_reg,OPAL_SLW_SET_REG);
+OPAL_CALL(opal_slw_self_save_reg,  OPAL_SLW_SELF_SAVE_REG);
 OPAL_CALL(opal_register_dump_region,   OPAL_REGISTER_DUMP_REGION);
 OPAL_CALL(opal_unregister_dump_region, OPAL_UNREGISTER_DUMP_REGION);
 OPAL_CALL(opal_pci_set_phb_cxl_mode,   OPAL_PCI_SET_PHB_CAPI_MODE);
-- 
2.24.1



[RESEND PATCH v2 1/3] powerpc/powernv: Interface to define support and preference for a SPR

2020-01-12 Thread Pratik Rajesh Sampat
Define a bitmask interface to determine support for the Self Restore,
Self Save or both.

Also define an interface to determine the preference of that SPR to
be strictly saved or restored or encapsulated with an order of preference.

The preference bitmask is shown as below:

|... | 2nd pref | 1st pref |

MSB   LSB

The preference from higher to lower is from LSB to MSB with a shift of 8
bits.
Example:
Prefer self save first, if not available then prefer self
restore
The preference mask for this scenario will be seen as below.
((SELF_RESTORE_STRICT << PREFERENCE_SHIFT) | SELF_SAVE_STRICT)
-
|... | Self restore | Self save |
-
MSB LSB

Finally, declare a list of preferred SPRs which encapsulate the bitmaks
for preferred and supported with defaults of both being set to support
legacy firmware.

This commit also implements using the above interface and retains the
legacy functionality of self restore.

Signed-off-by: Pratik Rajesh Sampat 
---
 arch/powerpc/platforms/powernv/idle.c | 327 +-
 1 file changed, 271 insertions(+), 56 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 78599bca66c2..2f328403b0dc 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -32,9 +32,106 @@
 #define P9_STOP_SPR_MSR 2000
 #define P9_STOP_SPR_PSSCR  855
 
+/* Interface for the stop state supported and preference */
+#define SELF_RESTORE_TYPE0
+#define SELF_SAVE_TYPE   1
+
+#define NR_PREFERENCES2
+#define PREFERENCE_SHIFT  4
+#define PREFERENCE_MASK   0xf
+
+#define UNSUPPORTED 0x0
+#define SELF_RESTORE_STRICT 0x1
+#define SELF_SAVE_STRICT0x2
+
+/*
+ * Bitmask defining the kind of preferences available.
+ * Note : The higher to lower preference is from LSB to MSB, with a shift of
+ * 4 bits.
+ * 
+ * || 2nd pref | 1st pref |
+ * 
+ * MSB   LSB
+ */
+/* Prefer Restore if available, otherwise unsupported */
+#define PREFER_SELF_RESTORE_ONLY   SELF_RESTORE_STRICT
+/* Prefer Save if available, otherwise unsupported */
+#define PREFER_SELF_SAVE_ONLY  SELF_SAVE_STRICT
+/* Prefer Restore when available, otherwise prefer Save */
+#define PREFER_RESTORE_SAVE((SELF_SAVE_STRICT << \
+ PREFERENCE_SHIFT)\
+ | SELF_RESTORE_STRICT)
+/* Prefer Save when available, otherwise prefer Restore*/
+#define PREFER_SAVE_RESTORE((SELF_RESTORE_STRICT <<\
+ PREFERENCE_SHIFT)\
+ | SELF_SAVE_STRICT)
 static u32 supported_cpuidle_states;
 struct pnv_idle_states_t *pnv_idle_states;
 int nr_pnv_idle_states;
+/* Caching the lpcr & ptcr support to use later */
+static bool is_lpcr_self_save;
+static bool is_ptcr_self_save;
+
+struct preferred_sprs {
+   u64 spr;
+   u32 preferred_mode;
+   u32 supported_mode;
+};
+
+struct preferred_sprs preferred_sprs[] = {
+   {
+   .spr = SPRN_HSPRG0,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = SPRN_LPCR,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = SPRN_PTCR,
+   .preferred_mode = PREFER_SAVE_RESTORE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = SPRN_HMEER,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = SPRN_HID0,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = P9_STOP_SPR_MSR,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = P9_STOP_SPR_PSSCR,
+   .preferred_mode = PREFER_SAVE_RESTORE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = SPRN_HID1,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = SPRN_HID4,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   },
+   {
+   .spr = SPRN_HID5,
+   .preferred_mode = PREFER_RESTORE_SAVE,
+   .supported_mode = SELF_RESTORE_STRICT,
+   }
+};
+
+const int nr_preferred_sprs = ARRAY_SIZE(preferred_sprs);
 
 

[RESEND PATCH v2 0/3] Introduce Self-Save API for deep stop states

2020-01-12 Thread Pratik Rajesh Sampat
RESEND Changes:
1. Updated OPAL API numbering for consistency

Skiboot patches: https://patchwork.ozlabs.org/patch/1221011/
RFC v1 patches: https://lkml.org/lkml/2019/12/4/193
Changelog
RFC v1 --> v2
1. Optimized preference bitmask
2. Addressed comments from Ram Pai

Currently the stop-API supports a mechanism called as self-restore
which allows us to restore the values of certain SPRs on wakeup from a
deep-stop state to a desired value. To use this, the Kernel makes an
OPAL call passing the PIR of the CPU, the SPR number and the value to
which the SPR should be restored when that CPU wakes up from a deep
stop state.

Recently, a new feature, named self-save has been enabled in the
stop-api, which is an alternative mechanism to do the same, except
that self-save will save the current content of the SPR before
entering a deep stop state and also restore the content back on
waking up from a deep stop state.

This patch series aims at introducing and leveraging the self-save feature in
the kernel.

Now, as the kernel has a choice to prefer one mode over the other and
there can be registers in both the save/restore SPR list which are sent
from the device tree, a new interface has been defined for the seamless
handing of the modes for each SPR.

A list of preferred SPRs are maintained in the kernel which contains two
properties:
1. supported_mode: Helps in identifying if it strictly supports self
   save or restore or both.
   Initialized using the information from device tree.
2. preferred_mode: Calls out what mode is preferred for each SPR. It
   could be strictly self save or restore, or it can also
   determine the preference of  mode over the other if both
   are present by encapsulating the other in bitmask from
   LSB to MSB.
   Initialized statically.

Below is a table to show the Scenario::Consequence when the self save and
self restore modes are available or disabled in different combinations as
perceived from the device tree thus giving complete backwards compatibly
regardless of an older firmware running a newer kernel or vise-versa.
Support for self save or self-restore is embedded in the device tree,
along with the set of registers it supports.

SR = Self restore; SS = Self save

.---..
| Scenario  |Consequence |
:---+:
| Legacy Firmware. No SS or SR node | Self restore is called for all |
|   | supported SPRs |
:---+:
| SR: !active SS: !active   | Deep stop states disabled  |
:---+:
| SR: active SS: !active| Self restore is called for all |
|   | supported SPRs |
:---+:
| SR: active SS: active | Goes through the preferences for each  |
|   | SPR and executes of the modes  |
|   | accordingly. Currently, Self restore is|
|   | called for all the SPRs except PSSCR   |
|   | which is self saved|
:---+:
| SR: active(only HID0) SS: active  | Self save called for all supported |
|   | registers expect HID0 (as HID0 cannot  |
|   | be self saved currently)   |
:---+:
| SR: !active SS: active| currently will disable deep states as  |
|   | HID0 is needed to be self restored and |
|   | cannot be self saved   |
'---''

Pratik Rajesh Sampat (3):
  powerpc/powernv: Interface to define support and preference for a SPR
  powerpc/powernv: Introduce Self save support
  powerpc/powernv: Parse device tree, population of SPR support

 arch/powerpc/include/asm/opal-api.h|   3 +-
 arch/powerpc/include/asm/opal.h|   1 +
 arch/powerpc/platforms/powernv/idle.c  | 433 ++---
 arch/powerpc/platforms/powernv/opal-call.c |   1 +
 4 files changed, 381 insertions(+), 57 deletions(-)

-- 
2.24.1



Re: [PATCH v3 2/2] powerpc/pseries/svm: Disable BHRB/EBB/PMU access

2020-01-12 Thread Paul Mackerras
On Thu, Jan 09, 2020 at 09:19:57PM -0800, Sukadev Bhattiprolu wrote:
> Ultravisor disables some CPU features like BHRB, EBB and PMU in
> secure virtual machines (SVMs). Skip accessing those registers
> in SVMs to avoid getting a Program Interrupt.

It would be useful to have more explanation of the rationale for the
ultravisor disabling access to those features, and indicate whether
this is a temporary restriction or a permanent one.  If SVMs are never
going to be able to use the PMU then that is a bad thing in my
opinion.  In other words, the commit message should tell us whether
the restriction is just because the ultravisor doesn't yet have code
for managing and context-switching the PMU, or if there is there some
reason why using the PMU in a SVM will always be prohibited for some
security-related reason.

Also, the only way that a SVM would be getting into the KVM code that
you are patching is if it is trying to do nested virtualization.
However, the SVM should already know that it is not able to do nested
virtualization because the ultravisor should be intercepting and
failing the H_SET_PARTITION_TABLE hypercall.  So I think there is no
good reason for patching the KVM code like you are doing unless the
PMU restriction is permanent and we are intending someday to enable
SVMs to have nested guests.

Paul.