Skip to content

Commit bb18b52

Browse files
committed
Merge tag 'signed-for-3.16' of git://github.com/agraf/linux-2.6 into kvm-master
Patch queue for 3.16 - 2014-07-08 A few bug fixes to make 3.16 work well with KVM on PowerPC: - Fix ppc32 module builds - Fix Little Endian hosts - Fix Book3S HV HPTE lookup with huge pages in guest - Fix BookE lock leak
2 parents 9242b5b + 19a44ec commit bb18b52

File tree

9 files changed

+52
-58
lines changed

9 files changed

+52
-58
lines changed

arch/powerpc/include/asm/kvm_book3s_64.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,10 @@ static inline unsigned long compute_tlbie_rb(unsigned long v, unsigned long r,
198198
return rb;
199199
}
200200

201-
static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
201+
static inline unsigned long __hpte_page_size(unsigned long h, unsigned long l,
202+
bool is_base_size)
202203
{
204+
203205
int size, a_psize;
204206
/* Look at the 8 bit LP value */
205207
unsigned int lp = (l >> LP_SHIFT) & ((1 << LP_BITS) - 1);
@@ -214,14 +216,27 @@ static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
214216
continue;
215217

216218
a_psize = __hpte_actual_psize(lp, size);
217-
if (a_psize != -1)
219+
if (a_psize != -1) {
220+
if (is_base_size)
221+
return 1ul << mmu_psize_defs[size].shift;
218222
return 1ul << mmu_psize_defs[a_psize].shift;
223+
}
219224
}
220225

221226
}
222227
return 0;
223228
}
224229

230+
static inline unsigned long hpte_page_size(unsigned long h, unsigned long l)
231+
{
232+
return __hpte_page_size(h, l, 0);
233+
}
234+
235+
static inline unsigned long hpte_base_page_size(unsigned long h, unsigned long l)
236+
{
237+
return __hpte_page_size(h, l, 1);
238+
}
239+
225240
static inline unsigned long hpte_rpn(unsigned long ptel, unsigned long psize)
226241
{
227242
return ((ptel & HPTE_R_RPN) & ~(psize - 1)) >> PAGE_SHIFT;

arch/powerpc/include/asm/ppc_asm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ GLUE(.,name):
277277
.globl n; \
278278
n:
279279

280+
#define _GLOBAL_TOC(name) _GLOBAL(name)
281+
280282
#define _KPROBE(n) \
281283
.section ".kprobes.text","a"; \
282284
.globl n; \

arch/powerpc/kvm/book3s_64_mmu_hv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,7 @@ static ssize_t kvm_htab_write(struct file *file, const char __user *buf,
15621562
goto out;
15631563
}
15641564
if (!rma_setup && is_vrma_hpte(v)) {
1565-
unsigned long psize = hpte_page_size(v, r);
1565+
unsigned long psize = hpte_base_page_size(v, r);
15661566
unsigned long senc = slb_pgsize_encoding(psize);
15671567
unsigned long lpcr;
15681568

arch/powerpc/kvm/book3s_hv_rm_mmu.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -814,13 +814,10 @@ long kvmppc_hv_find_lock_hpte(struct kvm *kvm, gva_t eaddr, unsigned long slb_v,
814814
r = hpte[i+1];
815815

816816
/*
817-
* Check the HPTE again, including large page size
818-
* Since we don't currently allow any MPSS (mixed
819-
* page-size segment) page sizes, it is sufficient
820-
* to check against the actual page size.
817+
* Check the HPTE again, including base page size
821818
*/
822819
if ((v & valid) && (v & mask) == val &&
823-
hpte_page_size(v, r) == (1ul << pshift))
820+
hpte_base_page_size(v, r) == (1ul << pshift))
824821
/* Return with the HPTE still locked */
825822
return (hash << 3) + (i >> 1);
826823

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
*
4949
* LR = return address to continue at after eventually re-enabling MMU
5050
*/
51-
_GLOBAL(kvmppc_hv_entry_trampoline)
51+
_GLOBAL_TOC(kvmppc_hv_entry_trampoline)
5252
mflr r0
5353
std r0, PPC_LR_STKOFF(r1)
5454
stdu r1, -112(r1)

arch/powerpc/kvm/book3s_interrupts.S

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@
2525
#include <asm/exception-64s.h>
2626

2727
#if defined(CONFIG_PPC_BOOK3S_64)
28+
#if defined(_CALL_ELF) && _CALL_ELF == 2
29+
#define FUNC(name) name
30+
#else
2831
#define FUNC(name) GLUE(.,name)
32+
#endif
2933
#define GET_SHADOW_VCPU(reg) addi reg, r13, PACA_SVCPU
3034

3135
#elif defined(CONFIG_PPC_BOOK3S_32)

arch/powerpc/kvm/book3s_rmhandlers.S

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636

3737
#if defined(CONFIG_PPC_BOOK3S_64)
3838

39+
#if defined(_CALL_ELF) && _CALL_ELF == 2
40+
#define FUNC(name) name
41+
#else
3942
#define FUNC(name) GLUE(.,name)
43+
#endif
4044

4145
#elif defined(CONFIG_PPC_BOOK3S_32)
4246

@@ -146,7 +150,7 @@ kvmppc_handler_skip_ins:
146150
* On entry, r4 contains the guest shadow MSR
147151
* MSR.EE has to be 0 when calling this function
148152
*/
149-
_GLOBAL(kvmppc_entry_trampoline)
153+
_GLOBAL_TOC(kvmppc_entry_trampoline)
150154
mfmsr r5
151155
LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
152156
toreal(r7)

arch/powerpc/kvm/book3s_rtas.c

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,33 @@ static void kvm_rtas_set_xive(struct kvm_vcpu *vcpu, struct rtas_args *args)
2323
u32 irq, server, priority;
2424
int rc;
2525

26-
if (args->nargs != 3 || args->nret != 1) {
26+
if (be32_to_cpu(args->nargs) != 3 || be32_to_cpu(args->nret) != 1) {
2727
rc = -3;
2828
goto out;
2929
}
3030

31-
irq = args->args[0];
32-
server = args->args[1];
33-
priority = args->args[2];
31+
irq = be32_to_cpu(args->args[0]);
32+
server = be32_to_cpu(args->args[1]);
33+
priority = be32_to_cpu(args->args[2]);
3434

3535
rc = kvmppc_xics_set_xive(vcpu->kvm, irq, server, priority);
3636
if (rc)
3737
rc = -3;
3838
out:
39-
args->rets[0] = rc;
39+
args->rets[0] = cpu_to_be32(rc);
4040
}
4141

4242
static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args)
4343
{
4444
u32 irq, server, priority;
4545
int rc;
4646

47-
if (args->nargs != 1 || args->nret != 3) {
47+
if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 3) {
4848
rc = -3;
4949
goto out;
5050
}
5151

52-
irq = args->args[0];
52+
irq = be32_to_cpu(args->args[0]);
5353

5454
server = priority = 0;
5555
rc = kvmppc_xics_get_xive(vcpu->kvm, irq, &server, &priority);
@@ -58,48 +58,48 @@ static void kvm_rtas_get_xive(struct kvm_vcpu *vcpu, struct rtas_args *args)
5858
goto out;
5959
}
6060

61-
args->rets[1] = server;
62-
args->rets[2] = priority;
61+
args->rets[1] = cpu_to_be32(server);
62+
args->rets[2] = cpu_to_be32(priority);
6363
out:
64-
args->rets[0] = rc;
64+
args->rets[0] = cpu_to_be32(rc);
6565
}
6666

6767
static void kvm_rtas_int_off(struct kvm_vcpu *vcpu, struct rtas_args *args)
6868
{
6969
u32 irq;
7070
int rc;
7171

72-
if (args->nargs != 1 || args->nret != 1) {
72+
if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) {
7373
rc = -3;
7474
goto out;
7575
}
7676

77-
irq = args->args[0];
77+
irq = be32_to_cpu(args->args[0]);
7878

7979
rc = kvmppc_xics_int_off(vcpu->kvm, irq);
8080
if (rc)
8181
rc = -3;
8282
out:
83-
args->rets[0] = rc;
83+
args->rets[0] = cpu_to_be32(rc);
8484
}
8585

8686
static void kvm_rtas_int_on(struct kvm_vcpu *vcpu, struct rtas_args *args)
8787
{
8888
u32 irq;
8989
int rc;
9090

91-
if (args->nargs != 1 || args->nret != 1) {
91+
if (be32_to_cpu(args->nargs) != 1 || be32_to_cpu(args->nret) != 1) {
9292
rc = -3;
9393
goto out;
9494
}
9595

96-
irq = args->args[0];
96+
irq = be32_to_cpu(args->args[0]);
9797

9898
rc = kvmppc_xics_int_on(vcpu->kvm, irq);
9999
if (rc)
100100
rc = -3;
101101
out:
102-
args->rets[0] = rc;
102+
args->rets[0] = cpu_to_be32(rc);
103103
}
104104
#endif /* CONFIG_KVM_XICS */
105105

@@ -205,32 +205,6 @@ int kvm_vm_ioctl_rtas_define_token(struct kvm *kvm, void __user *argp)
205205
return rc;
206206
}
207207

208-
static void kvmppc_rtas_swap_endian_in(struct rtas_args *args)
209-
{
210-
#ifdef __LITTLE_ENDIAN__
211-
int i;
212-
213-
args->token = be32_to_cpu(args->token);
214-
args->nargs = be32_to_cpu(args->nargs);
215-
args->nret = be32_to_cpu(args->nret);
216-
for (i = 0; i < args->nargs; i++)
217-
args->args[i] = be32_to_cpu(args->args[i]);
218-
#endif
219-
}
220-
221-
static void kvmppc_rtas_swap_endian_out(struct rtas_args *args)
222-
{
223-
#ifdef __LITTLE_ENDIAN__
224-
int i;
225-
226-
for (i = 0; i < args->nret; i++)
227-
args->args[i] = cpu_to_be32(args->args[i]);
228-
args->token = cpu_to_be32(args->token);
229-
args->nargs = cpu_to_be32(args->nargs);
230-
args->nret = cpu_to_be32(args->nret);
231-
#endif
232-
}
233-
234208
int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
235209
{
236210
struct rtas_token_definition *d;
@@ -249,22 +223,20 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
249223
if (rc)
250224
goto fail;
251225

252-
kvmppc_rtas_swap_endian_in(&args);
253-
254226
/*
255227
* args->rets is a pointer into args->args. Now that we've
256228
* copied args we need to fix it up to point into our copy,
257229
* not the guest args. We also need to save the original
258230
* value so we can restore it on the way out.
259231
*/
260232
orig_rets = args.rets;
261-
args.rets = &args.args[args.nargs];
233+
args.rets = &args.args[be32_to_cpu(args.nargs)];
262234

263235
mutex_lock(&vcpu->kvm->lock);
264236

265237
rc = -ENOENT;
266238
list_for_each_entry(d, &vcpu->kvm->arch.rtas_tokens, list) {
267-
if (d->token == args.token) {
239+
if (d->token == be32_to_cpu(args.token)) {
268240
d->handler->handler(vcpu, &args);
269241
rc = 0;
270242
break;
@@ -275,7 +247,6 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
275247

276248
if (rc == 0) {
277249
args.rets = orig_rets;
278-
kvmppc_rtas_swap_endian_out(&args);
279250
rc = kvm_write_guest(vcpu->kvm, args_phys, &args, sizeof(args));
280251
if (rc)
281252
goto fail;

arch/powerpc/kvm/e500_mmu_host.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,8 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
473473
if (printk_ratelimit())
474474
pr_err("%s: pte not present: gfn %lx, pfn %lx\n",
475475
__func__, (long)gfn, pfn);
476-
return -EINVAL;
476+
ret = -EINVAL;
477+
goto out;
477478
}
478479
kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg);
479480

0 commit comments

Comments
 (0)