Message ID | 20230904082318.1465055-4-nrb@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | s390x: Add support for running guests without MSO/MSL | expand |
On 04/09/2023 10.22, Nico Boehr wrote: > This is to prepare for running guests without MSO/MSL, which is > currently not possible. > > We already have code in sie64a to setup a guest primary ASCE before > entering SIE, so we can in theory switch to the page tables which > translate gpa to hpa. > > But the host is running in primary space mode already, so changing the > primary ASCE before entering SIE will also affect the host's code and > data. > > To make this switch useful, the host should run in a different address > space mode. Hence, set up and change to home address space mode before > installing the guest ASCE. > > The home space ASCE is just copied over from the primary space ASCE, so > no functional change is intended, also for tests that want to use > MSO/MSL. If a test intends to use a different primary space ASCE, it can > now just set the guest.asce in the save_area. > > Signed-off-by: Nico Boehr <nrb@linux.ibm.com> > --- > lib/s390x/asm/arch_def.h | 1 + > lib/s390x/sie.c | 26 ++++++++++++++++++++++++++ > 2 files changed, 27 insertions(+) > > diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h > index 5638fd01fd85..90a178ca0351 100644 > --- a/lib/s390x/asm/arch_def.h > +++ b/lib/s390x/asm/arch_def.h > @@ -93,6 +93,7 @@ enum address_space { > }; > > #define PSW_MASK_DAT 0x0400000000000000UL > +#define PSW_MASK_HOME 0x0000C00000000000UL > #define PSW_MASK_IO 0x0200000000000000UL > #define PSW_MASK_EXT 0x0100000000000000UL > #define PSW_MASK_KEY 0x00F0000000000000UL > diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c > index b44febdeaaac..7f4474555ff7 100644 > --- a/lib/s390x/sie.c > +++ b/lib/s390x/sie.c > @@ -52,6 +52,8 @@ void sie_handle_validity(struct vm *vm) > > void sie(struct vm *vm) > { > + uint64_t old_cr13; > + > if (vm->sblk->sdf == 2) > memcpy(vm->sblk->pv_grregs, vm->save_area.guest.grs, > sizeof(vm->save_area.guest.grs)); > @@ -59,6 +61,24 @@ void sie(struct vm *vm) > /* Reset icptcode so we don't trip over it below */ > vm->sblk->icptcode = 0; > > + /* > + * Set up home address space to match primary space. Instead of running > + * in home space all the time, we switch every time in sie() because: > + * - tests that depend on running in primary space mode don't need to be > + * touched > + * - it avoids regressions in tests > + * - switching every time makes it easier to extend this in the future, > + * for example to allow tests to run in whatever space they want If we want tests to be able in other modes in the future... > + */ > + old_cr13 = stctg(13); > + lctlg(13, stctg(1)); > + > + /* switch to home space so guest tables can be different from host */ > + psw_mask_set_bits(PSW_MASK_HOME); > + > + /* also handle all interruptions in home space while in SIE */ > + irq_set_dat_mode(true, AS_HOME); > + > while (vm->sblk->icptcode == 0) { > sie64a(vm->sblk, &vm->save_area); > sie_handle_validity(vm); > @@ -66,6 +86,12 @@ void sie(struct vm *vm) > vm->save_area.guest.grs[14] = vm->sblk->gg14; > vm->save_area.guest.grs[15] = vm->sblk->gg15; > > + irq_set_dat_mode(true, AS_PRIM); > + psw_mask_clear_bits(PSW_MASK_HOME); ... we should maybe restore the previous mode here instead of switching always to primary mode? Anyway, could be done later, but you might want to update your comment. Reviewed-by: Thomas Huth <thuth@redhat.com>
Quoting Thomas Huth (2023-09-04 11:59:30) [...] > If we want tests to be able in other modes in the future... > > > + */ > > + old_cr13 = stctg(13); > > + lctlg(13, stctg(1)); > > + > > + /* switch to home space so guest tables can be different from host */ > > + psw_mask_set_bits(PSW_MASK_HOME); > > + > > + /* also handle all interruptions in home space while in SIE */ > > + irq_set_dat_mode(true, AS_HOME); > > + > > while (vm->sblk->icptcode == 0) { > > sie64a(vm->sblk, &vm->save_area); > > sie_handle_validity(vm); > > @@ -66,6 +86,12 @@ void sie(struct vm *vm) > > vm->save_area.guest.grs[14] = vm->sblk->gg14; > > vm->save_area.guest.grs[15] = vm->sblk->gg15; > > > > + irq_set_dat_mode(true, AS_PRIM); > > + psw_mask_clear_bits(PSW_MASK_HOME); > > ... we should maybe restore the previous mode here instead of switching > always to primary mode? I don't want to add untested "should work" code, so I'd much prefer if we'd have a proper test which uses multiple address spaces - and that seems out of scope for this series to me. > Anyway, could be done later, but you might want to update your comment. Yep, agree, I'd prefer to do this later. Pardon if I'm not getting it but the comment IMO makes sufficiently clear that multiple AS are for future extensions. If you have any suggestion on how this could be clearer, I'd be happy to incorporate.
On 04/09/2023 13.07, Nico Boehr wrote: > Quoting Thomas Huth (2023-09-04 11:59:30) > [...] >> If we want tests to be able in other modes in the future... >> >>> + */ >>> + old_cr13 = stctg(13); >>> + lctlg(13, stctg(1)); >>> + >>> + /* switch to home space so guest tables can be different from host */ >>> + psw_mask_set_bits(PSW_MASK_HOME); >>> + >>> + /* also handle all interruptions in home space while in SIE */ >>> + irq_set_dat_mode(true, AS_HOME); >>> + >>> while (vm->sblk->icptcode == 0) { >>> sie64a(vm->sblk, &vm->save_area); >>> sie_handle_validity(vm); >>> @@ -66,6 +86,12 @@ void sie(struct vm *vm) >>> vm->save_area.guest.grs[14] = vm->sblk->gg14; >>> vm->save_area.guest.grs[15] = vm->sblk->gg15; >>> >>> + irq_set_dat_mode(true, AS_PRIM); >>> + psw_mask_clear_bits(PSW_MASK_HOME); >> >> ... we should maybe restore the previous mode here instead of switching >> always to primary mode? > > I don't want to add untested "should work" code, so I'd much prefer if we'd > have a proper test which uses multiple address spaces - and that seems out > of scope for this series to me. > >> Anyway, could be done later, but you might want to update your comment. > > Yep, agree, I'd prefer to do this later. > > Pardon if I'm not getting it but the comment IMO makes sufficiently clear > that multiple AS are for future extensions. If you have any suggestion on > how this could be clearer, I'd be happy to incorporate. I guess it's ok for now. I was thinking of something like: + * - switching every time makes it easier to extend this in the future, + * for example to allow tests to run in whatever space they want + * (this still needs some modification to return to the previous mode below) ... but it's maybe too verbose already. So just keep your patch the way it currently is. Thomas
diff --git a/lib/s390x/asm/arch_def.h b/lib/s390x/asm/arch_def.h index 5638fd01fd85..90a178ca0351 100644 --- a/lib/s390x/asm/arch_def.h +++ b/lib/s390x/asm/arch_def.h @@ -93,6 +93,7 @@ enum address_space { }; #define PSW_MASK_DAT 0x0400000000000000UL +#define PSW_MASK_HOME 0x0000C00000000000UL #define PSW_MASK_IO 0x0200000000000000UL #define PSW_MASK_EXT 0x0100000000000000UL #define PSW_MASK_KEY 0x00F0000000000000UL diff --git a/lib/s390x/sie.c b/lib/s390x/sie.c index b44febdeaaac..7f4474555ff7 100644 --- a/lib/s390x/sie.c +++ b/lib/s390x/sie.c @@ -52,6 +52,8 @@ void sie_handle_validity(struct vm *vm) void sie(struct vm *vm) { + uint64_t old_cr13; + if (vm->sblk->sdf == 2) memcpy(vm->sblk->pv_grregs, vm->save_area.guest.grs, sizeof(vm->save_area.guest.grs)); @@ -59,6 +61,24 @@ void sie(struct vm *vm) /* Reset icptcode so we don't trip over it below */ vm->sblk->icptcode = 0; + /* + * Set up home address space to match primary space. Instead of running + * in home space all the time, we switch every time in sie() because: + * - tests that depend on running in primary space mode don't need to be + * touched + * - it avoids regressions in tests + * - switching every time makes it easier to extend this in the future, + * for example to allow tests to run in whatever space they want + */ + old_cr13 = stctg(13); + lctlg(13, stctg(1)); + + /* switch to home space so guest tables can be different from host */ + psw_mask_set_bits(PSW_MASK_HOME); + + /* also handle all interruptions in home space while in SIE */ + irq_set_dat_mode(true, AS_HOME); + while (vm->sblk->icptcode == 0) { sie64a(vm->sblk, &vm->save_area); sie_handle_validity(vm); @@ -66,6 +86,12 @@ void sie(struct vm *vm) vm->save_area.guest.grs[14] = vm->sblk->gg14; vm->save_area.guest.grs[15] = vm->sblk->gg15; + irq_set_dat_mode(true, AS_PRIM); + psw_mask_clear_bits(PSW_MASK_HOME); + + /* restore the old CR 13 */ + lctlg(13, old_cr13); + if (vm->sblk->sdf == 2) memcpy(vm->save_area.guest.grs, vm->sblk->pv_grregs, sizeof(vm->save_area.guest.grs));
This is to prepare for running guests without MSO/MSL, which is currently not possible. We already have code in sie64a to setup a guest primary ASCE before entering SIE, so we can in theory switch to the page tables which translate gpa to hpa. But the host is running in primary space mode already, so changing the primary ASCE before entering SIE will also affect the host's code and data. To make this switch useful, the host should run in a different address space mode. Hence, set up and change to home address space mode before installing the guest ASCE. The home space ASCE is just copied over from the primary space ASCE, so no functional change is intended, also for tests that want to use MSO/MSL. If a test intends to use a different primary space ASCE, it can now just set the guest.asce in the save_area. Signed-off-by: Nico Boehr <nrb@linux.ibm.com> --- lib/s390x/asm/arch_def.h | 1 + lib/s390x/sie.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+)