HP-UX 10.20 contains a fundamental change in the virtual memory
kernel address space that might affect third-party kernel components,
such as kernel drivers or file systems. Third-party HP-UX kernel
components might contain code that makes assumptions that might
no longer be true, resulting in a need to modify these kernel products
in minor ways. This change was done to enable other system performance
optimizations. Only kernel code and kernel component products are
affected. If your product contains only user level code, like typical
ISUs/ISVs, you are not affected by this change.
More specifically for kernel component developers, the space
id associated with the kernel buffer cache will be changing from
0 (KERNELSPACE)
to a non-zero value. The buffer cache will still remain in the third
quadrant, but the value of sr6
will no longer be zero. This means that short pointer accesses within
the kernel address space will not be affected. However, routines
that use long pointers (that is, where a space is specified) will
need to make sure that they are not currently hardwiring the space
to zero (or KERNELSPACE).
Previous to this change, the space id associated with both
the first quadrant and third quadrant for the kernel address space
was zero (the value of the constant KERNELSPACE).
After the change, the space for the buffer cache is non-zero and
it is contained in the global variable bufcache_spaceid.
Until now, the design assumption has been that both quadrants
are in the same space and code that did not use the entire long
address could hardwire KERNELSPACE
for the space identifier.
Except for remote file systems like NFS, this has no affect
on networking drivers. Mbufs are allocated out of dynamic memory
in the first quadrant, whose space will remain zero. It is only
when a data pointer might point to an address in the buffer cache
that there might be a problem. This can happen in the networking
write path when, for instance, NFS is providing file data to a remote
system.
The write path through the network drivers needs to be checked
for calls to routines that take a space identifier as an argument.
Some examples of routines like this are: lbcopy,
privlbcopy, dma_sync,
fdcache, wsio_map,
sio_map, ltor,
and so on. Typically there can be multiple calls in the driver to
some of these routines, but only one or two need to be changed because
they are the only ones where data from outside of the networking
subsystem is passed to the network interface.
In some cases, the driver already has a variable for the space
argument, but that variable has been hardwired to KERNELSPACE.
For example, the only change to the lan1
driver is follows:
Old:
sid = KERNELSPACE; mbuf_vaddr = mtod (mbuf_ptr, char *); |
New:
mbuf_vaddr = mtod (mbuf_ptr, char *); sid = ldsid(mbuf_vaddr); |
This change is because sid
was used as an argument for ltor(),
privlbcopy(),
and fdcache(),
so it only had to be assigned the correct value. The ldsid()
procedure is an assembly language procedure that simply uses the
ldsid PARISC
instruction to obtain the proper space associated with the virtual
address passed in as an argument.
Other drivers might need more changes if a variable was not
used already as an argument to routines like privlbcopy;
that is, KERNELSPACE
was passed in as an argument. In this case, a variable like sid
in the above example should be declared and ldsid()
should be called to initialize it. The argument to ldsid
should be the virtual address associated with the data being written
to the network interface. Then, all the hardwired KERNELSPACES
associated with this virtual address should be replaced with the
newly declared variable.
Once the driver has been fixed, it should be tested on a 10.20
kernel by attempting to serve an NFS client over the network (that
is, another machine should attempt to mount one of local file systems
via NFS). If the appropriate changes have not been made, the system
will immediately crash. If a debug kernel is used, you might get
an assertion failure. Otherwise, you will most likely get a data
page fault, where the ior
is in the third quadrant (0x80000000 through 0xBFFFFFFF), but the
isr is 0.