Message ID | 2187e535bf91f5f650401a4e08e0e795003ad2aa.1332430810.git.julien.grall@citrix.com |
---|---|
State | New |
Headers | show |
>>> On 22.03.12 at 16:59, Julien Grall <julien.grall@citrix.com> wrote: > --- a/xen/include/public/hvm/hvm_op.h > +++ b/xen/include/public/hvm/hvm_op.h > @@ -24,6 +24,8 @@ > #include "../xen.h" > #include "../trace.h" > > +#include "hvm_info_table.h" /* HVM_MAX_VCPUS */ > + > /* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. > */ > #define HVMOP_set_param 0 > #define HVMOP_get_param 1 > @@ -227,6 +229,53 @@ struct xen_hvm_inject_trap { > typedef struct xen_hvm_inject_trap xen_hvm_inject_trap_t; > DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_trap_t); > > +#define HVMOP_register_ioreq_server 20 > +struct xen_hvm_register_ioreq_server { > + domid_t domid; /* IN - domain to be serviced */ > + unsigned int id; /* OUT - handle for identifying this server */ > +}; > +typedef struct xen_hvm_register_ioreq_server > xen_hvm_register_ioreq_server_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_register_ioreq_server_t); > + > +#define HVMOP_get_ioreq_server_buf_channel 21 > +struct xen_hvm_get_ioreq_server_buf_channel { > + domid_t domid; /* IN - domain to be serviced */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ > + unsigned int channel; /* OUT - buf ioreq channel */ > +}; > +typedef struct xen_hvm_get_ioreq_server_buf_channel > xen_hvm_get_ioreq_server_buf_channel_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_buf_channel_t); > + > +#define HVMOP_map_io_range_to_ioreq_server 22 > +struct xen_hvm_map_io_range_to_ioreq_server { > + domid_t domid; /* IN - domain to be serviced */ > + uint8_t is_mmio; /* IN - MMIO or port IO? */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server > */ > + uint64_aligned_t s, e; /* IN - inclusive start and end of range */ > +}; > +typedef struct xen_hvm_map_io_range_to_ioreq_server > xen_hvm_map_io_range_to_ioreq_server_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_map_io_range_to_ioreq_server_t); > + > +#define HVMOP_unmap_io_range_from_ioreq_server 23 > +struct xen_hvm_unmap_io_range_from_ioreq_server { > + domid_t domid; /* IN - domain to be serviced */ > + uint8_t is_mmio; /* IN - MMIO or port IO? */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server > */ > + uint64_aligned_t addr; /* IN - address inside the range to remove */ > +}; > +typedef struct xen_hvm_unmap_io_range_from_ioreq_server > xen_hvm_unmap_io_range_from_ioreq_server_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_unmap_io_range_from_ioreq_server_t); > + > +#define HVMOP_register_pcidev 24 > +struct xen_hvm_register_pcidev { > + domid_t domid; /* IN - domain to be serviced */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ > + uint16_t bdf; /* IN - pci */ Can we please avoid the mistake of again not surfacing the PCI segment in interface definitions, even if it may be required to be zero for the immediate needs? Jan > +}; > +typedef struct xen_hvm_register_pcidev xen_hvm_register_pcidev_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_register_pcidev_t); > + > + > #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ > > #define HVMOP_get_mem_type 15
On Thu, 2012-03-22 at 15:59 +0000, Julien Grall wrote: > Add structure to handle ioreq server. It's server which can > handle a range of IO (MMIO and/or PIO) and emulate a PCI. > Each server as its own shared page to receive ioreq. So > we have introduced to HVM PARAM to set/get the first and > the last shared used for ioreq. > With it's id, the server knows which page it must use. So id is always the page offset with the range? Why not just call it iobuf_offset then? Is the additional layer of abstraction from calling it "id" useful if we are just going to peek around it? > We introduce a new kind a ioreq type IOREQ_TYPE_PCICONFIG > which permit to forward easily PCI config space access. > > Signed-off-by: Julien Grall <julien.grall@citrix.com> > --- > [...] > xen/include/public/hvm/hvm_op.h | 49 ++++++++++++++++++++++++++++++++++++++ > xen/include/public/hvm/ioreq.h | 1 + > xen/include/public/hvm/params.h | 6 ++++- > xen/include/public/xen.h | 1 + I only looked at the public interface changes so far. > diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h > index 6a78f75..1e0e27b 100644 > --- a/xen/include/public/hvm/hvm_op.h > +++ b/xen/include/public/hvm/hvm_op.h > @@ -24,6 +24,8 @@ > #include "../xen.h" > #include "../trace.h" > > +#include "hvm_info_table.h" /* HVM_MAX_VCPUS */ You don't appear to use HVM_MAX_VCPUS anywhere in your additions? > /* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */ > #define HVMOP_set_param 0 > #define HVMOP_get_param 1 > @@ -227,6 +229,53 @@ struct xen_hvm_inject_trap { > typedef struct xen_hvm_inject_trap xen_hvm_inject_trap_t; > DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_trap_t); > > +#define HVMOP_register_ioreq_server 20 > +struct xen_hvm_register_ioreq_server { > + domid_t domid; /* IN - domain to be serviced */ > + unsigned int id; /* OUT - handle for identifying this server */ elsewhere this is called servid_t? > +}; > +typedef struct xen_hvm_register_ioreq_server xen_hvm_register_ioreq_server_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_register_ioreq_server_t); > + > +#define HVMOP_get_ioreq_server_buf_channel 21 > +struct xen_hvm_get_ioreq_server_buf_channel { > + domid_t domid; /* IN - domain to be serviced */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ > + unsigned int channel; /* OUT - buf ioreq channel */ evtchn_port_t? > +}; > +typedef struct xen_hvm_get_ioreq_server_buf_channel xen_hvm_get_ioreq_server_buf_channel_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_buf_channel_t); > + > +#define HVMOP_map_io_range_to_ioreq_server 22 > +struct xen_hvm_map_io_range_to_ioreq_server { > + domid_t domid; /* IN - domain to be serviced */ > + uint8_t is_mmio; /* IN - MMIO or port IO? */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ > + uint64_aligned_t s, e; /* IN - inclusive start and end of range */ > +}; > +typedef struct xen_hvm_map_io_range_to_ioreq_server xen_hvm_map_io_range_to_ioreq_server_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_map_io_range_to_ioreq_server_t); > + > +#define HVMOP_unmap_io_range_from_ioreq_server 23 > +struct xen_hvm_unmap_io_range_from_ioreq_server { > + domid_t domid; /* IN - domain to be serviced */ > + uint8_t is_mmio; /* IN - MMIO or port IO? */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ > + uint64_aligned_t addr; /* IN - address inside the range to remove */ > +}; > +typedef struct xen_hvm_unmap_io_range_from_ioreq_server xen_hvm_unmap_io_range_from_ioreq_server_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_unmap_io_range_from_ioreq_server_t); > + > +#define HVMOP_register_pcidev 24 > +struct xen_hvm_register_pcidev { > + domid_t domid; /* IN - domain to be serviced */ > + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ > + uint16_t bdf; /* IN - pci */ > +}; > +typedef struct xen_hvm_register_pcidev xen_hvm_register_pcidev_t; > +DEFINE_XEN_GUEST_HANDLE(xen_hvm_register_pcidev_t); > + > + > #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ > > #define HVMOP_get_mem_type 15 > diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h > index 4022a1d..87aacd3 100644 > --- a/xen/include/public/hvm/ioreq.h > +++ b/xen/include/public/hvm/ioreq.h > @@ -34,6 +34,7 @@ > > #define IOREQ_TYPE_PIO 0 /* pio */ > #define IOREQ_TYPE_COPY 1 /* mmio ops */ > +#define IOREQ_TYPE_PCI_CONFIG 2 /* pci config space ops */ > #define IOREQ_TYPE_TIMEOFFSET 7 > #define IOREQ_TYPE_INVALIDATE 8 /* mapcache */ > > diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h > index 55c1b57..309ac1b 100644 > --- a/xen/include/public/hvm/params.h > +++ b/xen/include/public/hvm/params.h > @@ -147,6 +147,10 @@ > #define HVM_PARAM_ACCESS_RING_PFN 28 > #define HVM_PARAM_SHARING_RING_PFN 29 > > -#define HVM_NR_PARAMS 30 > +/* Param for ioreq servers */ > +#define HVM_PARAM_IO_PFN_FIRST 30 > +#define HVM_PARAM_IO_PFN_LAST 31 > + > +#define HVM_NR_PARAMS 32 > > #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ > diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h > index b2f6c50..26d0e9d 100644 > --- a/xen/include/public/xen.h > +++ b/xen/include/public/xen.h > @@ -466,6 +466,7 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); > #ifndef __ASSEMBLY__ > > typedef uint16_t domid_t; > +typedef uint32_t servid_t; ioservid_t? > /* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */ > #define DOMID_FIRST_RESERVED (0x7FF0U)
On 03/23/2012 08:18 AM, Jan Beulich wrote: >> +#define HVMOP_register_pcidev 24 >> +struct xen_hvm_register_pcidev { >> + domid_t domid; /* IN - domain to be serviced */ >> + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ >> + uint16_t bdf; /* IN - pci */ >> > Can we please avoid the mistake of again not surfacing the PCI > segment in interface definitions, even if it may be required to be > zero for the immediate needs? > What do you hear by surfacing the PCI segment ? Do I need to add the PCI domain ?
>>> On 26.03.12 at 14:32, Julien Grall <julien.grall@citrix.com> wrote: > On 03/23/2012 08:18 AM, Jan Beulich wrote: >>> +#define HVMOP_register_pcidev 24 >>> +struct xen_hvm_register_pcidev { >>> + domid_t domid; /* IN - domain to be serviced */ >>> + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ >>> + uint16_t bdf; /* IN - pci */ >>> >> Can we please avoid the mistake of again not surfacing the PCI >> segment in interface definitions, even if it may be required to be >> zero for the immediate needs? >> > > What do you hear by surfacing the PCI segment ? > Do I need to add the PCI domain ? "domain" and "segment" appear to be used interchangeably. Jan
Julien Grall writes ("[Xen-devel] [XEN][RFC PATCH 01/15] hvm: Modify interface to support multiple ioreq server"): > Add structure to handle ioreq server. It's server which can > handle a range of IO (MMIO and/or PIO) and emulate a PCI. > Each server as its own shared page to receive ioreq. So > we have introduced to HVM PARAM to set/get the first and > the last shared used for ioreq. With it's id, the server > knows which page it must use. This explanation, and full documentation of the new HVMOPs, should be included in the hvm_op.h header. Ian.
On 03/23/2012 11:33 AM, Ian Campbell wrote: > On Thu, 2012-03-22 at 15:59 +0000, Julien Grall wrote: > >> Add structure to handle ioreq server. It's server which can >> handle a range of IO (MMIO and/or PIO) and emulate a PCI. >> Each server as its own shared page to receive ioreq. So >> we have introduced to HVM PARAM to set/get the first and >> the last shared used for ioreq. >> With it's id, the server knows which page it must use. >> > So id is always the page offset with the range? Why not just call it > iobuf_offset then? Is the additional layer of abstraction from calling > it "id" useful if we are just going to peek around it? > Indeed, but this parameter is also used to register bdf/io range. So can we call it server_id or server_offset ? >> diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h >> index 6a78f75..1e0e27b 100644 >> --- a/xen/include/public/hvm/hvm_op.h >> +++ b/xen/include/public/hvm/hvm_op.h >> @@ -24,6 +24,8 @@ >> #include "../xen.h" >> #include "../trace.h" >> >> +#include "hvm_info_table.h" /* HVM_MAX_VCPUS */ >> > You don't appear to use HVM_MAX_VCPUS anywhere in your additions? > > I use it in xen-all.c in QEMU. It permits to check that smp_cpus is lower that the maximum of vpcus. It avoids page overflow.
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h index 27b3de5..0cfdc69 100644 --- a/xen/include/asm-x86/hvm/domain.h +++ b/xen/include/asm-x86/hvm/domain.h @@ -28,6 +28,7 @@ #include <asm/hvm/vioapic.h> #include <asm/hvm/io.h> #include <xen/hvm/iommu.h> +#include <xen/hvm/pci_emul.h> #include <asm/hvm/viridian.h> #include <asm/hvm/vmx/vmcs.h> #include <asm/hvm/svm/vmcb.h> @@ -41,14 +42,35 @@ struct hvm_ioreq_page { void *va; }; +struct hvm_io_range { + uint64_t s, e; + struct hvm_io_range *next; +}; + +struct hvm_ioreq_server { + unsigned int id; + struct hvm_io_range *mmio_range_list; + struct hvm_io_range *portio_range_list; + struct hvm_ioreq_server *next; + struct hvm_ioreq_page ioreq; + struct hvm_ioreq_page buf_ioreq; + unsigned int buf_ioreq_evtchn; +}; + struct hvm_domain { + /* Use for the IO handles by Xen */ struct hvm_ioreq_page ioreq; - struct hvm_ioreq_page buf_ioreq; + struct hvm_ioreq_server *ioreq_server_list; + uint32_t nr_ioreq_server; + spinlock_t ioreq_server_lock; struct pl_time pl_time; struct hvm_io_handler *io_handler; + /* PCI Information */ + struct pci_root_emul pci_root; + /* Lock protects access to irq, vpic and vioapic. */ spinlock_t irq_lock; struct hvm_irq irq; diff --git a/xen/include/asm-x86/hvm/vcpu.h b/xen/include/asm-x86/hvm/vcpu.h index 537da96..2774ced 100644 --- a/xen/include/asm-x86/hvm/vcpu.h +++ b/xen/include/asm-x86/hvm/vcpu.h @@ -125,7 +125,9 @@ struct hvm_vcpu { spinlock_t tm_lock; struct list_head tm_list; - int xen_port; + struct hvm_ioreq_page *ioreq; + /* PCI Information */ + uint32_t pci_cf8; bool_t flag_dr_dirty; bool_t debug_state_latch; diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index 6a78f75..1e0e27b 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -24,6 +24,8 @@ #include "../xen.h" #include "../trace.h" +#include "hvm_info_table.h" /* HVM_MAX_VCPUS */ + /* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */ #define HVMOP_set_param 0 #define HVMOP_get_param 1 @@ -227,6 +229,53 @@ struct xen_hvm_inject_trap { typedef struct xen_hvm_inject_trap xen_hvm_inject_trap_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_trap_t); +#define HVMOP_register_ioreq_server 20 +struct xen_hvm_register_ioreq_server { + domid_t domid; /* IN - domain to be serviced */ + unsigned int id; /* OUT - handle for identifying this server */ +}; +typedef struct xen_hvm_register_ioreq_server xen_hvm_register_ioreq_server_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_register_ioreq_server_t); + +#define HVMOP_get_ioreq_server_buf_channel 21 +struct xen_hvm_get_ioreq_server_buf_channel { + domid_t domid; /* IN - domain to be serviced */ + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ + unsigned int channel; /* OUT - buf ioreq channel */ +}; +typedef struct xen_hvm_get_ioreq_server_buf_channel xen_hvm_get_ioreq_server_buf_channel_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_buf_channel_t); + +#define HVMOP_map_io_range_to_ioreq_server 22 +struct xen_hvm_map_io_range_to_ioreq_server { + domid_t domid; /* IN - domain to be serviced */ + uint8_t is_mmio; /* IN - MMIO or port IO? */ + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ + uint64_aligned_t s, e; /* IN - inclusive start and end of range */ +}; +typedef struct xen_hvm_map_io_range_to_ioreq_server xen_hvm_map_io_range_to_ioreq_server_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_map_io_range_to_ioreq_server_t); + +#define HVMOP_unmap_io_range_from_ioreq_server 23 +struct xen_hvm_unmap_io_range_from_ioreq_server { + domid_t domid; /* IN - domain to be serviced */ + uint8_t is_mmio; /* IN - MMIO or port IO? */ + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ + uint64_aligned_t addr; /* IN - address inside the range to remove */ +}; +typedef struct xen_hvm_unmap_io_range_from_ioreq_server xen_hvm_unmap_io_range_from_ioreq_server_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_unmap_io_range_from_ioreq_server_t); + +#define HVMOP_register_pcidev 24 +struct xen_hvm_register_pcidev { + domid_t domid; /* IN - domain to be serviced */ + servid_t id; /* IN - handle from HVMOP_register_ioreq_server */ + uint16_t bdf; /* IN - pci */ +}; +typedef struct xen_hvm_register_pcidev xen_hvm_register_pcidev_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_register_pcidev_t); + + #endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ #define HVMOP_get_mem_type 15 diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 4022a1d..87aacd3 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -34,6 +34,7 @@ #define IOREQ_TYPE_PIO 0 /* pio */ #define IOREQ_TYPE_COPY 1 /* mmio ops */ +#define IOREQ_TYPE_PCI_CONFIG 2 /* pci config space ops */ #define IOREQ_TYPE_TIMEOFFSET 7 #define IOREQ_TYPE_INVALIDATE 8 /* mapcache */ diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index 55c1b57..309ac1b 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -147,6 +147,10 @@ #define HVM_PARAM_ACCESS_RING_PFN 28 #define HVM_PARAM_SHARING_RING_PFN 29 -#define HVM_NR_PARAMS 30 +/* Param for ioreq servers */ +#define HVM_PARAM_IO_PFN_FIRST 30 +#define HVM_PARAM_IO_PFN_LAST 31 + +#define HVM_NR_PARAMS 32 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index b2f6c50..26d0e9d 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -466,6 +466,7 @@ DEFINE_XEN_GUEST_HANDLE(mmuext_op_t); #ifndef __ASSEMBLY__ typedef uint16_t domid_t; +typedef uint32_t servid_t; /* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */ #define DOMID_FIRST_RESERVED (0x7FF0U) diff --git a/xen/include/xen/hvm/pci_emul.h b/xen/include/xen/hvm/pci_emul.h new file mode 100644 index 0000000..4e4a2fd --- /dev/null +++ b/xen/include/xen/hvm/pci_emul.h @@ -0,0 +1,37 @@ +#ifndef PCI_EMUL_H_ +# define PCI_EMUL_H_ + +# include <xen/spinlock.h> +# include <xen/types.h> + +int hvm_init_pci_emul(struct domain *d); +void hvm_destroy_pci_emul(struct domain *d); +int hvm_register_pcidev(domid_t domid, servid_t id, u16 bdf); + +/* Size of the standard PCI config space */ +#define PCI_CONFIG_SPACE_SIZE 0x100 +#define PCI_CMP_BDF(Pci, Bdf) ((Pci)->bdf == PCI_MASK_BDF(Bdf)) +#define PCI_MASK_BDF(bdf) (((bdf) & 0x00ffff00) >> 8) + +struct pci_device_emul { + u16 bdf; + struct hvm_ioreq_server *server; + struct pci_device_emul *next; +}; + +struct pci_root_emul { + spinlock_t pci_lock; + struct pci_device_emul *pci; +}; + +#endif /* !PCI_EMUL_H_ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */
Add structure to handle ioreq server. It's server which can handle a range of IO (MMIO and/or PIO) and emulate a PCI. Each server as its own shared page to receive ioreq. So we have introduced to HVM PARAM to set/get the first and the last shared used for ioreq. With it's id, the server knows which page it must use. We introduce a new kind a ioreq type IOREQ_TYPE_PCICONFIG which permit to forward easily PCI config space access. Signed-off-by: Julien Grall <julien.grall@citrix.com> --- xen/include/asm-x86/hvm/domain.h | 24 +++++++++++++++++- xen/include/asm-x86/hvm/vcpu.h | 4 ++- xen/include/public/hvm/hvm_op.h | 49 ++++++++++++++++++++++++++++++++++++++ xen/include/public/hvm/ioreq.h | 1 + xen/include/public/hvm/params.h | 6 ++++- xen/include/public/xen.h | 1 + xen/include/xen/hvm/pci_emul.h | 37 ++++++++++++++++++++++++++++ 7 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 xen/include/xen/hvm/pci_emul.h