Skip to contentSkip to conversation

Add support for a VM generation ID virtual device (v2)

PATCH Applied Paul Durrant 4 participants 19 messages Nov 29, 2011 – Nov 30, 2011 Arm/actions semi architecture

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Add support for a VM generation ID virtual device (v2)

The following is a revised patch series to add support for a VM generation ID virtual device for HVM guests. The basic requirements of this device are as follows:

- It must be exposed somewhere in ACPI namespace with a _CID of "VM_Gen_Counter".
- It must also include a _DDN of "VM_Gen_Counter".
- It must contain a _HID object but no particular value is required.
- It must expose a package called ADDR which evaluates to two integers; the first being the low order 32-bits of a guest physical address (GPA), the second by the high order 32-bits of the GPA. This GPA is the address of an 8-byte aligned 8-byte buffer containing the VM generation ID.
This buffer must not be in ranges supported as AddressRangeMemory or AddressRangeACPI and must not be mapped by any PTE with caching disabled.

The semantics of the VM generation ID itself are left up to the tools but it must be possible to change it each time the VM is booted, migrated, or restored from a saved image.

Patch 1 adds the device and an acpi_info field to allow population of the ADDR package.
Patch 2 adds ctype infrastructure to hvloader in preparation for... Patch 3 adds all the code to plumb the value of a new 'generation_id' parameter in the VM config through to the VM generation id buffer at VM boot time.
Patch 4 adds an implementation of sprintf() to hvmloader. Patch 5 adds an implementation of xenstore-write to hvmloader. Patch 6 adds support for tracking the address of the VM generation id buffer (via xenstore) across save/restore or migrate and updating the value of the buffer with the value from the VM config file.

#1 lore raw

PATCH 1/1 Add an ACPI device exposing a package called ADDR, evaluating to two

# HG changeset patch
# User Paul Durrant <[email protected]>
# Date 1322563733 0
# Node ID ac68bd6d4853fdde5a24d78a7d0f1cee69f5416e
# Parent a9c67c2daf4b0181ef2581471ea920eecb495616
Add an ACPI device exposing a package called ADDR, evaluating to two integers, and with _CID and _DDN set to "VM_Gen_Counter".

tools/firmware/hvmloader/acpi/build.c +1 -0
diff -r a9c67c2daf4b -r ac68bd6d4853 tools/firmware/hvmloader/acpi/build.c
@@ -47,6 +47,7 @@ struct acpi_info {
     uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
     uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
     uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
+    uint32_t vm_gid_addr;       /* 20   - Address of VM generation id buffer */
 };
 
 /* Number of processor objects in the chosen DSDT. */
tools/firmware/hvmloader/acpi/dsdt.asl +27 -1
diff -r a9c67c2daf4b -r ac68bd6d4853 tools/firmware/hvmloader/acpi/dsdt.asl
@@ -55,7 +55,8 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
            PMIN, 32,
            PLEN, 32,
            MSUA, 32, /* MADT checksum address */
-           MAPA, 32  /* MADT LAPIC0 address */
+           MAPA, 32, /* MADT LAPIC0 address */
+           VGIA, 32  /* VM generation id address */
        }
 
         /* Fix HCT test for 0x400 pci memory:
@@ -396,6 +397,31 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 
                         IRQNoFlags () {7}
                     })
                 } 
+
+                Device(VGID) {
+                    Name(_HID, "ACPI0001")
+                    Name(_UID, 0x00)
+                    Name(_CID, "VM_Gen_Counter")
+                    Name(_DDN, "VM_Gen_Counter")
+                    Method(_STA, 0, NotSerialized)
+                    {
+                        If(LEqual(\_SB.VGIA, 0x00000000)) {
+                            Return(0x00)
+                        } Else {
+                            Return(0x0F)
+                        }
+                    }
+                    Name(PKG, Package ()
+                    {
+                        0x00000000,
+                        0x00000000
+                    })
+                    Method(ADDR, 0, NotSerialized)
+                    {
+                        Store(\_SB.VGIA, Index(PKG, 0))
+                        Return(PKG)
+                    }
+                }
             }
         }
     }
#2 lore raw

Re: [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 82 lines

-----Original Message-----
From: [email protected] [mailto:xen-devel- [email protected]] On Behalf Of Paul Durrant
Sent: Tuesday, November 29, 2011 5:53 AM
To: [email protected]
Cc: Paul Durrant
Subject: [Xen-devel] [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

# HG changeset patch
# User Paul Durrant <[email protected]> # Date 1322563733 0 # Node ID ac68bd6d4853fdde5a24d78a7d0f1cee69f5416e
# Parent a9c67c2daf4b0181ef2581471ea920eecb495616
Add an ACPI device exposing a package called ADDR, evaluating to two integers, and with _CID and _DDN set to "VM_Gen_Counter".

diff -r a9c67c2daf4b -r ac68bd6d4853
tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c Mon Nov 28 11:57:23 2011
+0000
+++ b/tools/firmware/hvmloader/acpi/build.c Tue Nov 29 10:48:53 2011
+0000

tools/firmware/hvmloader/acpi/build.c +0 -0
@@ -47,6 +47,7 @@ struct acpi_info {
     uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
     uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
     uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC

struct */
+ uint32_t vm_gid_addr; /* 20 - Address of VM generation id
buffer */
};

/* Number of processor objects in the chosen DSDT. */ diff -r
a9c67c2daf4b -r ac68bd6d4853 tools/firmware/hvmloader/acpi/dsdt.asl
--- a/tools/firmware/hvmloader/acpi/dsdt.asl Mon Nov 28 11:57:23 2011
+0000
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl Tue Nov 29 10:48:53 2011
+0000

tools/firmware/hvmloader/acpi/dsdt.asl +27 -1
@@ -55,7 +55,8 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2,
            PMIN, 32,
            PLEN, 32,
            MSUA, 32, /* MADT checksum address */
-           MAPA, 32  /* MADT LAPIC0 address */
+           MAPA, 32, /* MADT LAPIC0 address */
+           VGIA, 32  /* VM generation id address */
        }
 
         /* Fix HCT test for 0x400 pci memory:
@@ -396,6 +397,31 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2,
                         IRQNoFlags () {7}
                     })
                 }
+
+                Device(VGID) {
+                    Name(_HID, "ACPI0001")
+                    Name(_UID, 0x00)
+                    Name(_CID, "VM_Gen_Counter")
+                    Name(_DDN, "VM_Gen_Counter")
+                    Method(_STA, 0, NotSerialized)
+                    {
+                        If(LEqual(\_SB.VGIA, 0x00000000)) {
+                            Return(0x00)
+                        } Else {
+                            Return(0x0F)
+                        }
+                    }
+                    Name(PKG, Package ()
+                    {
+                        0x00000000,
+                        0x00000000
+                    })
+                    Method(ADDR, 0, NotSerialized)
+                    {
+                        Store(\_SB.VGIA, Index(PKG, 0))
+                        Return(PKG)
+                    }
+                }
             }
         }
     }
Quoted 4 lines

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

Paul, perhaps a different _HID might be better. Per the 3.0 spec, ACPI0001 is for SMBus host controller device; this might lead to some confusion for an OSPM. Maybe one of the generic PNP device IDs or perhaps we need a manufacturer ID for Xen?

Ross

#3 lore raw

Re: [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 2 lines

-----Original Message-----
From: Ross Philipson

[snip]

Quoted 6 lines

Paul, perhaps a different _HID might be better. Per the 3.0 spec, ACPI0001 is for SMBus host controller device; this might lead to some confusion for an OSPM. Maybe one of the generic PNP device IDs or perhaps we need a manufacturer ID for Xen?

I have no problem choosing a different _HID. I just don't have a good reference for what name is not going to clash with something else. Looks like ACPI0001 was a bad guess. Any better suggestions? What are the 'generic PNP device IDs'?

Paul

#4 lore raw

Re: [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 17 lines

-----Original Message-----
From: Paul Durrant
Sent: Tuesday, November 29, 2011 11:05 AM
To: Ross Philipson; [email protected]
Subject: RE: [Xen-devel] [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 2 lines

-----Original Message-----
From: Ross Philipson

[snip]

Quoted 6 lines

Paul, perhaps a different _HID might be better. Per the 3.0 spec, ACPI0001 is for SMBus host controller device; this might lead to some confusion for an OSPM. Maybe one of the generic PNP device IDs or perhaps we need a manufacturer ID for Xen?

Quoted 6 lines

I have no problem choosing a different _HID. I just don't have a good reference for what name is not going to clash with something else. Looks like ACPI0001 was a bad guess. Any better suggestions? What are the 'generic PNP device IDs'?

Paul

Well I actually brought it up as a discussion point. I have the same sort of issue - I have a generic device for a virtualized environment. I don't really want it to be recognized as anything specific. I guess I see three options:

- Use an unassigned APCIXXXX string. I believe the _HID string values of the form "ACPIXXXX" are defined by the ACPI specs themselves so this may not work in the long run.
- Use one of the predefined generic container EisaId PNP values. By that I meant using EisaId(PNP0A05) or EisaId(PNP0A06). Looking at the Linux generic container driver, it doesn't do very much with these devices so that might be OK.
- Acquire a vendor specific EisaId range for Xen (e.g. EisaId(XENABCD)). Then we could carve up the product number part of the ID as we see fit.

Anyway, just some ideas.

Ross

#5 lore raw

Re: [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 11 lines · Ross Philipson
Quoted 6 lines

I have no problem choosing a different _HID. I just don't have a good reference for what name is not going to clash with something else. Looks like ACPI0001 was a bad guess. Any better suggestions? What are the 'generic PNP device IDs'?

Paul

Well I actually brought it up as a discussion point. I have the same sort of issue - I have a generic device for a virtualized environment. I don't really want it to be recognized as anything specific. I guess I see three options:

Quoted 7 lines

- Use an unassigned APCIXXXX string. I believe the _HID string values of the
form "ACPIXXXX" are defined by the ACPI specs themselves so this may not work in the long run.
- Use one of the predefined generic container EisaId PNP values. By that I
meant using EisaId(PNP0A05) or EisaId(PNP0A06). Looking at the Linux generic container driver, it doesn't do very much with these devices so that might be OK.

This option sounds reasonable. We have freedom to change it in future if it turns out to be a bad choice, not that I can see why it would be.

-- Keir

Quoted 2 lines

- Acquire a vendor specific EisaId range for Xen (e.g. EisaId(XENABCD)). Then
we could carve up the product number part of the ID as we see fit.

#6 lore raw

Re: [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Keir,

Do you want me to re-send that patch or will you fix it up?

Paul

Quoted 48 lines

-----Original Message-----
From: Keir Fraser [mailto:[email protected]]
Sent: 29 November 2011 09:20
To: Ross Philipson; Paul Durrant; [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 1 line · Ross Philipson
Quoted 1 line

I have no problem choosing a different _HID. I just don't have a

good

Quoted 1 line
Quoted 1 line

reference for what name is not going to clash with something

else.

Quoted 1 line
Quoted 1 line

Looks like ACPI0001 was a bad guess. Any better suggestions? What

are

Quoted 5 lines
Quoted 3 lines

the 'generic PNP device IDs'?

Paul

Well I actually brought it up as a discussion point. I have the

same

Quoted 1 line

sort of issue - I have a generic device for a virtualized

environment.

Quoted 1 line

I don't really want it to be recognized as anything specific. I

guess I see three options:

Quoted 2 lines

- Use an unassigned APCIXXXX string. I believe the _HID string

values

Quoted 3 lines

of the form "ACPIXXXX" are defined by the ACPI specs themselves so this may not work in the long run.
- Use one of the predefined generic container EisaId PNP values.

By

Quoted 1 line

that I meant using EisaId(PNP0A05) or EisaId(PNP0A06). Looking at

the

Quoted 2 lines

Linux generic container driver, it doesn't do very much with these devices so that might be OK.

This option sounds reasonable. We have freedom to change it in future if it turns out to be a bad choice, not that I can see why it would be.

-- Keir

Quoted 2 lines

- Acquire a vendor specific EisaId range for Xen (e.g.
EisaId(XENABCD)). Then we could carve up the product number part

of the ID as we see fit.

#7 lore raw

Re: [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Pick a name and I can fix it up. :-)

-- Keir

Quoted 55 lines · Paul Durrant

Keir,

Do you want me to re-send that patch or will you fix it up?

Paul

Quoted 48 lines

-----Original Message-----
From: Keir Fraser [mailto:[email protected]]
Sent: 29 November 2011 09:20
To: Ross Philipson; Paul Durrant; [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 1 line · Ross Philipson
Quoted 1 line

I have no problem choosing a different _HID. I just don't have a

good

Quoted 1 line
Quoted 1 line

reference for what name is not going to clash with something

else.

Quoted 1 line
Quoted 1 line

Looks like ACPI0001 was a bad guess. Any better suggestions? What

are

Quoted 5 lines
Quoted 3 lines

the 'generic PNP device IDs'?

Paul

Well I actually brought it up as a discussion point. I have the

same

Quoted 1 line

sort of issue - I have a generic device for a virtualized

environment.

Quoted 1 line

I don't really want it to be recognized as anything specific. I

guess I see three options:

Quoted 2 lines

- Use an unassigned APCIXXXX string. I believe the _HID string

values

Quoted 3 lines

of the form "ACPIXXXX" are defined by the ACPI specs themselves so this may not work in the long run.
- Use one of the predefined generic container EisaId PNP values.

By

Quoted 1 line

that I meant using EisaId(PNP0A05) or EisaId(PNP0A06). Looking at

the

Quoted 2 lines

Linux generic container driver, it doesn't do very much with these devices so that might be OK.

This option sounds reasonable. We have freedom to change it in future if it turns out to be a bad choice, not that I can see why it would be.

-- Keir

Quoted 2 lines

- Acquire a vendor specific EisaId range for Xen (e.g.
EisaId(XENABCD)). Then we could carve up the product number part

of the ID as we see fit.

#8 lore raw

Re: [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

I have been using EisaId(PNP0A06) in my device without any noticeable ill effect. I see that one in use in various DSDT's I have picked apart too (though I don't see the 0A05 one). So it gets my vote.

Thanks
Ross

Quoted 69 lines

-----Original Message-----
From: Keir Fraser [mailto:[email protected]]
Sent: Tuesday, November 29, 2011 6:14 AM
To: Paul Durrant; Ross Philipson; [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Pick a name and I can fix it up. :-)

-- Keir

Quoted 55 lines · Paul Durrant

Keir,

Do you want me to re-send that patch or will you fix it up?

Paul

Quoted 48 lines

-----Original Message-----
From: Keir Fraser [mailto:[email protected]]
Sent: 29 November 2011 09:20
To: Ross Philipson; Paul Durrant; [email protected]
Subject: Re: [Xen-devel] [PATCH 1 of 6] Add an ACPI device exposing a package called ADDR, evaluating to two

Quoted 1 line · Ross Philipson
Quoted 1 line

I have no problem choosing a different _HID. I just don't have a

good

Quoted 1 line
Quoted 1 line

reference for what name is not going to clash with something

else.

Quoted 1 line
Quoted 1 line

Looks like ACPI0001 was a bad guess. Any better suggestions? What

are

Quoted 5 lines
Quoted 3 lines

the 'generic PNP device IDs'?

Paul

Well I actually brought it up as a discussion point. I have the

same

Quoted 1 line

sort of issue - I have a generic device for a virtualized

environment.

Quoted 1 line

I don't really want it to be recognized as anything specific. I

guess I see three options:

Quoted 2 lines

- Use an unassigned APCIXXXX string. I believe the _HID string

values

Quoted 3 lines

of the form "ACPIXXXX" are defined by the ACPI specs themselves so this may not work in the long run.
- Use one of the predefined generic container EisaId PNP values.

By

Quoted 1 line

that I meant using EisaId(PNP0A05) or EisaId(PNP0A06). Looking at

the

Quoted 2 lines

Linux generic container driver, it doesn't do very much with these devices so that might be OK.

This option sounds reasonable. We have freedom to change it in future if it turns out to be a bad choice, not that I can see why it would be.

-- Keir

Quoted 2 lines

- Acquire a vendor specific EisaId range for Xen (e.g.
EisaId(XENABCD)). Then we could carve up the product number part

of the ID as we see fit.

#9 lore raw

PATCH 1/1 Add 'ctype' infrastructure to hvmloader

In reply to Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date 1322563734 0
# Node ID ec35c9c5a0c053532de953f59f7c8f28ba69167a # Parent ac68bd6d4853fdde5a24d78a7d0f1cee69f5416e Add 'ctype' infrastructure to hvmloader.

tools/firmware/hvmloader/Makefile +1 -1
diff -r ac68bd6d4853 -r ec35c9c5a0c0 tools/firmware/hvmloader/Makefile
@@ -30,7 +30,7 @@ CFLAGS += $(CFLAGS_xeninclude)
 
 OBJS  = hvmloader.o mp_tables.o util.o smbios.o 
 OBJS += 32bitbios_support.o smp.o cacheattr.o xenbus.o
-OBJS += e820.o pci.o pir.o
+OBJS += e820.o pci.o pir.o ctype.o
 ifeq ($(debug),y)
 OBJS += tests.o
 endif
tools/firmware/hvmloader/ctype.c new file +27 -0
diff -r ac68bd6d4853 -r ec35c9c5a0c0 tools/firmware/hvmloader/ctype.c
@@ -0,0 +1,27 @@
+#include "ctype.h"
+
+const unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C,                        /* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,         /* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C,                        /* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C,                        /* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,                    /* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P,                        /* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D,                        /* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P,                        /* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,      /* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U,                        /* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U,                        /* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P,                        /* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,      /* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L,                        /* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L,                        /* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C,                        /* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                /* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
tools/firmware/hvmloader/ctype.h new file +30 -0
diff -r ac68bd6d4853 -r ec35c9c5a0c0 tools/firmware/hvmloader/ctype.h
@@ -0,0 +1,30 @@
+#ifndef __HVMLOADER_CTYPE_H__
+#define __HVMLOADER_CTYPE_H__
+
+#define _U	0x01	/* upper */
+#define _L	0x02	/* lower */
+#define _D	0x04	/* digit */
+#define _C	0x08	/* cntrl */
+#define _P	0x10	/* punct */
+#define _S	0x20	/* white space (space/lf/tab) */
+#define _X	0x40	/* hex digit */
+#define _SP	0x80	/* hard space (0x20) */
+
+extern const unsigned char _ctype[];
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c)	((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c)	((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c)	((__ismask(c)&(_C)) != 0)
+#define isdigit(c)	((__ismask(c)&(_D)) != 0)
+#define isgraph(c)	((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c)	((__ismask(c)&(_L)) != 0)
+#define isprint(c)	((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c)	((__ismask(c)&(_P)) != 0)
+#define isspace(c)	((__ismask(c)&(_S)) != 0)
+#define isupper(c)	((__ismask(c)&(_U)) != 0)
+#define isxdigit(c)	((__ismask(c)&(_D|_X)) != 0)
+
+#endif /* __HVMLOADER_CTYPE_H__ */
+
tools/firmware/hvmloader/util.c +1 -0
diff -r ac68bd6d4853 -r ec35c9c5a0c0 tools/firmware/hvmloader/util.c
@@ -21,6 +21,7 @@
 #include "util.h"
 #include "config.h"
 #include "hypercall.h"
+#include "ctype.h"
 #include <stdint.h>
 #include <xen/xen.h>
 #include <xen/memory.h>
tools/firmware/hvmloader/util.h +0 -2
diff -r ac68bd6d4853 -r ec35c9c5a0c0 tools/firmware/hvmloader/util.h
@@ -225,8 +225,6 @@ void perform_tests(void);
 #define perform_tests() ((void)0)
 #endif
 
-#define isdigit(c) ((c) >= '0' && (c) <= '9')
-
 extern char _start[], _end[];
 
 #endif /* __HVMLOADER_UTIL_H__ */
#10 lore raw

PATCH 1/1 Allocate an 8 byte buffer to contain the VM generation id and populate it

In reply to Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]>
# Date 1322563734 0
# Node ID 58cdfa17fb8801ab0a9e8133e0ec2ad47a426f5d
# Parent ec35c9c5a0c053532de953f59f7c8f28ba69167a
Allocate an 8 byte buffer to contain the VM generation id and populate it at boot time with a value read from "platform/generation_id". Also add code to libxl to populate this xenstore key with the value of a new 'generation_id' parameter in the VM config file.
Populate the ADDR package of VM_Gen_Counter ACPI device such that the first integer evaluates to the low order 32 bits of the buffer address and the second integer evaluates to the high order 32 bits of the buffer address.

tools/firmware/hvmloader/acpi/build.c +19 -0
diff -r ec35c9c5a0c0 -r 58cdfa17fb88 tools/firmware/hvmloader/acpi/build.c
@@ -297,6 +297,20 @@ static int construct_secondary_tables(un
     return nr_tables;
 }
 
+unsigned long new_vm_gid(void)
+{
+    uint64_t gid;
+    unsigned char *buf;
+
+    buf = mem_alloc(8, 8);
+    if (!buf) return 0;
+
+    gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0);
+    *(uint64_t *)buf = gid;
+
+    return virt_to_phys(buf);    
+}
+
 void acpi_build_tables(struct acpi_config *config, unsigned int physical)
 {
     struct acpi_info *acpi_info;
@@ -309,6 +323,7 @@ void acpi_build_tables(struct acpi_confi
     unsigned char       *dsdt;
     unsigned long        secondary_tables[16];
     int                  nr_secondaries, i;
+    unsigned long        vm_gid_addr;
 
     /* Allocate and initialise the acpi info area. */
     mem_hole_populate_ram(ACPI_INFO_PHYSICAL_ADDRESS >> PAGE_SHIFT, 1);
@@ -421,12 +436,16 @@ void acpi_build_tables(struct acpi_confi
                  offsetof(struct acpi_20_rsdp, extended_checksum),
                  sizeof(struct acpi_20_rsdp));
 
+    vm_gid_addr = new_vm_gid();
+    if (!vm_gid_addr) goto oom;
+
     acpi_info->com1_present = uart_exists(0x3f8);
     acpi_info->com2_present = uart_exists(0x2f8);
     acpi_info->lpt1_present = lpt_exists(0x378);
     acpi_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS);
     acpi_info->pci_min = pci_mem_start;
     acpi_info->pci_len = pci_mem_end - pci_mem_start;
+    acpi_info->vm_gid_addr = vm_gid_addr;
 
     return;
 
tools/firmware/hvmloader/util.c +72 -0

78 lines not on this page · raw message

tools/firmware/hvmloader/util.h +1 -0
diff -r ec35c9c5a0c0 -r 58cdfa17fb88 tools/firmware/hvmloader/util.h
@@ -152,6 +152,7 @@ int strncmp(const char *s1, const char *
 char *strcpy(char *dest, const char *src);
 char *strncpy(char *dest, const char *src, unsigned n);
 unsigned strlen(const char *s);
+long long strtoll(const char *s, char **end, int base);
 int memcmp(const void *s1, const void *s2, unsigned n);
 void *memcpy(void *dest, const void *src, unsigned n);
 void *memmove(void *dest, const void *src, unsigned n);
tools/libxl/libxl_create.c +4 -1
diff -r ec35c9c5a0c0 -r 58cdfa17fb88 tools/libxl/libxl_create.c
@@ -101,6 +101,7 @@ int libxl_init_build_info(libxl_ctx *ctx
         b_info->u.hvm.vpt_align = 1;
         b_info->u.hvm.timer_mode = 1;
         b_info->u.hvm.nested_hvm = 0;
+        b_info->u.hvm.generation_id = 0;
         break;
     case LIBXL_DOMAIN_TYPE_PV:
         b_info->u.pv.slack_memkb = 8 * 1024;
@@ -191,13 +192,15 @@ int libxl__domain_build(libxl__gc *gc,
         vments[4] = "start_time";
         vments[5] = libxl__sprintf(gc, "%lu.%02d", start_time.tv_sec,(int)start_time.tv_usec/10000);
 
-        localents = libxl__calloc(gc, 7, sizeof(char *));
+        localents = libxl__calloc(gc, 9, sizeof(char *));
         localents[0] = "platform/acpi";
         localents[1] = (info->u.hvm.acpi) ? "1" : "0";
         localents[2] = "platform/acpi_s3";
         localents[3] = (info->u.hvm.acpi_s3) ? "1" : "0";
         localents[4] = "platform/acpi_s4";
         localents[5] = (info->u.hvm.acpi_s4) ? "1" : "0";
+        localents[6] = "platform/generation-id";
+        localents[7] = libxl__sprintf(gc, "0x%llx", info->u.hvm.generation_id);
 
         break;
     case LIBXL_DOMAIN_TYPE_PV:
tools/libxl/libxl_types.idl +1 -0
diff -r ec35c9c5a0c0 -r 58cdfa17fb88 tools/libxl/libxl_types.idl
@@ -176,6 +176,7 @@ libxl_domain_build_info = Struct("domain
                                        ("vpt_align", bool),
                                        ("timer_mode", integer),
                                        ("nested_hvm", bool),
+                                       ("generation_id", uint64),
                                        ])),
                  ("pv", Struct(None, [("kernel", libxl_file_reference),
                                       ("slack_memkb", uint32),
tools/libxl/libxlu_cfg.c +28 -0
diff -r ec35c9c5a0c0 -r 58cdfa17fb88 tools/libxl/libxlu_cfg.c
@@ -232,7 +232,35 @@ int xlu_cfg_get_long(const XLU_Config *c
     return 0;
 }
 
+int xlu_cfg_get_long_long(const XLU_Config *cfg, const char *n,
+                          long long *value_r) {
+    long long ll;
+    XLU_ConfigSetting *set;
+    int e;
+    char *ep;
 
+    e= find_atom(cfg,n,&set);  if (e) return e;
+    errno= 0; ll= strtoll(set->values[0], &ep, 0);
+    e= errno;
+    if (errno) {
+        e= errno;
+        assert(e==EINVAL || e==ERANGE);
+        fprintf(cfg->report,
+                "%s:%d: warning: parameter `%s' could not be parsed"
+                " as a number: %s\n",
+                cfg->filename, set->lineno, n, strerror(e));
+        return e;
+    }
+    if (*ep || ep==set->values[0]) {
+        fprintf(cfg->report,
+                "%s:%d: warning: parameter `%s' is not a valid number\n",
+                cfg->filename, set->lineno, n);
+        return EINVAL;
+    }
+    *value_r= ll;
+    return 0;
+}
+ 
 int xlu_cfg_get_list(const XLU_Config *cfg, const char *n,
                      XLU_ConfigList **list_r, int *entries_r, int dont_warn) {
     XLU_ConfigSetting *set;
tools/libxl/libxlutil.h +1 -0
diff -r ec35c9c5a0c0 -r 58cdfa17fb88 tools/libxl/libxlutil.h
@@ -48,6 +48,7 @@ void xlu_cfg_destroy(XLU_Config*);
 int xlu_cfg_get_string(const XLU_Config*, const char *n, const char **value_r);
 int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n, char **value_r); /* free/strdup version */
 int xlu_cfg_get_long(const XLU_Config*, const char *n, long *value_r);
+int xlu_cfg_get_long_long(const XLU_Config*, const char *n, long long *value_r);
 
 int xlu_cfg_get_list(const XLU_Config*, const char *n,
                      XLU_ConfigList **list_r /* may be 0 */,
tools/libxl/xl_cmdimpl.c +4 -0
diff -r ec35c9c5a0c0 -r 58cdfa17fb88 tools/libxl/xl_cmdimpl.c
@@ -355,6 +355,7 @@ static void printf_info(int domid,
         printf("\t\t\t(vpt_align %d)\n", b_info->u.hvm.vpt_align);
         printf("\t\t\t(timer_mode %d)\n", b_info->u.hvm.timer_mode);
         printf("\t\t\t(nestedhvm %d)\n", b_info->u.hvm.nested_hvm);
+        printf("\t\t\t(generation_id %llx)\n", b_info->u.hvm.generation_id);
 
         printf("\t\t\t(device_model %s)\n", dm_info->device_model ? : "default");
         printf("\t\t\t(videoram %d)\n", dm_info->videoram);
@@ -523,6 +524,7 @@ static void parse_config_data(const char
 {
     const char *buf;
     long l;
+    long long ll;
     XLU_Config *config;
     XLU_ConfigList *vbds, *nics, *pcis, *cvfbs, *cpuids;
     int pci_power_mgmt = 0;
@@ -699,6 +701,8 @@ static void parse_config_data(const char
             b_info->u.hvm.timer_mode = l;
         if (!xlu_cfg_get_long (config, "nestedhvm", &l))
             b_info->u.hvm.nested_hvm = l;
+        if (!xlu_cfg_get_long_long (config, "generation_id", &ll))
+            b_info->u.hvm.generation_id = ll;
         break;
     case LIBXL_DOMAIN_TYPE_PV:
     {
#11 lore raw

PATCH 1/1 Add sprintf() to hvmloader

In reply to Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date 1322563734 0
# Node ID e9997777ab6d629b97a8b8f020c18f40c4cf3aa0 # Parent 58cdfa17fb8801ab0a9e8133e0ec2ad47a426f5d Add sprintf() to hvmloader.

tools/firmware/hvmloader/util.c +36 -13
diff -r 58cdfa17fb88 -r e9997777ab6d tools/firmware/hvmloader/util.c
@@ -528,7 +528,7 @@ static char *printnum(char *p, unsigned 
     return p;
 }
 
-static void _doprint(void (*put)(char), const char *fmt, va_list ap)
+static void _doprint(void (*emit)(char**, char), char **arg, const char *fmt, va_list ap)
 {
     char *str, c;
     int lflag, zflag, nflag;
@@ -540,7 +540,7 @@ static void _doprint(void (*put)(char), 
     {
         if ( *fmt != '%' )
         {
-            put(*fmt);
+            emit(arg, *fmt);
             continue;
         }
 
@@ -571,7 +571,7 @@ static void _doprint(void (*put)(char), 
                 if ( (c == 'd') && ((long)value < 0) )
                 {
                     value = -value;
-                    put('-');
+                    emit(arg, '-');
                 }
             }
             else
@@ -580,7 +580,7 @@ static void _doprint(void (*put)(char), 
                 if ( (c == 'd') && ((int)value < 0) )
                 {
                     value = -(int)value;
-                    put('-');
+                    emit(arg, '-');
                 }
             }
             str = buffer;
@@ -588,13 +588,13 @@ static void _doprint(void (*put)(char), 
                      c == 'o' ? 8 : ((c == 'x') || (c == 'X') ? 16 : 10));
             slen = strlen(str);
             for ( i = pad - slen; i > 0; i-- )
-                put(zflag ? '0' : ' ');
+                emit(arg, zflag ? '0' : ' ');
             while ( *str )
             {
                 char ch = *str++;
                 if ( (ch >= 'a') && (c == 'X') )
                     ch += 'A'-'a';
-                put(ch);
+                emit(arg, ch);
             }
         }
         else if ( c == 's' )
@@ -603,20 +603,20 @@ static void _doprint(void (*put)(char), 
             slen = strlen(str);
             if ( nflag == 0 )
                 for ( i = pad - slen; i > 0; i-- )
-                    put(' ');
+                    emit(arg, ' ');
             while ( *str )
-                put(*str++);
+                emit(arg, *str++);
             if ( nflag )
                 for ( i = pad - slen; i > 0; i-- )
-                    put(' ');
+                    emit(arg, ' ');
         }
         else if ( c == 'c' )
         {
-            put(va_arg(ap, int));
+            emit(arg, va_arg(ap, int));
         }
         else
         {
-            put(*fmt);
+            emit(arg, *fmt);
         }
     }
 }
@@ -626,12 +626,17 @@ static void putchar(char c)
     outb(0xe9, c);
 }
 
+static void __put(char **ignore, char c)
+{
+    putchar(c);
+}
+
 int printf(const char *fmt, ...)
 {
     va_list ap;
 
     va_start(ap, fmt);
-    _doprint(putchar, fmt, ap);
+    _doprint(__put, NULL, fmt, ap);
     va_end(ap);
 
     return 0;
@@ -639,7 +644,25 @@ int printf(const char *fmt, ...)
 
 int vprintf(const char *fmt, va_list ap)
 {
-    _doprint(putchar, fmt, ap);
+    _doprint(__put, NULL, fmt, ap);
+    return 0;
+}
+
+static void __copy(char **buf, char c)
+{
+    **buf = c;
+    (*buf)++;
+}
+
+int sprintf(char *buf, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    _doprint(__copy, &buf, fmt, ap);
+    va_end(ap);
+
+    *buf = '\0';
     return 0;
 }
 
tools/firmware/hvmloader/util.h +3 -0
diff -r 58cdfa17fb88 -r e9997777ab6d tools/firmware/hvmloader/util.h
@@ -171,6 +171,9 @@ void uuid_to_string(char *dest, uint8_t 
 int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
 int vprintf(const char *fmt, va_list ap);
 
+/* Buffer output */
+int sprintf(char *buf, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
 /* Populate specified memory hole with RAM. */
 void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns);
#12 lore raw

Re: [PATCH 4 of 6] Add sprintf() to hvmloader

Quoted 6 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant<[email protected]> # Date 1322563734 0
# Node ID e9997777ab6d629b97a8b8f020c18f40c4cf3aa0 # Parent 58cdfa17fb8801ab0a9e8133e0ec2ad47a426f5d Add sprintf() to hvmloader.

For security reasons I prefer snprintf().

Christoph

Quoted 149 lines

diff -r 58cdfa17fb88 -r e9997777ab6d tools/firmware/hvmloader/util.c

tools/firmware/hvmloader/util.c +36 -13
@@ -528,7 +528,7 @@ static char *printnum(char *p, unsigned
      return p;
  }
 
-static void _doprint(void (*put)(char), const char *fmt, va_list ap)
+static void _doprint(void (*emit)(char**, char), char **arg, const char *fmt, va_list ap)
  {
      char *str, c;
      int lflag, zflag, nflag;
@@ -540,7 +540,7 @@ static void _doprint(void (*put)(char),
      {
          if ( *fmt != '%' )
          {
-            put(*fmt);
+            emit(arg, *fmt);
              continue;
          }
 
@@ -571,7 +571,7 @@ static void _doprint(void (*put)(char),
                  if ( (c == 'd')&&  ((long)value<  0) )
                  {
                      value = -value;
-                    put('-');
+                    emit(arg, '-');
                  }
              }
              else
@@ -580,7 +580,7 @@ static void _doprint(void (*put)(char),
                  if ( (c == 'd')&&  ((int)value<  0) )
                  {
                      value = -(int)value;
-                    put('-');
+                    emit(arg, '-');
                  }
              }
              str = buffer;
@@ -588,13 +588,13 @@ static void _doprint(void (*put)(char),
                       c == 'o' ? 8 : ((c == 'x') || (c == 'X') ? 16 : 10));
              slen = strlen(str);
              for ( i = pad - slen; i>  0; i-- )
-                put(zflag ? '0' : ' ');
+                emit(arg, zflag ? '0' : ' ');
              while ( *str )
              {
                  char ch = *str++;
                  if ( (ch>= 'a')&&  (c == 'X') )
                      ch += 'A'-'a';
-                put(ch);
+                emit(arg, ch);
              }
          }
          else if ( c == 's' )
@@ -603,20 +603,20 @@ static void _doprint(void (*put)(char),
              slen = strlen(str);
              if ( nflag == 0 )
                  for ( i = pad - slen; i>  0; i-- )
-                    put(' ');
+                    emit(arg, ' ');
              while ( *str )
-                put(*str++);
+                emit(arg, *str++);
              if ( nflag )
                  for ( i = pad - slen; i>  0; i-- )
-                    put(' ');
+                    emit(arg, ' ');
          }
          else if ( c == 'c' )
          {
-            put(va_arg(ap, int));
+            emit(arg, va_arg(ap, int));
          }
          else
          {
-            put(*fmt);
+            emit(arg, *fmt);
          }
      }
  }
@@ -626,12 +626,17 @@ static void putchar(char c)
      outb(0xe9, c);
  }
 
+static void __put(char **ignore, char c)
+{
+    putchar(c);
+}
+
  int printf(const char *fmt, ...)
  {
      va_list ap;
 
      va_start(ap, fmt);
-    _doprint(putchar, fmt, ap);
+    _doprint(__put, NULL, fmt, ap);
      va_end(ap);
 
      return 0;
@@ -639,7 +644,25 @@ int printf(const char *fmt, ...)
 
  int vprintf(const char *fmt, va_list ap)
  {
-    _doprint(putchar, fmt, ap);
+    _doprint(__put, NULL, fmt, ap);
+    return 0;
+}
+
+static void __copy(char **buf, char c)
+{
+    **buf = c;
+    (*buf)++;
+}
+
+int sprintf(char *buf, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    _doprint(__copy,&buf, fmt, ap);
+    va_end(ap);
+
+    *buf = '\0';
      return 0;
  }
 

diff -r 58cdfa17fb88 -r e9997777ab6d tools/firmware/hvmloader/util.h

tools/firmware/hvmloader/util.h +3 -0
@@ -171,6 +171,9 @@ void uuid_to_string(char *dest, uint8_t
  int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
  int vprintf(const char *fmt, va_list ap);
 
+/* Buffer output */
+int sprintf(char *buf, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
+
  /* Populate specified memory hole with RAM. */
  void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns);
 

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xensource.com/xen-devel

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
#13 lore raw

Re: [PATCH 4 of 6] Add sprintf() to hvmloader

Quoted 7 lines

-----Original Message-----
From: Christoph Egger [mailto:[email protected]]
Sent: 29 November 2011 11:02
To: Paul Durrant
Cc: [email protected]
Subject: Re: [Xen-devel] [PATCH 4 of 6] Add sprintf() to hvmloader

Quoted 9 lines
Quoted 5 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant<[email protected]> # Date 1322563734 0 # Node ID e9997777ab6d629b97a8b8f020c18f40c4cf3aa0
# Parent 58cdfa17fb8801ab0a9e8133e0ec2ad47a426f5d
Add sprintf() to hvmloader.

For security reasons I prefer snprintf().

Given the limited usecase, I decided it wasn't worth it but I can tag on a extra patch to make the conversion if you want me to.

Paul

#14 lore raw

Re: [PATCH 4 of 6] Add sprintf() to hvmloader

Quoted 14 lines · Paul Durrant
Quoted 14 lines

-----Original Message-----
From: Christoph Egger [mailto:[email protected]]
Sent: 29 November 2011 11:02
To: Paul Durrant
Cc: [email protected]
Subject: Re: [Xen-devel] [PATCH 4 of 6] Add sprintf() to hvmloader

Quoted 5 lines · Paul Durrant

# HG changeset patch
# User Paul Durrant<[email protected]> # Date 1322563734 0 # Node ID e9997777ab6d629b97a8b8f020c18f40c4cf3aa0
# Parent 58cdfa17fb8801ab0a9e8133e0ec2ad47a426f5d
Add sprintf() to hvmloader.

Quoted 5 lines
Quoted 2 lines

For security reasons I prefer snprintf().

Given the limited usecase, I decided it wasn't worth it but I can tag on a extra patch to make the conversion if you want me to.

Yes, please. This makes new code less prone to buffer overflows in general.

Christoph

Signature · 6 lines
---to satisfy European Law for business letters:
Advanced Micro Devices GmbH
Einsteinring 24, 85689 Dornach b. Muenchen
Geschaeftsfuehrer: Alberto Bozzo, Andrew Bowd
Sitz: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
#15 lore raw

PATCH 1/1 Add xenstore-write support to hvmloader

In reply to Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]> # Date 1322563734 0
# Node ID acc408d667e139c6b8b96e1ec51e65d159d72b67 # Parent e9997777ab6d629b97a8b8f020c18f40c4cf3aa0 Add xenstore-write support to hvmloader.

tools/firmware/hvmloader/util.h +5 -0
diff -r e9997777ab6d -r acc408d667e1 tools/firmware/hvmloader/util.h
@@ -202,6 +202,11 @@ void xenbus_shutdown(void);
  */
 const char *xenstore_read(const char *path, const char *default_resp);
 
+/* Write a xenstore key.  @value must be a nul-terminated string. Returns
+ * zero on success or a xenstore error code on failure.
+ */
+int xenstore_write(const char *path, const char *value);
+
 /* Setup PCI bus */
 void pci_setup(void);
 
tools/firmware/hvmloader/xenbus.c +60 -16

124 lines not on this page · raw message

#16 lore raw

PATCH 1/1 Add code to track the address of the VM generation id buffer across a

In reply to Paul Durrant

# HG changeset patch
# User Paul Durrant <[email protected]>
# Date 1322563734 0
# Node ID 225da1242ba979ddc8c48767d3822e0c8d274ae1
# Parent acc408d667e139c6b8b96e1ec51e65d159d72b67
Add code to track the address of the VM generation id buffer across a save/restore or migrate and inject a new value.
The address of the buffer is written into xenstore by hvmloader at boot time. It must be read from xenstore by the caller of xc_domain_save() and then written back again by the caller of xc_domain_restore().

tools/firmware/hvmloader/acpi/build.c +4 -0
diff -r acc408d667e1 -r 225da1242ba9 tools/firmware/hvmloader/acpi/build.c
@@ -301,10 +301,14 @@ unsigned long new_vm_gid(void)
 {
     uint64_t gid;
     unsigned char *buf;
+    char addr[11];
 
     buf = mem_alloc(8, 8);
     if (!buf) return 0;
 
+    sprintf(addr, "0x%lx", virt_to_phys(buf));
+    xenstore_write("data/generation-id", addr);
+
     gid = strtoll(xenstore_read("platform/generation-id", "0"), NULL, 0);
     *(uint64_t *)buf = gid;
 
tools/libxc/ia64/xc_ia64_linux_restore.c +2 -1
diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/ia64/xc_ia64_linux_restore.c
@@ -548,7 +548,8 @@ int
 xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                   unsigned int store_evtchn, unsigned long *store_mfn,
                   unsigned int console_evtchn, unsigned long *console_mfn,
-                  unsigned int hvm, unsigned int pae, int superpages)
+                  unsigned int hvm, unsigned int pae, int superpages,
+                  uint64_t gid)
 {
     DECLARE_DOMCTL;
     int rc = 1;
tools/libxc/ia64/xc_ia64_linux_save.c +2 -1
diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/ia64/xc_ia64_linux_save.c
@@ -382,7 +382,8 @@ out:
 int
 xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
                uint32_t max_factor, uint32_t flags,
-               struct save_callbacks* callbacks, int hvm)
+               struct save_callbacks* callbacks, int hvm,
+               unsigned long vm_gid_addr)
 {
     DECLARE_DOMCTL;
     xc_dominfo_t info;
tools/libxc/xc_domain_restore.c +41 -1

66 lines not on this page · raw message

tools/libxc/xc_domain_save.c +12 -1
diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/xc_domain_save.c
@@ -754,7 +754,8 @@ static int save_tsc_info(xc_interface *x
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
                    uint32_t max_factor, uint32_t flags,
-                   struct save_callbacks* callbacks, int hvm)
+                   struct save_callbacks* callbacks, int hvm,
+                   unsigned long vm_gid_addr)
 {
     xc_dominfo_t info;
     DECLARE_DOMCTL;
@@ -1460,6 +1461,16 @@ int xc_domain_save(xc_interface *xch, in
             uint64_t data;
         } chunk = { 0, };
 
+        chunk.id = XC_SAVE_ID_HVM_GENERATION_ID_ADDR;
+        chunk.data = vm_gid_addr;
+
+        if ( (chunk.data != 0) &&
+             wrexact(io_fd, &chunk, sizeof(chunk)) )
+        {
+            PERROR("Error when writing the generation id buffer location for guest");
+            goto out;
+        }
+
         chunk.id = XC_SAVE_ID_HVM_IDENT_PT;
         chunk.data = 0;
         xc_get_hvm_param(xch, dom, HVM_PARAM_IDENT_PT,
tools/libxc/xenguest.h +6 -2
diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/xenguest.h
@@ -57,7 +57,8 @@ struct save_callbacks {
  */
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
                    uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
-                   struct save_callbacks* callbacks, int hvm);
+                   struct save_callbacks* callbacks, int hvm,
+                   unsigned long vm_gid_addr);
 
 
 /**
@@ -71,12 +72,15 @@ int xc_domain_save(xc_interface *xch, in
  * @parm hvm non-zero if this is a HVM restore
  * @parm pae non-zero if this HVM domain has PAE support enabled
  * @parm superpages non-zero to allocate guest memory with superpages
+ * @parm gid the new generation id of the VM
+ * @parm vm_gid_addr returned with the address of the generation id buffer
  * @return 0 on success, -1 on failure
  */
 int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
                       unsigned int console_evtchn, unsigned long *console_mfn,
-                      unsigned int hvm, unsigned int pae, int superpages);
+                      unsigned int hvm, unsigned int pae, int superpages,
+                      uint64_t gid, unsigned long *vm_gid_addr);
 /**
  * xc_domain_restore writes a file to disk that contains the device
  * model saved state.
tools/libxc/xg_save_restore.h +1 -0
diff -r acc408d667e1 -r 225da1242ba9 tools/libxc/xg_save_restore.h
@@ -135,6 +135,7 @@
 #define XC_SAVE_ID_LAST_CHECKPOINT    -9 /* Commit to restoring after completion of current iteration. */
 #define XC_SAVE_ID_HVM_ACPI_IOPORTS_LOCATION -10
 #define XC_SAVE_ID_HVM_VIRIDIAN       -11
+#define XC_SAVE_ID_HVM_GENERATION_ID_ADDR -12
 
 /*
 ** We process save/restore/migrate in batches of pages; the below
tools/libxl/libxl_dom.c +22 -6
diff -r acc408d667e1 -r 225da1242ba9 tools/libxl/libxl_dom.c
@@ -108,7 +108,7 @@ int libxl__build_post(libxl__gc *gc, uin
     if (info->cpuid != NULL)
         libxl_cpuid_set(ctx, domid, info->cpuid);
 
-    ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
+    ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, sizeof(char *));
     ents[0] = "memory/static-max";
     ents[1] = libxl__sprintf(gc, "%d", info->max_memkb);
     ents[2] = "memory/target";
@@ -121,9 +121,11 @@ int libxl__build_post(libxl__gc *gc, uin
     ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port);
     ents[10] = "store/ring-ref";
     ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn);
+    ents[12] = "data/generation-id";
+    ents[13] = libxl__sprintf(gc, "0x%lx", state->vm_gid_addr);
     for (i = 0; i < info->max_vcpus; i++) {
-        ents[12+(i*2)]   = libxl__sprintf(gc, "cpu/%d/availability", i);
-        ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i)))
+        ents[14+(i*2)]   = libxl__sprintf(gc, "cpu/%d/availability", i);
+        ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i)))
                             ? "offline" : "online";
     }
 
@@ -340,16 +342,19 @@ int libxl__domain_restore_common(libxl__
     /* read signature */
     int rc;
     int hvm, pae, superpages;
+    uint64_t gid;
     switch (info->type) {
     case LIBXL_DOMAIN_TYPE_HVM:
         hvm = 1;
         superpages = 1;
         pae = info->u.hvm.pae;
+        gid = info->u.hvm.generation_id;
         break;
     case LIBXL_DOMAIN_TYPE_PV:
         hvm = 0;
         superpages = 0;
         pae = 1;
+        gid = 0;
         break;
     default:
         return ERROR_INVAL;
@@ -357,7 +362,7 @@ int libxl__domain_restore_common(libxl__
     rc = xc_domain_restore(ctx->xch, fd, domid,
                            state->store_port, &state->store_mfn,
                            state->console_port, &state->console_mfn,
-                           hvm, pae, superpages);
+                           hvm, pae, superpages, gid, &state->vm_gid_addr);
     if ( rc ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "restoring domain");
         return ERROR_FAIL;
@@ -523,12 +528,22 @@ int libxl__domain_suspend_common(libxl__
     struct save_callbacks callbacks;
     struct suspendinfo si;
     int hvm, rc = ERROR_FAIL;
+    unsigned long vm_gid_addr;
 
     switch (type) {
-    case LIBXL_DOMAIN_TYPE_HVM:
+    case LIBXL_DOMAIN_TYPE_HVM: {
+        char *path;
+        char *addr;
+
+        path = libxl__sprintf(gc, "%s/data/generation-id", libxl__xs_get_dompath(gc, domid));
+        addr = libxl__xs_read(gc, XBT_NULL, path);
+
+        vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0;
         hvm = 1;
         break;
+    }
     case LIBXL_DOMAIN_TYPE_PV:
+        vm_gid_addr = 0;
         hvm = 0;
         break;
     default:
@@ -566,7 +581,8 @@ int libxl__domain_suspend_common(libxl__
     callbacks.switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty;
     callbacks.data = &si;
 
-    rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm);
+    rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks,
+                        hvm, vm_gid_addr);
     if ( rc ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain: %s",
                          si.guest_responded ?
tools/libxl/libxl_internal.h +2 -0
diff -r acc408d667e1 -r 225da1242ba9 tools/libxl/libxl_internal.h
@@ -199,6 +199,8 @@ typedef struct {
 
     uint32_t console_port;
     unsigned long console_mfn;
+
+    unsigned long vm_gid_addr;
 } libxl__domain_build_state;
 
 _hidden int libxl__build_pre(libxl__gc *gc, uint32_t domid,
tools/python/xen/lowlevel/checkpoint/libcheckpoint.c +13 -1
diff -r acc408d667e1 -r 225da1242ba9 tools/python/xen/lowlevel/checkpoint/libcheckpoint.c
@@ -174,6 +174,7 @@ int checkpoint_start(checkpoint_state* s
 {
     int hvm, rc;
     int flags = XCFLAGS_LIVE;
+    unsigned long vm_gid_addr;
 
     if (!s->domid) {
        s->errstr = "checkpoint state not opened";
@@ -184,14 +185,25 @@ int checkpoint_start(checkpoint_state* s
 
     hvm = s->domtype > dt_pv;
     if (hvm) {
+       char path[128];
+       char *addr;
+
+       sprintf(path, "/local/domain/%u/data/generation-id", s->domid);
+       addr = xs_read(s->xsh, XBT_NULL, path, NULL);
+
+       vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0;
+       free(addr);
+
        flags |= XCFLAGS_HVM;
        if (switch_qemu_logdirty(s, 1))
            return -1;
+    } else {
+       vm_gid_addr = 0;
     }
 
     callbacks->switch_qemu_logdirty = noop_switch_logdirty;
 
-    rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm);
+    rc = xc_domain_save(s->xch, fd, s->domid, 0, 0, flags, callbacks, hvm, vm_gid_addr);
 
     if (hvm)
        switch_qemu_logdirty(s, 0);
tools/xcutils/xc_restore.c +10 -3
diff -r acc408d667e1 -r 225da1242ba9 tools/xcutils/xc_restore.c
@@ -23,7 +23,8 @@ main(int argc, char **argv)
     xc_interface *xch;
     int io_fd, ret;
     int superpages;
-    unsigned long store_mfn, console_mfn;
+    unsigned long store_mfn, console_mfn, vm_gid_addr;
+    uint64_t gid;
 
     if ( (argc != 8) && (argc != 9) )
         errx(1, "usage: %s iofd domid store_evtchn "
@@ -40,19 +41,25 @@ main(int argc, char **argv)
     hvm  = atoi(argv[5]);
     pae  = atoi(argv[6]);
     apic = atoi(argv[7]);
-    if ( argc == 9 )
+    if ( argc >= 9 )
 	    superpages = atoi(argv[8]);
     else
 	    superpages = !!hvm;
+    if ( argc >= 10 )
+	    gid = strtoll(argv[9], NULL, 0);
+    else
+	    gid = 0;
 
     ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn,
-                            console_evtchn, &console_mfn, hvm, pae, superpages);
+                            console_evtchn, &console_mfn, hvm, pae, superpages,
+                            gid, &vm_gid_addr);
 
     if ( ret == 0 )
     {
 	printf("store-mfn %li\n", store_mfn);
         if ( !hvm )
             printf("console-mfn %li\n", console_mfn);
+	printf("vm-gid-addr %lx\n", vm_gid_addr);
 	fflush(stdout);
     }
 
tools/xcutils/xc_save.c +18 -1
diff -r acc408d667e1 -r 225da1242ba9 tools/xcutils/xc_save.c
@@ -169,6 +169,10 @@ main(int argc, char **argv)
     unsigned int maxit, max_f;
     int io_fd, ret, port;
     struct save_callbacks callbacks;
+    char path[128];
+    struct xs_handle *xs;
+    char *addr;
+    unsigned long vm_gid_addr;
 
     if (argc != 6)
         errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
@@ -207,8 +211,21 @@ main(int argc, char **argv)
     memset(&callbacks, 0, sizeof(callbacks));
     callbacks.suspend = suspend;
     callbacks.switch_qemu_logdirty = switch_qemu_logdirty;
+
+    sprintf(path, "/local/domain/%d/data/generation-id", si.domid);
+
+    if ((xs = xs_daemon_open()) == NULL)
+        errx(1, "Couldn't contact xenstore");
+
+    addr = xs_read(xs, XBT_NULL, path, NULL);
+
+    xs_daemon_close(xs);
+
+    vm_gid_addr = (addr) ? strtoul(addr, NULL, 0) : 0;
+    free(addr);
+
     ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, si.flags, 
-                         &callbacks, !!(si.flags & XCFLAGS_HVM));
+                         &callbacks, !!(si.flags & XCFLAGS_HVM), vm_gid_addr);
 
     if (si.suspend_evtchn > 0)
 	 xc_suspend_evtchn_release(si.xch, si.xce, si.domid, si.suspend_evtchn);
Applied
#17 lore raw
In reply to Paul Durrant
Quoted 2 lines · Paul Durrant

Patch 1 adds the device and an acpi_info field to allow population of the ADDR package.

Applied.

Quoted 1 line

Patch 2 adds ctype infrastructure to hvloader in preparation for...

Applied.

Quoted 3 lines

Patch 3 adds all the code to plumb the value of a new 'generation_id' parameter in the VM config through to the VM generation id buffer at VM boot time.

Applied the hvmloader part. Forgot to change the comment that refers to libxl, oops! But I didn;t check in the libxl part (it didn't apply cleanly to tip anyway).

Quoted 1 line

Patch 4 adds an implementation of sprintf() to hvmloader.

Applied (inc. snprintf update).

Quoted 1 line

Patch 5 adds an implementation of xenstore-write to hvmloader.

Applied (inc. incremental fix).

Quoted 3 lines

Patch 6 adds support for tracking the address of the VM generation id buffer (via xenstore) across save/restore or migrate and updating the value of the buffer with the value from the VM config file.

Applied the hvmloader part.

In summary, all the hvmloader changes are in. A toolstack maintainer should check in the other toolstack parts.

-- Keir

#18 lore raw

Ok, thanks. I'll re-sync my tree and re-spin the xl/libxl bits.

Paul

Quoted 51 lines

-----Original Message-----
From: Keir Fraser [mailto:[email protected]]
Sent: 30 November 2011 07:19
To: Paul Durrant; [email protected]
Subject: Re: [Xen-devel] [PATCH 0 of 6] Add support for a VM generation ID virtual device (v2)

Quoted 1 line · Paul Durrant

Patch 1 adds the device and an acpi_info field to allow population

of

Quoted 1 line

the ADDR package.

Applied.

Quoted 1 line

Patch 2 adds ctype infrastructure to hvloader in preparation

for...

Applied.

Quoted 1 line

Patch 3 adds all the code to plumb the value of a new

'generation_id'

Quoted 1 line

parameter in the VM config through to the VM generation id buffer

at

Quoted 1 line

VM boot time.

Applied the hvmloader part. Forgot to change the comment that refers to libxl, oops! But I didn;t check in the libxl part (it didn't apply cleanly to tip anyway).

Quoted 1 line

Patch 4 adds an implementation of sprintf() to hvmloader.

Applied (inc. snprintf update).

Quoted 1 line

Patch 5 adds an implementation of xenstore-write to hvmloader.

Applied (inc. incremental fix).

Quoted 1 line

Patch 6 adds support for tracking the address of the VM generation

id

Quoted 1 line

buffer (via xenstore) across save/restore or migrate and updating

the

Quoted 1 line

value of the buffer with the value from the VM config file.

Applied the hvmloader part.

In summary, all the hvmloader changes are in. A toolstack maintainer should check in the other toolstack parts.

-- Keir