From: David Vrabel <david.vrabel@citrix.com> During early setup of a dom0 kernel, populate boot_params with the Enhanced Disk Drive (EDD) and MBR signature data. This makes information on the BIOS boot device available in /sys/firmware/edd/. Signed-off-by: David Vrabel <david.vrabel@citrix.com> --- arch/x86/xen/enlighten.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 57 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index c8e1c7b..857d3bc 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -31,6 +31,7 @@ #include <linux/pci.h> #include <linux/gfp.h> #include <linux/memblock.h> +#include <linux/edd.h> #include <xen/xen.h> #include <xen/events.h> @@ -1306,6 +1307,60 @@ static const struct machine_ops xen_machine_ops __initconst = { .emergency_restart = xen_emergency_restart, }; +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) +static void __init load_edd(void) +{ + struct xen_platform_op op; + struct edd_info *edd_info; + u32 *mbr_signature; + unsigned nr; + int ret; + + edd_info = boot_params.eddbuf; + mbr_signature = boot_params.edd_mbr_sig_buffer; + + op.cmd = XENPF_firmware_info; + + op.u.firmware_info.type = XEN_FW_DISK_INFO; + for (nr = 0; nr < EDDMAXNR; nr++) { + struct edd_info *info = edd_info + nr; + + op.u.firmware_info.index = nr; + info->params.length = sizeof(info->params); + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, + &info->params); + ret = HYPERVISOR_dom0_op(&op); + if (ret) + break; + +#define C(x) info->x = op.u.firmware_info.u.disk_info.x + C(device); + C(version); + C(interface_support); + C(legacy_max_cylinder); + C(legacy_max_head); + C(legacy_sectors_per_track); +#undef C + } + boot_params.eddbuf_entries = nr; + + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; + for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { + op.u.firmware_info.index = nr; + ret = HYPERVISOR_dom0_op(&op); + if (ret) + break; + mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; + } + boot_params.edd_mbr_sig_buf_entries = nr; +} +#else +static inline void __init load_edd(void) +{ +} +#endif + + /* * Set up the GDT and segment registers for -fstack-protector. Until * we do this, we have to be careful not to call any stack-protected @@ -1508,6 +1563,8 @@ asmlinkage void __init xen_start_kernel(void) /* Avoid searching for BIOS MP tables */ x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.mpparse.get_smp_config = x86_init_uint_noop; + + load_edd(); } #ifdef CONFIG_PCI /* PCI BIOS service won''t work from a PV guest. */ -- 1.7.2.5
>>> On 03.04.13 at 13:10, David Vrabel <david.vrabel@citrix.com> wrote: > @@ -1306,6 +1307,60 @@ static const struct machine_ops xen_machine_ops __initconst = { > .emergency_restart = xen_emergency_restart, > }; > > +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)This is #if IS_ENABLED(CONFIG_EDD) nowadays.> +static void __init load_edd(void) > +{ > + struct xen_platform_op op; > + struct edd_info *edd_info; > + u32 *mbr_signature; > + unsigned nr; > + int ret; > + > + edd_info = boot_params.eddbuf; > + mbr_signature = boot_params.edd_mbr_sig_buffer; > + > + op.cmd = XENPF_firmware_info; > + > + op.u.firmware_info.type = XEN_FW_DISK_INFO; > + for (nr = 0; nr < EDDMAXNR; nr++) { > + struct edd_info *info = edd_info + nr; > + > + op.u.firmware_info.index = nr; > + info->params.length = sizeof(info->params); > + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, > + &info->params); > + ret = HYPERVISOR_dom0_op(&op); > + if (ret) > + break; > + > +#define C(x) info->x = op.u.firmware_info.u.disk_info.x > + C(device); > + C(version); > + C(interface_support); > + C(legacy_max_cylinder); > + C(legacy_max_head); > + C(legacy_sectors_per_track); > +#undef C > + } > + boot_params.eddbuf_entries = nr; > + > + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; > + for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { > + op.u.firmware_info.index = nr; > + ret = HYPERVISOR_dom0_op(&op); > + if (ret) > + break; > + mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; > + } > + boot_params.edd_mbr_sig_buf_entries = nr; > +} > +#else > +static inline void __init load_edd(void) > +{ > +} > +#endifAnd if you put the conditionals inside the curly braces, you can avoid the else portion here altogether. Jan
David Vrabel
2013-Apr-03 12:49 UTC
Re: [PATCH] x86/xen: populate boot_params with EDD data
On 03/04/13 13:47, Jan Beulich wrote:>>>> On 03.04.13 at 13:10, David Vrabel <david.vrabel@citrix.com> wrote: >> +} >> +#else >> +static inline void __init load_edd(void) >> +{ >> +} >> +#endif > > And if you put the conditionals inside the curly braces, you can > avoid the else portion here altogether.I thought the #if around the whole function was the standard pattern. Konrad, what''s your opinion here? David
From: David Vrabel <david.vrabel@citrix.com> During early setup of a dom0 kernel, populate boot_params with the Enhanced Disk Drive (EDD) and MBR signature data. This makes information on the BIOS boot device available in /sys/firmware/edd/. Signed-off-by: David Vrabel <david.vrabel@citrix.com> --- v2: - use IS_ENABLED() - #if in the function looks more readable --- arch/x86/xen/enlighten.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 52 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index c8e1c7b..dfe5422 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -31,6 +31,7 @@ #include <linux/pci.h> #include <linux/gfp.h> #include <linux/memblock.h> +#include <linux/edd.h> #include <xen/xen.h> #include <xen/events.h> @@ -1306,6 +1307,55 @@ static const struct machine_ops xen_machine_ops __initconst = { .emergency_restart = xen_emergency_restart, }; +static void __init load_edd(void) +{ +#if IS_ENABLED(CONFIG_EDD) + struct xen_platform_op op; + struct edd_info *edd_info; + u32 *mbr_signature; + unsigned nr; + int ret; + + edd_info = boot_params.eddbuf; + mbr_signature = boot_params.edd_mbr_sig_buffer; + + op.cmd = XENPF_firmware_info; + + op.u.firmware_info.type = XEN_FW_DISK_INFO; + for (nr = 0; nr < EDDMAXNR; nr++) { + struct edd_info *info = edd_info + nr; + + op.u.firmware_info.index = nr; + info->params.length = sizeof(info->params); + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, + &info->params); + ret = HYPERVISOR_dom0_op(&op); + if (ret) + break; + +#define C(x) info->x = op.u.firmware_info.u.disk_info.x + C(device); + C(version); + C(interface_support); + C(legacy_max_cylinder); + C(legacy_max_head); + C(legacy_sectors_per_track); +#undef C + } + boot_params.eddbuf_entries = nr; + + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; + for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { + op.u.firmware_info.index = nr; + ret = HYPERVISOR_dom0_op(&op); + if (ret) + break; + mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; + } + boot_params.edd_mbr_sig_buf_entries = nr; +#endif +} + /* * Set up the GDT and segment registers for -fstack-protector. Until * we do this, we have to be careful not to call any stack-protected @@ -1508,6 +1558,8 @@ asmlinkage void __init xen_start_kernel(void) /* Avoid searching for BIOS MP tables */ x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.mpparse.get_smp_config = x86_init_uint_noop; + + load_edd(); } #ifdef CONFIG_PCI /* PCI BIOS service won''t work from a PV guest. */ -- 1.7.2.5
Jan Beulich
2013-Apr-03 13:40 UTC
Re: [PATCHv2] x86/xen: populate boot_params with EDD data
>>> On 03.04.13 at 15:29, David Vrabel <david.vrabel@citrix.com> wrote: > From: David Vrabel <david.vrabel@citrix.com> > > During early setup of a dom0 kernel, populate boot_params with the > Enhanced Disk Drive (EDD) and MBR signature data. This makes > information on the BIOS boot device available in /sys/firmware/edd/. > > Signed-off-by: David Vrabel <david.vrabel@citrix.com>Acked-by: Jan Beulich <jbeulich@suse.com>> --- a/arch/x86/xen/enlighten.c > +++ b/arch/x86/xen/enlighten.c > @@ -31,6 +31,7 @@ > #include <linux/pci.h> > #include <linux/gfp.h> > #include <linux/memblock.h> > +#include <linux/edd.h> > > #include <xen/xen.h> > #include <xen/events.h> > @@ -1306,6 +1307,55 @@ static const struct machine_ops xen_machine_ops > __initconst = { > .emergency_restart = xen_emergency_restart, > }; > > +static void __init load_edd(void) > +{ > +#if IS_ENABLED(CONFIG_EDD) > + struct xen_platform_op op; > + struct edd_info *edd_info; > + u32 *mbr_signature; > + unsigned nr; > + int ret; > + > + edd_info = boot_params.eddbuf; > + mbr_signature = boot_params.edd_mbr_sig_buffer; > + > + op.cmd = XENPF_firmware_info; > + > + op.u.firmware_info.type = XEN_FW_DISK_INFO; > + for (nr = 0; nr < EDDMAXNR; nr++) { > + struct edd_info *info = edd_info + nr; > + > + op.u.firmware_info.index = nr; > + info->params.length = sizeof(info->params); > + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, > + &info->params); > + ret = HYPERVISOR_dom0_op(&op); > + if (ret) > + break; > + > +#define C(x) info->x = op.u.firmware_info.u.disk_info.x > + C(device); > + C(version); > + C(interface_support); > + C(legacy_max_cylinder); > + C(legacy_max_head); > + C(legacy_sectors_per_track); > +#undef C > + } > + boot_params.eddbuf_entries = nr; > + > + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; > + for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { > + op.u.firmware_info.index = nr; > + ret = HYPERVISOR_dom0_op(&op); > + if (ret) > + break; > + mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; > + } > + boot_params.edd_mbr_sig_buf_entries = nr; > +#endif > +} > + > /* > * Set up the GDT and segment registers for -fstack-protector. Until > * we do this, we have to be careful not to call any stack-protected > @@ -1508,6 +1558,8 @@ asmlinkage void __init xen_start_kernel(void) > /* Avoid searching for BIOS MP tables */ > x86_init.mpparse.find_smp_config = x86_init_noop; > x86_init.mpparse.get_smp_config = x86_init_uint_noop; > + > + load_edd(); > } > #ifdef CONFIG_PCI > /* PCI BIOS service won''t work from a PV guest. */
Konrad Rzeszutek Wilk
2013-Apr-03 14:51 UTC
Re: [PATCH] x86/xen: populate boot_params with EDD data
On Wed, Apr 03, 2013 at 01:49:16PM +0100, David Vrabel wrote:> On 03/04/13 13:47, Jan Beulich wrote: > >>>> On 03.04.13 at 13:10, David Vrabel <david.vrabel@citrix.com> wrote: > >> +} > >> +#else > >> +static inline void __init load_edd(void) > >> +{ > >> +} > >> +#endif > > > > And if you put the conditionals inside the curly braces, you can > > avoid the else portion here altogether. > > I thought the #if around the whole function was the standard pattern. > Konrad, what''s your opinion here?That is the way to do it in the header files. You are not doing this in a header, I would go with what Jan suggested and just do the #ifdef CONFIG_EDD.. inside the function. Also just for completness, lets call the function ''xen_load_edd''> > David > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel >
Konrad Rzeszutek Wilk
2013-Apr-03 14:53 UTC
Re: [PATCH] x86/xen: populate boot_params with EDD data
On Wed, Apr 03, 2013 at 12:10:49PM +0100, David Vrabel wrote:> From: David Vrabel <david.vrabel@citrix.com> > > During early setup of a dom0 kernel, populate boot_params with the > Enhanced Disk Drive (EDD) and MBR signature data. This makes > information on the BIOS boot device available in /sys/firmware/edd/. > > Signed-off-by: David Vrabel <david.vrabel@citrix.com> > --- > arch/x86/xen/enlighten.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 57 insertions(+), 0 deletions(-) > > diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c > index c8e1c7b..857d3bc 100644 > --- a/arch/x86/xen/enlighten.c > +++ b/arch/x86/xen/enlighten.c > @@ -31,6 +31,7 @@ > #include <linux/pci.h> > #include <linux/gfp.h> > #include <linux/memblock.h> > +#include <linux/edd.h> > > #include <xen/xen.h> > #include <xen/events.h> > @@ -1306,6 +1307,60 @@ static const struct machine_ops xen_machine_ops __initconst = { > .emergency_restart = xen_emergency_restart, > }; > > +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) > +static void __init load_edd(void) > +{ > + struct xen_platform_op op; > + struct edd_info *edd_info; > + u32 *mbr_signature; > + unsigned nr; > + int ret; > + > + edd_info = boot_params.eddbuf; > + mbr_signature = boot_params.edd_mbr_sig_buffer; > + > + op.cmd = XENPF_firmware_info; > + > + op.u.firmware_info.type = XEN_FW_DISK_INFO; > + for (nr = 0; nr < EDDMAXNR; nr++) { > + struct edd_info *info = edd_info + nr; > + > + op.u.firmware_info.index = nr; > + info->params.length = sizeof(info->params); > + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, > + &info->params); > + ret = HYPERVISOR_dom0_op(&op); > + if (ret) > + break; > + > +#define C(x) info->x = op.u.firmware_info.u.disk_info.x > + C(device); > + C(version); > + C(interface_support); > + C(legacy_max_cylinder); > + C(legacy_max_head); > + C(legacy_sectors_per_track); > +#undef C > + } > + boot_params.eddbuf_entries = nr; > + > + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; > + for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { > + op.u.firmware_info.index = nr; > + ret = HYPERVISOR_dom0_op(&op); > + if (ret) > + break; > + mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; > + } > + boot_params.edd_mbr_sig_buf_entries = nr;If those two loops end up terminating at different spots (say first one ends at nr=1, and the second at nr=5), is that going to present a problem? Should we have some form of ''min(nr_earlier, nr)'' to clamp down in case of weird oddities?> +} > +#else > +static inline void __init load_edd(void) > +{ > +} > +#endif > + > + > /* > * Set up the GDT and segment registers for -fstack-protector. Until > * we do this, we have to be careful not to call any stack-protected > @@ -1508,6 +1563,8 @@ asmlinkage void __init xen_start_kernel(void) > /* Avoid searching for BIOS MP tables */ > x86_init.mpparse.find_smp_config = x86_init_noop; > x86_init.mpparse.get_smp_config = x86_init_uint_noop; > + > + load_edd(); > } > #ifdef CONFIG_PCI > /* PCI BIOS service won''t work from a PV guest. */ > -- > 1.7.2.5 >
David Vrabel
2013-Apr-03 15:00 UTC
Re: [PATCH] x86/xen: populate boot_params with EDD data
On 03/04/13 15:53, Konrad Rzeszutek Wilk wrote:> On Wed, Apr 03, 2013 at 12:10:49PM +0100, David Vrabel wrote: >> From: David Vrabel <david.vrabel@citrix.com> >> >> During early setup of a dom0 kernel, populate boot_params with the >> Enhanced Disk Drive (EDD) and MBR signature data. This makes >> information on the BIOS boot device available in /sys/firmware/edd/.[...]>> --- a/arch/x86/xen/enlighten.c >> +++ b/arch/x86/xen/enlighten.c >> @@ -1306,6 +1307,60 @@ static const struct machine_ops xen_machine_ops __initconst = { >> .emergency_restart = xen_emergency_restart, >> }; >> >> +#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) >> +static void __init load_edd(void) >> +{ >> + struct xen_platform_op op; >> + struct edd_info *edd_info; >> + u32 *mbr_signature; >> + unsigned nr; >> + int ret; >> + >> + edd_info = boot_params.eddbuf; >> + mbr_signature = boot_params.edd_mbr_sig_buffer; >> + >> + op.cmd = XENPF_firmware_info; >> + >> + op.u.firmware_info.type = XEN_FW_DISK_INFO; >> + for (nr = 0; nr < EDDMAXNR; nr++) { >> + struct edd_info *info = edd_info + nr; >> + >> + op.u.firmware_info.index = nr; >> + info->params.length = sizeof(info->params); >> + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, >> + &info->params); >> + ret = HYPERVISOR_dom0_op(&op); >> + if (ret) >> + break; >> + >> +#define C(x) info->x = op.u.firmware_info.u.disk_info.x >> + C(device); >> + C(version); >> + C(interface_support); >> + C(legacy_max_cylinder); >> + C(legacy_max_head); >> + C(legacy_sectors_per_track); >> +#undef C >> + } >> + boot_params.eddbuf_entries = nr; >> + >> + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; >> + for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { >> + op.u.firmware_info.index = nr; >> + ret = HYPERVISOR_dom0_op(&op); >> + if (ret) >> + break; >> + mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; >> + } >> + boot_params.edd_mbr_sig_buf_entries = nr; > > If those two loops end up terminating at different spots (say first > one ends at nr=1, and the second at nr=5), is that going to present > a problem? > > Should we have some form of ''min(nr_earlier, nr)'' to clamp down in > case of weird oddities?The edd firmware driver looks to correctly handle this -- it will only show attributes for things that exist. David
From: David Vrabel <david.vrabel@citrix.com> During early setup of a dom0 kernel, populate boot_params with the Enhanced Disk Drive (EDD) and MBR signature data. This makes information on the BIOS boot device available in /sys/firmware/edd/. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Acked-by: Jan Beulich <jbeulich@suse.com> --- v3: - load_edd() -> xen_boot_params_init_edd() v2: - use IS_ENABLED() - #if in the function looks more readable --- arch/x86/xen/enlighten.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 52 insertions(+), 0 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index c8e1c7b..47d3243 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -31,6 +31,7 @@ #include <linux/pci.h> #include <linux/gfp.h> #include <linux/memblock.h> +#include <linux/edd.h> #include <xen/xen.h> #include <xen/events.h> @@ -1306,6 +1307,55 @@ static const struct machine_ops xen_machine_ops __initconst = { .emergency_restart = xen_emergency_restart, }; +static void __init xen_boot_params_init_edd(void) +{ +#if IS_ENABLED(CONFIG_EDD) + struct xen_platform_op op; + struct edd_info *edd_info; + u32 *mbr_signature; + unsigned nr; + int ret; + + edd_info = boot_params.eddbuf; + mbr_signature = boot_params.edd_mbr_sig_buffer; + + op.cmd = XENPF_firmware_info; + + op.u.firmware_info.type = XEN_FW_DISK_INFO; + for (nr = 0; nr < EDDMAXNR; nr++) { + struct edd_info *info = edd_info + nr; + + op.u.firmware_info.index = nr; + info->params.length = sizeof(info->params); + set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, + &info->params); + ret = HYPERVISOR_dom0_op(&op); + if (ret) + break; + +#define C(x) info->x = op.u.firmware_info.u.disk_info.x + C(device); + C(version); + C(interface_support); + C(legacy_max_cylinder); + C(legacy_max_head); + C(legacy_sectors_per_track); +#undef C + } + boot_params.eddbuf_entries = nr; + + op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; + for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { + op.u.firmware_info.index = nr; + ret = HYPERVISOR_dom0_op(&op); + if (ret) + break; + mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; + } + boot_params.edd_mbr_sig_buf_entries = nr; +#endif +} + /* * Set up the GDT and segment registers for -fstack-protector. Until * we do this, we have to be careful not to call any stack-protected @@ -1508,6 +1558,8 @@ asmlinkage void __init xen_start_kernel(void) /* Avoid searching for BIOS MP tables */ x86_init.mpparse.find_smp_config = x86_init_noop; x86_init.mpparse.get_smp_config = x86_init_uint_noop; + + xen_boot_params_init_edd(); } #ifdef CONFIG_PCI /* PCI BIOS service won''t work from a PV guest. */ -- 1.7.2.5