Message ID | 20170404152435.4915-1-tamas.lengyel@zentific.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 04/04/2017 11:24 AM, Tamas K Lengyel wrote: > Currently setting altp2mhvm=1 in the domain configuration allows access to the > altp2m interface for both in-guest and external privileged tools. This poses > a problem for use-cases where only external access should be allowed, requiring > the user to compile Xen with XSM enabled to be able to appropriately restrict > access. > > In this patch we deprecate the altp2mhvm domain configuration option and > introduce the altp2m option, which allows specifying if by default the altp2m > interface should be external-only or limited. The information is stored in > HVM_PARAM_ALTP2M which we now define with specific XEN_ALTP2M_* modes. > If external mode is selected, the XSM check is shifted to use XSM_DM_PRIV > type check, thus restricting access to the interface by the guest itself. Note > that we keep the default XSM policy untouched. Users of XSM who wish to enforce > external mode for altp2m can do so by adjusting their XSM policy directly, > as this domain config option does not override an active XSM policy. > > Also, as part of this patch we adjust the hvmop handler to require > HVM_PARAM_ALTP2M to be of a type other then disabled for all ops. This has been > previously only required for get/set altp2m domain state, all other options > were gated on altp2m_enabled. Since altp2m_enabled only gets set during set > altp2m domain state, this change introduces no new requirements to the other > ops but makes it more clear that it is required for all ops. > > Signed-off-by: Tamas K Lengyel <tamas.lengyel@zentific.com> > Signed-off-by: Sergej Proskurin <proskurin@sec.in.tum.de> > Acked-by: Wei Liu <wei.liu2@citrix.com> Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
>>> On 04.04.17 at 17:24, <tamas.lengyel@zentific.com> wrote: > Currently setting altp2mhvm=1 in the domain configuration allows access to the > altp2m interface for both in-guest and external privileged tools. This poses > a problem for use-cases where only external access should be allowed, requiring > the user to compile Xen with XSM enabled to be able to appropriately restrict > access. > > In this patch we deprecate the altp2mhvm domain configuration option and > introduce the altp2m option, which allows specifying if by default the altp2m > interface should be external-only or limited. The information is stored in > HVM_PARAM_ALTP2M which we now define with specific XEN_ALTP2M_* modes. > If external mode is selected, the XSM check is shifted to use XSM_DM_PRIV > type check, thus restricting access to the interface by the guest itself. Note > that we keep the default XSM policy untouched. Users of XSM who wish to enforce > external mode for altp2m can do so by adjusting their XSM policy directly, > as this domain config option does not override an active XSM policy. > > Also, as part of this patch we adjust the hvmop handler to require > HVM_PARAM_ALTP2M to be of a type other then disabled for all ops. This has been > previously only required for get/set altp2m domain state, all other options > were gated on altp2m_enabled. Since altp2m_enabled only gets set during set > altp2m domain state, this change introduces no new requirements to the other > ops but makes it more clear that it is required for all ops. > > Signed-off-by: Tamas K Lengyel <tamas.lengyel@zentific.com> > Signed-off-by: Sergej Proskurin <proskurin@sec.in.tum.de> > Acked-by: Wei Liu <wei.liu2@citrix.com> x86 hypervisor and public interface parts Acked-by: Jan Beulich <jbeulich@suse.com>
>>> On 04.04.17 at 17:24, <tamas.lengyel@zentific.com> wrote: > Currently setting altp2mhvm=1 in the domain configuration allows access to the > altp2m interface for both in-guest and external privileged tools. This poses > a problem for use-cases where only external access should be allowed, requiring > the user to compile Xen with XSM enabled to be able to appropriately restrict > access. > > In this patch we deprecate the altp2mhvm domain configuration option and > introduce the altp2m option, which allows specifying if by default the altp2m > interface should be external-only or limited. The information is stored in > HVM_PARAM_ALTP2M which we now define with specific XEN_ALTP2M_* modes. > If external mode is selected, the XSM check is shifted to use XSM_DM_PRIV > type check, thus restricting access to the interface by the guest itself. Note > that we keep the default XSM policy untouched. Users of XSM who wish to enforce > external mode for altp2m can do so by adjusting their XSM policy directly, > as this domain config option does not override an active XSM policy. > > Also, as part of this patch we adjust the hvmop handler to require > HVM_PARAM_ALTP2M to be of a type other then disabled for all ops. This has been > previously only required for get/set altp2m domain state, all other options > were gated on altp2m_enabled. Since altp2m_enabled only gets set during set > altp2m domain state, this change introduces no new requirements to the other > ops but makes it more clear that it is required for all ops. > > Signed-off-by: Tamas K Lengyel <tamas.lengyel@zentific.com> > Signed-off-by: Sergej Proskurin <proskurin@sec.in.tum.de> > Acked-by: Wei Liu <wei.liu2@citrix.com> > --- > Cc: Ian Jackson <ian.jackson@eu.citrix.com> > Cc: Andrew Cooper <andrew.cooper3@citrix.com> > Cc: Jan Beulich <jbeulich@suse.com> > Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov> > > v5: Add "limited" mode where the guest only has access to enable/disable > VMFUNC and #VE features. > > v6: Check mode when XSM is enabled so that both the mode and the XSM policy > has to allow the altp2m operation to succeed. Makes limited mode available > even when XSM is enabled. > --- > docs/man/xl.cfg.pod.5.in | 41 ++++++++++++++++++++++++++++++++++++++++- > tools/libxl/libxl_create.c | 6 ++++-- > tools/libxl/libxl_dom.c | 18 ++++++++++++++++-- > tools/libxl/libxl_types.idl | 14 ++++++++++++++ > tools/xl/xl_parse.c | 20 +++++++++++++++++++- > xen/arch/x86/hvm/hvm.c | 22 ++++++++++++---------- > xen/include/public/hvm/params.h | 12 +++++++++++- > xen/include/xsm/dummy.h | 23 ++++++++++++++++++++--- > xen/include/xsm/xsm.h | 6 +++--- > xen/xsm/flask/hooks.c | 21 ++++++++++++++++++++- > 10 files changed, 159 insertions(+), 24 deletions(-) George, strictly from the list of changed files your ack here is not required, but the subject made me want to at least ask whether you want to look over this, considering that you also weren't Cc-ed. Jan
On Tue, Apr 4, 2017 at 4:24 PM, Tamas K Lengyel <tamas.lengyel@zentific.com> wrote: > Currently setting altp2mhvm=1 in the domain configuration allows access to the > altp2m interface for both in-guest and external privileged tools. This poses > a problem for use-cases where only external access should be allowed, requiring > the user to compile Xen with XSM enabled to be able to appropriately restrict > access. > > In this patch we deprecate the altp2mhvm domain configuration option and > introduce the altp2m option, which allows specifying if by default the altp2m > interface should be external-only or limited. The information is stored in > HVM_PARAM_ALTP2M which we now define with specific XEN_ALTP2M_* modes. > If external mode is selected, the XSM check is shifted to use XSM_DM_PRIV > type check, thus restricting access to the interface by the guest itself. Note > that we keep the default XSM policy untouched. Users of XSM who wish to enforce > external mode for altp2m can do so by adjusting their XSM policy directly, > as this domain config option does not override an active XSM policy. > > Also, as part of this patch we adjust the hvmop handler to require > HVM_PARAM_ALTP2M to be of a type other then disabled for all ops. This has been > previously only required for get/set altp2m domain state, all other options > were gated on altp2m_enabled. Since altp2m_enabled only gets set during set > altp2m domain state, this change introduces no new requirements to the other > ops but makes it more clear that it is required for all ops. > > Signed-off-by: Tamas K Lengyel <tamas.lengyel@zentific.com> > Signed-off-by: Sergej Proskurin <proskurin@sec.in.tum.de> > Acked-by: Wei Liu <wei.liu2@citrix.com> > --- > Cc: Ian Jackson <ian.jackson@eu.citrix.com> > Cc: Andrew Cooper <andrew.cooper3@citrix.com> > Cc: Jan Beulich <jbeulich@suse.com> > Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov> > > v5: Add "limited" mode where the guest only has access to enable/disable > VMFUNC and #VE features. > > v6: Check mode when XSM is enabled so that both the mode and the XSM policy > has to allow the altp2m operation to succeed. Makes limited mode available > even when XSM is enabled. > --- > docs/man/xl.cfg.pod.5.in | 41 ++++++++++++++++++++++++++++++++++++++++- > tools/libxl/libxl_create.c | 6 ++++-- > tools/libxl/libxl_dom.c | 18 ++++++++++++++++-- > tools/libxl/libxl_types.idl | 14 ++++++++++++++ > tools/xl/xl_parse.c | 20 +++++++++++++++++++- > xen/arch/x86/hvm/hvm.c | 22 ++++++++++++---------- > xen/include/public/hvm/params.h | 12 +++++++++++- > xen/include/xsm/dummy.h | 23 ++++++++++++++++++++--- > xen/include/xsm/xsm.h | 6 +++--- > xen/xsm/flask/hooks.c | 21 ++++++++++++++++++++- > 10 files changed, 159 insertions(+), 24 deletions(-) > > diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in > index 206d33eb3f..616dc093b0 100644 > --- a/docs/man/xl.cfg.pod.5.in > +++ b/docs/man/xl.cfg.pod.5.in > @@ -1319,6 +1319,41 @@ enabled by default and you should usually omit it. It may be necessary > to disable the HPET in order to improve compatibility with guest > Operating Systems (X86 only) > > +=item B<altp2m=MODE> > + > +Specifies access mode to the alternate-p2m capability. Alternate-p2m allows a > +guest to manage multiple p2m guest physical "memory views" (as opposed to a > +single p2m). This option is disabled by default and is available to x86 hvm > +domains. You may want this option if you want to access-control/isolate > +access to specific guest physical memory pages accessed by the guest, e.g. for > +domain memory introspection or for isolation/access-control of memory between > +components within a single guest domain. > + > +The valid values are as follows: > + > +=over 4 > + > +=item B<"disabled"> > + > +Altp2m is disabled for the domain (default). > + > +=item B<"mixed"> > + > +The mixed mode allows access to the altp2m interface for both in-guest > +and external tools as well. > + > +=item B<"external"> > + > +Enables access to the alternate-p2m capability for hvm guests only > +by external privileged tools. > + > +=item B<"limited"> > + > +Enables limited access to the alternate-p2m capability for hvm guests only, > +ie. giving the guest access only to enable/disable the VMFUNC and #VE features. So just trying to understand the options here... is it he case that in all non-"disabled" modes dom0 has access to all altp2m functionality? And so the various "enabled" modes are varying levels of access to guest functionality: - "external": No guest functionality - "limited": Guest can call HVMOP_altp2m_vcpu_enable_notify only - "mixed": Guest has access to all altp2m functionality If so, I think the documentation would be clearer like this: "mixed" Both external domains and the guest itself have full access to altp2m functionality "limited" External domains have access to full altp2m functionality; guest has access only to HVMOP_altp2m_vcpu_enable_notify (ability to enable VMFUNC and #VE features). "external" External domains have access to full altp2m functionality; guest has no access to any altp2m functionality. Out of curiosity, what's the use case of the "mixed" mode? Code itself looks good to me. -George
On Wed, Apr 5, 2017 at 9:04 AM, George Dunlap <george.dunlap@citrix.com> wrote: > On Tue, Apr 4, 2017 at 4:24 PM, Tamas K Lengyel > <tamas.lengyel@zentific.com> wrote: >> Currently setting altp2mhvm=1 in the domain configuration allows access to the >> altp2m interface for both in-guest and external privileged tools. This poses >> a problem for use-cases where only external access should be allowed, requiring >> the user to compile Xen with XSM enabled to be able to appropriately restrict >> access. >> >> In this patch we deprecate the altp2mhvm domain configuration option and >> introduce the altp2m option, which allows specifying if by default the altp2m >> interface should be external-only or limited. The information is stored in >> HVM_PARAM_ALTP2M which we now define with specific XEN_ALTP2M_* modes. >> If external mode is selected, the XSM check is shifted to use XSM_DM_PRIV >> type check, thus restricting access to the interface by the guest itself. Note >> that we keep the default XSM policy untouched. Users of XSM who wish to enforce >> external mode for altp2m can do so by adjusting their XSM policy directly, >> as this domain config option does not override an active XSM policy. >> >> Also, as part of this patch we adjust the hvmop handler to require >> HVM_PARAM_ALTP2M to be of a type other then disabled for all ops. This has been >> previously only required for get/set altp2m domain state, all other options >> were gated on altp2m_enabled. Since altp2m_enabled only gets set during set >> altp2m domain state, this change introduces no new requirements to the other >> ops but makes it more clear that it is required for all ops. >> >> Signed-off-by: Tamas K Lengyel <tamas.lengyel@zentific.com> >> Signed-off-by: Sergej Proskurin <proskurin@sec.in.tum.de> >> Acked-by: Wei Liu <wei.liu2@citrix.com> >> --- >> Cc: Ian Jackson <ian.jackson@eu.citrix.com> >> Cc: Andrew Cooper <andrew.cooper3@citrix.com> >> Cc: Jan Beulich <jbeulich@suse.com> >> Cc: Daniel De Graaf <dgdegra@tycho.nsa.gov> >> >> v5: Add "limited" mode where the guest only has access to enable/disable >> VMFUNC and #VE features. >> >> v6: Check mode when XSM is enabled so that both the mode and the XSM policy >> has to allow the altp2m operation to succeed. Makes limited mode available >> even when XSM is enabled. >> --- >> docs/man/xl.cfg.pod.5.in | 41 ++++++++++++++++++++++++++++++++++++++++- >> tools/libxl/libxl_create.c | 6 ++++-- >> tools/libxl/libxl_dom.c | 18 ++++++++++++++++-- >> tools/libxl/libxl_types.idl | 14 ++++++++++++++ >> tools/xl/xl_parse.c | 20 +++++++++++++++++++- >> xen/arch/x86/hvm/hvm.c | 22 ++++++++++++---------- >> xen/include/public/hvm/params.h | 12 +++++++++++- >> xen/include/xsm/dummy.h | 23 ++++++++++++++++++++--- >> xen/include/xsm/xsm.h | 6 +++--- >> xen/xsm/flask/hooks.c | 21 ++++++++++++++++++++- >> 10 files changed, 159 insertions(+), 24 deletions(-) >> >> diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in >> index 206d33eb3f..616dc093b0 100644 >> --- a/docs/man/xl.cfg.pod.5.in >> +++ b/docs/man/xl.cfg.pod.5.in >> @@ -1319,6 +1319,41 @@ enabled by default and you should usually omit it. It may be necessary >> to disable the HPET in order to improve compatibility with guest >> Operating Systems (X86 only) >> >> +=item B<altp2m=MODE> >> + >> +Specifies access mode to the alternate-p2m capability. Alternate-p2m allows a >> +guest to manage multiple p2m guest physical "memory views" (as opposed to a >> +single p2m). This option is disabled by default and is available to x86 hvm >> +domains. You may want this option if you want to access-control/isolate >> +access to specific guest physical memory pages accessed by the guest, e.g. for >> +domain memory introspection or for isolation/access-control of memory between >> +components within a single guest domain. >> + >> +The valid values are as follows: >> + >> +=over 4 >> + >> +=item B<"disabled"> >> + >> +Altp2m is disabled for the domain (default). >> + >> +=item B<"mixed"> >> + >> +The mixed mode allows access to the altp2m interface for both in-guest >> +and external tools as well. >> + >> +=item B<"external"> >> + >> +Enables access to the alternate-p2m capability for hvm guests only >> +by external privileged tools. >> + >> +=item B<"limited"> >> + >> +Enables limited access to the alternate-p2m capability for hvm guests only, >> +ie. giving the guest access only to enable/disable the VMFUNC and #VE features. > > So just trying to understand the options here... is it he case that in > all non-"disabled" modes dom0 has access to all altp2m functionality? Yes. > And so the various "enabled" modes are varying levels of access to > guest functionality: > > - "external": No guest functionality > - "limited": Guest can call HVMOP_altp2m_vcpu_enable_notify only > - "mixed": Guest has access to all altp2m functionality > > If so, I think the documentation would be clearer like this: > > "mixed" > > Both external domains and the guest itself have full access to altp2m > functionality > > "limited" > > External domains have access to full altp2m functionality; guest has > access only to HVMOP_altp2m_vcpu_enable_notify (ability to enable > VMFUNC and #VE features). > > "external" > > External domains have access to full altp2m functionality; guest has > no access to any altp2m functionality. Sounds good to me. > Out of curiosity, what's the use case of the "mixed" mode? It's not entirely clear but that has been the mode that it was introduced with. Tamas
On 05/04/17 18:41, Tamas K Lengyel wrote: > On Wed, Apr 5, 2017 at 9:04 AM, George Dunlap <george.dunlap@citrix.com> wrote: >> On Tue, Apr 4, 2017 at 4:24 PM, Tamas K Lengyel >> <tamas.lengyel@zentific.com> wrote: >> "mixed" >> >> Both external domains and the guest itself have full access to altp2m >> functionality >> >> "limited" >> >> External domains have access to full altp2m functionality; guest has >> access only to HVMOP_altp2m_vcpu_enable_notify (ability to enable >> VMFUNC and #VE features). [snip] >> Out of curiosity, what's the use case of the "mixed" mode? > > It's not entirely clear but that has been the mode that it was introduced with. Actually I had some sort of a weird typo there... What I meant to ask about was actually "limited" mode: if the guest can't modify its own p2m tables, what's the use of a #VE? (Again, no objections to the patch, just curious.) -George
>>> On 06.04.17 at 10:52, <george.dunlap@citrix.com> wrote: > On 05/04/17 18:41, Tamas K Lengyel wrote: >> On Wed, Apr 5, 2017 at 9:04 AM, George Dunlap <george.dunlap@citrix.com> wrote: >>> On Tue, Apr 4, 2017 at 4:24 PM, Tamas K Lengyel >>> <tamas.lengyel@zentific.com> wrote: >>> "mixed" >>> >>> Both external domains and the guest itself have full access to altp2m >>> functionality >>> >>> "limited" >>> >>> External domains have access to full altp2m functionality; guest has >>> access only to HVMOP_altp2m_vcpu_enable_notify (ability to enable >>> VMFUNC and #VE features). > [snip] >>> Out of curiosity, what's the use case of the "mixed" mode? >> >> It's not entirely clear but that has been the mode that it was introduced with. > > Actually I had some sort of a weird typo there... What I meant to ask > about was actually "limited" mode: if the guest can't modify its own p2m > tables, what's the use of a #VE? While this may not be as it works today, I'd expect "cannot change its altp2m-s" to neither imply in can't use VMFUNC to switch between them nor to extend to being able to set/clear the suppress-VE bit (which isn't permission bit after all). Jan
diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in index 206d33eb3f..616dc093b0 100644 --- a/docs/man/xl.cfg.pod.5.in +++ b/docs/man/xl.cfg.pod.5.in @@ -1319,6 +1319,41 @@ enabled by default and you should usually omit it. It may be necessary to disable the HPET in order to improve compatibility with guest Operating Systems (X86 only) +=item B<altp2m=MODE> + +Specifies access mode to the alternate-p2m capability. Alternate-p2m allows a +guest to manage multiple p2m guest physical "memory views" (as opposed to a +single p2m). This option is disabled by default and is available to x86 hvm +domains. You may want this option if you want to access-control/isolate +access to specific guest physical memory pages accessed by the guest, e.g. for +domain memory introspection or for isolation/access-control of memory between +components within a single guest domain. + +The valid values are as follows: + +=over 4 + +=item B<"disabled"> + +Altp2m is disabled for the domain (default). + +=item B<"mixed"> + +The mixed mode allows access to the altp2m interface for both in-guest +and external tools as well. + +=item B<"external"> + +Enables access to the alternate-p2m capability for hvm guests only +by external privileged tools. + +=item B<"limited"> + +Enables limited access to the alternate-p2m capability for hvm guests only, +ie. giving the guest access only to enable/disable the VMFUNC and #VE features. + +=back + =item B<altp2mhvm=BOOLEAN> Enables or disables hvm guest access to alternate-p2m capability. @@ -1329,7 +1364,11 @@ You may want this option if you want to access-control/isolate access to specific guest physical memory pages accessed by the guest, e.g. for HVM domain memory introspection or for isolation/access-control of memory between components within -a single guest hvm domain. +a single guest hvm domain. This option is deprecated, use the option +"altp2m" instead. + +Note: While the option "altp2mhvm" is deprecated, legacy applications for +x86 systems will continue to work using it. =item B<nestedhvm=BOOLEAN> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 399b91426b..bffbc456c1 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -902,14 +902,16 @@ static void initiate_domain_create(libxl__egc *egc, if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM && (libxl_defbool_val(d_config->b_info.u.hvm.nested_hvm) && - libxl_defbool_val(d_config->b_info.u.hvm.altp2m))) { + (libxl_defbool_val(d_config->b_info.u.hvm.altp2m) || + (d_config->b_info.altp2m != LIBXL_ALTP2M_MODE_DISABLED)))) { ret = ERROR_INVAL; LOGD(ERROR, domid, "nestedhvm and altp2mhvm cannot be used together"); goto error_out; } if (d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM && - libxl_defbool_val(d_config->b_info.u.hvm.altp2m) && + (libxl_defbool_val(d_config->b_info.u.hvm.altp2m) || + (d_config->b_info.altp2m != LIBXL_ALTP2M_MODE_DISABLED)) && pod_enabled) { ret = ERROR_INVAL; LOGD(ERROR, domid, "Cannot enable PoD and ALTP2M at the same time"); diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c index cf03ded67d..5d914a59ee 100644 --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -295,8 +295,6 @@ static void hvm_set_conf_params(xc_interface *handle, uint32_t domid, libxl_defbool_val(info->u.hvm.vpt_align)); xc_hvm_param_set(handle, domid, HVM_PARAM_NESTEDHVM, libxl_defbool_val(info->u.hvm.nested_hvm)); - xc_hvm_param_set(handle, domid, HVM_PARAM_ALTP2M, - libxl_defbool_val(info->u.hvm.altp2m)); } int libxl__build_pre(libxl__gc *gc, uint32_t domid, @@ -445,6 +443,22 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid, #endif } + /* Alternate p2m support on x86 is available only for HVM guests. */ + if (info->type == LIBXL_DOMAIN_TYPE_HVM) { + /* The config parameter "altp2m" replaces the parameter "altp2mhvm". For + * legacy reasons, both parameters are accepted on x86 HVM guests. + * + * If the legacy field info->u.hvm.altp2m is set, activate altp2m. + * Otherwise set altp2m based on the field info->altp2m. */ + if (info->altp2m == LIBXL_ALTP2M_MODE_DISABLED && + libxl_defbool_val(info->u.hvm.altp2m)) + xc_hvm_param_set(ctx->xch, domid, HVM_PARAM_ALTP2M, + libxl_defbool_val(info->u.hvm.altp2m)); + else + xc_hvm_param_set(ctx->xch, domid, HVM_PARAM_ALTP2M, + info->altp2m); + } + rc = libxl__arch_domain_create(gc, d_config, domid); return rc; diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index d970284ffa..bac226cf7d 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -441,6 +441,14 @@ libxl_rdm_reserve = Struct("rdm_reserve", [ ("policy", libxl_rdm_reserve_policy), ]) +# Consistent with the values defined for HVM_PARAM_ALTP2M +libxl_altp2m_mode = Enumeration("altp2m_mode", [ + (0, "disabled"), + (1, "mixed"), + (2, "external"), + (3, "limited"), + ], init_val = "LIBXL_ALTP2M_MODE_DISABLED") + libxl_domain_build_info = Struct("domain_build_info",[ ("max_vcpus", integer), ("avail_vcpus", libxl_bitmap), @@ -519,6 +527,9 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("mmio_hole_memkb", MemKB), ("timer_mode", libxl_timer_mode), ("nested_hvm", libxl_defbool), + # The u.hvm.altp2m field is used solely + # for x86 HVM guests and is maintained + # for legacy purposes. ("altp2m", libxl_defbool), ("system_firmware", string), ("smbios_firmware", string), @@ -569,6 +580,9 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("arch_arm", Struct(None, [("gic_version", libxl_gic_version), ])), + # Alternate p2m is not bound to any architecture or guest type, as it is + # supported by x86 HVM and ARM support is planned. + ("altp2m", libxl_altp2m_mode), ], dir=DIR_IN ) diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 66327dcc01..856a304b30 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1156,7 +1156,9 @@ void parse_config_data(const char *config_source, xlu_cfg_get_defbool(config, "nestedhvm", &b_info->u.hvm.nested_hvm, 0); - xlu_cfg_get_defbool(config, "altp2mhvm", &b_info->u.hvm.altp2m, 0); + if (!xlu_cfg_get_defbool(config, "altp2mhvm", &b_info->u.hvm.altp2m, 0)) + fprintf(stderr, "WARNING: Specifying \"altp2mhvm\" is deprecated. " + "Please use \"altp2m\" instead.\n"); xlu_cfg_replace_string(config, "smbios_firmware", &b_info->u.hvm.smbios_firmware, 0); @@ -1216,6 +1218,22 @@ void parse_config_data(const char *config_source, abort(); } + if (!xlu_cfg_get_long(config, "altp2m", &l, 1)) { + if (l < LIBXL_ALTP2M_MODE_DISABLED || + l > LIBXL_ALTP2M_MODE_LIMITED) { + fprintf(stderr, "ERROR: invalid value %ld for \"altp2m\"\n", l); + exit (1); + } + + b_info->altp2m = l; + } else if (!xlu_cfg_get_string(config, "altp2m", &buf, 0)) { + if (libxl_altp2m_mode_from_string(buf, &b_info->altp2m)) { + fprintf(stderr, "ERROR: invalid value \"%s\" for \"altp2m\"\n", + buf); + exit (1); + } + } + if (!xlu_cfg_get_list(config, "ioports", &ioports, &num_ioports, 0)) { b_info->num_ioports = num_ioports; b_info->ioports = calloc(num_ioports, sizeof(*b_info->ioports)); diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 0282986738..fd77e3e7b8 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -4110,7 +4110,7 @@ static int hvmop_set_param( rc = xsm_hvm_param_altp2mhvm(XSM_PRIV, d); if ( rc ) break; - if ( a.value > 1 ) + if ( a.value > XEN_ALTP2M_limited ) rc = -EINVAL; if ( a.value && d->arch.hvm_domain.params[HVM_PARAM_NESTEDHVM] ) @@ -4324,6 +4324,7 @@ static int do_altp2m_op( struct xen_hvm_altp2m_op a; struct domain *d = NULL; int rc = 0; + uint64_t mode; if ( !hvm_altp2m_supported() ) return -EOPNOTSUPP; @@ -4370,18 +4371,20 @@ static int do_altp2m_op( goto out; } - if ( (rc = xsm_hvm_altp2mhvm_op(XSM_TARGET, d)) ) + mode = d->arch.hvm_domain.params[HVM_PARAM_ALTP2M]; + + if ( XEN_ALTP2M_disabled == mode ) + { + rc = -EINVAL; + goto out; + } + + if ( (rc = xsm_hvm_altp2mhvm_op(XSM_OTHER, d, mode, a.cmd)) ) goto out; switch ( a.cmd ) { case HVMOP_altp2m_get_domain_state: - if ( !d->arch.hvm_domain.params[HVM_PARAM_ALTP2M] ) - { - rc = -EINVAL; - break; - } - a.u.domain_state.state = altp2m_active(d); rc = __copy_to_guest(arg, &a, 1) ? -EFAULT : 0; break; @@ -4391,8 +4394,7 @@ static int do_altp2m_op( struct vcpu *v; bool_t ostate; - if ( !d->arch.hvm_domain.params[HVM_PARAM_ALTP2M] || - nestedhvm_enabled(d) ) + if ( nestedhvm_enabled(d) ) { rc = -EINVAL; break; diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index 19c9eb8886..1f3ed0906d 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -233,8 +233,18 @@ /* Location of the VM Generation ID in guest physical address space. */ #define HVM_PARAM_VM_GENERATION_ID_ADDR 34 -/* Boolean: Enable altp2m */ +/* + * Set mode for altp2m: + * disabled: don't activate altp2m (default) + * mixed: allow access to all altp2m ops for both in-guest and external tools + * external: allow access to external privileged tools only + * limited: guest only has limited access (ie. control VMFUNC and #VE) + */ #define HVM_PARAM_ALTP2M 35 +#define XEN_ALTP2M_disabled 0 +#define XEN_ALTP2M_mixed 1 +#define XEN_ALTP2M_external 2 +#define XEN_ALTP2M_limited 3 /* * Size of the x87 FPU FIP/FDP registers that the hypervisor needs to diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index ff730391d5..56a8814d82 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -555,10 +555,27 @@ static XSM_INLINE int xsm_hvm_param_altp2mhvm(XSM_DEFAULT_ARG struct domain *d) return xsm_default_action(action, current->domain, d); } -static XSM_INLINE int xsm_hvm_altp2mhvm_op(XSM_DEFAULT_ARG struct domain *d) +static XSM_INLINE int xsm_hvm_altp2mhvm_op(XSM_DEFAULT_ARG struct domain *d, uint64_t mode, uint32_t op) { - XSM_ASSERT_ACTION(XSM_TARGET); - return xsm_default_action(action, current->domain, d); + xsm_default_t a; + XSM_ASSERT_ACTION(XSM_OTHER); + + switch ( mode ) + { + case XEN_ALTP2M_mixed: + a = XSM_TARGET; + break; + case XEN_ALTP2M_external: + a = XSM_DM_PRIV; + break; + case XEN_ALTP2M_limited: + a = (HVMOP_altp2m_vcpu_enable_notify == op) ? XSM_TARGET : XSM_DM_PRIV; + break; + default: + return -EPERM; + }; + + return xsm_default_action(a, current->domain, d); } static XSM_INLINE int xsm_vm_event_control(XSM_DEFAULT_ARG struct domain *d, int mode, int op) diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 2cf7ac10db..60c0fd6a62 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -140,7 +140,7 @@ struct xsm_operations { int (*hvm_control) (struct domain *d, unsigned long op); int (*hvm_param_nested) (struct domain *d); int (*hvm_param_altp2mhvm) (struct domain *d); - int (*hvm_altp2mhvm_op) (struct domain *d); + int (*hvm_altp2mhvm_op) (struct domain *d, uint64_t mode, uint32_t op); int (*get_vnumainfo) (struct domain *d); int (*vm_event_control) (struct domain *d, int mode, int op); @@ -579,9 +579,9 @@ static inline int xsm_hvm_param_altp2mhvm (xsm_default_t def, struct domain *d) return xsm_ops->hvm_param_altp2mhvm(d); } -static inline int xsm_hvm_altp2mhvm_op (xsm_default_t def, struct domain *d) +static inline int xsm_hvm_altp2mhvm_op (xsm_default_t def, struct domain *d, uint64_t mode, uint32_t op) { - return xsm_ops->hvm_altp2mhvm_op(d); + return xsm_ops->hvm_altp2mhvm_op(d, mode, op); } static inline int xsm_get_vnumainfo (xsm_default_t def, struct domain *d) diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 4baed39890..fd84ac0f09 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1197,8 +1197,27 @@ static int flask_hvm_param_altp2mhvm(struct domain *d) return current_has_perm(d, SECCLASS_HVM, HVM__ALTP2MHVM); } -static int flask_hvm_altp2mhvm_op(struct domain *d) +static int flask_hvm_altp2mhvm_op(struct domain *d, uint64_t mode, uint32_t op) { + /* + * Require both mode and XSM to allow the operation. Assume XSM rules + * are written with the XSM_TARGET policy in mind, so add restrictions + * on the domain acting on itself when forbidden by the mode. + */ + switch ( mode ) + { + case XEN_ALTP2M_mixed: + break; + case XEN_ALTP2M_limited: + if ( HVMOP_altp2m_vcpu_enable_notify == op ) + break; + /* fall-through */ + case XEN_ALTP2M_external: + if ( d == current->domain ) + return -EPERM; + break; + }; + return current_has_perm(d, SECCLASS_HVM, HVM__ALTP2MHVM_OP); }