All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/3] s390x: css: adapting the I/O tests for PV
@ 2020-08-31 12:05 Pierre Morel
  2020-08-31 12:05 ` [PATCH v1 1/3] s390x: pv: implement routine to share/unshare memory Pierre Morel
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Pierre Morel @ 2020-08-31 12:05 UTC (permalink / raw)
  To: kvm; +Cc: linux-s390, frankja, david, thuth, cohuck

To adapt the test for PV we need to share the I/O memory with the host.

To do so we:
- implement the share/unshare ultravisor code.
- implement dedicated allocation routine which make sure that
  - the I/O memory is on dedicated pages
  - the I/O memory is shared if the guest is run under PV
- replace the start_single_ccw() by ccw_alloc() and start the
  start_ccw1_chain() directly from the test function.
  This allows to correctly free the I/O memory after the interruption.

Best regards,
Pierre

Pierre Morel (3):
  s390x: pv: implement routine to share/unshare memory
  s390: define UV compatible I/O allocation
  s390x: css: pv: css test adaptation for PV

 lib/s390x/asm/uv.h    | 33 +++++++++++++++++++++++++++
 lib/s390x/css.h       |  3 +--
 lib/s390x/css_lib.c   | 28 +++++++----------------
 lib/s390x/malloc_io.c | 53 +++++++++++++++++++++++++++++++++++++++++++
 lib/s390x/malloc_io.h | 14 ++++++++++++
 s390x/Makefile        |  1 +
 s390x/css.c           | 35 +++++++++++++++++++---------
 7 files changed, 134 insertions(+), 33 deletions(-)
 create mode 100644 lib/s390x/malloc_io.c
 create mode 100644 lib/s390x/malloc_io.h

-- 
2.25.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v1 1/3] s390x: pv: implement routine to share/unshare memory
  2020-08-31 12:05 [PATCH v1 0/3] s390x: css: adapting the I/O tests for PV Pierre Morel
@ 2020-08-31 12:05 ` Pierre Morel
  2020-08-31 12:05 ` [PATCH v1 2/3] s390: define UV compatible I/O allocation Pierre Morel
  2020-08-31 12:05 ` [PATCH v1 3/3] s390x: css: pv: css test adaptation for PV Pierre Morel
  2 siblings, 0 replies; 6+ messages in thread
From: Pierre Morel @ 2020-08-31 12:05 UTC (permalink / raw)
  To: kvm; +Cc: linux-s390, frankja, david, thuth, cohuck

When communicating with the host we need to share part of
the memory.

Let's implement the ultravisor calls for this.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
Suggested-by: Janosch Frank <frankja@linux.ibm.com>
---
 lib/s390x/asm/uv.h | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/lib/s390x/asm/uv.h b/lib/s390x/asm/uv.h
index 4c2fc48..19019e4 100644
--- a/lib/s390x/asm/uv.h
+++ b/lib/s390x/asm/uv.h
@@ -71,4 +71,37 @@ static inline int uv_call(unsigned long r1, unsigned long r2)
 	return cc;
 }
 
+static inline int share(unsigned long addr, u16 cmd)
+{
+	struct uv_cb_share uvcb = {
+		.header.cmd = cmd,
+		.header.len = sizeof(uvcb),
+		.paddr = addr
+	};
+
+	uv_call(0, (u64)&uvcb);
+	return uvcb.header.rc;
+}
+
+/*
+ * Guest 2 request to the Ultravisor to make a page shared with the
+ * hypervisor for IO.
+ *
+ * @addr: Real or absolute address of the page to be shared
+ */
+static inline int uv_set_shared(unsigned long addr)
+{
+	return share(addr, UVC_CMD_SET_SHARED_ACCESS);
+}
+
+/*
+ * Guest 2 request to the Ultravisor to make a page unshared.
+ *
+ * @addr: Real or absolute address of the page to be unshared
+ */
+static inline int uv_remove_shared(unsigned long addr)
+{
+	return share(addr, UVC_CMD_REMOVE_SHARED_ACCESS);
+}
+
 #endif
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1 2/3] s390: define UV compatible I/O allocation
  2020-08-31 12:05 [PATCH v1 0/3] s390x: css: adapting the I/O tests for PV Pierre Morel
  2020-08-31 12:05 ` [PATCH v1 1/3] s390x: pv: implement routine to share/unshare memory Pierre Morel
@ 2020-08-31 12:05 ` Pierre Morel
  2020-09-11 12:40   ` Cornelia Huck
  2020-08-31 12:05 ` [PATCH v1 3/3] s390x: css: pv: css test adaptation for PV Pierre Morel
  2 siblings, 1 reply; 6+ messages in thread
From: Pierre Morel @ 2020-08-31 12:05 UTC (permalink / raw)
  To: kvm; +Cc: linux-s390, frankja, david, thuth, cohuck

To centralize the memory allocation for I/O we define
the alloc/free_io_page() functions which share the I/O
memory with the host in case the guest runs with
protected virtualization.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
 lib/s390x/malloc_io.c | 53 +++++++++++++++++++++++++++++++++++++++++++
 lib/s390x/malloc_io.h | 14 ++++++++++++
 s390x/Makefile        |  1 +
 3 files changed, 68 insertions(+)
 create mode 100644 lib/s390x/malloc_io.c
 create mode 100644 lib/s390x/malloc_io.h

diff --git a/lib/s390x/malloc_io.c b/lib/s390x/malloc_io.c
new file mode 100644
index 0000000..0e67aab
--- /dev/null
+++ b/lib/s390x/malloc_io.c
@@ -0,0 +1,53 @@
+/*
+ * I/O page allocation
+ *
+ * Copyright (c) 2020 IBM Corp
+ *
+ * Authors:
+ *  Pierre Morel <pmorel@linux.ibm.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2.
+ *
+ * Using this interface provide host access to the allocated pages in
+ * case the guest is a secure guest.
+ * This is needed for I/O buffers.
+ *
+ */
+
+#include <libcflat.h>
+#include <alloc_page.h>
+#include <asm/page.h>
+#include <asm/uv.h>
+#include <malloc_io.h>
+#include <asm/facility.h>
+
+
+void *alloc_io_page(int size)
+{
+	void *p;
+
+	assert(size <= PAGE_SIZE);
+	p = alloc_page();
+	if (!p) {
+		report(0, "Memory allocation");
+		return NULL;
+	}
+
+	if (!test_facility(158))
+		return p;
+
+	if (!uv_set_shared((unsigned long)p)) {
+		report(0, "Sharing memory");
+		return NULL;
+	}
+
+	return p;
+}
+
+void free_io_page(void *p)
+{
+	if (test_facility(158) && !uv_remove_shared((unsigned long)p))
+		report(0, "Unsharing memory");
+	free_page(p);
+}
diff --git a/lib/s390x/malloc_io.h b/lib/s390x/malloc_io.h
new file mode 100644
index 0000000..6916f55
--- /dev/null
+++ b/lib/s390x/malloc_io.h
@@ -0,0 +1,14 @@
+/*
+ * I/O allocations
+ *
+ * Copyright (c) 2020 IBM Corp
+ *
+ * Authors:
+ *  Pierre Morel <pmorel@linux.ibm.com>
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2.
+ */
+
+void *alloc_io_page(int size);
+void free_io_page(void *p);
diff --git a/s390x/Makefile b/s390x/Makefile
index 9144d57..f545597 100644
--- a/s390x/Makefile
+++ b/s390x/Makefile
@@ -62,6 +62,7 @@ cflatobjs += lib/s390x/smp.o
 cflatobjs += lib/s390x/vm.o
 cflatobjs += lib/s390x/css_dump.o
 cflatobjs += lib/s390x/css_lib.o
+cflatobjs += lib/s390x/malloc_io.o
 
 OBJDIRS += lib/s390x
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1 3/3] s390x: css: pv: css test adaptation for PV
  2020-08-31 12:05 [PATCH v1 0/3] s390x: css: adapting the I/O tests for PV Pierre Morel
  2020-08-31 12:05 ` [PATCH v1 1/3] s390x: pv: implement routine to share/unshare memory Pierre Morel
  2020-08-31 12:05 ` [PATCH v1 2/3] s390: define UV compatible I/O allocation Pierre Morel
@ 2020-08-31 12:05 ` Pierre Morel
  2 siblings, 0 replies; 6+ messages in thread
From: Pierre Morel @ 2020-08-31 12:05 UTC (permalink / raw)
  To: kvm; +Cc: linux-s390, frankja, david, thuth, cohuck

We want the tests to automatically work with or without protected
virtualisation.
To do this we need to share the I/O memory with the host.

Let's replace all static allocations with dynamic allocations
to clearly separate shared and private memory.

Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
---
 lib/s390x/css.h     |  3 +--
 lib/s390x/css_lib.c | 28 ++++++++--------------------
 s390x/css.c         | 35 ++++++++++++++++++++++++-----------
 3 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/lib/s390x/css.h b/lib/s390x/css.h
index 221b67c..e3dee9f 100644
--- a/lib/s390x/css.h
+++ b/lib/s390x/css.h
@@ -283,8 +283,7 @@ int css_enable(int schid, int isc);
 
 /* Library functions */
 int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw);
-int start_single_ccw(unsigned int sid, int code, void *data, int count,
-		     unsigned char flags);
+struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags);
 void css_irq_io(void);
 int css_residual_count(unsigned int schid);
 
diff --git a/lib/s390x/css_lib.c b/lib/s390x/css_lib.c
index 8e02371..6a0a0ec 100644
--- a/lib/s390x/css_lib.c
+++ b/lib/s390x/css_lib.c
@@ -18,6 +18,7 @@
 #include <asm/time.h>
 #include <asm/arch_def.h>
 
+#include <malloc_io.h>
 #include <css.h>
 
 static struct schib schib;
@@ -202,33 +203,20 @@ int start_ccw1_chain(unsigned int sid, struct ccw1 *ccw)
 	return ssch(sid, &orb);
 }
 
-/*
- * In the future, we want to implement support for CCW chains;
- * for that, we will need to work with ccw1 pointers.
- */
-static struct ccw1 unique_ccw;
-
-int start_single_ccw(unsigned int sid, int code, void *data, int count,
-		     unsigned char flags)
+struct ccw1 *ccw_alloc(int code, void *data, int count, unsigned char flags)
 {
-	int cc;
-	struct ccw1 *ccw = &unique_ccw;
+	struct ccw1 *ccw;
+
+	ccw = alloc_io_page(sizeof(*ccw));
+	if (!ccw)
+		return NULL;
 
-	report_prefix_push("start_subchannel");
-	/* Build the CCW chain with a single CCW */
 	ccw->code = code;
 	ccw->flags = flags;
 	ccw->count = count;
 	ccw->data_address = (int)(unsigned long)data;
 
-	cc = start_ccw1_chain(sid, ccw);
-	if (cc) {
-		report(0, "cc = %d", cc);
-		report_prefix_pop();
-		return cc;
-	}
-	report_prefix_pop();
-	return 0;
+	return ccw;
 }
 
 /* wait_and_check_io_completion:
diff --git a/s390x/css.c b/s390x/css.c
index ee3bc83..4b0b6b1 100644
--- a/s390x/css.c
+++ b/s390x/css.c
@@ -17,13 +17,15 @@
 #include <interrupt.h>
 #include <asm/arch_def.h>
 
+#include <malloc_io.h>
 #include <css.h>
+#include <asm/barrier.h>
 
 #define DEFAULT_CU_TYPE		0x3832 /* virtio-ccw */
 static unsigned long cu_type = DEFAULT_CU_TYPE;
 
 static int test_device_sid;
-static struct senseid senseid;
+static struct senseid *senseid;
 
 static void test_enumerate(void)
 {
@@ -57,6 +59,7 @@ static void test_enable(void)
  */
 static void test_sense(void)
 {
+	struct ccw1 *ccw;
 	int ret;
 	int len;
 
@@ -80,9 +83,15 @@ static void test_sense(void)
 
 	lowcore_ptr->io_int_param = 0;
 
-	memset(&senseid, 0, sizeof(senseid));
-	ret = start_single_ccw(test_device_sid, CCW_CMD_SENSE_ID,
-			       &senseid, sizeof(senseid), CCW_F_SLI);
+	senseid = alloc_io_page(sizeof(*senseid));
+	if (!senseid)
+		goto error_senseid;
+
+	ccw = ccw_alloc(CCW_CMD_SENSE_ID, senseid, sizeof(*senseid), CCW_F_SLI);
+	if (!ccw)
+		goto error_ccw;
+
+	ret = start_ccw1_chain(test_device_sid, ccw);
 	if (ret)
 		goto error;
 
@@ -97,7 +106,7 @@ static void test_sense(void)
 	if (ret < 0) {
 		report_info("no valid residual count");
 	} else if (ret != 0) {
-		len = sizeof(senseid) - ret;
+		len = sizeof(*senseid) - ret;
 		if (ret && len < CSS_SENSEID_COMMON_LEN) {
 			report(0, "transferred a too short length: %d", ret);
 			goto error;
@@ -105,21 +114,25 @@ static void test_sense(void)
 			report_info("transferred a shorter length: %d", len);
 	}
 
-	if (senseid.reserved != 0xff) {
-		report(0, "transferred garbage: 0x%02x", senseid.reserved);
+	if (senseid->reserved != 0xff) {
+		report(0, "transferred garbage: 0x%02x", senseid->reserved);
 		goto error;
 	}
 
 	report_prefix_pop();
 
 	report_info("reserved 0x%02x cu_type 0x%04x cu_model 0x%02x dev_type 0x%04x dev_model 0x%02x",
-		    senseid.reserved, senseid.cu_type, senseid.cu_model,
-		    senseid.dev_type, senseid.dev_model);
+		    senseid->reserved, senseid->cu_type, senseid->cu_model,
+		    senseid->dev_type, senseid->dev_model);
 
-	report(senseid.cu_type == cu_type, "cu_type expected 0x%04x got 0x%04x",
-	       (uint16_t) cu_type, senseid.cu_type);
+	report(senseid->cu_type == cu_type, "cu_type expected 0x%04x got 0x%04x",
+	       (uint16_t) cu_type, senseid->cu_type);
 
 error:
+	free_io_page(ccw);
+error_ccw:
+	free_io_page(senseid);
+error_senseid:
 	unregister_io_int_func(css_irq_io);
 }
 
-- 
2.25.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 2/3] s390: define UV compatible I/O allocation
  2020-08-31 12:05 ` [PATCH v1 2/3] s390: define UV compatible I/O allocation Pierre Morel
@ 2020-09-11 12:40   ` Cornelia Huck
  2020-09-14  8:23     ` Pierre Morel
  0 siblings, 1 reply; 6+ messages in thread
From: Cornelia Huck @ 2020-09-11 12:40 UTC (permalink / raw)
  To: Pierre Morel; +Cc: kvm, linux-s390, frankja, david, thuth

On Mon, 31 Aug 2020 14:05:32 +0200
Pierre Morel <pmorel@linux.ibm.com> wrote:

> To centralize the memory allocation for I/O we define
> the alloc/free_io_page() functions which share the I/O
> memory with the host in case the guest runs with
> protected virtualization.
> 
> Signed-off-by: Pierre Morel <pmorel@linux.ibm.com>
> ---
>  lib/s390x/malloc_io.c | 53 +++++++++++++++++++++++++++++++++++++++++++
>  lib/s390x/malloc_io.h | 14 ++++++++++++
>  s390x/Makefile        |  1 +
>  3 files changed, 68 insertions(+)
>  create mode 100644 lib/s390x/malloc_io.c
>  create mode 100644 lib/s390x/malloc_io.h
> 
> diff --git a/lib/s390x/malloc_io.c b/lib/s390x/malloc_io.c
> new file mode 100644
> index 0000000..0e67aab
> --- /dev/null
> +++ b/lib/s390x/malloc_io.c
> @@ -0,0 +1,53 @@
> +/*
> + * I/O page allocation
> + *
> + * Copyright (c) 2020 IBM Corp
> + *
> + * Authors:
> + *  Pierre Morel <pmorel@linux.ibm.com>
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2.
> + *
> + * Using this interface provide host access to the allocated pages in
> + * case the guest is a secure guest.
> + * This is needed for I/O buffers.
> + *
> + */
> +
> +#include <libcflat.h>
> +#include <alloc_page.h>
> +#include <asm/page.h>
> +#include <asm/uv.h>
> +#include <malloc_io.h>
> +#include <asm/facility.h>
> +
> +
> +void *alloc_io_page(int size)
> +{
> +	void *p;
> +
> +	assert(size <= PAGE_SIZE);
> +	p = alloc_page();

I see that you use this for some I/O structures in the next patch. Is
this guaranteed to be under 2G all the time?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 2/3] s390: define UV compatible I/O allocation
  2020-09-11 12:40   ` Cornelia Huck
@ 2020-09-14  8:23     ` Pierre Morel
  0 siblings, 0 replies; 6+ messages in thread
From: Pierre Morel @ 2020-09-14  8:23 UTC (permalink / raw)
  To: Cornelia Huck; +Cc: kvm, linux-s390, frankja, david, thuth



On 2020-09-11 14:40, Cornelia Huck wrote:
> On Mon, 31 Aug 2020 14:05:32 +0200
> Pierre Morel <pmorel@linux.ibm.com> wrote:
> 
>> To centralize the memory allocation for I/O we define
>> the alloc/free_io_page() functions which share the I/O
>> memory with the host in case the guest runs with
>> protected virtualization.

...

>> +
>> +void *alloc_io_page(int size)
>> +{
>> +	void *p;
>> +
>> +	assert(size <= PAGE_SIZE);
>> +	p = alloc_page();
> 
> I see that you use this for some I/O structures in the next patch. Is
> this guaranteed to be under 2G all the time?
> 

Good catch.
I forgot that I already worked on this problem a while ago, I will 
rework the allocation.

Thanks,
Pierre

-- 
Pierre Morel
IBM Lab Boeblingen

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-09-14  8:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-31 12:05 [PATCH v1 0/3] s390x: css: adapting the I/O tests for PV Pierre Morel
2020-08-31 12:05 ` [PATCH v1 1/3] s390x: pv: implement routine to share/unshare memory Pierre Morel
2020-08-31 12:05 ` [PATCH v1 2/3] s390: define UV compatible I/O allocation Pierre Morel
2020-09-11 12:40   ` Cornelia Huck
2020-09-14  8:23     ` Pierre Morel
2020-08-31 12:05 ` [PATCH v1 3/3] s390x: css: pv: css test adaptation for PV Pierre Morel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.