Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-12 Thread Stefano Stabellini
On Wed, 6 Apr 2022, Julien Grall wrote:
> But if we use the 'connection status' field, then you could just delay the
> initialization until you receive an event and the connection status is
> connected.

I prototyped this approach and I managed to validate it successfully.
See attached patches for xen and linux (on top of existing patches). I
allocated the page from init-dom0less (instead of Xen) to achieve best
compatibility with older kernels.

There are some rough edges in the two patches but let me know if you
have any comments on the overall approach.diff --git a/tools/helpers/Makefile b/tools/helpers/Makefile
index 8e42997052..8d78ab1e90 100644
--- a/tools/helpers/Makefile
+++ b/tools/helpers/Makefile
@@ -46,7 +46,7 @@ init-xenstore-domain: $(INIT_XENSTORE_DOMAIN_OBJS)
 	$(CC) $(LDFLAGS) -o $@ $(INIT_XENSTORE_DOMAIN_OBJS) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenlight) $(APPEND_LDFLAGS)
 
 init-dom0less: $(INIT_DOM0LESS_OBJS)
-	$(CC) $(LDFLAGS) -o $@ $(INIT_DOM0LESS_OBJS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenevtchn) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) $(LDLIBS_libxenlight) $(LDLIBS_libxenguest)  $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $(INIT_DOM0LESS_OBJS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenevtchn) $(LDLIBS_libxentoollog) $(LDLIBS_libxenstore) $(LDLIBS_libxenlight) $(LDLIBS_libxenguest) $(LDLIBS_libxenforeignmemory) $(APPEND_LDFLAGS)
 
 .PHONY: install
 install: all
diff --git a/tools/helpers/init-dom0less.c b/tools/helpers/init-dom0less.c
index dc9ccee868..329aa44da6 100644
--- a/tools/helpers/init-dom0less.c
+++ b/tools/helpers/init-dom0less.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "init-dom-json.h"
 
+#define XS_CONNECTION_STATE_OFFSET   (2068/4)
+#define XS_CONNECTION_STATE_RECONNECTING 0x1
 #define XENSTORE_PFN_OFFSET 1
 #define STR_MAX_LENGTH 64
 
@@ -215,12 +218,18 @@ err:
 static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
 {
 struct xc_interface_core *xch;
+xenforeignmemory_handle *xfh;
 libxl_uuid uuid;
 uint64_t xenstore_evtchn, xenstore_pfn;
 int rc;
+uint32_t *page;
 
 printf("Init dom0less domain: %u\n", info->domid);
 xch = xc_interface_open(0, 0, 0);
+xfh = xenforeignmemory_open(0, 0);
+
+if (xch == NULL || xfh == NULL)
+err(1, "Cannot open xc/xenforeignmemory interfaces\n");
 
 rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
   _evtchn);
@@ -235,6 +244,14 @@ static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
 return 1;
 }
 
+page = xenforeignmemory_map(xfh, info->domid, XS_READ | XS_WRITE, 1, _pfn, NULL);
+if (!page) {
+printf("Error mapping xenstore page\n");
+return 1;
+}
+page[XS_CONNECTION_STATE_OFFSET] = XS_CONNECTION_STATE_RECONNECTING;
+xenforeignmemory_unmap(xfh, page, 1);
+
 rc = xc_dom_gnttab_seed(xch, info->domid, true,
 (xen_pfn_t)-1, xenstore_pfn, 0, 0);
 if (rc)
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 0543f49670..7bb8c64d33 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -494,6 +494,7 @@ static struct domain *introduce_domain(const void *ctx,
 		talloc_steal(domain->conn, domain);
 
 		/* Notify the domain that xenstore is available */
+		interface->connection = 0x0;
 		xenevtchn_notify(xce_handle, domain->port);
 
 		if (!is_master_domain && !restore)
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 51e52e175892..dc046d25789e 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -939,6 +939,7 @@ static int __init xenbus_init(void)
 {
 	int err;
 	uint64_t v = 0;
+	bool wait = false;
 	xen_store_domain_type = XS_UNKNOWN;
 
 	if (!xen_domain())
@@ -992,17 +993,7 @@ static int __init xenbus_init(void)
 			goto out_error;
 		}
 		if (v == ~0ULL) {
-			err = bind_evtchn_to_irqhandler(xen_store_evtchn,
-			xenbus_late_init,
-			0, "xenstore_late_init",
-			_waitq);
-			if (err < 0) {
-pr_err("xenstore_late_init couldn't bind irq err=%d\n",
-   err);
-return err;
-			}
-
-			xs_init_irq = err;
+			wait = true;
 		} else {
 			/* Avoid truncation on 32-bit. */
 #if BITS_PER_LONG == 32
@@ -1017,6 +1008,21 @@ static int __init xenbus_init(void)
 			xen_store_interface =
 xen_remap(xen_store_gfn << XEN_PAGE_SHIFT,
 	  XEN_PAGE_SIZE);
+			if (xen_store_interface->connection != 0)
+wait = true;
+		}
+		if (wait) {
+			err = bind_evtchn_to_irqhandler(xen_store_evtchn,
+			xenbus_late_init,
+			0, "xenstore_late_init",
+			_waitq);
+			if (err < 0) {
+pr_err("xenstore_late_init couldn't bind irq err=%d\n",
+   err);
+return err;
+			}
+
+			xs_init_irq = err;
 		}
 		break;
 	default:
diff --git a/include/xen/interface/io/xs_wire.h 

Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-06 Thread Julien Grall

Hi Stefano,

On 06/04/2022 03:21, Stefano Stabellini wrote:

On Fri, 1 Apr 2022, Juergen Gross wrote:

On 01.04.22 12:21, Julien Grall wrote:

This would be a problem if Linux is still booting and hasn't yet call
xenbus_probe_initcall().

I understand we need to have the page setup before raising the event
channel. I don't think we can allow Xenstored to set the HVM_PARAM (it may
run in a domain with less privilege). So I think we may need to create a
separate command to kick the client (not great).

Juergen, any thoughts?


I think it should work like that:

- setup the grant via xc_dom_gnttab_seed()
- introduce the domain to Xenstore
- call xc_hvm_param_set()

When the guest is receiving the event, it should wait for the xenstore
page to appear.



I am OK with what you wrote above, and I understand Julien's concerns
about "waiting". Before discussing that, I would like to make sure I
understood why setting HVM_PARAM_STORE_PFN first (before
xs_introduce_domain) is not possible.

In a previous reply to Julien I wrote that it is not a good idea to
set HVM_PARAM_STORE_PFN in Xen before creating the domains because it
would cause Linux to hang at boot. That is true, Linux hangs on
drivers/xen/xenbus/xenbus_comms.c:xb_init_comms waiting on xb_waitq.
I looked at the implementation of xb_init_comms in 5.17 and I couldn't 
find out how it would block here. Can you clarify?



It could wait a very long time as domUs are typically a lot faster than
dom0 to boot.

However, if we set HVM_PARAM_STORE_PFN before calling
xs_introduce_domain in init-dom0less, for Linux to see it before
xs_introduce_domain is done, Linux would need to be racing against
init-dom0less. In that case, the wait in xb_init_comms would be minimal
anyway. It shouldn't be a problem. There would be no "hang", just a wait
a bit longer than usual.


From my understanding, Linux may send commands as soon as it sees 
HVM_PARAM_STORE_PFN. With your proposal, this may happen before 
xs_introduce_domain() has updated the features supported by Xenstored.


With the recent proposal from Juergen [1], an OS will need to read the 
features field to understand whether Xenstored support the extended 
version of a command.


This means, any commands sent before xs_introduce_domain() would not be 
able to take advantage of the new features. Therefore, we would need to 
wait until Xenstored has advertised the features.


With your approach, the wait would be a busy loop. Although, I am not 
entirely sure what you would be waiting on?


But if we use the 'connection status' field, then you could just delay 
the initialization until you receive an event and the connection status 
is connected.


Cheers,

[1] https://lore.kernel.org/xen-devel/20220316161017.3579-1-jgr...@suse.com/

--
Julien Grall



Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-05 Thread Stefano Stabellini
On Fri, 1 Apr 2022, Juergen Gross wrote:
> On 01.04.22 12:21, Julien Grall wrote:
> > Hi,
> > 
> > I have posted some comments in v3 after you sent this version. Please have a
> > look.
> > 
> > On 01/04/2022 01:38, Stefano Stabellini wrote:
> > > +static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
> > > +{
> > > +    struct xc_interface_core *xch;
> > > +    libxl_uuid uuid;
> > > +    uint64_t xenstore_evtchn, xenstore_pfn;
> > > +    int rc;
> > > +
> > > +    printf("Init dom0less domain: %u\n", info->domid);
> > > +    xch = xc_interface_open(0, 0, 0);
> > > +
> > > +    rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
> > > +  _evtchn);
> > > +    if (rc != 0) {
> > > +    printf("Failed to get HVM_PARAM_STORE_EVTCHN\n");
> > > +    return 1;
> > > +    }
> > > +
> > > +    /* Alloc xenstore page */
> > > +    if (alloc_xs_page(xch, info, _pfn) != 0) {
> > > +    printf("Error on alloc magic pages\n");
> > > +    return 1;
> > > +    }
> > > +
> > > +    rc = xc_dom_gnttab_seed(xch, info->domid, true,
> > > +    (xen_pfn_t)-1, xenstore_pfn, 0, 0);
> > > +    if (rc)
> > > +    err(1, "xc_dom_gnttab_seed");
> > > +
> > > +    libxl_uuid_generate();
> > > +    xc_domain_sethandle(xch, info->domid, libxl_uuid_bytearray());
> > > +
> > > +    rc = gen_stub_json_config(info->domid, );
> > > +    if (rc)
> > > +    err(1, "gen_stub_json_config");
> > > +
> > > +    /* Now everything is ready: set HVM_PARAM_STORE_PFN */
> > > +    rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN,
> > > +  xenstore_pfn);
> > 
> > On patch #1, you told me you didn't want to allocate the page in Xen because
> > it wouldn't be initialized by Xenstored. But this is what we are doing here.
> 
> Xenstore (at least the C variant) is only using the fixed grant ref
> GNTTAB_RESERVED_XENSTORE, so it doesn't need the page to be advertised
> to the guest. And the mapping is done only when the domain is being
> introduced to Xenstore.
> 
> > 
> > This would be a problem if Linux is still booting and hasn't yet call
> > xenbus_probe_initcall().
> > 
> > I understand we need to have the page setup before raising the event
> > channel. I don't think we can allow Xenstored to set the HVM_PARAM (it may
> > run in a domain with less privilege). So I think we may need to create a
> > separate command to kick the client (not great).
> > 
> > Juergen, any thoughts?
> 
> I think it should work like that:
> 
> - setup the grant via xc_dom_gnttab_seed()
> - introduce the domain to Xenstore
> - call xc_hvm_param_set()
> 
> When the guest is receiving the event, it should wait for the xenstore
> page to appear.


I am OK with what you wrote above, and I understand Julien's concerns
about "waiting". Before discussing that, I would like to make sure I
understood why setting HVM_PARAM_STORE_PFN first (before
xs_introduce_domain) is not possible.

In a previous reply to Julien I wrote that it is not a good idea to
set HVM_PARAM_STORE_PFN in Xen before creating the domains because it
would cause Linux to hang at boot. That is true, Linux hangs on
drivers/xen/xenbus/xenbus_comms.c:xb_init_comms waiting on xb_waitq.
It could wait a very long time as domUs are typically a lot faster than
dom0 to boot.

However, if we set HVM_PARAM_STORE_PFN before calling
xs_introduce_domain in init-dom0less, for Linux to see it before
xs_introduce_domain is done, Linux would need to be racing against
init-dom0less. In that case, the wait in xb_init_comms would be minimal
anyway. It shouldn't be a problem. There would be no "hang", just a wait
a bit longer than usual.

Is that right?


Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-01 Thread Juergen Gross

On 01.04.22 16:04, Julien Grall wrote:

Hi Juergen,

On 01/04/2022 14:52, Juergen Gross wrote:

On 01.04.22 15:35, Julien Grall wrote:

Hi Juergen,

On 01/04/2022 11:46, Juergen Gross wrote:

On 01.04.22 12:21, Julien Grall wrote:

Hi,

I have posted some comments in v3 after you sent this version. Please have 
a look.


On 01/04/2022 01:38, Stefano Stabellini wrote:

+static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
+{
+    struct xc_interface_core *xch;
+    libxl_uuid uuid;
+    uint64_t xenstore_evtchn, xenstore_pfn;
+    int rc;
+
+    printf("Init dom0less domain: %u\n", info->domid);
+    xch = xc_interface_open(0, 0, 0);
+
+    rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
+  _evtchn);
+    if (rc != 0) {
+    printf("Failed to get HVM_PARAM_STORE_EVTCHN\n");
+    return 1;
+    }
+
+    /* Alloc xenstore page */
+    if (alloc_xs_page(xch, info, _pfn) != 0) {
+    printf("Error on alloc magic pages\n");
+    return 1;
+    }
+
+    rc = xc_dom_gnttab_seed(xch, info->domid, true,
+    (xen_pfn_t)-1, xenstore_pfn, 0, 0);
+    if (rc)
+    err(1, "xc_dom_gnttab_seed");
+
+    libxl_uuid_generate();
+    xc_domain_sethandle(xch, info->domid, libxl_uuid_bytearray());
+
+    rc = gen_stub_json_config(info->domid, );
+    if (rc)
+    err(1, "gen_stub_json_config");
+
+    /* Now everything is ready: set HVM_PARAM_STORE_PFN */
+    rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN,
+  xenstore_pfn);


On patch #1, you told me you didn't want to allocate the page in Xen 
because it wouldn't be initialized by Xenstored. But this is what we are 
doing here.


Xenstore (at least the C variant) is only using the fixed grant ref
GNTTAB_RESERVED_XENSTORE, so it doesn't need the page to be advertised
to the guest. And the mapping is done only when the domain is being
introduced to Xenstore.


And we don't expect the guest to use the grant entry to find the xenstore page?




This would be a problem if Linux is still booting and hasn't yet call 
xenbus_probe_initcall().


I understand we need to have the page setup before raising the event 
channel. I don't think we can allow Xenstored to set the HVM_PARAM (it may 
run in a domain with less privilege). So I think we may need to create a 
separate command to kick the client (not great).


Juergen, any thoughts?


I think it should work like that:

- setup the grant via xc_dom_gnttab_seed()
- introduce the domain to Xenstore
- call xc_hvm_param_set()

When the guest is receiving the event, it should wait for the xenstore
page to appear.
IIUC, this would mean the guest would need to do some sort of busy loop until 
the xenstore page to appear.


Looking for it every second or so would be enough.


This is a better than a busy loop but not by much. I would argue a design that 
requires to poll after receiving an interrupt is broken.




If so, this doesn't sound great to me. I think it would be better to have a 
flag in the page to indicate whether the page is not ready.


Xenstored could then clear the flag before raising the event channel.


Hmm, the "connection" field could be used for that.


I thought about the field but the description doesn't entirely match what we 
want. In particular, the spec says only the guest should set the value to 1 
(i.e. reconnect). Maybe this could be relaxed?




It would mean, though, that e.g. libxl would need to initialize the
page accordingly before calling xs_introduce()


libxl only create domain paused. So I don't think it would be necessary to 
update it.


Maybe not libxl, but whoever is calling xc_dom_gnttab_seed(),
xc_hvm_param_set() and/or xs_introduce() needs to set the field, in
order to have an effect of Xenstore resetting it.


Juergen


OpenPGP_0xB0DE9DD628BF132F.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-01 Thread Julien Grall

Hi Juergen,

On 01/04/2022 14:52, Juergen Gross wrote:

On 01.04.22 15:35, Julien Grall wrote:

Hi Juergen,

On 01/04/2022 11:46, Juergen Gross wrote:

On 01.04.22 12:21, Julien Grall wrote:

Hi,

I have posted some comments in v3 after you sent this version. 
Please have a look.


On 01/04/2022 01:38, Stefano Stabellini wrote:

+static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
+{
+    struct xc_interface_core *xch;
+    libxl_uuid uuid;
+    uint64_t xenstore_evtchn, xenstore_pfn;
+    int rc;
+
+    printf("Init dom0less domain: %u\n", info->domid);
+    xch = xc_interface_open(0, 0, 0);
+
+    rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
+  _evtchn);
+    if (rc != 0) {
+    printf("Failed to get HVM_PARAM_STORE_EVTCHN\n");
+    return 1;
+    }
+
+    /* Alloc xenstore page */
+    if (alloc_xs_page(xch, info, _pfn) != 0) {
+    printf("Error on alloc magic pages\n");
+    return 1;
+    }
+
+    rc = xc_dom_gnttab_seed(xch, info->domid, true,
+    (xen_pfn_t)-1, xenstore_pfn, 0, 0);
+    if (rc)
+    err(1, "xc_dom_gnttab_seed");
+
+    libxl_uuid_generate();
+    xc_domain_sethandle(xch, info->domid, 
libxl_uuid_bytearray());

+
+    rc = gen_stub_json_config(info->domid, );
+    if (rc)
+    err(1, "gen_stub_json_config");
+
+    /* Now everything is ready: set HVM_PARAM_STORE_PFN */
+    rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN,
+  xenstore_pfn);


On patch #1, you told me you didn't want to allocate the page in Xen 
because it wouldn't be initialized by Xenstored. But this is what we 
are doing here.


Xenstore (at least the C variant) is only using the fixed grant ref
GNTTAB_RESERVED_XENSTORE, so it doesn't need the page to be advertised
to the guest. And the mapping is done only when the domain is being
introduced to Xenstore.


And we don't expect the guest to use the grant entry to find the 
xenstore page?




This would be a problem if Linux is still booting and hasn't yet 
call xenbus_probe_initcall().


I understand we need to have the page setup before raising the event 
channel. I don't think we can allow Xenstored to set the HVM_PARAM 
(it may run in a domain with less privilege). So I think we may need 
to create a separate command to kick the client (not great).


Juergen, any thoughts?


I think it should work like that:

- setup the grant via xc_dom_gnttab_seed()
- introduce the domain to Xenstore
- call xc_hvm_param_set()

When the guest is receiving the event, it should wait for the xenstore
page to appear.
IIUC, this would mean the guest would need to do some sort of busy 
loop until the xenstore page to appear.


Looking for it every second or so would be enough.


This is a better than a busy loop but not by much. I would argue a 
design that requires to poll after receiving an interrupt is broken.




If so, this doesn't sound great to me. I think it would be better to 
have a flag in the page to indicate whether the page is not ready.


Xenstored could then clear the flag before raising the event channel.


Hmm, the "connection" field could be used for that.


I thought about the field but the description doesn't entirely match 
what we want. In particular, the spec says only the guest should set the 
value to 1 (i.e. reconnect). Maybe this could be relaxed?




It would mean, though, that e.g. libxl would need to initialize the
page accordingly before calling xs_introduce()


libxl only create domain paused. So I don't think it would be necessary 
to update it.


Cheers,

--
Julien Grall



Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-01 Thread Juergen Gross

On 01.04.22 15:35, Julien Grall wrote:

Hi Juergen,

On 01/04/2022 11:46, Juergen Gross wrote:

On 01.04.22 12:21, Julien Grall wrote:

Hi,

I have posted some comments in v3 after you sent this version. Please have a 
look.


On 01/04/2022 01:38, Stefano Stabellini wrote:

+static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
+{
+    struct xc_interface_core *xch;
+    libxl_uuid uuid;
+    uint64_t xenstore_evtchn, xenstore_pfn;
+    int rc;
+
+    printf("Init dom0less domain: %u\n", info->domid);
+    xch = xc_interface_open(0, 0, 0);
+
+    rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
+  _evtchn);
+    if (rc != 0) {
+    printf("Failed to get HVM_PARAM_STORE_EVTCHN\n");
+    return 1;
+    }
+
+    /* Alloc xenstore page */
+    if (alloc_xs_page(xch, info, _pfn) != 0) {
+    printf("Error on alloc magic pages\n");
+    return 1;
+    }
+
+    rc = xc_dom_gnttab_seed(xch, info->domid, true,
+    (xen_pfn_t)-1, xenstore_pfn, 0, 0);
+    if (rc)
+    err(1, "xc_dom_gnttab_seed");
+
+    libxl_uuid_generate();
+    xc_domain_sethandle(xch, info->domid, libxl_uuid_bytearray());
+
+    rc = gen_stub_json_config(info->domid, );
+    if (rc)
+    err(1, "gen_stub_json_config");
+
+    /* Now everything is ready: set HVM_PARAM_STORE_PFN */
+    rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN,
+  xenstore_pfn);


On patch #1, you told me you didn't want to allocate the page in Xen because 
it wouldn't be initialized by Xenstored. But this is what we are doing here.


Xenstore (at least the C variant) is only using the fixed grant ref
GNTTAB_RESERVED_XENSTORE, so it doesn't need the page to be advertised
to the guest. And the mapping is done only when the domain is being
introduced to Xenstore.


And we don't expect the guest to use the grant entry to find the xenstore page?




This would be a problem if Linux is still booting and hasn't yet call 
xenbus_probe_initcall().


I understand we need to have the page setup before raising the event channel. 
I don't think we can allow Xenstored to set the HVM_PARAM (it may run in a 
domain with less privilege). So I think we may need to create a separate 
command to kick the client (not great).


Juergen, any thoughts?


I think it should work like that:

- setup the grant via xc_dom_gnttab_seed()
- introduce the domain to Xenstore
- call xc_hvm_param_set()

When the guest is receiving the event, it should wait for the xenstore
page to appear.
IIUC, this would mean the guest would need to do some sort of busy loop until 
the xenstore page to appear.


Looking for it every second or so would be enough.

If so, this doesn't sound great to me. I think it would be better to have a flag 
in the page to indicate whether the page is not ready.


Xenstored could then clear the flag before raising the event channel.


Hmm, the "connection" field could be used for that.

It would mean, though, that e.g. libxl would need to initialize the
page accordingly before calling xs_introduce().


Juergen


OpenPGP_0xB0DE9DD628BF132F.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-01 Thread Julien Grall

Hi Juergen,

On 01/04/2022 11:46, Juergen Gross wrote:

On 01.04.22 12:21, Julien Grall wrote:

Hi,

I have posted some comments in v3 after you sent this version. Please 
have a look.


On 01/04/2022 01:38, Stefano Stabellini wrote:

+static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
+{
+    struct xc_interface_core *xch;
+    libxl_uuid uuid;
+    uint64_t xenstore_evtchn, xenstore_pfn;
+    int rc;
+
+    printf("Init dom0less domain: %u\n", info->domid);
+    xch = xc_interface_open(0, 0, 0);
+
+    rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
+  _evtchn);
+    if (rc != 0) {
+    printf("Failed to get HVM_PARAM_STORE_EVTCHN\n");
+    return 1;
+    }
+
+    /* Alloc xenstore page */
+    if (alloc_xs_page(xch, info, _pfn) != 0) {
+    printf("Error on alloc magic pages\n");
+    return 1;
+    }
+
+    rc = xc_dom_gnttab_seed(xch, info->domid, true,
+    (xen_pfn_t)-1, xenstore_pfn, 0, 0);
+    if (rc)
+    err(1, "xc_dom_gnttab_seed");
+
+    libxl_uuid_generate();
+    xc_domain_sethandle(xch, info->domid, libxl_uuid_bytearray());
+
+    rc = gen_stub_json_config(info->domid, );
+    if (rc)
+    err(1, "gen_stub_json_config");
+
+    /* Now everything is ready: set HVM_PARAM_STORE_PFN */
+    rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN,
+  xenstore_pfn);


On patch #1, you told me you didn't want to allocate the page in Xen 
because it wouldn't be initialized by Xenstored. But this is what we 
are doing here.


Xenstore (at least the C variant) is only using the fixed grant ref
GNTTAB_RESERVED_XENSTORE, so it doesn't need the page to be advertised
to the guest. And the mapping is done only when the domain is being
introduced to Xenstore.


And we don't expect the guest to use the grant entry to find the 
xenstore page?




This would be a problem if Linux is still booting and hasn't yet call 
xenbus_probe_initcall().


I understand we need to have the page setup before raising the event 
channel. I don't think we can allow Xenstored to set the HVM_PARAM (it 
may run in a domain with less privilege). So I think we may need to 
create a separate command to kick the client (not great).


Juergen, any thoughts?


I think it should work like that:

- setup the grant via xc_dom_gnttab_seed()
- introduce the domain to Xenstore
- call xc_hvm_param_set()

When the guest is receiving the event, it should wait for the xenstore
page to appear.
IIUC, this would mean the guest would need to do some sort of busy loop 
until the xenstore page to appear.


If so, this doesn't sound great to me. I think it would be better to 
have a flag in the page to indicate whether the page is not ready.


Xenstored could then clear the flag before raising the event channel.

Cheers,

--
Julien Grall



Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-01 Thread Juergen Gross

On 01.04.22 12:21, Julien Grall wrote:

Hi,

I have posted some comments in v3 after you sent this version. Please have a 
look.

On 01/04/2022 01:38, Stefano Stabellini wrote:

+static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
+{
+    struct xc_interface_core *xch;
+    libxl_uuid uuid;
+    uint64_t xenstore_evtchn, xenstore_pfn;
+    int rc;
+
+    printf("Init dom0less domain: %u\n", info->domid);
+    xch = xc_interface_open(0, 0, 0);
+
+    rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
+  _evtchn);
+    if (rc != 0) {
+    printf("Failed to get HVM_PARAM_STORE_EVTCHN\n");
+    return 1;
+    }
+
+    /* Alloc xenstore page */
+    if (alloc_xs_page(xch, info, _pfn) != 0) {
+    printf("Error on alloc magic pages\n");
+    return 1;
+    }
+
+    rc = xc_dom_gnttab_seed(xch, info->domid, true,
+    (xen_pfn_t)-1, xenstore_pfn, 0, 0);
+    if (rc)
+    err(1, "xc_dom_gnttab_seed");
+
+    libxl_uuid_generate();
+    xc_domain_sethandle(xch, info->domid, libxl_uuid_bytearray());
+
+    rc = gen_stub_json_config(info->domid, );
+    if (rc)
+    err(1, "gen_stub_json_config");
+
+    /* Now everything is ready: set HVM_PARAM_STORE_PFN */
+    rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN,
+  xenstore_pfn);


On patch #1, you told me you didn't want to allocate the page in Xen because it 
wouldn't be initialized by Xenstored. But this is what we are doing here.


Xenstore (at least the C variant) is only using the fixed grant ref
GNTTAB_RESERVED_XENSTORE, so it doesn't need the page to be advertised
to the guest. And the mapping is done only when the domain is being
introduced to Xenstore.



This would be a problem if Linux is still booting and hasn't yet call 
xenbus_probe_initcall().


I understand we need to have the page setup before raising the event channel. I 
don't think we can allow Xenstored to set the HVM_PARAM (it may run in a domain 
with less privilege). So I think we may need to create a separate command to 
kick the client (not great).


Juergen, any thoughts?


I think it should work like that:

- setup the grant via xc_dom_gnttab_seed()
- introduce the domain to Xenstore
- call xc_hvm_param_set()

When the guest is receiving the event, it should wait for the xenstore
page to appear.


Juergen


OpenPGP_0xB0DE9DD628BF132F.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v4 8/9] tools: add example application to initialize dom0less PV drivers

2022-04-01 Thread Julien Grall

Hi,

I have posted some comments in v3 after you sent this version. Please 
have a look.


On 01/04/2022 01:38, Stefano Stabellini wrote:

+static int init_domain(struct xs_handle *xsh, libxl_dominfo *info)
+{
+struct xc_interface_core *xch;
+libxl_uuid uuid;
+uint64_t xenstore_evtchn, xenstore_pfn;
+int rc;
+
+printf("Init dom0less domain: %u\n", info->domid);
+xch = xc_interface_open(0, 0, 0);
+
+rc = xc_hvm_param_get(xch, info->domid, HVM_PARAM_STORE_EVTCHN,
+  _evtchn);
+if (rc != 0) {
+printf("Failed to get HVM_PARAM_STORE_EVTCHN\n");
+return 1;
+}
+
+/* Alloc xenstore page */
+if (alloc_xs_page(xch, info, _pfn) != 0) {
+printf("Error on alloc magic pages\n");
+return 1;
+}
+
+rc = xc_dom_gnttab_seed(xch, info->domid, true,
+(xen_pfn_t)-1, xenstore_pfn, 0, 0);
+if (rc)
+err(1, "xc_dom_gnttab_seed");
+
+libxl_uuid_generate();
+xc_domain_sethandle(xch, info->domid, libxl_uuid_bytearray());
+
+rc = gen_stub_json_config(info->domid, );
+if (rc)
+err(1, "gen_stub_json_config");
+
+/* Now everything is ready: set HVM_PARAM_STORE_PFN */
+rc = xc_hvm_param_set(xch, info->domid, HVM_PARAM_STORE_PFN,
+  xenstore_pfn);


On patch #1, you told me you didn't want to allocate the page in Xen 
because it wouldn't be initialized by Xenstored. But this is what we are 
doing here.


This would be a problem if Linux is still booting and hasn't yet call 
xenbus_probe_initcall().


I understand we need to have the page setup before raising the event 
channel. I don't think we can allow Xenstored to set the HVM_PARAM (it 
may run in a domain with less privilege). So I think we may need to 
create a separate command to kick the client (not great).


Juergen, any thoughts?

Cheers,

--
Julien Grall