You can subscribe to this list here.
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(33) |
Nov
(325) |
Dec
(320) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2007 |
Jan
(484) |
Feb
(438) |
Mar
(407) |
Apr
(713) |
May
(831) |
Jun
(806) |
Jul
(1023) |
Aug
(1184) |
Sep
(1118) |
Oct
(1461) |
Nov
(1224) |
Dec
(1042) |
2008 |
Jan
(1449) |
Feb
(1110) |
Mar
(1428) |
Apr
(1643) |
May
(682) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: rzvajgh4 <gua...@ya...> - 2008-05-03 07:20:42
|
舐めるのが好きな27歳です。結婚はしています。 お互い舐めあいませんか? 舐められるのや舐めるのが好きな不倫パートナーが欲しいです。 あなたがエッチに積極的な方だったらいいなぁ(*^_^*) http://tsuma2.net/pc/main.php?y7ts04 |
From: Aurelien J. <aur...@au...> - 2008-05-02 22:45:40
|
On Fri, May 02, 2008 at 07:23:22PM -0300, Marcelo Tosatti wrote: > On Fri, May 02, 2008 at 10:39:25PM +0200, Aurelien Jarno wrote: > > Hi, > > > > Since commit a0d22c57fbf0c67d73ab7ca3416841030e0bc22f, FreeBSD guests > > takes all host CPU even when they are idle. Reverting this patch in > > kvm-67 or git tree fixes (or workarounds?) the problem. Using > > -no-kvm-pit also workarounds the problem. > > > > Some more details: > > Host: Linux 2.6.24 x86-64 > > CPU: problem occurs on T7500 and Q9450 > > Guest: problem occurs with FreeBSD/i386 6.2 and 6.3 > > > > Regards, > > Aurelien > > Aurelien, > > Can you give this a try. Yep, that fixes the problem. Thanks a lot! > diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c > index 1646102..07f9ff1 100644 > --- a/arch/x86/kvm/i8254.c > +++ b/arch/x86/kvm/i8254.c > @@ -216,7 +216,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu) > { > struct kvm_pit *pit = vcpu->kvm->arch.vpit; > > - if (pit && vcpu->vcpu_id == 0) > + if (pit && vcpu->vcpu_id == 0 && pit->pit_state.inject_pending) > return atomic_read(&pit->pit_state.pit_timer.pending); > > return 0; > -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' au...@de... | aur...@au... `- people.debian.org/~aurel32 | www.aurel32.net |
From: Marcelo T. <mto...@re...> - 2008-05-02 22:20:27
|
On Fri, May 02, 2008 at 10:39:25PM +0200, Aurelien Jarno wrote: > Hi, > > Since commit a0d22c57fbf0c67d73ab7ca3416841030e0bc22f, FreeBSD guests > takes all host CPU even when they are idle. Reverting this patch in > kvm-67 or git tree fixes (or workarounds?) the problem. Using > -no-kvm-pit also workarounds the problem. > > Some more details: > Host: Linux 2.6.24 x86-64 > CPU: problem occurs on T7500 and Q9450 > Guest: problem occurs with FreeBSD/i386 6.2 and 6.3 > > Regards, > Aurelien Aurelien, Can you give this a try. diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 1646102..07f9ff1 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -216,7 +216,7 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu) { struct kvm_pit *pit = vcpu->kvm->arch.vpit; - if (pit && vcpu->vcpu_id == 0) + if (pit && vcpu->vcpu_id == 0 && pit->pit_state.inject_pending) return atomic_read(&pit->pit_state.pit_timer.pending); return 0; |
From: Aurelien J. <aur...@au...> - 2008-05-02 20:39:21
|
Hi, Since commit a0d22c57fbf0c67d73ab7ca3416841030e0bc22f, FreeBSD guests takes all host CPU even when they are idle. Reverting this patch in kvm-67 or git tree fixes (or workarounds?) the problem. Using -no-kvm-pit also workarounds the problem. Some more details: Host: Linux 2.6.24 x86-64 CPU: problem occurs on T7500 and Q9450 Guest: problem occurs with FreeBSD/i386 6.2 and 6.3 Regards, Aurelien commit a0d22c57fbf0c67d73ab7ca3416841030e0bc22f Author: Marcelo Tosatti <mto...@re...> Date: Fri Apr 11 14:53:26 2008 -0300 KVM: hlt emulation should take in-kernel APIC/PIT timers into account Timers that fire between guest hlt and vcpu_block's add_wait_queue() are ignored, possibly resulting in hangs. Also make sure that atomic_inc and waitqueue_active tests happen in the specified order, otherwise the following race is open: CPU0 CPU1 if (waitqueue_active(wq)) add_wait_queue() if (!atomic_read(pit_timer->pending)) schedule() atomic_inc(pit_timer->pending) Signed-off-by: Marcelo Tosatti <mto...@re...> Signed-off-by: Avi Kivity <av...@qu...> -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' au...@de... | aur...@au... `- people.debian.org/~aurel32 | www.aurel32.net |
From: Glauber C. <gc...@re...> - 2008-05-02 20:26:32
|
Paul Brook wrote: >>> Maybe 'VCPU' would be a clearer name? QEMU provides its own VCPU, and >>> KQEMU+QEMU also provide one toegether. While KVM provides essentially >>> one or more whole VCPUs by itself and uses QEMU's drivers only doesn't >>> it? >>> >>> -- Jamie >> VCPU is rather confusing with the vcpus themselves. KVM, for instance, >> has its own structures called "vcpu". >> >> If it is preferred, however, we can name the structure VCPUOperations, >> and change the function names that involves accel_yyy to vcpu_op_yyy() > > kvm wants to hook into more than just the CPU doesn't it? But so far, the structure I proposed only touches cpu-related things. We can have two structures for clarity. Like MEMOperations, and so far. We do it this way for paravirt_ops in linux, with good results in code clarity. |
From: Paul B. <pa...@co...> - 2008-05-02 20:16:30
|
> > Maybe 'VCPU' would be a clearer name? QEMU provides its own VCPU, and > > KQEMU+QEMU also provide one toegether. While KVM provides essentially > > one or more whole VCPUs by itself and uses QEMU's drivers only doesn't > > it? > > > > -- Jamie > > VCPU is rather confusing with the vcpus themselves. KVM, for instance, > has its own structures called "vcpu". > > If it is preferred, however, we can name the structure VCPUOperations, > and change the function names that involves accel_yyy to vcpu_op_yyy() kvm wants to hook into more than just the CPU doesn't it? Paul |
From: Glauber C. <gc...@re...> - 2008-05-02 19:56:50
|
Jamie Lokier wrote: > Glauber Costa wrote: >> This patch introduces QEMUAccel, a placeholder for function pointers >> that aims at helping qemu to abstract accelerators such as kqemu and >> kvm (actually, the 'accelerator' name was proposed by avi kivity, since >> he loves referring to kvm that way). > > Just a little thought... > > Maybe 'VCPU' would be a clearer name? QEMU provides its own VCPU, and > KQEMU+QEMU also provide one toegether. While KVM provides essentially > one or more whole VCPUs by itself and uses QEMU's drivers only doesn't > it? > > -- Jamie VCPU is rather confusing with the vcpus themselves. KVM, for instance, has its own structures called "vcpu". If it is preferred, however, we can name the structure VCPUOperations, and change the function names that involves accel_yyy to vcpu_op_yyy() What do you think? |
From: Anthony L. <ali...@us...> - 2008-05-02 19:44:17
|
This patch reworks the IO thread to use signalfd() instead of sigtimedwait(). This will eliminate the need to use SIGIO everywhere. In this version of the patch, we use signalfd() when it's available. When it isn't available, we instead use a pipe() that is written to in each signal handler. I've tested Windows and Linux guests with SMP without seeing an obvious regressions. Signed-off-by: Anthony Liguori <ali...@us...> diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c index 9a9bf59..0c7f49f 100644 --- a/qemu/qemu-kvm.c +++ b/qemu/qemu-kvm.c @@ -12,6 +12,9 @@ int kvm_allowed = 1; int kvm_irqchip = 1; int kvm_pit = 1; +#include "qemu-common.h" +#include "console.h" + #include <string.h> #include "hw/hw.h" #include "sysemu.h" @@ -38,14 +41,6 @@ __thread struct vcpu_info *vcpu; static int qemu_system_ready; -struct qemu_kvm_signal_table { - sigset_t sigset; - sigset_t negsigset; -}; - -static struct qemu_kvm_signal_table io_signal_table; -static struct qemu_kvm_signal_table vcpu_signal_table; - #define SIG_IPI (SIGRTMIN+4) struct vcpu_info { @@ -169,37 +164,23 @@ static int has_work(CPUState *env) return kvm_arch_has_work(env); } -static int kvm_process_signal(int si_signo) -{ - struct sigaction sa; - - switch (si_signo) { - case SIGUSR2: - pthread_cond_signal(&qemu_aio_cond); - break; - case SIGALRM: - case SIGIO: - sigaction(si_signo, NULL, &sa); - sa.sa_handler(si_signo); - break; - } - - return 1; -} - -static int kvm_eat_signal(struct qemu_kvm_signal_table *waitset, CPUState *env, - int timeout) +static int kvm_eat_signal(CPUState *env, int timeout) { struct timespec ts; int r, e, ret = 0; siginfo_t siginfo; + sigset_t waitset; ts.tv_sec = timeout / 1000; ts.tv_nsec = (timeout % 1000) * 1000000; - r = sigtimedwait(&waitset->sigset, &siginfo, &ts); + sigemptyset(&waitset); + sigaddset(&waitset, SIG_IPI); + + r = sigtimedwait(&waitset, &siginfo, &ts); if (r == -1 && (errno == EAGAIN || errno == EINTR) && !timeout) return 0; e = errno; + pthread_mutex_lock(&qemu_mutex); if (env && vcpu) cpu_single_env = vcpu->env; @@ -208,7 +189,7 @@ static int kvm_eat_signal(struct qemu_kvm_signal_table *waitset, CPUState *env, exit(1); } if (r != -1) - ret = kvm_process_signal(siginfo.si_signo); + ret = 1; if (env && vcpu_info[env->cpu_index].stop) { vcpu_info[env->cpu_index].stop = 0; @@ -224,14 +205,13 @@ static int kvm_eat_signal(struct qemu_kvm_signal_table *waitset, CPUState *env, static void kvm_eat_signals(CPUState *env, int timeout) { int r = 0; - struct qemu_kvm_signal_table *waitset = &vcpu_signal_table; - while (kvm_eat_signal(waitset, env, 0)) + while (kvm_eat_signal(env, 0)) r = 1; if (!r && timeout) { - r = kvm_eat_signal(waitset, env, timeout); + r = kvm_eat_signal(env, timeout); if (r) - while (kvm_eat_signal(waitset, env, 0)) + while (kvm_eat_signal(env, 0)) ; } } @@ -264,9 +244,7 @@ static void pause_all_threads(void) pthread_kill(vcpu_info[i].thread, SIG_IPI); } while (!all_threads_paused()) { - pthread_mutex_unlock(&qemu_mutex); - kvm_eat_signal(&io_signal_table, NULL, 1000); - pthread_mutex_lock(&qemu_mutex); + main_loop_wait(1000); cpu_single_env = NULL; } } @@ -307,6 +285,13 @@ static void setup_kernel_sigmask(CPUState *env) { sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + sigaddset(&set, SIGUSR2); + sigaddset(&set, SIGIO); + sigaddset(&set, SIGALRM); + sigprocmask(SIG_BLOCK, &set, NULL); + sigprocmask(SIG_BLOCK, NULL, &set); sigdelset(&set, SIG_IPI); @@ -343,7 +328,7 @@ static int kvm_main_loop_cpu(CPUState *env) cpu_single_env = env; while (1) { while (!has_work(env)) - kvm_main_loop_wait(env, 10); + kvm_main_loop_wait(env, 1000); if (env->interrupt_request & CPU_INTERRUPT_HARD) env->hflags &= ~HF_HALTED_MASK; if (!kvm_irqchip_in_kernel(kvm_context) && info->sipi_needed) @@ -391,18 +376,6 @@ static void *ap_main_loop(void *_env) return NULL; } -static void qemu_kvm_init_signal_table(struct qemu_kvm_signal_table *sigtab) -{ - sigemptyset(&sigtab->sigset); - sigfillset(&sigtab->negsigset); -} - -static void kvm_add_signal(struct qemu_kvm_signal_table *sigtab, int signum) -{ - sigaddset(&sigtab->sigset, signum); - sigdelset(&sigtab->negsigset, signum); -} - void kvm_init_new_ap(int cpu, CPUState *env) { pthread_create(&vcpu_info[cpu].thread, NULL, ap_main_loop, env); @@ -411,28 +384,12 @@ void kvm_init_new_ap(int cpu, CPUState *env) pthread_cond_wait(&qemu_vcpu_cond, &qemu_mutex); } -static void qemu_kvm_init_signal_tables(void) -{ - qemu_kvm_init_signal_table(&io_signal_table); - qemu_kvm_init_signal_table(&vcpu_signal_table); - - kvm_add_signal(&io_signal_table, SIGIO); - kvm_add_signal(&io_signal_table, SIGALRM); - kvm_add_signal(&io_signal_table, SIGUSR1); - kvm_add_signal(&io_signal_table, SIGUSR2); - - kvm_add_signal(&vcpu_signal_table, SIG_IPI); - - sigprocmask(SIG_BLOCK, &io_signal_table.sigset, NULL); -} - int kvm_init_ap(void) { #ifdef TARGET_I386 kvm_tpr_opt_setup(); #endif qemu_add_vm_change_state_handler(kvm_vm_state_change_handler, NULL); - qemu_kvm_init_signal_tables(); signal(SIG_IPI, sig_ipi_handler); return 0; @@ -444,25 +401,235 @@ void qemu_kvm_notify_work(void) pthread_kill(io_thread, SIGUSR1); } -/* - * The IO thread has all signals that inform machine events - * blocked (io_signal_table), so it won't get interrupted - * while processing in main_loop_wait(). +static int received_signal; + +/* QEMU relies on periodically breaking out of select via EINTR to poll for IO + and timer signals. Since we're now using a file descriptor to handle + signals, select() won't be interrupted by a signal. We need to forcefully + break the select() loop when a signal is received hence + kvm_check_received_signal(). */ + +int kvm_check_received_signal(void) +{ + if (received_signal) { + received_signal = 0; + return 1; + } + + return 0; +} + +#if defined(SYS_signalfd) +#if !defined(HAVE_signalfd) +#include <linux/signalfd.h> + +static int signalfd(int fd, const sigset_t *mask, int flags) +{ + if (flags) { + errno = EINVAL; + return -1; + } + + return syscall(SYS_signalfd, fd, mask, _NSIG / 8); +} +#endif + +/* If we have signalfd, we mask out the signals we want to handle and then + * use signalfd to listen for them. We rely on whatever the current signal + * handler is to dispatch the signals when we receive them. */ +static void sigfd_handler(void *opaque) +{ + int fd = (unsigned long)opaque; + struct signalfd_siginfo info; + struct sigaction action; + ssize_t len; + + while (1) { + do { + len = read(fd, &info, sizeof(info)); + } while (len == -1 && errno == EINTR); + + if (len == -1 && errno == EAGAIN) + break; + + if (len != sizeof(info)) { + printf("read from sigfd returned %ld: %m\n", len); + return; + } + + sigaction(info.ssi_signo, NULL, &action); + if (action.sa_handler) + action.sa_handler(info.ssi_signo); + + if (info.ssi_signo == SIGUSR2) + pthread_cond_signal(&qemu_aio_cond); + } + + received_signal = 1; +} + +static int setup_signal_handlers(int nr_signals, ...) +{ + sigset_t mask; + va_list ap; + int i, fd; + + sigemptyset(&mask); + + va_start(ap, nr_signals); + for (i = 0; i < nr_signals; i++) { + int signo = va_arg(ap, int); + + sigaddset(&mask, signo); + } + va_end(ap); + + sigprocmask(SIG_BLOCK, &mask, NULL); + + fd = signalfd(-1, &mask, 0); + if (fd == -1) + return -1; + + fcntl(fd, F_SETFL, O_NONBLOCK); + + qemu_set_fd_handler2(fd, NULL, sigfd_handler, NULL, + (void *)(unsigned long)fd); + + return 0; +} +#else +struct kvm_sighandler +{ + int signo; + void (*action)(int); +}; + +static int nr_sighandlers; +static struct kvm_sighandler *sighandlers; +static int sigpipefd; + +/* If we don't have signalfd, we don't mask out the signals we want to receive. + * To avoid the signal/select race, we use a pipe() that we write to from the + * signal handler. As a consequence, we save off the signal handler to perform + * dispatch. + */ + +static void kvm_sighandler(int signo) +{ + char buffer[4]; + size_t offset = 0; + + memcpy(&buffer, &signo, 4); + while (offset < 4) { + ssize_t len; + + len = write(sigpipefd, buffer + offset, 4 - offset); + if (len == -1 && errno == EINTR) + continue; + + if (len < 1) + return; + + offset += len; + } +} + +static void sigfd_handler(void *opaque) +{ + int fd = (unsigned long)opaque; + char buffer[4]; + int signo, i; + size_t offset = 0; + + while (1) { + while (offset < 4) { + ssize_t len; + + len = read(fd, buffer + offset, 4 - offset); + if (len == -1 && errno == EINTR) + continue; + + if (len == -1 && errno == EAGAIN) + return; + + if (len < 1) { + fprintf(stderr, "unexpected error in sigfd_handler\n"); + exit(1); + } + + offset += len; + } + + offset = 0; + + memcpy(&signo, buffer, 4); + for (i = 0; i < nr_sighandlers; i++) { + if (sighandlers[i].signo == signo) { + if (sighandlers[i].action) + sighandlers[i].action(signo); + break; + } + } + + if (signo == SIGUSR2) + pthread_cond_signal(&qemu_aio_cond); + } + + received_signal = 1; +} + +static int setup_signal_handlers(int nr_signals, ...) +{ + va_list ap; + int fds[2]; + int i; + + if (pipe(fds) == -1) + return -1; + + sigpipefd = fds[1]; + + nr_sighandlers = nr_signals; + sighandlers = qemu_malloc(nr_sighandlers * sizeof(sighandlers[0])); + + fcntl(fds[0], F_SETFL, O_NONBLOCK); + fcntl(fds[1], F_SETFL, O_NONBLOCK); + + va_start(ap, nr_signals); + for (i = 0; i < nr_signals; i++) { + int signo = va_arg(ap, int); + + sighandlers[i].signo = signo; + sighandlers[i].action = signal(signo, kvm_sighandler); + } + va_end(ap); + + qemu_set_fd_handler2(fds[0], NULL, sigfd_handler, NULL, + (void *)(unsigned long)fds[0]); + + return 0; +} +#endif + int kvm_main_loop(void) { io_thread = pthread_self(); qemu_system_ready = 1; + + setup_signal_handlers(4, SIGIO, SIGALRM, SIGUSR1, SIGUSR2); + pthread_mutex_unlock(&qemu_mutex); pthread_cond_broadcast(&qemu_system_cond); + pthread_mutex_lock(&qemu_mutex); + + cpu_single_env = NULL; + while (1) { - kvm_eat_signal(&io_signal_table, NULL, 1000); - pthread_mutex_lock(&qemu_mutex); - cpu_single_env = NULL; - main_loop_wait(0); + main_loop_wait(1000); if (qemu_shutdown_requested()) break; else if (qemu_powerdown_requested()) @@ -471,7 +638,6 @@ int kvm_main_loop(void) pthread_kill(vcpu_info[0].thread, SIG_IPI); qemu_kvm_reset_requested = 1; } - pthread_mutex_unlock(&qemu_mutex); } pause_all_threads(); @@ -834,10 +1000,7 @@ void qemu_kvm_aio_wait(void) CPUState *cpu_single = cpu_single_env; if (!cpu_single_env) { - pthread_mutex_unlock(&qemu_mutex); - kvm_eat_signal(&io_signal_table, NULL, 1000); - pthread_mutex_lock(&qemu_mutex); - cpu_single_env = NULL; + main_loop_wait(1000); } else { pthread_cond_wait(&qemu_aio_cond, &qemu_mutex); cpu_single_env = cpu_single; @@ -864,3 +1027,14 @@ void kvm_cpu_destroy_phys_mem(target_phys_addr_t start_addr, { kvm_destroy_phys_mem(kvm_context, start_addr, size); } + +void kvm_mutex_unlock(void) +{ + pthread_mutex_unlock(&qemu_mutex); +} + +void kvm_mutex_lock(void) +{ + pthread_mutex_lock(&qemu_mutex); + cpu_single_env = NULL; +} diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h index 024a653..bcab82c 100644 --- a/qemu/qemu-kvm.h +++ b/qemu/qemu-kvm.h @@ -97,4 +97,28 @@ extern kvm_context_t kvm_context; #define qemu_kvm_pit_in_kernel() (0) #endif +void kvm_mutex_unlock(void); +void kvm_mutex_lock(void); + +static inline void kvm_sleep_begin(void) +{ + if (kvm_enabled()) + kvm_mutex_unlock(); +} + +static inline void kvm_sleep_end(void) +{ + if (kvm_enabled()) + kvm_mutex_lock(); +} + +int kvm_check_received_signal(void); + +static inline int kvm_received_signal(void) +{ + if (kvm_enabled()) + return kvm_check_received_signal(); + return 0; +} + #endif diff --git a/qemu/vl.c b/qemu/vl.c index 74be059..1192759 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -7836,6 +7836,23 @@ void qemu_system_powerdown_request(void) cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); } +static int qemu_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *xfds, + struct timeval *tv) +{ + int ret; + + /* KVM holds a mutex while QEMU code is running, we need hooks to + release the mutex whenever QEMU code sleeps. */ + + kvm_sleep_begin(); + + ret = select(max_fd, rfds, wfds, xfds, tv); + + kvm_sleep_end(); + + return ret; +} + void main_loop_wait(int timeout) { IOHandlerRecord *ioh; @@ -7907,11 +7924,12 @@ void main_loop_wait(int timeout) } } - tv.tv_sec = 0; #ifdef _WIN32 + tv.tv_sec = 0; tv.tv_usec = 0; #else - tv.tv_usec = timeout * 1000; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; #endif #if defined(CONFIG_SLIRP) if (slirp_inited) { @@ -7919,7 +7937,7 @@ void main_loop_wait(int timeout) } #endif moreio: - ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); + ret = qemu_select(nfds + 1, &rfds, &wfds, &xfds, &tv); if (ret > 0) { IOHandlerRecord **pioh; int more = 0; @@ -7948,7 +7966,7 @@ void main_loop_wait(int timeout) } else pioh = &ioh->next; } - if (more) + if (more && !kvm_received_signal()) goto moreio; } #if defined(CONFIG_SLIRP) |
From: Karl R. <km...@us...> - 2008-05-02 19:21:20
|
On Thursday 01 May 2008 7:16:53 pm Marcelo Tosatti wrote: > On Thu, May 01, 2008 at 06:00:44PM -0500, Karl Rister wrote: > > Hi > > > > I have been trying to do some testing of a large number of guests (72) on > > a big multi-node IBM box (8 sockets, 32 cores, 128GB) and I am having > > various issues with the guests. I can get the guests to boot, but then I > > start to have problems. Some guests appear to stall doing I/O and some > > become unresponsive and spin their single vcpu at 100%. > > Does -no-kvm-irqchip or -no-kvm-pit makes a difference? If not, please > grab kvm_stat --once output when that happens. I have tried -no-kvm-irqchip and it didn't help any. I will try -no-kvm-pit and get the kvm_stat info for both. > > Also run "readprofile -r ; readprofile -m System-map-of-guest.map" with the > host booted with "profile=kvm". Make sure all guests are running the same > kernel image. Will do. > > The profiling should be easier to understand if you have 1 guest spinning > and remaining ones idle. -- Karl Rister IBM Linux Performance Team km...@us... (512) 838-1553 (t/l 678) |
From: Jamie L. <ja...@sh...> - 2008-05-02 18:16:08
|
Glauber Costa wrote: > This patch introduces QEMUAccel, a placeholder for function pointers > that aims at helping qemu to abstract accelerators such as kqemu and > kvm (actually, the 'accelerator' name was proposed by avi kivity, since > he loves referring to kvm that way). Just a little thought... Maybe 'VCPU' would be a clearer name? QEMU provides its own VCPU, and KQEMU+QEMU also provide one toegether. While KVM provides essentially one or more whole VCPUs by itself and uses QEMU's drivers only doesn't it? -- Jamie |
From: Glauber C. <gc...@re...> - 2008-05-02 17:55:23
|
This patch introduces QEMUAccel, a placeholder for function pointers that aims at helping qemu to abstract accelerators such as kqemu and kvm (actually, the 'accelerator' name was proposed by avi kivity, since he loves referring to kvm that way). To begin with, the accelerator is given the opportunity to register a cpu_interrupt function, to be called after the raw cpu_interrupt. This has the side effect of, for the kqemu accelerator, calling kqemu_cpu_interrupt everytime, which didn't use to happen. But looking at the code, this seems safe to me. This patch applies on raw qemu. Signed-off-by: Glauber Costa <gc...@re...> --- block-raw-posix.c | 5 ----- exec-all.h | 18 +++++++++++++++++- exec.c | 2 ++ kqemu.c | 26 ++++++++++++++++---------- vl.c | 6 +----- 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/block-raw-posix.c b/block-raw-posix.c index 6b0009e..61c23ba 100644 --- a/block-raw-posix.c +++ b/block-raw-posix.c @@ -250,11 +250,6 @@ static void aio_signal_handler(int signum) if (env) { /* stop the currently executing cpu because a timer occured */ cpu_interrupt(env, CPU_INTERRUPT_EXIT); -#ifdef USE_KQEMU - if (env->kqemu_enabled) { - kqemu_cpu_interrupt(env); - } -#endif } #endif } diff --git a/exec-all.h b/exec-all.h index 3ce8242..5162307 100644 --- a/exec-all.h +++ b/exec-all.h @@ -574,6 +574,23 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) } #endif +typedef struct QEMUAccel { + void (*cpu_interrupt)(CPUState *env); +} QEMUAccel; + +extern QEMUAccel *current_accel; + +static inline void register_qemu_accel(QEMUAccel *accel) +{ + current_accel = accel; +} + +static inline void accel_cpu_interrupt(CPUState *env) +{ + if (current_accel && current_accel->cpu_interrupt) + current_accel->cpu_interrupt(env); +} + #ifdef USE_KQEMU #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG)) @@ -583,7 +600,6 @@ void kqemu_flush_page(CPUState *env, target_ulong addr); void kqemu_flush(CPUState *env, int global); void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr); void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr); -void kqemu_cpu_interrupt(CPUState *env); void kqemu_record_dump(void); static inline int kqemu_is_ok(CPUState *env) diff --git a/exec.c b/exec.c index 48dabd6..93d9b01 100644 --- a/exec.c +++ b/exec.c @@ -1226,6 +1226,8 @@ void cpu_interrupt(CPUState *env, int mask) tb_reset_jump_recursive(tb); resetlock(&interrupt_lock); } + + accel_cpu_interrupt(env); } void cpu_reset_interrupt(CPUState *env, int mask) diff --git a/kqemu.c b/kqemu.c index 148a52f..c46698c 100644 --- a/kqemu.c +++ b/kqemu.c @@ -158,6 +158,19 @@ static void kqemu_update_cpuid(CPUState *env) accelerated code */ } +void kqemu_cpu_interrupt(CPUState *env) +{ +#if defined(_WIN32) && KQEMU_VERSION >= 0x010101 + /* cancelling the I/O request causes KQEMU to finish executing the + current block and successfully returning. */ + CancelIo(kqemu_fd); +#endif +} + +QEMUAccel kqemu_accel = { + .cpu_interrupt = kqemu_cpu_interrupt, +}; + int kqemu_init(CPUState *env) { struct kqemu_init init; @@ -239,6 +252,9 @@ int kqemu_init(CPUState *env) } kqemu_update_cpuid(env); env->kqemu_enabled = kqemu_allowed; + if (env->kqemu_enabled) + register_qemu_accel(&kqemu_accel); + nb_pages_to_flush = 0; nb_ram_pages_to_update = 0; return 0; @@ -901,14 +917,4 @@ int kqemu_cpu_exec(CPUState *env) } return 0; } - -void kqemu_cpu_interrupt(CPUState *env) -{ -#if defined(_WIN32) && KQEMU_VERSION >= 0x010101 - /* cancelling the I/O request causes KQEMU to finish executing the - current block and successfully returning. */ - CancelIo(kqemu_fd); -#endif -} - #endif diff --git a/vl.c b/vl.c index 9289982..9272541 100644 --- a/vl.c +++ b/vl.c @@ -240,6 +240,7 @@ struct drive_opt { static CPUState *cur_cpu; static CPUState *next_cpu; static int event_pending = 1; +QEMUAccel *current_accel; #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) @@ -1200,11 +1201,6 @@ static void host_alarm_handler(int host_signum) if (env) { /* stop the currently executing cpu because a timer occured */ cpu_interrupt(env, CPU_INTERRUPT_EXIT); -#ifdef USE_KQEMU - if (env->kqemu_enabled) { - kqemu_cpu_interrupt(env); - } -#endif } event_pending = 1; } -- 1.5.0.6 |
From: Glauber C. <gc...@re...> - 2008-05-02 17:55:19
|
--- exec-all.h | 8 +++++++- kqemu.c | 1 + target-i386/helper2.c | 4 +--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/exec-all.h b/exec-all.h index 621e1ca..784d0ac 100644 --- a/exec-all.h +++ b/exec-all.h @@ -577,6 +577,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) typedef struct QEMUAccel { void (*cpu_interrupt)(CPUState *env); int (*exec_interrupt)(CPUState *env); + void (*init_env)(CPUState *env); } QEMUAccel; extern QEMUAccel *current_accel; @@ -601,10 +602,15 @@ static inline int accel_exec_interrupt(CPUState *env, int *ret) return 0; } +static inline void accel_init_env(CPUState *env) +{ + if (current_accel && current_accel->init_env) + current_accel->init_env(env); +} + #ifdef USE_KQEMU #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG)) -int kqemu_init(CPUState *env); int kqemu_cpu_exec(CPUState *env); void kqemu_flush_page(CPUState *env, target_ulong addr); void kqemu_flush(CPUState *env, int global); diff --git a/kqemu.c b/kqemu.c index 08622ad..95d8a94 100644 --- a/kqemu.c +++ b/kqemu.c @@ -172,6 +172,7 @@ extern int kqemu_exec_interrupt(CPUState *env); QEMUAccel kqemu_accel = { .cpu_interrupt = kqemu_cpu_interrupt, .exec_interrupt = kqemu_exec_interrupt, + .init_env = kqemu_init, }; int kqemu_init(CPUState *env) diff --git a/target-i386/helper2.c b/target-i386/helper2.c index 551a0d8..b11bc22 100644 --- a/target-i386/helper2.c +++ b/target-i386/helper2.c @@ -111,9 +111,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model) return NULL; } cpu_reset(env); -#ifdef USE_KQEMU - kqemu_init(env); -#endif + accel_init_env(env); return env; } -- 1.5.0.6 |
From: Glauber C. <gc...@re...> - 2008-05-02 17:55:19
|
--- cpu-exec.c | 29 ++++++++++++++++++----------- exec-all.h | 10 ++++++++++ kqemu.c | 3 +++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 3246264..79da619 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -35,6 +35,22 @@ #include <sys/ucontext.h> #endif +/* FIXME: This does not belong here */ +int kqemu_exec_interrupt(CPUState *env) +{ + int ret = 0; + if (kqemu_is_ok(env) && env->interrupt_request == 0) { + env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); + ret = kqemu_cpu_exec(env); + /* put eflags in CPU temporary format */ + CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + DF = 1 - (2 * ((env->eflags >> 10) & 1)); + CC_OP = CC_OP_EFLAGS; + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + } + return ret; +} + int tb_invalidated_flag; //#define DEBUG_EXEC @@ -388,16 +404,8 @@ int cpu_exec(CPUState *env1) } env->exception_index = -1; } -#ifdef USE_KQEMU - if (kqemu_is_ok(env) && env->interrupt_request == 0) { - int ret; - env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); - ret = kqemu_cpu_exec(env); - /* put eflags in CPU temporary format */ - CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((env->eflags >> 10) & 1)); - CC_OP = CC_OP_EFLAGS; - env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + + if (accel_exec_interrupt(env, &ret)) { if (ret == 1) { /* exception */ longjmp(env->jmp_env, 1); @@ -412,7 +420,6 @@ int cpu_exec(CPUState *env1) } } } -#endif T0 = 0; /* force lookup of first TB */ for(;;) { diff --git a/exec-all.h b/exec-all.h index 5162307..621e1ca 100644 --- a/exec-all.h +++ b/exec-all.h @@ -576,6 +576,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) typedef struct QEMUAccel { void (*cpu_interrupt)(CPUState *env); + int (*exec_interrupt)(CPUState *env); } QEMUAccel; extern QEMUAccel *current_accel; @@ -591,6 +592,15 @@ static inline void accel_cpu_interrupt(CPUState *env) current_accel->cpu_interrupt(env); } +static inline int accel_exec_interrupt(CPUState *env, int *ret) +{ + if (current_accel && current_accel->exec_interrupt) { + *ret = current_accel->exec_interrupt(env); + return 1; + } + return 0; +} + #ifdef USE_KQEMU #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG)) diff --git a/kqemu.c b/kqemu.c index c46698c..08622ad 100644 --- a/kqemu.c +++ b/kqemu.c @@ -167,8 +167,11 @@ void kqemu_cpu_interrupt(CPUState *env) #endif } +extern int kqemu_exec_interrupt(CPUState *env); + QEMUAccel kqemu_accel = { .cpu_interrupt = kqemu_cpu_interrupt, + .exec_interrupt = kqemu_exec_interrupt, }; int kqemu_init(CPUState *env) -- 1.5.0.6 |
From: Glauber C. <gc...@re...> - 2008-05-02 17:55:18
|
--- exec-all.h | 16 ++++++++++++++-- exec.c | 12 ++---------- kqemu.c | 2 ++ 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/exec-all.h b/exec-all.h index 784d0ac..9925a80 100644 --- a/exec-all.h +++ b/exec-all.h @@ -578,6 +578,8 @@ typedef struct QEMUAccel { void (*cpu_interrupt)(CPUState *env); int (*exec_interrupt)(CPUState *env); void (*init_env)(CPUState *env); + void (*flush_cache)(CPUState *env, int global); + void (*flush_page)(CPUState *env, target_ulong addr); } QEMUAccel; extern QEMUAccel *current_accel; @@ -608,12 +610,22 @@ static inline void accel_init_env(CPUState *env) current_accel->init_env(env); } +static inline void accel_flush_cache(CPUState *env, int global) +{ + if (current_accel && current_accel->flush_cache) + current_accel->flush_cache(env, global); +} + +static inline void accel_flush_page(CPUState *env, target_ulong addr) +{ + if (current_accel && current_accel->flush_page) + current_accel->flush_page(env, addr); +} + #ifdef USE_KQEMU #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG)) int kqemu_cpu_exec(CPUState *env); -void kqemu_flush_page(CPUState *env, target_ulong addr); -void kqemu_flush(CPUState *env, int global); void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr); void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr); void kqemu_record_dump(void); diff --git a/exec.c b/exec.c index 93d9b01..b0f50e3 100644 --- a/exec.c +++ b/exec.c @@ -1393,11 +1393,7 @@ void tlb_flush(CPUState *env, int flush_global) #if !defined(CONFIG_SOFTMMU) munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); #endif -#ifdef USE_KQEMU - if (env->kqemu_enabled) { - kqemu_flush(env, flush_global); - } -#endif + accel_flush_cache(env, flush_global); tlb_flush_count++; } @@ -1450,11 +1446,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr) if (addr < MMAP_AREA_END) munmap((void *)addr, TARGET_PAGE_SIZE); #endif -#ifdef USE_KQEMU - if (env->kqemu_enabled) { - kqemu_flush_page(env, addr); - } -#endif + accel_flush_page(env, addr); } /* update the TLBs so that writes to code in the virtual page 'addr' diff --git a/kqemu.c b/kqemu.c index 95d8a94..f92b60d 100644 --- a/kqemu.c +++ b/kqemu.c @@ -173,6 +173,8 @@ QEMUAccel kqemu_accel = { .cpu_interrupt = kqemu_cpu_interrupt, .exec_interrupt = kqemu_exec_interrupt, .init_env = kqemu_init, + .flush_cache = kqemu_flush, + .flush_page = kqemu_flush_page, }; int kqemu_init(CPUState *env) -- 1.5.0.6 |
From: Glauber C. <gc...@re...> - 2008-05-02 17:55:11
|
Hey guys, This was already discussed, mostly on kvm-devel (but qemu list always copied, if you remember), and here is the pre work I've done. I don't feel it to be mergeable yet, but with your comments, I expect to get it in a good shape soon. This is not extensibly tested (but it will). These patches applies ontop of raw qemu, so they are not kvm-specific _at all_. I've choosen to start by abstracting kqemu first, since this is what we have already in the tree. The abstraction of kqemu is also, not complete. It cover mostly areas that are common to kvm, i.e., provide functions that kvm could implement as-is. Comments are welcome, rants not so. Have fun. |
From: Marcelo T. <mto...@re...> - 2008-05-02 17:43:42
|
Initialize and configure 3 PCI bridges (Intel 82801 PCI Bridge rev d9), which have no special handling (quirks) in current Linux versions. IO base/limit registers are initialized with zero and read-only, indicating that the bridge does not support IO address ranges. To avoid potentially breaking SPARC, a separate pci_set_irq function is introduced to handle the flat IRQ space. Signed-off-by: Marcelo Tosatti <mto...@re...> Index: kvm-userspace.pci3/qemu/hw/pci.c =================================================================== --- kvm-userspace.pci3.orig/qemu/hw/pci.c +++ kvm-userspace.pci3/qemu/hw/pci.c @@ -528,6 +528,8 @@ uint32_t pci_data_read(void *opaque, uin /***********************************************************/ /* generic PCI irq support */ +/* SPARC uses the IRQ assigned to the bridge device for its children??? */ +#ifdef TARGET_SPARC /* 0 <= irq_num <= 3. level must be 0 or 1 */ static void pci_set_irq(void *opaque, int irq_num, int level) { @@ -550,6 +552,33 @@ static void pci_set_irq(void *opaque, in bus->irq_count[irq_num] += change; bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); } +#else +/* 0 <= irq_num <= 3. level must be 0 or 1 */ +static void pci_set_irq(void *opaque, int irq_num, int level) +{ + PCIDevice *pci_dev = (PCIDevice *)opaque; + PCIDevice *host_dev; + PCIBus *bus; + int change; + + change = level - pci_dev->irq_state[irq_num]; + if (!change) + return; + + pci_dev->irq_state[irq_num] = level; + host_dev = pci_dev; + for (;;) { + bus = host_dev->bus; + if (bus->set_irq) { + irq_num = bus->map_irq(pci_dev, irq_num); + break; + } + host_dev = bus->parent_dev; + } + bus->irq_count[irq_num] += change; + bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); +} +#endif /***********************************************************/ /* monitor info on PCI */ @@ -706,11 +735,6 @@ PCIDevice *pci_nic_init(PCIBus *bus, NIC return pci_dev; } -typedef struct { - PCIDevice dev; - PCIBus *bus; -} PCIBridge; - static void pci_bridge_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { @@ -725,6 +749,13 @@ static void pci_bridge_write_config(PCID printf ("pci-bridge: %s: Assigned bus %d\n", d->name, s->bus->bus_num); #endif } +#ifdef TARGET_I386 + /* on x86 the bridges do not implement I/O address ranges, I/O base/limit + * registers are read-only and should return 0. + */ + if (address == 0x1c || address == 0x1d) + return; +#endif pci_default_write_config(d, address, val, len); } @@ -755,7 +786,7 @@ PCIDevice *pci_find_device(int bus_num, return NULL; } -PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id, +PCIBridge *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id, pci_map_irq_fn map_irq, const char *name) { PCIBridge *s; @@ -778,5 +809,5 @@ PCIBus *pci_bridge_init(PCIBus *bus, int s->dev.config[0x1E] = 0xa0; // secondary status s->bus = pci_register_secondary_bus(&s->dev, map_irq); - return s->bus; + return s; } Index: kvm-userspace.pci3/bios/rombios32.c =================================================================== --- kvm-userspace.pci3.orig/bios/rombios32.c +++ kvm-userspace.pci3/bios/rombios32.c @@ -652,6 +652,30 @@ static void bios_lock_shadow_ram(void) pci_config_writeb(d, 0x59, v); } +static int nr_bridges = 1; +static int current_bridge = 0; + +static void pci_bios_count_p2p(PCIDevice *d) +{ + uint16_t vendor_id, device_id; + + vendor_id = pci_config_readw(d, PCI_VENDOR_ID); + device_id = pci_config_readw(d, PCI_DEVICE_ID); + if (vendor_id == 0x8086 && device_id == 0x244e) + nr_bridges++; +} + +int fls(int i) +{ + int bit; + + for (bit=31; bit >= 0; bit--) + if (i & (1 << bit)) + return bit+1; + + return 0; +} + static void pci_bios_init_bridges(PCIDevice *d) { uint16_t vendor_id, device_id; @@ -681,6 +705,20 @@ static void pci_bios_init_bridges(PCIDev } else if (vendor_id == 0x8086 && device_id == 0x1237) { /* i440 PCI bridge */ bios_shadow_init(d); + } else if (vendor_id == 0x8086 && device_id == 0x244e) { + int len, base; + + len = (0xfebfffff - 0xf0000000) / nr_bridges; + if (len & (len-1)) + len = 1 << fls(len); + + /* memory IO */ + base = (0xf0000000+len) + (current_bridge*len); + base >>= 16; + pci_config_writew(d, 0x20, base); + pci_config_writew(d, 0x22, base); + + current_bridge++; } } @@ -775,6 +813,8 @@ static void pci_bios_init_device(PCIDevi pci_set_io_region_addr(d, 0, 0x80800000); } break; + case 0x0604: + break; default: default_map: /* default memory mappings */ @@ -859,6 +899,8 @@ void pci_bios_init(void) if (pci_bios_bigmem_addr < 0x90000000) pci_bios_bigmem_addr = 0x90000000; + pci_for_each_device(pci_bios_count_p2p); + pci_for_each_device(pci_bios_init_bridges); pci_for_each_device(pci_bios_init_device); Index: kvm-userspace.pci3/qemu/hw/piix_pci.c =================================================================== --- kvm-userspace.pci3.orig/qemu/hw/piix_pci.c +++ kvm-userspace.pci3/qemu/hw/piix_pci.c @@ -172,6 +172,7 @@ static int i440fx_load(QEMUFile* f, void PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic) { PCIBus *b; + PCIBridge *b1, *b2, *b3; PCIDevice *d; I440FXState *s; @@ -203,6 +204,15 @@ PCIBus *i440fx_init(PCIDevice **pi440fx_ d->config[0x72] = 0x02; /* SMRAM */ + b1 = pci_bridge_init(s->bus, 24, 0x8086244e, pci_slot_get_pirq, + "first PCI-to-PCI bridge "); + b2 = pci_bridge_init(s->bus, 32, 0x8086244e, pci_slot_get_pirq, + "second PCI-to-PCI bridge"); + b3 = pci_bridge_init(s->bus, 40, 0x8086244e, pci_slot_get_pirq, + "third PCI-to-PCI bridge"); + b1->dev.config[0x1c] = b2->dev.config[0x1c] = b3->dev.config[0x1c] = 0; + b1->dev.config[0x1d] = b2->dev.config[0x1d] = b3->dev.config[0x1d] = 0; + register_savevm("I440FX", 0, 2, i440fx_save, i440fx_load, d); *pi440fx_state = d; return b; Index: kvm-userspace.pci3/qemu/hw/apb_pci.c =================================================================== --- kvm-userspace.pci3.orig/qemu/hw/apb_pci.c +++ kvm-userspace.pci3/qemu/hw/apb_pci.c @@ -214,7 +214,7 @@ PCIBus *pci_apb_init(target_phys_addr_t APBState *s; PCIDevice *d; int pci_mem_config, pci_mem_data, apb_config, pci_ioport; - PCIBus *secondary; + PCIBridge *secondary; s = qemu_mallocz(sizeof(APBState)); /* Ultrasparc PBM main bus */ @@ -254,7 +254,7 @@ PCIBus *pci_apb_init(target_phys_addr_t /* APB secondary busses */ secondary = pci_bridge_init(s->bus, 8, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 1"); pci_bridge_init(s->bus, 9, 0x108e5000, pci_apb_map_irq, "Advanced PCI Bus secondary bridge 2"); - return secondary; + return secondary->bus; } Index: kvm-userspace.pci3/qemu/hw/pci.h =================================================================== --- kvm-userspace.pci3.orig/qemu/hw/pci.h +++ kvm-userspace.pci3/qemu/hw/pci.h @@ -70,6 +70,11 @@ struct PCIDevice { int irq_state[4]; }; +typedef struct { + PCIDevice dev; + PCIBus *bus; +} PCIBridge; + PCIDevice *pci_register_device(PCIBus *bus, const char *name, int instance_size, int devfn, PCIConfigReadFunc *config_read, @@ -102,7 +107,7 @@ PCIBus *pci_find_bus(int bus_num); PCIDevice *pci_find_device(int bus_num, int slot); void pci_info(void); -PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id, +PCIBridge *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id, pci_map_irq_fn map_irq, const char *name); /* lsi53c895a.c */ -- |
From: Marcelo T. <mto...@re...> - 2008-05-02 17:43:40
|
Add three PCI bridges to support 128 slots. Changes since v1: - Remove I/O address range "support" (so standard PCI I/O space is used). - Verify that there's no special quirks for 82801 PCI bridge. - Introduce separate flat IRQ mapping function for non-SPARC targets. -- |
From: Marcelo T. <mto...@re...> - 2008-05-02 17:43:38
|
Support more than one bus in the ACPI PCI hotplug code. Currently 4 buses are supported, but can be easily extended. Signed-off-by: Marcelo Tosatti <mto...@re...> Index: kvm-userspace.pci3/qemu/hw/acpi.c =================================================================== --- kvm-userspace.pci3.orig/qemu/hw/acpi.c +++ kvm-userspace.pci3/qemu/hw/acpi.c @@ -552,10 +552,11 @@ struct gpe_regs { struct pci_status { uint32_t up; uint32_t down; + unsigned long base; }; static struct gpe_regs gpe; -static struct pci_status pci0_status; +static struct pci_status pci_bus_status[4]; static uint32_t gpe_readb(void *opaque, uint32_t addr) { @@ -625,16 +626,19 @@ static void gpe_writeb(void *opaque, uin static uint32_t pcihotplug_read(void *opaque, uint32_t addr) { - uint32_t val = 0; struct pci_status *g = opaque; - switch (addr) { - case PCI_BASE: + uint32_t val, offset; + + offset = addr - g->base; + switch (offset) { + case 0: val = g->up; break; - case PCI_BASE + 4: + case 4: val = g->down; break; default: + val = 0; break; } @@ -647,11 +651,13 @@ static uint32_t pcihotplug_read(void *op static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val) { struct pci_status *g = opaque; - switch (addr) { - case PCI_BASE: + uint32_t offset = addr - g->base; + + switch (offset) { + case 0: g->up = val; break; - case PCI_BASE + 4: + case 4: g->down = val; break; } @@ -671,9 +677,13 @@ static uint32_t pciej_read(void *opaque, static void pciej_write(void *opaque, uint32_t addr, uint32_t val) { - int slot = ffs(val) - 1; + struct pci_status *g = opaque; + int slot, bus; - device_hot_remove_success(0, slot); + bus = (g->base - PCI_BASE) / 12; + slot = ffs(val) - 1; + + device_hot_remove_success(bus, slot); #if defined(DEBUG) printf("pciej write %lx <== %d\n", addr, val); @@ -684,17 +694,25 @@ static const char *model; void qemu_system_hot_add_init(const char *cpu_model) { + int i; + register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe); register_ioport_read(GPE_BASE, 4, 1, gpe_readb, &gpe); register_ioport_write(PROC_BASE, 4, 1, gpe_writeb, &gpe); register_ioport_read(PROC_BASE, 4, 1, gpe_readb, &gpe); - register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status); - register_ioport_read(PCI_BASE, 8, 4, pcihotplug_read, &pci0_status); + for (i = 0; i < 4; i++) { + struct pci_status *pci_status = &pci_bus_status[i]; + unsigned long base = PCI_BASE + (i*12); + + pci_status->base = base; + register_ioport_write(base, 8, 4, pcihotplug_write, pci_status); + register_ioport_read(base, 8, 4, pcihotplug_read, pci_status); + register_ioport_write(base+8, 4, 4, pciej_write, pci_status); + register_ioport_read(base+8, 4, 4, pciej_read, pci_status); + } - register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, NULL); - register_ioport_read(PCI_EJ_BASE, 4, 4, pciej_read, NULL); model = cpu_model; } @@ -740,28 +758,34 @@ void qemu_system_cpu_hot_add(int cpu, in } #endif -static void enable_device(struct pci_status *p, struct gpe_regs *g, int slot) +static void enable_device(struct pci_status *p, struct gpe_regs *g, int bus, int slot) { - g->sts |= 2; - g->en |= 2; + int gpe_bit = (1 << (bus+1)); + + g->sts |= gpe_bit; + g->en |= gpe_bit; p->up |= (1 << slot); } -static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot) +static void disable_device(struct pci_status *p, struct gpe_regs *g, int bus, int slot) { - g->sts |= 2; - g->en |= 2; + int gpe_bit = (1 << (bus+1)); + + g->sts |= gpe_bit; + g->en |= gpe_bit; p->down |= (1 << slot); } void qemu_system_device_hot_add(int pcibus, int slot, int state) { + struct pci_status *pci_status = &pci_bus_status[pcibus]; + qemu_set_irq(pm_state->irq, 1); - pci0_status.up = 0; - pci0_status.down = 0; + pci_status->up = 0; + pci_status->down = 0; if (state) - enable_device(&pci0_status, &gpe, slot); + enable_device(pci_status, &gpe, pcibus, slot); else - disable_device(&pci0_status, &gpe, slot); + disable_device(pci_status, &gpe, pcibus, slot); qemu_set_irq(pm_state->irq, 0); } -- |
From: Marcelo T. <mto...@re...> - 2008-05-02 17:43:37
|
Add 3 PCI bridges to the ACPI table: - Move IRQ routing, slot device and GPE processing to separate files which can be included from acpi-dsdt.dsl. - Add _SUN methods to every slot device so as to avoid collisions in OS handling. - Fix copy&paste typo in slot devices 8/9 and 24/25. This table breaks PCI hotplug for older userspace, hopefully not an issue (trivial enough to upgrade the BIOS). Signed-off-by: Marcelo Tosatti <mto...@re...> Index: kvm-userspace.pci3/bios/acpi-dsdt.dsl =================================================================== --- kvm-userspace.pci3.orig/bios/acpi-dsdt.dsl +++ kvm-userspace.pci3/bios/acpi-dsdt.dsl @@ -208,218 +208,29 @@ DefinitionBlock ( Name (_HID, EisaId ("PNP0A03")) Name (_ADR, 0x00) Name (_UID, 1) - Name(_PRT, Package() { - /* PCI IRQ routing table, example from ACPI 2.0a specification, - section 6.2.8.1 */ - /* Note: we provide the same info as the PCI routing - table of the Bochs BIOS */ - - // PCI Slot 0 - Package() {0x0000ffff, 0, LNKD, 0}, - Package() {0x0000ffff, 1, LNKA, 0}, - Package() {0x0000ffff, 2, LNKB, 0}, - Package() {0x0000ffff, 3, LNKC, 0}, - - // PCI Slot 1 - Package() {0x0001ffff, 0, LNKA, 0}, - Package() {0x0001ffff, 1, LNKB, 0}, - Package() {0x0001ffff, 2, LNKC, 0}, - Package() {0x0001ffff, 3, LNKD, 0}, - - // PCI Slot 2 - Package() {0x0002ffff, 0, LNKB, 0}, - Package() {0x0002ffff, 1, LNKC, 0}, - Package() {0x0002ffff, 2, LNKD, 0}, - Package() {0x0002ffff, 3, LNKA, 0}, - - // PCI Slot 3 - Package() {0x0003ffff, 0, LNKC, 0}, - Package() {0x0003ffff, 1, LNKD, 0}, - Package() {0x0003ffff, 2, LNKA, 0}, - Package() {0x0003ffff, 3, LNKB, 0}, - - // PCI Slot 4 - Package() {0x0004ffff, 0, LNKD, 0}, - Package() {0x0004ffff, 1, LNKA, 0}, - Package() {0x0004ffff, 2, LNKB, 0}, - Package() {0x0004ffff, 3, LNKC, 0}, - - // PCI Slot 5 - Package() {0x0005ffff, 0, LNKA, 0}, - Package() {0x0005ffff, 1, LNKB, 0}, - Package() {0x0005ffff, 2, LNKC, 0}, - Package() {0x0005ffff, 3, LNKD, 0}, - - // PCI Slot 6 - Package() {0x0006ffff, 0, LNKB, 0}, - Package() {0x0006ffff, 1, LNKC, 0}, - Package() {0x0006ffff, 2, LNKD, 0}, - Package() {0x0006ffff, 3, LNKA, 0}, - - // PCI Slot 7 - Package() {0x0007ffff, 0, LNKC, 0}, - Package() {0x0007ffff, 1, LNKD, 0}, - Package() {0x0007ffff, 2, LNKA, 0}, - Package() {0x0007ffff, 3, LNKB, 0}, - - // PCI Slot 8 - Package() {0x0008ffff, 0, LNKD, 0}, - Package() {0x0008ffff, 1, LNKA, 0}, - Package() {0x0008ffff, 2, LNKB, 0}, - Package() {0x0008ffff, 3, LNKC, 0}, - - // PCI Slot 9 - Package() {0x0008ffff, 0, LNKA, 0}, - Package() {0x0008ffff, 1, LNKB, 0}, - Package() {0x0008ffff, 2, LNKC, 0}, - Package() {0x0008ffff, 3, LNKD, 0}, - - // PCI Slot 10 - Package() {0x000affff, 0, LNKB, 0}, - Package() {0x000affff, 1, LNKC, 0}, - Package() {0x000affff, 2, LNKD, 0}, - Package() {0x000affff, 3, LNKA, 0}, - - // PCI Slot 11 - Package() {0x000bffff, 0, LNKC, 0}, - Package() {0x000bffff, 1, LNKD, 0}, - Package() {0x000bffff, 2, LNKA, 0}, - Package() {0x000bffff, 3, LNKB, 0}, - - // PCI Slot 12 - Package() {0x000cffff, 0, LNKD, 0}, - Package() {0x000cffff, 1, LNKA, 0}, - Package() {0x000cffff, 2, LNKB, 0}, - Package() {0x000cffff, 3, LNKC, 0}, - - // PCI Slot 13 - Package() {0x000dffff, 0, LNKA, 0}, - Package() {0x000dffff, 1, LNKB, 0}, - Package() {0x000dffff, 2, LNKC, 0}, - Package() {0x000dffff, 3, LNKD, 0}, - - // PCI Slot 14 - Package() {0x000effff, 0, LNKB, 0}, - Package() {0x000effff, 1, LNKC, 0}, - Package() {0x000effff, 2, LNKD, 0}, - Package() {0x000effff, 3, LNKA, 0}, - - // PCI Slot 15 - Package() {0x000fffff, 0, LNKC, 0}, - Package() {0x000fffff, 1, LNKD, 0}, - Package() {0x000fffff, 2, LNKA, 0}, - Package() {0x000fffff, 3, LNKB, 0}, - - // PCI Slot 16 - Package() {0x0010ffff, 0, LNKD, 0}, - Package() {0x0010ffff, 1, LNKA, 0}, - Package() {0x0010ffff, 2, LNKB, 0}, - Package() {0x0010ffff, 3, LNKC, 0}, - - // PCI Slot 17 - Package() {0x0011ffff, 0, LNKA, 0}, - Package() {0x0011ffff, 1, LNKB, 0}, - Package() {0x0011ffff, 2, LNKC, 0}, - Package() {0x0011ffff, 3, LNKD, 0}, - - // PCI Slot 18 - Package() {0x0012ffff, 0, LNKB, 0}, - Package() {0x0012ffff, 1, LNKC, 0}, - Package() {0x0012ffff, 2, LNKD, 0}, - Package() {0x0012ffff, 3, LNKA, 0}, - - // PCI Slot 19 - Package() {0x0013ffff, 0, LNKC, 0}, - Package() {0x0013ffff, 1, LNKD, 0}, - Package() {0x0013ffff, 2, LNKA, 0}, - Package() {0x0013ffff, 3, LNKB, 0}, - - // PCI Slot 20 - Package() {0x0014ffff, 0, LNKD, 0}, - Package() {0x0014ffff, 1, LNKA, 0}, - Package() {0x0014ffff, 2, LNKB, 0}, - Package() {0x0014ffff, 3, LNKC, 0}, - - // PCI Slot 21 - Package() {0x0015ffff, 0, LNKA, 0}, - Package() {0x0015ffff, 1, LNKB, 0}, - Package() {0x0015ffff, 2, LNKC, 0}, - Package() {0x0015ffff, 3, LNKD, 0}, - - // PCI Slot 22 - Package() {0x0016ffff, 0, LNKB, 0}, - Package() {0x0016ffff, 1, LNKC, 0}, - Package() {0x0016ffff, 2, LNKD, 0}, - Package() {0x0016ffff, 3, LNKA, 0}, - - // PCI Slot 23 - Package() {0x0017ffff, 0, LNKC, 0}, - Package() {0x0017ffff, 1, LNKD, 0}, - Package() {0x0017ffff, 2, LNKA, 0}, - Package() {0x0017ffff, 3, LNKB, 0}, - - // PCI Slot 24 - Package() {0x0018ffff, 0, LNKD, 0}, - Package() {0x0018ffff, 1, LNKA, 0}, - Package() {0x0018ffff, 2, LNKB, 0}, - Package() {0x0018ffff, 3, LNKC, 0}, - - // PCI Slot 25 - Package() {0x0018ffff, 0, LNKA, 0}, - Package() {0x0018ffff, 1, LNKB, 0}, - Package() {0x0018ffff, 2, LNKC, 0}, - Package() {0x0018ffff, 3, LNKD, 0}, - - // PCI Slot 26 - Package() {0x001affff, 0, LNKB, 0}, - Package() {0x001affff, 1, LNKC, 0}, - Package() {0x001affff, 2, LNKD, 0}, - Package() {0x001affff, 3, LNKA, 0}, - - // PCI Slot 27 - Package() {0x001bffff, 0, LNKC, 0}, - Package() {0x001bffff, 1, LNKD, 0}, - Package() {0x001bffff, 2, LNKA, 0}, - Package() {0x001bffff, 3, LNKB, 0}, - - // PCI Slot 28 - Package() {0x001cffff, 0, LNKD, 0}, - Package() {0x001cffff, 1, LNKA, 0}, - Package() {0x001cffff, 2, LNKB, 0}, - Package() {0x001cffff, 3, LNKC, 0}, - - // PCI Slot 29 - Package() {0x001dffff, 0, LNKA, 0}, - Package() {0x001dffff, 1, LNKB, 0}, - Package() {0x001dffff, 2, LNKC, 0}, - Package() {0x001dffff, 3, LNKD, 0}, - - // PCI Slot 30 - Package() {0x001effff, 0, LNKB, 0}, - Package() {0x001effff, 1, LNKC, 0}, - Package() {0x001effff, 2, LNKD, 0}, - Package() {0x001effff, 3, LNKA, 0}, - - // PCI Slot 31 - Package() {0x001fffff, 0, LNKC, 0}, - Package() {0x001fffff, 1, LNKD, 0}, - Package() {0x001fffff, 2, LNKA, 0}, - Package() {0x001fffff, 3, LNKB, 0}, - }) + + Include ("acpi-irq-routing.dsl") OperationRegion(PCST, SystemIO, 0xae00, 0x08) Field (PCST, DWordAcc, NoLock, WriteAsZeros) - { + { PCIU, 32, PCID, 32, - } - + } OperationRegion(SEJ, SystemIO, 0xae08, 0x04) Field (SEJ, DWordAcc, NoLock, WriteAsZeros) { B0EJ, 32, } + Device (S0) { // Slot 0 + Name (_ADR, 0x00000000) + Method (_EJ0,1) { + Store(0x1, B0EJ) + Return (0x0) + } + } + Device (S1) { // Slot 1 Name (_ADR, 0x00010000) Method (_EJ0,1) { @@ -436,28 +247,70 @@ DefinitionBlock ( } } - Device (S3) { // Slot 3 + Device (S3) { // Slot 3, PCI-to-PCI bridge Name (_ADR, 0x00030000) - Method (_EJ0,1) { - Store (0x8, B0EJ) - Return (0x0) + Include ("acpi-irq-routing.dsl") + + OperationRegion(PCST, SystemIO, 0xae0c, 0x08) + Field (PCST, DWordAcc, NoLock, WriteAsZeros) + { + PCIU, 32, + PCID, 32, } + + OperationRegion(SEJ, SystemIO, 0xae14, 0x04) + Field (SEJ, DWordAcc, NoLock, WriteAsZeros) + { + B1EJ, 32, + } + + Name (SUN1, 30) + Alias (\_SB.PCI0.S3.B1EJ, BEJ) + Include ("acpi-pci-slots.dsl") } - Device (S4) { // Slot 4 + Device (S4) { // Slot 4, PCI-to-PCI bridge Name (_ADR, 0x00040000) - Method (_EJ0,1) { - Store(0x10, B0EJ) - Return (0x0) + Include ("acpi-irq-routing.dsl") + + OperationRegion(PCST, SystemIO, 0xae18, 0x08) + Field (PCST, DWordAcc, NoLock, WriteAsZeros) + { + PCIU, 32, + PCID, 32, + } + + OperationRegion(SEJ, SystemIO, 0xae20, 0x04) + Field (SEJ, DWordAcc, NoLock, WriteAsZeros) + { + B2EJ, 32, } + + Name (SUN1, 62) + Alias (\_SB.PCI0.S4.B2EJ, BEJ) + Include ("acpi-pci-slots.dsl") } - Device (S5) { // Slot 5 + Device (S5) { // Slot 5, PCI-to-PCI bridge Name (_ADR, 0x00050000) - Method (_EJ0,1) { - Store(0x20, B0EJ) - Return (0x0) + Include ("acpi-irq-routing.dsl") + + OperationRegion(PCST, SystemIO, 0xae24, 0x08) + Field (PCST, DWordAcc, NoLock, WriteAsZeros) + { + PCIU, 32, + PCID, 32, } + + OperationRegion(SEJ, SystemIO, 0xae2c, 0x04) + Field (SEJ, DWordAcc, NoLock, WriteAsZeros) + { + B3EJ, 32, + } + + Name (SUN1, 94) + Alias (\_SB.PCI0.S5.B3EJ, BEJ) + Include ("acpi-pci-slots.dsl") } Device (S6) { // Slot 6 @@ -1248,266 +1101,156 @@ DefinitionBlock ( Return(0x01) } Method(_L01) { - /* Up status */ - If (And(\_SB.PCI0.PCIU, 0x2)) { - Notify(\_SB.PCI0.S1, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x4)) { - Notify(\_SB.PCI0.S2, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x8)) { - Notify(\_SB.PCI0.S3, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x10)) { - Notify(\_SB.PCI0.S4, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x20)) { - Notify(\_SB.PCI0.S5, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x40)) { - Notify(\_SB.PCI0.S6, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x80)) { - Notify(\_SB.PCI0.S7, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x0100)) { - Notify(\_SB.PCI0.S8, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x0200)) { - Notify(\_SB.PCI0.S9, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x0400)) { - Notify(\_SB.PCI0.S10, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x0800)) { - Notify(\_SB.PCI0.S11, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x1000)) { - Notify(\_SB.PCI0.S12, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x2000)) { - Notify(\_SB.PCI0.S13, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x4000)) { - Notify(\_SB.PCI0.S14, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x8000)) { - Notify(\_SB.PCI0.S15, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x10000)) { - Notify(\_SB.PCI0.S16, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x20000)) { - Notify(\_SB.PCI0.S17, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x40000)) { - Notify(\_SB.PCI0.S18, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x80000)) { - Notify(\_SB.PCI0.S19, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x100000)) { - Notify(\_SB.PCI0.S20, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x200000)) { - Notify(\_SB.PCI0.S21, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x400000)) { - Notify(\_SB.PCI0.S22, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x800000)) { - Notify(\_SB.PCI0.S23, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x1000000)) { - Notify(\_SB.PCI0.S24, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x2000000)) { - Notify(\_SB.PCI0.S25, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x4000000)) { - Notify(\_SB.PCI0.S26, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x8000000)) { - Notify(\_SB.PCI0.S27, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x10000000)) { - Notify(\_SB.PCI0.S28, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x20000000)) { - Notify(\_SB.PCI0.S29, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x40000000)) { - Notify(\_SB.PCI0.S30, 0x1) - } - - If (And(\_SB.PCI0.PCIU, 0x80000000)) { - Notify(\_SB.PCI0.S31, 0x1) - } - - /* Down status */ - If (And(\_SB.PCI0.PCID, 0x2)) { - Notify(\_SB.PCI0.S1, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x4)) { - Notify(\_SB.PCI0.S2, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x8)) { - Notify(\_SB.PCI0.S3, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x10)) { - Notify(\_SB.PCI0.S4, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x20)) { - Notify(\_SB.PCI0.S5, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x40)) { - Notify(\_SB.PCI0.S6, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x80)) { - Notify(\_SB.PCI0.S7, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x0100)) { - Notify(\_SB.PCI0.S8, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x0200)) { - Notify(\_SB.PCI0.S9, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x0400)) { - Notify(\_SB.PCI0.S10, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x0800)) { - Notify(\_SB.PCI0.S11, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x1000)) { - Notify(\_SB.PCI0.S12, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x2000)) { - Notify(\_SB.PCI0.S13, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x4000)) { - Notify(\_SB.PCI0.S14, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x8000)) { - Notify(\_SB.PCI0.S15, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x10000)) { - Notify(\_SB.PCI0.S16, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x20000)) { - Notify(\_SB.PCI0.S17, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x40000)) { - Notify(\_SB.PCI0.S18, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x80000)) { - Notify(\_SB.PCI0.S19, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x100000)) { - Notify(\_SB.PCI0.S20, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x200000)) { - Notify(\_SB.PCI0.S21, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x400000)) { - Notify(\_SB.PCI0.S22, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x800000)) { - Notify(\_SB.PCI0.S23, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x1000000)) { - Notify(\_SB.PCI0.S24, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x2000000)) { - Notify(\_SB.PCI0.S25, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x4000000)) { - Notify(\_SB.PCI0.S26, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x8000000)) { - Notify(\_SB.PCI0.S27, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x10000000)) { - Notify(\_SB.PCI0.S28, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x20000000)) { - Notify(\_SB.PCI0.S29, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x40000000)) { - Notify(\_SB.PCI0.S30, 0x3) - } - - If (And(\_SB.PCI0.PCID, 0x80000000)) { - Notify(\_SB.PCI0.S31, 0x3) - } - - Return(0x01) + Alias (\_SB.PCI0.PCIU, UP) + Alias (\_SB.PCI0.PCID, DOWN) + Alias (\_SB.PCI0.S0, S0) + Alias (\_SB.PCI0.S1, S1) + Alias (\_SB.PCI0.S2, S2) + Alias (\_SB.PCI0.S3, S3) + Alias (\_SB.PCI0.S4, S4) + Alias (\_SB.PCI0.S5, S5) + Alias (\_SB.PCI0.S6, S6) + Alias (\_SB.PCI0.S7, S7) + Alias (\_SB.PCI0.S8, S8) + Alias (\_SB.PCI0.S9, S9) + Alias (\_SB.PCI0.S10, S10) + Alias (\_SB.PCI0.S11, S11) + Alias (\_SB.PCI0.S12, S12) + Alias (\_SB.PCI0.S13, S13) + Alias (\_SB.PCI0.S14, S14) + Alias (\_SB.PCI0.S15, S15) + Alias (\_SB.PCI0.S16, S16) + Alias (\_SB.PCI0.S17, S17) + Alias (\_SB.PCI0.S18, S18) + Alias (\_SB.PCI0.S19, S19) + Alias (\_SB.PCI0.S20, S20) + Alias (\_SB.PCI0.S21, S21) + Alias (\_SB.PCI0.S22, S22) + Alias (\_SB.PCI0.S23, S23) + Alias (\_SB.PCI0.S24, S24) + Alias (\_SB.PCI0.S25, S25) + Alias (\_SB.PCI0.S26, S26) + Alias (\_SB.PCI0.S27, S27) + Alias (\_SB.PCI0.S28, S28) + Alias (\_SB.PCI0.S29, S29) + Alias (\_SB.PCI0.S30, S30) + Alias (\_SB.PCI0.S31, S31) + Include ("acpi-hotplug-gpe.dsl") + Return (0x01) } Method(_L02) { - Return(0x01) + Alias (\_SB.PCI0.S3.PCIU, UP) + Alias (\_SB.PCI0.S3.PCID, DOWN) + Alias (\_SB.PCI0.S3.S0, S0) + Alias (\_SB.PCI0.S3.S1, S1) + Alias (\_SB.PCI0.S3.S2, S2) + Alias (\_SB.PCI0.S3.S3, S3) + Alias (\_SB.PCI0.S3.S4, S4) + Alias (\_SB.PCI0.S3.S5, S5) + Alias (\_SB.PCI0.S3.S6, S6) + Alias (\_SB.PCI0.S3.S7, S7) + Alias (\_SB.PCI0.S3.S8, S8) + Alias (\_SB.PCI0.S3.S9, S9) + Alias (\_SB.PCI0.S3.S10, S10) + Alias (\_SB.PCI0.S3.S11, S11) + Alias (\_SB.PCI0.S3.S12, S12) + Alias (\_SB.PCI0.S3.S13, S13) + Alias (\_SB.PCI0.S3.S14, S14) + Alias (\_SB.PCI0.S3.S15, S15) + Alias (\_SB.PCI0.S3.S16, S16) + Alias (\_SB.PCI0.S3.S17, S17) + Alias (\_SB.PCI0.S3.S18, S18) + Alias (\_SB.PCI0.S3.S19, S19) + Alias (\_SB.PCI0.S3.S20, S20) + Alias (\_SB.PCI0.S3.S21, S21) + Alias (\_SB.PCI0.S3.S22, S22) + Alias (\_SB.PCI0.S3.S23, S23) + Alias (\_SB.PCI0.S3.S24, S24) + Alias (\_SB.PCI0.S3.S25, S25) + Alias (\_SB.PCI0.S3.S26, S26) + Alias (\_SB.PCI0.S3.S27, S27) + Alias (\_SB.PCI0.S3.S28, S28) + Alias (\_SB.PCI0.S3.S29, S29) + Alias (\_SB.PCI0.S3.S30, S30) + Alias (\_SB.PCI0.S3.S31, S31) + Include ("acpi-hotplug-gpe.dsl") + Return (0x01) } Method(_L03) { - Return(0x01) + Alias (\_SB.PCI0.S4.PCIU, UP) + Alias (\_SB.PCI0.S4.PCID, DOWN) + Alias (\_SB.PCI0.S4.S0, S0) + Alias (\_SB.PCI0.S4.S1, S1) + Alias (\_SB.PCI0.S4.S2, S2) + Alias (\_SB.PCI0.S4.S3, S3) + Alias (\_SB.PCI0.S4.S4, S4) + Alias (\_SB.PCI0.S4.S5, S5) + Alias (\_SB.PCI0.S4.S6, S6) + Alias (\_SB.PCI0.S4.S7, S7) + Alias (\_SB.PCI0.S4.S8, S8) + Alias (\_SB.PCI0.S4.S9, S9) + Alias (\_SB.PCI0.S4.S10, S10) + Alias (\_SB.PCI0.S4.S11, S11) + Alias (\_SB.PCI0.S4.S12, S12) + Alias (\_SB.PCI0.S4.S13, S13) + Alias (\_SB.PCI0.S4.S14, S14) + Alias (\_SB.PCI0.S4.S15, S15) + Alias (\_SB.PCI0.S4.S16, S16) + Alias (\_SB.PCI0.S4.S17, S17) + Alias (\_SB.PCI0.S4.S18, S18) + Alias (\_SB.PCI0.S4.S19, S19) + Alias (\_SB.PCI0.S4.S20, S20) + Alias (\_SB.PCI0.S4.S21, S21) + Alias (\_SB.PCI0.S4.S22, S22) + Alias (\_SB.PCI0.S4.S23, S23) + Alias (\_SB.PCI0.S4.S24, S24) + Alias (\_SB.PCI0.S4.S25, S25) + Alias (\_SB.PCI0.S4.S26, S26) + Alias (\_SB.PCI0.S4.S27, S27) + Alias (\_SB.PCI0.S4.S28, S28) + Alias (\_SB.PCI0.S4.S29, S29) + Alias (\_SB.PCI0.S4.S30, S30) + Alias (\_SB.PCI0.S4.S31, S31) + Include ("acpi-hotplug-gpe.dsl") + Return (0x01) } Method(_L04) { - Return(0x01) + Alias (\_SB.PCI0.S5.PCIU, UP) + Alias (\_SB.PCI0.S5.PCID, DOWN) + Alias (\_SB.PCI0.S5.S0, S0) + Alias (\_SB.PCI0.S5.S1, S1) + Alias (\_SB.PCI0.S5.S2, S2) + Alias (\_SB.PCI0.S5.S3, S3) + Alias (\_SB.PCI0.S5.S4, S4) + Alias (\_SB.PCI0.S5.S5, S5) + Alias (\_SB.PCI0.S5.S6, S6) + Alias (\_SB.PCI0.S5.S7, S7) + Alias (\_SB.PCI0.S5.S8, S8) + Alias (\_SB.PCI0.S5.S9, S9) + Alias (\_SB.PCI0.S5.S10, S10) + Alias (\_SB.PCI0.S5.S11, S11) + Alias (\_SB.PCI0.S5.S12, S12) + Alias (\_SB.PCI0.S5.S13, S13) + Alias (\_SB.PCI0.S5.S14, S14) + Alias (\_SB.PCI0.S5.S15, S15) + Alias (\_SB.PCI0.S5.S16, S16) + Alias (\_SB.PCI0.S5.S17, S17) + Alias (\_SB.PCI0.S5.S18, S18) + Alias (\_SB.PCI0.S5.S19, S19) + Alias (\_SB.PCI0.S5.S20, S20) + Alias (\_SB.PCI0.S5.S21, S21) + Alias (\_SB.PCI0.S5.S22, S22) + Alias (\_SB.PCI0.S5.S23, S23) + Alias (\_SB.PCI0.S5.S24, S24) + Alias (\_SB.PCI0.S5.S25, S25) + Alias (\_SB.PCI0.S5.S26, S26) + Alias (\_SB.PCI0.S5.S27, S27) + Alias (\_SB.PCI0.S5.S28, S28) + Alias (\_SB.PCI0.S5.S29, S29) + Alias (\_SB.PCI0.S5.S30, S30) + Alias (\_SB.PCI0.S5.S31, S31) + Include ("acpi-hotplug-gpe.dsl") + Return (0x01) } Method(_L05) { Return(0x01) Index: kvm-userspace.pci3/bios/acpi-hotplug-gpe.dsl =================================================================== --- /dev/null +++ kvm-userspace.pci3/bios/acpi-hotplug-gpe.dsl @@ -0,0 +1,257 @@ + /* Up status */ + If (And(UP, 0x1)) { + Notify(S0, 0x1) + } + + If (And(UP, 0x2)) { + Notify(S1, 0x1) + } + + If (And(UP, 0x4)) { + Notify(S2, 0x1) + } + + If (And(UP, 0x8)) { + Notify(S3, 0x1) + } + + If (And(UP, 0x10)) { + Notify(S4, 0x1) + } + + If (And(UP, 0x20)) { + Notify(S5, 0x1) + } + + If (And(UP, 0x40)) { + Notify(S6, 0x1) + } + + If (And(UP, 0x80)) { + Notify(S7, 0x1) + } + + If (And(UP, 0x0100)) { + Notify(S8, 0x1) + } + + If (And(UP, 0x0200)) { + Notify(S9, 0x1) + } + + If (And(UP, 0x0400)) { + Notify(S10, 0x1) + } + + If (And(UP, 0x0800)) { + Notify(S11, 0x1) + } + + If (And(UP, 0x1000)) { + Notify(S12, 0x1) + } + + If (And(UP, 0x2000)) { + Notify(S13, 0x1) + } + + If (And(UP, 0x4000)) { + Notify(S14, 0x1) + } + + If (And(UP, 0x8000)) { + Notify(S15, 0x1) + } + + If (And(UP, 0x10000)) { + Notify(S16, 0x1) + } + + If (And(UP, 0x20000)) { + Notify(S17, 0x1) + } + + If (And(UP, 0x40000)) { + Notify(S18, 0x1) + } + + If (And(UP, 0x80000)) { + Notify(S19, 0x1) + } + + If (And(UP, 0x100000)) { + Notify(S20, 0x1) + } + + If (And(UP, 0x200000)) { + Notify(S21, 0x1) + } + + If (And(UP, 0x400000)) { + Notify(S22, 0x1) + } + + If (And(UP, 0x800000)) { + Notify(S23, 0x1) + } + + If (And(UP, 0x1000000)) { + Notify(S24, 0x1) + } + + If (And(UP, 0x2000000)) { + Notify(S25, 0x1) + } + + If (And(UP, 0x4000000)) { + Notify(S26, 0x1) + } + + If (And(UP, 0x8000000)) { + Notify(S27, 0x1) + } + + If (And(UP, 0x10000000)) { + Notify(S28, 0x1) + } + + If (And(UP, 0x20000000)) { + Notify(S29, 0x1) + } + + If (And(UP, 0x40000000)) { + Notify(S30, 0x1) + } + + If (And(UP, 0x80000000)) { + Notify(S31, 0x1) + } + + /* Down status */ + If (And(DOWN, 0x1)) { + Notify(S0, 0x3) + } + + If (And(DOWN, 0x2)) { + Notify(S1, 0x3) + } + + If (And(DOWN, 0x4)) { + Notify(S2, 0x3) + } + + If (And(DOWN, 0x8)) { + Notify(S3, 0x3) + } + + If (And(DOWN, 0x10)) { + Notify(S4, 0x3) + } + + If (And(DOWN, 0x20)) { + Notify(S5, 0x3) + } + + If (And(DOWN, 0x40)) { + Notify(S6, 0x3) + } + + If (And(DOWN, 0x80)) { + Notify(S7, 0x3) + } + + If (And(DOWN, 0x0100)) { + Notify(S8, 0x3) + } + + If (And(DOWN, 0x0200)) { + Notify(S9, 0x3) + } + + If (And(DOWN, 0x0400)) { + Notify(S10, 0x3) + } + + If (And(DOWN, 0x0800)) { + Notify(S11, 0x3) + } + + If (And(DOWN, 0x1000)) { + Notify(S12, 0x3) + } + + If (And(DOWN, 0x2000)) { + Notify(S13, 0x3) + } + + If (And(DOWN, 0x4000)) { + Notify(S14, 0x3) + } + + If (And(DOWN, 0x8000)) { + Notify(S15, 0x3) + } + + If (And(DOWN, 0x10000)) { + Notify(S16, 0x3) + } + + If (And(DOWN, 0x20000)) { + Notify(S17, 0x3) + } + + If (And(DOWN, 0x40000)) { + Notify(S18, 0x3) + } + + If (And(DOWN, 0x80000)) { + Notify(S19, 0x3) + } + + If (And(DOWN, 0x100000)) { + Notify(S20, 0x3) + } + + If (And(DOWN, 0x200000)) { + Notify(S21, 0x3) + } + + If (And(DOWN, 0x400000)) { + Notify(S22, 0x3) + } + + If (And(DOWN, 0x800000)) { + Notify(S23, 0x3) + } + + If (And(DOWN, 0x1000000)) { + Notify(S24, 0x3) + } + + If (And(DOWN, 0x2000000)) { + Notify(S25, 0x3) + } + + If (And(DOWN, 0x4000000)) { + Notify(S26, 0x3) + } + + If (And(DOWN, 0x8000000)) { + Notify(S27, 0x3) + } + + If (And(DOWN, 0x10000000)) { + Notify(S28, 0x3) + } + + If (And(DOWN, 0x20000000)) { + Notify(S29, 0x3) + } + + If (And(DOWN, 0x40000000)) { + Notify(S30, 0x3) + } + + If (And(DOWN, 0x80000000)) { + Notify(S31, 0x3) + } Index: kvm-userspace.pci3/bios/acpi-irq-routing.dsl =================================================================== --- /dev/null +++ kvm-userspace.pci3/bios/acpi-irq-routing.dsl @@ -0,0 +1,203 @@ + External(LNKA, DeviceObj) + External(LNKB, DeviceObj) + External(LNKC, DeviceObj) + External(LNKD, DeviceObj) + + Name(_PRT, Package() { + /* PCI IRQ routing table, example from ACPI 2.0a specification, + section 6.2.8.1 */ + /* Note: we provide the same info as the PCI routing + table of the Bochs BIOS */ + + // PCI Slot 0 + Package() {0x0000ffff, 0, LNKD, 0}, + Package() {0x0000ffff, 1, LNKA, 0}, + Package() {0x0000ffff, 2, LNKB, 0}, + Package() {0x0000ffff, 3, LNKC, 0}, + + // PCI Slot 1 + Package() {0x0001ffff, 0, LNKA, 0}, + Package() {0x0001ffff, 1, LNKB, 0}, + Package() {0x0001ffff, 2, LNKC, 0}, + Package() {0x0001ffff, 3, LNKD, 0}, + + // PCI Slot 2 + Package() {0x0002ffff, 0, LNKB, 0}, + Package() {0x0002ffff, 1, LNKC, 0}, + Package() {0x0002ffff, 2, LNKD, 0}, + Package() {0x0002ffff, 3, LNKA, 0}, + + // PCI Slot 3 + Package() {0x0003ffff, 0, LNKC, 0}, + Package() {0x0003ffff, 1, LNKD, 0}, + Package() {0x0003ffff, 2, LNKA, 0}, + Package() {0x0003ffff, 3, LNKB, 0}, + + // PCI Slot 4 + Package() {0x0004ffff, 0, LNKD, 0}, + Package() {0x0004ffff, 1, LNKA, 0}, + Package() {0x0004ffff, 2, LNKB, 0}, + Package() {0x0004ffff, 3, LNKC, 0}, + + // PCI Slot 5 + Package() {0x0005ffff, 0, LNKA, 0}, + Package() {0x0005ffff, 1, LNKB, 0}, + Package() {0x0005ffff, 2, LNKC, 0}, + Package() {0x0005ffff, 3, LNKD, 0}, + + // PCI Slot 6 + Package() {0x0006ffff, 0, LNKB, 0}, + Package() {0x0006ffff, 1, LNKC, 0}, + Package() {0x0006ffff, 2, LNKD, 0}, + Package() {0x0006ffff, 3, LNKA, 0}, + + // PCI Slot 7 + Package() {0x0007ffff, 0, LNKC, 0}, + Package() {0x0007ffff, 1, LNKD, 0}, + Package() {0x0007ffff, 2, LNKA, 0}, + Package() {0x0007ffff, 3, LNKB, 0}, + + // PCI Slot 8 + Package() {0x0008ffff, 0, LNKD, 0}, + Package() {0x0008ffff, 1, LNKA, 0}, + Package() {0x0008ffff, 2, LNKB, 0}, + Package() {0x0008ffff, 3, LNKC, 0}, + + // PCI Slot 9 + Package() {0x0009ffff, 0, LNKA, 0}, + Package() {0x0009ffff, 1, LNKB, 0}, + Package() {0x0009ffff, 2, LNKC, 0}, + Package() {0x0009ffff, 3, LNKD, 0}, + + // PCI Slot 10 + Package() {0x000affff, 0, LNKB, 0}, + Package() {0x000affff, 1, LNKC, 0}, + Package() {0x000affff, 2, LNKD, 0}, + Package() {0x000affff, 3, LNKA, 0}, + + // PCI Slot 11 + Package() {0x000bffff, 0, LNKC, 0}, + Package() {0x000bffff, 1, LNKD, 0}, + Package() {0x000bffff, 2, LNKA, 0}, + Package() {0x000bffff, 3, LNKB, 0}, + + // PCI Slot 12 + Package() {0x000cffff, 0, LNKD, 0}, + Package() {0x000cffff, 1, LNKA, 0}, + Package() {0x000cffff, 2, LNKB, 0}, + Package() {0x000cffff, 3, LNKC, 0}, + + // PCI Slot 13 + Package() {0x000dffff, 0, LNKA, 0}, + Package() {0x000dffff, 1, LNKB, 0}, + Package() {0x000dffff, 2, LNKC, 0}, + Package() {0x000dffff, 3, LNKD, 0}, + + // PCI Slot 14 + Package() {0x000effff, 0, LNKB, 0}, + Package() {0x000effff, 1, LNKC, 0}, + Package() {0x000effff, 2, LNKD, 0}, + Package() {0x000effff, 3, LNKA, 0}, + + // PCI Slot 15 + Package() {0x000fffff, 0, LNKC, 0}, + Package() {0x000fffff, 1, LNKD, 0}, + Package() {0x000fffff, 2, LNKA, 0}, + Package() {0x000fffff, 3, LNKB, 0}, + + // PCI Slot 16 + Package() {0x0010ffff, 0, LNKD, 0}, + Package() {0x0010ffff, 1, LNKA, 0}, + Package() {0x0010ffff, 2, LNKB, 0}, + Package() {0x0010ffff, 3, LNKC, 0}, + + // PCI Slot 17 + Package() {0x0011ffff, 0, LNKA, 0}, + Package() {0x0011ffff, 1, LNKB, 0}, + Package() {0x0011ffff, 2, LNKC, 0}, + Package() {0x0011ffff, 3, LNKD, 0}, + + // PCI Slot 18 + Package() {0x0012ffff, 0, LNKB, 0}, + Package() {0x0012ffff, 1, LNKC, 0}, + Package() {0x0012ffff, 2, LNKD, 0}, + Package() {0x0012ffff, 3, LNKA, 0}, + + // PCI Slot 19 + Package() {0x0013ffff, 0, LNKC, 0}, + Package() {0x0013ffff, 1, LNKD, 0}, + Package() {0x0013ffff, 2, LNKA, 0}, + Package() {0x0013ffff, 3, LNKB, 0}, + + // PCI Slot 20 + Package() {0x0014ffff, 0, LNKD, 0}, + Package() {0x0014ffff, 1, LNKA, 0}, + Package() {0x0014ffff, 2, LNKB, 0}, + Package() {0x0014ffff, 3, LNKC, 0}, + + // PCI Slot 21 + Package() {0x0015ffff, 0, LNKA, 0}, + Package() {0x0015ffff, 1, LNKB, 0}, + Package() {0x0015ffff, 2, LNKC, 0}, + Package() {0x0015ffff, 3, LNKD, 0}, + + // PCI Slot 22 + Package() {0x0016ffff, 0, LNKB, 0}, + Package() {0x0016ffff, 1, LNKC, 0}, + Package() {0x0016ffff, 2, LNKD, 0}, + Package() {0x0016ffff, 3, LNKA, 0}, + + // PCI Slot 23 + Package() {0x0017ffff, 0, LNKC, 0}, + Package() {0x0017ffff, 1, LNKD, 0}, + Package() {0x0017ffff, 2, LNKA, 0}, + Package() {0x0017ffff, 3, LNKB, 0}, + + // PCI Slot 24 + Package() {0x0018ffff, 0, LNKD, 0}, + Package() {0x0018ffff, 1, LNKA, 0}, + Package() {0x0018ffff, 2, LNKB, 0}, + Package() {0x0018ffff, 3, LNKC, 0}, + + // PCI Slot 25 + Package() {0x0019ffff, 0, LNKA, 0}, + Package() {0x0019ffff, 1, LNKB, 0}, + Package() {0x0019ffff, 2, LNKC, 0}, + Package() {0x0019ffff, 3, LNKD, 0}, + + // PCI Slot 26 + Package() {0x001affff, 0, LNKB, 0}, + Package() {0x001affff, 1, LNKC, 0}, + Package() {0x001affff, 2, LNKD, 0}, + Package() {0x001affff, 3, LNKA, 0}, + + // PCI Slot 27 + Package() {0x001bffff, 0, LNKC, 0}, + Package() {0x001bffff, 1, LNKD, 0}, + Package() {0x001bffff, 2, LNKA, 0}, + Package() {0x001bffff, 3, LNKB, 0}, + + // PCI Slot 28 + Package() {0x001cffff, 0, LNKD, 0}, + Package() {0x001cffff, 1, LNKA, 0}, + Package() {0x001cffff, 2, LNKB, 0}, + Package() {0x001cffff, 3, LNKC, 0}, + + // PCI Slot 29 + Package() {0x001dffff, 0, LNKA, 0}, + Package() {0x001dffff, 1, LNKB, 0}, + Package() {0x001dffff, 2, LNKC, 0}, + Package() {0x001dffff, 3, LNKD, 0}, + + // PCI Slot 30 + Package() {0x001effff, 0, LNKB, 0}, + Package() {0x001effff, 1, LNKC, 0}, + Package() {0x001effff, 2, LNKD, 0}, + Package() {0x001effff, 3, LNKA, 0}, + + // PCI Slot 31 + Package() {0x001fffff, 0, LNKC, 0}, + Package() {0x001fffff, 1, LNKD, 0}, + Package() {0x001fffff, 2, LNKA, 0}, + Package() {0x001fffff, 3, LNKB, 0}, + }) Index: kvm-userspace.pci3/bios/acpi-pci-slots.dsl =================================================================== --- /dev/null +++ kvm-userspace.pci3/bios/acpi-pci-slots.dsl @@ -0,0 +1,385 @@ + Device (S0) { // Slot 0 + Name (_ADR, 0x00000000) + Method (_EJ0,1) { + Store(0x1, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 0, Local0) + Return (Local0) + } + } + + Device (S1) { // Slot 1 + Name (_ADR, 0x00010000) + Method (_EJ0,1) { + Store(0x2, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 1, Local0) + Return (Local0) + } + } + + Device (S2) { // Slot 2 + Name (_ADR, 0x00020000) + Method (_EJ0,1) { + Store(0x4, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 2, Local0) + Return (Local0) + } + } + + Device (S3) { // Slot 3 + Name (_ADR, 0x00030000) + Method (_EJ0,1) { + Store(0x4, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 3, Local0) + Return (Local0) + } + } + + Device (S4) { // Slot 4 + Name (_ADR, 0x00040000) + Method (_EJ0,1) { + Store(0x4, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 4, Local0) + Return (Local0) + } + } + + Device (S5) { // Slot 5 + Name (_ADR, 0x00050000) + Method (_EJ0,1) { + Store(0x4, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 5, Local0) + Return (Local0) + } + } + + Device (S6) { // Slot 6 + Name (_ADR, 0x00060000) + Method (_EJ0,1) { + Store(0x40, BEJ) + Return (0x0) + } + + Method(_SUN) { + Add (SUN1, 6, Local0) + Return (Local0) + } + } + + Device (S7) { // Slot 7 + Name (_ADR, 0x00070000) + Method (_EJ0,1) { + Store(0x80, BEJ) + Return (0x0) + } + + Method(_SUN) { + Add (SUN1, 7, Local0) + Return (Local0) + } + } + + Device (S8) { // Slot 8 + Name (_ADR, 0x00080000) + Method (_EJ0,1) { + Store(0x100, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 8, Local0) + Return (Local0) + } + } + + Device (S9) { // Slot 9 + Name (_ADR, 0x00090000) + Method (_EJ0,1) { + Store(0x200, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 9, Local0) + Return (Local0) + } + } + + Device (S10) { // Slot 10 + Name (_ADR, 0x000A0000) + Method (_EJ0,1) { + Store(0x400, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 10, Local0) + Return (Local0) + } + } + + Device (S11) { // Slot 11 + Name (_ADR, 0x000B0000) + Method (_EJ0,1) { + Store(0x800, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 11, Local0) + Return (Local0) + } + } + + Device (S12) { // Slot 12 + Name (_ADR, 0x000C0000) + Method (_EJ0,1) { + Store(0x1000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 12, Local0) + Return (Local0) + } + } + + Device (S13) { // Slot 13 + Name (_ADR, 0x000D0000) + Method (_EJ0,1) { + Store(0x2000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 13, Local0) + Return (Local0) + } + } + + Device (S14) { // Slot 14 + Name (_ADR, 0x000E0000) + Method (_EJ0,1) { + Store(0x4000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 14, Local0) + Return (Local0) + } + } + + Device (S15) { // Slot 15 + Name (_ADR, 0x000F0000) + Method (_EJ0,1) { + Store(0x8000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 15, Local0) + Return (Local0) + } + } + + Device (S16) { // Slot 16 + Name (_ADR, 0x00100000) + Method (_EJ0,1) { + Store(0x10000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 16, Local0) + Return (Local0) + } + } + + Device (S17) { // Slot 17 + Name (_ADR, 0x00110000) + Method (_EJ0,1) { + Store(0x20000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 17, Local0) + Return (Local0) + } + } + + Device (S18) { // Slot 18 + Name (_ADR, 0x00120000) + Method (_EJ0,1) { + Store(0x40000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 18, Local0) + Return (Local0) + } + } + + Device (S19) { // Slot 19 + Name (_ADR, 0x00130000) + Method (_EJ0,1) { + Store(0x80000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 19, Local0) + Return (Local0) + } + } + + Device (S20) { // Slot 20 + Name (_ADR, 0x00140000) + Method (_EJ0,1) { + Store(0x100000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 20, Local0) + Return (Local0) + } + } + + Device (S21) { // Slot 21 + Name (_ADR, 0x00150000) + Method (_EJ0,1) { + Store(0x200000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 21, Local0) + Return (Local0) + } + } + + Device (S22) { // Slot 22 + Name (_ADR, 0x00160000) + Method (_EJ0,1) { + Store(0x400000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 22, Local0) + Return (Local0) + } + } + + Device (S23) { // Slot 23 + Name (_ADR, 0x00170000) + Method (_EJ0,1) { + Store(0x800000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 23, Local0) + Return (Local0) + } + } + + Device (S24) { // Slot 24 + Name (_ADR, 0x00180000) + Method (_EJ0,1) { + Store(0x1000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 24, Local0) + Return (Local0) + } + } + + Device (S25) { // Slot 25 + Name (_ADR, 0x00190000) + Method (_EJ0,1) { + Store(0x2000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 25, Local0) + Return (Local0) + } + } + + Device (S26) { // Slot 26 + Name (_ADR, 0x001A0000) + Method (_EJ0,1) { + Store(0x4000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 26, Local0) + Return (Local0) + } + } + + Device (S27) { // Slot 27 + Name (_ADR, 0x001B0000) + Method (_EJ0,1) { + Store(0x8000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 27, Local0) + Return (Local0) + } + } + + Device (S28) { // Slot 28 + Name (_ADR, 0x001C0000) + Method (_EJ0,1) { + Store(0x10000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 28, Local0) + Return (Local0) + } + } + + Device (S29) { // Slot 29 + Name (_ADR, 0x001D0000) + Method (_EJ0,1) { + Store(0x20000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 29, Local0) + Return (Local0) + } + } + + Device (S30) { // Slot 30 + Name (_ADR, 0x001E0000) + Method (_EJ0,1) { + Store(0x40000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 30, Local0) + Return (Local0) + } + } + + Device (S31) { // Slot 31 + Name (_ADR, 0x001F0000) + Method (_EJ0,1) { + Store(0x80000000, BEJ) + Return (0x0) + } + Method(_SUN) { + Add (SUN1, 31, Local0) + Return (Local0) + } + } -- |
From: David A. <da...@bo...> - 2008-05-02 16:38:43
|
Avi Kivity wrote: > David Abrahams wrote: >> Jon <iroquoi <at> gmail.com> writes: >> >> >>> I use: >>> >>> export QEMU_AUDIO_DRV=alsa >>> export QEMU_AUDIO_DAC_FIXED_FREQ=48000 >>> export QEMU_AUDIO_ADC_FIXED_FREQ=48000 >>> export QEMU_ALSA_DAC_BUFFER_SIZE=16384 >>> >>> Buffer size is very important, else it crackles and pops for me. >>> >> >> Unfortunately with my upgrade to Ubuntu Hardy this has stopped >> working; I can >> put off the effect by playing a test tone in linux, but Qemu again >> takes over >> the sound system completely the first time it succeeds in making >> noise. Maybe >> this has something to do with the addition of *yet another* audio >> layer in Hardy >> (PulseAudio?) > > What does your /etc/alsa/alsa.conf look like? The only alsa.conf here is in /usr/share/alsa. It's enclosed > Also, please remove any > user-local alsa configuration files you may have inherited from the > previous installation. This was a fresh installation. -- Dave Abrahams Boost Consulting http://boost-consulting.com |
From: Jamie L. <ja...@sh...> - 2008-05-02 15:37:35
|
Daniel P. Berrange wrote: > > > 2/ two instances of kvm can be passed the same -hda. There is no locking > > > whatsoever. This messes up things seriously. > > That depends entirely on what you are doing with the disk in the guest OS. > > The disk could be hosting a cluster filesystem. The guest OS could be > running on a read-only root FS. The disk could be application raw data > storage which can be shared (eg Oracle RAC). That reminds me, a "read-only" option for disk images would be handy occasionally. Writes would return errors, rather than to an expanding snapshot file. And then, logically, any default locking for disk images (if you don't disable it) would use shared locking for a read-only disk image. > > These two are upstream qemu problems. Copying qemu-devel. > > > > I guess using file locking by default would improve the situation, and > > we can add a -drive ...,exclusive=no option for people playing with > > cluster filesystems. > > Turning on file locking by default will break existing apps / deployments > using shared disks. IMHO this is a policy decision that should be solved > at ahigher level in the management stack where a whole world view is > available rather than QEMU which only knows about its own VM & host. Imho disk locking should be on by default and easy to turn off. Casual small scale use of QEMU doesn't use a "management stack", it uses the command line directly invoking qemu or kvm, or a one-line script. In that scenario locking against running two instances _by mistake_ is most useful (it's easy to accidentally forget you have one running when hidden on the desktop), and least likely for someone to use a wrapper. The few cluster deployments using shared disks will notice very quickly that an additional option is needed for the new QEMU version. It won't be the first time a new version has required a change to the command line options to keep an existing deployment working. -- Jamie |
From: Marcelo T. <mto...@re...> - 2008-05-02 15:32:32
|
On Fri, May 02, 2008 at 04:55:24PM +0200, Alexander Graf wrote: > Hi, > > in the DSDT there are two different ways of defining, how an interrupt > is supposed to be routed. Currently we are using the LNKA - LNKD method, > which afaict is for legacy support. > The other method is to directly tell the Operating System, which APIC > pin the device is attached to. We can get that information from the very > same entry, the LNKA to LNKD pseudo devices receive it. > > For now this does not give any obvious improvement. It does leave room > for more advanced mappings, with several IOAPICs that can handle more > devices separately. This might help when we have a lot of devices, as > currently all devices sit on two interrupt lanes. > > More importantly (for me) though, is that Darwin enables the APIC mode > unconditionally, so it won't easily run in legacy mode. Hi Alexander, I'm just about to resend the patchset to add 3 PCI bridges, which already adds the _SUN method appropriately. Please rebase the APRT patch on top of that. Thanks! |
From: Anthony L. <an...@co...> - 2008-05-02 15:21:59
|
Avi Kivity wrote: > > Well, one user (me) has made this mistake, several times. I guess it's usage patterns. I'm pretty religious about using -snapshot unless I have a very specific reason not to. I have never encountered this problem myself. >> FWIW, the whole override thing for Xen has been an endless source of >> pain. It's very difficult (if not impossible) to accurately >> determine if someone else is using the disk. > > What's wrong with the standard file locking API? Of course it won't > stop non-qemu apps from accessing it, but that's unlikely anyway. Xen tries to be very smart about determining whether devices are mounted somewhere else or not. >> Also, it tends to confuse people trying to do something legitimate >> more often than helping someone doing something stupid. > > -drive exclusive=off (or share=yes) The problem I have is that the default policy gets very complicated. At first thought, I would say it's fine as long as exclusive=off was the default for using -snapshot or using raw images. However, if you create a VM with a qcow image using -snapshot, and then create another one without using snapshot, you're boned. What we really need is a global configuration file so that individual users can select these defaults according to what makes sense for them. In the mean time, I think the policy vs. mechanism strongly suggests that exclusive=off should be the default (not to mention maintaining backwards compatibility). >> >> I very frequently run multiple VMs with the same disk. I do it >> strictly for the purposes of benchmarking. There are ways to share a >> disk without using a clustered filesystem. > > I imagine only raw format disks, and only as non-root filesystems (or > with -shapshot, which should automatically set exclusive=off)? Yup. >> >> If a higher level management tool wants to enforce a policy (like >> libvirt), then let it. We should not be enforcing policies within >> QEMU though. > > I agree that qemu is not the place to enforce policies, but covering a > hole that users are likely to step into, while allowing its explicit > uncovering, is a good thing. We're not enforcing the policy, only > hinting. Unfortunately, the solution involves breaking backwards compatibility for legitimate use-cases (not to mention making those use-cases more awkward). I think the only way to sanely do this is as a global configuration parameter. Regards, Anthony Liguori |
From: Andrea A. <an...@qu...> - 2008-05-02 15:19:17
|
On Fri, May 02, 2008 at 12:28:32PM +0300, Avi Kivity wrote: > Applied, thanks. Dynamic allocation for the fpu state was introduced in > 2.6.26-rc, right? It seems very recent, hit mainline on 30 Apr. Also we may want to think if there's something cheaper than fx_save to trigger a math exception that doesn't alter the fpu state, I didn't think much about it given it's such a slow path that's probably not worth changing with something more complicated anyway. And bringing in a few l1 exclusive cachelines in the cpu should allow the second instruction to repeat faster than the first. |
From: Andrea A. <an...@qu...> - 2008-05-02 15:13:07
|
# HG changeset patch # User Andrea Arcangeli <an...@qu...> # Date 1209740229 -7200 # Node ID b4bf6df98bc00bfbef9423b0dd31cfdba63a5eeb # Parent 4f462fb3dff614cd7d971219c3feaef0b43359c1 mmap sems This patch adds a lock ordering rule to avoid a potential deadlock when multiple mmap_sems need to be locked. Signed-off-by: Dean Nelson <dc...@sg...> Signed-off-by: Andrea Arcangeli <an...@qu...> diff --git a/mm/filemap.c b/mm/filemap.c --- a/mm/filemap.c +++ b/mm/filemap.c @@ -79,6 +79,9 @@ generic_file_direct_IO(int rw, struct ki * * ->i_mutex (generic_file_buffered_write) * ->mmap_sem (fault_in_pages_readable->do_page_fault) + * + * When taking multiple mmap_sems, one should lock the lowest-addressed + * one first proceeding on up to the highest-addressed one. * * ->i_mutex * ->i_alloc_sem (various) |