amd64 passes first argument in RARG (BP) register
which has the be preserved duing _profin() and
_profout() calls. to handle this we introduce
_saveret() and _savearg(). _saveret() returns
AX, _savearg() returns RARG (BP). for archs other
and amd64, _saveret() and _savearg() are the
same function, doing nothing.
restoing works with dummy function:
uintptr
_restore(uintptr, uintptr ret)
{
return ret;
}
...
ret = _saveret();
arg = _savearg();
...
return _restore(arg, ret);
as we pass arg as the first argument, RARG (BP) is
restored.
we did the utf-8 to unicode conversion in pl_nextc(),
but the plaintext handler uses pl_readc() which only
translates newlines but otherwise returns bytes.
move unicode conversion in pl_readc() fixes it.
modifying the kernel pdp (CPU0PDP) hangs vmware. so
we initialize the pdp with KZERO and KZERO+1GB map
in l.s and never change it. (except when removing
the zero double map which seems to work).
VMAP has its own pdp now allowing to map 512GB of
physical address space. this simplifies the code
a bit and gives nice virtual addresses.
to make it easier to write portable acid code, we
introduce 'A' format in the same meaning as in db(1):
A Print the value of dot in hexadecimal. Dot is
unaffected.
both 'a' (symbolic) and 'A' will both have 64 or 32 bit
size depending on the mach, so pointer array indexing
works the same.
we cannot call gc() in execute() because it will gc
anonyous intermediate results which happens when we
construct a list and the elements are calculated by
calling a function thru ocall() which calls execute().
also, the _thiscmd symbol; which is used to keep
a reference to a statement so it wont get garbage
collected; does not work as yyparse() is recursive
(include statements).
we add execrec() function which *only* gets called from
yyparse() when evaluating a statement. it will
keep a stack on the _thiscmd symbol handling the yyparse()
recursion.
we also only call gc() in execrec() before calling
execute(). so execute() will never gc() while evaluating
a statement which prevents the intermediate results
from getting collected.
file offset is 64 bit signed integer, negative offsets
are invalid and rejected by the kernel. to still access
kernel memory on amd64, we unconditionally clear the sign
bit of the 64 bit offset in libmach and devproc sign
extends the offset back to a 64 bit address.
when using the jpg(1) programs interactively, draw the
image in the center of it. this avoids wasting space
with always on borders on small windows and looks better
when used in fullscreen.
on intel processors, a general protection exception is fired if a non-canonical address is loaded into PC during SYSRET. this will cause the kernel to panic.
see http://www.kb.cert.org/vuls/id/649219 and the intel software developer manual for more information.
kmapindex has to be per process, not per mach, as the process
can be switched to another processor while the mapping is
established.
to bootstrap the first process, we have to temporarily set up
so the kmap MMU's can be attached to the process. previously
we assumed that the first two pages for the initial process
where below 2GB and could be accessed with KADDR() directly.
with 16GB machine, all the 2GB above KZERO are dedicated to
the kernel so the user pages returned by newpage() need to
be mapped.
no need for switch here, just calculate the values. also fixes
6l warning about uninitialized min/max (compiler assumes none
of the case statements could match).
this doubling affects all segment types, not just bss.
(tho text/data are usually small...)
and theres no telling if the segment will actually
grow in the future justifying the reduction of memmove
overhead in ibrk().
some ape programs are approaching the 16mb ssegmap size
so that code might trigger.
removing the smarts...
we have to keep kmap page tables in ther own list
because user tables are subject to (virtual) tlb flushing.
we never free kmap page tables except in mmurelease()
where we just link the kmap mmu list in front of the user
mmus and call mmufree() which will free all the mmu's
of the process.
as erik quanstro suggests, theres not much of a point in
storing the full 64bit pc as one cannot get a code segment
bigger than 4G and amd64 makes it hard to use a pc that
isnt 64bit sign extension of 32bit.
instead, we only store ulong (as originally), but sign
extend back when returning in getmalloctag() and
getrealloctag().
getrealloctag() used to be broken. its now fixed.
this change is in preparation for amd64. the systab calling
convention was also changed to return uintptr (as segattach
returns a pointer) and the arguments are now passed as
va_list which handles amd64 arguments properly (all arguments
are passed in 64bit quantities on the stack, tho the upper
part will not be initialized when the element is smaller
than 8 bytes).
this is partial. xalloc needs to be converted in the future.
when user does read of exactly 12*12 bytes on draw
ctl file, the snprint() adds one more \0 byte writing
beyond the user buffer and corrupting memory.
fix this by not snprint()ing the final space and add
it manually.
according to a comment in linux driver, reading Isrc2
register caused interrupts to be disabled. we used
to read Isrc2 in ifstat() and it was confirmed that
reading ifstat locks up ethernet. removing the Isrc2
read in ifstats, and also reenable interrupts after
reading Isrc2 when the interrupt was not for us.
(this is from the linux driver)
in replenish(), set ring software write pointer (Sring.wp)
*before* the hardware write index register. otherwise
rx() could get status notification for completed
receive but wont find the rx descriptor in the ring.
handle uint wrap arround when calculating ring fill
count and remaining count.
the stats and ifstats files in the 3rd level of a netif
are not per connection, but for the interface.
this made fstat fail for /net/ether0/N/*stats where N > 0
as the NETID() bits in the qid didnt compare.
cachechars() used to skip over characters on its own when
loadchar() could not find the character or a PJW replacement.
this resulted in wrong width calculation. now we just return
and handle the case inside _string and _stringwidth.
fix subfont leak in stringwidth()
remove annoying prints in stringwidth()
scrollwheel now works proportional to y mouse position.
special case is when shift is hold down. then scrollwheel
will work like before and scroll one line up or down.
from erik quanstros 9fans post:
i think the list insertion code needs a single-read
test that f->alarm != 0. to prevent the 0 from
acting like a fencepost. e.g. trying to insert -10 into
list -40 -30 0 -20.
if(alarms.head) {
l = &alarms.head;
for(f = *l; f; f = f->palarm) {
>> fw = f->alarm;
>> if(fw != 0 && (long)(fw - when) >= 0) {
up->palarm = f;
*l = up;
goto done;
}
l = &f->palarm;
}
*l = up;
}
disabling mouse packet streaming command 0xf5 can fail
when a packet is currently transmitted.
this can be seen when one moves the mouse while running:
while(){echo accelerated >/dev/mousectl; sleep 0.5}
make sure not to dereference Proc* nil pointer. this can potentially
happen from devip which has code like:
if(er->read4p)
postnote(er->read4p, 1, "unbind", 0);
the process it is about to kill can zero er->read4p at any time,
so there is the possibility of the condition to be true and then
er->read4p becoming nil.
check if the process has already exited (p->pid == 0) in postnote()
under p->debug qlock.
when alarmkproc is commited to send the alarm note to the process,
the process might have exited already, or worse, being reused for
another process. pexit() zeros p->alarm at the beginning, but the
kalarmproc() might read p->alarm before pexit() zeroed it, decide
to send the note, then get preempted and pexit() releases the proc.
once kalarmproc() is resumed, the proc might be already something
different and we send the note to the wrong thing.
we now check p->alarm under the debug qlock. that way, pexit()
cannot make progress while we test the condition.
remove the error label arround postnote(). postnote does not raise
error.
make sure noteid is valid (>0).
prohibit changing note group of kernel processes. this is also
checked for in pgrpnote().
prevent "none" user from changing its note group to another "none"
sessions. this would allow him to send notes other none processes
other than its own.
this works differently from mischiefs original patch. instead of
overloading the address bar, we popup our own enter box. the
function can be invoked from the menu or by hitting ^F.
add new functions pageaddr() that returns a string describing
the page to be loaded. it is in the form of:
/path/to/file!pagename!subpage!....
one can jump to such a page by calling trywalk(name, addr)
where name and addr get concatinated with ! to form a page
address and then the currently loaded pages are walked up
to the nearest page which is then returned. (or nil when
not found). the remaining address will be set in the global
pagewalk variable.
once pages get loaded (asynchronously), pagewalk1() gets
called again on addpage() and continues the walking up to the
last page.
new program flag -j <addr> was added to jump to a page on
startup.
page address (without filename) can also be supplied in
plumb message with the "addr" attribute.
rio looks backwards in the line for the beginning of a filename
that needs to be completed with ^F. this change makes the
characters: =, ^, ( and { stoppers, so filename completion
will work in all these cases:
foobar=/foo/ba^F; for(i in (fo^F ba^F)){/bin/baz^F
this means completion will not work for prefixes having these
special characters in them.
thanks to burnzez for bringing it up.
dont spam the console with qfull warnings. this makes things worse.
handle loopback packets as stated in the comment. we call etheriq()
with fromwire=1 for loopback packets so etheriq() can pass the packet
on (without copying) or free it. dont inhibit interrupts while calling
etheriq(). etheriq() can safely be called from process and interrupt
context. it is unclear what this was supposed to fix and testing didnt
seem to have any odd effects.
(11:02:29 PM) me: why is buf in /sys/src/9/port/devssl.c:/^sslwrite only 128 bytes?
(11:02:58 PM) me: it makes it so you can't use a 128 bytes secret as negotiated by infauth in a secretin or secretout ctl message
(11:03:30 PM) me: which in turn means you can't use such a secret with pushssl(2)
(11:06:15 PM) me: inferno's sslwrite is limited to 32 bytes, but its ssl library writes to the secret files instead of to the ctl file
(11:08:50 PM) mischief: what should it be instead of 128 bytes
(11:08:58 PM) me: larger
(11:09:16 PM) mischief: how about 129 bytes?
(11:09:59 PM) me: also broken in 9front, by the way
(11:15:14 PM) me: i guess it should be replaced with parsecmd
get rid of the service buffer limit. keep service buffers
on a global freelist protected by lock.
dont fatal when we hit the process limit. instead, just
abort the rpc with an error.
handle rendezvous() interrupts.
when a replicated source image with a clipr with clipr.min > Pt(0, 0),
drawclip() would properly translate the src->clipr on the dstr
but then clamp the source rectangle back on src->r.
while traversing down multiple layers, this would cause the translation to
be applied multiple times to the dst rectangle giving the wrong image result.
this change adds a new drawclipnorepl() function that avoids the clamping
of source and mask rectangles to src->r and mask->r. this is then used in
libmemlayer.
the final memimagedraw() call will call drawclip() which will do the final
claming.
a testcase is provided:
#include <u.h>
#include <libc.h>
#include <draw.h>
Image *blue;
Image *red;
void
main(int, char *argv[])
{
Image *i;
if(initdraw(nil, nil, argv[0]) < 0)
sysfatal("initdraw: %r");
i = allocimage(display, screen->r, screen->chan, 1, DWhite);
red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
blue = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPaleblue);
replclipr(red, 1, Rect(10, 10, 110, 110));
replclipr(blue, 1, Rect(11, 11, 111, 111));
/* draw on non-layer, works correctly */
draw(i, i->r, red, nil, ZP);
draw(i, i->r, blue, nil, ZP);
draw(screen, screen->r, i, nil, i->r.min);
flushimage(display, 1);
/* draw on (screen) layer is too far to the right */
draw(screen, screen->r, red, nil, ZP);
draw(screen, screen->r, blue, nil, ZP);
flushimage(display, 1);
for(;;){
sleep(1000);
}
}
the nt blob ends with 4 zero bytes, this is not the same as
the EOL av-pair terminator!
this makes ntlmv2 work with windows xp with LmCompatibityLevel = 3
extending factotums and the auth servers mschap implementation
to handle variable length NT response for NTLMv2.
fix some minor bugs.
only tested with cifs so far.
replaced the p->pid != 0 check with up->parentpid != 0 so
p->pid == up->parentpid is never true for p->pid == 0.
avoid allocating the wait records when up->parentpid == 0.
when a process got forked with RFNOWAIT, its p->parent will still
point to the parent process, but its p->parentpid == 0.
this causes the "parent still alive" check in pexit to get confused
as it only checked p->pid == up->parentpid. this condition is *TRUE*
in the case of RFNOWAIT when the parent process is actually dead
(p->pid == 0) so we attached the wait structure to the dead parent
leaking the memory.
we do not need to wait for fork/execed program to finish when
not collecting waitmsg. this reduces the number of rio
processes hanging arround for each window shell just waiting
for it to terminate and then dumping the waitmsg.
U9fs(4) misuses Fcall.afid in its p9any authentication module.
The afid field of Fcall structure is only valid with Tauth or Tattach.
Tread, Twrite, Tclunk should use rx->fid instead. It's been lucky so
far to get the job done because rx->afid survives from previous
Tauth/Tattach. The issue pops up when several authentications happen
concurrently.
Test case:
u9fs = 'host with u9fs on tcp!*!564'
9fs $u9fs; for(i in 1 2 3 4 5 6 7 8){ 9fs $u9fs & }; wait
Should:
no errors
Should not:
mount failed: authentication failed
we might get a unreachable nameserver ip from a parent
nameserver. if the remaining set of nameservers does not
loop, we should try to resolve them.
so skip the loopcheck for nameservers already tried.
validurl() is just used to check if the string is a full
absolute url with a protocol scheme. we do not have to
match the host part *exactly*, only if there is *something*
in the hostpart.
Add pages for esc1+shift and esc1+ctrl - some UK USB keyboards (Dell) and it seems some
German ones: https://groups.google.com/forum/#!topic/comp.os.plan9/ycok6NTCWCg seem to
generate an esc1 + code scancode combination for the pipe/backslash key. Seems like
overkill to add two whole pages for just two keys, but there again RAM is cheap these days.
Probably should take the changes across to omap/kbd.c (and by extension bcm/kbd.c)
but the changes are trivial.
catch the error() that can be thrown by sleep() and tsleep()
in kprocs.
add missing pexit() calls.
always set the freemem argument to pexit() from kproc otherwise
the process gets added to the broken list.
catch the error() that can be thrown by sleep() and tsleep()
in kprocs.
add missing pexit() calls.
always set the freemem argument to pexit() from kproc otherwise
the process gets added to the broken list.
from 9atom/acmearrowfun patch:
reported by mark van atten
In Plan 9 acme, if you type
{}
then go back and type text between the brackets
{Curiouser and curiouser!}
the right arrow is blocked when you want to go over the closing
bracket to continue typing to its right. (If you first go to the left,
and then back to the right, it works.)
Same for the other brackets: [ ], ( ), < >.
noted that brackets are not necessary. same behavior with any
character.
fix is to textcommit before moving.
we have to fail the whole query that got no cached
nameservers and nameservers are looping, not just omit
the looping nameserver. issuequery() will refresh
nameserver info for the domain when recursing up.
never try to resolve a nameserver address when that nameserver
is in the set of nameservers already being queried.
this situation can happen when the Ta and Taaaa RR's expire, but
the Tns records are still in the cache so there is no usable
nameserver but they still refer to each another.
stop absolute/relative dual use of RR.ttl. now RR.ttl is
*always* the *relative* ttl value. we derive absolute
timeout in RR.expire.
remove unused lookuptime field in DN. replace refs and
keep with mark field in DN. we do not care about the
number of references. only *iff* it is referenced, so
use a single bit for that (bit 0). for keep, we use
bit 1.
remove dolock parameter in dnagenever(), it is not
needed. we always need to lock.
mark local dns servers and domains as never to be aged.
the keeper bit is *just* a cache optimization, preventing
the domain and the domains it points to from being flushed.
it should not be used as a write protect bit in rrattach()
for preventing spoofing as it will prevent updates of say,
cname domains.
remove "removing spam ..." message. these are usualy just
hints, so normal. still, remove the hint as we currently
do no check if the nameserver has authority over the
cname domain.
remove "mydnsquery: trying to send to myself (%s); bzzzt"
message. this can happen when myaddr() fails for other
reasons. myaddr() will print error for us anyway.
ndb keys are strictly case sensitive, so consitently
use strcmp() when comparing attribute keys.
dblookup() used to lower case convert its name argument
inplace to match domain/sys name in ndb. better to do
the convesion in its own buffer and only read from the
name argument.
always use cistrcmp() when comparing DN.name.
the Domlen constant denotes the size of the buffer including
the null terminator. consistently use it as such.
have to hold dnlock in freearea() before reading list
head pointer.
the image cache should not hold onto the text file channel
when not neccesary. now, the image keeps track of the number
of page cache references in Image.pgref. if the number of
page cache references and Image.ref are equal, this means
all the references to this image are from the page cache.
so no segments are using this image. in that case, we can
close the channel, but keep the Image in the hash table.
when attachimage() finds our image, it will check if Image.c
is nil and reattach the channel to the image before it is
used.
the Image.nocache flag isnt needed anymore.
the libmad samples need to be scaled properly. the
previous assumption was that it is 32 bits, but it
really is MAD_F_FRACTBITS + sign bit and rest used
for overflow.
thanks eekee!
in ape's vfprintf we don't check if the file we're writing is actually a string buffer, resulting in a return of -1, when we should actually return the number of bytes that would be written.
frinsert() shouldnt modify the runes passed and the
buffer isnt going to be modified my us during the call
so removing the temporary copies.
namecomplete() makes utf-8 copies of the rune strings so
theres no need to copy the runes.
xfidflush() now uses a simpler way to flush another xfid.
when we can send to Xfid.c channel, we know that the
xfid is completed. so all xfidflush() needs todo is to
do an alt sending to both Xfid.c and Xfid.flushc.
once the send to Xfid.c succeeds, we know the xfid is gone
and we can respond to the flush request.
theres no need to keep track of flush state anymore. so
Xfid.active and Xfid.flushing can be removed.
note, that it is ok to respond normally to a currently
flushed request.
flushing isnt optional for concurrently handled requests.
we need to ensure that Rflush is replied *after* the
origianl request.
so we assign the flushtag for *every* xfid in xfidctl(),
and filsysrespond() checks if the xfid was flushed
*after* replying and wakes up the flushing xfid.
when multiple flushes are send, they need to be replied
in order. we ensure this by having the flush xfid taking
over the flushtag (synchronized with a new fs->csyncflush
channel) so the next flush will flush the previous flush.
the diver used to skip auto negotiation when
auto-negotiation enable (bit 12 in command register)
was clear.
setting the bit now, which makes auto negotiation work.
we skip auto negotiation only when it was already enabled
and status regiser indicates completion (bit 9).
the shr mount is linked into the Mhead with m->to initially nil. only
after the the server has been attached is m->to set. just check for
it in createdir().
the image cache has the property of keeping a channel
for the executable binary arround which prevents the
mountpoint from going away.
this can easily be reproduced by running:
@{rfork n; ramfs; cp /bin/echo /tmp; /tmp/echo}
observe how ramfs stays arround until the image is
reclaimed. the echo binary is also cached but is
unreachable from any namespace.
we now restrict the caching to mounts that use the client
cache (-C flag) only. this should always be the case
for /bin. places where this isnt the case might observe
a performance regression.
closechanq() is unable to fork a new closeproc when palloc
is locked. so we spawn a closeproc early in chandevinit()
and make sure theres always one process arround to handle
the queue.
we'r getting a rectangle taller than a single line from
coladd() which causes textresize() to collapse the tag
text to zero height.
should probably fix coladd() instead.
introduce kernel inspured Block structure with
read/write pointers to pass packets arround.
the intend is to avoid copying when adding/removing
frame headers and simplifying the drivers.
the driver now calls etheriq() directly allowing it to
queue multiple packets in one pass without having
to keep state.
transmit gets a buffer passed that has room for
frame headers and trailers so no copying is needed.
blocks are refcounted avoiding another copy when
passed to only one receive queue (common case).
receive queues are now limited to 100KB avoiding
buffer bloat.
Dq* a memory leak in destroyfid has been fixed.
lots of minor cleanups.