Skip to content

Commit b4453cc

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64: armv8_deprecated: fold ops into insn_emulation
The code for emulating deprecated instructions has two related structures: struct insn_emulation_ops and struct insn_emulation, where each struct insn_emulation_ops is associated 1-1 with a struct insn_emulation. It would be simpler to combine the two into a single structure, removing the need for (unconditional) dynamic allocation at boot time, and simplifying some runtime pointer chasing. This patch merges the two structures together. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: James Morse <[email protected]> Cc: Joey Gouly <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Will Deacon <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent f5962ad commit b4453cc

File tree

1 file changed

+33
-43
lines changed

1 file changed

+33
-43
lines changed

arch/arm64/kernel/armv8_deprecated.c

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,12 @@ enum legacy_insn_status {
4141
INSN_OBSOLETE,
4242
};
4343

44-
struct insn_emulation_ops {
45-
const char *name;
46-
enum legacy_insn_status status;
47-
struct undef_hook *hooks;
48-
int (*set_hw_mode)(bool enable);
49-
};
50-
5144
struct insn_emulation {
52-
struct list_head node;
53-
struct insn_emulation_ops *ops;
45+
const char *name;
46+
struct list_head node;
47+
enum legacy_insn_status status;
48+
struct undef_hook *hooks;
49+
int (*set_hw_mode)(bool enable);
5450
int current_mode;
5551
int min;
5652
int max;
@@ -61,48 +57,48 @@ static int nr_insn_emulated __initdata;
6157
static DEFINE_RAW_SPINLOCK(insn_emulation_lock);
6258
static DEFINE_MUTEX(insn_emulation_mutex);
6359

64-
static void register_emulation_hooks(struct insn_emulation_ops *ops)
60+
static void register_emulation_hooks(struct insn_emulation *insn)
6561
{
6662
struct undef_hook *hook;
6763

68-
BUG_ON(!ops->hooks);
64+
BUG_ON(!insn->hooks);
6965

70-
for (hook = ops->hooks; hook->instr_mask; hook++)
66+
for (hook = insn->hooks; hook->instr_mask; hook++)
7167
register_undef_hook(hook);
7268

73-
pr_notice("Registered %s emulation handler\n", ops->name);
69+
pr_notice("Registered %s emulation handler\n", insn->name);
7470
}
7571

76-
static void remove_emulation_hooks(struct insn_emulation_ops *ops)
72+
static void remove_emulation_hooks(struct insn_emulation *insn)
7773
{
7874
struct undef_hook *hook;
7975

80-
BUG_ON(!ops->hooks);
76+
BUG_ON(!insn->hooks);
8177

82-
for (hook = ops->hooks; hook->instr_mask; hook++)
78+
for (hook = insn->hooks; hook->instr_mask; hook++)
8379
unregister_undef_hook(hook);
8480

85-
pr_notice("Removed %s emulation handler\n", ops->name);
81+
pr_notice("Removed %s emulation handler\n", insn->name);
8682
}
8783

8884
static void enable_insn_hw_mode(void *data)
8985
{
9086
struct insn_emulation *insn = (struct insn_emulation *)data;
91-
if (insn->ops->set_hw_mode)
92-
insn->ops->set_hw_mode(true);
87+
if (insn->set_hw_mode)
88+
insn->set_hw_mode(true);
9389
}
9490

9591
static void disable_insn_hw_mode(void *data)
9692
{
9793
struct insn_emulation *insn = (struct insn_emulation *)data;
98-
if (insn->ops->set_hw_mode)
99-
insn->ops->set_hw_mode(false);
94+
if (insn->set_hw_mode)
95+
insn->set_hw_mode(false);
10096
}
10197

10298
/* Run set_hw_mode(mode) on all active CPUs */
10399
static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool enable)
104100
{
105-
if (!insn->ops->set_hw_mode)
101+
if (!insn->set_hw_mode)
106102
return -EINVAL;
107103
if (enable)
108104
on_each_cpu(enable_insn_hw_mode, (void *)insn, true);
@@ -126,9 +122,9 @@ static int run_all_insn_set_hw_mode(unsigned int cpu)
126122
raw_spin_lock_irqsave(&insn_emulation_lock, flags);
127123
list_for_each_entry(insn, &insn_emulation, node) {
128124
bool enable = (insn->current_mode == INSN_HW);
129-
if (insn->ops->set_hw_mode && insn->ops->set_hw_mode(enable)) {
125+
if (insn->set_hw_mode && insn->set_hw_mode(enable)) {
130126
pr_warn("CPU[%u] cannot support the emulation of %s",
131-
cpu, insn->ops->name);
127+
cpu, insn->name);
132128
rc = -EINVAL;
133129
}
134130
}
@@ -145,43 +141,37 @@ static int update_insn_emulation_mode(struct insn_emulation *insn,
145141
case INSN_UNDEF: /* Nothing to be done */
146142
break;
147143
case INSN_EMULATE:
148-
remove_emulation_hooks(insn->ops);
144+
remove_emulation_hooks(insn);
149145
break;
150146
case INSN_HW:
151147
if (!run_all_cpu_set_hw_mode(insn, false))
152-
pr_notice("Disabled %s support\n", insn->ops->name);
148+
pr_notice("Disabled %s support\n", insn->name);
153149
break;
154150
}
155151

156152
switch (insn->current_mode) {
157153
case INSN_UNDEF:
158154
break;
159155
case INSN_EMULATE:
160-
register_emulation_hooks(insn->ops);
156+
register_emulation_hooks(insn);
161157
break;
162158
case INSN_HW:
163159
ret = run_all_cpu_set_hw_mode(insn, true);
164160
if (!ret)
165-
pr_notice("Enabled %s support\n", insn->ops->name);
161+
pr_notice("Enabled %s support\n", insn->name);
166162
break;
167163
}
168164

169165
return ret;
170166
}
171167

172-
static void __init register_insn_emulation(struct insn_emulation_ops *ops)
168+
static void __init register_insn_emulation(struct insn_emulation *insn)
173169
{
174170
unsigned long flags;
175-
struct insn_emulation *insn;
176-
177-
insn = kzalloc(sizeof(*insn), GFP_KERNEL);
178-
if (!insn)
179-
return;
180171

181-
insn->ops = ops;
182172
insn->min = INSN_UNDEF;
183173

184-
switch (ops->status) {
174+
switch (insn->status) {
185175
case INSN_DEPRECATED:
186176
insn->current_mode = INSN_EMULATE;
187177
/* Disable the HW mode if it was turned on at early boot time */
@@ -247,7 +237,7 @@ static void __init register_insn_emulation_sysctl(void)
247237
sysctl->mode = 0644;
248238
sysctl->maxlen = sizeof(int);
249239

250-
sysctl->procname = insn->ops->name;
240+
sysctl->procname = insn->name;
251241
sysctl->data = &insn->current_mode;
252242
sysctl->extra1 = &insn->min;
253243
sysctl->extra2 = &insn->max;
@@ -445,7 +435,7 @@ static struct undef_hook swp_hooks[] = {
445435
{ }
446436
};
447437

448-
static struct insn_emulation_ops swp_ops = {
438+
static struct insn_emulation insn_swp = {
449439
.name = "swp",
450440
.status = INSN_OBSOLETE,
451441
.hooks = swp_hooks,
@@ -532,7 +522,7 @@ static struct undef_hook cp15_barrier_hooks[] = {
532522
{ }
533523
};
534524

535-
static struct insn_emulation_ops cp15_barrier_ops = {
525+
static struct insn_emulation insn_cp15_barrier = {
536526
.name = "cp15_barrier",
537527
.status = INSN_DEPRECATED,
538528
.hooks = cp15_barrier_hooks,
@@ -605,7 +595,7 @@ static struct undef_hook setend_hooks[] = {
605595
{}
606596
};
607597

608-
static struct insn_emulation_ops setend_ops = {
598+
static struct insn_emulation insn_setend = {
609599
.name = "setend",
610600
.status = INSN_DEPRECATED,
611601
.hooks = setend_hooks,
@@ -619,14 +609,14 @@ static struct insn_emulation_ops setend_ops = {
619609
static int __init armv8_deprecated_init(void)
620610
{
621611
if (IS_ENABLED(CONFIG_SWP_EMULATION))
622-
register_insn_emulation(&swp_ops);
612+
register_insn_emulation(&insn_swp);
623613

624614
if (IS_ENABLED(CONFIG_CP15_BARRIER_EMULATION))
625-
register_insn_emulation(&cp15_barrier_ops);
615+
register_insn_emulation(&insn_cp15_barrier);
626616

627617
if (IS_ENABLED(CONFIG_SETEND_EMULATION)) {
628618
if (system_supports_mixed_endian_el0())
629-
register_insn_emulation(&setend_ops);
619+
register_insn_emulation(&insn_setend);
630620
else
631621
pr_info("setend instruction emulation is not supported on this system\n");
632622
}

0 commit comments

Comments
 (0)