Lines 3421-3426
HostIF_NumOnlineLogicalCPUs(void)
Link Here
|
3421 |
#endif |
3421 |
#endif |
3422 |
} |
3422 |
} |
3423 |
|
3423 |
|
|
|
3424 |
/* |
3425 |
*---------------------------------------------------------------------- |
3426 |
* |
3427 |
* HostIFDoIoctl -- |
3428 |
* |
3429 |
* Issue ioctl. Assume kernel is not locked. It is not true now, |
3430 |
* but it makes things easier to understand, and won't surprise us |
3431 |
* later when we get rid of kernel lock from our code. |
3432 |
* |
3433 |
* Results: |
3434 |
* Same as ioctl method. |
3435 |
* |
3436 |
* Side effects: |
3437 |
* none. |
3438 |
* |
3439 |
*---------------------------------------------------------------------- |
3440 |
*/ |
3441 |
|
3442 |
static long |
3443 |
HostIFDoIoctl(struct file *filp, |
3444 |
u_int iocmd, |
3445 |
unsigned long ioarg) |
3446 |
{ |
3447 |
#ifdef HAVE_UNLOCKED_IOCTL |
3448 |
if (filp->f_op->unlocked_ioctl) { |
3449 |
return filp->f_op->unlocked_ioctl(filp, iocmd, ioarg); |
3450 |
} |
3451 |
#endif |
3452 |
if (filp->f_op->ioctl) { |
3453 |
long err; |
3454 |
|
3455 |
lock_kernel(); |
3456 |
err = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, iocmd, ioarg); |
3457 |
unlock_kernel(); |
3458 |
return err; |
3459 |
} |
3460 |
return -ENOIOCTLCMD; |
3461 |
} |
3424 |
|
3462 |
|
3425 |
/* |
3463 |
/* |
3426 |
*---------------------------------------------------------------------- |
3464 |
*---------------------------------------------------------------------- |
Lines 3443-3465
HostIF_NumOnlineLogicalCPUs(void)
Link Here
|
3443 |
*/ |
3481 |
*/ |
3444 |
|
3482 |
|
3445 |
static int |
3483 |
static int |
3446 |
HostIFFastClockThread(void *data) |
3484 |
HostIFFastClockThread(void *data) // IN: |
3447 |
{ |
3485 |
{ |
3448 |
struct file *filp = (struct file *) data; |
3486 |
struct file *filp = (struct file *) data; |
3449 |
int res; |
3487 |
int res; |
3450 |
mm_segment_t oldFS; |
3488 |
mm_segment_t oldFS; |
3451 |
unsigned rate = 0; |
3489 |
unsigned rate = 0; |
3452 |
|
3490 |
|
3453 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) |
|
|
3454 |
compat_daemonize("vmware-rtc"); |
3491 |
compat_daemonize("vmware-rtc"); |
3455 |
#endif |
|
|
3456 |
oldFS = get_fs(); |
3492 |
oldFS = get_fs(); |
3457 |
set_fs(KERNEL_DS); |
3493 |
set_fs(KERNEL_DS); |
|
|
3494 |
compat_allow_signal(SIGKILL); |
3458 |
cap_raise(current->cap_effective, CAP_SYS_RESOURCE); |
3495 |
cap_raise(current->cap_effective, CAP_SYS_RESOURCE); |
3459 |
compat_set_user_nice(current, -20); |
3496 |
compat_set_user_nice(current, linuxState.fastClockPriority); |
3460 |
|
3497 |
|
3461 |
while (linuxState.fastClockRate > HZ + HZ/16 && |
3498 |
while (linuxState.fastClockRate > HZ + HZ/16) { |
3462 |
!signal_pending(current)) { |
|
|
3463 |
unsigned long buf; |
3499 |
unsigned long buf; |
3464 |
loff_t pos = 0; |
3500 |
loff_t pos = 0; |
3465 |
unsigned p2rate; |
3501 |
unsigned p2rate; |
Lines 3473-3480
HostIFFastClockThread(void *data)
Link Here
|
3473 |
p2rate <<= 1; |
3509 |
p2rate <<= 1; |
3474 |
} |
3510 |
} |
3475 |
|
3511 |
|
3476 |
res = filp->f_op->ioctl(filp->f_dentry->d_inode, |
3512 |
res = HostIFDoIoctl(filp, RTC_IRQP_SET, p2rate); |
3477 |
filp, RTC_IRQP_SET, p2rate); |
|
|
3478 |
if (res < 0) { |
3513 |
if (res < 0) { |
3479 |
Warning("/dev/rtc set rate %d failed: %d\n", p2rate, res); |
3514 |
Warning("/dev/rtc set rate %d failed: %d\n", p2rate, res); |
3480 |
goto out; |
3515 |
goto out; |
Lines 3542-3561
HostIFFastClockThread(void *data)
Link Here
|
3542 |
*/ |
3577 |
*/ |
3543 |
|
3578 |
|
3544 |
int |
3579 |
int |
3545 |
HostIF_SetFastClockRate(unsigned rate) |
3580 |
HostIF_SetFastClockRate(unsigned int rate) // IN: Frequency in Hz. |
3546 |
{ |
3581 |
{ |
3547 |
ASSERT(MutexIsLocked(&fastClockMutex)); |
3582 |
ASSERT(MutexIsLocked(&fastClockMutex)); |
3548 |
linuxState.fastClockRate = rate; |
3583 |
linuxState.fastClockRate = rate; |
|
|
3584 |
|
3585 |
/* |
3586 |
* Overview |
3587 |
* -------- |
3588 |
* An SMP Linux kernel programs the 8253 timer (to increment the 'jiffies' |
3589 |
* counter) _and_ all local APICs (to run the scheduler code) to deliver |
3590 |
* interrupts HZ times a second. |
3591 |
* |
3592 |
* Time |
3593 |
* ---- |
3594 |
* The kernel tries very hard to spread all these interrupts evenly over |
3595 |
* time, i.e. on a 1 CPU system, the 1 local APIC phase is shifted by 1/2 |
3596 |
* period compared to the 8253, and on a 2 CPU system, the 2 local APIC |
3597 |
* phases are respectively shifted by 1/3 and 2/3 period compared to the |
3598 |
* 8253. This is done to reduce contention on locks guarding the global task |
3599 |
* queue. |
3600 |
* |
3601 |
* Space |
3602 |
* ----- |
3603 |
* The 8253 interrupts are distributed between physical CPUs, evenly on a P3 |
3604 |
* system, whereas on a P4 system physical CPU 0 gets all of them. |
3605 |
* |
3606 |
* Long story short, unless the monitor requested rate is significantly |
3607 |
* higher than HZ, we don't need to send IPIs or exclusively grab /dev/rtc |
3608 |
* to periodically kick vCPU threads running in the monitor on all physical |
3609 |
* CPUs. |
3610 |
*/ |
3611 |
|
3549 |
if (rate > HZ + HZ/16) { |
3612 |
if (rate > HZ + HZ/16) { |
3550 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) |
|
|
3551 |
if (linuxState.fastClockTask==NULL) { |
3552 |
struct task_struct *t; |
3553 |
#else |
3554 |
if (!linuxState.fastClockThread) { |
3613 |
if (!linuxState.fastClockThread) { |
3555 |
#endif |
|
|
3556 |
struct file *filp; |
3614 |
struct file *filp; |
3557 |
int fsuid, res; |
3615 |
int fsuid, res; |
3558 |
Bool cap; |
3616 |
Bool cap; |
|
|
3617 |
long pid; |
3559 |
|
3618 |
|
3560 |
fsuid = current->fsuid; |
3619 |
fsuid = current->fsuid; |
3561 |
current->fsuid = 0; |
3620 |
current->fsuid = 0; |
Lines 3567-3573
HostIF_SetFastClockRate(unsigned rate)
Link Here
|
3567 |
} |
3626 |
} |
3568 |
cap = cap_raised(current->cap_effective, CAP_SYS_RESOURCE); |
3627 |
cap = cap_raised(current->cap_effective, CAP_SYS_RESOURCE); |
3569 |
cap_raise(current->cap_effective, CAP_SYS_RESOURCE); |
3628 |
cap_raise(current->cap_effective, CAP_SYS_RESOURCE); |
3570 |
res = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, RTC_PIE_ON, 0); |
3629 |
res = HostIFDoIoctl(filp, RTC_PIE_ON, 0); |
3571 |
if (!cap) { |
3630 |
if (!cap) { |
3572 |
cap_lower(current->cap_effective, CAP_SYS_RESOURCE); |
3631 |
cap_lower(current->cap_effective, CAP_SYS_RESOURCE); |
3573 |
} |
3632 |
} |
Lines 3576-3613
HostIF_SetFastClockRate(unsigned rate)
Link Here
|
3576 |
compat_filp_close(filp, current->files); |
3635 |
compat_filp_close(filp, current->files); |
3577 |
return -res; |
3636 |
return -res; |
3578 |
} |
3637 |
} |
3579 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) |
3638 |
pid = kernel_thread(HostIFFastClockThread, filp, 0); |
3580 |
t = kthread_create(HostIFFastClockThread, filp, "vmware-rtc"); |
3639 |
if (pid < 0) { |
3581 |
if (IS_ERR(t)) { |
3640 |
/* |
3582 |
compat_filp_close(filp, current->files); |
3641 |
* Ignore ERESTARTNOINTR silently, it occurs when signal is |
3583 |
return -PTR_ERR(t); |
3642 |
* pending, and syscall layer automatically reissues operation |
3584 |
} |
3643 |
* after signal is handled. |
3585 |
linuxState.fastClockTask=t; |
3644 |
*/ |
3586 |
wake_up_process(t); |
3645 |
if (pid != -ERESTARTNOINTR) { |
3587 |
#else |
3646 |
Warning("/dev/rtc cannot start watch thread: %ld\n", pid); |
3588 |
linuxState.fastClockThread = |
3647 |
} |
3589 |
kernel_thread(HostIFFastClockThread, filp, 0); |
3648 |
compat_filp_close(filp, current->files); |
3590 |
#endif |
3649 |
return -pid; |
|
|
3650 |
} |
3651 |
linuxState.fastClockThread = compat_find_get_pid(pid); |
3591 |
} |
3652 |
} |
3592 |
} else { |
3653 |
} else { |
3593 |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) |
|
|
3594 |
if (linuxState.fastClockTask!=NULL) { |
3595 |
kthread_stop(linuxState.fastClockTask); |
3596 |
linuxState.fastClockTask = NULL; |
3597 |
compat_wait_for_completion(&fastClockExited); |
3598 |
} |
3599 |
#else |
3600 |
if (linuxState.fastClockThread) { |
3654 |
if (linuxState.fastClockThread) { |
3601 |
kill_proc(linuxState.fastClockThread, SIGKILL, 1); |
3655 |
compat_kill_pid(linuxState.fastClockThread, SIGKILL, 1); |
|
|
3656 |
compat_put_pid(linuxState.fastClockThread); |
3602 |
linuxState.fastClockThread = 0; |
3657 |
linuxState.fastClockThread = 0; |
3603 |
compat_wait_for_completion(&fastClockExited); |
3658 |
compat_wait_for_completion(&fastClockExited); |
3604 |
} |
3659 |
} |
3605 |
#endif |
|
|
3606 |
} |
3660 |
} |
3607 |
return 0; |
3661 |
return 0; |
3608 |
} |
3662 |
} |
3609 |
|
3663 |
|
3610 |
|
|
|
3611 |
/* |
3664 |
/* |
3612 |
*----------------------------------------------------------------------------- |
3665 |
*----------------------------------------------------------------------------- |
3613 |
* |
3666 |
* |