Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c566ccfc
Commit
c566ccfc
authored
Aug 12, 2013
by
Paolo Bonzini
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'kvm-arm-fixes-3.11' of
git://git.linaro.org/people/cdall/linux-kvm-arm
into kvm-master
KVM/ARM Fixes for the Linux 3.11 release
parents
cada23f3
2184a60d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
44 additions
and
30 deletions
+44
-30
arch/arm/kvm/coproc.c
arch/arm/kvm/coproc.c
+19
-7
arch/arm/kvm/coproc.h
arch/arm/kvm/coproc.h
+3
-0
arch/arm/kvm/coproc_a15.c
arch/arm/kvm/coproc_a15.c
+5
-1
arch/arm/kvm/mmio.c
arch/arm/kvm/mmio.c
+2
-1
arch/arm/kvm/mmu.c
arch/arm/kvm/mmu.c
+15
-21
No files found.
arch/arm/kvm/coproc.c
View file @
c566ccfc
...
...
@@ -146,7 +146,11 @@ static bool pm_fake(struct kvm_vcpu *vcpu,
#define access_pmintenclr pm_fake
/* Architected CP15 registers.
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2
* CRn denotes the primary register number, but is copied to the CRm in the
* user space API for 64-bit register access in line with the terminology used
* in the ARM ARM.
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
* registers preceding 32-bit ones.
*/
static
const
struct
coproc_reg
cp15_regs
[]
=
{
/* CSSELR: swapped by interrupt.S. */
...
...
@@ -154,8 +158,8 @@ static const struct coproc_reg cp15_regs[] = {
NULL
,
reset_unknown
,
c0_CSSELR
},
/* TTBR0/TTBR1: swapped by interrupt.S. */
{
CRm
(
2
),
Op1
(
0
),
is64
,
NULL
,
reset_unknown64
,
c2_TTBR0
},
{
CRm
(
2
),
Op1
(
1
),
is64
,
NULL
,
reset_unknown64
,
c2_TTBR1
},
{
CRm
64
(
2
),
Op1
(
0
),
is64
,
NULL
,
reset_unknown64
,
c2_TTBR0
},
{
CRm
64
(
2
),
Op1
(
1
),
is64
,
NULL
,
reset_unknown64
,
c2_TTBR1
},
/* TTBCR: swapped by interrupt.S. */
{
CRn
(
2
),
CRm
(
0
),
Op1
(
0
),
Op2
(
2
),
is32
,
...
...
@@ -182,7 +186,7 @@ static const struct coproc_reg cp15_regs[] = {
NULL
,
reset_unknown
,
c6_IFAR
},
/* PAR swapped by interrupt.S */
{
CR
n
(
7
),
Op1
(
0
),
is64
,
NULL
,
reset_unknown64
,
c7_PAR
},
{
CR
m64
(
7
),
Op1
(
0
),
is64
,
NULL
,
reset_unknown64
,
c7_PAR
},
/*
* DC{C,I,CI}SW operations:
...
...
@@ -399,12 +403,13 @@ static bool index_to_params(u64 id, struct coproc_params *params)
|
KVM_REG_ARM_OPC1_MASK
))
return
false
;
params
->
is_64bit
=
true
;
params
->
CRm
=
((
id
&
KVM_REG_ARM_CRM_MASK
)
/* CRm to CRn: see cp15_to_index for details */
params
->
CRn
=
((
id
&
KVM_REG_ARM_CRM_MASK
)
>>
KVM_REG_ARM_CRM_SHIFT
);
params
->
Op1
=
((
id
&
KVM_REG_ARM_OPC1_MASK
)
>>
KVM_REG_ARM_OPC1_SHIFT
);
params
->
Op2
=
0
;
params
->
CR
n
=
0
;
params
->
CR
m
=
0
;
return
true
;
default:
return
false
;
...
...
@@ -898,7 +903,14 @@ static u64 cp15_to_index(const struct coproc_reg *reg)
if
(
reg
->
is_64
)
{
val
|=
KVM_REG_SIZE_U64
;
val
|=
(
reg
->
Op1
<<
KVM_REG_ARM_OPC1_SHIFT
);
val
|=
(
reg
->
CRm
<<
KVM_REG_ARM_CRM_SHIFT
);
/*
* CRn always denotes the primary coproc. reg. nr. for the
* in-kernel representation, but the user space API uses the
* CRm for the encoding, because it is modelled after the
* MRRC/MCRR instructions: see the ARM ARM rev. c page
* B3-1445
*/
val
|=
(
reg
->
CRn
<<
KVM_REG_ARM_CRM_SHIFT
);
}
else
{
val
|=
KVM_REG_SIZE_U32
;
val
|=
(
reg
->
Op1
<<
KVM_REG_ARM_OPC1_SHIFT
);
...
...
arch/arm/kvm/coproc.h
View file @
c566ccfc
...
...
@@ -135,6 +135,8 @@ static inline int cmp_reg(const struct coproc_reg *i1,
return
-
1
;
if
(
i1
->
CRn
!=
i2
->
CRn
)
return
i1
->
CRn
-
i2
->
CRn
;
if
(
i1
->
is_64
!=
i2
->
is_64
)
return
i2
->
is_64
-
i1
->
is_64
;
if
(
i1
->
CRm
!=
i2
->
CRm
)
return
i1
->
CRm
-
i2
->
CRm
;
if
(
i1
->
Op1
!=
i2
->
Op1
)
...
...
@@ -145,6 +147,7 @@ static inline int cmp_reg(const struct coproc_reg *i1,
#define CRn(_x) .CRn = _x
#define CRm(_x) .CRm = _x
#define CRm64(_x) .CRn = _x, .CRm = 0
#define Op1(_x) .Op1 = _x
#define Op2(_x) .Op2 = _x
#define is64 .is_64 = true
...
...
arch/arm/kvm/coproc_a15.c
View file @
c566ccfc
...
...
@@ -114,7 +114,11 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu,
/*
* A15-specific CP15 registers.
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2
* CRn denotes the primary register number, but is copied to the CRm in the
* user space API for 64-bit register access in line with the terminology used
* in the ARM ARM.
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
* registers preceding 32-bit ones.
*/
static
const
struct
coproc_reg
a15_regs
[]
=
{
/* MPIDR: we use VMPIDR for guest access. */
...
...
arch/arm/kvm/mmio.c
View file @
c566ccfc
...
...
@@ -63,7 +63,8 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run)
static
int
decode_hsr
(
struct
kvm_vcpu
*
vcpu
,
phys_addr_t
fault_ipa
,
struct
kvm_exit_mmio
*
mmio
)
{
unsigned
long
rt
,
len
;
unsigned
long
rt
;
int
len
;
bool
is_write
,
sign_extend
;
if
(
kvm_vcpu_dabt_isextabt
(
vcpu
))
{
...
...
arch/arm/kvm/mmu.c
View file @
c566ccfc
...
...
@@ -85,6 +85,12 @@ static void *mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc)
return
p
;
}
static
bool
page_empty
(
void
*
ptr
)
{
struct
page
*
ptr_page
=
virt_to_page
(
ptr
);
return
page_count
(
ptr_page
)
==
1
;
}
static
void
clear_pud_entry
(
struct
kvm
*
kvm
,
pud_t
*
pud
,
phys_addr_t
addr
)
{
pmd_t
*
pmd_table
=
pmd_offset
(
pud
,
0
);
...
...
@@ -103,12 +109,6 @@ static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr)
put_page
(
virt_to_page
(
pmd
));
}
static
bool
pmd_empty
(
pmd_t
*
pmd
)
{
struct
page
*
pmd_page
=
virt_to_page
(
pmd
);
return
page_count
(
pmd_page
)
==
1
;
}
static
void
clear_pte_entry
(
struct
kvm
*
kvm
,
pte_t
*
pte
,
phys_addr_t
addr
)
{
if
(
pte_present
(
*
pte
))
{
...
...
@@ -118,12 +118,6 @@ static void clear_pte_entry(struct kvm *kvm, pte_t *pte, phys_addr_t addr)
}
}
static
bool
pte_empty
(
pte_t
*
pte
)
{
struct
page
*
pte_page
=
virt_to_page
(
pte
);
return
page_count
(
pte_page
)
==
1
;
}
static
void
unmap_range
(
struct
kvm
*
kvm
,
pgd_t
*
pgdp
,
unsigned
long
long
start
,
u64
size
)
{
...
...
@@ -132,37 +126,37 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp,
pmd_t
*
pmd
;
pte_t
*
pte
;
unsigned
long
long
addr
=
start
,
end
=
start
+
size
;
u64
range
;
u64
next
;
while
(
addr
<
end
)
{
pgd
=
pgdp
+
pgd_index
(
addr
);
pud
=
pud_offset
(
pgd
,
addr
);
if
(
pud_none
(
*
pud
))
{
addr
+=
PUD_SIZE
;
addr
=
pud_addr_end
(
addr
,
end
)
;
continue
;
}
pmd
=
pmd_offset
(
pud
,
addr
);
if
(
pmd_none
(
*
pmd
))
{
addr
+=
PMD_SIZE
;
addr
=
pmd_addr_end
(
addr
,
end
)
;
continue
;
}
pte
=
pte_offset_kernel
(
pmd
,
addr
);
clear_pte_entry
(
kvm
,
pte
,
addr
);
range
=
PAGE_SIZE
;
next
=
addr
+
PAGE_SIZE
;
/* If we emptied the pte, walk back up the ladder */
if
(
p
t
e_empty
(
pte
))
{
if
(
p
ag
e_empty
(
pte
))
{
clear_pmd_entry
(
kvm
,
pmd
,
addr
);
range
=
PMD_SIZE
;
if
(
p
md_empty
(
pm
d
))
{
next
=
pmd_addr_end
(
addr
,
end
)
;
if
(
p
age_empty
(
pmd
)
&&
!
page_empty
(
pu
d
))
{
clear_pud_entry
(
kvm
,
pud
,
addr
);
range
=
PUD_SIZE
;
next
=
pud_addr_end
(
addr
,
end
)
;
}
}
addr
+=
range
;
addr
=
next
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment