Re: [PATCH v4 2/2] powerpc/powernv: Add ultravisor message log interface

2019-08-28 Thread Claudio Carvalho


On 8/28/19 10:05 AM, Michael Ellerman wrote:
> From: Claudio Carvalho 
>
> The ultravisor (UV) provides an in-memory console which follows the
> OPAL in-memory console structure.
>
> This patch extends the OPAL msglog code to initialize the UV memory
> console and provide the "/sys/firmware/ultravisor/msglog" interface
> for userspace to view the UV message log.

Tested-by: Claudio Carvalho 

Thanks,
Claudio

>
> Signed-off-by: Claudio Carvalho 
> Signed-off-by: Michael Ellerman 
> ---
> v4: mpe: Move all the code into ultravisor.c.
> Consistently use "uv_" as the prefix not "ultra_".
> Use powernv.h for routines that are shared within the platform.
> Rather than bloating the kernel with strings for every rare error
> case, return error codes from the init routine which can be
> seen with initcall_debug.
> ---
>  arch/powerpc/platforms/powernv/powernv.h|  5 +++
>  arch/powerpc/platforms/powernv/ultravisor.c | 45 +
>  2 files changed, 50 insertions(+)
>
> diff --git a/arch/powerpc/platforms/powernv/powernv.h 
> b/arch/powerpc/platforms/powernv/powernv.h
> index fd4a1c5a6369..1aa51c4fa904 100644
> --- a/arch/powerpc/platforms/powernv/powernv.h
> +++ b/arch/powerpc/platforms/powernv/powernv.h
> @@ -30,4 +30,9 @@ extern void opal_event_shutdown(void);
>  
>  bool cpu_core_split_required(void);
>  
> +struct memcons;
> +ssize_t memcons_copy(struct memcons *mc, char *to, loff_t pos, size_t count);
> +u32 memcons_get_size(struct memcons *mc);
> +struct memcons *memcons_init(struct device_node *node, const char 
> *mc_prop_name);
> +
>  #endif /* _POWERNV_H */
> diff --git a/arch/powerpc/platforms/powernv/ultravisor.c 
> b/arch/powerpc/platforms/powernv/ultravisor.c
> index 02ac57b4bded..e4a00ad06f9d 100644
> --- a/arch/powerpc/platforms/powernv/ultravisor.c
> +++ b/arch/powerpc/platforms/powernv/ultravisor.c
> @@ -8,9 +8,15 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> +#include 
> +
> +#include "powernv.h"
> +
> +static struct kobject *ultravisor_kobj;
>  
>  int __init early_init_dt_scan_ultravisor(unsigned long node, const char 
> *uname,
>int depth, void *data)
> @@ -22,3 +28,42 @@ int __init early_init_dt_scan_ultravisor(unsigned long 
> node, const char *uname,
>   pr_debug("Ultravisor detected!\n");
>   return 1;
>  }
> +
> +static struct memcons *uv_memcons;
> +
> +static ssize_t uv_msglog_read(struct file *file, struct kobject *kobj,
> +   struct bin_attribute *bin_attr, char *to,
> +   loff_t pos, size_t count)
> +{
> + return memcons_copy(uv_memcons, to, pos, count);
> +}
> +
> +static struct bin_attribute uv_msglog_attr = {
> + .attr = {.name = "msglog", .mode = 0400},
> + .read = uv_msglog_read
> +};
> +
> +static int __init uv_init(void)
> +{
> + struct device_node *node;
> +
> + if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
> + return 0;
> +
> + node = of_find_compatible_node(NULL, NULL, "ibm,uv-firmware");
> + if (!node)
> + return -ENODEV;
> +
> + uv_memcons = memcons_init(node, "memcons");
> + if (!uv_memcons)
> + return -ENOENT;
> +
> + uv_msglog_attr.size = memcons_get_size(uv_memcons);
> +
> + ultravisor_kobj = kobject_create_and_add("ultravisor", firmware_kobj);
> + if (!ultravisor_kobj)
> + return -ENOMEM;
> +
> + return sysfs_create_bin_file(ultravisor_kobj, _msglog_attr);
> +}
> +machine_subsys_initcall(powernv, uv_init);


Re: [PATCH v4 1/2] powerpc/powernv/opal-msglog: Refactor memcons code

2019-08-28 Thread Claudio Carvalho


On 8/28/19 10:05 AM, Michael Ellerman wrote:
> From: Claudio Carvalho 
>
> This patch refactors the code in opal-msglog that operates on the OPAL
> memory console in order to make it cleaner and also allow the reuse of
> the new memcons_* functions.

Tested-by: Claudio Carvalho 

Thanks,
Claudio

> Signed-off-by: Claudio Carvalho 
> Signed-off-by: Michael Ellerman 
> ---
> v4: mpe: Rename memcons_load_from_dt() to memcons_init().
>  Make memcons_init() and memcons_get_size() non-static.
>Continue to use opal_msglog_copy() in opal_msglog_read().
> ---
>  arch/powerpc/platforms/powernv/opal-msglog.c | 57 +---
>  1 file changed, 39 insertions(+), 18 deletions(-)
>
> diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c 
> b/arch/powerpc/platforms/powernv/opal-msglog.c
> index dc51d03c6370..d26da19a611f 100644
> --- a/arch/powerpc/platforms/powernv/opal-msglog.c
> +++ b/arch/powerpc/platforms/powernv/opal-msglog.c
> @@ -29,23 +29,23 @@ struct memcons {
>  
>  static struct memcons *opal_memcons = NULL;
>  
> -ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
> +ssize_t memcons_copy(struct memcons *mc, char *to, loff_t pos, size_t count)
>  {
>   const char *conbuf;
>   ssize_t ret;
>   size_t first_read = 0;
>   uint32_t out_pos, avail;
>  
> - if (!opal_memcons)
> + if (!mc)
>   return -ENODEV;
>  
> - out_pos = be32_to_cpu(READ_ONCE(opal_memcons->out_pos));
> + out_pos = be32_to_cpu(READ_ONCE(mc->out_pos));
>  
>   /* Now we've read out_pos, put a barrier in before reading the new
>* data it points to in conbuf. */
>   smp_rmb();
>  
> - conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys));
> + conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
>  
>   /* When the buffer has wrapped, read from the out_pos marker to the end
>* of the buffer, and then read the remaining data as in the un-wrapped
> @@ -53,7 +53,7 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
>   if (out_pos & MEMCONS_OUT_POS_WRAP) {
>  
>   out_pos &= MEMCONS_OUT_POS_MASK;
> - avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos;
> + avail = be32_to_cpu(mc->obuf_size) - out_pos;
>  
>   ret = memory_read_from_buffer(to, count, ,
>   conbuf + out_pos, avail);
> @@ -71,7 +71,7 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
>   }
>  
>   /* Sanity check. The firmware should not do this to us. */
> - if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) {
> + if (out_pos > be32_to_cpu(mc->obuf_size)) {
>   pr_err("OPAL: memory console corruption. Aborting read.\n");
>   return -EINVAL;
>   }
> @@ -86,6 +86,11 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t 
> count)
>   return ret;
>  }
>  
> +ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
> +{
> + return memcons_copy(opal_memcons, to, pos, count);
> +}
> +
>  static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
>   struct bin_attribute *bin_attr, char *to,
>   loff_t pos, size_t count)
> @@ -98,32 +103,48 @@ static struct bin_attribute opal_msglog_attr = {
>   .read = opal_msglog_read
>  };
>  
> -void __init opal_msglog_init(void)
> +struct memcons *memcons_init(struct device_node *node, const char 
> *mc_prop_name)
>  {
>   u64 mcaddr;
>   struct memcons *mc;
>  
> - if (of_property_read_u64(opal_node, "ibm,opal-memcons", )) {
> - pr_warn("OPAL: Property ibm,opal-memcons not found, no message 
> log\n");
> - return;
> + if (of_property_read_u64(node, mc_prop_name, )) {
> + pr_warn("%s property not found, no message log\n",
> + mc_prop_name);
> + goto out_err;
>   }
>  
>   mc = phys_to_virt(mcaddr);
>   if (!mc) {
> - pr_warn("OPAL: memory console address is invalid\n");
> - return;
> + pr_warn("memory console address is invalid\n");
> + goto out_err;
>   }
>  
>   if (be64_to_cpu(mc->magic) != MEMCONS_MAGIC) {
> - pr_warn("OPAL: memory console version is invalid\n");
> - return;
> + pr_warn("memory console version is invalid\n");
> + goto out_err;
>   }
>  
> - /* Report maximum size */
> - opal_msglog_attr.size =  be3

[PATCH v3 2/2] powerpc/powernv: Add ultravisor message log interface

2019-08-27 Thread Claudio Carvalho
The ultravisor (UV) provides an in-memory console which follows the OPAL
in-memory console structure.

This patch extends the OPAL msglog code to initialize the UV memory
console and provide the "/sys/firmware/ultravisor/msglog" interface
for userspace to view the UV message log.

Signed-off-by: Claudio Carvalho 
---
This patch applies on top of the "kvmppc: Paravirtualize KVM to support
ultravisor" patch series submitted by Claudio Carvalho.
---
 arch/powerpc/include/asm/ultravisor.h|  8 
 arch/powerpc/platforms/powernv/opal-msglog.c | 36 ++
 arch/powerpc/platforms/powernv/ultravisor.c  | 40 
 3 files changed, 84 insertions(+)

diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index d7aa97aa7834..62932d403847 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -12,6 +12,14 @@
 #include 
 #include 
 
+/* /sys/firmware/ultravisor */
+extern struct kobject *ultravisor_kobj;
+
+/* /ibm,ultravisor/ibm,uv-firmware */
+extern struct device_node *uv_firmware_node;
+
+void ultra_msglog_init(void);
+void ultra_msglog_sysfs_init(void);
 int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
  int depth, void *data);
 
diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c 
b/arch/powerpc/platforms/powernv/opal-msglog.c
index 0e8eb62c8afe..7c6b2001e62f 100644
--- a/arch/powerpc/platforms/powernv/opal-msglog.c
+++ b/arch/powerpc/platforms/powernv/opal-msglog.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* OPAL in-memory console. Defined in OPAL source at core/console.c */
 struct memcons {
@@ -28,6 +29,7 @@ struct memcons {
 };
 
 static struct memcons *opal_memcons = NULL;
+static struct memcons *ultra_memcons;
 
 static ssize_t memcons_copy(struct memcons *mc, char *to, loff_t pos,
   size_t count)
@@ -104,6 +106,18 @@ static struct bin_attribute opal_msglog_attr = {
.read = opal_msglog_read
 };
 
+static ssize_t ultra_msglog_read(struct file *file, struct kobject *kobj,
+   struct bin_attribute *bin_attr, char *to,
+   loff_t pos, size_t count)
+{
+   return memcons_copy(ultra_memcons, to, pos, count);
+}
+
+static struct bin_attribute ultra_msglog_attr = {
+   .attr = {.name = "msglog", .mode = 0400},
+   .read = ultra_msglog_read
+};
+
 static struct memcons *memcons_load_from_dt(struct device_node *node,
const char *mc_prop_name)
 {
@@ -159,3 +173,25 @@ void __init opal_msglog_sysfs_init(void)
if (sysfs_create_bin_file(opal_kobj, _msglog_attr) != 0)
pr_warn("OPAL: sysfs file creation failed\n");
 }
+
+void __init ultra_msglog_init(void)
+{
+   ultra_memcons = memcons_load_from_dt(uv_firmware_node, "memcons");
+   if (!ultra_memcons) {
+   pr_warn("Ultravisor: memcons failed to load from DT\n");
+   return;
+   }
+
+   ultra_msglog_attr.size = memcons_get_size(ultra_memcons);
+}
+
+void __init ultra_msglog_sysfs_init(void)
+{
+   if (!ultra_memcons) {
+   pr_warn("Ultravisor: msglog initialisation failed, not creating 
sysfs entry\n");
+   return;
+   }
+
+   if (sysfs_create_bin_file(ultravisor_kobj, _msglog_attr) != 0)
+   pr_warn("Ultravisor: sysfs msglog file creation failed\n");
+}
diff --git a/arch/powerpc/platforms/powernv/ultravisor.c 
b/arch/powerpc/platforms/powernv/ultravisor.c
index 02ac57b4bded..4ec63b7c0c78 100644
--- a/arch/powerpc/platforms/powernv/ultravisor.c
+++ b/arch/powerpc/platforms/powernv/ultravisor.c
@@ -8,9 +8,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
+#include 
+
+struct kobject *ultravisor_kobj;
+struct device_node *uv_firmware_node;
 
 int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data)
@@ -22,3 +27,38 @@ int __init early_init_dt_scan_ultravisor(unsigned long node, 
const char *uname,
pr_debug("Ultravisor detected!\n");
return 1;
 }
+
+static int __init ultra_sysfs_init(void)
+{
+   ultravisor_kobj = kobject_create_and_add("ultravisor", firmware_kobj);
+   if (!ultravisor_kobj) {
+   pr_warn("kobject_create_and_add ultravisor failed\n");
+   return -ENOMEM;
+   }
+
+   return 0;
+}
+
+static int __init ultra_init(void)
+{
+   int rc;
+
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   goto out;
+
+   uv_firmware_node = of_find_compatible_node(NULL, NULL,
+  "ibm,uv-firmware");
+   if (!uv_firmware_node) {
+   pr_err(&q

[PATCH v3 1/2] powerpc/powernv/opal-msglog: Refactor memcons code

2019-08-27 Thread Claudio Carvalho
This patch refactors the code in opal-msglog that operates on the OPAL
memory console in order to make it cleaner and also allow the reuse of
the new memcons_* functions.

Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/platforms/powernv/opal-msglog.c | 61 ++--
 1 file changed, 42 insertions(+), 19 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c 
b/arch/powerpc/platforms/powernv/opal-msglog.c
index dc51d03c6370..0e8eb62c8afe 100644
--- a/arch/powerpc/platforms/powernv/opal-msglog.c
+++ b/arch/powerpc/platforms/powernv/opal-msglog.c
@@ -29,23 +29,24 @@ struct memcons {
 
 static struct memcons *opal_memcons = NULL;
 
-ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
+static ssize_t memcons_copy(struct memcons *mc, char *to, loff_t pos,
+  size_t count)
 {
const char *conbuf;
ssize_t ret;
size_t first_read = 0;
uint32_t out_pos, avail;
 
-   if (!opal_memcons)
+   if (!mc)
return -ENODEV;
 
-   out_pos = be32_to_cpu(READ_ONCE(opal_memcons->out_pos));
+   out_pos = be32_to_cpu(READ_ONCE(mc->out_pos));
 
/* Now we've read out_pos, put a barrier in before reading the new
 * data it points to in conbuf. */
smp_rmb();
 
-   conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys));
+   conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys));
 
/* When the buffer has wrapped, read from the out_pos marker to the end
 * of the buffer, and then read the remaining data as in the un-wrapped
@@ -53,7 +54,7 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
if (out_pos & MEMCONS_OUT_POS_WRAP) {
 
out_pos &= MEMCONS_OUT_POS_MASK;
-   avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos;
+   avail = be32_to_cpu(mc->obuf_size) - out_pos;
 
ret = memory_read_from_buffer(to, count, ,
conbuf + out_pos, avail);
@@ -71,7 +72,7 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
}
 
/* Sanity check. The firmware should not do this to us. */
-   if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) {
+   if (out_pos > be32_to_cpu(mc->obuf_size)) {
pr_err("OPAL: memory console corruption. Aborting read.\n");
return -EINVAL;
}
@@ -86,11 +87,16 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
return ret;
 }
 
+ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
+{
+   return memcons_copy(opal_memcons, to, pos, count);
+}
+
 static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
struct bin_attribute *bin_attr, char *to,
loff_t pos, size_t count)
 {
-   return opal_msglog_copy(to, pos, count);
+   return memcons_copy(opal_memcons, to, pos, count);
 }
 
 static struct bin_attribute opal_msglog_attr = {
@@ -98,32 +104,49 @@ static struct bin_attribute opal_msglog_attr = {
.read = opal_msglog_read
 };
 
-void __init opal_msglog_init(void)
+static struct memcons *memcons_load_from_dt(struct device_node *node,
+   const char *mc_prop_name)
 {
u64 mcaddr;
struct memcons *mc;
 
-   if (of_property_read_u64(opal_node, "ibm,opal-memcons", )) {
-   pr_warn("OPAL: Property ibm,opal-memcons not found, no message 
log\n");
-   return;
+   if (of_property_read_u64(node, mc_prop_name, )) {
+   pr_warn("%s property not found, no message log\n",
+   mc_prop_name);
+   goto out_err;
}
 
mc = phys_to_virt(mcaddr);
if (!mc) {
-   pr_warn("OPAL: memory console address is invalid\n");
-   return;
+   pr_warn("memory console address is invalid\n");
+   goto out_err;
}
 
if (be64_to_cpu(mc->magic) != MEMCONS_MAGIC) {
-   pr_warn("OPAL: memory console version is invalid\n");
-   return;
+   pr_warn("memory console version is invalid\n");
+   goto out_err;
}
 
-   /* Report maximum size */
-   opal_msglog_attr.size =  be32_to_cpu(mc->ibuf_size) +
-   be32_to_cpu(mc->obuf_size);
+   return mc;
+
+out_err:
+   return NULL;
+}
+
+static u32 memcons_get_size(struct memcons *mc)
+{
+   return be32_to_cpu(mc->ibuf_size) + be32_to_cpu(mc->obuf_size);
+}
+
+void __init opal_msglog_init(void)
+{
+   opal_memcons = memcons_load_from_dt(opal_node, "ibm,opal-memcons");
+   if (!opal_memcons) {
+   pr_warn("OPAL: memcons failed to load from ibm,opal-memcons\n");
+   return;
+   }
 
-   opal_memcons = mc;
+   opal_msglog_attr.size = memcons_get_size(opal_memcons);
 }
 
 void __init opal_msglog_sysfs_init(void)
-- 
2.20.1



Re: [PATCH v2] powerpc/powernv: Add ultravisor message log interface

2019-08-24 Thread Claudio Carvalho


On 8/23/19 9:48 AM, Michael Ellerman wrote:
> Hi Claudio,

Hi Michael,

>
> Claudio Carvalho  writes:
>> Ultravisor (UV) provides an in-memory console which follows the OPAL
>> in-memory console structure.
>>
>> This patch extends the OPAL msglog code to also initialize the UV memory
>> console and provide a sysfs interface (uv_msglog) for userspace to view
>> the UV message log.
>>
>> CC: Madhavan Srinivasan 
>> CC: Oliver O'Halloran 
>> Signed-off-by: Claudio Carvalho 
>> ---
>> This patch depends on the "kvmppc: Paravirtualize KVM to support
>> ultravisor" patchset submitted by Claudio Carvalho.
>> ---
>>  arch/powerpc/platforms/powernv/opal-msglog.c | 99 ++--
>>  1 file changed, 72 insertions(+), 27 deletions(-)
> I think the code changes look mostly OK here.
>
> But I'm not sure about the end result in sysfs.
>
> If I'm reading it right this will create:
>
>  /sys/firmware/opal/uv_msglog
>
> Which I think is a little weird, because the UV is not OPAL.
>
> So I guess I wonder if the file should be created elsewhere to avoid any
> confusion and keep things nicely separated.
>
> Possibly /sys/firmware/ultravisor/msglog ?


Yes, makes sense. I will do that.

Currently, the ultravisor memory console DT property is in
/ibm,opal/ibm,opal-uv-memcons. I think we should move it to
/ibm,ultravisor/ibm,uv-firmware/ibm,uv-memcons. What do you think?

Thanks,
Claudio


>
> cheers


[PATCH v2] powerpc/powernv: Add ultravisor message log interface

2019-08-23 Thread Claudio Carvalho
Ultravisor (UV) provides an in-memory console which follows the OPAL
in-memory console structure.

This patch extends the OPAL msglog code to also initialize the UV memory
console and provide a sysfs interface (uv_msglog) for userspace to view
the UV message log.

CC: Madhavan Srinivasan 
CC: Oliver O'Halloran 
Signed-off-by: Claudio Carvalho 
---
This patch depends on the "kvmppc: Paravirtualize KVM to support
ultravisor" patchset submitted by Claudio Carvalho.
---
 arch/powerpc/platforms/powernv/opal-msglog.c | 99 ++--
 1 file changed, 72 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c 
b/arch/powerpc/platforms/powernv/opal-msglog.c
index dc51d03c6370..da73908fdabe 100644
--- a/arch/powerpc/platforms/powernv/opal-msglog.c
+++ b/arch/powerpc/platforms/powernv/opal-msglog.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* OPAL in-memory console. Defined in OPAL source at core/console.c */
 struct memcons {
@@ -28,24 +29,26 @@ struct memcons {
 };
 
 static struct memcons *opal_memcons = NULL;
+static struct memcons *opal_uv_memcons;
 
-ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
+static ssize_t msglog_copy(struct memcons *memcons, const char *bin_attr_name,
+  char *to, loff_t pos, size_t count)
 {
const char *conbuf;
ssize_t ret;
size_t first_read = 0;
uint32_t out_pos, avail;
 
-   if (!opal_memcons)
+   if (!memcons)
return -ENODEV;
 
-   out_pos = be32_to_cpu(READ_ONCE(opal_memcons->out_pos));
+   out_pos = be32_to_cpu(READ_ONCE(memcons->out_pos));
 
/* Now we've read out_pos, put a barrier in before reading the new
 * data it points to in conbuf. */
smp_rmb();
 
-   conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys));
+   conbuf = phys_to_virt(be64_to_cpu(memcons->obuf_phys));
 
/* When the buffer has wrapped, read from the out_pos marker to the end
 * of the buffer, and then read the remaining data as in the un-wrapped
@@ -53,7 +56,7 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
if (out_pos & MEMCONS_OUT_POS_WRAP) {
 
out_pos &= MEMCONS_OUT_POS_MASK;
-   avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos;
+   avail = be32_to_cpu(memcons->obuf_size) - out_pos;
 
ret = memory_read_from_buffer(to, count, ,
conbuf + out_pos, avail);
@@ -71,8 +74,8 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
}
 
/* Sanity check. The firmware should not do this to us. */
-   if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) {
-   pr_err("OPAL: memory console corruption. Aborting read.\n");
+   if (out_pos > be32_to_cpu(memcons->obuf_size)) {
+   pr_err("OPAL: %s corruption. Aborting read.\n", bin_attr_name);
return -EINVAL;
}
 
@@ -86,53 +89,95 @@ ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
return ret;
 }
 
+#define BIN_ATTR_NAME_OPAL "msglog"
+#define BIN_ATTR_NAME_UV   "uv_msglog"
+
+ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count)
+{
+   return msglog_copy(opal_memcons, BIN_ATTR_NAME_OPAL, to, pos,
+  count);
+}
+
 static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj,
struct bin_attribute *bin_attr, char *to,
loff_t pos, size_t count)
 {
-   return opal_msglog_copy(to, pos, count);
+   return msglog_copy(opal_memcons, BIN_ATTR_NAME_OPAL, to, pos,
+  count);
+}
+
+static ssize_t opal_uv_msglog_read(struct file *file, struct kobject *kobj,
+  struct bin_attribute *bin_attr, char *to,
+  loff_t pos, size_t count)
+{
+   return msglog_copy(opal_uv_memcons, BIN_ATTR_NAME_UV, to, pos,
+  count);
 }
 
 static struct bin_attribute opal_msglog_attr = {
-   .attr = {.name = "msglog", .mode = 0400},
+   .attr = {.name = BIN_ATTR_NAME_OPAL, .mode = 0400},
.read = opal_msglog_read
 };
 
-void __init opal_msglog_init(void)
+static struct bin_attribute opal_uv_msglog_attr = {
+   .attr = {.name = BIN_ATTR_NAME_UV, .mode = 0400},
+   .read = opal_uv_msglog_read
+};
+
+static void __init msglog_init(struct memcons **memcons,
+  struct bin_attribute *bin_attr,
+  const char *dt_prop_name)
 {
-   u64 mcaddr;
-   struct memcons *mc;
+   u64 memcons_addr;
 
-   if (of_property_read_u64(opal_node, "ibm,opal-memcons", )) {
-   pr_warn("OPAL: Property ibm,opal-memcons not found, no message 
log\n");
+   

[PATCH v6 7/7] powerpc/kvm: Use UV_RETURN ucall to return to ultravisor

2019-08-21 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

When an SVM makes an hypercall or incurs some other exception, the
Ultravisor usually forwards (a.k.a. reflects) the exceptions to the
Hypervisor. After processing the exception, Hypervisor uses the
UV_RETURN ultracall to return control back to the SVM.

The expected register state on entry to this ultracall is:

* Non-volatile registers are restored to their original values.
* If returning from an hypercall, register R0 contains the return value
  (unlike other ultracalls) and, registers R4 through R12 contain any
  output values of the hypercall.
* R3 contains the ultracall number, i.e UV_RETURN.
* If returning with a synthesized interrupt, R2 contains the
  synthesized interrupt number.

Thanks to input from Paul Mackerras, Ram Pai and Mike Anderson.

Signed-off-by: Sukadev Bhattiprolu 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/kvm_host.h   |  1 +
 arch/powerpc/include/asm/ultravisor-api.h |  1 +
 arch/powerpc/kernel/asm-offsets.c |  1 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 39 +++
 4 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index e6e5f59aaa97..4bb552d639b8 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -283,6 +283,7 @@ struct kvm_arch {
cpumask_t cpu_in_guest;
u8 radix;
u8 fwnmi_enabled;
+   u8 secure_guest;
bool threads_indep;
bool nested_enable;
pgd_t *pgtable;
diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 8cd49abff4f3..6a0f9c74f959 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -24,5 +24,6 @@
 
 /* opcodes */
 #define UV_WRITE_PATE  0xF104
+#define UV_RETURN  0xF11C
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 4ccb6b3a7fbd..484f54dab247 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -506,6 +506,7 @@ int main(void)
OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
OFFSET(KVM_RADIX, kvm, arch.radix);
OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
+   OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 07181d0dfcb7..9a05b0d932ef 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Sign-extend HDEC if not on POWER9 */
 #define EXTEND_HDEC(reg)   \
@@ -1085,16 +1086,10 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
ld  r5, VCPU_LR(r4)
-   ld  r6, VCPU_CR(r4)
mtlrr5
-   mtcrr6
 
ld  r1, VCPU_GPR(R1)(r4)
-   ld  r2, VCPU_GPR(R2)(r4)
-   ld  r3, VCPU_GPR(R3)(r4)
ld  r5, VCPU_GPR(R5)(r4)
-   ld  r6, VCPU_GPR(R6)(r4)
-   ld  r7, VCPU_GPR(R7)(r4)
ld  r8, VCPU_GPR(R8)(r4)
ld  r9, VCPU_GPR(R9)(r4)
ld  r10, VCPU_GPR(R10)(r4)
@@ -1112,10 +1107,42 @@ BEGIN_FTR_SECTION
mtspr   SPRN_HDSISR, r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 
+   ld  r6, VCPU_KVM(r4)
+   lbz r7, KVM_SECURE_GUEST(r6)
+   cmpdi   r7, 0
+   ld  r6, VCPU_GPR(R6)(r4)
+   ld  r7, VCPU_GPR(R7)(r4)
+   bne ret_to_ultra
+
+   lwz r0, VCPU_CR(r4)
+   mtcrr0
+
ld  r0, VCPU_GPR(R0)(r4)
+   ld  r2, VCPU_GPR(R2)(r4)
+   ld  r3, VCPU_GPR(R3)(r4)
ld  r4, VCPU_GPR(R4)(r4)
HRFI_TO_GUEST
b   .
+/*
+ * Use UV_RETURN ultracall to return control back to the Ultravisor after
+ * processing an hypercall or interrupt that was forwarded (a.k.a. reflected)
+ * to the Hypervisor.
+ *
+ * All registers have already been loaded, except:
+ *   R0 = hcall result
+ *   R2 = SRR1, so UV can detect a synthesized interrupt (if any)
+ *   R3 = UV_RETURN
+ */
+ret_to_ultra:
+   lwz r0, VCPU_CR(r4)
+   mtcrr0
+
+   ld  r0, VCPU_GPR(R3)(r4)
+   mfspr   r2, SPRN_SRR1
+   li  r3, 0
+   ori r3, r3, UV_RETURN
+   ld  r4, VCPU_GPR(R4)(r4)
+   sc  2
 
 /*
  * Enter the guest on a P9 or later system where we have exactly
-- 
2.20.1



[PATCH v6 6/7] powerpc/powernv: Access LDBAR only if ultravisor disabled

2019-08-21 Thread Claudio Carvalho
LDBAR is a per-thread SPR populated and used by the thread-imc pmu
driver to dump the data counter into memory. It contains memory along
with few other configuration bits. LDBAR is populated and enabled only
when any of the thread imc pmu events are monitored.

In ultravisor enabled systems, LDBAR becomes ultravisor privileged and
an attempt to write to it will cause a Hypervisor Emulation Assistance
interrupt.

In ultravisor enabled systems, the ultravisor is responsible to maintain
the LDBAR (e.g. save and restore it).

This restricts LDBAR access to only when ultravisor is disabled.

Signed-off-by: Claudio Carvalho 
Reviewed-by: Ram Pai 
Reviewed-by: Ryan Grimm 
---
 arch/powerpc/platforms/powernv/idle.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 09f49eed7fb8..78599bca66c2 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -675,7 +675,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
sprs.ptcr   = mfspr(SPRN_PTCR);
sprs.rpr= mfspr(SPRN_RPR);
sprs.tscr   = mfspr(SPRN_TSCR);
-   sprs.ldbar  = mfspr(SPRN_LDBAR);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   sprs.ldbar = mfspr(SPRN_LDBAR);
 
sprs_saved = true;
 
@@ -789,7 +790,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
mtspr(SPRN_MMCR0,   sprs.mmcr0);
mtspr(SPRN_MMCR1,   sprs.mmcr1);
mtspr(SPRN_MMCR2,   sprs.mmcr2);
-   mtspr(SPRN_LDBAR,   sprs.ldbar);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_LDBAR, sprs.ldbar);
 
mtspr(SPRN_SPRG3,   local_paca->sprg_vdso);
 
-- 
2.20.1



[PATCH v6 5/7] powerpc/mm: Write to PTCR only if ultravisor disabled

2019-08-21 Thread Claudio Carvalho
In ultravisor enabled systems, PTCR becomes ultravisor privileged only
for writing and an attempt to write to it will cause a Hypervisor
Emulation Assitance interrupt.

This patch uses the set_ptcr_when_no_uv() function to restrict PTCR
writing to only when ultravisor is disabled.

Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/ultravisor.h| 12 
 arch/powerpc/mm/book3s64/hash_utils.c|  5 +++--
 arch/powerpc/mm/book3s64/pgtable.c   |  2 +-
 arch/powerpc/mm/book3s64/radix_pgtable.c |  8 +---
 4 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index 6fe1f365dec8..d7aa97aa7834 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -10,10 +10,22 @@
 
 #include 
 #include 
+#include 
 
 int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
  int depth, void *data);
 
+/*
+ * In ultravisor enabled systems, PTCR becomes ultravisor privileged only for
+ * writing and an attempt to write to it will cause a Hypervisor Emulation
+ * Assistance interrupt.
+ */
+static inline void set_ptcr_when_no_uv(u64 val)
+{
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_PTCR, val);
+}
+
 static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
 {
return ucall_norets(UV_WRITE_PATE, lpid, dw0, dw1);
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c 
b/arch/powerpc/mm/book3s64/hash_utils.c
index c3bfef08dcf8..4d0bb194ed70 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -62,6 +62,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -1076,8 +1077,8 @@ void hash__early_init_mmu_secondary(void)
if (!cpu_has_feature(CPU_FTR_ARCH_300))
mtspr(SPRN_SDR1, _SDR1);
else
-   mtspr(SPRN_PTCR,
- __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+   set_ptcr_when_no_uv(__pa(partition_tb) |
+   (PATB_SIZE_SHIFT - 12));
}
/* Initialize SLB */
slb_initialize();
diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 4173f6931009..01a7570c10e0 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -207,7 +207,7 @@ void __init mmu_partition_table_init(void)
 * 64 K size.
 */
ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
-   mtspr(SPRN_PTCR, ptcr);
+   set_ptcr_when_no_uv(ptcr);
powernv_set_nmmu_ptcr(ptcr);
 }
 
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
b/arch/powerpc/mm/book3s64/radix_pgtable.c
index 2204d8eeb784..ec3560b96177 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -650,8 +651,9 @@ void radix__early_init_mmu_secondary(void)
lpcr = mfspr(SPRN_LPCR);
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
 
-   mtspr(SPRN_PTCR,
- __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+   set_ptcr_when_no_uv(__pa(partition_tb) |
+   (PATB_SIZE_SHIFT - 12));
+
radix_init_amor();
}
 
@@ -667,7 +669,7 @@ void radix__mmu_cleanup_all(void)
if (!firmware_has_feature(FW_FEATURE_LPAR)) {
lpcr = mfspr(SPRN_LPCR);
mtspr(SPRN_LPCR, lpcr & ~LPCR_UPRT);
-   mtspr(SPRN_PTCR, 0);
+   set_ptcr_when_no_uv(0);
powernv_set_nmmu_ptcr(0);
radix__flush_tlb_all();
}
-- 
2.20.1



[PATCH v6 4/7] powerpc/mm: Use UV_WRITE_PATE ucall to register a PATE

2019-08-21 Thread Claudio Carvalho
From: Michael Anderson 

When Ultravisor (UV) is enabled, the partition table is stored in secure
memory and can only be accessed via the UV. The Hypervisor (HV) however
maintains a copy of the partition table in normal memory to allow Nest MMU
translations to occur (for normal VMs). The HV copy includes partition
table entries (PATE)s for secure VMs which would currently be unused
(Nest MMU translations cannot access secure memory) but they would be
needed as we add functionality.

This patch adds the UV_WRITE_PATE ucall which is used to update the PATE
for a VM (both normal and secure) when Ultravisor is enabled.

Signed-off-by: Michael Anderson 
Signed-off-by: Madhavan Srinivasan 
Signed-off-by: Ram Pai 
[ cclaudio: Write the PATE in HV's table before doing that in UV's ]
Signed-off-by: Claudio Carvalho 
Reviewed-by: Ryan Grimm 
---
 arch/powerpc/include/asm/ultravisor-api.h |  5 +++
 arch/powerpc/include/asm/ultravisor.h |  8 
 arch/powerpc/mm/book3s64/pgtable.c| 50 +--
 3 files changed, 50 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 88ffa78f9d61..8cd49abff4f3 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -11,6 +11,7 @@
 #include 
 
 /* Return codes */
+#define U_BUSY H_BUSY
 #define U_FUNCTION H_FUNCTION
 #define U_NOT_AVAILABLEH_NOT_AVAILABLE
 #define U_P2   H_P2
@@ -18,6 +19,10 @@
 #define U_P4   H_P4
 #define U_P5   H_P5
 #define U_PARAMETERH_PARAMETER
+#define U_PERMISSION   H_PERMISSION
 #define U_SUCCESS  H_SUCCESS
 
+/* opcodes */
+#define UV_WRITE_PATE  0xF104
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index dc6e1ea198f2..6fe1f365dec8 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -8,7 +8,15 @@
 #ifndef _ASM_POWERPC_ULTRAVISOR_H
 #define _ASM_POWERPC_ULTRAVISOR_H
 
+#include 
+#include 
+
 int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
  int depth, void *data);
 
+static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
+{
+   return ucall_norets(UV_WRITE_PATE, lpid, dw0, dw1);
+}
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 7d0e0d0d22c4..4173f6931009 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -12,6 +12,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -209,21 +211,10 @@ void __init mmu_partition_table_init(void)
powernv_set_nmmu_ptcr(ptcr);
 }
 
-void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-  unsigned long dw1)
+static void flush_partition(unsigned int lpid, bool radix)
 {
-   unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
-
-   partition_tb[lpid].patb0 = cpu_to_be64(dw0);
-   partition_tb[lpid].patb1 = cpu_to_be64(dw1);
-
-   /*
-* Global flush of TLBs and partition table caches for this lpid.
-* The type of flush (hash or radix) depends on what the previous
-* use of this partition ID was, not the new use.
-*/
asm volatile("ptesync" : : : "memory");
-   if (old & PATB_HR) {
+   if (radix) {
asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
 "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
@@ -237,6 +228,39 @@ void mmu_partition_table_set_entry(unsigned int lpid, 
unsigned long dw0,
/* do we need fixup here ?*/
asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
+
+void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
+ unsigned long dw1)
+{
+   unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
+
+   /*
+* When ultravisor is enabled, the partition table is stored in secure
+* memory and can only be accessed doing an ultravisor call. However, we
+* maintain a copy of the partition table in normal memory to allow Nest
+* MMU translations to occur (for normal VMs).
+*
+* Therefore, here we always update partition_tb, regardless of whether
+* we are running under an ultravisor or not.
+*/
+   partition_tb[lpid].patb0 = cpu_to_be64(dw0);
+   partition_tb[lpid].patb1 = cpu_to_be64(dw1);
+
+   /*
+* If ultravisor is enabled, we do an ultravisor call to register the
+* partition table entry (PATE), which also do a global 

[PATCH v6 3/7] powerpc/powernv: Introduce FW_FEATURE_ULTRAVISOR

2019-08-21 Thread Claudio Carvalho
In PEF enabled systems, some of the resources which were previously
hypervisor privileged are now ultravisor privileged and controlled by
the ultravisor firmware.

This adds FW_FEATURE_ULTRAVISOR to indicate if PEF is enabled.

The host kernel can use FW_FEATURE_ULTRAVISOR, for instance, to skip
accessing resources (e.g. PTCR and LDBAR) in case PEF is enabled.

Signed-off-by: Claudio Carvalho 
[ andmike: Device node name to "ibm,ultravisor" ]
Signed-off-by: Michael Anderson 
---
 arch/powerpc/include/asm/firmware.h |  5 +++--
 arch/powerpc/include/asm/ultravisor.h   | 14 
 arch/powerpc/kernel/prom.c  |  4 
 arch/powerpc/platforms/powernv/Makefile |  1 +
 arch/powerpc/platforms/powernv/ultravisor.c | 24 +
 5 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/platforms/powernv/ultravisor.c

diff --git a/arch/powerpc/include/asm/firmware.h 
b/arch/powerpc/include/asm/firmware.h
index faeca8b76c8c..b3e214a97f3a 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -50,6 +50,7 @@
 #define FW_FEATURE_DRC_INFOASM_CONST(0x0008)
 #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0010)
 #define FW_FEATURE_PAPR_SCMASM_CONST(0x0020)
+#define FW_FEATURE_ULTRAVISOR  ASM_CONST(0x0040)
 
 #ifndef __ASSEMBLY__
 
@@ -68,9 +69,9 @@ enum {
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE |
-   FW_FEATURE_PAPR_SCM,
+   FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_PSERIES_ALWAYS = 0,
-   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
+   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_POWERNV_ALWAYS = 0,
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
new file mode 100644
index ..dc6e1ea198f2
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor definitions
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_H
+#define _ASM_POWERPC_ULTRAVISOR_H
+
+int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+ int depth, void *data);
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 7159e791a70d..5828f1c81dc9 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -55,6 +55,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -702,6 +703,9 @@ void __init early_init_devtree(void *params)
 #ifdef CONFIG_PPC_POWERNV
/* Some machines might need OPAL info for debugging, grab it now. */
of_scan_flat_dt(early_init_dt_scan_opal, NULL);
+
+   /* Scan tree for ultravisor feature */
+   of_scan_flat_dt(early_init_dt_scan_ultravisor, NULL);
 #endif
 
 #ifdef CONFIG_FA_DUMP
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index 69a3aefa905b..49186f0985a4 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -4,6 +4,7 @@ obj-y   += idle.o opal-rtc.o opal-nvram.o 
opal-lpc.o opal-flash.o
 obj-y  += rng.o opal-elog.o opal-dump.o opal-sysparam.o 
opal-sensor.o
 obj-y  += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
 obj-y  += opal-kmsg.o opal-powercap.o opal-psr.o 
opal-sensor-groups.o
+obj-y  += ultravisor.o
 
 obj-$(CONFIG_SMP)  += smp.o subcore.o subcore-asm.o
 obj-$(CONFIG_PCI)  += pci.o pci-ioda.o npu-dma.o pci-ioda-tce.o
diff --git a/arch/powerpc/platforms/powernv/ultravisor.c 
b/arch/powerpc/platforms/powernv/ultravisor.c
new file mode 100644
index ..02ac57b4bded
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/ultravisor.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ultravisor high level interfaces
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data)
+{
+   if (!of_flat_dt_is_compatible(node, "ibm,ultravisor"))
+   return 0;
+
+   powerpc_firmware_features |= FW_FEATURE_ULTRAVISOR;
+   pr_debug("Ultravisor detected!\n");
+   return 1;
+}
-- 
2.20.1



[PATCH v6 2/7] powerpc/kernel: Add ucall_norets() ultravisor call handler

2019-08-21 Thread Claudio Carvalho
The ultracalls (ucalls for short) allow the Secure Virtual Machines
(SVM)s and hypervisor to request services from the ultravisor such as
accessing a register or memory region that can only be accessed when
running in ultravisor-privileged mode.

This patch adds the ucall_norets() ultravisor call handler.

The specific service needed from an ucall is specified in register
R3 (the first parameter to the ucall). Other parameters to the
ucall, if any, are specified in registers R4 through R12.

Return value of all ucalls is in register R3. Other output values
from the ucall, if any, are returned in registers R4 through R12.

Each ucall returns specific error codes, applicable in the context
of the ucall. However, like with the PowerPC Architecture Platform
Reference (PAPR), if no specific error code is defined for a particular
situation, then the ucall will fallback to an erroneous
parameter-position based code. i.e U_PARAMETER, U_P2, U_P3 etc depending
on the ucall parameter that may have caused the error.

Every host kernel (powernv) needs to be able to do ucalls in case it
ends up being run in a machine with ultravisor enabled. Otherwise, the
kernel may crash early in boot trying to access ultravisor resources,
for instance, trying to set the partition table entry 0. Secure guests
also need to be able to do ucalls and its kernel may not have
CONFIG_PPC_POWERNV=y. For that reason, the ucall.S file is placed under
arch/powerpc/kernel.

If ultravisor is not enabled, the ucalls will be redirected to the
hypervisor which must handle/fail the call.

Thanks to inputs from Ram Pai and Michael Anderson.

Signed-off-by: Claudio Carvalho 

---
Ultravisor call support for secure guests is being proposed as part of
the patchset "Secure Virtual Machine Enablement" posted by Thiago
Bauermann.
---
 arch/powerpc/include/asm/asm-prototypes.h | 11 +++
 arch/powerpc/include/asm/ultravisor-api.h | 23 +++
 arch/powerpc/kernel/Makefile  |  1 +
 arch/powerpc/kernel/ucall.S   | 14 ++
 4 files changed, 49 insertions(+)
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/kernel/ucall.S

diff --git a/arch/powerpc/include/asm/asm-prototypes.h 
b/arch/powerpc/include/asm/asm-prototypes.h
index ec1c97a8e8cb..e698f48cbc6d 100644
--- a/arch/powerpc/include/asm/asm-prototypes.h
+++ b/arch/powerpc/include/asm/asm-prototypes.h
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -34,6 +35,16 @@ extern struct static_key hcall_tracepoint_key;
 void __trace_hcall_entry(unsigned long opcode, unsigned long *args);
 void __trace_hcall_exit(long opcode, long retval, unsigned long *retbuf);
 
+/* Ultravisor */
+#ifdef CONFIG_PPC_POWERNV
+long ucall_norets(unsigned long opcode, ...);
+#else
+static inline long ucall_norets(unsigned long opcode, ...)
+{
+   return U_NOT_AVAILABLE;
+}
+#endif
+
 /* OPAL */
 int64_t __opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
int64_t a4, int64_t a5, int64_t a6, int64_t a7,
diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
new file mode 100644
index ..88ffa78f9d61
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor API.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_API_H
+#define _ASM_POWERPC_ULTRAVISOR_API_H
+
+#include 
+
+/* Return codes */
+#define U_FUNCTION H_FUNCTION
+#define U_NOT_AVAILABLEH_NOT_AVAILABLE
+#define U_P2   H_P2
+#define U_P3   H_P3
+#define U_P4   H_P4
+#define U_P5   H_P5
+#define U_PARAMETERH_PARAMETER
+#define U_SUCCESS  H_SUCCESS
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ea0c69236789..c6c4ea240b2a 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -156,6 +156,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
+obj-$(CONFIG_PPC_POWERNV)  += ucall.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/ucall.S b/arch/powerpc/kernel/ucall.S
new file mode 100644
index ..07296bc39166
--- /dev/null
+++ b/arch/powerpc/kernel/ucall.S
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Generic code to perform an ultravisor call.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+#include 
+
+_GLOBAL(ucall_norets)
+EXPORT_SYMBOL_GPL(ucall_norets)
+   sc  2   /* Invoke the ultravisor */
+   blr /* Return r3 = status */
-- 
2.20.1



[PATCH v6 1/7] Documentation/powerpc: Ultravisor API

2019-08-21 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

Protected Execution Facility (PEF) is an architectural change for
POWER 9 that enables Secure Virtual Machines (SVMs). When enabled,
PEF adds a new higher privileged mode, called Ultravisor mode, to POWER
architecture. Along with the new mode there is new firmware called the
Protected Execution Ultravisor (or Ultravisor for short).

POWER 9 DD2.3 chips (PVR=0x004e1203) or greater will be PEF-capable.

Attached documentation provides an overview of PEF and defines the API
for various interfaces that must be implemented in the Ultravisor
firmware as well as in the KVM Hypervisor.

Based on input from Mike Anderson, Thiago Bauermann, Claudio Carvalho,
Ben Herrenschmidt, Guerney Hunt, Paul Mackerras.

Signed-off-by: Sukadev Bhattiprolu 
Signed-off-by: Ram Pai 
Signed-off-by: Guerney Hunt 
Reviewed-by: Claudio Carvalho 
Reviewed-by: Michael Anderson 
Reviewed-by: Thiago Bauermann 
Signed-off-by: Claudio Carvalho 
---
 Documentation/powerpc/ultravisor.rst | 1057 ++
 1 file changed, 1057 insertions(+)
 create mode 100644 Documentation/powerpc/ultravisor.rst

diff --git a/Documentation/powerpc/ultravisor.rst 
b/Documentation/powerpc/ultravisor.rst
new file mode 100644
index ..94a149f34ec3
--- /dev/null
+++ b/Documentation/powerpc/ultravisor.rst
@@ -0,0 +1,1057 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. _ultravisor:
+
+
+Protected Execution Facility
+
+
+.. contents::
+:depth: 3
+
+.. sectnum::
+:depth: 3
+
+Protected Execution Facility
+
+
+Protected Execution Facility (PEF) is an architectural change for
+POWER 9 that enables Secure Virtual Machines (SVMs). DD2.3 chips
+(PVR=0x004e1203) or greater will be PEF-capable. A new ISA release
+will include the PEF RFC02487 changes.
+
+When enabled, PEF adds a new higher privileged mode, called Ultravisor
+mode, to POWER architecture. Along with the new mode there is new
+firmware called the Protected Execution Ultravisor (or Ultravisor
+for short). Ultravisor mode is the highest privileged mode in POWER
+architecture.
+
+   +--+
+   | Privilege States |
+   +==+
+   |  Problem |
+   +--+
+   |  Supervisor  |
+   +--+
+   |  Hypervisor  |
+   +--+
+   |  Ultravisor  |
+   +--+
+
+PEF protects SVMs from the hypervisor, privileged users, and other
+VMs in the system. SVMs are protected while at rest and can only be
+executed by an authorized machine. All virtual machines utilize
+hypervisor services. The Ultravisor filters calls between the SVMs
+and the hypervisor to assure that information does not accidentally
+leak. All hypercalls except H_RANDOM are reflected to the hypervisor.
+H_RANDOM is not reflected to prevent the hypervisor from influencing
+random values in the SVM.
+
+To support this there is a refactoring of the ownership of resources
+in the CPU. Some of the resources which were previously hypervisor
+privileged are now ultravisor privileged.
+
+Hardware
+
+
+The hardware changes include the following:
+
+* There is a new bit in the MSR that determines whether the current
+  process is running in secure mode, MSR(S) bit 41. MSR(S)=1, process
+  is in secure mode, MSR(s)=0 process is in normal mode.
+
+* The MSR(S) bit can only be set by the Ultravisor.
+
+* HRFID cannot be used to set the MSR(S) bit. If the hypervisor needs
+  to return to a SVM it must use an ultracall. It can determine if
+  the VM it is returning to is secure.
+
+* There is a new Ultravisor privileged register, SMFCTRL, which has an
+  enable/disable bit SMFCTRL(E).
+
+* The privilege of a process is now determined by three MSR bits,
+  MSR(S, HV, PR). In each of the tables below the modes are listed
+  from least privilege to highest privilege. The higher privilege
+  modes can access all the resources of the lower privilege modes.
+
+  **Secure Mode MSR Settings**
+
+  +---+---+---+---+
+  | S | HV| PR|Privilege  |
+  +===+===+===+===+
+  | 1 | 0 | 1 | Problem   |
+  +---+---+---+---+
+  | 1 | 0 | 0 | Privileged(OS)|
+  +---+---+---+---+
+  | 1 | 1 | 0 | Ultravisor|
+  +---+---+---+---+
+  | 1 | 1 | 1 | Reserved  |
+  +---+---+---+---+
+
+  **Normal Mode MSR Settings**
+
+  +---+---+---+---+
+  | S | HV| PR|Privilege  |
+  +===+===+===+===+
+  | 0 | 0 | 1 | Problem   |
+  +---+---+---+---+
+  | 0 | 0 | 0 | Privileged(OS)|
+  +---+---+---+---+
+  | 0 | 1 | 0 | Hypervisor

[PATCH v6 0/7] kvmppc: Paravirtualize KVM to support ultravisor

2019-08-21 Thread Claudio Carvalho
hitespaces in ucall.S and in ultravisor-api.h.
  - Changed to depend only on CONFIG_PPC_POWERNV.
  - Changed the ucall wrapper to pass the ucall number in R3.

- Patch "KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a
  PATE:
  - Changed to depend only on CONFIG_PPC_POWERNV.

- Patch "KVM: PPC: Ultravisor: Restrict LDBAR access":
  - Fixed comment in opal-imc.c to be "Disable IMC devices, when
    Ultravisor is enabled.
  - Fixed signed-off-by.

- Patch "KVM: PPC: Ultravisor: Enter a secure guest":
  - Changed the UV_RETURN assembly call to save the actual R3 in
R0 for the ultravisor and pass the UV_RETURN call number in R3.

- Patch "KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr":
  - Fixed commit message.

- Rebased to powerpc/next.

Claudio Carvalho (4):
  powerpc/kernel: Add ucall_norets() ultravisor call handler
  powerpc/powernv: Introduce FW_FEATURE_ULTRAVISOR
  powerpc/mm: Write to PTCR only if ultravisor disabled
  powerpc/powernv: Access LDBAR only if ultravisor disabled

Michael Anderson (1):
  powerpc/mm: Use UV_WRITE_PATE ucall to register a PATE

Sukadev Bhattiprolu (2):
  Documentation/powerpc: Ultravisor API
  powerpc/kvm: Use UV_RETURN ucall to return to ultravisor

 Documentation/powerpc/ultravisor.rst| 1057 +++
 arch/powerpc/include/asm/asm-prototypes.h   |   11 +
 arch/powerpc/include/asm/firmware.h |5 +-
 arch/powerpc/include/asm/kvm_host.h |1 +
 arch/powerpc/include/asm/ultravisor-api.h   |   29 +
 arch/powerpc/include/asm/ultravisor.h   |   34 +
 arch/powerpc/kernel/Makefile|1 +
 arch/powerpc/kernel/asm-offsets.c   |1 +
 arch/powerpc/kernel/prom.c  |4 +
 arch/powerpc/kernel/ucall.S |   14 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S |   39 +-
 arch/powerpc/mm/book3s64/hash_utils.c   |5 +-
 arch/powerpc/mm/book3s64/pgtable.c  |   52 +-
 arch/powerpc/mm/book3s64/radix_pgtable.c|8 +-
 arch/powerpc/platforms/powernv/Makefile |1 +
 arch/powerpc/platforms/powernv/idle.c   |6 +-
 arch/powerpc/platforms/powernv/ultravisor.c |   24 +
 17 files changed, 1263 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/powerpc/ultravisor.rst
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/kernel/ucall.S
 create mode 100644 arch/powerpc/platforms/powernv/ultravisor.c

-- 
2.20.1



Re: [PATCH v5 4/7] powerpc/mm: Use UV_WRITE_PATE ucall to register a PATE

2019-08-21 Thread Claudio Carvalho


On 8/14/19 8:33 AM, Michael Ellerman wrote:
> Hi Claudio,
>
> Claudio Carvalho  writes:
>> From: Michael Anderson 
>>
>> In ultravisor enabled systems, the ultravisor creates and maintains the
>> partition table in secure memory where the hypervisor cannot access, and
>^
>which?
>
>> therefore, the hypervisor have to do the UV_WRITE_PATE ucall whenever it
> ^  ^
> hasa
>> wants to set a partition table entry (PATE).
>>
>> This patch adds the UV_WRITE_PATE ucall and uses it to set a PATE if
>> ultravisor is enabled. Additionally, this also also keeps a copy of the
>> partition table because the nestMMU does not have access to secure
>> memory. Such copy has entries for nonsecure and hypervisor partition.
> I'm having trouble parsing the last sentence there.
>
> Or at least it doesn't seem to match the code, or I don't understand
> either the code or the comment. More below.
>
>> diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
>> b/arch/powerpc/mm/book3s64/pgtable.c
>> index 85bc81abd286..033731f5dbaa 100644
>> --- a/arch/powerpc/mm/book3s64/pgtable.c
>> +++ b/arch/powerpc/mm/book3s64/pgtable.c
>> @@ -213,34 +223,50 @@ void __init mmu_partition_table_init(void)
>>  powernv_set_nmmu_ptcr(ptcr);
>>  }
>>  
>> -void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
>> -   unsigned long dw1)
>> +/*
>> + * Global flush of TLBs and partition table caches for this lpid. The type 
>> of
>> + * flush (hash or radix) depends on what the previous use of this partition 
>> ID
>> + * was, not the new use.
>> + */
>> +static void flush_partition(unsigned int lpid, unsigned long old_patb0)
> A nicer API would be for the 2nd param to be a "bool radix", and have
> the caller worry about the fact that it comes from (patb0 & PATB_HR).

Yes, I agree. I applied that to next patchset version.


>
>>  {
>> -unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
>> -
>> -partition_tb[lpid].patb0 = cpu_to_be64(dw0);
>> -partition_tb[lpid].patb1 = cpu_to_be64(dw1);
>> -
>> -/*
>> - * Global flush of TLBs and partition table caches for this lpid.
>> - * The type of flush (hash or radix) depends on what the previous
>> - * use of this partition ID was, not the new use.
>> - */
>>  asm volatile("ptesync" : : : "memory");
>> -if (old & PATB_HR) {
>> -asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
>> +if (old_patb0 & PATB_HR) {
>> +asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 1) : :
>>   "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>> -asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
>> +asm volatile(PPC_TLBIE_5(%0, %1, 2, 1, 1) : :
> That looks like an unrelated whitespace change.
>
>>   "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>>  trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
>>  } else {
>> -asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
>> +asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 0) : :
> Ditto.

True. I dropped the two changes above in the next patchset version.

Thanks,
Claudio


>
>>   "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>>  trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
>>  }
>>  /* do we need fixup here ?*/
>>  asm volatile("eieio; tlbsync; ptesync" : : : "memory");
>>  }
>> +
>> +void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
>> +  unsigned long dw1)
>> +{
>> +unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
>> +
>> +partition_tb[lpid].patb0 = cpu_to_be64(dw0);
>> +partition_tb[lpid].patb1 = cpu_to_be64(dw1);
> ie. here we always update the copy of the partition table, regardless of
> whether we're running under an ultravisor or not. So the copy is a
> complete copy isn't it?
>
>> +/*
>> + * In ultravisor enabled systems, the ultravisor maintains the partition
>> + * table in secure memory where we don't have access, therefore, we have
>> + * to do a ucall to set an entry.
>> + */
>> +if (firmware_has_feature(FW_FEATURE_ULTRAVISOR)) {
>> +uv_register_pate(lpid, dw0, dw1);
>> +pr_info("PATE registered by ultravisor: dw0 = 0x%lx, dw1 = 
>> 0x%lx\n",
>> +dw0, dw1);
>> +} else {
>> +flush_partition(lpid, old);
>> +}
> What is different is whether we flush or not.
>
> And don't we still need to do the flush for the nestMMU? I assume we're
> saying the ultravisor will broadcast a flush for us, which will also
> handle the nestMMU case?
>
> cheers
>


Re: [PATCH v5 2/7] powerpc/kernel: Add ucall_norets() ultravisor call handler

2019-08-21 Thread Claudio Carvalho


On 8/14/19 3:34 PM, Segher Boessenkool wrote:
> On Wed, Aug 14, 2019 at 08:46:15PM +1000, Michael Ellerman wrote:
>> Claudio Carvalho  writes:
>>> +_GLOBAL(ucall_norets)
>>> +EXPORT_SYMBOL_GPL(ucall_norets)
>>> +   mfcrr0
>>> +   stw r0,8(r1)
>>> +
>>> +   sc  2   /* Invoke the ultravisor */
>>> +
>>> +   lwz r0,8(r1)
>>> +   mtcrf   0xff,r0
>>> +   blr /* Return r3 = status */
>> Paulus points that we shouldn't need to save CR here. Our caller will
>> have already saved it if it needed to, and we don't use CR in this
>> function so we don't need to save it.
>>
>> That's assuming the Ultravisor follows the hcall ABI in which CR2-4 are
>> non-volatile (PAPR § 14.5.3).
> And assuming the ultravisor already clears (or sets, or whatever) all CR
> fields it does not want to leak the contents of (which it also should,
> of course).

Thanks Segher. We are working on that in the ultravisor source code.

Claudio.


>
>> I know plpar_hcall_norets() does save CR, but it shouldn't need to, that
>> seems to be historical. aka. no one knows why it does it but it always
>> has.
>
> Segher
>


Re: [PATCH v5 2/7] powerpc/kernel: Add ucall_norets() ultravisor call handler

2019-08-21 Thread Claudio Carvalho


On 8/14/19 7:46 AM, Michael Ellerman wrote:
> Claudio Carvalho  writes:
>> diff --git a/arch/powerpc/kernel/ucall.S b/arch/powerpc/kernel/ucall.S
>> new file mode 100644
>> index ..de9133e45d21
>> --- /dev/null
>> +++ b/arch/powerpc/kernel/ucall.S
>> @@ -0,0 +1,20 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Generic code to perform an ultravisor call.
>> + *
>> + * Copyright 2019, IBM Corporation.
>> + *
>> + */
>> +#include 
>> +#include 
>> +
>> +_GLOBAL(ucall_norets)
>> +EXPORT_SYMBOL_GPL(ucall_norets)
>> +mfcrr0
>> +stw r0,8(r1)
>> +
>> +sc  2   /* Invoke the ultravisor */
>> +
>> +lwz r0,8(r1)
>> +mtcrf   0xff,r0
>> +blr /* Return r3 = status */
> Paulus points that we shouldn't need to save CR here. Our caller will
> have already saved it if it needed to, and we don't use CR in this
> function so we don't need to save it.

Dropped the CR save/restore in the next patchset version:

_GLOBAL(ucall_norets)
EXPORT_SYMBOL_GPL(ucall_norets)
    sc  2   /* Invoke the ultravisor */
    blr /* Return r3 = status */


Thanks,
Claudio


>
> That's assuming the Ultravisor follows the hcall ABI in which CR2-4 are
> non-volatile (PAPR § 14.5.3).
>
> I know plpar_hcall_norets() does save CR, but it shouldn't need to, that
> seems to be historical. aka. no one knows why it does it but it always
> has.
>
> cheers
>


Re: [PATCH v5 1/7] Documentation/powerpc: Ultravisor API

2019-08-21 Thread Claudio Carvalho


On 8/9/19 9:45 AM, Michael Ellerman wrote:
> Claudio Carvalho  writes:
>> From: Sukadev Bhattiprolu 
>>
>> POWER9 processor includes support for Protected Execution Facility (PEF).

>> Which POWER9? Please be more precise.
>>
>> It's public knowledge that some versions of Power9 don't have PEF (or
>> have it broken / fused off).
>>
>> People are going to try and test this on various chip revisions that are
>> out in the wild, we need to make it clear where it's expected to work
>> and where it's not.

Updated this part of the commit message to:

    Protected Execution Facility (PEF) is an architectural change for
    POWER 9 that enables Secure Virtual Machines (SVMs). When enabled,
    PEF adds a new higher privileged mode, called Ultravisor mode, to POWER
    architecture. Along with the new mode there is new firmware called the
    Protected Execution Ultravisor (or Ultravisor for short).
   
    POWER 9 DD2.3 chips (PVR=0x004e1203) or greater will be PEF-capable.

    Attached documentation ...


>
>> Attached documentation provides an overview of PEF and defines the API
>> for various interfaces that must be implemented in the Ultravisor
>> firmware as well as in the KVM Hypervisor.
>>
>> Based on input from Mike Anderson, Thiago Bauermann, Claudio Carvalho,
>> Ben Herrenschmidt, Guerney Hunt, Paul Mackerras.
>>
>> Signed-off-by: Sukadev Bhattiprolu 
>> Signed-off-by: Ram Pai 
>> Signed-off-by: Guerney Hunt 
>> Reviewed-by: Claudio Carvalho 
>> Reviewed-by: Michael Anderson 
>> Reviewed-by: Thiago Bauermann 
>> Signed-off-by: Claudio Carvalho 
>> ---
>>  Documentation/powerpc/ultravisor.rst | 1055 ++
>>  1 file changed, 1055 insertions(+)
>>  create mode 100644 Documentation/powerpc/ultravisor.rst
>>
>> diff --git a/Documentation/powerpc/ultravisor.rst 
>> b/Documentation/powerpc/ultravisor.rst
>> new file mode 100644
>> index ..8d5246585b66
>> --- /dev/null
>> +++ b/Documentation/powerpc/ultravisor.rst
>> @@ -0,0 +1,1055 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +.. _ultravisor:
>> +
>> +
>> +Protected Execution Facility
>> +
>> +
>> +.. contents::
>> +:depth: 3
>> +
>> +.. sectnum::
>> +:depth: 3
>> +
>> +Protected Execution Facility
>> +
>> +
>> +Protected Execution Facility (PEF) is an architectural change for
>> +POWER 9 that enables Secure Virtual Machines (SVMs). When enabled,
> Ditto here.
>
> Also you don't mention which ISA version PEF is (will be) documented in.
> Do we know? Or can we at least reference the RFC number so folks can
> find it.
>
> Otherwise this looks really good. I'll try and find time to proof read
> it thoroughly.
>
> cheers
>
>> +PEF adds a new higher privileged mode, called Ultravisor mode, to
>> +POWER architecture. Along with the new mode there is new firmware
>> +called the Protected Execution Ultravisor (or Ultravisor for short).
>> +Ultravisor mode is the highest privileged mode in POWER architecture.

Updated this part to:

    Protected Execution Facility (PEF) is an architectural change for
    POWER 9 that enables Secure Virtual Machines (SVMs). DD2.3 chips
    (PVR=0x004e1203) or greater will be PEF-capable. A new ISA release
    will include the PEF RFC02487 changes.

    When enabled, PEF adds a new higher privileged mode, called Ultravisor
    mode, to POWER architecture. Along with the new mode there is new
    firmware called the Protected Execution Ultravisor (or Ultravisor
    for short). Ultravisor mode is the highest privileged mode in POWER
    architecture.

Followed by the original table below.

Thanks Michael

Claudio.

>> +
>> ++--+
>> +| Privilege States |
>> ++==+
>> +|  Problem |
>> ++--+
>> +|  Supervisor  |
>> ++--+
>> +|  Hypervisor  |
>> ++--+
>> +|  Ultravisor  |
>> ++--+
>> +
>> +PEF protects SVMs from the hypervisor, privileged users, and other
>> +VMs in the system. SVMs are protected while at rest and can only be
>> +executed by an authorized machine. All virtual machines utilize
>> +hypervisor services. The Ultravisor filters calls between the SVMs
>> +and the hypervisor to assure that information does not accidentally
>> +leak. All hypercalls except H_RANDOM are reflected to the hyperviso

Re: [PATCH v5 1/7] Documentation/powerpc: Ultravisor API

2019-08-21 Thread Claudio Carvalho


On 8/12/19 12:58 PM, Fabiano Rosas wrote:
> Claudio Carvalho  writes:
>
> Some small suggestions below:
>
>> +
>> +* The privilege of a process is now determined by three MSR bits,
>> +  MSR(S, HV, PR). In each of the tables below the modes are listed
>> +  from least privilege to highest privilege. The higher privilege
>> +  modes can access all the resources of the lower privilege modes.
>> +
>> +  **Secure Mode MSR Settings**
>> +
>> +  +---+---+---+---+
>> +  | S | HV| PR|Privilege  |
>> +  +===+===+===+===+
>> +  | 1 | 0 | 1 | Problem   |
>> +  +---+---+---+---+
>> +  | 1 | 0 | 0 | Privileged(OS)|
>> +  +---+---+---+---+
>> +  | 1 | 1 | 0 | Ultravisor|
>> +  +---+---+---+---+
>> +  | 1 | 1 | 1 | Reserved  |
>> +  +---+---+---+---+
>> +
>> +  **Normal Mode MSR Settings**
>> +
>> +  +---+---+---+---+
>> +  | S | HV| PR|Privilege  |
>> +  +===+===+===+===+
>> +  | 0 | 0 | 1 | Problem   |
>> +  +---+---+---+---+
>> +  | 0 | 0 | 0 | Privileged(OS)|
>> +  +---+---+---+---+
>> +  | 0 | 1 | 0 | Hypervisor|
>> +  +---+---+---+---+
>> +  | 0 | 1 | 1 | Problem (HV)  |
>> +  +---+---+---+---+
> I find the use of '(HV)' in this last line a bit ambiguous. Since we are
> already using 'HV' to refer to MSR(HV). I'd suggest using '(Host)' or
> simply leaving it out.
>
>> +
>> +* Memory is partitioned into secure and normal memory. Only processes
>> +  that are running in secure mode can access secure memory.
>> +
>> +* The hardware does not allow anything that is not running secure to
>> +  access secure memory. This means that the Hypervisor cannot access
>> +  the memory of the SVM without using an ultracall (asking the
>> +  Ultravisor). The Ultravisor will only allow the hypervisor to see
>> +  the SVM memory encrypted.
>> +
>> +* I/O systems are not allowed to directly address secure memory. This
>> +  limits the SVMs to virtual I/O only.
>> +
>> +* The architecture allows the SVM to share pages of memory with the
>> +  hypervisor that are not protected with encryption. However, this
>> +  sharing must be initiated by the SVM.
>> +
>> +* When a process is running in secure mode all hypercalls
>> +  (syscall lev=1) are reflected to the Ultravisor.
> Here 'reflected' refers to the Ultravisor. Later on, it is used as
> meaning the Ultravisor reflects hypercalls/interrupts to the
> Hypervisor. I suggest we use this term to mean the latter only.
>
>> +
>> +* When a process is in secure mode all interrupts go to the
>> +  Ultravisor.
>> +
>> +* The following resources have become Ultravisor privileged and
>> +  require an Ultravisor interface to manipulate:
>> +
>> +  * Processor configurations registers (SCOMs).
>> +
>> +  * Stop state information.
>> +
>> +  * The debug registers CIABR, DAWR, and DAWRX become Ultravisor
>> +resources when SMFCTRL(D) is set. If SMFCTRL(D) is not set they do
> It looks like you could go without "become Ultravisor resources" since
> it is already mentioned in the parent item above (The following...).
>
>> +not work in secure mode. When set, reading and writing requires
>> +an Ultravisor call, otherwise that will cause a Hypervisor Emulation
>> +Assistance interrupt.
>> +
>> +  * PTCR and partition table entries (partition table is in secure
>> +memory). An attempt to write to PTCR will cause a Hypervisor
>> +Emulation Assitance interrupt.
>> +
>> +  * LDBAR (LD Base Address Register) and IMC (In-Memory Collection)
>> +non-architected registers. An attempt to write to them will cause a
>> +Hypervisor Emulation Assistance interrupt.
>> +
>> +  * Paging for an SVM, sharing of memory with Hypervisor for an SVM.
>> +(Including Virtual Processor Area (VPA) and virtual I/O).
>> +
>> +
>> +Software/Microcode
>> +==
>> +
>> +The software changes include:
>> +
>> +* SVMs are created from normal VM using (open source) tooling supplied
>> +  by IBM.
>> +
>> +* All SVMs start as normal VMs and utilize an ultracall, UV_ESM
>> +   

[PATCH v5 7/7] powerpc/kvm: Use UV_RETURN ucall to return to ultravisor

2019-08-07 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

When an SVM makes an hypercall or incurs some other exception, the
Ultravisor usually forwards (a.k.a. reflects) the exceptions to the
Hypervisor. After processing the exception, Hypervisor uses the
UV_RETURN ultracall to return control back to the SVM.

The expected register state on entry to this ultracall is:

* Non-volatile registers are restored to their original values.
* If returning from an hypercall, register R0 contains the return value
  (unlike other ultracalls) and, registers R4 through R12 contain any
  output values of the hypercall.
* R3 contains the ultracall number, i.e UV_RETURN.
* If returning with a synthesized interrupt, R2 contains the
  synthesized interrupt number.

Thanks to input from Paul Mackerras, Ram Pai and Mike Anderson.

Signed-off-by: Sukadev Bhattiprolu 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/kvm_host.h   |  1 +
 arch/powerpc/include/asm/ultravisor-api.h |  1 +
 arch/powerpc/kernel/asm-offsets.c |  1 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 39 +++
 4 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 013c76a0a03e..184becb62ea4 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -294,6 +294,7 @@ struct kvm_arch {
cpumask_t cpu_in_guest;
u8 radix;
u8 fwnmi_enabled;
+   u8 secure_guest;
bool threads_indep;
bool nested_enable;
pgd_t *pgtable;
diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 8cd49abff4f3..6a0f9c74f959 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -24,5 +24,6 @@
 
 /* opcodes */
 #define UV_WRITE_PATE  0xF104
+#define UV_RETURN  0xF11C
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 524a7bba0ee5..aadc6176824b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -510,6 +510,7 @@ int main(void)
OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
OFFSET(KVM_RADIX, kvm, arch.radix);
OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
+   OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index bc18366cd1ba..0a5b2a8236c7 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Sign-extend HDEC if not on POWER9 */
 #define EXTEND_HDEC(reg)   \
@@ -1090,16 +1091,10 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
ld  r5, VCPU_LR(r4)
-   ld  r6, VCPU_CR(r4)
mtlrr5
-   mtcrr6
 
ld  r1, VCPU_GPR(R1)(r4)
-   ld  r2, VCPU_GPR(R2)(r4)
-   ld  r3, VCPU_GPR(R3)(r4)
ld  r5, VCPU_GPR(R5)(r4)
-   ld  r6, VCPU_GPR(R6)(r4)
-   ld  r7, VCPU_GPR(R7)(r4)
ld  r8, VCPU_GPR(R8)(r4)
ld  r9, VCPU_GPR(R9)(r4)
ld  r10, VCPU_GPR(R10)(r4)
@@ -1117,10 +1112,42 @@ BEGIN_FTR_SECTION
mtspr   SPRN_HDSISR, r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 
+   ld  r6, VCPU_KVM(r4)
+   lbz r7, KVM_SECURE_GUEST(r6)
+   cmpdi   r7, 0
+   ld  r6, VCPU_GPR(R6)(r4)
+   ld  r7, VCPU_GPR(R7)(r4)
+   bne ret_to_ultra
+
+   lwz r0, VCPU_CR(r4)
+   mtcrr0
+
ld  r0, VCPU_GPR(R0)(r4)
+   ld  r2, VCPU_GPR(R2)(r4)
+   ld  r3, VCPU_GPR(R3)(r4)
ld  r4, VCPU_GPR(R4)(r4)
HRFI_TO_GUEST
b   .
+/*
+ * Use UV_RETURN ultracall to return control back to the Ultravisor after
+ * processing an hypercall or interrupt that was forwarded (a.k.a. reflected)
+ * to the Hypervisor.
+ *
+ * All registers have already been loaded, except:
+ *   R0 = hcall result
+ *   R2 = SRR1, so UV can detect a synthesized interrupt (if any)
+ *   R3 = UV_RETURN
+ */
+ret_to_ultra:
+   lwz r0, VCPU_CR(r4)
+   mtcrr0
+
+   ld  r0, VCPU_GPR(R3)(r4)
+   mfspr   r2, SPRN_SRR1
+   li  r3, 0
+   ori r3, r3, UV_RETURN
+   ld  r4, VCPU_GPR(R4)(r4)
+   sc  2
 
 /*
  * Enter the guest on a P9 or later system where we have exactly
-- 
2.20.1



[PATCH v5 6/7] powerpc/powernv: Access LDBAR only if ultravisor disabled

2019-08-07 Thread Claudio Carvalho
LDBAR is a per-thread SPR populated and used by the thread-imc pmu
driver to dump the data counter into memory. It contains memory along
with few other configuration bits. LDBAR is populated and enabled only
when any of the thread imc pmu events are monitored.

In ultravisor enabled systems, LDBAR becomes ultravisor privileged and
an attempt to write to it will cause a Hypervisor Emulation Assistance
interrupt.

In ultravisor enabled systems, the ultravisor is responsible to maintain
the LDBAR (e.g. save and restore it).

This restricts LDBAR access to only when ultravisor is disabled.

Signed-off-by: Claudio Carvalho 
Reviewed-by: Ram Pai 
Reviewed-by: Ryan Grimm 
---
 arch/powerpc/platforms/powernv/idle.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 210fb73a5121..14018463a8f0 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -679,7 +679,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
sprs.ptcr   = mfspr(SPRN_PTCR);
sprs.rpr= mfspr(SPRN_RPR);
sprs.tscr   = mfspr(SPRN_TSCR);
-   sprs.ldbar  = mfspr(SPRN_LDBAR);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   sprs.ldbar = mfspr(SPRN_LDBAR);
 
sprs_saved = true;
 
@@ -793,7 +794,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
mtspr(SPRN_MMCR0,   sprs.mmcr0);
mtspr(SPRN_MMCR1,   sprs.mmcr1);
mtspr(SPRN_MMCR2,   sprs.mmcr2);
-   mtspr(SPRN_LDBAR,   sprs.ldbar);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_LDBAR, sprs.ldbar);
 
mtspr(SPRN_SPRG3,   local_paca->sprg_vdso);
 
-- 
2.20.1



[PATCH v5 5/7] powerpc/mm: Write to PTCR only if ultravisor disabled

2019-08-07 Thread Claudio Carvalho
In ultravisor enabled systems, PTCR becomes ultravisor privileged only
for writing and an attempt to write to it will cause a Hypervisor
Emulation Assitance interrupt.

This patch adds the try_set_ptcr(val) macro as an accessor to
mtspr(SPRN_PTCR, val), which will be executed only if ultravisor
disabled.

Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/reg.h   | 13 +
 arch/powerpc/mm/book3s64/hash_utils.c|  4 ++--
 arch/powerpc/mm/book3s64/pgtable.c   |  2 +-
 arch/powerpc/mm/book3s64/radix_pgtable.c |  6 +++---
 4 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 10caa145f98b..14139b1ebdb8 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Pickup Book E specific registers. */
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
@@ -1452,6 +1453,18 @@ static inline void update_power8_hid0(unsigned long hid0)
 */
asm volatile("sync; mtspr %0,%1; isync":: "i"(SPRN_HID0), "r"(hid0));
 }
+
+/*
+ * In ultravisor enabled systems, PTCR becomes ultravisor privileged only for
+ * writing and an attempt to write to it will cause a Hypervisor Emulation
+ * Assistance interrupt.
+ */
+#define try_set_ptcr(val)  \
+   do {\
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))   \
+   mtspr(SPRN_PTCR, val);  \
+   } while (0)
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_REG_H */
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c 
b/arch/powerpc/mm/book3s64/hash_utils.c
index 25a2cf32d544..048b7f58deae 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1079,8 +1079,8 @@ void hash__early_init_mmu_secondary(void)
if (!cpu_has_feature(CPU_FTR_ARCH_300))
mtspr(SPRN_SDR1, _SDR1);
else
-   mtspr(SPRN_PTCR,
- __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+   try_set_ptcr(__pa(partition_tb) |
+(PATB_SIZE_SHIFT - 12));
}
/* Initialize SLB */
slb_initialize();
diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 033731f5dbaa..016c6ccb5b81 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -219,7 +219,7 @@ void __init mmu_partition_table_init(void)
 * 64 K size.
 */
ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
-   mtspr(SPRN_PTCR, ptcr);
+   try_set_ptcr(ptcr);
powernv_set_nmmu_ptcr(ptcr);
 }
 
diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
b/arch/powerpc/mm/book3s64/radix_pgtable.c
index e92c6472a20c..246b32550eab 100644
--- a/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -654,8 +654,8 @@ void radix__early_init_mmu_secondary(void)
lpcr = mfspr(SPRN_LPCR);
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
 
-   mtspr(SPRN_PTCR,
- __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+   try_set_ptcr(__pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+
radix_init_amor();
}
 
@@ -671,7 +671,7 @@ void radix__mmu_cleanup_all(void)
if (!firmware_has_feature(FW_FEATURE_LPAR)) {
lpcr = mfspr(SPRN_LPCR);
mtspr(SPRN_LPCR, lpcr & ~LPCR_UPRT);
-   mtspr(SPRN_PTCR, 0);
+   try_set_ptcr(0);
powernv_set_nmmu_ptcr(0);
radix__flush_tlb_all();
}
-- 
2.20.1



[PATCH v5 4/7] powerpc/mm: Use UV_WRITE_PATE ucall to register a PATE

2019-08-07 Thread Claudio Carvalho
From: Michael Anderson 

In ultravisor enabled systems, the ultravisor creates and maintains the
partition table in secure memory where the hypervisor cannot access, and
therefore, the hypervisor have to do the UV_WRITE_PATE ucall whenever it
wants to set a partition table entry (PATE).

This patch adds the UV_WRITE_PATE ucall and uses it to set a PATE if
ultravisor is enabled. Additionally, this also also keeps a copy of the
partition table because the nestMMU does not have access to secure
memory. Such copy has entries for nonsecure and hypervisor partition.

Signed-off-by: Michael Anderson 
Signed-off-by: Madhavan Srinivasan 
Signed-off-by: Ram Pai 
[ cclaudio: Write the PATE in HV's table before doing that in UV's ]
Signed-off-by: Claudio Carvalho 
Reviewed-by: Ryan Grimm 
---
 arch/powerpc/include/asm/ultravisor-api.h |  5 ++
 arch/powerpc/include/asm/ultravisor.h |  8 +++
 arch/powerpc/mm/book3s64/pgtable.c| 60 ---
 3 files changed, 56 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 88ffa78f9d61..8cd49abff4f3 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -11,6 +11,7 @@
 #include 
 
 /* Return codes */
+#define U_BUSY H_BUSY
 #define U_FUNCTION H_FUNCTION
 #define U_NOT_AVAILABLEH_NOT_AVAILABLE
 #define U_P2   H_P2
@@ -18,6 +19,10 @@
 #define U_P4   H_P4
 #define U_P5   H_P5
 #define U_PARAMETERH_PARAMETER
+#define U_PERMISSION   H_PERMISSION
 #define U_SUCCESS  H_SUCCESS
 
+/* opcodes */
+#define UV_WRITE_PATE  0xF104
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index dc6e1ea198f2..6fe1f365dec8 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -8,7 +8,15 @@
 #ifndef _ASM_POWERPC_ULTRAVISOR_H
 #define _ASM_POWERPC_ULTRAVISOR_H
 
+#include 
+#include 
+
 int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
  int depth, void *data);
 
+static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
+{
+   return ucall_norets(UV_WRITE_PATE, lpid, dw0, dw1);
+}
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 85bc81abd286..033731f5dbaa 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -198,7 +200,15 @@ void __init mmu_partition_table_init(void)
unsigned long ptcr;
 
BUILD_BUG_ON_MSG((PATB_SIZE_SHIFT > 36), "Partition table size too 
large.");
-   /* Initialize the Partition Table with no entries */
+   /*
+* Initialize the Partition Table with no entries, even in the presence
+* of an ultravisor firmware.
+*
+* In ultravisor enabled systems, the ultravisor creates and maintains
+* the partition table in secure memory. However, we keep a copy of the
+* partition table because nestMMU cannot access secure memory. Our copy
+* contains entries for nonsecure and hypervisor partition.
+*/
partition_tb = memblock_alloc(patb_size, patb_size);
if (!partition_tb)
panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
@@ -213,34 +223,50 @@ void __init mmu_partition_table_init(void)
powernv_set_nmmu_ptcr(ptcr);
 }
 
-void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-  unsigned long dw1)
+/*
+ * Global flush of TLBs and partition table caches for this lpid. The type of
+ * flush (hash or radix) depends on what the previous use of this partition ID
+ * was, not the new use.
+ */
+static void flush_partition(unsigned int lpid, unsigned long old_patb0)
 {
-   unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
-
-   partition_tb[lpid].patb0 = cpu_to_be64(dw0);
-   partition_tb[lpid].patb1 = cpu_to_be64(dw1);
-
-   /*
-* Global flush of TLBs and partition table caches for this lpid.
-* The type of flush (hash or radix) depends on what the previous
-* use of this partition ID was, not the new use.
-*/
asm volatile("ptesync" : : : "memory");
-   if (old & PATB_HR) {
-   asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
+   if (old_patb0 & PATB_HR) {
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 1) : :
 "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
+   asm vo

[PATCH v5 3/7] powerpc/powernv: Introduce FW_FEATURE_ULTRAVISOR

2019-08-07 Thread Claudio Carvalho
In PEF enabled systems, some of the resources which were previously
hypervisor privileged are now ultravisor privileged and controlled by
the ultravisor firmware.

This adds FW_FEATURE_ULTRAVISOR to indicate if PEF is enabled.

The host kernel can use FW_FEATURE_ULTRAVISOR, for instance, to skip
accessing resources (e.g. PTCR and LDBAR) in case PEF is enabled.

Signed-off-by: Claudio Carvalho 
[ andmike: Device node name to "ibm,ultravisor" ]
Signed-off-by: Michael Anderson 
---
 arch/powerpc/include/asm/firmware.h |  5 +++--
 arch/powerpc/include/asm/ultravisor.h   | 14 
 arch/powerpc/kernel/prom.c  |  4 
 arch/powerpc/platforms/powernv/Makefile |  1 +
 arch/powerpc/platforms/powernv/ultravisor.c | 24 +
 5 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/platforms/powernv/ultravisor.c

diff --git a/arch/powerpc/include/asm/firmware.h 
b/arch/powerpc/include/asm/firmware.h
index 00bc42d95679..43b48c4d3ca9 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -54,6 +54,7 @@
 #define FW_FEATURE_DRC_INFOASM_CONST(0x0008)
 #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0010)
 #define FW_FEATURE_PAPR_SCMASM_CONST(0x0020)
+#define FW_FEATURE_ULTRAVISOR  ASM_CONST(0x0040)
 
 #ifndef __ASSEMBLY__
 
@@ -72,9 +73,9 @@ enum {
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE |
-   FW_FEATURE_PAPR_SCM,
+   FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_PSERIES_ALWAYS = 0,
-   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
+   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_POWERNV_ALWAYS = 0,
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
new file mode 100644
index ..dc6e1ea198f2
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor definitions
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_H
+#define _ASM_POWERPC_ULTRAVISOR_H
+
+int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+ int depth, void *data);
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4221527b082f..67a2c1b39252 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -706,6 +707,9 @@ void __init early_init_devtree(void *params)
 #ifdef CONFIG_PPC_POWERNV
/* Some machines might need OPAL info for debugging, grab it now. */
of_scan_flat_dt(early_init_dt_scan_opal, NULL);
+
+   /* Scan tree for ultravisor feature */
+   of_scan_flat_dt(early_init_dt_scan_ultravisor, NULL);
 #endif
 
 #ifdef CONFIG_FA_DUMP
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index da2e99efbd04..2c27c8ac00c8 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -4,6 +4,7 @@ obj-y   += idle.o opal-rtc.o opal-nvram.o 
opal-lpc.o opal-flash.o
 obj-y  += rng.o opal-elog.o opal-dump.o opal-sysparam.o 
opal-sensor.o
 obj-y  += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
 obj-y  += opal-kmsg.o opal-powercap.o opal-psr.o 
opal-sensor-groups.o
+obj-y  += ultravisor.o
 
 obj-$(CONFIG_SMP)  += smp.o subcore.o subcore-asm.o
 obj-$(CONFIG_PCI)  += pci.o pci-ioda.o npu-dma.o pci-ioda-tce.o
diff --git a/arch/powerpc/platforms/powernv/ultravisor.c 
b/arch/powerpc/platforms/powernv/ultravisor.c
new file mode 100644
index ..02ac57b4bded
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/ultravisor.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ultravisor high level interfaces
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data)
+{
+   if (!of_flat_dt_is_compatible(node, "ibm,ultravisor"))
+   return 0;
+
+   powerpc_firmware_features |= FW_FEATURE_ULTRAVISOR;
+   pr_debug("Ultravisor detected!\n");
+   return 1;
+}
-- 
2.20.1



[PATCH v5 2/7] powerpc/kernel: Add ucall_norets() ultravisor call handler

2019-08-07 Thread Claudio Carvalho
The ultracalls (ucalls for short) allow the Secure Virtual Machines
(SVM)s and hypervisor to request services from the ultravisor such as
accessing a register or memory region that can only be accessed when
running in ultravisor-privileged mode.

This patch adds the ucall_norets() ultravisor call handler. Like
plpar_hcall_norets(), it also saves and restores the Condition
Register (CR).

The specific service needed from an ucall is specified in register
R3 (the first parameter to the ucall). Other parameters to the
ucall, if any, are specified in registers R4 through R12.

Return value of all ucalls is in register R3. Other output values
from the ucall, if any, are returned in registers R4 through R12.

Each ucall returns specific error codes, applicable in the context
of the ucall. However, like with the PowerPC Architecture Platform
Reference (PAPR), if no specific error code is defined for a particular
situation, then the ucall will fallback to an erroneous
parameter-position based code. i.e U_PARAMETER, U_P2, U_P3 etc depending
on the ucall parameter that may have caused the error.

Every host kernel (powernv) needs to be able to do ucalls in case it
ends up being run in a machine with ultravisor enabled. Otherwise, the
kernel may crash early in boot trying to access ultravisor resources,
for instance, trying to set the partition table entry 0. Secure guests
also need to be able to do ucalls and its kernel may not have
CONFIG_PPC_POWERNV=y. For that reason, the ucall.S file is placed under
arch/powerpc/kernel.

If ultravisor is not enabled, the ucalls will be redirected to the
hypervisor which must handle/fail the call.

Thanks to inputs from Ram Pai and Michael Anderson.

Signed-off-by: Claudio Carvalho 

---
Ultravisor call support for secure guests is being proposed as part of
the patchset "Secure Virtual Machine Enablement" posted by Thiago
Bauermann.
---
 arch/powerpc/include/asm/asm-prototypes.h | 11 +++
 arch/powerpc/include/asm/ultravisor-api.h | 23 +++
 arch/powerpc/kernel/Makefile  |  1 +
 arch/powerpc/kernel/ucall.S   | 20 
 4 files changed, 55 insertions(+)
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/kernel/ucall.S

diff --git a/arch/powerpc/include/asm/asm-prototypes.h 
b/arch/powerpc/include/asm/asm-prototypes.h
index 296584e6dd55..ee2e67d5a005 100644
--- a/arch/powerpc/include/asm/asm-prototypes.h
+++ b/arch/powerpc/include/asm/asm-prototypes.h
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -38,6 +39,16 @@ extern struct static_key hcall_tracepoint_key;
 void __trace_hcall_entry(unsigned long opcode, unsigned long *args);
 void __trace_hcall_exit(long opcode, long retval, unsigned long *retbuf);
 
+/* Ultravisor */
+#ifdef CONFIG_PPC_POWERNV
+long ucall_norets(unsigned long opcode, ...);
+#else
+static inline long ucall_norets(unsigned long opcode, ...)
+{
+   return U_NOT_AVAILABLE;
+}
+#endif
+
 /* OPAL */
 int64_t __opal_call(int64_t a0, int64_t a1, int64_t a2, int64_t a3,
int64_t a4, int64_t a5, int64_t a6, int64_t a7,
diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
new file mode 100644
index ..88ffa78f9d61
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor API.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_API_H
+#define _ASM_POWERPC_ULTRAVISOR_API_H
+
+#include 
+
+/* Return codes */
+#define U_FUNCTION H_FUNCTION
+#define U_NOT_AVAILABLEH_NOT_AVAILABLE
+#define U_P2   H_P2
+#define U_P3   H_P3
+#define U_P4   H_P4
+#define U_P5   H_P5
+#define U_PARAMETERH_PARAMETER
+#define U_SUCCESS  H_SUCCESS
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 56dfa7a2a6f2..35379b632f3c 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -155,6 +155,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
+obj-$(CONFIG_PPC_POWERNV)  += ucall.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/ucall.S b/arch/powerpc/kernel/ucall.S
new file mode 100644
index ..de9133e45d21
--- /dev/null
+++ b/arch/powerpc/kernel/ucall.S
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Generic code to perform an ultravisor call.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+#include 
+
+_GLOBAL(ucall_norets)
+EXPORT_SYMBOL_GPL(ucall_norets)
+   mfcrr0
+   stw r0,8(r1)
+
+   sc  2  

[PATCH v5 1/7] Documentation/powerpc: Ultravisor API

2019-08-07 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

POWER9 processor includes support for Protected Execution Facility (PEF).
Attached documentation provides an overview of PEF and defines the API
for various interfaces that must be implemented in the Ultravisor
firmware as well as in the KVM Hypervisor.

Based on input from Mike Anderson, Thiago Bauermann, Claudio Carvalho,
Ben Herrenschmidt, Guerney Hunt, Paul Mackerras.

Signed-off-by: Sukadev Bhattiprolu 
Signed-off-by: Ram Pai 
Signed-off-by: Guerney Hunt 
Reviewed-by: Claudio Carvalho 
Reviewed-by: Michael Anderson 
Reviewed-by: Thiago Bauermann 
Signed-off-by: Claudio Carvalho 
---
 Documentation/powerpc/ultravisor.rst | 1055 ++
 1 file changed, 1055 insertions(+)
 create mode 100644 Documentation/powerpc/ultravisor.rst

diff --git a/Documentation/powerpc/ultravisor.rst 
b/Documentation/powerpc/ultravisor.rst
new file mode 100644
index ..8d5246585b66
--- /dev/null
+++ b/Documentation/powerpc/ultravisor.rst
@@ -0,0 +1,1055 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. _ultravisor:
+
+
+Protected Execution Facility
+
+
+.. contents::
+:depth: 3
+
+.. sectnum::
+:depth: 3
+
+Protected Execution Facility
+
+
+Protected Execution Facility (PEF) is an architectural change for
+POWER 9 that enables Secure Virtual Machines (SVMs). When enabled,
+PEF adds a new higher privileged mode, called Ultravisor mode, to
+POWER architecture. Along with the new mode there is new firmware
+called the Protected Execution Ultravisor (or Ultravisor for short).
+Ultravisor mode is the highest privileged mode in POWER architecture.
+
+   +--+
+   | Privilege States |
+   +==+
+   |  Problem |
+   +--+
+   |  Supervisor  |
+   +--+
+   |  Hypervisor  |
+   +--+
+   |  Ultravisor  |
+   +--+
+
+PEF protects SVMs from the hypervisor, privileged users, and other
+VMs in the system. SVMs are protected while at rest and can only be
+executed by an authorized machine. All virtual machines utilize
+hypervisor services. The Ultravisor filters calls between the SVMs
+and the hypervisor to assure that information does not accidentally
+leak. All hypercalls except H_RANDOM are reflected to the hypervisor.
+H_RANDOM is not reflected to prevent the hypervisor from influencing
+random values in the SVM.
+
+To support this there is a refactoring of the ownership of resources
+in the CPU. Some of the resources which were previously hypervisor
+privileged are now ultravisor privileged.
+
+Hardware
+
+
+The hardware changes include the following:
+
+* There is a new bit in the MSR that determines whether the current
+  process is running in secure mode, MSR(S) bit 41. MSR(S)=1, process
+  is in secure mode, MSR(s)=0 process is in normal mode.
+
+* The MSR(S) bit can only be set by the Ultravisor.
+
+* HRFID cannot be used to set the MSR(S) bit. If the hypervisor needs
+  to return to a SVM it must use an ultracall. It can determine if
+  the VM it is returning to is secure.
+
+* There is a new Ultravisor privileged register, SMFCTRL, which has an
+  enable/disable bit SMFCTRL(E).
+
+* The privilege of a process is now determined by three MSR bits,
+  MSR(S, HV, PR). In each of the tables below the modes are listed
+  from least privilege to highest privilege. The higher privilege
+  modes can access all the resources of the lower privilege modes.
+
+  **Secure Mode MSR Settings**
+
+  +---+---+---+---+
+  | S | HV| PR|Privilege  |
+  +===+===+===+===+
+  | 1 | 0 | 1 | Problem   |
+  +---+---+---+---+
+  | 1 | 0 | 0 | Privileged(OS)|
+  +---+---+---+---+
+  | 1 | 1 | 0 | Ultravisor|
+  +---+---+---+---+
+  | 1 | 1 | 1 | Reserved  |
+  +---+---+---+---+
+
+  **Normal Mode MSR Settings**
+
+  +---+---+---+---+
+  | S | HV| PR|Privilege  |
+  +===+===+===+===+
+  | 0 | 0 | 1 | Problem   |
+  +---+---+---+---+
+  | 0 | 0 | 0 | Privileged(OS)|
+  +---+---+---+---+
+  | 0 | 1 | 0 | Hypervisor|
+  +---+---+---+---+
+  | 0 | 1 | 1 | Problem (HV)  |
+  +---+---+---+---+
+
+* Memory is partitioned into secure and normal memory. Only processes
+  that are running in secure mode can access secure memory.
+
+* The hardware does not allow anything that is not running secure to
+  access secure memory. This means that the Hypervisor cannot access
+  the memory of the SVM without using an ultracall (asking the
+  Ultravisor

[PATCH v5 0/7] kvmppc: Paravirtualize KVM to support ultravisor

2019-08-07 Thread Claudio Carvalho
k3S HV: Fixed for running secure guests"
- Renamed patch from/to:
  - "KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
  - "KVM: PPC: Ultravisor: Enter a secure guest
- Rebased
- Addressed comments from Paul Mackerras
  - Dropped ultravisor checks made in power8 code
  - Updated the commit message for:
   "KVM: PPC: Ultravisor: Enter a secure guest"
- Addressed comments from Maddy
  - Dropped imc-pmu.c changes
- Changed opal-imc.c to fail the probe when the ultravisor is enabled
- Fixed "ucall defined but not used" issue when CONFIG_PPC_UV not set 

Claudio Carvalho (4):
  powerpc/kernel: Add ucall_norets() ultravisor call handler
  powerpc/powernv: Introduce FW_FEATURE_ULTRAVISOR
  powerpc/mm: Write to PTCR only if ultravisor disabled
  powerpc/powernv: Access LDBAR only if ultravisor disabled

Michael Anderson (1):
  powerpc/mm: Use UV_WRITE_PATE ucall to register a PATE

Sukadev Bhattiprolu (2):
  Documentation/powerpc: Ultravisor API
  powerpc/kvm: Use UV_RETURN ucall to return to ultravisor

 Documentation/powerpc/ultravisor.rst| 1055 +++
 arch/powerpc/include/asm/asm-prototypes.h   |   11 +
 arch/powerpc/include/asm/firmware.h |5 +-
 arch/powerpc/include/asm/kvm_host.h |1 +
 arch/powerpc/include/asm/reg.h  |   13 +
 arch/powerpc/include/asm/ultravisor-api.h   |   29 +
 arch/powerpc/include/asm/ultravisor.h   |   22 +
 arch/powerpc/kernel/Makefile|1 +
 arch/powerpc/kernel/asm-offsets.c   |1 +
 arch/powerpc/kernel/prom.c  |4 +
 arch/powerpc/kernel/ucall.S |   20 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S |   39 +-
 arch/powerpc/mm/book3s64/hash_utils.c   |4 +-
 arch/powerpc/mm/book3s64/pgtable.c  |   62 +-
 arch/powerpc/mm/book3s64/radix_pgtable.c|6 +-
 arch/powerpc/platforms/powernv/Makefile |1 +
 arch/powerpc/platforms/powernv/idle.c   |6 +-
 arch/powerpc/platforms/powernv/ultravisor.c |   24 +
 18 files changed, 1271 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/powerpc/ultravisor.rst
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/kernel/ucall.S
 create mode 100644 arch/powerpc/platforms/powernv/ultravisor.c

-- 
2.20.1



Re: [PATCH v4 4/8] KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE

2019-07-18 Thread Claudio Carvalho


On 7/11/19 9:57 AM, Michael Ellerman wrote:
>
>>  
>>  static pmd_t *get_pmd_from_cache(struct mm_struct *mm)
>> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c 
>> b/arch/powerpc/mm/book3s64/radix_pgtable.c
>> index 8904aa1243d8..da6a6b76a040 100644
>> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
>> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
>> @@ -656,8 +656,10 @@ void radix__early_init_mmu_secondary(void)
>>  lpcr = mfspr(SPRN_LPCR);
>>  mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
>>  
>> -mtspr(SPRN_PTCR,
>> -  __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
>> +if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> +mtspr(SPRN_PTCR, __pa(partition_tb) |
>> +  (PATB_SIZE_SHIFT - 12));
>> +
>>  radix_init_amor();
>>  }
>>  
>> @@ -673,7 +675,8 @@ void radix__mmu_cleanup_all(void)
>>  if (!firmware_has_feature(FW_FEATURE_LPAR)) {
>>  lpcr = mfspr(SPRN_LPCR);
>>  mtspr(SPRN_LPCR, lpcr & ~LPCR_UPRT);
>> -mtspr(SPRN_PTCR, 0);
>> +if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> +mtspr(SPRN_PTCR, 0);
>>  powernv_set_nmmu_ptcr(0);
>>  radix__flush_tlb_all();
>>  }
> There's four of these case where we skip touching the PTCR, which is
> right on the borderline of warranting an accessor. I guess we can do it
> as a cleanup later.

I agree.

Since the kernel doesn't need to access a big number of ultravisor
privileged registers, maybe we can define mtspr_ and mfspr_
inline functions that in ultravisor.h that skip touching the register if an
ultravisor is present and and the register is ultravisor privileged. Thus,
we don't need to replicate comments and that also would make it easier for
developers to know what are the ultravisor privileged registers.

Something like this:

--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -10,10 +10,21 @@
 
 #include 
 #include 
+#include 
 
 int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
  int depth, void *data);
 
+static inline void mtspr_ptcr(unsigned long val)
+{
+   /*
+    * If the ultravisor firmware is present, it maintains the partition
+    * table. PTCR becomes ultravisor privileged only for writing.
+    */
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_PTCR, val);
+}
+
 static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
 {
    return ucall_norets(UV_WRITE_PATE, lpid, dw0, dw1);
diff --git a/arch/powerpc/mm/book3s64/pgtable.c
b/arch/powerpc/mm/book3s64/pgtable.c
index e1bbc48e730f..25156f9dfde8 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -220,7 +220,7 @@ void __init mmu_partition_table_init(void)
 * 64 K size.
 */
    ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
-   mtspr(SPRN_PTCR, ptcr);
+   mtspr_ptcr(ptcr);
    powernv_set_nmmu_ptcr(ptcr);
 }

What do you think?
An alternative could be to change the mtspr() and mfspr() macros as we
proposed in the v1, but access to non-ultravisor privileged registers would
be performance impacted because we always would need to check if the
register is one of the few ultravisor registers that the kernel needs to
access.

Thanks,
Claudio


> cheers
>



Re: [PATCH v4 6/8] KVM: PPC: Ultravisor: Restrict LDBAR access

2019-07-14 Thread Claudio Carvalho


On 7/11/19 9:57 AM, Michael Ellerman wrote:
> Claudio Carvalho  writes:
>> When the ultravisor firmware is available, it takes control over the
>> LDBAR register. In this case, thread-imc updates and save/restore
>> operations on the LDBAR register are handled by ultravisor.
> Please roll up the replies to Alexey's question about LDBAR into the
> change log.
>
>> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
>> b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> index f9b2620fbecd..cffb365d9d02 100644
>> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> @@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
>>  mtspr   SPRN_RPR, r0
>>  ld  r0, KVM_SPLIT_PMMAR(r6)
>>  mtspr   SPRN_PMMAR, r0
>> +BEGIN_FW_FTR_SECTION_NESTED(70)
>>  ld  r0, KVM_SPLIT_LDBAR(r6)
>>  mtspr   SPRN_LDBAR, r0
>> +END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
> That's in Power8 code isn't it? Which will never have an ultravisor.

IIUC, it might be executed in Power9 as well, but I can double check that.


>
>> diff --git a/arch/powerpc/platforms/powernv/opal-imc.c 
>> b/arch/powerpc/platforms/powernv/opal-imc.c
>> index 1b6932890a73..5fe2d4526cbc 100644
>> --- a/arch/powerpc/platforms/powernv/opal-imc.c
>> +++ b/arch/powerpc/platforms/powernv/opal-imc.c
>> @@ -254,6 +254,10 @@ static int opal_imc_counters_probe(struct 
>> platform_device *pdev)
>>  bool core_imc_reg = false, thread_imc_reg = false;
>>  u32 type;
>>  
>> +/* Disable IMC devices, when Ultravisor is enabled. */
>> +if (firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> +return -EACCES;
> I don't mind taking this change. But at the same time should the IMC
> stuff just be omitted from the device tree when we're in ultravisor mode?

Yes. Maddy said that he will patch skiboot to remove the IMC nodes if
ultravisor is present.

I added this check just to protect the kernel in case skiboot is not in the
right level for some
reason.

Thanks,
Claudio



>
> cheers
>



Re: [PATCH v4 6/8] KVM: PPC: Ultravisor: Restrict LDBAR access

2019-07-13 Thread Claudio Carvalho


On 7/1/19 3:46 AM, Ram Pai wrote:
> On Mon, Jul 01, 2019 at 04:30:55PM +1000, Alexey Kardashevskiy wrote:
>>
>> On 01/07/2019 16:17, maddy wrote:
>>> On 01/07/19 11:24 AM, Alexey Kardashevskiy wrote:
>>>> On 29/06/2019 06:08, Claudio Carvalho wrote:
>>>>> When the ultravisor firmware is available, it takes control over the
>>>>> LDBAR register. In this case, thread-imc updates and save/restore
>>>>> operations on the LDBAR register are handled by ultravisor.
>>>> What does LDBAR do? "Power ISA™ Version 3.0 B" or "User’s Manual POWER9
>>>> Processor" do not tell.
>>> LDBAR is a per-thread SPR used by thread-imc pmu to dump the counter
>>> data into memory.
>>> LDBAR contains memory address along with few other configuration bits
>>> (it is populated
>>> by the thread-imc pmu driver). It is populated and enabled only when any
>>> of the thread
>>> imc pmu events are monitored.
>>
>> I was actually looking for a spec for this register, what is the
>> document name?
>   Its not a architected register. Its documented in the Power9
>   workbook.

I also found some information about the LDBAR in
arch/powerpc/perf/imc-pmu.c

Claudio


>
> RP
>


Re: [PATCH v4 3/8] KVM: PPC: Ultravisor: Add generic ultravisor call handler

2019-07-13 Thread Claudio Carvalho


On 7/11/19 9:57 AM, Michael Ellerman wrote:
> Claudio Carvalho  writes:
>> From: Ram Pai 
>>
>> Add the ucall() function, which can be used to make ultravisor calls
>> with varied number of in and out arguments. Ultravisor calls can be made
>> from the host or guests.
>>
>> This copies the implementation of plpar_hcall().
> .. with quite a few changes?
>
> This is one of the things I'd like to see in a Documentation file, so
> that people can review the implementation vs the specification.

I will document this (and other things) in a file under Documentation/powerpc.


>
>> Signed-off-by: Ram Pai 
>> [ Change ucall.S to not save CR, rename and move headers, build ucall.S
>>   if CONFIG_PPC_POWERNV set, use R3 for the ucall number and add some
>>   comments in the code ]
> Why are we not saving CR? See previous comment about Documentation :)
>
>> Signed-off-by: Claudio Carvalho 
>> ---
>>  arch/powerpc/include/asm/ultravisor-api.h | 20 +++
>>  arch/powerpc/include/asm/ultravisor.h | 20 +++
>>  arch/powerpc/kernel/Makefile  |  2 +-
>>  arch/powerpc/kernel/ucall.S   | 30 +++
>>  arch/powerpc/kernel/ultravisor.c  |  4 +++
>>  5 files changed, 75 insertions(+), 1 deletion(-)
>>  create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
>>  create mode 100644 arch/powerpc/kernel/ucall.S
>>
>> diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
>> b/arch/powerpc/include/asm/ultravisor-api.h
>> new file mode 100644
>> index ..49e766adabc7
>> --- /dev/null
>> +++ b/arch/powerpc/include/asm/ultravisor-api.h
>> @@ -0,0 +1,20 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Ultravisor API.
>> + *
>> + * Copyright 2019, IBM Corporation.
>> + *
>> + */
>> +#ifndef _ASM_POWERPC_ULTRAVISOR_API_H
>> +#define _ASM_POWERPC_ULTRAVISOR_API_H
>> +
>> +#include 
>> +
>> +/* Return codes */
>> +#define U_NOT_AVAILABLE H_NOT_AVAILABLE
>> +#define U_SUCCESS   H_SUCCESS
>> +#define U_FUNCTION  H_FUNCTION
>> +#define U_PARAMETER H_PARAMETER
> Is there any benefit in redefining these?
>
>> diff --git a/arch/powerpc/include/asm/ultravisor.h 
>> b/arch/powerpc/include/asm/ultravisor.h
>> index e5009b0d84ea..a78a2dacfd0b 100644
>> --- a/arch/powerpc/include/asm/ultravisor.h
>> +++ b/arch/powerpc/include/asm/ultravisor.h
>> @@ -8,8 +8,28 @@
>>  #ifndef _ASM_POWERPC_ULTRAVISOR_H
>>  #define _ASM_POWERPC_ULTRAVISOR_H
>>  
>> +#include 
>> +
>> +#if !defined(__ASSEMBLY__)
> Just #ifndef is fine.
>
>>  /* Internal functions */
> How is it internal?
>
>>  extern int early_init_dt_scan_ultravisor(unsigned long node, const char 
>> *uname,
>>   int depth, void *data);
>>  
>> +/* API functions */
>> +#define UCALL_BUFSIZE 4
> Please don't copy this design from the hcall code, it has led to bugs in
> the past.
>
> See my (still unmerged) attempt to fix this for the hcall case:
>   https://patchwork.ozlabs.org/patch/683577/
>
> Basically instead of asking callers nicely to define a certain sized
> buffer, and them forgetting, define a proper type that has the right size.

I will keep that in mind. For now I think we don't need that since the v5
will have ucall_norets() instead.


>
>> +/**
>> + * ucall: Make a powerpc ultravisor call.
>> + * @opcode: The ultravisor call to make.
>> + * @retbuf: Buffer to store up to 4 return arguments in.
>> + *
>> + * This call supports up to 6 arguments and 4 return arguments. Use
>> + * UCALL_BUFSIZE to size the return argument buffer.
>> + */
>> +#if defined(CONFIG_PPC_POWERNV)
> #ifdef
>
>> +long ucall(unsigned long opcode, unsigned long *retbuf, ...);
>> +#endif
>> +
>> +#endif /* !__ASSEMBLY__ */
>> +
>>  #endif  /* _ASM_POWERPC_ULTRAVISOR_H */
>> diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
>> index f0caa302c8c0..f28baccc0a79 100644
>> --- a/arch/powerpc/kernel/Makefile
>> +++ b/arch/powerpc/kernel/Makefile
>> @@ -154,7 +154,7 @@ endif
>>  
>>  obj-$(CONFIG_EPAPR_PARAVIRT)+= epapr_paravirt.o epapr_hcalls.o
>>  obj-$(CONFIG_KVM_GUEST) += kvm.o kvm_emul.o
>> -obj-$(CONFIG_PPC_POWERNV)   += ultravisor.o
>> +obj-$(CONFIG_PPC_POWERNV)   += ultravisor.o ucall.o
> Same comment about being platforms/powernv ?
>> diff --git a/arch/powerpc/kernel/ucall.S b/arch/po

Re: [PATCH v4 2/8] powerpc: Introduce FW_FEATURE_ULTRAVISOR

2019-07-13 Thread Claudio Carvalho

On 7/11/19 9:57 AM, Michael Ellerman wrote:
> Claudio Carvalho  writes:
>> diff --git a/arch/powerpc/include/asm/ultravisor.h 
>> b/arch/powerpc/include/asm/ultravisor.h
>> new file mode 100644
>> index ..e5009b0d84ea
>> --- /dev/null
>> +++ b/arch/powerpc/include/asm/ultravisor.h
>> @@ -0,0 +1,15 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Ultravisor definitions
>> + *
>> + * Copyright 2019, IBM Corporation.
>> + *
>> + */
>> +#ifndef _ASM_POWERPC_ULTRAVISOR_H
>> +#define _ASM_POWERPC_ULTRAVISOR_H
>> +
>> +/* Internal functions */
>> +extern int early_init_dt_scan_ultravisor(unsigned long node, const char 
>> *uname,
>> + int depth, void *data);
> Please don't use extern in new headers.
>
>> diff --git a/arch/powerpc/kernel/ultravisor.c 
>> b/arch/powerpc/kernel/ultravisor.c
>> new file mode 100644
>> index ..dc6021f63c97
>> --- /dev/null
>> +++ b/arch/powerpc/kernel/ultravisor.c
> Is there a reason this (and other later files) aren't in platforms/powernv ?

Yes, there is.
https://www.spinics.net/lists/kvm-ppc/msg14998.html

We also need to do ucalls from a secure guest and its kernel may not have 
CONFIG_PPC_POWERNV=y. I can make it clear in the commit message.


>
>> @@ -0,0 +1,24 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Ultravisor high level interfaces
>> + *
>> + * Copyright 2019, IBM Corporation.
>> + *
>> + */
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#include 
>> +#include 
>> +
>> +int __init early_init_dt_scan_ultravisor(unsigned long node, const char 
>> *uname,
>> + int depth, void *data)
>> +{
>> +if (depth != 1 || strcmp(uname, "ibm,ultravisor") != 0)
>> +return 0;
> I know you're following the example of OPAL, but this is not the best
> way to search for the ultravisor node.
>
> It makes the location and name of the node part of the ABI, when there's
> no need for it to be.
>
> If instead you just scan the tree for a node that is *compatible* with
> "ibm,ultravisor" (or whatever compatible string) then the node can be
> placed any where in the tree and have any name, which gives us the most
> flexibility in future to change the location of the device tree node.

I will do that in the next version.

Thanks,
Claudio


>
> cheers
>


Re: [PATCH v4 1/8] KVM: PPC: Ultravisor: Introduce the MSR_S bit

2019-07-12 Thread Claudio Carvalho


On 7/11/19 9:57 PM, Nicholas Piggin wrote:
> Claudio Carvalho's on June 29, 2019 6:08 am:
>> From: Sukadev Bhattiprolu 
>>
>> The ultravisor processor mode is introduced in POWER platforms that
>> supports the Protected Execution Facility (PEF). Ultravisor is higher
>> privileged than hypervisor mode.
>>
>> In PEF enabled platforms, the MSR_S bit is used to indicate if the
>> thread is in secure state. With the MSR_S bit, the privilege state of
>> the thread is now determined by MSR_S, MSR_HV and MSR_PR, as follows:
>>
>> S   HV  PR
>> ---
>> 0   x   1   problem
>> 1   0   1   problem
>> x   x   0   privileged
>> x   1   0   hypervisor
>> 1   1   0   ultravisor
>> 1   1   1   reserved
> What does this table mean? I thought 'x' meant either


Yes, it means either. The table was arranged that way to say that:
- hypervisor state is also a privileged state,
- ultravisor state is also a hypervisor state.


> , but in that
> case there are several states that can apply to the same
> combination of bits.
>
> Would it be clearer to rearrange the table so the columns are the HV
> and PR bits we know and love, plus the effect of S=1 on each of them?
>
>   HV  PR  S=0 S=1
>   -
>   0   0   privileged  privileged (secure guest kernel)
>   0   1   problem problem (secure guest userspace)
>   1   0   hypervisor  ultravisor
>   1   1   problem reserved
>
> Is that accurate?

Yes, it is. I also like this format. I will consider it.


>
>
>> The hypervisor doesn't (and can't) run with the MSR_S bit set, but a
>> secure guest and the ultravisor firmware do.
>>
>> Signed-off-by: Sukadev Bhattiprolu 
>> Signed-off-by: Ram Pai 
>> [ Update the commit message ]
>> Signed-off-by: Claudio Carvalho 
>> ---
>>  arch/powerpc/include/asm/reg.h | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
>> index 10caa145f98b..39b4c0a519f5 100644
>> --- a/arch/powerpc/include/asm/reg.h
>> +++ b/arch/powerpc/include/asm/reg.h
>> @@ -38,6 +38,7 @@
>>  #define MSR_TM_LG   32  /* Trans Mem Available */
>>  #define MSR_VEC_LG  25  /* Enable AltiVec */
>>  #define MSR_VSX_LG  23  /* Enable VSX */
>> +#define MSR_S_LG22  /* Secure VM bit */
>>  #define MSR_POW_LG  18  /* Enable Power Management */
>>  #define MSR_WE_LG   18  /* Wait State Enable */
>>  #define MSR_TGPR_LG 17  /* TLB Update registers in use */
>> @@ -71,11 +72,13 @@
>>  #define MSR_SF  __MASK(MSR_SF_LG)   /* Enable 64 bit mode */
>>  #define MSR_ISF __MASK(MSR_ISF_LG)  /* Interrupt 64b mode 
>> valid on 630 */
>>  #define MSR_HV  __MASK(MSR_HV_LG)   /* Hypervisor state */
>> +#define MSR_S   __MASK(MSR_S_LG)/* Secure state */
> This is a real nitpick, but why two different comments for the bit 
> number and the mask?

Fixed for the next version. Both comments will be /* Secure state */

Thanks
Claudio




Re: [PATCH v4 7/8] KVM: PPC: Ultravisor: Enter a secure guest

2019-07-08 Thread Claudio Carvalho


On 7/8/19 5:53 PM, janani wrote:
> On 2019-06-28 15:08, Claudio Carvalho wrote:
>> From: Sukadev Bhattiprolu 
>>
>> To enter a secure guest, we have to go through the ultravisor, therefore
>> we do a ucall when we are entering a secure guest.
>>
>> This change is needed for any sort of entry to the secure guest from the
>> hypervisor, whether it is a return from an hcall, a return from a
>> hypervisor interrupt, or the first time that a secure guest vCPU is run.
>>
>> If we are returning from an hcall, the results are already in the
>> appropriate registers R3:12, except for R3, R6 and R7. R3 has the status
>> of the reflected hcall, therefore we move it to R0 for the ultravisor and
>> set R3 to the UV_RETURN ucall number. R6,7 were used as temporary
>> registers, hence we restore them.
>>
>> Have fast_guest_return check the kvm_arch.secure_guest field so that a
>> new CPU enters UV when started (in response to a RTAS start-cpu call).
>>
>> Thanks to input from Paul Mackerras, Ram Pai and Mike Anderson.
>>
>> Signed-off-by: Sukadev Bhattiprolu 
>> [ Pass SRR1 in r11 for UV_RETURN, fix kvmppc_msr_interrupt to preserve
>>   the MSR_S bit ]
>> Signed-off-by: Paul Mackerras 
>> [ Fix UV_RETURN ucall number and arch.secure_guest check ]
>> Signed-off-by: Ram Pai 
>> [ Save the actual R3 in R0 for the ultravisor and use R3 for the
>>   UV_RETURN ucall number. Update commit message and ret_to_ultra comment ]
>> Signed-off-by: Claudio Carvalho 
>  Reviewed-by: Janani Janakiraman 


Thanks Janani for reviewing the patchset.

Claudio


>> ---
>>  arch/powerpc/include/asm/kvm_host.h   |  1 +
>>  arch/powerpc/include/asm/ultravisor-api.h |  1 +
>>  arch/powerpc/kernel/asm-offsets.c |  1 +
>>  arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 40 +++
>>  4 files changed, 37 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/kvm_host.h
>> b/arch/powerpc/include/asm/kvm_host.h
>> index 013c76a0a03e..184becb62ea4 100644
>> --- a/arch/powerpc/include/asm/kvm_host.h
>> +++ b/arch/powerpc/include/asm/kvm_host.h
>> @@ -294,6 +294,7 @@ struct kvm_arch {
>>  cpumask_t cpu_in_guest;
>>  u8 radix;
>>  u8 fwnmi_enabled;
>> +    u8 secure_guest;
>>  bool threads_indep;
>>  bool nested_enable;
>>  pgd_t *pgtable;
>> diff --git a/arch/powerpc/include/asm/ultravisor-api.h
>> b/arch/powerpc/include/asm/ultravisor-api.h
>> index 141940771add..7c4d0b4ced12 100644
>> --- a/arch/powerpc/include/asm/ultravisor-api.h
>> +++ b/arch/powerpc/include/asm/ultravisor-api.h
>> @@ -19,5 +19,6 @@
>>
>>  /* opcodes */
>>  #define UV_WRITE_PATE    0xF104
>> +#define UV_RETURN    0xF11C
>>
>>  #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
>> diff --git a/arch/powerpc/kernel/asm-offsets.c
>> b/arch/powerpc/kernel/asm-offsets.c
>> index 8e02444e9d3d..44742724513e 100644
>> --- a/arch/powerpc/kernel/asm-offsets.c
>> +++ b/arch/powerpc/kernel/asm-offsets.c
>> @@ -508,6 +508,7 @@ int main(void)
>>  OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
>>  OFFSET(KVM_RADIX, kvm, arch.radix);
>>  OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
>> +    OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
>>  OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
>>  OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
>>  OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
>> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> index cffb365d9d02..89813ca987c2 100644
>> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> @@ -36,6 +36,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  /* Sign-extend HDEC if not on POWER9 */
>>  #define EXTEND_HDEC(reg)    \
>> @@ -1092,16 +1093,12 @@ BEGIN_FTR_SECTION
>>  END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
>>
>>  ld    r5, VCPU_LR(r4)
>> -    ld    r6, VCPU_CR(r4)
>>  mtlr    r5
>> -    mtcr    r6
>>
>>  ld    r1, VCPU_GPR(R1)(r4)
>>  ld    r2, VCPU_GPR(R2)(r4)
>>  ld    r3, VCPU_GPR(R3)(r4)
>>  ld    r5, VCPU_GPR(R5)(r4)
>> -    ld    r6, VCPU_GPR(R6)(r4)
>> -    ld    r7, VCPU_GPR(R7)(r4)
>>  ld    r8, VCPU_GPR(R8)(r4)
>>  ld    r9, VCPU_GPR(R9)(r4)
>>  ld    r10, VCPU_GPR(R10)(r4)
>> @@ -1119,10 +1116,38 @@ BEGIN_FTR_SECTION
>>  mtspr    SPRN_HDSISR, r0
&

[RFC PATCH] powerpc/powernv: Add ultravisor message log interface

2019-07-08 Thread Claudio Carvalho
From: Madhavan Srinivasan 

Ultravisor provides an in-memory circular buffer containing a message
log populated with various runtime message produced by firmware.

Based on "powernv/opal-msglog.c", this patch provides a sysfs interface
/sys/firmware/opal/uv_msglog for userspace to view the messages.

CC: Joel Stanley 
CC: Oliver O'Halloran 
Signed-off-by: Madhavan Srinivasan 
[ Read ibm,opal-uv-memcons instead of OPAL's ]
Signed-off-by: Ryan Grimm 
[ Fix license, update the commit message ]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/opal.h   |   2 +
 arch/powerpc/platforms/powernv/Makefile   |   1 +
 .../platforms/powernv/opal-uv-msglog.c| 141 ++
 arch/powerpc/platforms/powernv/opal.c |   2 +
 4 files changed, 146 insertions(+)
 create mode 100644 arch/powerpc/platforms/powernv/opal-uv-msglog.c

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 4cc37e708bc7..86299c5d866b 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -351,6 +351,8 @@ extern void opal_platform_dump_init(void);
 extern void opal_sys_param_init(void);
 extern void opal_msglog_init(void);
 extern void opal_msglog_sysfs_init(void);
+extern void opal_uv_msglog_init(void);
+extern void opal_uv_msglog_sysfs_init(void);
 extern int opal_async_comp_init(void);
 extern int opal_sensor_init(void);
 extern int opal_hmi_handler_init(void);
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index da2e99efbd04..216629c63e1d 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -4,6 +4,7 @@ obj-y   += idle.o opal-rtc.o opal-nvram.o 
opal-lpc.o opal-flash.o
 obj-y  += rng.o opal-elog.o opal-dump.o opal-sysparam.o 
opal-sensor.o
 obj-y  += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o
 obj-y  += opal-kmsg.o opal-powercap.o opal-psr.o 
opal-sensor-groups.o
+obj-y  += opal-uv-msglog.o
 
 obj-$(CONFIG_SMP)  += smp.o subcore.o subcore-asm.o
 obj-$(CONFIG_PCI)  += pci.o pci-ioda.o npu-dma.o pci-ioda-tce.o
diff --git a/arch/powerpc/platforms/powernv/opal-uv-msglog.c 
b/arch/powerpc/platforms/powernv/opal-uv-msglog.c
new file mode 100644
index ..87d665d7e6ad
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-uv-msglog.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PowerNV OPAL in-memory ultravisor console interface
+ *
+ * Copyright 2018 IBM Corp.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* OPAL in-memory console. Defined in OPAL source at core/console.c */
+struct memcons {
+   __be64 magic;
+#define MEMCONS_MAGIC  0x6630696567726173L
+   __be64 obuf_phys;
+   __be64 ibuf_phys;
+   __be32 obuf_size;
+   __be32 ibuf_size;
+   __be32 out_pos;
+#define MEMCONS_OUT_POS_WRAP   0x8000u
+#define MEMCONS_OUT_POS_MASK   0x00ffu
+   __be32 in_prod;
+   __be32 in_cons;
+};
+
+static struct memcons *opal_uv_memcons;
+
+ssize_t opal_uv_msglog_copy(char *to, loff_t pos, size_t count)
+{
+   const char *conbuf;
+   ssize_t ret;
+   size_t first_read = 0;
+   uint32_t out_pos, avail;
+
+   if (!opal_uv_memcons)
+   return -ENODEV;
+
+   out_pos = be32_to_cpu(READ_ONCE(opal_uv_memcons->out_pos));
+
+   /*
+* Now we've read out_pos, put a barrier in before reading the new data
+* it points to in conbuf.
+*/
+   smp_rmb();
+
+   conbuf = phys_to_virt(be64_to_cpu(opal_uv_memcons->obuf_phys));
+
+   /*
+* When the buffer has wrapped, read from the out_pos marker to the end
+* of the buffer, and then read the remaining data as in the un-wrapped
+* case.
+*/
+   if (out_pos & MEMCONS_OUT_POS_WRAP) {
+
+   out_pos &= MEMCONS_OUT_POS_MASK;
+   avail = be32_to_cpu(opal_uv_memcons->obuf_size) - out_pos;
+
+   ret = memory_read_from_buffer(to, count, ,
+   conbuf + out_pos, avail);
+
+   if (ret < 0)
+   goto out;
+
+   first_read = ret;
+   to += first_read;
+   count -= first_read;
+   pos -= avail;
+
+   if (count <= 0)
+   goto out;
+   }
+
+   /* Sanity check. The firmware should not do this to us. */
+   if (out_pos > be32_to_cpu(opal_uv_memcons->obuf_size)) {
+   pr_err("OPAL: memory console corruption. Aborting read.\n");
+   return -EINVAL;
+   }
+
+   ret = memory_read_from_buffer(to, count, , conbuf, out_pos);
+
+   if (ret < 0)
+   goto out;
+
+   ret += first_read;
+out:
+   return ret;
+}
+
+static ssize_t opal_uv

Re: [PATCH v4 5/8] KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache

2019-07-08 Thread Claudio Carvalho


On 7/1/19 2:54 AM, Alexey Kardashevskiy wrote:
>
> On 29/06/2019 06:08, Claudio Carvalho wrote:
>> From: Ram Pai 
>>
>> Ultravisor is responsible for flushing the tlb cache, since it manages
>> the PATE entries. Hence skip tlb flush, if the ultravisor firmware is
>> available.
>>
>> Signed-off-by: Ram Pai 
>> Signed-off-by: Claudio Carvalho 
>> ---
>>  arch/powerpc/mm/book3s64/pgtable.c | 33 +-
>>  1 file changed, 19 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
>> b/arch/powerpc/mm/book3s64/pgtable.c
>> index 224c5c7c2e3d..bc8eb2bf9810 100644
>> --- a/arch/powerpc/mm/book3s64/pgtable.c
>> +++ b/arch/powerpc/mm/book3s64/pgtable.c
>> @@ -224,6 +224,23 @@ void __init mmu_partition_table_init(void)
>>  powernv_set_nmmu_ptcr(ptcr);
>>  }
>>  
>> +static void flush_partition(unsigned int lpid, unsigned long dw0)
>> +{
>> +if (dw0 & PATB_HR) {
>> +asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 1) : :
>> + "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>> +asm volatile(PPC_TLBIE_5(%0, %1, 2, 1, 1) : :
>> + "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>> +trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
>> +} else {
>> +asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 0) : :
>> + "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>> +trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
>> +}
>> +/* do we need fixup here ?*/
>> +asm volatile("eieio; tlbsync; ptesync" : : : "memory");
>> +}
>> +
>>  static void __mmu_partition_table_set_entry(unsigned int lpid,
>>  unsigned long dw0,
>>  unsigned long dw1)
>> @@ -238,20 +255,8 @@ static void __mmu_partition_table_set_entry(unsigned 
>> int lpid,
>>   * The type of flush (hash or radix) depends on what the previous
>>   * use of this partition ID was, not the new use.
>>   */
>> -asm volatile("ptesync" : : : "memory");
>> -if (old & PATB_HR) {
>> -asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
>> - "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>> -asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
>> - "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>> -trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
>> -} else {
>> -asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
>> - "r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
>> -trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
>> -}
>> -/* do we need fixup here ?*/
>> -asm volatile("eieio; tlbsync; ptesync" : : : "memory");
>> +if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>
> __mmu_partition_table_set_entry() checks for UV and
> mmu_partition_table_set_entry() (the caller) checks for UV and the whole
> point of having separate flush_partition() and
> __mmu_partition_table_set_entry() is not really clear.
>
>
> 4/8 and 5/8 make more sense as one patch imho.


Makes sense. I merged them in the next version. Thanks.

Claudio


>
>
>> +flush_partition(lpid, old);
>>  }
>>  
>>  void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
>>



Re: [PATCH v3 3/9] powerpc: Introduce FW_FEATURE_ULTRAVISOR

2019-07-01 Thread Claudio Carvalho


On 6/15/19 4:36 AM, Paul Mackerras wrote:
> On Thu, Jun 06, 2019 at 02:36:08PM -0300, Claudio Carvalho wrote:
>> This feature tells if the ultravisor firmware is available to handle
>> ucalls.
> Everything in this patch that depends on CONFIG_PPC_UV should just
> depend on CONFIG_PPC_POWERNV instead.  The reason is that every host
> kernel needs to be able to do the ultracall to set partition table
> entry 0, in case it ends up being run on a machine with an ultravisor.
> Otherwise we will have the situation where a host kernel may crash
> early in boot just because the machine it's booted on happens to have
> an ultravisor running.  The crash will be a particularly nasty one
> because it will happen before we have probed the machine type and
> initialized the console; therefore it will just look like the machine
> hangs for no discernable reason.

> We also need to think about how to provide a way for petitboot to know
> whether the kernel it is booting knows how to do a ucall to set its
> partition table entry.  One suggestion would be to modify
> vmlinux.lds.S to add a new PT_NOTE entry in the program header of the
> binary with (say) a 64-bit doubleword which is a bitmap indicating
> capabilities of the binary.  We would define the first bit as
> indicating that the kernel knows how to run under an ultravisor.
> When running under an ultravisor, petitboot could then look for the
> PT_NOTE and the ultravisor-capable bit in it, and if the PT_NOTE is
> not there or the bit is zero, put up a dialog warning the user that
> the kernel will probably crash early in boot, and asking for explicit
> confirmation that the user wants to proceed.


I just posted a separated RFC patch for the ELF note.

Thanks, Claudio.


>
> Paul.
>


[RFC PATCH] powerpc: Add the ppc_capabilities ELF note

2019-07-01 Thread Claudio Carvalho
Add the ppc_capabilities ELF note to the powerpc kernel binary. It is a
bitmap that can be used to advertise kernel capabilities to userland.

This patch also defines PPCCAP_ULTRAVISOR_BIT as being the bit zero.

Suggested-by: Paul Mackerras 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/kernel/Makefile |  2 +-
 arch/powerpc/kernel/note.S   | 36 
 2 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/kernel/note.S

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 0ea6c4aa3a20..4ec36fe4325b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -49,7 +49,7 @@ obj-y := cputable.o ptrace.o 
syscalls.o \
   signal.o sysfs.o cacheinfo.o time.o \
   prom.o traps.o setup-common.o \
   udbg.o misc.o io.o misc_$(BITS).o \
-  of_platform.o prom_parse.o
+  of_platform.o prom_parse.o note.o
 obj-$(CONFIG_PPC64)+= setup_64.o sys_ppc32.o \
   signal_64.o ptrace32.o \
   paca.o nvram_64.o firmware.o
diff --git a/arch/powerpc/kernel/note.S b/arch/powerpc/kernel/note.S
new file mode 100644
index ..721bf8ce9eb7
--- /dev/null
+++ b/arch/powerpc/kernel/note.S
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PowerPC ELF notes.
+ *
+ * Copyright 2019, IBM Corporation
+ */
+#include 
+
+/*
+ * Ultravisor-capable bit (PowerNV only).
+ *
+ * Indicate that the powerpc kernel binary knows how to run in an
+ * ultravisor-enabled system.
+ *
+ * In an ultravisor-enabled system, some machine resources are now controlled
+ * by the ultravisor. If the kernel is not ultravisor-capable, but it ends up
+ * being run on a machine with ultravisor, the kernel will probably crash
+ * trying to access ultravisor resources. For instance, it may crash in early
+ * boot trying to set the partition table entry 0.
+ *
+ * In an ultravisor-enabled system, petitboot can warn the user or prevent the
+ * kernel from being run if the ppc_capabilities doesn't exist or the
+ * Ultravisor-capable bit is not set.
+ */
+#if defined(CONFIG_PPC_POWERNV)
+#define PPCCAP_ULTRAVISOR_BIT  (1 << 0)
+#else
+#define PPCCAP_ULTRAVISOR_BIT  0
+#endif
+
+/*
+ * Add the ppc_capabilities ELF note to the powerpc kernel binary. It is a
+ * bitmap that can be used to advertise kernel capabilities to userland.
+ */
+ELFNOTE(ppc_capabilities, 3,
+   .long PPCCAP_ULTRAVISOR_BIT)
-- 
2.20.1



[PATCH v4 7/8] KVM: PPC: Ultravisor: Enter a secure guest

2019-06-28 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

To enter a secure guest, we have to go through the ultravisor, therefore
we do a ucall when we are entering a secure guest.

This change is needed for any sort of entry to the secure guest from the
hypervisor, whether it is a return from an hcall, a return from a
hypervisor interrupt, or the first time that a secure guest vCPU is run.

If we are returning from an hcall, the results are already in the
appropriate registers R3:12, except for R3, R6 and R7. R3 has the status
of the reflected hcall, therefore we move it to R0 for the ultravisor and
set R3 to the UV_RETURN ucall number. R6,7 were used as temporary
registers, hence we restore them.

Have fast_guest_return check the kvm_arch.secure_guest field so that a
new CPU enters UV when started (in response to a RTAS start-cpu call).

Thanks to input from Paul Mackerras, Ram Pai and Mike Anderson.

Signed-off-by: Sukadev Bhattiprolu 
[ Pass SRR1 in r11 for UV_RETURN, fix kvmppc_msr_interrupt to preserve
  the MSR_S bit ]
Signed-off-by: Paul Mackerras 
[ Fix UV_RETURN ucall number and arch.secure_guest check ]
Signed-off-by: Ram Pai 
[ Save the actual R3 in R0 for the ultravisor and use R3 for the
  UV_RETURN ucall number. Update commit message and ret_to_ultra comment ]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/kvm_host.h   |  1 +
 arch/powerpc/include/asm/ultravisor-api.h |  1 +
 arch/powerpc/kernel/asm-offsets.c |  1 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 40 +++
 4 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 013c76a0a03e..184becb62ea4 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -294,6 +294,7 @@ struct kvm_arch {
cpumask_t cpu_in_guest;
u8 radix;
u8 fwnmi_enabled;
+   u8 secure_guest;
bool threads_indep;
bool nested_enable;
pgd_t *pgtable;
diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 141940771add..7c4d0b4ced12 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -19,5 +19,6 @@
 
 /* opcodes */
 #define UV_WRITE_PATE  0xF104
+#define UV_RETURN  0xF11C
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 8e02444e9d3d..44742724513e 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -508,6 +508,7 @@ int main(void)
OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
OFFSET(KVM_RADIX, kvm, arch.radix);
OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
+   OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index cffb365d9d02..89813ca987c2 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Sign-extend HDEC if not on POWER9 */
 #define EXTEND_HDEC(reg)   \
@@ -1092,16 +1093,12 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
ld  r5, VCPU_LR(r4)
-   ld  r6, VCPU_CR(r4)
mtlrr5
-   mtcrr6
 
ld  r1, VCPU_GPR(R1)(r4)
ld  r2, VCPU_GPR(R2)(r4)
ld  r3, VCPU_GPR(R3)(r4)
ld  r5, VCPU_GPR(R5)(r4)
-   ld  r6, VCPU_GPR(R6)(r4)
-   ld  r7, VCPU_GPR(R7)(r4)
ld  r8, VCPU_GPR(R8)(r4)
ld  r9, VCPU_GPR(R9)(r4)
ld  r10, VCPU_GPR(R10)(r4)
@@ -1119,10 +1116,38 @@ BEGIN_FTR_SECTION
mtspr   SPRN_HDSISR, r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 
+   ld  r6, VCPU_KVM(r4)
+   lbz r7, KVM_SECURE_GUEST(r6)
+   cmpdi   r7, 0
+   bne ret_to_ultra
+
+   lwz r6, VCPU_CR(r4)
+   mtcrr6
+
+   ld  r7, VCPU_GPR(R7)(r4)
+   ld  r6, VCPU_GPR(R6)(r4)
ld  r0, VCPU_GPR(R0)(r4)
ld  r4, VCPU_GPR(R4)(r4)
HRFI_TO_GUEST
b   .
+/*
+ * We are entering a secure guest, so we have to invoke the ultravisor to do
+ * that. If we are returning from a hcall, the results are already in the
+ * appropriate registers R3:12, except for R3, R6 and R7. R3 has the status of
+ * the reflected hcall, therefore we move it to R0 for the ultravisor and set
+ * R3 to the UV_RETURN ucall number. R6,7 were used as temporary registers
+ * above, hence we restore them.
+ */
+ret_to_ultra:
+   lwz r6, VCPU_CR(r4)
+   mtcrr6
+   mfspr   r11, SPRN_SRR1
+   mr  r0, r3

[PATCH v4 8/8] KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr

2019-06-28 Thread Claudio Carvalho
From: Michael Anderson 

 - Check for MSR_S so that kvmppc_set_msr will include it. Prior to this
   change return to guest would not have the S bit set.

 - Patch based on comment from Paul Mackerras 

Signed-off-by: Michael Anderson 
Signed-off-by: Claudio Carvalho 
Acked-by: Paul Mackerras 
---
 arch/powerpc/kvm/book3s_64_mmu_hv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c 
b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index ab3d484c5e2e..ab62a66f9b4e 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -295,6 +295,7 @@ static void kvmppc_mmu_book3s_64_hv_reset_msr(struct 
kvm_vcpu *vcpu)
msr |= MSR_TS_S;
else
msr |= vcpu->arch.shregs.msr & MSR_TS_MASK;
+   msr |= vcpu->arch.shregs.msr & MSR_S;
kvmppc_set_msr(vcpu, msr);
 }
 
-- 
2.20.1



[PATCH v4 6/8] KVM: PPC: Ultravisor: Restrict LDBAR access

2019-06-28 Thread Claudio Carvalho
When the ultravisor firmware is available, it takes control over the
LDBAR register. In this case, thread-imc updates and save/restore
operations on the LDBAR register are handled by ultravisor.

Signed-off-by: Claudio Carvalho 
Reviewed-by: Ram Pai 
Reviewed-by: Ryan Grimm 
Acked-by: Madhavan Srinivasan 
Acked-by: Paul Mackerras 
---
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 2 ++
 arch/powerpc/platforms/powernv/idle.c | 6 --
 arch/powerpc/platforms/powernv/opal-imc.c | 4 
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index f9b2620fbecd..cffb365d9d02 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
mtspr   SPRN_RPR, r0
ld  r0, KVM_SPLIT_PMMAR(r6)
mtspr   SPRN_PMMAR, r0
+BEGIN_FW_FTR_SECTION_NESTED(70)
ld  r0, KVM_SPLIT_LDBAR(r6)
mtspr   SPRN_LDBAR, r0
+END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
isync
 FTR_SECTION_ELSE
/* On P9 we use the split_info for coordinating LPCR changes */
diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index 77f2e0a4ee37..5593a2d55959 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -679,7 +679,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
sprs.ptcr   = mfspr(SPRN_PTCR);
sprs.rpr= mfspr(SPRN_RPR);
sprs.tscr   = mfspr(SPRN_TSCR);
-   sprs.ldbar  = mfspr(SPRN_LDBAR);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   sprs.ldbar  = mfspr(SPRN_LDBAR);
 
sprs_saved = true;
 
@@ -762,7 +763,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
mtspr(SPRN_PTCR,sprs.ptcr);
mtspr(SPRN_RPR, sprs.rpr);
mtspr(SPRN_TSCR,sprs.tscr);
-   mtspr(SPRN_LDBAR,   sprs.ldbar);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_LDBAR,   sprs.ldbar);
 
if (pls >= pnv_first_tb_loss_level) {
/* TB loss */
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c 
b/arch/powerpc/platforms/powernv/opal-imc.c
index 1b6932890a73..5fe2d4526cbc 100644
--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -254,6 +254,10 @@ static int opal_imc_counters_probe(struct platform_device 
*pdev)
bool core_imc_reg = false, thread_imc_reg = false;
u32 type;
 
+   /* Disable IMC devices, when Ultravisor is enabled. */
+   if (firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   return -EACCES;
+
/*
 * Check whether this is kdump kernel. If yes, force the engines to
 * stop and return.
-- 
2.20.1



[PATCH v4 5/8] KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache

2019-06-28 Thread Claudio Carvalho
From: Ram Pai 

Ultravisor is responsible for flushing the tlb cache, since it manages
the PATE entries. Hence skip tlb flush, if the ultravisor firmware is
available.

Signed-off-by: Ram Pai 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/mm/book3s64/pgtable.c | 33 +-
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 224c5c7c2e3d..bc8eb2bf9810 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -224,6 +224,23 @@ void __init mmu_partition_table_init(void)
powernv_set_nmmu_ptcr(ptcr);
 }
 
+static void flush_partition(unsigned int lpid, unsigned long dw0)
+{
+   if (dw0 & PATB_HR) {
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 1) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 1, 1) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
+   } else {
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 0) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
+   }
+   /* do we need fixup here ?*/
+   asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+}
+
 static void __mmu_partition_table_set_entry(unsigned int lpid,
unsigned long dw0,
unsigned long dw1)
@@ -238,20 +255,8 @@ static void __mmu_partition_table_set_entry(unsigned int 
lpid,
 * The type of flush (hash or radix) depends on what the previous
 * use of this partition ID was, not the new use.
 */
-   asm volatile("ptesync" : : : "memory");
-   if (old & PATB_HR) {
-   asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
-   } else {
-   asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
-   }
-   /* do we need fixup here ?*/
-   asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   flush_partition(lpid, old);
 }
 
 void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-- 
2.20.1



[PATCH v4 4/8] KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE

2019-06-28 Thread Claudio Carvalho
From: Michael Anderson 

When running under an ultravisor, the ultravisor controls the real
partition table and has it in secure memory where the hypervisor can't
access it, and therefore we (the HV) have to do a ucall whenever we want
to update an entry.

The HV still keeps a copy of its view of the partition table in normal
memory so that the nest MMU can access it.

Both partition tables will have PATE entries for HV and normal virtual
machines.

Suggested-by: Ryan Grimm 
Signed-off-by: Michael Anderson 
Signed-off-by: Madhavan Srinivasan 
Signed-off-by: Ram Pai 
[ Write the pate in HV's table before doing that in UV's ]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/ultravisor-api.h |  5 +++-
 arch/powerpc/include/asm/ultravisor.h | 14 ++
 arch/powerpc/mm/book3s64/hash_utils.c |  3 +-
 arch/powerpc/mm/book3s64/pgtable.c| 34 +--
 arch/powerpc/mm/book3s64/radix_pgtable.c  |  9 --
 5 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 49e766adabc7..141940771add 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -15,6 +15,9 @@
 #define U_SUCCESS  H_SUCCESS
 #define U_FUNCTION H_FUNCTION
 #define U_PARAMETERH_PARAMETER
+#define U_PERMISSION   H_PERMISSION
 
-#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
+/* opcodes */
+#define UV_WRITE_PATE  0xF104
 
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index a78a2dacfd0b..996c1efd6c6d 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -12,6 +12,8 @@
 
 #if !defined(__ASSEMBLY__)
 
+#include 
+
 /* Internal functions */
 extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data);
@@ -28,8 +30,20 @@ extern int early_init_dt_scan_ultravisor(unsigned long node, 
const char *uname,
  */
 #if defined(CONFIG_PPC_POWERNV)
 long ucall(unsigned long opcode, unsigned long *retbuf, ...);
+#else
+static long ucall(unsigned long opcode, unsigned long *retbuf, ...)
+{
+   return U_NOT_AVAILABLE;
+}
 #endif
 
+static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
+{
+   unsigned long retbuf[UCALL_BUFSIZE];
+
+   return ucall(UV_WRITE_PATE, retbuf, lpid, dw0, dw1);
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c 
b/arch/powerpc/mm/book3s64/hash_utils.c
index 1ff451892d7f..220a4e133240 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1080,9 +1080,10 @@ void hash__early_init_mmu_secondary(void)
 
if (!cpu_has_feature(CPU_FTR_ARCH_300))
mtspr(SPRN_SDR1, _SDR1);
-   else
+   else if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
mtspr(SPRN_PTCR,
  __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+
}
/* Initialize SLB */
slb_initialize();
diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index ad3dd977c22d..224c5c7c2e3d 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -206,12 +208,25 @@ void __init mmu_partition_table_init(void)
 * 64 K size.
 */
ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
-   mtspr(SPRN_PTCR, ptcr);
+   /*
+* If ultravisor is available, it is responsible for creating and
+* managing partition table
+*/
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_PTCR, ptcr);
+
+   /*
+* Since nestMMU cannot access secure memory. Create
+* and manage our own partition table. This table
+* contains entries for nonsecure and hypervisor
+* partition.
+*/
powernv_set_nmmu_ptcr(ptcr);
 }
 
-void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-  unsigned long dw1)
+static void __mmu_partition_table_set_entry(unsigned int lpid,
+   unsigned long dw0,
+   unsigned long dw1)
 {
unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
 
@@ -238,6 +253,19 @@ void mmu_partition_table_set_entry(unsigned int lpid, 
unsigned long dw0,
/* do we need fixup here ?*/
asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
+
+void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
+  

[PATCH v4 3/8] KVM: PPC: Ultravisor: Add generic ultravisor call handler

2019-06-28 Thread Claudio Carvalho
From: Ram Pai 

Add the ucall() function, which can be used to make ultravisor calls
with varied number of in and out arguments. Ultravisor calls can be made
from the host or guests.

This copies the implementation of plpar_hcall().

Signed-off-by: Ram Pai 
[ Change ucall.S to not save CR, rename and move headers, build ucall.S
  if CONFIG_PPC_POWERNV set, use R3 for the ucall number and add some
  comments in the code ]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/ultravisor-api.h | 20 +++
 arch/powerpc/include/asm/ultravisor.h | 20 +++
 arch/powerpc/kernel/Makefile  |  2 +-
 arch/powerpc/kernel/ucall.S   | 30 +++
 arch/powerpc/kernel/ultravisor.c  |  4 +++
 5 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/kernel/ucall.S

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
new file mode 100644
index ..49e766adabc7
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor API.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_API_H
+#define _ASM_POWERPC_ULTRAVISOR_API_H
+
+#include 
+
+/* Return codes */
+#define U_NOT_AVAILABLEH_NOT_AVAILABLE
+#define U_SUCCESS  H_SUCCESS
+#define U_FUNCTION H_FUNCTION
+#define U_PARAMETERH_PARAMETER
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
+
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index e5009b0d84ea..a78a2dacfd0b 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -8,8 +8,28 @@
 #ifndef _ASM_POWERPC_ULTRAVISOR_H
 #define _ASM_POWERPC_ULTRAVISOR_H
 
+#include 
+
+#if !defined(__ASSEMBLY__)
+
 /* Internal functions */
 extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data);
 
+/* API functions */
+#define UCALL_BUFSIZE 4
+/**
+ * ucall: Make a powerpc ultravisor call.
+ * @opcode: The ultravisor call to make.
+ * @retbuf: Buffer to store up to 4 return arguments in.
+ *
+ * This call supports up to 6 arguments and 4 return arguments. Use
+ * UCALL_BUFSIZE to size the return argument buffer.
+ */
+#if defined(CONFIG_PPC_POWERNV)
+long ucall(unsigned long opcode, unsigned long *retbuf, ...);
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index f0caa302c8c0..f28baccc0a79 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -154,7 +154,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
-obj-$(CONFIG_PPC_POWERNV)  += ultravisor.o
+obj-$(CONFIG_PPC_POWERNV)  += ultravisor.o ucall.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/ucall.S b/arch/powerpc/kernel/ucall.S
new file mode 100644
index ..1678f6eb7230
--- /dev/null
+++ b/arch/powerpc/kernel/ucall.S
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Generic code to perform an ultravisor call.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+
+/*
+ * This function is based on the plpar_hcall()
+ */
+_GLOBAL_TOC(ucall)
+   std r4,STK_PARAM(R4)(r1)/* Save ret buffer */
+   mr  r4,r5
+   mr  r5,r6
+   mr  r6,r7
+   mr  r7,r8
+   mr  r8,r9
+   mr  r9,r10
+
+   sc 2/* Invoke the ultravisor */
+
+   ld  r12,STK_PARAM(R4)(r1)
+   std r4,  0(r12)
+   std r5,  8(r12)
+   std r6, 16(r12)
+   std r7, 24(r12)
+
+   blr /* Return r3 = status */
diff --git a/arch/powerpc/kernel/ultravisor.c b/arch/powerpc/kernel/ultravisor.c
index dc6021f63c97..02ddf79a9522 100644
--- a/arch/powerpc/kernel/ultravisor.c
+++ b/arch/powerpc/kernel/ultravisor.c
@@ -8,10 +8,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
+/* in ucall.S */
+EXPORT_SYMBOL_GPL(ucall);
+
 int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data)
 {
-- 
2.20.1



[PATCH v4 1/8] KVM: PPC: Ultravisor: Introduce the MSR_S bit

2019-06-28 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

The ultravisor processor mode is introduced in POWER platforms that
supports the Protected Execution Facility (PEF). Ultravisor is higher
privileged than hypervisor mode.

In PEF enabled platforms, the MSR_S bit is used to indicate if the
thread is in secure state. With the MSR_S bit, the privilege state of
the thread is now determined by MSR_S, MSR_HV and MSR_PR, as follows:

S   HV  PR
---
0   x   1   problem
1   0   1   problem
x   x   0   privileged
x   1   0   hypervisor
1   1   0   ultravisor
1   1   1   reserved

The hypervisor doesn't (and can't) run with the MSR_S bit set, but a
secure guest and the ultravisor firmware do.

Signed-off-by: Sukadev Bhattiprolu 
Signed-off-by: Ram Pai 
[ Update the commit message ]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/reg.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 10caa145f98b..39b4c0a519f5 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -38,6 +38,7 @@
 #define MSR_TM_LG  32  /* Trans Mem Available */
 #define MSR_VEC_LG 25  /* Enable AltiVec */
 #define MSR_VSX_LG 23  /* Enable VSX */
+#define MSR_S_LG   22  /* Secure VM bit */
 #define MSR_POW_LG 18  /* Enable Power Management */
 #define MSR_WE_LG  18  /* Wait State Enable */
 #define MSR_TGPR_LG17  /* TLB Update registers in use */
@@ -71,11 +72,13 @@
 #define MSR_SF __MASK(MSR_SF_LG)   /* Enable 64 bit mode */
 #define MSR_ISF__MASK(MSR_ISF_LG)  /* Interrupt 64b mode 
valid on 630 */
 #define MSR_HV __MASK(MSR_HV_LG)   /* Hypervisor state */
+#define MSR_S  __MASK(MSR_S_LG)/* Secure state */
 #else
 /* so tests for these bits fail on 32-bit */
 #define MSR_SF 0
 #define MSR_ISF0
 #define MSR_HV 0
+#define MSR_S  0
 #endif
 
 /*
-- 
2.20.1



[PATCH v4 0/8] kvmppc: Paravirtualize KVM to support ultravisor

2019-06-28 Thread Claudio Carvalho
POWER platforms that supports the Protected Execution Facility (PEF)
introduce features that combine hardware facilities and firmware to
enable secure virtual machines. That includes a new processor mode
(ultravisor mode) and the ultravisor firmware.

In PEF enabled systems, the ultravisor firmware runs at a privilege
level above the hypervisor and also takes control over some system
resources. The hypervisor, though, can make system calls to access these
resources. Such system calls, a.k.a. ucalls, are handled by the
ultravisor firmware.

The processor allows part of the system memory to be configured as
secure memory, and introduces a a new mode, called secure mode, where
any software entity in that mode can access secure memory. The
hypervisor doesn't (and can't) run in secure mode, but a secure guest
and the ultravisor firmware do.

This patch set adds support for ultravisor calls and do some preparation
for running secure guests.

---
Changelog:
---

v3->v4:

- Patch "KVM: PPC: Ultravisor: Add PPC_UV config option":
  - Moved to the patchset "kvmppc: HMM driver to manage pages of secure
guest" v5 that will be posted by Bharata Rao.

- Patch "powerpc: Introduce FW_FEATURE_ULTRAVISOR":
  - Changed to depend only on CONFIG_PPC_POWERNV.

- Patch "KVM: PPC: Ultravisor: Add generic ultravisor call handler":
  - Fixed whitespaces in ucall.S and in ultravisor-api.h.
  - Changed to depend only on CONFIG_PPC_POWERNV.
  - Changed the ucall wrapper to pass the ucall number in R3.

- Patch "KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a
  PATE:
  - Changed to depend only on CONFIG_PPC_POWERNV.

- Patch "KVM: PPC: Ultravisor: Restrict LDBAR access":
  - Fixed comment in opal-imc.c to be "Disable IMC devices, when
Ultravisor is enabled.
  - Fixed signed-off-by.

- Patch "KVM: PPC: Ultravisor: Enter a secure guest":
  - Changed the UV_RETURN assembly call to save the actual R3 in
R0 for the ultravisor and pass the UV_RETURN call number in R3.

- Patch "KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr":
  - Fixed commit message.

- Rebased to powerpc/next.

v2->v3:

- Squashed patches:
  - "KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
  - "KVM: PPC: Book3S HV: Fixed for running secure guests"
- Renamed patch from/to:
  - "KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
  - "KVM: PPC: Ultravisor: Enter a secure guest
- Rebased
- Addressed comments from Paul Mackerras
  - Dropped ultravisor checks made in power8 code
  - Updated the commit message for:
   "KVM: PPC: Ultravisor: Enter a secure guest"
- Addressed comments from Maddy
  - Dropped imc-pmu.c changes
- Changed opal-imc.c to fail the probe when the ultravisor is enabled
- Fixed "ucall defined but not used" issue when CONFIG_PPC_UV not set 

v1->v2:

- Addressed comments from Paul Mackerras:
  - Write the pate in HV's table before doing that in UV's
  - Renamed and better documented the ultravisor header files. Also added
all possible return codes for each ucall
  - Updated the commit message that introduces the MSR_S bit 
  - Moved ultravisor.c and ucall.S to arch/powerpc/kernel
  - Changed ucall.S to not save CR
- Rebased
- Changed the patches order
- Updated several commit messages
- Added FW_FEATURE_ULTRAVISOR to enable use of firmware_has_feature()
- Renamed CONFIG_PPC_KVM_UV to CONFIG_PPC_UV and used it to ifdef the ucall
  handler and the code that populates the powerpc_firmware_features for 
  ultravisor
- Exported the ucall symbol. KVM may be built as module.
- Restricted LDBAR access if the ultravisor firmware is available
- Dropped patches:
  - "[PATCH 06/13] KVM: PPC: Ultravisor: UV_RESTRICTED_SPR_WRITE ucall"
  - "[PATCH 07/13] KVM: PPC: Ultravisor: UV_RESTRICTED_SPR_READ ucall"
  - "[PATCH 08/13] KVM: PPC: Ultravisor: fix mtspr and mfspr"
- Squashed patches:
  - "[PATCH 09/13] KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
  - "[PATCH 13/13] KVM: PPC: UV: Have fast_guest_return check secure_guest"

Claudio Carvalho (2):
  powerpc: Introduce FW_FEATURE_ULTRAVISOR
  KVM: PPC: Ultravisor: Restrict LDBAR access

Michael Anderson (2):
  KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE
  KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr

Ram Pai (2):
  KVM: PPC: Ultravisor: Add generic ultravisor call handler
  KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache

Sukadev Bhattiprolu (2):
  KVM: PPC: Ultravisor: Introduce the MSR_S bit
  KVM: PPC: Ultravisor: Enter a secure guest

 arch/powerpc/include/asm/firmware.h   |  5 +-
 arch/powerpc/include/asm/kvm_host.h   |  1 +
 arch/powerpc/include/asm/reg.h|  3 ++
 arch/powerpc/include/asm/ultravisor-api.h | 24 +
 arch/powerpc/include/asm/ultravisor.h | 49 +
 arc

[PATCH v4 2/8] powerpc: Introduce FW_FEATURE_ULTRAVISOR

2019-06-28 Thread Claudio Carvalho
This feature tells if the ultravisor firmware is available to handle
ucalls.

Signed-off-by: Claudio Carvalho 
[ Device node name to "ibm,ultravisor" ]
Signed-off-by: Michael Anderson 
---
 arch/powerpc/include/asm/firmware.h   |  5 +++--
 arch/powerpc/include/asm/ultravisor.h | 15 +++
 arch/powerpc/kernel/Makefile  |  1 +
 arch/powerpc/kernel/prom.c|  4 
 arch/powerpc/kernel/ultravisor.c  | 24 
 5 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/kernel/ultravisor.c

diff --git a/arch/powerpc/include/asm/firmware.h 
b/arch/powerpc/include/asm/firmware.h
index 00bc42d95679..43b48c4d3ca9 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -54,6 +54,7 @@
 #define FW_FEATURE_DRC_INFOASM_CONST(0x0008)
 #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0010)
 #define FW_FEATURE_PAPR_SCMASM_CONST(0x0020)
+#define FW_FEATURE_ULTRAVISOR  ASM_CONST(0x0040)
 
 #ifndef __ASSEMBLY__
 
@@ -72,9 +73,9 @@ enum {
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE |
-   FW_FEATURE_PAPR_SCM,
+   FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_PSERIES_ALWAYS = 0,
-   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
+   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_POWERNV_ALWAYS = 0,
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
new file mode 100644
index ..e5009b0d84ea
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor definitions
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_H
+#define _ASM_POWERPC_ULTRAVISOR_H
+
+/* Internal functions */
+extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data);
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 0ea6c4aa3a20..f0caa302c8c0 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -154,6 +154,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
+obj-$(CONFIG_PPC_POWERNV)  += ultravisor.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4221527b082f..67a2c1b39252 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -706,6 +707,9 @@ void __init early_init_devtree(void *params)
 #ifdef CONFIG_PPC_POWERNV
/* Some machines might need OPAL info for debugging, grab it now. */
of_scan_flat_dt(early_init_dt_scan_opal, NULL);
+
+   /* Scan tree for ultravisor feature */
+   of_scan_flat_dt(early_init_dt_scan_ultravisor, NULL);
 #endif
 
 #ifdef CONFIG_FA_DUMP
diff --git a/arch/powerpc/kernel/ultravisor.c b/arch/powerpc/kernel/ultravisor.c
new file mode 100644
index ..dc6021f63c97
--- /dev/null
+++ b/arch/powerpc/kernel/ultravisor.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ultravisor high level interfaces
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data)
+{
+   if (depth != 1 || strcmp(uname, "ibm,ultravisor") != 0)
+   return 0;
+
+   powerpc_firmware_features |= FW_FEATURE_ULTRAVISOR;
+   pr_debug("Ultravisor detected!\n");
+   return 1;
+}
-- 
2.20.1



Re: [PATCH v3 1/9] KVM: PPC: Ultravisor: Add PPC_UV config option

2019-06-10 Thread Claudio Carvalho


On 6/7/19 5:11 PM, Leonardo Bras wrote:
>
> On Thu, 2019-06-06 at 14:36 -0300, Claudio Carvalho wrote:
>> From: Anshuman Khandual 
>>
>> CONFIG_PPC_UV adds support for ultravisor.
>>
>> Signed-off-by: Anshuman Khandual 
>> Signed-off-by: Bharata B Rao 
>> Signed-off-by: Ram Pai 
>> [Update config help and commit message]
>> Signed-off-by: Claudio Carvalho 
>> ---
>>  arch/powerpc/Kconfig | 20 
>>  1 file changed, 20 insertions(+)
>>
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 8c1c636308c8..276c1857c335 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -439,6 +439,26 @@ config PPC_TRANSACTIONAL_MEM
>> ---help---
>>   Support user-mode Transactional Memory on POWERPC.
>>
>> +config PPC_UV
>> +bool "Ultravisor support"
>> +depends on KVM_BOOK3S_HV_POSSIBLE
>> +select HMM_MIRROR
>> +select HMM
>> +select ZONE_DEVICE
>> +select MIGRATE_VMA_HELPER
>> +select DEV_PAGEMAP_OPS
>> +select DEVICE_PRIVATE
>> +select MEMORY_HOTPLUG
>> +select MEMORY_HOTREMOVE
>> +default n
>> +help
>> +  This option paravirtualizes the kernel to run in POWER platforms that
>> +  supports the Protected Execution Facility (PEF). In such platforms,
>> +  the ultravisor firmware runs at a privilege level above the
>> +  hypervisor.
>> +
>> +  If unsure, say "N".
>> +
>>  config LD_HEAD_STUB_CATCH
>>  bool "Reserve 256 bytes to cope with linker stubs in HEAD text" if 
>> EXPERT
>>  depends on PPC64
> Maybe this patch should be the last of the series, as it may cause some
> bisect trouble to have this option enabled while missing some of the
> patches.

Thanks Leonardo. I changed that for the next version.

Claudio




Re: [PATCH v3 7/9] KVM: PPC: Ultravisor: Restrict LDBAR access

2019-06-07 Thread Claudio Carvalho


On 6/7/19 1:48 AM, Madhavan Srinivasan wrote:
>
> On 06/06/19 11:06 PM, Claudio Carvalho wrote:
>> When the ultravisor firmware is available, it takes control over the
>> LDBAR register. In this case, thread-imc updates and save/restore
>> operations on the LDBAR register are handled by ultravisor.
>>
>> Signed-off-by: Claudio Carvalho 
>> Signed-off-by: Ram Pai 
>> ---
>>   arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 2 ++
>>   arch/powerpc/platforms/powernv/idle.c | 6 --
>>   arch/powerpc/platforms/powernv/opal-imc.c | 7 +++
>>   3 files changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> index f9b2620fbecd..cffb365d9d02 100644
>> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> @@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
>>   mtspr    SPRN_RPR, r0
>>   ld    r0, KVM_SPLIT_PMMAR(r6)
>>   mtspr    SPRN_PMMAR, r0
>> +BEGIN_FW_FTR_SECTION_NESTED(70)
>>   ld    r0, KVM_SPLIT_LDBAR(r6)
>>   mtspr    SPRN_LDBAR, r0
>> +END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
>>   isync
>>   FTR_SECTION_ELSE
>>   /* On P9 we use the split_info for coordinating LPCR changes */
>> diff --git a/arch/powerpc/platforms/powernv/idle.c
>> b/arch/powerpc/platforms/powernv/idle.c
>> index c9133f7908ca..fd62435e3267 100644
>> --- a/arch/powerpc/platforms/powernv/idle.c
>> +++ b/arch/powerpc/platforms/powernv/idle.c
>> @@ -679,7 +679,8 @@ static unsigned long power9_idle_stop(unsigned long
>> psscr, bool mmu_on)
>>   sprs.ptcr    = mfspr(SPRN_PTCR);
>>   sprs.rpr    = mfspr(SPRN_RPR);
>>   sprs.tscr    = mfspr(SPRN_TSCR);
>> -    sprs.ldbar    = mfspr(SPRN_LDBAR);
>> +    if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> +    sprs.ldbar    = mfspr(SPRN_LDBAR);
>>
>>   sprs_saved = true;
>>
>> @@ -762,7 +763,8 @@ static unsigned long power9_idle_stop(unsigned long
>> psscr, bool mmu_on)
>>   mtspr(SPRN_PTCR,    sprs.ptcr);
>>   mtspr(SPRN_RPR,    sprs.rpr);
>>   mtspr(SPRN_TSCR,    sprs.tscr);
>> -    mtspr(SPRN_LDBAR,    sprs.ldbar);
>> +    if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> +    mtspr(SPRN_LDBAR,    sprs.ldbar);
>>
>>   if (pls >= pnv_first_tb_loss_level) {
>>   /* TB loss */
>> diff --git a/arch/powerpc/platforms/powernv/opal-imc.c
>> b/arch/powerpc/platforms/powernv/opal-imc.c
>> index 1b6932890a73..e9b641d313fb 100644
>> --- a/arch/powerpc/platforms/powernv/opal-imc.c
>> +++ b/arch/powerpc/platforms/powernv/opal-imc.c
>> @@ -254,6 +254,13 @@ static int opal_imc_counters_probe(struct
>> platform_device *pdev)
>>   bool core_imc_reg = false, thread_imc_reg = false;
>>   u32 type;
>>
>> +    /*
>> + * When the Ultravisor is enabled, it is responsible for thread-imc
>> + * updates
>> + */
>
> Would prefer the comment to be "Disable IMC devices, when Ultravisor is
> enabled"
> Rest looks good.
> Acked-by: Madhavan Srinivasan 


Thanks Maddy. I applied that change to the next version.

Claudio


>
>> +    if (firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> +    return -EACCES;
>> +
>>   /*
>>    * Check whether this is kdump kernel. If yes, force the engines to
>>    * stop and return.



[PATCH v3 9/9] KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr

2019-06-06 Thread Claudio Carvalho
From: Michael Anderson 

 - Check for MSR_S so that kvmppc_set_msr will include. Prior to this
   change return to guest would not have the S bit set.

 - Patch based on comment from Paul Mackerras 

Signed-off-by: Michael Anderson 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/kvm/book3s_64_mmu_hv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c 
b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index ab3d484c5e2e..ab62a66f9b4e 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -295,6 +295,7 @@ static void kvmppc_mmu_book3s_64_hv_reset_msr(struct 
kvm_vcpu *vcpu)
msr |= MSR_TS_S;
else
msr |= vcpu->arch.shregs.msr & MSR_TS_MASK;
+   msr |= vcpu->arch.shregs.msr & MSR_S;
kvmppc_set_msr(vcpu, msr);
 }
 
-- 
2.20.1



[PATCH v3 0/9] kvmppc: Paravirtualize KVM to support ultravisor

2019-06-06 Thread Claudio Carvalho
POWER platforms that supports the Protected Execution Facility (PEF)
introduce features that combine hardware facilities and firmware to
enable secure virtual machines. That includes a new processor mode
(ultravisor mode) and the ultravisor firmware.

In PEF enabled systems, the ultravisor firmware runs at a privilege
level above the hypervisor and also takes control over some system
resources. The hypervisor, though, can make system calls to access these
resources. Such system calls, a.k.a. ucalls, are handled by the
ultravisor firmware.

The processor allows part of the system memory to be configured as
secure memory, and introduces a a new mode, called secure mode, where
any software entity in that mode can access secure memory. The
hypervisor doesn't (and can't) run in secure mode, but a secure guest
and the ultravisor firmware do.

This patch set adds support for ultravisor calls and do some preparation
for running secure guests.

---
Changelog:
---
v2->v3:
 - Squashed patches:
 "[PATCH v2 08/10] KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
 "[PATCH v2 09/10] KVM: PPC: Book3S HV: Fixed for running secure guests"
 - Renamed patch from/to:
 "[PATCH v2 08/10] KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
 "[PATCH v3 08/09] KVM: PPC: Ultravisor: Enter a secure guest
 - Rebased
 - Addressed comments from Paul Mackerras
 - Dropped ultravisor checks made in power8 code
 - Updated the commit message for:
 "[PATCH v3 08/09] KVM: PPC: Ultravisor: Enter a secure guest"
 - Addressed comments from Maddy
 - Dropped imc-pmu.c changes
 - Changed opal-imc.c to fail the probe when the ultravisor is enabled
 - Fixed "ucall defined but not used" issue when CONFIG_PPC_UV not set 

v1->v2:
 - Addressed comments from Paul Mackerras:
 - Write the pate in HV's table before doing that in UV's
 - Renamed and better documented the ultravisor header files. Also added
   all possible return codes for each ucall
 - Updated the commit message that introduces the MSR_S bit 
 - Moved ultravisor.c and ucall.S to arch/powerpc/kernel
 - Changed ucall.S to not save CR
 - Rebased
 - Changed the patches order
 - Updated several commit messages
 - Added FW_FEATURE_ULTRAVISOR to enable use of firmware_has_feature()
 - Renamed CONFIG_PPC_KVM_UV to CONFIG_PPC_UV and used it to ifdef the ucall
   handler and the code that populates the powerpc_firmware_features for 
   ultravisor
 - Exported the ucall symbol. KVM may be built as module.
 - Restricted LDBAR access if the ultravisor firmware is available
 - Dropped patches:
 "[PATCH 06/13] KVM: PPC: Ultravisor: UV_RESTRICTED_SPR_WRITE ucall"
 "[PATCH 07/13] KVM: PPC: Ultravisor: UV_RESTRICTED_SPR_READ ucall"
 "[PATCH 08/13] KVM: PPC: Ultravisor: fix mtspr and mfspr"
 - Squashed patches:
 "[PATCH 09/13] KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
 "[PATCH 13/13] KVM: PPC: UV: Have fast_guest_return check secure_guest"

Anshuman Khandual (1):
  KVM: PPC: Ultravisor: Add PPC_UV config option

Claudio Carvalho (2):
  powerpc: Introduce FW_FEATURE_ULTRAVISOR
  KVM: PPC: Ultravisor: Restrict LDBAR access

Michael Anderson (2):
  KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE
  KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr

Ram Pai (2):
  KVM: PPC: Ultravisor: Add generic ultravisor call handler
  KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache

Sukadev Bhattiprolu (2):
  KVM: PPC: Ultravisor: Introduce the MSR_S bit
  KVM: PPC: Ultravisor: Enter a secure guest

 arch/powerpc/Kconfig  | 20 +++
 arch/powerpc/include/asm/firmware.h   |  5 +-
 arch/powerpc/include/asm/kvm_host.h   |  1 +
 arch/powerpc/include/asm/reg.h|  3 ++
 arch/powerpc/include/asm/ultravisor-api.h | 24 +
 arch/powerpc/include/asm/ultravisor.h | 49 +
 arch/powerpc/kernel/Makefile  |  1 +
 arch/powerpc/kernel/asm-offsets.c |  1 +
 arch/powerpc/kernel/prom.c|  6 +++
 arch/powerpc/kernel/ucall.S   | 31 +++
 arch/powerpc/kernel/ultravisor.c  | 28 ++
 arch/powerpc/kvm/book3s_64_mmu_hv.c   |  1 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 39 +++---
 arch/powerpc/mm/book3s64/hash_utils.c |  3 +-
 arch/powerpc/mm/book3s64/pgtable.c| 65 +--
 arch/powerpc/mm/book3s64/radix_pgtable.c  |  9 ++--
 arch/powerpc/platforms/powernv/idle.c |  6 ++-
 arch/powerpc/platforms/powernv/opal-imc.c |  7 +++
 18 files changed, 269 insertions(+), 30 deletions(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/kernel/ucall.S
 create mode 100644 arch/powerpc/kernel/ultravisor.c

-- 
2.20.1



[PATCH v3 7/9] KVM: PPC: Ultravisor: Restrict LDBAR access

2019-06-06 Thread Claudio Carvalho
When the ultravisor firmware is available, it takes control over the
LDBAR register. In this case, thread-imc updates and save/restore
operations on the LDBAR register are handled by ultravisor.

Signed-off-by: Claudio Carvalho 
Signed-off-by: Ram Pai 
---
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 2 ++
 arch/powerpc/platforms/powernv/idle.c | 6 --
 arch/powerpc/platforms/powernv/opal-imc.c | 7 +++
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index f9b2620fbecd..cffb365d9d02 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
mtspr   SPRN_RPR, r0
ld  r0, KVM_SPLIT_PMMAR(r6)
mtspr   SPRN_PMMAR, r0
+BEGIN_FW_FTR_SECTION_NESTED(70)
ld  r0, KVM_SPLIT_LDBAR(r6)
mtspr   SPRN_LDBAR, r0
+END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
isync
 FTR_SECTION_ELSE
/* On P9 we use the split_info for coordinating LPCR changes */
diff --git a/arch/powerpc/platforms/powernv/idle.c 
b/arch/powerpc/platforms/powernv/idle.c
index c9133f7908ca..fd62435e3267 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -679,7 +679,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
sprs.ptcr   = mfspr(SPRN_PTCR);
sprs.rpr= mfspr(SPRN_RPR);
sprs.tscr   = mfspr(SPRN_TSCR);
-   sprs.ldbar  = mfspr(SPRN_LDBAR);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   sprs.ldbar  = mfspr(SPRN_LDBAR);
 
sprs_saved = true;
 
@@ -762,7 +763,8 @@ static unsigned long power9_idle_stop(unsigned long psscr, 
bool mmu_on)
mtspr(SPRN_PTCR,sprs.ptcr);
mtspr(SPRN_RPR, sprs.rpr);
mtspr(SPRN_TSCR,sprs.tscr);
-   mtspr(SPRN_LDBAR,   sprs.ldbar);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_LDBAR,   sprs.ldbar);
 
if (pls >= pnv_first_tb_loss_level) {
/* TB loss */
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c 
b/arch/powerpc/platforms/powernv/opal-imc.c
index 1b6932890a73..e9b641d313fb 100644
--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -254,6 +254,13 @@ static int opal_imc_counters_probe(struct platform_device 
*pdev)
bool core_imc_reg = false, thread_imc_reg = false;
u32 type;
 
+   /*
+* When the Ultravisor is enabled, it is responsible for thread-imc
+* updates
+*/
+   if (firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   return -EACCES;
+
/*
 * Check whether this is kdump kernel. If yes, force the engines to
 * stop and return.
-- 
2.20.1



[PATCH v3 8/9] KVM: PPC: Ultravisor: Enter a secure guest

2019-06-06 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

To enter a secure guest, we have to go through the ultravisor, therefore
we do a ucall when we are entering a secure guest.

This change is needed for any sort of entry to the secure guest from the
hypervisor, whether it is a return from an hcall, a return from a
hypervisor interrupt, or the first time that a secure guest vCPU is run.

If we are returning from an hcall, the results are already in the
appropriate registers (R3:12), except for R6,7, which need to be
restored before doing the ucall (UV_RETURN).

Have fast_guest_return check the kvm_arch.secure_guest field so that a
new CPU enters UV when started (in response to a RTAS start-cpu call).

Thanks to input from Paul Mackerras, Ram Pai and Mike Anderson.

Signed-off-by: Sukadev Bhattiprolu 
[Pass SRR1 in r11 for UV_RETURN, fix kvmppc_msr_interrupt to preserve
 the MSR_S bit]
Signed-off-by: Paul Mackerras 
[Fix UV_RETURN token number and arch.secure_guest check]
Signed-off-by: Ram Pai 
[Update commit message and ret_to_ultra comment]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/kvm_host.h   |  1 +
 arch/powerpc/include/asm/ultravisor-api.h |  1 +
 arch/powerpc/kernel/asm-offsets.c |  1 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 37 +++
 4 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index 013c76a0a03e..184becb62ea4 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -294,6 +294,7 @@ struct kvm_arch {
cpumask_t cpu_in_guest;
u8 radix;
u8 fwnmi_enabled;
+   u8 secure_guest;
bool threads_indep;
bool nested_enable;
pgd_t *pgtable;
diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 24bfb4c1737e..15e6ce77a131 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -19,5 +19,6 @@
 
 /* opcodes */
 #define UV_WRITE_PATE  0xF104
+#define UV_RETURN  0xF11C
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 8e02444e9d3d..44742724513e 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -508,6 +508,7 @@ int main(void)
OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
OFFSET(KVM_RADIX, kvm, arch.radix);
OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
+   OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index cffb365d9d02..d719d730d31e 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Sign-extend HDEC if not on POWER9 */
 #define EXTEND_HDEC(reg)   \
@@ -1092,16 +1093,12 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
ld  r5, VCPU_LR(r4)
-   ld  r6, VCPU_CR(r4)
mtlrr5
-   mtcrr6
 
ld  r1, VCPU_GPR(R1)(r4)
ld  r2, VCPU_GPR(R2)(r4)
ld  r3, VCPU_GPR(R3)(r4)
ld  r5, VCPU_GPR(R5)(r4)
-   ld  r6, VCPU_GPR(R6)(r4)
-   ld  r7, VCPU_GPR(R7)(r4)
ld  r8, VCPU_GPR(R8)(r4)
ld  r9, VCPU_GPR(R9)(r4)
ld  r10, VCPU_GPR(R10)(r4)
@@ -1119,10 +1116,35 @@ BEGIN_FTR_SECTION
mtspr   SPRN_HDSISR, r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 
+   ld  r6, VCPU_KVM(r4)
+   lbz r7, KVM_SECURE_GUEST(r6)
+   cmpdi   r7, 0
+   bne ret_to_ultra
+
+   lwz r6, VCPU_CR(r4)
+   mtcrr6
+
+   ld  r7, VCPU_GPR(R7)(r4)
+   ld  r6, VCPU_GPR(R6)(r4)
ld  r0, VCPU_GPR(R0)(r4)
ld  r4, VCPU_GPR(R4)(r4)
HRFI_TO_GUEST
b   .
+/*
+ * We are entering a secure guest, so we have to invoke the ultravisor to do
+ * that. If we are returning from a hcall, the results are already in the
+ * appropriate registers (R3:12), except for R6,7 which we used as temporary
+ * registers above. Restore them, and set R0 to the ucall number (UV_RETURN).
+ */
+ret_to_ultra:
+   lwz r6, VCPU_CR(r4)
+   mtcrr6
+   mfspr   r11, SPRN_SRR1
+   LOAD_REG_IMMEDIATE(r0, UV_RETURN)
+   ld  r7, VCPU_GPR(R7)(r4)
+   ld  r6, VCPU_GPR(R6)(r4)
+   ld  r4, VCPU_GPR(R4)(r4)
+   sc  2
 
 /*
  * Enter the guest on a P9 or later system where we have exactly
@@ -3318,13 +3340,16 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
  *   r0 is used as a scratch register
  */
 kvmppc_msr_interrupt

[PATCH v3 6/9] KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache

2019-06-06 Thread Claudio Carvalho
From: Ram Pai 

Ultravisor is responsible for flushing the tlb cache, since it manages
the PATE entries. Hence skip tlb flush, if the ultravisor firmware is
available.

Signed-off-by: Ram Pai 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/mm/book3s64/pgtable.c | 33 +-
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 40a9fc8b139f..1eeb5fe87023 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -224,6 +224,23 @@ void __init mmu_partition_table_init(void)
powernv_set_nmmu_ptcr(ptcr);
 }
 
+static void flush_partition(unsigned int lpid, unsigned long dw0)
+{
+   if (dw0 & PATB_HR) {
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 1) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 1, 1) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
+   } else {
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 0) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
+   }
+   /* do we need fixup here ?*/
+   asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+}
+
 static void __mmu_partition_table_set_entry(unsigned int lpid,
unsigned long dw0,
unsigned long dw1)
@@ -238,20 +255,8 @@ static void __mmu_partition_table_set_entry(unsigned int 
lpid,
 * The type of flush (hash or radix) depends on what the previous
 * use of this partition ID was, not the new use.
 */
-   asm volatile("ptesync" : : : "memory");
-   if (old & PATB_HR) {
-   asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
-   } else {
-   asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
-   }
-   /* do we need fixup here ?*/
-   asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   flush_partition(lpid, old);
 }
 
 void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-- 
2.20.1



[PATCH v3 5/9] KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE

2019-06-06 Thread Claudio Carvalho
From: Michael Anderson 

When running under an ultravisor, the ultravisor controls the real
partition table and has it in secure memory where the hypervisor can't
access it, and therefore we (the HV) have to do a ucall whenever we want
to update an entry.

The HV still keeps a copy of its view of the partition table in normal
memory so that the nest MMU can access it.

Both partition tables will have PATE entries for HV and normal virtual
machines.

Suggested-by: Ryan Grimm 
Signed-off-by: Michael Anderson 
Signed-off-by: Madhavan Srinivasan 
Signed-off-by: Ram Pai 
[Write the pate in HV's table before doing that in UV's]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/ultravisor-api.h |  5 +++-
 arch/powerpc/include/asm/ultravisor.h | 14 ++
 arch/powerpc/mm/book3s64/hash_utils.c |  3 +-
 arch/powerpc/mm/book3s64/pgtable.c| 34 +--
 arch/powerpc/mm/book3s64/radix_pgtable.c  |  9 --
 5 files changed, 57 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 5f538f33c704..24bfb4c1737e 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -15,6 +15,9 @@
 #define U_SUCCESS  H_SUCCESS
 #define U_FUNCTION H_FUNCTION
 #define U_PARAMETERH_PARAMETER
+#define U_PERMISSION   H_PERMISSION
 
-#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
+/* opcodes */
+#define UV_WRITE_PATE  0xF104
 
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index 7500771a8ebd..4ffec7a36acd 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -12,6 +12,8 @@
 
 #if !defined(__ASSEMBLY__)
 
+#include 
+
 /* Internal functions */
 extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data);
@@ -28,8 +30,20 @@ extern int early_init_dt_scan_ultravisor(unsigned long node, 
const char *uname,
  */
 #if defined(CONFIG_PPC_UV)
 long ucall(unsigned long opcode, unsigned long *retbuf, ...);
+#else
+static long ucall(unsigned long opcode, unsigned long *retbuf, ...)
+{
+   return U_NOT_AVAILABLE;
+}
 #endif
 
+static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
+{
+   unsigned long retbuf[UCALL_BUFSIZE];
+
+   return ucall(UV_WRITE_PATE, retbuf, lpid, dw0, dw1);
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c 
b/arch/powerpc/mm/book3s64/hash_utils.c
index 1ff451892d7f..220a4e133240 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1080,9 +1080,10 @@ void hash__early_init_mmu_secondary(void)
 
if (!cpu_has_feature(CPU_FTR_ARCH_300))
mtspr(SPRN_SDR1, _SDR1);
-   else
+   else if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
mtspr(SPRN_PTCR,
  __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+
}
/* Initialize SLB */
slb_initialize();
diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 16bda049187a..40a9fc8b139f 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -206,12 +208,25 @@ void __init mmu_partition_table_init(void)
 * 64 K size.
 */
ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
-   mtspr(SPRN_PTCR, ptcr);
+   /*
+* If ultravisor is available, it is responsible for creating and
+* managing partition table
+*/
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_PTCR, ptcr);
+
+   /*
+* Since nestMMU cannot access secure memory. Create
+* and manage our own partition table. This table
+* contains entries for nonsecure and hypervisor
+* partition.
+*/
powernv_set_nmmu_ptcr(ptcr);
 }
 
-void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-  unsigned long dw1)
+static void __mmu_partition_table_set_entry(unsigned int lpid,
+   unsigned long dw0,
+   unsigned long dw1)
 {
unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
 
@@ -238,6 +253,19 @@ void mmu_partition_table_set_entry(unsigned int lpid, 
unsigned long dw0,
/* do we need fixup here ?*/
asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
+
+void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
+  

[PATCH v3 4/9] KVM: PPC: Ultravisor: Add generic ultravisor call handler

2019-06-06 Thread Claudio Carvalho
From: Ram Pai 

Add the ucall() function, which can be used to make ultravisor calls
with varied number of in and out arguments. Ultravisor calls can be made
from the host or guests.

This copies the implementation of plpar_hcall().

Signed-off-by: Ram Pai 
[Change ucall.S to not save CR, rename and move the headers, build
 ucall.S if CONFIG_PPC_UV set, and add some comments in the code]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/ultravisor-api.h | 20 +++
 arch/powerpc/include/asm/ultravisor.h | 20 +++
 arch/powerpc/kernel/Makefile  |  2 +-
 arch/powerpc/kernel/ucall.S   | 31 +++
 arch/powerpc/kernel/ultravisor.c  |  4 +++
 5 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/kernel/ucall.S

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
new file mode 100644
index ..5f538f33c704
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor calls.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_API_H
+#define _ASM_POWERPC_ULTRAVISOR_API_H
+
+#include 
+
+/* Return codes */
+#define U_NOT_AVAILABLEH_NOT_AVAILABLE
+#define U_SUCCESS  H_SUCCESS
+#define U_FUNCTION H_FUNCTION
+#define U_PARAMETERH_PARAMETER
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
+
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index e5009b0d84ea..7500771a8ebd 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -8,8 +8,28 @@
 #ifndef _ASM_POWERPC_ULTRAVISOR_H
 #define _ASM_POWERPC_ULTRAVISOR_H
 
+#include 
+
+#if !defined(__ASSEMBLY__)
+
 /* Internal functions */
 extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data);
 
+/* API functions */
+#define UCALL_BUFSIZE 4
+/**
+ * ucall: Make a powerpc ultravisor call.
+ * @opcode: The ultravisor call to make.
+ * @retbuf: Buffer to store up to 4 return arguments in.
+ *
+ * This call supports up to 6 arguments and 4 return arguments. Use
+ * UCALL_BUFSIZE to size the return argument buffer.
+ */
+#if defined(CONFIG_PPC_UV)
+long ucall(unsigned long opcode, unsigned long *retbuf, ...);
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index c8ca219e54bf..43ff4546e469 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -154,7 +154,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
-obj-$(CONFIG_PPC_UV)   += ultravisor.o
+obj-$(CONFIG_PPC_UV)   += ultravisor.o ucall.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/ucall.S b/arch/powerpc/kernel/ucall.S
new file mode 100644
index ..ecc88998a13b
--- /dev/null
+++ b/arch/powerpc/kernel/ucall.S
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Generic code to perform an ultravisor call.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+
+/*
+ * This function is based on the plpar_hcall()
+ */
+_GLOBAL_TOC(ucall)
+   mr  r0,r3
+   std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
+   mr  r3,r5
+   mr  r4,r6
+   mr  r5,r7
+   mr  r6,r8
+   mr  r7,r9
+   mr  r8,r10
+
+   sc 2/* invoke the ultravisor */
+
+   ld  r12,STK_PARAM(R4)(r1)
+   std r4,  0(r12)
+   std r5,  8(r12)
+   std r6, 16(r12)
+   std r7, 24(r12)
+
+   blr /* return r3 = status */
diff --git a/arch/powerpc/kernel/ultravisor.c b/arch/powerpc/kernel/ultravisor.c
index dc6021f63c97..02ddf79a9522 100644
--- a/arch/powerpc/kernel/ultravisor.c
+++ b/arch/powerpc/kernel/ultravisor.c
@@ -8,10 +8,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
+/* in ucall.S */
+EXPORT_SYMBOL_GPL(ucall);
+
 int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data)
 {
-- 
2.20.1



[PATCH v3 3/9] powerpc: Introduce FW_FEATURE_ULTRAVISOR

2019-06-06 Thread Claudio Carvalho
This feature tells if the ultravisor firmware is available to handle
ucalls.

Signed-off-by: Claudio Carvalho 
[Device node name to "ibm,ultravisor"]
Signed-off-by: Michael Anderson 
---
 arch/powerpc/include/asm/firmware.h   |  5 +++--
 arch/powerpc/include/asm/ultravisor.h | 15 +++
 arch/powerpc/kernel/Makefile  |  1 +
 arch/powerpc/kernel/prom.c|  6 ++
 arch/powerpc/kernel/ultravisor.c  | 24 
 5 files changed, 49 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/kernel/ultravisor.c

diff --git a/arch/powerpc/include/asm/firmware.h 
b/arch/powerpc/include/asm/firmware.h
index 00bc42d95679..43b48c4d3ca9 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -54,6 +54,7 @@
 #define FW_FEATURE_DRC_INFOASM_CONST(0x0008)
 #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0010)
 #define FW_FEATURE_PAPR_SCMASM_CONST(0x0020)
+#define FW_FEATURE_ULTRAVISOR  ASM_CONST(0x0040)
 
 #ifndef __ASSEMBLY__
 
@@ -72,9 +73,9 @@ enum {
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE |
-   FW_FEATURE_PAPR_SCM,
+   FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_PSERIES_ALWAYS = 0,
-   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
+   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_POWERNV_ALWAYS = 0,
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
new file mode 100644
index ..e5009b0d84ea
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor definitions
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_H
+#define _ASM_POWERPC_ULTRAVISOR_H
+
+/* Internal functions */
+extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data);
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 0ea6c4aa3a20..c8ca219e54bf 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -154,6 +154,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
+obj-$(CONFIG_PPC_UV)   += ultravisor.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4221527b082f..8a9a8a319959 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -713,6 +714,11 @@ void __init early_init_devtree(void *params)
of_scan_flat_dt(early_init_dt_scan_fw_dump, NULL);
 #endif
 
+#if defined(CONFIG_PPC_UV)
+   /* Scan tree for ultravisor feature */
+   of_scan_flat_dt(early_init_dt_scan_ultravisor, NULL);
+#endif
+
/* Retrieve various informations from the /chosen node of the
 * device-tree, including the platform type, initrd location and
 * size, TCE reserve, and more ...
diff --git a/arch/powerpc/kernel/ultravisor.c b/arch/powerpc/kernel/ultravisor.c
new file mode 100644
index ..dc6021f63c97
--- /dev/null
+++ b/arch/powerpc/kernel/ultravisor.c
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ultravisor high level interfaces
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data)
+{
+   if (depth != 1 || strcmp(uname, "ibm,ultravisor") != 0)
+   return 0;
+
+   powerpc_firmware_features |= FW_FEATURE_ULTRAVISOR;
+   pr_debug("Ultravisor detected!\n");
+   return 1;
+}
-- 
2.20.1



[PATCH v3 1/9] KVM: PPC: Ultravisor: Add PPC_UV config option

2019-06-06 Thread Claudio Carvalho
From: Anshuman Khandual 

CONFIG_PPC_UV adds support for ultravisor.

Signed-off-by: Anshuman Khandual 
Signed-off-by: Bharata B Rao 
Signed-off-by: Ram Pai 
[Update config help and commit message]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/Kconfig | 20 
 1 file changed, 20 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 8c1c636308c8..276c1857c335 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -439,6 +439,26 @@ config PPC_TRANSACTIONAL_MEM
---help---
  Support user-mode Transactional Memory on POWERPC.
 
+config PPC_UV
+   bool "Ultravisor support"
+   depends on KVM_BOOK3S_HV_POSSIBLE
+   select HMM_MIRROR
+   select HMM
+   select ZONE_DEVICE
+   select MIGRATE_VMA_HELPER
+   select DEV_PAGEMAP_OPS
+   select DEVICE_PRIVATE
+   select MEMORY_HOTPLUG
+   select MEMORY_HOTREMOVE
+   default n
+   help
+ This option paravirtualizes the kernel to run in POWER platforms that
+ supports the Protected Execution Facility (PEF). In such platforms,
+ the ultravisor firmware runs at a privilege level above the
+ hypervisor.
+
+ If unsure, say "N".
+
 config LD_HEAD_STUB_CATCH
bool "Reserve 256 bytes to cope with linker stubs in HEAD text" if 
EXPERT
depends on PPC64
-- 
2.20.1



[PATCH v3 2/9] KVM: PPC: Ultravisor: Introduce the MSR_S bit

2019-06-06 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

The ultravisor processor mode is introduced in POWER platforms that
supports the Protected Execution Facility (PEF). Ultravisor is higher
privileged than hypervisor mode.

In PEF enabled platforms, the MSR_S bit is used to indicate if the
thread is in secure state. With the MSR_S bit, the privilege state of
the thread is now determined by MSR_S, MSR_HV and MSR_PR, as follows:

S   HV  PR
---
0   x   1   problem
1   0   1   problem
x   x   0   privileged
x   1   0   hypervisor
1   1   0   ultravisor
1   1   1   reserved

The hypervisor doesn't (and can't) run with the MSR_S bit set, but a
secure guest and the ultravisor firmware do.

Signed-off-by: Sukadev Bhattiprolu 
Signed-off-by: Ram Pai 
[Update the commit message]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/reg.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 10caa145f98b..39b4c0a519f5 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -38,6 +38,7 @@
 #define MSR_TM_LG  32  /* Trans Mem Available */
 #define MSR_VEC_LG 25  /* Enable AltiVec */
 #define MSR_VSX_LG 23  /* Enable VSX */
+#define MSR_S_LG   22  /* Secure VM bit */
 #define MSR_POW_LG 18  /* Enable Power Management */
 #define MSR_WE_LG  18  /* Wait State Enable */
 #define MSR_TGPR_LG17  /* TLB Update registers in use */
@@ -71,11 +72,13 @@
 #define MSR_SF __MASK(MSR_SF_LG)   /* Enable 64 bit mode */
 #define MSR_ISF__MASK(MSR_ISF_LG)  /* Interrupt 64b mode 
valid on 630 */
 #define MSR_HV __MASK(MSR_HV_LG)   /* Hypervisor state */
+#define MSR_S  __MASK(MSR_S_LG)/* Secure state */
 #else
 /* so tests for these bits fail on 32-bit */
 #define MSR_SF 0
 #define MSR_ISF0
 #define MSR_HV 0
+#define MSR_S  0
 #endif
 
 /*
-- 
2.20.1



Re: [RFC PATCH v2 07/10] KVM: PPC: Ultravisor: Restrict LDBAR access

2019-05-30 Thread Claudio Carvalho


On 5/21/19 2:24 AM, Madhavan Srinivasan wrote:
>
> On 18/05/19 7:55 PM, Claudio Carvalho wrote:
>> From: Ram Pai  When the ultravisor firmware is
>> available, it takes control over the LDBAR register. In this case,
>> thread-imc updates and save/restore operations on the LDBAR register are
>> handled by ultravisor.
> we should remove the core and thread imc nodes in the skiboot
> if the ultravisor is enabled. We dont need imc-pmu.c file changes, imc-pmu.c
> inits only if we have the corresponding nodes. I will post a skiboot patch.

Hi Maddy,

Thanks for the feedback and for taking care of the change needed in skiboot.

Right, if the core and thread imc devtree nodes were not created by
skiboot, then we don't need imc-pmu changes. As a sanity check, should we
have something like the following to make sure that the imc-pmu code will
not be executed even in the situation where ultravisor is enabled, but for
some reason skiboot did not remove those devtree nodes (e.g. your skiboot
patch was not applied)?

-

--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -258,6 +258,15 @@ static int opal_imc_counters_probe(struct
platform_device *pdev)
    bool core_imc_reg = false, thread_imc_reg = false;
    u32 type;
 
+   /*
+    * When ultravisor is enabled, it is responsible for thread-imc
+    * updates
+    */
+   if (firmware_has_feature(FW_FEATURE_ULTRAVISOR)) {
+   pr_info("IMC Ultravisor enabled\n");
+   return -EACCES;
+   }
+
    /*
 * Check whether this is kdump kernel. If yes, force the engines to
 * stop and return.



Claudio


> Maddy
>
>> Signed-off-by: Ram Pai 
>> [Restrict LDBAR access in assembly code and some in C, update the commit
>>   message]
>> Signed-off-by: Claudio Carvalho 
>> ---
>>   arch/powerpc/kvm/book3s_hv.c |  4 +-
>>   arch/powerpc/kvm/book3s_hv_rmhandlers.S  |  2 +
>>   arch/powerpc/perf/imc-pmu.c  | 64 
>>   arch/powerpc/platforms/powernv/idle.c    |  6 +-
>>   arch/powerpc/platforms/powernv/subcore-asm.S |  4 ++
>>   5 files changed, 52 insertions(+), 28 deletions(-)
>>
>> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
>> index 0fab0a201027..81f35f955d16 100644
>> --- a/arch/powerpc/kvm/book3s_hv.c
>> +++ b/arch/powerpc/kvm/book3s_hv.c
>> @@ -75,6 +75,7 @@
>>   #include 
>>   #include 
>>   #include 
>> +#include 
>>
>>   #include "book3s.h"
>>
>> @@ -3117,7 +3118,8 @@ static noinline void kvmppc_run_core(struct
>> kvmppc_vcore *vc)
>>   subcore_size = MAX_SMT_THREADS / split;
>>   split_info.rpr = mfspr(SPRN_RPR);
>>   split_info.pmmar = mfspr(SPRN_PMMAR);
>> -    split_info.ldbar = mfspr(SPRN_LDBAR);
>> +    if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
>> +    split_info.ldbar = mfspr(SPRN_LDBAR);
>>   split_info.subcore_size = subcore_size;
>>   } else {
>>   split_info.subcore_size = 1;
>> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> index dd014308f065..938cfa5dceed 100644
>> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
>> @@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
>>   mtspr    SPRN_RPR, r0
>>   ld    r0, KVM_SPLIT_PMMAR(r6)
>>   mtspr    SPRN_PMMAR, r0
>> +BEGIN_FW_FTR_SECTION_NESTED(70)
>>   ld    r0, KVM_SPLIT_LDBAR(r6)
>>   mtspr    SPRN_LDBAR, r0
>> +END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
>>   isync
>>   FTR_SECTION_ELSE
>>   /* On P9 we use the split_info for coordinating LPCR changes */
>> diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
>> index 31fa753e2eb2..39c84de74da9 100644
>> --- a/arch/powerpc/perf/imc-pmu.c
>> +++ b/arch/powerpc/perf/imc-pmu.c
>> @@ -17,6 +17,7 @@
>>   #include 
>>   #include 
>>   #include 
>> +#include 
>>
>>   /* Nest IMC data structures and variables */
>>
>> @@ -816,6 +817,17 @@ static int core_imc_event_init(struct perf_event
>> *event)
>>   return 0;
>>   }
>>
>> +static void thread_imc_ldbar_disable(void *dummy)
>> +{
>> +    /*
>> + * By Zeroing LDBAR, we disable thread-imc updates. When the
>> ultravisor
>> + * firmware is available, it is responsible for handling thread-imc
>> + * 

[RFC PATCH v2 10/10] KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr

2019-05-18 Thread Claudio Carvalho
From: Michael Anderson 

 - Check for MSR_S so that kvmppc_set_msr will include. Prior to this
   change return to guest would not have the S bit set.

 - Patch based on comment from Paul Mackerras 

Signed-off-by: Michael Anderson 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/kvm/book3s_64_mmu_hv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c 
b/arch/powerpc/kvm/book3s_64_mmu_hv.c
index be7bc070eae5..dcc1c1fb5f9c 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_hv.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c
@@ -295,6 +295,7 @@ static void kvmppc_mmu_book3s_64_hv_reset_msr(struct 
kvm_vcpu *vcpu)
msr |= MSR_TS_S;
else
msr |= vcpu->arch.shregs.msr & MSR_TS_MASK;
+   msr |= vcpu->arch.shregs.msr & MSR_S;
kvmppc_set_msr(vcpu, msr);
 }
 
-- 
2.20.1



[RFC PATCH v2 09/10] KVM: PPC: Book3S HV: Fixed for running secure guests

2019-05-18 Thread Claudio Carvalho
From: Paul Mackerras 

- Pass SRR1 in r11 for UV_RETURN because SRR0 and SRR1 get set by
  the sc 2 instruction. (Note r3 - r10 potentially have hcall return
  values in them.)

- Fix kvmppc_msr_interrupt to preserve the MSR_S bit.

Signed-off-by: Paul Mackerras 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index d89efa0783a2..1b44c85956b9 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -1160,6 +1160,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 ret_to_ultra:
lwz r6, VCPU_CR(r4)
mtcrr6
+   mfspr   r11, SPRN_SRR1
LOAD_REG_IMMEDIATE(r0, UV_RETURN)
ld  r7, VCPU_GPR(R7)(r4)
ld  r6, VCPU_GPR(R6)(r4)
@@ -3360,13 +3361,16 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
  *   r0 is used as a scratch register
  */
 kvmppc_msr_interrupt:
+   andis.  r0, r11, MSR_S@h
rldicl  r0, r11, 64 - MSR_TS_S_LG, 62
-   cmpwi   r0, 2 /* Check if we are in transactional state..  */
+   cmpwi   cr1, r0, 2 /* Check if we are in transactional state..  */
ld  r11, VCPU_INTR_MSR(r9)
-   bne 1f
+   bne cr1, 1f
/* ... if transactional, change to suspended */
li  r0, 1
 1: rldimi  r11, r0, MSR_TS_S_LG, 63 - MSR_TS_T_LG
+   beqlr
+   orisr11, r11, MSR_S@h   /* preserve MSR_S bit setting */
blr
 
 /*
-- 
2.20.1



[RFC PATCH v2 08/10] KVM: PPC: Ultravisor: Return to UV for hcalls from SVM

2019-05-18 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

All hcalls from a secure VM go to the ultravisor from where they are
reflected into the HV. When we (HV) complete processing such hcalls,
we should return to the UV rather than to the guest kernel.

Have fast_guest_return check the kvm_arch.secure_guest field so that
even a new CPU will enter UV when started (in response to a RTAS
start-cpu call).

Thanks to input from Paul Mackerras, Ram Pai and Mike Anderson.

Signed-off-by: Sukadev Bhattiprolu 
[Fix UV_RETURN token number and arch.secure_guest check]
Signed-off-by: Ram Pai 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/kvm_host.h   |  1 +
 arch/powerpc/include/asm/ultravisor-api.h |  1 +
 arch/powerpc/kernel/asm-offsets.c |  1 +
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   | 30 ---
 4 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h 
b/arch/powerpc/include/asm/kvm_host.h
index e6b5bb012ccb..ba7dd35cb916 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -290,6 +290,7 @@ struct kvm_arch {
cpumask_t cpu_in_guest;
u8 radix;
u8 fwnmi_enabled;
+   u8 secure_guest;
bool threads_indep;
bool nested_enable;
pgd_t *pgtable;
diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 24bfb4c1737e..15e6ce77a131 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -19,5 +19,6 @@
 
 /* opcodes */
 #define UV_WRITE_PATE  0xF104
+#define UV_RETURN  0xF11C
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index 8e02444e9d3d..44742724513e 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -508,6 +508,7 @@ int main(void)
OFFSET(KVM_VRMA_SLB_V, kvm, arch.vrma_slb_v);
OFFSET(KVM_RADIX, kvm, arch.radix);
OFFSET(KVM_FWNMI, kvm, arch.fwnmi_enabled);
+   OFFSET(KVM_SECURE_GUEST, kvm, arch.secure_guest);
OFFSET(VCPU_DSISR, kvm_vcpu, arch.shregs.dsisr);
OFFSET(VCPU_DAR, kvm_vcpu, arch.shregs.dar);
OFFSET(VCPU_VPA, kvm_vcpu, arch.vpa.pinned_addr);
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 938cfa5dceed..d89efa0783a2 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Sign-extend HDEC if not on POWER9 */
 #define EXTEND_HDEC(reg)   \
@@ -1112,16 +1113,12 @@ BEGIN_FTR_SECTION
 END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
 
ld  r5, VCPU_LR(r4)
-   ld  r6, VCPU_CR(r4)
mtlrr5
-   mtcrr6
 
ld  r1, VCPU_GPR(R1)(r4)
ld  r2, VCPU_GPR(R2)(r4)
ld  r3, VCPU_GPR(R3)(r4)
ld  r5, VCPU_GPR(R5)(r4)
-   ld  r6, VCPU_GPR(R6)(r4)
-   ld  r7, VCPU_GPR(R7)(r4)
ld  r8, VCPU_GPR(R8)(r4)
ld  r9, VCPU_GPR(R9)(r4)
ld  r10, VCPU_GPR(R10)(r4)
@@ -1139,10 +1136,35 @@ BEGIN_FTR_SECTION
mtspr   SPRN_HDSISR, r0
 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
 
+   ld  r6, VCPU_KVM(r4)
+   lbz r7, KVM_SECURE_GUEST(r6)
+   cmpdi   r7, 0
+   bne ret_to_ultra
+
+   lwz r6, VCPU_CR(r4)
+   mtcrr6
+
+   ld  r7, VCPU_GPR(R7)(r4)
+   ld  r6, VCPU_GPR(R6)(r4)
ld  r0, VCPU_GPR(R0)(r4)
ld  r4, VCPU_GPR(R4)(r4)
HRFI_TO_GUEST
b   .
+/*
+ * The hcall we just completed was from Ultravisor. Use UV_RETURN
+ * ultra call to return to the Ultravisor. Results from the hcall
+ * are already in the appropriate registers (r3:12), except for
+ * R6,7 which we used as temporary registers above. Restore them,
+ * and set R0 to the ucall number (UV_RETURN).
+ */
+ret_to_ultra:
+   lwz r6, VCPU_CR(r4)
+   mtcrr6
+   LOAD_REG_IMMEDIATE(r0, UV_RETURN)
+   ld  r7, VCPU_GPR(R7)(r4)
+   ld  r6, VCPU_GPR(R6)(r4)
+   ld  r4, VCPU_GPR(R4)(r4)
+   sc  2
 
 /*
  * Enter the guest on a P9 or later system where we have exactly
-- 
2.20.1



[RFC PATCH v2 07/10] KVM: PPC: Ultravisor: Restrict LDBAR access

2019-05-18 Thread Claudio Carvalho
From: Ram Pai 

When the ultravisor firmware is available, it takes control over the
LDBAR register. In this case, thread-imc updates and save/restore
operations on the LDBAR register are handled by ultravisor.

Signed-off-by: Ram Pai 
[Restrict LDBAR access in assembly code and some in C, update the commit
 message]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/kvm/book3s_hv.c |  4 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S  |  2 +
 arch/powerpc/perf/imc-pmu.c  | 64 
 arch/powerpc/platforms/powernv/idle.c|  6 +-
 arch/powerpc/platforms/powernv/subcore-asm.S |  4 ++
 5 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 0fab0a201027..81f35f955d16 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -75,6 +75,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "book3s.h"
 
@@ -3117,7 +3118,8 @@ static noinline void kvmppc_run_core(struct kvmppc_vcore 
*vc)
subcore_size = MAX_SMT_THREADS / split;
split_info.rpr = mfspr(SPRN_RPR);
split_info.pmmar = mfspr(SPRN_PMMAR);
-   split_info.ldbar = mfspr(SPRN_LDBAR);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   split_info.ldbar = mfspr(SPRN_LDBAR);
split_info.subcore_size = subcore_size;
} else {
split_info.subcore_size = 1;
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index dd014308f065..938cfa5dceed 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -375,8 +375,10 @@ BEGIN_FTR_SECTION
mtspr   SPRN_RPR, r0
ld  r0, KVM_SPLIT_PMMAR(r6)
mtspr   SPRN_PMMAR, r0
+BEGIN_FW_FTR_SECTION_NESTED(70)
ld  r0, KVM_SPLIT_LDBAR(r6)
mtspr   SPRN_LDBAR, r0
+END_FW_FTR_SECTION_NESTED(FW_FEATURE_ULTRAVISOR, 0, 70)
isync
 FTR_SECTION_ELSE
/* On P9 we use the split_info for coordinating LPCR changes */
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 31fa753e2eb2..39c84de74da9 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Nest IMC data structures and variables */
 
@@ -816,6 +817,17 @@ static int core_imc_event_init(struct perf_event *event)
return 0;
 }
 
+static void thread_imc_ldbar_disable(void *dummy)
+{
+   /*
+* By Zeroing LDBAR, we disable thread-imc updates. When the ultravisor
+* firmware is available, it is responsible for handling thread-imc
+* updates, though
+*/
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_LDBAR, 0);
+}
+
 /*
  * Allocates a page of memory for each of the online cpus, and load
  * LDBAR with 0.
@@ -856,7 +868,7 @@ static int thread_imc_mem_alloc(int cpu_id, int size)
per_cpu(thread_imc_mem, cpu_id) = local_mem;
}
 
-   mtspr(SPRN_LDBAR, 0);
+   thread_imc_ldbar_disable(NULL);
return 0;
 }
 
@@ -867,7 +879,7 @@ static int ppc_thread_imc_cpu_online(unsigned int cpu)
 
 static int ppc_thread_imc_cpu_offline(unsigned int cpu)
 {
-   mtspr(SPRN_LDBAR, 0);
+   thread_imc_ldbar_disable(NULL);
return 0;
 }
 
@@ -1010,7 +1022,6 @@ static int thread_imc_event_add(struct perf_event *event, 
int flags)
 {
int core_id;
struct imc_pmu_ref *ref;
-   u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, 
smp_processor_id());
 
if (flags & PERF_EF_START)
imc_event_start(event, flags);
@@ -1019,8 +1030,14 @@ static int thread_imc_event_add(struct perf_event 
*event, int flags)
return -EINVAL;
 
core_id = smp_processor_id() / threads_per_core;
-   ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) | 
THREAD_IMC_ENABLE;
-   mtspr(SPRN_LDBAR, ldbar_value);
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR)) {
+   u64 ldbar_value, *local_mem;
+
+   local_mem = per_cpu(thread_imc_mem, smp_processor_id());
+   ldbar_value = ((u64)local_mem & THREAD_IMC_LDBAR_MASK) |
+   THREAD_IMC_ENABLE;
+   mtspr(SPRN_LDBAR, ldbar_value);
+   }
 
/*
 * imc pmus are enabled only when it is used.
@@ -1053,7 +1070,7 @@ static void thread_imc_event_del(struct perf_event 
*event, int flags)
int core_id;
struct imc_pmu_ref *ref;
 
-   mtspr(SPRN_LDBAR, 0);
+   thread_imc_ldbar_disable(NULL);
 
core_id = smp_processor_id() / threads_per_core;
ref = _imc_refc[core_id];
@@ -1109,7 +1126,7 @@ static int trace_imc_mem_alloc(int cpu_id, int size)

[RFC PATCH v2 06/10] KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache

2019-05-18 Thread Claudio Carvalho
From: Ram Pai 

Ultravisor is responsible for flushing the tlb cache, since it manages
the PATE entries. Hence skip tlb flush, if the ultravisor firmware is
available.

Signed-off-by: Ram Pai 
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/mm/book3s64/pgtable.c | 33 +-
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 40a9fc8b139f..1eeb5fe87023 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -224,6 +224,23 @@ void __init mmu_partition_table_init(void)
powernv_set_nmmu_ptcr(ptcr);
 }
 
+static void flush_partition(unsigned int lpid, unsigned long dw0)
+{
+   if (dw0 & PATB_HR) {
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 1) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 1, 1) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
+   } else {
+   asm volatile(PPC_TLBIE_5(%0, %1, 2, 0, 0) : :
+"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
+   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
+   }
+   /* do we need fixup here ?*/
+   asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+}
+
 static void __mmu_partition_table_set_entry(unsigned int lpid,
unsigned long dw0,
unsigned long dw1)
@@ -238,20 +255,8 @@ static void __mmu_partition_table_set_entry(unsigned int 
lpid,
 * The type of flush (hash or radix) depends on what the previous
 * use of this partition ID was, not the new use.
 */
-   asm volatile("ptesync" : : : "memory");
-   if (old & PATB_HR) {
-   asm volatile(PPC_TLBIE_5(%0,%1,2,0,1) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   asm volatile(PPC_TLBIE_5(%0,%1,2,1,1) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 1);
-   } else {
-   asm volatile(PPC_TLBIE_5(%0,%1,2,0,0) : :
-"r" (TLBIEL_INVAL_SET_LPID), "r" (lpid));
-   trace_tlbie(lpid, 0, TLBIEL_INVAL_SET_LPID, lpid, 2, 0, 0);
-   }
-   /* do we need fixup here ?*/
-   asm volatile("eieio; tlbsync; ptesync" : : : "memory");
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   flush_partition(lpid, old);
 }
 
 void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-- 
2.20.1



[RFC PATCH v2 05/10] KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE

2019-05-18 Thread Claudio Carvalho
From: Michael Anderson 

When running under an ultravisor, the ultravisor controls the real
partition table and has it in secure memory where the hypervisor can't
access it, and therefore we (the HV) have to do a ucall whenever we want
to update an entry.

The HV still keeps a copy of its view of the partition table in normal
memory so that the nest MMU can access it.

Both partition tables will have PATE entries for HV and normal virtual
machines.

Suggested-by: Ryan Grimm 
Signed-off-by: Michael Anderson 
Signed-off-by: Madhavan Srinivasan 
Signed-off-by: Ram Pai 
[Write the pate in HV's table before doing that in UV's]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/ultravisor-api.h |  5 +++-
 arch/powerpc/include/asm/ultravisor.h |  9 ++
 arch/powerpc/mm/book3s64/hash_utils.c |  3 +-
 arch/powerpc/mm/book3s64/pgtable.c| 34 +--
 arch/powerpc/mm/book3s64/radix_pgtable.c  |  9 --
 5 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
index 5f538f33c704..24bfb4c1737e 100644
--- a/arch/powerpc/include/asm/ultravisor-api.h
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -15,6 +15,9 @@
 #define U_SUCCESS  H_SUCCESS
 #define U_FUNCTION H_FUNCTION
 #define U_PARAMETERH_PARAMETER
+#define U_PERMISSION   H_PERMISSION
 
-#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
+/* opcodes */
+#define UV_WRITE_PATE  0xF104
 
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index e8abc1bbc194..4ffec7a36acd 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -12,6 +12,8 @@
 
 #if !defined(__ASSEMBLY__)
 
+#include 
+
 /* Internal functions */
 extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data);
@@ -35,6 +37,13 @@ static long ucall(unsigned long opcode, unsigned long 
*retbuf, ...)
 }
 #endif
 
+static inline int uv_register_pate(u64 lpid, u64 dw0, u64 dw1)
+{
+   unsigned long retbuf[UCALL_BUFSIZE];
+
+   return ucall(UV_WRITE_PATE, retbuf, lpid, dw0, dw1);
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c 
b/arch/powerpc/mm/book3s64/hash_utils.c
index 919a861a8ec0..8419e665fab0 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1080,9 +1080,10 @@ void hash__early_init_mmu_secondary(void)
 
if (!cpu_has_feature(CPU_FTR_ARCH_300))
mtspr(SPRN_SDR1, _SDR1);
-   else
+   else if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
mtspr(SPRN_PTCR,
  __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
+
}
/* Initialize SLB */
slb_initialize();
diff --git a/arch/powerpc/mm/book3s64/pgtable.c 
b/arch/powerpc/mm/book3s64/pgtable.c
index 16bda049187a..40a9fc8b139f 100644
--- a/arch/powerpc/mm/book3s64/pgtable.c
+++ b/arch/powerpc/mm/book3s64/pgtable.c
@@ -16,6 +16,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include 
 #include 
@@ -206,12 +208,25 @@ void __init mmu_partition_table_init(void)
 * 64 K size.
 */
ptcr = __pa(partition_tb) | (PATB_SIZE_SHIFT - 12);
-   mtspr(SPRN_PTCR, ptcr);
+   /*
+* If ultravisor is available, it is responsible for creating and
+* managing partition table
+*/
+   if (!firmware_has_feature(FW_FEATURE_ULTRAVISOR))
+   mtspr(SPRN_PTCR, ptcr);
+
+   /*
+* Since nestMMU cannot access secure memory. Create
+* and manage our own partition table. This table
+* contains entries for nonsecure and hypervisor
+* partition.
+*/
powernv_set_nmmu_ptcr(ptcr);
 }
 
-void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
-  unsigned long dw1)
+static void __mmu_partition_table_set_entry(unsigned int lpid,
+   unsigned long dw0,
+   unsigned long dw1)
 {
unsigned long old = be64_to_cpu(partition_tb[lpid].patb0);
 
@@ -238,6 +253,19 @@ void mmu_partition_table_set_entry(unsigned int lpid, 
unsigned long dw0,
/* do we need fixup here ?*/
asm volatile("eieio; tlbsync; ptesync" : : : "memory");
 }
+
+void mmu_partition_table_set_entry(unsigned int lpid, unsigned long dw0,
+ unsigned long dw1)
+{
+   __mmu_partition_table_set_entry(lpid, dw0, dw1);
+
+   if (firmware_has_feature(FW_FEATURE_ULTRAVISOR)) {
+   uv_register_pate(lpid, dw0, dw1);
+   pr_info("PATE

[RFC PATCH v2 03/10] powerpc: Introduce FW_FEATURE_ULTRAVISOR

2019-05-18 Thread Claudio Carvalho
This feature tells if the ultravisor firmware is available to handle
ucalls.

Signed-off-by: Claudio Carvalho 
[Device node name to "ibm,ultravisor"]
Signed-off-by: Michael Anderson 
---
 arch/powerpc/include/asm/firmware.h   |  5 +++--
 arch/powerpc/include/asm/ultravisor.h | 15 +++
 arch/powerpc/kernel/Makefile  |  1 +
 arch/powerpc/kernel/prom.c|  6 ++
 arch/powerpc/kernel/ultravisor.c  | 26 ++
 5 files changed, 51 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/kernel/ultravisor.c

diff --git a/arch/powerpc/include/asm/firmware.h 
b/arch/powerpc/include/asm/firmware.h
index 00bc42d95679..43b48c4d3ca9 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -54,6 +54,7 @@
 #define FW_FEATURE_DRC_INFOASM_CONST(0x0008)
 #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0010)
 #define FW_FEATURE_PAPR_SCMASM_CONST(0x0020)
+#define FW_FEATURE_ULTRAVISOR  ASM_CONST(0x0040)
 
 #ifndef __ASSEMBLY__
 
@@ -72,9 +73,9 @@ enum {
FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
FW_FEATURE_HPT_RESIZE | FW_FEATURE_DRMEM_V2 |
FW_FEATURE_DRC_INFO | FW_FEATURE_BLOCK_REMOVE |
-   FW_FEATURE_PAPR_SCM,
+   FW_FEATURE_PAPR_SCM | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_PSERIES_ALWAYS = 0,
-   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL,
+   FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_ULTRAVISOR,
FW_FEATURE_POWERNV_ALWAYS = 0,
FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
new file mode 100644
index ..e5009b0d84ea
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor definitions
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_H
+#define _ASM_POWERPC_ULTRAVISOR_H
+
+/* Internal functions */
+extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data);
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 0ea6c4aa3a20..c8ca219e54bf 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -154,6 +154,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
+obj-$(CONFIG_PPC_UV)   += ultravisor.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 4221527b082f..8a9a8a319959 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -59,6 +59,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -713,6 +714,11 @@ void __init early_init_devtree(void *params)
of_scan_flat_dt(early_init_dt_scan_fw_dump, NULL);
 #endif
 
+#if defined(CONFIG_PPC_UV)
+   /* Scan tree for ultravisor feature */
+   of_scan_flat_dt(early_init_dt_scan_ultravisor, NULL);
+#endif
+
/* Retrieve various informations from the /chosen node of the
 * device-tree, including the platform type, initrd location and
 * size, TCE reserve, and more ...
diff --git a/arch/powerpc/kernel/ultravisor.c b/arch/powerpc/kernel/ultravisor.c
new file mode 100644
index ..ac23835bdf5a
--- /dev/null
+++ b/arch/powerpc/kernel/ultravisor.c
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Ultravisor high level interfaces
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
+int depth, void *data)
+{
+   if (depth != 1 || strcmp(uname, "ibm,ultravisor") != 0)
+   return 0;
+
+   /* TODO: check the compatible devtree property once it is created */
+
+   powerpc_firmware_features |= FW_FEATURE_ULTRAVISOR;
+   pr_debug("Ultravisor detected!\n");
+   return 1;
+}
-- 
2.20.1



[RFC PATCH v2 04/10] KVM: PPC: Ultravisor: Add generic ultravisor call handler

2019-05-18 Thread Claudio Carvalho
From: Ram Pai 

Add the ucall() function, which can be used to make ultravisor calls
with varied number of in and out arguments. Ultravisor calls can be made
from the host or guests.

This copies the implementation of plpar_hcall().

Signed-off-by: Ram Pai 
[Change ucall.S to not save CR, rename and move the headers, build
 ucall.S if CONFIG_PPC_UV set, and add some comments in the code]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/ultravisor-api.h | 20 +++
 arch/powerpc/include/asm/ultravisor.h | 25 ++
 arch/powerpc/kernel/Makefile  |  2 +-
 arch/powerpc/kernel/ucall.S   | 31 +++
 arch/powerpc/kernel/ultravisor.c  |  4 +++
 5 files changed, 81 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/kernel/ucall.S

diff --git a/arch/powerpc/include/asm/ultravisor-api.h 
b/arch/powerpc/include/asm/ultravisor-api.h
new file mode 100644
index ..5f538f33c704
--- /dev/null
+++ b/arch/powerpc/include/asm/ultravisor-api.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Ultravisor calls.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#ifndef _ASM_POWERPC_ULTRAVISOR_API_H
+#define _ASM_POWERPC_ULTRAVISOR_API_H
+
+#include 
+
+/* Return codes */
+#define U_NOT_AVAILABLEH_NOT_AVAILABLE
+#define U_SUCCESS  H_SUCCESS
+#define U_FUNCTION H_FUNCTION
+#define U_PARAMETERH_PARAMETER
+
+#endif /* _ASM_POWERPC_ULTRAVISOR_API_H */
+
diff --git a/arch/powerpc/include/asm/ultravisor.h 
b/arch/powerpc/include/asm/ultravisor.h
index e5009b0d84ea..e8abc1bbc194 100644
--- a/arch/powerpc/include/asm/ultravisor.h
+++ b/arch/powerpc/include/asm/ultravisor.h
@@ -8,8 +8,33 @@
 #ifndef _ASM_POWERPC_ULTRAVISOR_H
 #define _ASM_POWERPC_ULTRAVISOR_H
 
+#include 
+
+#if !defined(__ASSEMBLY__)
+
 /* Internal functions */
 extern int early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data);
 
+/* API functions */
+#define UCALL_BUFSIZE 4
+/**
+ * ucall: Make a powerpc ultravisor call.
+ * @opcode: The ultravisor call to make.
+ * @retbuf: Buffer to store up to 4 return arguments in.
+ *
+ * This call supports up to 6 arguments and 4 return arguments. Use
+ * UCALL_BUFSIZE to size the return argument buffer.
+ */
+#if defined(CONFIG_PPC_UV)
+long ucall(unsigned long opcode, unsigned long *retbuf, ...);
+#else
+static long ucall(unsigned long opcode, unsigned long *retbuf, ...)
+{
+   return U_NOT_AVAILABLE;
+}
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
 #endif /* _ASM_POWERPC_ULTRAVISOR_H */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index c8ca219e54bf..43ff4546e469 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -154,7 +154,7 @@ endif
 
 obj-$(CONFIG_EPAPR_PARAVIRT)   += epapr_paravirt.o epapr_hcalls.o
 obj-$(CONFIG_KVM_GUEST)+= kvm.o kvm_emul.o
-obj-$(CONFIG_PPC_UV)   += ultravisor.o
+obj-$(CONFIG_PPC_UV)   += ultravisor.o ucall.o
 
 # Disable GCOV, KCOV & sanitizers in odd or sensitive code
 GCOV_PROFILE_prom_init.o := n
diff --git a/arch/powerpc/kernel/ucall.S b/arch/powerpc/kernel/ucall.S
new file mode 100644
index ..ecc88998a13b
--- /dev/null
+++ b/arch/powerpc/kernel/ucall.S
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Generic code to perform an ultravisor call.
+ *
+ * Copyright 2019, IBM Corporation.
+ *
+ */
+#include 
+
+/*
+ * This function is based on the plpar_hcall()
+ */
+_GLOBAL_TOC(ucall)
+   mr  r0,r3
+   std r4,STK_PARAM(R4)(r1) /* Save ret buffer */
+   mr  r3,r5
+   mr  r4,r6
+   mr  r5,r7
+   mr  r6,r8
+   mr  r7,r9
+   mr  r8,r10
+
+   sc 2/* invoke the ultravisor */
+
+   ld  r12,STK_PARAM(R4)(r1)
+   std r4,  0(r12)
+   std r5,  8(r12)
+   std r6, 16(r12)
+   std r7, 24(r12)
+
+   blr /* return r3 = status */
diff --git a/arch/powerpc/kernel/ultravisor.c b/arch/powerpc/kernel/ultravisor.c
index ac23835bdf5a..9fbf0804ee4e 100644
--- a/arch/powerpc/kernel/ultravisor.c
+++ b/arch/powerpc/kernel/ultravisor.c
@@ -8,10 +8,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
 
+/* in ucall.S */
+EXPORT_SYMBOL_GPL(ucall);
+
 int __init early_init_dt_scan_ultravisor(unsigned long node, const char *uname,
 int depth, void *data)
 {
-- 
2.20.1



[RFC PATCH v2 02/10] KVM: PPC: Ultravisor: Introduce the MSR_S bit

2019-05-18 Thread Claudio Carvalho
From: Sukadev Bhattiprolu 

The ultravisor processor mode is introduced in POWER platforms that
supports the Protected Execution Facility (PEF). Ultravisor is higher
privileged than hypervisor mode.

In PEF enabled platforms, the MSR_S bit is used to indicate if the
thread is in secure state. With the MSR_S bit, the privilege state of
the thread is now determined by MSR_S, MSR_HV and MSR_PR, as follows:

S   HV  PR
---
0   x   1   problem
1   0   1   problem
x   x   0   privileged
x   1   0   hypervisor
1   1   0   ultravisor
1   1   1   reserved

The hypervisor doesn't (and can't) run with the MSR_S bit set, but a
secure guest and the ultravisor firmware do.

Signed-off-by: Sukadev Bhattiprolu 
Signed-off-by: Ram Pai 
[Update the commit message]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/reg.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 10caa145f98b..39b4c0a519f5 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -38,6 +38,7 @@
 #define MSR_TM_LG  32  /* Trans Mem Available */
 #define MSR_VEC_LG 25  /* Enable AltiVec */
 #define MSR_VSX_LG 23  /* Enable VSX */
+#define MSR_S_LG   22  /* Secure VM bit */
 #define MSR_POW_LG 18  /* Enable Power Management */
 #define MSR_WE_LG  18  /* Wait State Enable */
 #define MSR_TGPR_LG17  /* TLB Update registers in use */
@@ -71,11 +72,13 @@
 #define MSR_SF __MASK(MSR_SF_LG)   /* Enable 64 bit mode */
 #define MSR_ISF__MASK(MSR_ISF_LG)  /* Interrupt 64b mode 
valid on 630 */
 #define MSR_HV __MASK(MSR_HV_LG)   /* Hypervisor state */
+#define MSR_S  __MASK(MSR_S_LG)/* Secure state */
 #else
 /* so tests for these bits fail on 32-bit */
 #define MSR_SF 0
 #define MSR_ISF0
 #define MSR_HV 0
+#define MSR_S  0
 #endif
 
 /*
-- 
2.20.1



[RFC PATCH v2 01/10] KVM: PPC: Ultravisor: Add PPC_UV config option

2019-05-18 Thread Claudio Carvalho
From: Anshuman Khandual 

CONFIG_PPC_UV adds support for ultravisor.

Signed-off-by: Anshuman Khandual 
Signed-off-by: Bharata B Rao 
Signed-off-by: Ram Pai 
[Update config help and commit message]
Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/Kconfig | 20 
 1 file changed, 20 insertions(+)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2711aac24621..894171c863bc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -438,6 +438,26 @@ config PPC_TRANSACTIONAL_MEM
---help---
  Support user-mode Transactional Memory on POWERPC.
 
+config PPC_UV
+   bool "Ultravisor support"
+   depends on KVM_BOOK3S_HV_POSSIBLE
+   select HMM_MIRROR
+   select HMM
+   select ZONE_DEVICE
+   select MIGRATE_VMA_HELPER
+   select DEV_PAGEMAP_OPS
+   select DEVICE_PRIVATE
+   select MEMORY_HOTPLUG
+   select MEMORY_HOTREMOVE
+   default n
+   help
+ This option paravirtualizes the kernel to run in POWER platforms that
+ supports the Protected Execution Facility (PEF). In such platforms,
+ the ultravisor firmware runs at a privilege level above the
+ hypervisor.
+
+ If unsure, say "N".
+
 config LD_HEAD_STUB_CATCH
bool "Reserve 256 bytes to cope with linker stubs in HEAD text" if 
EXPERT
depends on PPC64
-- 
2.20.1



[RFC PATCH v2 00/10] kvmppc: Paravirtualize KVM to support ultravisor

2019-05-18 Thread Claudio Carvalho
POWER platforms that supports the Protected Execution Facility (PEF)
introduce features that combine hardware facilities and firmware to
enable secure virtual machines. That includes a new processor mode
(ultravisor mode) and the ultravisor firmware.

In PEF enabled systems, the ultravisor firmware runs at a privilege
level above the hypervisor and also takes control over some system
resources. The hypervisor, though, can make system calls to access these
resources. Such system calls, a.k.a. ucalls, are handled by the
ultravisor firmware.

The processor allows part of the system memory to be configured as
secure memory, and introduces a a new mode, called secure mode, where
any software entity in that mode can access secure memory. The
hypervisor doesn't (and can't) run in secure mode, but a secure guest
and the ultravisor firmware do.

This patch set adds support for ultravisor calls and do some preparation
for running secure guests

---
Changelog:
---
v1->v2:
 - Addressed comments from Paul Mackerras:
 - Write the pate in HV's table before doing that in UV's
 - Renamed and better documented the ultravisor header files. Also added
   all possible return codes for each ucall
 - Updated the commit message that introduces the MSR_S bit
 - Moved ultravisor.c and ucall.S to arch/powerpc/kernel
 - Changed ucall.S to not save CR
 - Rebased
 - Changed the patches order
 - Updated several commit messages
 - Added FW_FEATURE_ULTRAVISOR to enable use of firmware_has_feature()
 - Renamed CONFIG_PPC_KVM_UV to CONFIG_PPC_UV and used it to ifdef the ucall
   handler and the code that populates the powerpc_firmware_features for 
   ultravisor
 - Exported the ucall symbol. KVM may be built as module.
 - Restricted LDBAR access if the ultravisor firmware is available
 - Dropped patches:
 "[PATCH 06/13] KVM: PPC: Ultravisor: UV_RESTRICTED_SPR_WRITE ucall"
 "[PATCH 07/13] KVM: PPC: Ultravisor: UV_RESTRICTED_SPR_READ ucall"
 "[PATCH 08/13] KVM: PPC: Ultravisor: fix mtspr and mfspr"
 - Squashed patches:
 "[PATCH 09/13] KVM: PPC: Ultravisor: Return to UV for hcalls from SVM"
 "[PATCH 13/13] KVM: PPC: UV: Have fast_guest_return check secure_guest"

Anshuman Khandual (1):
  KVM: PPC: Ultravisor: Add PPC_UV config option

Claudio Carvalho (1):
  powerpc: Introduce FW_FEATURE_ULTRAVISOR

Michael Anderson (2):
  KVM: PPC: Ultravisor: Use UV_WRITE_PATE ucall to register a PATE
  KVM: PPC: Ultravisor: Check for MSR_S during hv_reset_msr

Paul Mackerras (1):
  KVM: PPC: Book3S HV: Fixed for running secure guests

Ram Pai (3):
  KVM: PPC: Ultravisor: Add generic ultravisor call handler
  KVM: PPC: Ultravisor: Restrict flush of the partition tlb cache
  KVM: PPC: Ultravisor: Restrict LDBAR access

Sukadev Bhattiprolu (2):
  KVM: PPC: Ultravisor: Introduce the MSR_S bit
  KVM: PPC: Ultravisor: Return to UV for hcalls from SVM

 arch/powerpc/Kconfig | 20 ++
 arch/powerpc/include/asm/firmware.h  |  5 +-
 arch/powerpc/include/asm/kvm_host.h  |  1 +
 arch/powerpc/include/asm/reg.h   |  3 +
 arch/powerpc/include/asm/ultravisor-api.h| 24 
 arch/powerpc/include/asm/ultravisor.h| 49 +++
 arch/powerpc/kernel/Makefile |  1 +
 arch/powerpc/kernel/asm-offsets.c|  1 +
 arch/powerpc/kernel/prom.c   |  6 ++
 arch/powerpc/kernel/ucall.S  | 31 ++
 arch/powerpc/kernel/ultravisor.c | 30 +
 arch/powerpc/kvm/book3s_64_mmu_hv.c  |  1 +
 arch/powerpc/kvm/book3s_hv.c |  4 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S  | 40 ++--
 arch/powerpc/mm/book3s64/hash_utils.c|  3 +-
 arch/powerpc/mm/book3s64/pgtable.c   | 65 +++-
 arch/powerpc/mm/book3s64/radix_pgtable.c |  9 ++-
 arch/powerpc/perf/imc-pmu.c  | 64 +++
 arch/powerpc/platforms/powernv/idle.c|  6 +-
 arch/powerpc/platforms/powernv/subcore-asm.S |  4 ++
 20 files changed, 311 insertions(+), 56 deletions(-)
 create mode 100644 arch/powerpc/include/asm/ultravisor-api.h
 create mode 100644 arch/powerpc/include/asm/ultravisor.h
 create mode 100644 arch/powerpc/kernel/ucall.S
 create mode 100644 arch/powerpc/kernel/ultravisor.c

-- 
2.20.1



Re: [PATCH 0/4] Enabling secure boot on PowerNV systems

2019-05-10 Thread Claudio Carvalho
Hi Matthew,

Thanks for the feedback and sorry for the delay in responding.


On 4/10/19 2:36 PM, Matthew Garrett wrote:
> (Cc:ing Peter Jones)
>
> On Tue, Apr 9, 2019 at 3:55 PM Claudio Carvalho  
> wrote:
>>
>> On 4/5/19 7:19 PM, Matthew Garrett wrote:
>>> Based on our experience doing this in UEFI, that's insufficient - you
>>> want to be able to block individual binaries or leaf certificates
>>> without dropping trust in an intermediate certificate entirely.
>>
>> We agree that a dbx would be useful for blacklisting particular kernels
>> signed with given certificate. However, we have been avoiding doing so for
>> the initial release of secure boot on OpenPOWER. We don't have individual
>> firmware binaries in OpenPOWER. Kernels are currently the only concern for
>> the OS secure boot certificates we're discussing here. Also, we have a very
>> limited keystore space in POWER9.
>>
>> Petitboot doesn't have standardized OS kernel verification at all right
>> now.  Having the capability even without dbx seems valuable.
> I don't see the benefit in attempting to maintain compatibility with
> existing tooling unless you're going to be *completely* compatible
> with existing tooling. That means supporting dbx and dbt.


Before addressing that, I'd like to share some of the current OpenPOWER
secure boot design.
Different from UEFI, secure boot in OpenPOWER systems have two distinct
domains. Each one has its own key hierarchy and signing and signature
verification mechanisms.

In the firmware secure boot domain (work already upstream):
 - Every image loaded up to skiroot is wrapped in a secure boot container.
Skiroot is a Linux zimage with petitboot (kexec bootloader) embedded in the
initramfs.
 - Within the secure boot container, the payload image is protected by a
chain of signatures anchored in the root ECDSA keys, also known as hardware
keys.
 - All public keys required to verify the container are stored in the
container itself, but a hash of the trusted public hardware keys is stored
in a protected SEEPROM region outside of the container. Firmware uses it to
check if the container is anchored in the trusted hardware keys. If not,
the container payload is not executed and the boot is aborted.
 - The hash of the hardware keys is set by the firmware supplier, for
instance, the platform manufacturer.

In OS secure boot domain (work in progress):
- The skiroot container is verified as part of firmware secure boot.
- Skiroot uses UEFI-like secure variables (PK, KEK and db) to verify OS
kernels. Only X.509 certificates will be supported for these secure variables.
- OS kernels are signed using the Linux kernel sign-file tool, as if they
were kernel modules.
- In the skiroot kernel, if secure boot is enabled, the db certificates
will be loaded into the platform keyring and IMA-appraisal will verify the
kexec image against the platform keyring.
- The PK is set by whoever controls the platform, for instance, the
manufacturer or the end customer.

How about dbx and dbt?

The db keys will be used to verify only OS kernels via kexecs initiated by
petitboot. So we only need the dbx to revoke kernel images, either via
certs or hashes. Currently, the kernel loads certs and hashes from the dbx
to the system blacklist keyring. The revoked certs are checked during pkcs7
signature verification and loading of keys. However, there doesn't appear
to be any verification against blacklisted hashes. Should kernel images be
revoked only by keys and not hashes? We tried to find published revoked
kernel lists but couldn't find any. How is kernel image revocation handled
in practice?

Also, we didn't see the shim or kernel loading anything from dbt.

In general, how do you think the kernel ought to support blacklists?


>
>>>> The API is still a work in progress.  We are planning to publish a document
>>>> describing the current API and overall design shortly.
>>> Ok. How are the attributes interpreted by the API?
>>
>> We support a subset of standard EFI variable attributes, and we only use
>> EFI variables that relate to secure boot. Our goal is not to implement
>> UEFI.  However, we do seek to be compatible with user space tooling and
>> reuse as much existing infrastructure as possible. We don’t support the
>> following: EFI_VARIABLE_HARDWARE_ERROR_RECORD,
>> EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS and
>> EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS.
> Ok. I think that's realistically fine.
>
>>>> Perhaps the biggest departure is that the secure variables are stored in
>>>> flash memory that is not lockable.  In order to protect the secure
>>>> variables, hashes of the flash regions where they're stored are written to
>>>> TPM NVRAM indices.  The TPM NVRAM indices we use ar

Re: [PATCH 0/4] Enabling secure boot on PowerNV systems

2019-04-09 Thread Claudio Carvalho


On 4/5/19 7:19 PM, Matthew Garrett wrote:
> On Fri, Apr 5, 2019 at 2:11 PM Claudio Carvalho  
> wrote:
>>
>> On 4/3/19 7:27 PM, Matthew Garrett wrote:
>>> Not supporting dbx seems like a pretty significant shortcoming. How
>>> are signatures meant to be revoked?
>>
>> We began by focusing on certificates for keys that can be added at
>> runtime.  Before adding support for revocation, we plan to gather
>> additional use cases.  In the meantime, unwanted certificates can be
>> removed by the administrator.
> Based on our experience doing this in UEFI, that's insufficient - you
> want to be able to block individual binaries or leaf certificates
> without dropping trust in an intermediate certificate entirely.


We agree that a dbx would be useful for blacklisting particular kernels
signed with given certificate. However, we have been avoiding doing so for
the initial release of secure boot on OpenPOWER. We don't have individual
firmware binaries in OpenPOWER. Kernels are currently the only concern for
the OS secure boot certificates we're discussing here. Also, we have a very
limited keystore space in POWER9.

Petitboot doesn't have standardized OS kernel verification at all right
now.  Having the capability even without dbx seems valuable.


>
>>>> PK, KEK and db updates will be signed the same way, that is, using
>>>> userspace tooling like efitools in PowerNV. As for the authentication
>>>> descriptors, only the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be
>>>> supported.
>>> Is this API documented?
>>
>> The API is still a work in progress.  We are planning to publish a document
>> describing the current API and overall design shortly.
> Ok. How are the attributes interpreted by the API?


We support a subset of standard EFI variable attributes, and we only use
EFI variables that relate to secure boot. Our goal is not to implement
UEFI.  However, we do seek to be compatible with user space tooling and
reuse as much existing infrastructure as possible. We don’t support the
following: EFI_VARIABLE_HARDWARE_ERROR_RECORD,
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS and
EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS.


>
>> Perhaps the biggest departure is that the secure variables are stored in
>> flash memory that is not lockable.  In order to protect the secure
>> variables, hashes of the flash regions where they're stored are written to
>> TPM NVRAM indices.  The TPM NVRAM indices we use are write locked at
>> runtime.  The sysadmin enqueues update commands in flash.  During the next
>> boot, the firmware verifies and processes the commands to update the
>> certificate store and accompanying integrity hashes in the TPM NVRAM
>> indices and write locks them.  Before certificates read from flash are
>> used, the certificate store is hashed and compared against the hashes
>> stored from the TPM.  The one exception is the PK. We store it in a TPM
>> NVRAM index by itself rather than flash because updates to it must be
>> guaranteed to be atomic.
> What's the behaviour if multiple updates are enqueued? Does reading
> back show a mocked up updated variable or the original state?


Our secure variable updates are only applied at boot time. If any one of
them fails, they all fail.


>
>>> I think that depends on exactly what problem you're trying to solve.
>>> Some aspects of the EFI secure boot design end up mirroring the
>>> economics of the PC ecosystem rather than being inherently good design
>>> goals, so it'd be helpful to know whether you're taking this solution
>>> because you want the same three-level key infrastructure or because
>>> that just leaves you compatible with the tooling.
>>
>> In our use case,  the three-level key hierarchy conveniently supports the
>> concept of (1) an administrator authority, who authorizes (2) other
>> organizations, e.g., distros, to provide (3) certificates for their code
>> signing keys.   By using efivars, we leverage pre-existing userspace EFI
>> tools to generate authenticated updates and certificates.  Additionally,
>> pre-existing kernel infrastructure simplifies efivars processing.
> I'm not really clear on the workflow here. Who's the administrator
> authority? When would they be updating the second level of keys? If
> there's no support for revocation, why would distributions need two
> levels of key in the system database rather than just distributing a
> single intermediate and signing their actual signing certs with that?


In OpenPOWER systems, we enable our customers and business partners to
establish and manage the platform key certificate, which is the root of our
key hierarchy. From there, through the KEK, they can delegate authority to
intermediate level organizations, e.g. distros or IT departments or
business operations. Those intermediate level organizations then manage the
code signing certificates in the DB. If this answer doesn’t address your
question, can you please rephrase?


Thanks,
Claudio



Re: [PATCH 0/4] Enabling secure boot on PowerNV systems

2019-04-05 Thread Claudio Carvalho


On 4/3/19 7:27 PM, Matthew Garrett wrote:
> On Tue, Apr 2, 2019 at 4:31 PM Claudio Carvalho  
> wrote:
>>
>> On 4/2/19 6:51 PM, Matthew Garrett wrote:
>>> So you implement the full PK/KEK/db/dbx/dbt infrastructure, and
>>> updates are signed in the same way?
>> For the first version, our firmware will implement a simplistic PK, KEK and
>> db infrastructure (without dbx and dbt) where only the Setup and User modes
>> will be supported.
> Not supporting dbx seems like a pretty significant shortcoming. How
> are signatures meant to be revoked?


We began by focusing on certificates for keys that can be added at
runtime.  Before adding support for revocation, we plan to gather
additional use cases.  In the meantime, unwanted certificates can be
removed by the administrator.


>
>> PK, KEK and db updates will be signed the same way, that is, using
>> userspace tooling like efitools in PowerNV. As for the authentication
>> descriptors, only the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be
>> supported.
> Is this API documented?


The API is still a work in progress.  We are planning to publish a document
describing the current API and overall design shortly.

Perhaps the biggest departure is that the secure variables are stored in
flash memory that is not lockable.  In order to protect the secure
variables, hashes of the flash regions where they're stored are written to
TPM NVRAM indices.  The TPM NVRAM indices we use are write locked at
runtime.  The sysadmin enqueues update commands in flash.  During the next
boot, the firmware verifies and processes the commands to update the
certificate store and accompanying integrity hashes in the TPM NVRAM
indices and write locks them.  Before certificates read from flash are
used, the certificate store is hashed and compared against the hashes
stored from the TPM.  The one exception is the PK. We store it in a TPM
NVRAM index by itself rather than flash because updates to it must be
guaranteed to be atomic.


>>> In that case we might be better off with a generic interface for this
>>> purpose that we can expose on all platforms that implement a secure
>>> boot key hierarchy. Having an efivarfs that doesn't allow the creation
>>> of arbitrary attributes may break other existing userland
>>> expectations.
>>>
>> For what it's worth, gsmi uses the efivars infrastructure for EFI-like
>> variables.
> My recollection is that at the time the Chromebook firmware still had
> EFI underpinnings and the gsmi code was largely just an alternate
> mechanism for calling into something that was fundamentally the EFI
> variable store. With hindsight I don't think layering this was the
> right move - we've adjusted the semantics of efivarfs on more than one
> occasion to deal with the behaviour of real-world EFI platforms, and I
> don't think it's helpful to end up in a situation where we're trying
> to keep behaviour consistent among entirely different firmware
> interfaces.
>
>> What might a generic interface look like?  It would have to work for
>> existing secure boot solutions - including EFI - which would seem to imply
>> changes to userspace tools.
> I think that depends on exactly what problem you're trying to solve.
> Some aspects of the EFI secure boot design end up mirroring the
> economics of the PC ecosystem rather than being inherently good design
> goals, so it'd be helpful to know whether you're taking this solution
> because you want the same three-level key infrastructure or because
> that just leaves you compatible with the tooling.


In our use case,  the three-level key hierarchy conveniently supports the
concept of (1) an administrator authority, who authorizes (2) other
organizations, e.g., distros, to provide (3) certificates for their code
signing keys.   By using efivars, we leverage pre-existing userspace EFI
tools to generate authenticated updates and certificates.  Additionally,
pre-existing kernel infrastructure simplifies efivars processing.  


Thanks,
Claudio



Re: [PATCH 0/4] Enabling secure boot on PowerNV systems

2019-04-03 Thread Claudio Carvalho


On 4/3/19 10:21 AM, Michael Ellerman wrote:
> Hi Claudio,
>
> Thanks for posting this.
>
> Claudio Carvalho  writes:
>> This patch set is part of a series that implements secure boot on
>> PowerNV systems.
>>
>> In order to verify the OS kernel on PowerNV, secure boot requires X.509
>> certificates trusted by the platform, the secure boot modes, and several
>> other pieces of information. These are stored in secure variables
>> controlled by OPAL, also known as OPAL secure variables.
>>
>> This patch set adds the following features:
>>
>> 1. Enable efivarfs by selecting CONFIG_EFI in the CONFIG_OPAL_SECVAR
>>introduced in this patch set. With CONFIG_EFIVAR_FS, userspace tools can
>>be used to manage the secure variables.
>> 2. Add support for OPAL secure variables by overwriting the EFI hooks
>>(get_variable, get_next_variable, set_variable and query_variable_info)
>>with OPAL call wrappers. There is probably a better way to add this
>>support, for example, we are investigating if we could register the
>>efivar_operations rather than overwriting the EFI hooks. In this patch
>>set, CONFIG_OPAL_SECVAR selects CONFIG_EFI. If, instead, we registered
>>efivar_operations, CONFIG_EFIVAR_FS would need to depend on
>>CONFIG_EFI|| CONFIG_OPAL_SECVAR. Comments or suggestions on the
>>preferred technique would be greatly appreciated.
> I am *very* reluctant to start selecting CONFIG_EFI on powerpc.
>
> Simply because we don't actually have EFI, and I worry we're going to
> both break assumptions in the EFI code as well as impose requirements on
> the powerpc code that aren't really necessary.

Yes, we agree. We are working on the v2 and it is not going to depend on
CONFIG_EFI. Rather, the IMA arch policies will make the OPAL calls directly.


>
> So I'd definitely prefer we go the route of enabling efivarfs with an
> alternate backend.

Right, I'm investigating how we can do that, but it looks like we should
post that as a separate patchset to avoid delaying upstreaming signature
verification based on the secure boot variables.

Thanks,
Claudio


>
> Better still would be a generic secure variable interface as Matt
> suggests, if the userspace tools can be relatively easily adapted to use
> that interface.
>
> cheers
>



Re: [PATCH 0/4] Enabling secure boot on PowerNV systems

2019-04-02 Thread Claudio Carvalho


On 4/2/19 6:51 PM, Matthew Garrett wrote:
> On Tue, Apr 2, 2019 at 2:11 PM Claudio Carvalho  
> wrote:
>> We want to use the efivarfs for compatibility with existing userspace
>> tools. We will track and match any EFI changes that affect us.
> So you implement the full PK/KEK/db/dbx/dbt infrastructure, and
> updates are signed in the same way?

For the first version, our firmware will implement a simplistic PK, KEK and
db infrastructure (without dbx and dbt) where only the Setup and User modes
will be supported.

PK, KEK and db updates will be signed the same way, that is, using
userspace tooling like efitools in PowerNV. As for the authentication
descriptors, only the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be
supported.


>> Our use case is restricted to secure boot - this is not going to be a
>> general purpose EFI variable implementation.
> In that case we might be better off with a generic interface for this
> purpose that we can expose on all platforms that implement a secure
> boot key hierarchy. Having an efivarfs that doesn't allow the creation
> of arbitrary attributes may break other existing userland
> expectations.
>
For what it's worth, gsmi uses the efivars infrastructure for EFI-like
variables.

What might a generic interface look like?  It would have to work for
existing secure boot solutions - including EFI - which would seem to imply
changes to userspace tools.

Claudio




Re: [PATCH 0/4] Enabling secure boot on PowerNV systems

2019-04-02 Thread Claudio Carvalho


On 4/2/19 4:36 PM, Matthew Garrett wrote:
> On Tue, Apr 2, 2019 at 11:15 AM Claudio Carvalho  
> wrote:
>> 1. Enable efivarfs by selecting CONFIG_EFI in the CONFIG_OPAL_SECVAR
>>introduced in this patch set. With CONFIG_EFIVAR_FS, userspace tools can
>>be used to manage the secure variables.
> efivarfs has some pretty significant behavioural semantics that
> directly reflect the EFI specification. Using it to expose non-EFI
> variable data feels like it's going to increase fragility - there's a
> risk that we'll change things in a way that makes sense for the EFI
> spec but breaks your use case. Is the desire to use efivarfs to
> maintain consistency with existing userland tooling, or just to avoid
> having a separate filesystem?
>
We want to use the efivarfs for compatibility with existing userspace
tools. We will track and match any EFI changes that affect us.

Our use case is restricted to secure boot - this is not going to be a
general purpose EFI variable implementation.

Claudio




[PATCH 4/4] powerpc: Add support to initialize ima policy rules

2019-04-02 Thread Claudio Carvalho
From: Nayna Jain 

PowerNV secure boot relies on the kernel IMA security subsystem to
perform the OS kernel image signature verification. Since each secure
boot mode has different IMA policy requirements, dynamic definition of
the policy rules based on the runtime secure boot mode of the system is
required. On systems that support secure boot, but have it disabled,
only measurement policy rules of the kernel image and modules are
defined.

This patch defines the arch-specific implementation to retrieve the
secure boot mode of the system and accordingly configures the IMA policy
rules.

This patch will provide arch-specific IMA policies if PPC_SECURE_BOOT
config is enabled.

Signed-off-by: Nayna Jain 
---
 arch/powerpc/Kconfig   | 12 
 arch/powerpc/kernel/Makefile   |  1 +
 arch/powerpc/kernel/ima_arch.c | 54 ++
 include/linux/ima.h|  3 +-
 4 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/kernel/ima_arch.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2d0be82c3061..e0ba9a9114b3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -901,6 +901,18 @@ config PPC_MEM_KEYS
 
  If unsure, say y.
 
+config PPC_SECURE_BOOT
+   prompt "Enable PowerPC Secure Boot"
+   bool
+   default n
+   depends on IMA
+   depends on IMA_ARCH_POLICY
+   help
+ Linux on POWER with firmware secure boot enabled needs to define
+ security policies to extend secure boot to the OS.
+ This config allows user to enable OS Secure Boot on PowerPC systems
+ that have firmware secure boot support.
+
 endmenu
 
 config ISA_DMA_API
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index cddadccf551d..0f08ed7dfd1b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -119,6 +119,7 @@ ifdef CONFIG_IMA
 obj-y  += ima_kexec.o
 endif
 endif
+obj-$(CONFIG_IMA)  += ima_arch.o
 
 obj-$(CONFIG_AUDIT)+= audit.o
 obj64-$(CONFIG_AUDIT)  += compat_audit.o
diff --git a/arch/powerpc/kernel/ima_arch.c b/arch/powerpc/kernel/ima_arch.c
new file mode 100644
index ..871b321656fb
--- /dev/null
+++ b/arch/powerpc/kernel/ima_arch.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 IBM Corporation
+ * Author: Nayna Jain 
+ *
+ * ima_arch.c
+ *  - initialize ima policies for PowerPC Secure Boot
+ */
+
+#include 
+#include 
+
+bool arch_ima_get_secureboot(void)
+{
+   bool sb_mode;
+
+   sb_mode = get_powerpc_sb_mode();
+   if (sb_mode)
+   return true;
+   else
+   return false;
+}
+
+/*
+ * File signature verification is not needed, include only measurements
+ */
+static const char *const default_arch_rules[] = {
+   "measure func=KEXEC_KERNEL_CHECK",
+   "measure func=MODULE_CHECK",
+   NULL
+};
+
+/* Both file signature verification and measurements are needed */
+static const char *const sb_arch_rules[] = {
+   "measure func=KEXEC_KERNEL_CHECK",
+   "measure func=MODULE_CHECK",
+   "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig",
+#if !IS_ENABLED(CONFIG_MODULE_SIG)
+   "appraise func=MODULE_CHECK appraise_type=imasig",
+#endif
+   NULL
+};
+
+/*
+ * On PowerPC, file measurements are to be added to the IMA measurement list
+ * irrespective of the secure boot state of the system. Signature verification
+ * is conditionally enabled based on the secure boot state.
+ */
+const char *const *arch_get_ima_policy(void)
+{
+   if (IS_ENABLED(CONFIG_IMA_ARCH_POLICY) && arch_ima_get_secureboot())
+   return sb_arch_rules;
+   return default_arch_rules;
+}
diff --git a/include/linux/ima.h b/include/linux/ima.h
index dc12fbcf484c..32f46d69ebd7 100644
--- a/include/linux/ima.h
+++ b/include/linux/ima.h
@@ -31,7 +31,8 @@ extern void ima_post_path_mknod(struct dentry *dentry);
 extern void ima_add_kexec_buffer(struct kimage *image);
 #endif
 
-#if defined(CONFIG_X86) && defined(CONFIG_EFI)
+#if defined(CONFIG_X86) && defined(CONFIG_EFI) \
+   || defined(CONFIG_PPC_SECURE_BOOT)
 extern bool arch_ima_get_secureboot(void);
 extern const char * const *arch_get_ima_policy(void);
 #else
-- 
2.20.1



[PATCH 3/4] powerpc/powernv: Detect the secure boot mode of the system

2019-04-02 Thread Claudio Carvalho
From: Nayna Jain 

PowerNV secure boot defines different IMA policies based on the secure
boot state of the system.

This patch defines a function to detect the secure boot state of the
system.

Signed-off-by: Nayna Jain 
---
 arch/powerpc/include/asm/secboot.h   | 21 +
 arch/powerpc/platforms/powernv/Makefile  |  2 +-
 arch/powerpc/platforms/powernv/secboot.c | 54 
 3 files changed, 76 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/include/asm/secboot.h
 create mode 100644 arch/powerpc/platforms/powernv/secboot.c

diff --git a/arch/powerpc/include/asm/secboot.h 
b/arch/powerpc/include/asm/secboot.h
new file mode 100644
index ..1904fb4a3352
--- /dev/null
+++ b/arch/powerpc/include/asm/secboot.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PowerPC secure boot definitions
+ *
+ * Copyright (C) 2019 IBM Corporation
+ * Author: Nayna Jain 
+ *
+ */
+#ifndef POWERPC_SECBOOT_H
+#define POWERPC_SECBOOT_H
+
+#if defined(CONFIG_OPAL_SECVAR)
+extern bool get_powerpc_sb_mode(void);
+#else
+static inline bool get_powerpc_sb_mode(void)
+{
+   return false;
+}
+#endif
+
+#endif
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index 1511d836fd19..a36e22f8ecf8 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -16,4 +16,4 @@ obj-$(CONFIG_PERF_EVENTS) += opal-imc.o
 obj-$(CONFIG_PPC_MEMTRACE) += memtrace.o
 obj-$(CONFIG_PPC_VAS)  += vas.o vas-window.o vas-debug.o
 obj-$(CONFIG_OCXL_BASE)+= ocxl.o
-obj-$(CONFIG_OPAL_SECVAR)  += opal-secvar.o
+obj-$(CONFIG_OPAL_SECVAR)  += opal-secvar.o secboot.o
diff --git a/arch/powerpc/platforms/powernv/secboot.c 
b/arch/powerpc/platforms/powernv/secboot.c
new file mode 100644
index ..afb1552636c5
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/secboot.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 IBM Corporation
+ * Author: Nayna Jain 
+ *
+ * secboot.c
+ *  - util functions to get powerpc secboot state
+ *
+ */
+#include 
+#include 
+
+bool get_powerpc_sb_mode(void)
+{
+   efi_char16_t efi_SecureBoot_name[] = L"SecureBoot";
+   efi_char16_t efi_SetupMode_name[] = L"SetupMode";
+   efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
+   efi_status_t status;
+   u8 secboot, setupmode;
+   unsigned long size = sizeof(secboot);
+
+   status = efi.get_variable(efi_SecureBoot_name, _variable_guid,
+ NULL, , );
+
+   /*
+* For now assume all failures reading the SecureBoot variable implies
+* secure boot is not enabled. Later differentiate failure types.
+*/
+   if (status != EFI_SUCCESS) {
+   secboot = 0;
+   setupmode = 0;
+   goto out;
+   }
+
+   size = sizeof(setupmode);
+   status = efi.get_variable(efi_SetupMode_name, _variable_guid,
+ NULL, , );
+
+   /*
+* Failure to read the SetupMode variable does not prevent
+* secure boot mode
+*/
+   if (status != EFI_SUCCESS)
+   setupmode = 0;
+
+out:
+   if ((secboot == 0) || (setupmode == 1)) {
+   pr_info("ima: secureboot mode disabled\n");
+   return false;
+   }
+
+   pr_info("ima: secureboot mode enabled\n");
+   return true;
+}
-- 
2.20.1



[PATCH 2/4] powerpc/powernv: Add support for OPAL secure variables

2019-04-02 Thread Claudio Carvalho
The X.509 certificates trusted by the platform and other information
required to secure boot the host OS kernel are wrapped in secure
variables, which are controlled by OPAL.

The OPAL secure variables can be handled through the following OPAL
calls.

OPAL_SECVAR_GET:
Returns the data for a given secure variable name and vendor GUID.

OPAL_SECVAR_GET_NEXT:
For a given secure variable, it returns the name and vendor GUID
of the next variable.

OPAL_SECVAR_ENQUEUE:
Enqueue the supplied secure variable update so that it can be processed
by OPAL in the next boot. Variable updates cannot be be processed right
away because the variable storage is write locked at runtime.

OPAL_SECVAR_INFO:
Returns size information about the variable.

This patch adds support for OPAL secure variables by setting up the EFI
runtime variable services to make OPAL calls.

This patch also introduces CONFIG_OPAL_SECVAR for enabling the OPAL
secure variables support in the kernel. Since CONFIG_OPAL_SECVAR selects
CONFIG_EFI, it also allow us to manage the OPAL secure variables from
userspace via efivarfs.

Signed-off-by: Claudio Carvalho 
---
This patch depends on new OPAL calls that are being added to skiboot.
The patch set that implements the new calls has been posted to
https://patchwork.ozlabs.org/project/skiboot/list/?series=99805
---
 arch/powerpc/include/asm/opal-api.h  |   6 +-
 arch/powerpc/include/asm/opal.h  |  10 ++
 arch/powerpc/platforms/Kconfig   |   3 +
 arch/powerpc/platforms/powernv/Kconfig   |   9 +
 arch/powerpc/platforms/powernv/Makefile  |   1 +
 arch/powerpc/platforms/powernv/opal-call.c   |   4 +
 arch/powerpc/platforms/powernv/opal-secvar.c | 179 +++
 7 files changed, 211 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/platforms/powernv/opal-secvar.c

diff --git a/arch/powerpc/include/asm/opal-api.h 
b/arch/powerpc/include/asm/opal-api.h
index 870fb7b239ea..d3066f29cb7a 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -210,7 +210,11 @@
 #define OPAL_PCI_GET_PBCQ_TUNNEL_BAR   164
 #define OPAL_PCI_SET_PBCQ_TUNNEL_BAR   165
 #defineOPAL_NX_COPROC_INIT 167
-#define OPAL_LAST  167
+#define OPAL_SECVAR_GET170
+#define OPAL_SECVAR_GET_NEXT   171
+#define OPAL_SECVAR_ENQUEUE172
+#define OPAL_SECVAR_INFO   173
+#define OPAL_LAST  173
 
 #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 a55b01c90bb1..fdfd8dd7b326 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -385,6 +385,16 @@ void opal_powercap_init(void);
 void opal_psr_init(void);
 void opal_sensor_groups_init(void);
 
+extern int opal_secvar_get(uint64_t name, uint64_t vendor, uint64_t attr,
+  uint64_t data_size, uint64_t data);
+extern int opal_secvar_get_next(uint64_t name_size, uint64_t name,
+   uint64_t vendor);
+extern int opal_secvar_enqueue(uint64_t name, uint64_t vendor, uint64_t attr,
+  uint64_t data_size, uint64_t data);
+extern int opal_secvar_info(uint64_t attr, uint64_t storage_space,
+   uint64_t remaining_space,
+   uint64_t max_variable_size);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_OPAL_H */
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index f3fb79fccc72..8e30510bc0c1 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -326,4 +326,7 @@ config XILINX_PCI
bool "Xilinx PCI host bridge support"
depends on PCI && XILINX_VIRTEX
 
+config EFI
+   bool
+
 endmenu
diff --git a/arch/powerpc/platforms/powernv/Kconfig 
b/arch/powerpc/platforms/powernv/Kconfig
index 850eee860cf2..879f8e766098 100644
--- a/arch/powerpc/platforms/powernv/Kconfig
+++ b/arch/powerpc/platforms/powernv/Kconfig
@@ -47,3 +47,12 @@ config PPC_VAS
  VAS adapters are found in POWER9 based systems.
 
  If unsure, say N.
+
+config OPAL_SECVAR
+   bool "OPAL Secure Variables"
+   depends on PPC_POWERNV && !CPU_BIG_ENDIAN
+   select UCS2_STRING
+   select EFI
+   help
+ This enables the kernel to access OPAL secure variables via EFI
+ runtime variable services.
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index da2e99efbd04..1511d836fd19 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_PERF_EVENTS) += opal-imc.o
 obj-$(CONFIG_

[PATCH 1/4] powerpc/include: Override unneeded early ioremap functions

2019-04-02 Thread Claudio Carvalho
When CONFIG_EFI is enabled, the EFI driver includes the generic
early_ioremap header, which assumes that architectures may want to
provide their own early ioremap functions.

This patch overrides the ioremap functions in powerpc because they are
not required for secure boot on powerpc systems.

Signed-off-by: Claudio Carvalho 
---
 arch/powerpc/include/asm/early_ioremap.h | 41 
 1 file changed, 41 insertions(+)
 create mode 100644 arch/powerpc/include/asm/early_ioremap.h

diff --git a/arch/powerpc/include/asm/early_ioremap.h 
b/arch/powerpc/include/asm/early_ioremap.h
new file mode 100644
index ..a86a06e9f3b9
--- /dev/null
+++ b/arch/powerpc/include/asm/early_ioremap.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Early ioremap definitions
+ *
+ * Copyright (C) 2019 IBM Corporation
+ * Author: Claudio Carvalho 
+ *
+ */
+#ifndef _ASM_POWERPC_EARLY_IOREMAP_H
+#define _ASM_POWERPC_EARLY_IOREMAP_H
+
+static inline void __iomem *early_ioremap(resource_size_t phys_addr,
+ unsigned long size)
+{
+   return NULL;
+}
+
+static inline void *early_memremap(resource_size_t phys_addr,
+  unsigned long size)
+{
+   return NULL;
+}
+
+static inline void *early_memremap_ro(resource_size_t phys_addr,
+ unsigned long size)
+{
+   return NULL;
+}
+
+static inline void *early_memremap_prot(resource_size_t phys_addr,
+   unsigned long size,
+   unsigned long prot_val)
+{
+   return NULL;
+}
+
+static inline void early_iounmap(void __iomem *addr, unsigned long size) { }
+static inline void early_memunmap(void *addr, unsigned long size) { }
+static inline void early_ioremap_shutdown(void) { }
+
+#endif
-- 
2.20.1



[PATCH 0/4] Enabling secure boot on PowerNV systems

2019-04-02 Thread Claudio Carvalho
This patch set is part of a series that implements secure boot on
PowerNV systems.

In order to verify the OS kernel on PowerNV, secure boot requires X.509
certificates trusted by the platform, the secure boot modes, and several
other pieces of information. These are stored in secure variables
controlled by OPAL, also known as OPAL secure variables.

This patch set adds the following features:

1. Enable efivarfs by selecting CONFIG_EFI in the CONFIG_OPAL_SECVAR
   introduced in this patch set. With CONFIG_EFIVAR_FS, userspace tools can
   be used to manage the secure variables.
2. Add support for OPAL secure variables by overwriting the EFI hooks
   (get_variable, get_next_variable, set_variable and query_variable_info)
   with OPAL call wrappers. There is probably a better way to add this
   support, for example, we are investigating if we could register the
   efivar_operations rather than overwriting the EFI hooks. In this patch
   set, CONFIG_OPAL_SECVAR selects CONFIG_EFI. If, instead, we registered
   efivar_operations, CONFIG_EFIVAR_FS would need to depend on
   CONFIG_EFI|| CONFIG_OPAL_SECVAR. Comments or suggestions on the
   preferred technique would be greatly appreciated.
3. Define IMA arch-specific policies based on the secure boot state and
   mode of the system. On secure boot enabled powernv systems, the host OS
   kernel signature will be verified by IMA appraisal.

Claudio Carvalho (2):
  powerpc/include: Override unneeded early ioremap functions
  powerpc/powernv: Add support for OPAL secure variables

Nayna Jain (2):
  powerpc/powernv: Detect the secure boot mode of the system
  powerpc: Add support to initialize ima policy rules

 arch/powerpc/Kconfig |  12 ++
 arch/powerpc/include/asm/early_ioremap.h |  41 +
 arch/powerpc/include/asm/opal-api.h  |   6 +-
 arch/powerpc/include/asm/opal.h  |  10 ++
 arch/powerpc/include/asm/secboot.h   |  21 +++
 arch/powerpc/kernel/Makefile |   1 +
 arch/powerpc/kernel/ima_arch.c   |  54 ++
 arch/powerpc/platforms/Kconfig   |   3 +
 arch/powerpc/platforms/powernv/Kconfig   |   9 +
 arch/powerpc/platforms/powernv/Makefile  |   1 +
 arch/powerpc/platforms/powernv/opal-call.c   |   4 +
 arch/powerpc/platforms/powernv/opal-secvar.c | 179 +++
 arch/powerpc/platforms/powernv/secboot.c |  54 ++
 include/linux/ima.h  |   3 +-
 14 files changed, 396 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/include/asm/early_ioremap.h
 create mode 100644 arch/powerpc/include/asm/secboot.h
 create mode 100644 arch/powerpc/kernel/ima_arch.c
 create mode 100644 arch/powerpc/platforms/powernv/opal-secvar.c
 create mode 100644 arch/powerpc/platforms/powernv/secboot.c

-- 
2.20.1



[PATCH] powerpc/powernv: Fix no return statement issue in __opal_call_trace()

2019-03-08 Thread Claudio Carvalho
Commit 75d9fc7fd94e ("powerpc/powernv: move OPAL call wrapper tracing and
interrupt handling to C") adds the function:

static s64 __opal_call_trace(s64 a0, s64 a1, s64 a2, s64 a3,
 s64 a4, s64 a5, s64 a6, s64 a7,
  unsigned long opcode, unsigned long msr)
{
}

However, that causes the following compilation error:

$ make skiroot_defconfig
$ make -j$(nproc)
...
arch/powerpc/platforms/powernv/opal-call.c: In function
‘__opal_call_trace’:
arch/powerpc/platforms/powernv/opal-call.c:89:1: error: no return
statement in function returning non-void [-Werror=return-type]

This patch fixes the issue by returning zero as suggested by the author
of the commit.

Fixes: 75d9fc7fd94e ("powerpc/powernv: move OPAL call wrapper tracing and 
interrupt handling to C")
Signed-off-by: Claudio Carvalho 
CC: Nicholas Piggin 
---
 arch/powerpc/platforms/powernv/opal-call.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/powerpc/platforms/powernv/opal-call.c 
b/arch/powerpc/platforms/powernv/opal-call.c
index 578757d..daad8c4 100644
--- a/arch/powerpc/platforms/powernv/opal-call.c
+++ b/arch/powerpc/platforms/powernv/opal-call.c
@@ -86,6 +86,7 @@ static s64 __opal_call_trace(s64 a0, s64 a1, s64 a2, s64 a3,
 s64 a4, s64 a5, s64 a6, s64 a7,
  unsigned long opcode, unsigned long msr)
 {
+   return 0;
 }
 
 #define DO_TRACE false
-- 
2.7.4