functionality for the following entry pints:
mac_test_init_proc_label()
mac_test_destroy_proc_label()
For process labeling entry points, now also track the use of process
labels and test assertions about their integrity and life cycle.
mac_test_thread_userret()
mac_test_check_kenv_dump()
mac_test_check_kenv_get()
mac_test_check_kenv_set()
mac_test_check_kenv_unset()
mac_test_check_kld_load()
mac_test_check_kld_stat()
mac_test_check_kld_unload()
mac_test_check_sysarch_ioperm()
mac_test_check_system_acct()
mac_test_check_system_reboot()
mac_test_check_system_settime()
mac_test_check_system_swapon()
mac_test_check_system_swapoff()
mac_test_check_system_sysctl()
For other entry points, just provide testing stubs.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
for enforcement:
mac_mls_check_system_swapon() - Require that the subject and the
swapfile target vnode labels dominate one another. An additional
check is probably needed here to require that the swapfile target
has a label of mls/high to prevent information leakage through
swapfiles.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
include a new entry point available for enforcement:
mac_bsdextended_check_system_swapon() - Apply extended access
control checks to the file target of swap.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
points available for enforcement:
mac_biba_check_sysarch_ioperm() - Require Biba privilege to make
use of privileged machine-dependent interfaces, protecting against
bypass of the policy via various mechanisms.
mac_biba_check_system_swapoff() - Require Biba privilege to disable
swapping against a vnode target.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
where physical addresses larger than virtual addresses, such as i386s
with PAE.
- Use this to represent physical addresses in the MI vm system and in the
i386 pmap code. This also changes the paddr parameter to d_mmap_t.
- Fix printf formats to handle physical addresses >4G in the i386 memory
detection code, and due to kvtop returning vm_paddr_t instead of u_long.
Note that this is a name change only; vm_paddr_t is still the same as
vm_offset_t on all currently supported platforms.
Sponsored by: DARPA, Network Associates Laboratories
Discussed with: re, phk (cdevsw change)
flexible process_fork, process_exec, and process_exit eventhandlers. This
reduces code duplication and also means that I don't have to go duplicate
the eventhandler locking three more times for each of at_fork, at_exec, and
at_exit.
Reviewed by: phk, jake, almost complete silence on arch@
is set to 0, it now has the same affect as setting witness_dead used to
have.
- Added a sysctl handler that allows root to change witness_watch from a
non-zero value to zero to disable witness at runtime. Note that you
can't turn witness back on once it is off. You can only turn it off as
a one-way switch.
- Added a comment describing the possible values of witness_watch.
Otherwise sysbeep() makes an annoying clicking sound on some systems.
'kbdcontrol -b off' just sets the duration and pitch to zero, it doesn't
set the QUIET_BELL flag.
Tested by: SorAlx <soralx@cydem.zp.ua>
PR: misc/41772
MFC after: 1 week
fifo_open() waiting for another reader or writer if one arrived and
departed while we were waiting (or a little earlier).
Rev.1.79 broke blocking opens of fifos by making them time out after 1
second. This was bad for at least apsfilter.
Tested by: "Simon 'corecode' Schubert" <corecode@corecode.ath.cx>,
Alexander Leidinger <Alexander@leidinger.net>,
phk
MFC after: 4 weeks
doesn't do it. This fixes all known causes of "Context switches not
allowed in the debugger" in mi_switch(). The main cause was trap_fatal()
calling kdb_trap() with interrupts enabled. Switching to ithreads for
interrupt handling then made fatal traps more fatal and harder to debug.
The problem was limited in -current because most interrupt handlers are
blocked by Giant, but it occurred almost deterministically for me because
my clock interrupt handlers are non-fast and not blocked by Giant.
- Clear PCIM_CMD_MWRICEN:
some chips seem to have problem with write invalidate.
clearing this bit fixes SBP timeout problem.
Tested by: Michael Reifenberger <Michael.Reifenberger@Plaut.de>
- Set PCIM_CMD_SERRESPEN and PCIM_CMD_PERRESPEN
- Moderate value for latency timer.
which are no longer required now that we have UFS2 with extended
attribute transactions.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, Network Associates Laboratories
Change 27224 by imp@imp_hammer on 2003/03/22 00:16:22
Put what I think are the correct TX RATE translation tables
in place for LUCENT firmware. This is based on the 4.x driver.
Maybe it should be table driven?
ifconfig wi0 media DS/11Mbps still fails, but it fails before
we even get to the txrate stuff, so other things are wrong.
Change 27225 by imp@imp_hammer on 2003/03/22 00:45:11
Default ic_fixed_rate to -1. This is the same thing as autoselect.
There really should be a #define for this...
- Use it in atacontrol(8) when listing ATA devices instead of
stopping at the first ENXIO received.
This makes atacontrol list work on my sparc64 where the two ATA
channels I have are numbered 2 and 3.
Reviewed by: sos
functions are now all basically identical except that alpha linux uses
Elf64 arguments and svr4 and i386 linux use Elf32. The fixups include
changing the first argument to be a register_t ** to match the prototype
for fixup functions, asserting that the process in the image_params struct
is always curproc and removing unnecessary locking to read credentials as a
result, and a few style fixes.
in busdma tags. There are currently no tags shared accross
different drivers so this isn't needed at the moment, but it
will be required when we'll have a proper newbus method to get
the parent busdma tag.
switches. Not as lazy as it could be. Changing FPU state with sigcontext
still TODO.
fpu.c - convert some asm to inline C, and macroize fpu loads/stores
swtch.S - call out to save/restore fpu routines
trap.c - always call enable_fpu, since this shouldn't be called once
the FPU has been enabled for a thread
genassym.c - define for pcb fpu flag
on future UltraSPARC cpus for which the data cache is not direct mapped.
- Move UltraSPARC I and II (spitfire, blackbird, sapphire, sabre) specific
functions to spitfire.c, and add cheetah.c for UltraSPARC III specific
functions. Initially just cache flushing, but there are a few other
functions that will need to move here.
- Add an ipi handler for data cache flushing on UltraSPARC III.
- Use function pointers to select the right cache flushing functions based
on cpu_impl.
With this it is possible to boot single user from an mfs root on UltraSPARC
III systems, including spinning up secondary processors. There is currently
no support for the host to pci bridge, and no documentation for it is
publically available.
Thanks to Oleg Derevenetz for providing access to a system with UltraSPARC
III+ cpus.
UltraSPARC III and higher cpus and do needed setup.
- Disable the "system tick" interrupt for UltraSPARC III. This avoids
an interrupt storm on startup since we're not prepared for these at
all. This feature has questionable use anyway.
- Clear tick on startup and then leave it alone.
kse_mailbox to schedule an upcall, this is useful for userland timeout
routine, for example pthread_cond_timedwait().
Also extract upcall scheduling code from kse_reassign and create
a new function called thread_switchout to include these code.
Reviewed by: julain
the devstat is for an "interior" GEOM node and register using the
name argument as a geom identity pointer. Do not put these devstat
structures on the list returned by the sysctl.
This gives us the ability to tell the two kinds of nodes apart and
leave the current "strictly physical" view of devstat intact without
modifications, yet be able to use devstat for both kinds of devices.
It also saves us bloating struct devstat with another 48 bytes of
space for the name. At least for now.
Reviewed by: ken
Add a mutex and protect the allocation and traversal of the list with it.
When we allocate a page for devstat use we drop the mutex and use
M_WAITOK this is not nice, but under the given circumstances the
best we can do.
In the sysctl handler for returning the devstat entries we do not want to
hold the mutex across copyout(9) calls, so we keep a very careful eye on
the devstat_generation count, and abandon with EBUSY if it changes under
our feet.
Specifically test for BIO_WRITE, rather than default non-read,non-deletes
as write. Make the default be DEVSTAT_NO_DATA.
Add atomic increments of the sequence[01] fields so applications using the
mmap'ed view stand a chance of detecting updates in progress.
Reviewed by: ken
driver should use port or memory based IO, determine it dynamically
at runtime, preferring MMIO where possible. This helps us support newer
arches which dislike port based access better.
Tested on i386 & sparc64, with 3c900, 905, 905b, and 905C cards.
(in varying combinations by both jake and myself)
one tx buffer for these cards. The old driver only used one. We use
1 for symbol, and 3 for prism cards.
o Don't do the maximum loops thing in the ISR. In fact, revert to the
old interrupt handler. Lucent cards don't seem to work too well if
you don't disable/enable interrupts from the card in the ISR.
Between these two changes, Lucent cards suck less. They work in
autoselect mode only. And seem to get 1Mbps or 2Mbps only. Setting a
specific media speed doesn't work, and I've had a few issues even with
these patches. They turn a former brick into a nearly useful card.
These patches work on the prism 2 and 2.5 PC Card cards that I have.
I've not tested this on PCI cards. I suspect, but couldn't find
proof, that they were the reason that the ISR was changed so radically
from its FreeBSD roots in NetBSD. We might need to have a variant ISR
if so.
4 bits. This reportedly fixes booting on the SW7500CW2. Much thanks to
the submitter for tracking this down!
Submitted by: Brian Buchanan <brian@ncircle.com>
Reviewed by: peter
MFC after: 3 days
- Use SYSINIT to initialize the structures instead of checking
total_bpages against 0 in alloc_bounce_pages(), which could lead
to several initializations being done at the same time.
- Add missing locking in bus_dmamap_load(), the bounce pages mutex
must be held when calling reserve_bounce_pages() and when touching
the bounce_map_waitinglist list.
- Remove the useless splhigh() and splx() calls.
- Assert that the bounce pages mutex is held in reserve_bounce_pages()
to catch regressions.
code both seem to call wi_start (directly or via the if_start pointer)
without checking to see if OACTIVE is 0. In addition, I think that
with the use of 3 transmit buffers this routine can be called with
OACTIVE set, but I might be mistaken about that (and it doesn't
matter).
Reviewed by: sam
Noticed by: imp, alfred, ambrisko
but I decided that it was important for this patch to not bit-rot, and
since it is mainly moving code around, the total amount of entropy is
epsilon /phk)
This is a patch to move the common parts of linux_getcwd() back into
kern/vfs_cache.c so that the standard FreeBSD libc getcwd() can use it's
extended functionality. The linux syscall linux_getcwd() in
compat/linux/linux_getcwd.c has been rewritten to use it too. It should
be possible to simplify libc's getcwd() after this. No doubt this code
needs some cleaning up, since I've left in the sysctl variables I used
for debugging.
PR: 48169
Submitted by: James Whitwell <abacau@yahoo.com.au>
to avoid a "locking against myself" panic when udf_hashins() tries
to lock it again. Lock the vnode in udf_hashins() before adding it to
the hash bucket.
are machine dependent because they are not required to update the tlb when
mappings are added or removed, and doing so is machine dependent.
In addition, an implementation may require that pages mapped with pmap_kenter
have a backing vm_page_t, which is not necessarily true of all physical
pages, and so may choose to pass the vm_page_t to pmap_kenter instead of the
physical address in order to make this requirement clear.
- Support IFF_MONITOR.
- Borrow some consistency for if_input() routines from if_ethersubr.c.
- Correct comments regarding fddi_input() that no longer apply.
Kernel:
Change statistics to use the *uptime() timescale (ie: relative to
boottime) rather than the UTC aligned timescale. This makes the
device statistics code oblivious to clock steps.
Change timestamps to bintime format, they are cheaper.
Remove the "busy_count", and replace it with two counter fields:
"start_count" and "end_count", which are updated in the down and
up paths respectively. This removes the locking constraint on
devstat.
Add a timestamp argument to devstat_start_transaction(), this will
normally be a timestamp set by the *_bio() function in bp->bio_t0.
Use this field to calculate duration of I/O operations.
Add two timestamp arguments to devstat_end_transaction(), one is
the current time, a NULL pointer means "take timestamp yourself",
the other is the timestamp of when this transaction started (see
above).
Change calculation of busy_time to operate on "the salami principle":
Only when we are idle, which we can determine by the start+end
counts being identical, do we update the "busy_from" field in the
down path. In the up path we accumulate the timeslice in busy_time
and update busy_from.
Change the byte_* and num_* fields into two arrays: bytes[] and
operations[].
Userland:
Change the misleading "busy_time" name to be called "snap_time" and
make the time long double since that is what most users need anyway,
fill it using clock_gettime(CLOCK_MONOTONIC) to put it on the same
timescale as the kernel fields.
Change devstat_compute_etime() to operate on struct bintime.
Remove the version 2 legacy interface: the change to bintime makes
compatibility far too expensive.
Fix a bug in systat's "vm" page where boot relative busy times would
be bogus.
Bump __FreeBSD_version to 500107
Review & Collaboration by: ken
now unnecessary hack from the previous commit;
- Add support for Interrupt Latch Register (ILR) into puc(4). So far only
ILRs compatible with specifications from Digi International are supported.
Support for other types of ILRs could be easily added later;
- Correct clock frequency for IC Book Labs Dreadnought x16 Lite board;
- Enable ILR detection/usage for IC Book Labs Dreadnought x16 boards.
Sponsored by: IC Book Labs
MFC after: 2 weeks
comes in on is the same interface that we would route out of to get to
the packet's source address. Essentially automates an anti-spoofing
check using the information in the routing table.
Experimental. The usage and rule format for the feature may still be
subject to change.
take a thread instead of a proc for their first argument.
- Add a mutex to protect the system-wide Linux osname, osrelease, and
oss_version variables.
- Change linux_get_prison() to take a thread instead of a proc for its
first argument and to use td_ucred rather than p_ucred. This is ok
because a thread's prison does not change even though it's ucred might.
- Also, change linux_get_prison() to return a struct prison * instead of
a struct linux_prison * since it returns with the struct prison locked
and this makes it easier to safely unlock the prison when we are done
messing with it.
KTRFAC_DROP to track instances when ktrace events are dropped due to the
request pool being exhausted. When a thread tries to post a ktrace event
and is unable to due to no available ktrace request objects, it sets
KTRFAC_DROP in its process' p_traceflag field. The next trace event to
successfully post from that process will set the KTR_DROP flag in the
header of the request going out and clear KTRFAC_DROP.
The KTR_DROP flag is the high bit in the type field of the ktr_header
structure. Older kdump binaries will simply complain about an unknown type
when seeing an entry with KTR_DROP set. Note that KTR_DROP being set on a
record in a ktrace file does not tell you anything except that at least one
event from this process was dropped prior to this event. The user has no
way of knowing what types of events were dropped nor how many were dropped.
Requested by: phk
struct proc as p_tracecred alongside the current cache of the vnode in
p_tracep. This credential is then used for all later ktrace operations on
this file rather than using the credential of the current thread at the
time of each ktrace event.
- Now that we have multiple ktrace-related items in struct proc that are
pointers, rename p_tracep to p_tracevp to make it less ambiguous.
Requested by: rwatson (1)
frames. A comment in if_atm.h suggests that both macros, that for extracting
the ethertype and that for inserting it, handle their argument in host
byte order. In fact, the inserting macro treated its argument as an opposite
host order short and the calling code feeds it the result of htons(). This
happens to work on i386, but fails on sparc. Make the macro use real host
endianess.
Reviewed by: kjc, atm@
- Create a new function bdone() which sets B_DONE and calls wakup(bp). This
is suitable for use as b_iodone for buf consumers who are not going
through the buf cache.
- Create a new function bwait() which waits for the buf to be done at a set
priority and with a specific wmesg.
- Replace several cases where the above functionality was implemented
without locking with the new functions.
possible for some time.
- Lock the buf before accessing fields. This should very rarely be locked.
- Assert that B_DELWRI is set after we acquire the buf. This should always
be the case now.
requiring locked bufs in vfs_bio_awrite(). Previously the buf could
have been written out by fsync before we acquired the buf lock if it
weren't for giant. The cluster_wbuild() handles this race properly but
the single write at the end of vfs_bio_awrite() would not.
- Modify flushbufqueues() so there is only one copy of the loop. Pass a
parameter in that says whether or not we should sync bufs with deps.
- Call flushbufqueues() a second time and then break if we couldn't find
any bufs without deps.
than a MAXPHYS size block ahead. Having this set too high just leaves
other processes starved for IO and screws up interactive response. Let the
users with RAID set it higher when they need it.
process to kill, don't block on a map lock while holding the
process lock. Instead, skip processes whose map locks are held
and find something else to kill.
- Add vm_map_trylock_read() to support the above.
Reviewed by: alc, mike (mentor)
- If SYSCTL_OUT() fails in sysctl_kern_proc_args(), return the error
instead of ignoring it if we have new arguments for the process.
- If the new arguments for a process are too long, return ENOMEM instead of
returning success but not doing the actual copy.
Submitted by: bde
this card is based on 16750 UART, modify sio(4) a bit to ignore 16750-specific
7th bit of MCR when probing card. This allows card to be detected and attached
as 16550A-compatible device. More work needs to be done in order to enable
nice 16750-specific features such as larger fifo buffer and higher speeds.
Sponsored by: IC Book Labs
MFC after: 2 weeks
hold hold it across the check to avoid extra lock operations in the
common case.
- Copy in the new args to a temporary pargs structure before we drop the
reference to the old one. Thus, if the copyin() fails, the process
arguments are unchanged rather than being deleted. Also, p_args is no
longer NULL during the sysctl operation.
it from its pgrp to avoid leaving zombies around with p_pgrp == NULL.
This bug was apparent as a NULL-dereference in the pid selection code
in fork1().
Harti Brandt's effort.
remove the DMA test to detect problems of the first generation PCI chipsets
back in 1998.
it is no longer needed and has been the source of the false alarm that
the driver uses too much stack space.
pmap_release.
- Merged pmap_release and pmap_release_free_page. When pmap_release is
called only the page directory page(s) can be left in the pmap pte object,
since all page table pages will have been freed by pmap_remove_pages and
pmap_remove. In addition, there can only be one reference to the pmap and
the page directory is wired, so the page(s) can never be busy. So all there
is to do is clear the magic mappings from the page directory and free the
page(s).
Sponsored by: DARPA, Network Associates Laboratories
monitors the entropy data harvested by crypto drivers to verify it complies
with FIPS 140-2. If data fails any test then the driver discards it and
commences continuous testing of harvested data until it is deemed ok.
Results are collected in a statistics block and, optionally, reported on
the console. In normal use the overhead associated with this driver is
not noticeable.
Note that drivers must (currently) be compiled specially to enable use.
Obtained from: original code by Jason L. Wright
conditional in each driver on foo_RNDTEST being defined_
o bring HIFN_DEBUG and UBSEC_DEBUG out to be visible options; they control
the debugging printfs that are set with hw.foo.debug (e.g. hw.hifn.debug)
closely what function is really doing. Update all existing consumers
to use the new name.
Introduce a new vfs_stdsync function, which iterates over mount
point's vnodes and call FSYNC on each one of them in turn.
Make nwfs and smbfs use this new function instead of rolling their
own identical sync implementations.
Reviewed by: jeff
a parameter instead of using the level of a given witness. When
recursing, pass an indent level of indent + 1.
- Make use of the information witness_levelall() provides in
witness_display_list() to use an O(n) algorithm instead of an O(n^2)
algo to decide which witnesses to display hierarchies from. Basically,
we only display a hierarchy for witnesses with a level of 0.
- Add a new per-witness flag that is reset at the start of
witness_display() for all witness's and is set the first time a witness
is displayed in witness_displaydescendants(). If a witness is
encountered more than once in the lock order tree (which happens often),
witness_displaydescendants() marks the later occurrences with the string
"(already displayed)" and doesn't display the subtree under that
witness. This avoids duplicating large amounts of the lock order tree
in the 'show witness' output in DDB.
All these changes serve to make 'show witness' a lot more readable and
useful than it was previously.
adds a witness to the child list of a parent witness. rebalancetree()
runs through the entire tree removing direct descendants of witnesses
who already have said child witness as an indirect descendant through
another direct descendant. itismychild() now calls insertchild()
followed by rebalancetree() and no longer needs the evil hack of
having static recursed variable.
- Add a function reparentchildren() that adds all the direct descendants
of one witness as direct descendants of another witness.
- Change the return value of itismychild() and similar functions so that
they return 0 in the case of failure due to lack of resources instead
of 1. This makes the return value more intuitive.
- Check the return value of itismychild() when defining the static lock
order in witness_initialize().
- Don't try to setup a lock instance in witness_lock() if itismychild()
fails. Witness is hosed anyways so no need to do any more witness
related activity at that point. It also makes the code flow easier to
understand.
- Add a new depart() function as the opposite of enroll(). When the
reference count of a witness drops to 0 in witness_destroy(), this
function is called on that witness. First, it runs through the
lock order tree using reparentchildren() to reparent direct descendants
of the departing witness to each of the witness' parents in the tree.
Next, it releases it's own child list and other associated resources.
Finally it calls rebalanacetree() to rebalance the lock order tree.
- Sort function prototypes into something closer to alphabetical order.
As a result of these changes, there should no longer be 'dead' witnesses
in the order tree, and repeatedly loading and unloading a module should no
longer exhaust witness of its internal resources.
Inspired by: gallatin
recursing on a lock instead of before. This fixes a bug where WITNESS
could get a little confused if you did an sx_tryslock() on a sx lock that
you already had an slock on. WITNESS would still function correctly but
it could result in weirdness in the output of 'show locks'. This also
makes it possible for mtx_trylock() to recurse on a lock.
used popped into my head during my morning commute a few weeks ago, but
it is also very similar (though a bit simpler) to a patch that mini@
developed a while ago. Basically, each eventhandler list has a mutex and
a run count. During an eventhandler invocation, the mutex is held while
we traverse the list but is dropped while we execute actual handlers. Also,
a runcount counter is incremented at the start of an invocation and
decremented at the end of an invocation. Adding to the list is not a big
deal since the reference of a thread currently executing the handlers
remains valid across an add operation. Whether or not new handlers are
executed by threads currently executing the handlers for a given list is
indeterminate however. The harder case is when a handler is removed from
the list. If the runcount is zero, the handler is simply removed from the
list directly. If the runcount is not zero, then another thread is
currently executing the handlers of this list, so the priority of this
handler is set to a magic value (currently -1) to mark it as dead. Dead
handlers are not executed during an invocation. If the runcount is zero
after it is decremented at the end of an invocation, then a new
eventhandler_prune_list() function is called to remove dead handlers from
the list.
Additional minor notes:
- All the common parts of EVENTHANDLER_INVOKE() and
EVENTHANDLER_FAST_INVOKE() have been merged into a common
_EVENTHANDLER_INVOKE() macro to reduce duplication and ease maintenance.
- KTR logging for eventhandlers is now available via the KTR_EVH mask.
- The global eventhander_mutex is no longer recursive.
Tested by: scottl (SMP i386)
monitors the entropy data harvested by crypto drivers to verify it complies
with FIPS 140-2. If data fails any test then the driver discards it and
commences continuous testing of harvested data until it is deemed ok.
Results are collected in a statistics block and, optionally, reported on
the console. In normal use the overhead associated with this driver is
not noticeable.
Note that drivers must (currently) be compiled specially to enable use.
Obtained from: original code by Jason L. Wright
attach routine, calling WIUNLOCK in the error case of one of the ifs
for that routine is now bogus. This should have been removed when the
WILOCK() was removed, but wasn't.
Submitted by: "Harti Brandt" <brandt@fokus.fraunhofer.de>
it is expected that they will not be enabled at the time that it
is called. This is reported to work around a problem in RELENG_4
where the kernel panics on boot if FAST_IPSEC and crypto support
are enabled.
Tested by: Scott Johnson <scottj@insane.com>
- Issue the io that we will later block on prior to doing cluster read ahead
so that it is more likely to be ready when we block.
- Loop issuing clustered reads until we've exhausted the seq count supplied
by the file system.
- Use a sysctl tunable "vfs.read_max" to determine the maximum number of
blocks that we'll read ahead.
use the underlying AsahiOptical USB chip and thus this quirk may need to
be generalized in the future.
PR: kern/46369
Submitted by: Tim Vanderhoek <vanderh@ecf.utoronto.ca>
MFC After: 3 days
I had commented the #ifdef INVARIANTS checks out to make sure I ran this
code in all kernels and forgot to comment the #ifdefs back in before I
committed.
Spotted by: bmilekic
[1] PHCC = Pointy Hat Correction Commit
ddb 'show locks' command. Thus, move witness_list() to the #ifdef DDB
section and remove extra checks for calling this function outside of
DDB. Also, witness_list() now returns void instead of returning an int.
Reported by: Steve Ames <steve@energistic.com>
Prodded by: davidxu