Revision d76d1650

b/Makefile.target
659 659
OBJS+= device_tree.o
660 660
LIBS+= $(FDT_LIBS)
661 661
endif
662
ifdef CONFIG_KVM
663
OBJS+= kvm_ppc.o
664
endif
662 665
# virtio support
663 666
OBJS+= virtio.o virtio-blk.o virtio-balloon.o
664 667
endif
b/configure
1491 1491

  
1492 1492
# Make sure the target and host cpus are compatible
1493 1493
if test "$kvm" = "yes" -a ! \( "$target_cpu" = "$cpu" -o \
1494
  \( "$target_cpu" = "ppcemb" -a "$cpu" = "powerpc" \) -o \
1494 1495
  \( "$target_cpu" = "x86_64" -a "$cpu" = "i386"   \) -o \
1495 1496
  \( "$target_cpu" = "i386"   -a "$cpu" = "x86_64" \) \) ; then
1496 1497
  kvm="no"
......
1585 1586
    echo "#define TARGET_ARCH \"ppcemb\"" >> $config_h
1586 1587
    echo "#define TARGET_PPC 1" >> $config_h
1587 1588
    echo "#define TARGET_PPCEMB 1" >> $config_h
1589
    if test "$kvm" = "yes" ; then
1590
      echo "CONFIG_KVM=yes" >> $config_mak
1591
      echo "KVM_CFLAGS=$kvm_cflags" >> $config_mak
1592
      echo "#define CONFIG_KVM 1" >> $config_h
1593
    fi
1588 1594
  ;;
1589 1595
  ppc64)
1590 1596
    echo "TARGET_ARCH=ppc64" >> $config_mak
b/target-ppc/helper.c
29 29
#include "exec-all.h"
30 30
#include "helper_regs.h"
31 31
#include "qemu-common.h"
32
#include "kvm.h"
32 33

  
33 34
//#define DEBUG_MMU
34 35
//#define DEBUG_BATS
......
2920 2921
    env->cpu_model_str = cpu_model;
2921 2922
    cpu_ppc_register_internal(env, def);
2922 2923
    cpu_ppc_reset(env);
2924

  
2925
    if (kvm_enabled())
2926
        kvm_init_vcpu(env);
2927

  
2923 2928
    return env;
2924 2929
}
2925 2930

  
b/target-ppc/kvm.c
1
/*
2
 * PowerPC implementation of KVM hooks
3
 *
4
 * Copyright IBM Corp. 2007
5
 *
6
 * Authors:
7
 *  Jerone Young <jyoung5@us.ibm.com>
8
 *  Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
9
 *  Hollis Blanchard <hollisb@us.ibm.com>
10
 *
11
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
12
 * See the COPYING file in the top-level directory.
13
 *
14
 */
15

  
16
#include <sys/types.h>
17
#include <sys/ioctl.h>
18
#include <sys/mman.h>
19

  
20
#include <linux/kvm.h>
21

  
22
#include "qemu-common.h"
23
#include "qemu-timer.h"
24
#include "sysemu.h"
25
#include "kvm.h"
26
#include "kvm_ppc.h"
27
#include "cpu.h"
28
#include "device_tree.h"
29

  
30
//#define DEBUG_KVM
31

  
32
#ifdef DEBUG_KVM
33
#define dprintf(fmt, ...) \
34
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
35
#else
36
#define dprintf(fmt, ...) \
37
    do { } while (0)
38
#endif
39

  
40
int kvm_arch_init(KVMState *s, int smp_cpus)
41
{
42
    return 0;
43
}
44

  
45
int kvm_arch_init_vcpu(CPUState *cenv)
46
{
47
    return 0;
48
}
49

  
50
int kvm_arch_put_registers(CPUState *env)
51
{
52
    struct kvm_regs regs;
53
    int ret;
54
    int i;
55

  
56
    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
57
    if (ret < 0)
58
        return ret;
59

  
60
    regs.ctr = env->ctr;
61
    regs.lr  = env->lr;
62
    regs.xer = env->xer;
63
    regs.msr = env->msr;
64
    regs.pc = env->nip;
65

  
66
    regs.srr0 = env->spr[SPR_SRR0];
67
    regs.srr1 = env->spr[SPR_SRR1];
68

  
69
    regs.sprg0 = env->spr[SPR_SPRG0];
70
    regs.sprg1 = env->spr[SPR_SPRG1];
71
    regs.sprg2 = env->spr[SPR_SPRG2];
72
    regs.sprg3 = env->spr[SPR_SPRG3];
73
    regs.sprg4 = env->spr[SPR_SPRG4];
74
    regs.sprg5 = env->spr[SPR_SPRG5];
75
    regs.sprg6 = env->spr[SPR_SPRG6];
76
    regs.sprg7 = env->spr[SPR_SPRG7];
77

  
78
    for (i = 0;i < 32; i++)
79
        regs.gpr[i] = env->gpr[i];
80

  
81
    ret = kvm_vcpu_ioctl(env, KVM_SET_REGS, &regs);
82
    if (ret < 0)
83
        return ret;
84

  
85
    return ret;
86
}
87

  
88
int kvm_arch_get_registers(CPUState *env)
89
{
90
    struct kvm_regs regs;
91
    uint32_t i, ret;
92

  
93
    ret = kvm_vcpu_ioctl(env, KVM_GET_REGS, &regs);
94
    if (ret < 0)
95
        return ret;
96

  
97
    env->ctr = regs.ctr;
98
    env->lr = regs.lr;
99
    env->xer = regs.xer;
100
    env->msr = regs.msr;
101
    env->nip = regs.pc;
102

  
103
    env->spr[SPR_SRR0] = regs.srr0;
104
    env->spr[SPR_SRR1] = regs.srr1;
105

  
106
    env->spr[SPR_SPRG0] = regs.sprg0;
107
    env->spr[SPR_SPRG1] = regs.sprg1;
108
    env->spr[SPR_SPRG2] = regs.sprg2;
109
    env->spr[SPR_SPRG3] = regs.sprg3;
110
    env->spr[SPR_SPRG4] = regs.sprg4;
111
    env->spr[SPR_SPRG5] = regs.sprg5;
112
    env->spr[SPR_SPRG6] = regs.sprg6;
113
    env->spr[SPR_SPRG7] = regs.sprg7;
114

  
115
    for (i = 0;i < 32; i++)
116
        env->gpr[i] = regs.gpr[i];
117

  
118
    return 0;
119
}
120

  
121
int kvm_arch_pre_run(CPUState *env, struct kvm_run *run)
122
{
123
    int r;
124
    unsigned irq;
125

  
126
    /* PowerPC Qemu tracks the various core input pins (interrupt, critical
127
     * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
128
    if (run->ready_for_interrupt_injection &&
129
        (env->interrupt_request & CPU_INTERRUPT_HARD) &&
130
        (env->irq_input_state & (1<<PPC40x_INPUT_INT)))
131
    {
132
        /* For now KVM disregards the 'irq' argument. However, in the
133
         * future KVM could cache it in-kernel to avoid a heavyweight exit
134
         * when reading the UIC.
135
         */
136
        irq = -1U;
137

  
138
        dprintf("injected interrupt %d\n", irq);
139
        r = kvm_vcpu_ioctl(env, KVM_INTERRUPT, &irq);
140
        if (r < 0)
141
            printf("cpu %d fail inject %x\n", env->cpu_index, irq);
142
    }
143

  
144
    /* We don't know if there are more interrupts pending after this. However,
145
     * the guest will return to userspace in the course of handling this one
146
     * anyways, so we will get a chance to deliver the rest. */
147
    return 0;
148
}
149

  
150
int kvm_arch_post_run(CPUState *env, struct kvm_run *run)
151
{
152
    return 0;
153
}
154

  
155
static int kvmppc_handle_halt(CPUState *env)
156
{
157
    if (!(env->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
158
        env->halted = 1;
159
        env->exception_index = EXCP_HLT;
160
    }
161

  
162
    return 1;
163
}
164

  
165
/* map dcr access to existing qemu dcr emulation */
166
static int kvmppc_handle_dcr_read(CPUState *env, uint32_t dcrn, uint32_t *data)
167
{
168
    if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0)
169
        fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn);
170

  
171
    return 1;
172
}
173

  
174
static int kvmppc_handle_dcr_write(CPUState *env, uint32_t dcrn, uint32_t data)
175
{
176
    if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0)
177
        fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn);
178

  
179
    return 1;
180
}
181

  
182
int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
183
{
184
    int ret = 0;
185

  
186
    switch (run->exit_reason) {
187
    case KVM_EXIT_DCR:
188
        if (run->dcr.is_write) {
189
            dprintf("handle dcr write\n");
190
            ret = kvmppc_handle_dcr_write(env, run->dcr.dcrn, run->dcr.data);
191
        } else {
192
            dprintf("handle dcr read\n");
193
            ret = kvmppc_handle_dcr_read(env, run->dcr.dcrn, &run->dcr.data);
194
        }
195
        break;
196
    case KVM_EXIT_HLT:
197
        dprintf("handle halt\n");
198
        ret = kvmppc_handle_halt(env);
199
        break;
200
    }
201

  
202
    return ret;
203
}
204

  
b/target-ppc/kvm_ppc.c
1
/*
2
 * PowerPC KVM support
3
 *
4
 * Copyright IBM Corp. 2008
5
 *
6
 * Authors:
7
 *  Hollis Blanchard <hollisb@us.ibm.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10
 * See the COPYING file in the top-level directory.
11
 *
12
 */
13

  
14
#include "qemu-common.h"
15
#include "qemu-timer.h"
16
#include "kvm_ppc.h"
17
#include "device_tree.h"
18

  
19
#define PROC_DEVTREE_PATH "/proc/device-tree"
20

  
21
static QEMUTimer *kvmppc_timer;
22
static unsigned int kvmppc_timer_rate;
23

  
24
#ifdef HAVE_FDT
25
static int kvmppc_read_host_property(const char *node_path, const char *prop,
26
                                     void *val, size_t len)
27
{
28
    char *path;
29
    FILE *f;
30
    int ret;
31
    int pathlen;
32

  
33
    pathlen = snprintf(NULL, 0, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop)
34
              + 1;
35
    path = qemu_malloc(pathlen);
36
    if (path == NULL) {
37
        ret = -ENOMEM;
38
        goto out;
39
    }
40

  
41
    snprintf(path, pathlen, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop);
42

  
43
    f = fopen(path, "rb");
44
    if (f == NULL) {
45
        ret = errno;
46
        goto free;
47
    }
48

  
49
    len = fread(val, len, 1, f);
50
    if (len != 1) {
51
        ret = ferror(f);
52
        goto close;
53
    }
54

  
55
close:
56
    fclose(f);
57
free:
58
    free(path);
59
out:
60
    return ret;
61
}
62

  
63
static int kvmppc_copy_host_cell(void *fdt, const char *node, const char *prop)
64
{
65
    uint32_t cell;
66
    int ret;
67

  
68
    ret = kvmppc_read_host_property(node, prop, &cell, sizeof(cell));
69
    if (ret < 0) {
70
        fprintf(stderr, "couldn't read host %s/%s\n", node, prop);
71
        goto out;
72
    }
73

  
74
    ret = qemu_devtree_setprop_cell(fdt, node, prop, cell);
75
    if (ret < 0) {
76
        fprintf(stderr, "couldn't set guest %s/%s\n", node, prop);
77
        goto out;
78
    }
79

  
80
out:
81
    return ret;
82
}
83

  
84
void kvmppc_fdt_update(void *fdt)
85
{
86
    /* Copy data from the host device tree into the guest. Since the guest can
87
     * directly access the timebase without host involvement, we must expose
88
     * the correct frequencies. */
89
    kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "clock-frequency");
90
    kvmppc_copy_host_cell(fdt, "/cpus/cpu@0", "timebase-frequency");
91
}
92
#endif
93

  
94
static void kvmppc_timer_hack(void *opaque)
95
{
96
    qemu_service_io();
97
    qemu_mod_timer(kvmppc_timer, qemu_get_clock(vm_clock) + kvmppc_timer_rate);
98
}
99

  
100
void kvmppc_init(void)
101
{
102
    /* XXX The only reason KVM yields control back to qemu is device IO. Since
103
     * an idle guest does no IO, qemu's device model will never get a chance to
104
     * run. So, until Qemu gains IO threads, we create this timer to ensure
105
     * that the device model gets a chance to run. */
106
    kvmppc_timer_rate = ticks_per_sec / 10;
107
    kvmppc_timer = qemu_new_timer(vm_clock, &kvmppc_timer_hack, NULL);
108
    qemu_mod_timer(kvmppc_timer, qemu_get_clock(vm_clock) + kvmppc_timer_rate);
109
}
110

  
b/target-ppc/kvm_ppc.h
1
/*
2
 * Copyright 2008 IBM Corporation.
3
 * Authors: Hollis Blanchard <hollisb@us.ibm.com>
4
 *
5
 * This work is licensed under the GNU GPL license version 2 or later.
6
 *
7
 */
8

  
9
#ifndef __KVM_PPC_H__
10
#define __KVM_PPC_H__
11

  
12
void kvmppc_init(void);
13
void kvmppc_fdt_update(void *fdt);
14

  
15
#endif /* __KVM_PPC_H__ */

Also available in: Unified diff