> > > Further details on the layout of the compacted xsave > > > +area may be found in the Intel architecture manual, but note that the xsave > > > +buffer returned from ptrace will have its XCOMP_BV set to 0. > > I propose s/will have its XCOMP_BV set to 0/may have its XCOMP_BV set to 0/ > (future-proofing for the case that kernel may change this behavior). Sounds good, though I would hope that this behavior change comes with some flag to enable it :). > > > +.IP 3. > > > +For the given state component of interest, check the corresponding bit > > > +in the xsave header's XSTATE_BV bitfield. > > "...(the 64-bit field at 512 byte offset in the area)". applied. Will send out with v2 once I have all the comments in v1. > > If this bit is zero, the corresponding > > > +component is in initial state and was not written to the buffer (i.e. the kernel > > > +does not touch the memory corresponding to this state component at all, > > We probably can not guarantee these "untouched" parts > retain their contents before syscall, it's possible future kernels may zero-fill > it - I propose to not over-promise here. How about "the contents is undefined, > it may remain untouched, or be filled with dummy data"? Sounds reasonable. Applied. > > > + > > > +Thus, to obtain an xsave area that may be set back to the tracee, all unused > > > +state components must first be re-set to the correct initial state for the > > > +corresponding state component, and the XSTATE_BV bitfield must subsequently > > > +be adjusted to match the kernel xstate component bitmask (obtained as > > > +described above). > > The above paragraph needs a better wording. Are you saying the following? - > > "If a state component is not saved (its XSTATE_BV bit is zero) but you > want to modify corresponding registers in the tracee, you need to set > this bit to 1 and initialize the component to the desired state." Kind of, what I want to get across is a warning that the following pattern: struct iov = { ... }; ptrace(PTRACE_GETREGSET, pid1, NT_X86_XSTATE, &iov); ptrace(PTRACE_SETREGSET, pid2, NT_X86_XSTATE, &iov); will not necessarily result in pid1 and pid2 having identical register states. If a state component was in its initial state in pid1, the XSTATE_BV bit will be cleared, resulting in the registers in pid2 not being modified. Perhaps the easiest thing is just to include this example as well as some pseudo-code like the following: struct user_xstateregs *buffer = ...; struct iov = { iov_base=(uint8_t*)buffer, iov_len=... }; ptrace(PTRACE_GETREGSET, pid1, NT_X86_XSTATE, &iov); uint64_t kernel_xmask = buffer->i387.xstate_fx_sw[0]; uint64_t active_mask = buffer->header.xfeatures; for (int i = 0; i < XFEATURES_MAX; ++i) { uint64_t bit = (uint64_t)1 << i; if ((kernel_mask & big) && !(active_mask & bit)) { reset_state_component(buffer, i); } } ptrace(PTRACE_SETREGSET, pid2, NT_X86_XSTATE, &iov); to show how to make sure that pid2 ends up with the same register state as pid1.