A little over a decade ago, I was asked if I could track down decision
to add virtual memory to all IBM 370s and found a former staff member to
executive making the decision. Basically OS/360 MVT storage management
was so bad that region sizes had to be specified four times larger than
used ... as a result only four concurrent regions could be running
concurrently on typical 1mbyte 370/165 system, insufficient to keep
system busy and justified.
Mapping MVT to a 16mbyte virtual address space (vs2/svs, similar to
running MVT in a CP67 16mbyte virtual machine), allowed concurrently
running regions increased by factor of four (limited to 15 with 4bit
storage protect keys, keeping regions isolated). However, as systems
increase, even fifteen weren't sufficient and they went to providing a
separate 16mbyte virtual address space for each region
(VS2/MVS). However OS/360 heavy pointer-passing API, resulted in mapping
a 8mbyte image of the MVS kernel into every virtual address space
(kernel API call would be able to access API parameters) ... leaving
8mbytes for application. Then because subsystems were also placed in
their own separate 16mbyte virtual address space ... for subsystems
access to caller's parameters, they mapped a 1mbyte "common segment
area" (CSA) into every virtual address space (leaving 7mbyes for
applications). However CSA space requirement was proportional to
concurrent executing applications and number of subsystems ... and
quickly became multi-mbyte "common system area". By 3033 time-frame CSA
was frequently 5-6mbytes (leaving 2-3mbytes for applications) and
threatening to become 8mbytes (leaving zero).
This was part of the mad rush to 370/XA & MVS/XA with 31-bit addressing
and "access registers" (semi-privileged subsystem could access caller's
address space "as secondary address space"). As temporary stop-gap, a
subset of "access registers" were retrofitted to 3033 for MVS, as
"dual-address space mode". However, kernel code was still required to
swap hardware address space pointers (subsystem call, passing through
kernel, moving caller's address space pointer to secondary, and loading
subsystems address space pointer as primary ... and then restoring on
return). Then got hardware support with a "program call" table ... entry
for each subsystem and subsystem call could be handled all by hardware,
including the address space pointer swapping (w/o overhead of kernel
software).
"program transfer" ... more like continuation,
1983 370/XA Pinciples of Operation SSA22-7085
https://bitsavers.org/pdf/ibm/370/princOps/SA22-7085-0_370-XA_Principles_of_Operation_Mar83.pdfpg3-5 Primary & Secondary Virtual Address
pg10-22 "Program Call"
pg10-28 "Program Transfer"
"program transfer" originally could also be used to restore CPU to state
saved by previous "Program Call" (aka return, programming notes pg10-30)
Principles of Operation SA22-7832-13 (May 2022)
https://publibfp.dhe.ibm.com/epubs/pdf/a227832d.pdfpg3-23 "Address Spaces"
pg10-97 "Program Call"
pg10-110 "Program Return"
pg10-114 "Program Transfer"
-- virtualization experience starting Jan1968, online at home since Mar1970